u
This commit is contained in:
@@ -2,15 +2,19 @@ import { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import Box from '@mui/material/Box';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { enqueueSnackbar } from 'notistack';
|
||||
import BackendError from '../../components/BackendError';
|
||||
import { NewCategoryTile, CategoryBreadcrumbs } from '../../components/category';
|
||||
import { NewArticleTile } from '../../components/article';
|
||||
import { notifyError } from '../../utils/notify';
|
||||
import {
|
||||
ArticleTile,
|
||||
BackTile,
|
||||
CategoryTile,
|
||||
TILE_SIZE,
|
||||
tileBaseSx,
|
||||
} from '../../components/tiles';
|
||||
import withCategoryRoute from './withCategoryRoute';
|
||||
import { artikelDetailPath, articleSku } from './articleRoute';
|
||||
@@ -26,6 +30,7 @@ import {
|
||||
loadCategoryArticles,
|
||||
loadCategoryTree,
|
||||
navigateToCategory,
|
||||
renameCategory,
|
||||
selectCanNavigateBack,
|
||||
selectCategoryArticles,
|
||||
selectCategoryArticlesStatus,
|
||||
@@ -34,6 +39,7 @@ import {
|
||||
selectCategoryError,
|
||||
selectCategoryTreeStatus,
|
||||
selectChildCategories,
|
||||
selectRenameMode,
|
||||
} from '../../store/categorySlice';
|
||||
|
||||
const gridSx = {
|
||||
@@ -43,6 +49,13 @@ const gridSx = {
|
||||
};
|
||||
|
||||
class ArtikelKategorienPage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { drafts: {} };
|
||||
this.handleRenameSubmit = this.handleRenameSubmit.bind(this);
|
||||
this.handleDraftChange = this.handleDraftChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.ensureTreeLoaded();
|
||||
this.syncCategoryFromUrl();
|
||||
@@ -127,6 +140,29 @@ class ArtikelKategorienPage extends Component {
|
||||
navigate(buildCategoryPath(categories, rootCategoryId, categoryId));
|
||||
};
|
||||
|
||||
handleDraftChange(categoryId, value) {
|
||||
this.setState((state) => ({
|
||||
drafts: { ...state.drafts, [categoryId]: value },
|
||||
}));
|
||||
}
|
||||
|
||||
handleRenameSubmit = async (categoryId, name) => {
|
||||
const trimmed = String(name ?? '').trim();
|
||||
if (!trimmed) {
|
||||
enqueueSnackbar('Name ist erforderlich.', { variant: 'error' });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await this.props.renameCategory({
|
||||
categoryId,
|
||||
name: trimmed,
|
||||
}).unwrap();
|
||||
enqueueSnackbar('Kategorie umbenannt.', { variant: 'success' });
|
||||
} catch (err) {
|
||||
notifyError(err);
|
||||
}
|
||||
};
|
||||
|
||||
handleRetryTree = () => {
|
||||
if (this.props.companyId) this.props.loadCategoryTree();
|
||||
};
|
||||
@@ -161,6 +197,7 @@ class ArtikelKategorienPage extends Component {
|
||||
currentCategoryId,
|
||||
childCategories,
|
||||
articles,
|
||||
renameMode,
|
||||
} = this.props;
|
||||
|
||||
if (!companyId) {
|
||||
@@ -218,15 +255,62 @@ class ArtikelKategorienPage extends Component {
|
||||
<BackTile onClick={this.handleNavigateBack} />
|
||||
)}
|
||||
|
||||
{childCategories.map((item) => (
|
||||
<CategoryTile
|
||||
key={item.id}
|
||||
label={categoryDisplayName(item.name, item.id, rootCategoryId)}
|
||||
onClick={() => this.navigateToCategoryById(item.id)}
|
||||
/>
|
||||
))}
|
||||
{childCategories.map((item) => {
|
||||
const label = categoryDisplayName(item.name, item.id, rootCategoryId);
|
||||
if (renameMode) {
|
||||
const draftName =
|
||||
this.state.drafts[item.id] !== undefined
|
||||
? this.state.drafts[item.id]
|
||||
: label;
|
||||
return (
|
||||
<Box
|
||||
key={item.id}
|
||||
component="form"
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault();
|
||||
void this.handleRenameSubmit(item.id, this.state.drafts[item.id] ?? label);
|
||||
}}
|
||||
sx={{
|
||||
...tileBaseSx,
|
||||
cursor: 'default',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
my: 0.5,
|
||||
bgcolor: 'action.hover',
|
||||
'&:hover': { bgcolor: 'action.hover' },
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
fullWidth
|
||||
size="small"
|
||||
variant="standard"
|
||||
value={draftName}
|
||||
onChange={(e) => this.handleDraftChange(item.id, e.target.value)}
|
||||
slotProps={{ inputLabel: { shrink: true } }}
|
||||
sx={{
|
||||
mx: 0.5,
|
||||
'& .MuiInput-underline:before, & .MuiInput-underline:after': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
'& .MuiInputBase-input': {
|
||||
textAlign: 'center',
|
||||
fontWeight: 600,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<CategoryTile
|
||||
key={item.id}
|
||||
label={label}
|
||||
onClick={() => this.navigateToCategoryById(item.id)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
{articles.map((item) => (
|
||||
{!renameMode && articles.map((item) => (
|
||||
<ArticleTile
|
||||
key={item.id}
|
||||
label={item.name != null ? item.name.trim() : undefined}
|
||||
@@ -237,10 +321,12 @@ class ArtikelKategorienPage extends Component {
|
||||
))}
|
||||
|
||||
<NewCategoryTile parentId={currentCategoryId} />
|
||||
<NewArticleTile
|
||||
parentId={currentCategoryId}
|
||||
onOpenArticle={this.handleArticleClick}
|
||||
/>
|
||||
{!renameMode && (
|
||||
<NewArticleTile
|
||||
parentId={currentCategoryId}
|
||||
onOpenArticle={this.handleArticleClick}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{showArticlesLoading && (
|
||||
@@ -265,12 +351,14 @@ const mapStateToProps = (state) => ({
|
||||
childCategories: selectChildCategories(state),
|
||||
articles: selectCategoryArticles(state),
|
||||
canGoBack: selectCanNavigateBack(state),
|
||||
renameMode: selectRenameMode(state),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
loadCategoryTree,
|
||||
loadCategoryArticles,
|
||||
navigateToCategory,
|
||||
renameCategory,
|
||||
};
|
||||
|
||||
export default withCategoryRoute(connect(mapStateToProps, mapDispatchToProps)(ArtikelKategorienPage));
|
||||
|
||||
Reference in New Issue
Block a user