Show category pills in article name view, delay new article button until loaded
- Display category breadcrumb chips below article name in ArticleViewName - Only show NewArticleTile when articles are successfully loaded
This commit is contained in:
@@ -69,6 +69,8 @@ export default function ArticleView({
|
||||
<PanelTileGrid>
|
||||
<ArticleViewName
|
||||
article={articleData}
|
||||
categories={categories}
|
||||
rootCategoryId={rootCategoryId}
|
||||
onArticleUpdated={onArticleUpdated}
|
||||
/>
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import SingleLineTextEdit from '../../SingleLineTextEdit';
|
||||
import { article } from '../../../api';
|
||||
import { requireObject } from '../../../utils/apiShape';
|
||||
import { PANEL_TILE_KEYS } from '../../../theme';
|
||||
import { getCategoryBreadcrumbs } from '../../../store/categorySlice';
|
||||
import { Box, Chip } from '@mui/material';
|
||||
|
||||
const articleNameTextSx = {
|
||||
fontWeight: 700,
|
||||
@@ -33,6 +35,13 @@ const articleNameFieldHiddenSx = {
|
||||
},
|
||||
};
|
||||
|
||||
const pillsContainerSx = {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
gap: 0.5,
|
||||
mt: 'auto',
|
||||
};
|
||||
|
||||
function nameDraftDirty(draft, saved) {
|
||||
return draft.name.trim() !== String(saved.name ?? '').trim();
|
||||
}
|
||||
@@ -45,7 +54,14 @@ const headerTileSx = {
|
||||
minHeight: 0,
|
||||
};
|
||||
|
||||
export default function ArticleViewName({ article: articleData, onArticleUpdated }) {
|
||||
function buildCategoryLabel(categories, categoryId, rootCategoryId) {
|
||||
if (!categories || categoryId == null) return '';
|
||||
const crumbs = getCategoryBreadcrumbs(categories, categoryId, rootCategoryId);
|
||||
if (crumbs.length === 0) return '';
|
||||
return crumbs.map((c) => c.name).join(' | ');
|
||||
}
|
||||
|
||||
export default function ArticleViewName({ article: articleData, categories, rootCategoryId, onArticleUpdated }) {
|
||||
const handleSave = async (draft) => {
|
||||
const name = draft.name.trim();
|
||||
const res = await article.update(articleData.sku, { name });
|
||||
@@ -54,6 +70,11 @@ export default function ArticleViewName({ article: articleData, onArticleUpdated
|
||||
onArticleUpdated?.(res.article);
|
||||
};
|
||||
|
||||
const categoryIds = articleData.categoryIds ?? [];
|
||||
const categoryLabels = categoryIds
|
||||
.map((id) => ({ id, label: buildCategoryLabel(categories, id, rootCategoryId) }))
|
||||
.filter((c) => c.label);
|
||||
|
||||
return (
|
||||
<EditablePanelTile
|
||||
wide={3}
|
||||
@@ -65,13 +86,24 @@ export default function ArticleViewName({ article: articleData, onArticleUpdated
|
||||
isDirty={nameDraftDirty}
|
||||
canSave={nameDraftValid}
|
||||
renderDisplay={({ name }) => (
|
||||
<SingleLineTextEdit
|
||||
label="Name"
|
||||
value={name}
|
||||
readOnly
|
||||
onChange={() => {}}
|
||||
sx={articleNameFieldHiddenSx}
|
||||
/>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', flex: 1, alignSelf: 'stretch' }}>
|
||||
<Box sx={{ flex: 1, display: 'flex', alignItems: 'center' }}>
|
||||
<SingleLineTextEdit
|
||||
label="Name"
|
||||
value={name}
|
||||
readOnly
|
||||
onChange={() => {}}
|
||||
sx={articleNameFieldHiddenSx}
|
||||
/>
|
||||
</Box>
|
||||
{categoryLabels.length > 0 && (
|
||||
<Box sx={pillsContainerSx}>
|
||||
{categoryLabels.map(({ id, label }) => (
|
||||
<Chip key={id} label={label} size="small" variant="outlined" />
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
renderEdit={(draft, onChange, inputRef) => (
|
||||
<SingleLineTextEdit
|
||||
|
||||
@@ -462,7 +462,7 @@ class ArtikelKategorienPage extends Component {
|
||||
))}
|
||||
|
||||
{renameMode && <NewCategoryTile parentId={currentCategoryId} />}
|
||||
{!renameMode && (
|
||||
{!renameMode && articlesStatus === 'succeeded' && (
|
||||
<NewArticleTile
|
||||
parentId={currentCategoryId}
|
||||
onOpenArticle={this.handleArticleClick}
|
||||
|
||||
Reference in New Issue
Block a user