This commit is contained in:
seb
2026-09-22 13:45:22 +02:00
parent 3ae840b2fe
commit 49057dc0d6
11 changed files with 1233 additions and 421 deletions

View File

@@ -2,7 +2,7 @@ import { Component, PureComponent } from 'react';
import { EditablePanelTile } from 'dashgui/panels';
import SingleLineTextEdit from 'dashgui/SingleLineTextEdit';
import { StorageManagerContext } from '../../../api/storageManagerContext';
import { getCategoryBreadcrumbs } from '../../../utils/categoryUtils';
import { getCategoryBreadcrumbs, categoryDisplayName } from '../../../utils/categoryUtils';
import { Box, Chip, IconButton } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import CategoryPickerDialog from '../CategoryPickerDialog';
@@ -92,7 +92,7 @@ class CategoryPills extends Component {
constructor(props) {
super(props);
this.state = { pickerOpen: false };
this.state = { pickerOpen: false, targetPillId: null };
}
handleRemoveCategory = (removeId) => {
@@ -101,20 +101,52 @@ class CategoryPills extends Component {
onCategoryIdsChange?.(remaining);
};
handleOpenPicker = () => {
this.setState({ pickerOpen: true });
handleOpenAddPicker = () => {
this.setState({ pickerOpen: true, targetPillId: null });
};
handleOpenMovePicker = (pillId) => {
this.setState({ pickerOpen: true, targetPillId: pillId });
};
handleClosePicker = () => {
this.setState({ pickerOpen: false });
this.setState({ pickerOpen: false, targetPillId: null });
};
handleCategorySelect = (selectedCategoryId) => {
const { categoryIds, onCategoryIdsChange } = this.props;
const { targetPillId } = this.state;
if (targetPillId != null) {
const updated = categoryIds.map((id) =>
String(id) === String(targetPillId) ? selectedCategoryId : id
);
const deduped = [...new Set(updated)];
onCategoryIdsChange?.(deduped);
} else {
if (!categoryIds.some((id) => String(id) === String(selectedCategoryId))) {
onCategoryIdsChange?.([...categoryIds, selectedCategoryId]);
}
}
};
render() {
const { categoryIds, editMode, onCategoryIdsChange } = this.props;
const { pickerOpen } = this.state;
const { categoryIds, editMode } = this.props;
const { pickerOpen, targetPillId } = this.state;
const { categories, rootCategoryId } = this.context.getCategoryState() ?? {};
const labels = categoryLabels(categoryIds, categories, rootCategoryId);
const targetNode = categories && targetPillId != null ? categories[String(targetPillId)] : null;
const targetLabel = targetNode
? categoryDisplayName(targetNode.name, targetNode.id, rootCategoryId)
: '';
const dialogTitle =
targetPillId != null
? (targetLabel ? `Artikel aus Kategorie „${targetLabel}“ verschieben in…` : 'Artikel aus Kategorie verschieben in…')
: 'Kategorie hinzufügen';
const confirmLabel = targetPillId != null ? 'Hierher verschieben' : 'Hinzufügen';
return (
<>
<Box sx={pillsContainerSx}>
@@ -124,17 +156,28 @@ class CategoryPills extends Component {
label={label}
size="small"
variant="outlined"
onClick={editMode ? () => this.handleOpenMovePicker(id) : undefined}
onDelete={
editMode && categoryIds.length > 1
? () => this.handleRemoveCategory(id)
: undefined
}
sx={{
cursor: editMode ? 'pointer' : 'default',
...(editMode
? {
'&:hover': {
bgcolor: 'action.hover',
},
}
: {}),
}}
/>
))}
{editMode ? (
<IconButton
size="small"
onClick={this.handleOpenPicker}
onClick={this.handleOpenAddPicker}
sx={{ ml: 0.5, width: 24, height: 24 }}
>
<AddIcon fontSize="small" />
@@ -148,7 +191,11 @@ class CategoryPills extends Component {
categories={categories}
rootCategoryId={rootCategoryId}
currentCategoryIds={categoryIds}
onSelect={onCategoryIdsChange}
selectedId={targetPillId ?? rootCategoryId}
title={dialogTitle}
confirmLabel={confirmLabel}
mode="single"
onSelectCategory={this.handleCategorySelect}
/>
) : null}
</>