From caf08a3262526afcbe7602f36825e7f6e90c3b07 Mon Sep 17 00:00:00 2001 From: seb Date: Wed, 5 Aug 2026 20:15:39 +0200 Subject: [PATCH] u --- src/api/ApiClient.js | 12 +++- src/api/StorageManager.js | 7 ++ .../article/boxes/ArticleViewName.jsx | 71 +++++++++++++++---- 3 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/api/ApiClient.js b/src/api/ApiClient.js index 8197ce3..6fe2c27 100644 --- a/src/api/ApiClient.js +++ b/src/api/ApiClient.js @@ -118,11 +118,19 @@ export class ApiClient { const nameChange = body != null && Object.hasOwn(body, 'name'); if (nameChange) { this.setArticleIndexName(sku, body.name); + this.setArticleName(sku, body.name); } try { - return await this.#json('PATCH', `/api/article/${enc(sku)}`, { body }); + const res = await this.#json('PATCH', `/api/article/${enc(sku)}`, { body }); + this.setArticle(res.article); + return res; } catch (err) { - if (nameChange) this.clearArticleIndex(); + if (nameChange) { + this.clearArticleIndex(); + if (this.getArticle(sku)) { + void this.loadArticle(sku).catch(() => {}); + } + } throw err; } }, diff --git a/src/api/StorageManager.js b/src/api/StorageManager.js index c23eaa6..4597dd5 100644 --- a/src/api/StorageManager.js +++ b/src/api/StorageManager.js @@ -245,6 +245,13 @@ export class StorageManager extends ApiClient { ); } + /** Patch local article detail name if already cached; no-op otherwise. */ + setArticleName(sku, name) { + const current = this.#articlesBySku.get(String(sku)); + if (!current) return; + this.setArticle({ ...current, name }); + } + /** Drop local articleIndex if loaded (forces reload on next read). */ clearArticleIndex() { if (!this.#articleIndexCache.value) return; diff --git a/src/components/article/boxes/ArticleViewName.jsx b/src/components/article/boxes/ArticleViewName.jsx index f576b3e..cf8f219 100644 --- a/src/components/article/boxes/ArticleViewName.jsx +++ b/src/components/article/boxes/ArticleViewName.jsx @@ -178,21 +178,46 @@ class NameDisplay extends Component { } class NameEdit extends Component { + constructor(props) { + super(props); + this.state = { + name: props.name, + categoryIds: [...(props.categoryIds ?? [])], + }; + } + + componentDidMount() { + const { onNameDraftChange, onCategoryIdsDraftChange } = this.props; + onNameDraftChange?.(this.state.name); + onCategoryIdsDraftChange?.(this.state.categoryIds); + } + + handleNameChange = (name) => { + this.setState({ name }); + this.props.onNameDraftChange?.(name); + }; + + handleCategoryIdsChange = (categoryIds) => { + this.setState({ categoryIds }); + this.props.onCategoryIdsDraftChange?.(categoryIds); + }; + render() { - const { name, categoryIds } = this.props; + const { name, categoryIds } = this.state; return ( {}} + onChange={this.handleNameChange} sx={articleNameFieldSx} /> ); @@ -202,34 +227,58 @@ class NameEdit extends Component { export default class ArticleViewName extends Component { static contextType = StorageManagerContext; - handleSave = async (draft) => { + constructor(props) { + super(props); + this.state = { + nameDraft: null, + categoryIdsDraft: null, + }; + } + + handleNameDraftChange = (name) => { + this.setState({ nameDraft: name }); + }; + + handleCategoryIdsDraftChange = (categoryIds) => { + this.setState({ categoryIdsDraft: categoryIds }); + }; + + handleSave = async () => { const { article: articleData, onArticleUpdated } = this.props; + const { nameDraft, categoryIdsDraft } = this.state; const store = this.context; - const name = draft.name.trim(); - const categoryIds = draft.categoryIds ?? []; + const name = nameDraft.trim(); + const categoryIds = categoryIdsDraft; const nameChanged = name !== String(articleData.name ?? '').trim(); const categoriesChanged = categoryIdsChanged(categoryIds, articleData.categoryIds); let article = null; if (nameChanged) { - console.log('nameChanged', name, articleData.name); + console.log('storing name update', name, articleData.name); const nameRes = await store.article.update(articleData.sku, { name }); article = nameRes.article; } if (categoriesChanged) { + console.log('storing categories update', categoryIds, articleData.categoryIds); const catRes = await store.article.setCategories(articleData.sku, { categoryIds }); article = catRes.article; } if (article) onArticleUpdated?.(article); + this.setState({ nameDraft: null, categoryIdsDraft: null }); }; render() { const { article: articleData } = this.props; + const { nameDraft, categoryIdsDraft } = this.state; const savedCategoryIds = articleData.categoryIds ?? []; const value = { name: articleData.name ?? '', categoryIds: [...savedCategoryIds] }; + const draft = + nameDraft != null && categoryIdsDraft != null + ? { name: nameDraft, categoryIds: categoryIdsDraft } + : null; return ( draft != null && draftDirty(draft, value)} + canSave={() => draft != null && draftValid(draft)} display={ } edit={ {}} - onCategoryIdsChange={() => {}} - onIsDirtyChange={() => {}} + onNameDraftChange={this.handleNameDraftChange} + onCategoryIdsDraftChange={this.handleCategoryIdsDraftChange} /> } />