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:
seb
2026-08-03 08:39:22 +02:00
parent eb1b171d2e
commit 7ed6802070
3 changed files with 43 additions and 9 deletions

View File

@@ -69,6 +69,8 @@ export default function ArticleView({
<PanelTileGrid>
<ArticleViewName
article={articleData}
categories={categories}
rootCategoryId={rootCategoryId}
onArticleUpdated={onArticleUpdated}
/>

View File

@@ -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

View File

@@ -462,7 +462,7 @@ class ArtikelKategorienPage extends Component {
))}
{renameMode && <NewCategoryTile parentId={currentCategoryId} />}
{!renameMode && (
{!renameMode && articlesStatus === 'succeeded' && (
<NewArticleTile
parentId={currentCategoryId}
onOpenArticle={this.handleArticleClick}