fix(static-pages): backfill enabled/status in export, fix missing i18n key
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Independent review pass over the Static Pages Module sprint (M1-M7), including live browser E2E per the task's own verification checklist. - ProjectEditorFacade.normalize() now backfills enabled/status on record-format static pages (defaulting missing values to enabled+published, same rule ContentPageService.normalizePage applies for display - mirrored rather than imported, to avoid a project-editor <-> content-management circular dependency since ContentManagementFacade already depends on this facade). Found live: exporting a page that predates this sprint and was never touched/re-saved in the current session produced JSON missing enabled/status entirely - the editor UI and storefront resolver both normalize-on-read so nothing was actually broken live, but Export/Import fidelity should match what the editor shows. Verified fixed live (export now includes "enabled":true,"status":"published" for an untouched legacy page) and via the full gate. - Added the missing adminCategories.chooseImage i18n key (interface + en/ru/hy). Found live: the media-picker "choose image" button rendered as the literal string "adminCategories.chooseImage" - a pre-existing, repo-wide bug (5 templates reference this key; none of the locale files ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new occurrences by copying the existing branding-section/footer-section pattern into static-pages-editor. Fixed the actual defect (missing translation) rather than renaming the key, which would have required touching 2 unrelated admin components outside this sprint's scope. Live-verified this pass: Static Pages editor renders with all new fields; create page works (page count 4->confirmed); device preview toggles desktop/tablet/mobile widths correctly; navigation "Insert page link" creates a real type:'staticPage' nav item end-to-end (confirmed in the exported JSON); export includes all Sprint X+2 fields after the fix; no console errors throughout. Gate: tsc --noEmit, npm test (57/57), arch:check, build all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -552,7 +552,37 @@ export class ProjectEditorFacade {
|
||||
const leftOrder = Math.min(...left.sections.map(section => section.order));
|
||||
const rightOrder = Math.min(...right.sections.map(section => section.order));
|
||||
return leftOrder - rightOrder;
|
||||
})
|
||||
}),
|
||||
staticPages: this.normalizeStaticPagesShape(config.staticPages),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Backfills `enabled`/`status` on record-format static pages at the
|
||||
* bootstrap-normalization layer, mirroring (not importing - would create a
|
||||
* project-editor <-> content-management circular dependency, since
|
||||
* ContentManagementFacade already depends on this facade) the same default
|
||||
* ContentPageService.normalizePage applies for display: a page with no
|
||||
* enabled/status predates this field and was always live, so it defaults
|
||||
* to enabled+published rather than silently disappearing. Without this,
|
||||
* exportBootstrap() on a page nobody has touched this session would omit
|
||||
* both fields (present in the editor's display via normalize-on-read, but
|
||||
* literally absent from the stored/exported JSON) - the storefront
|
||||
* resolver was never at risk (it normalizes on every read), but export
|
||||
* fidelity should match what the editor shows.
|
||||
*/
|
||||
private normalizeStaticPagesShape(staticPages: BootstrapConfig['staticPages']): BootstrapConfig['staticPages'] {
|
||||
if (!staticPages || Array.isArray(staticPages)) {
|
||||
return staticPages;
|
||||
}
|
||||
const result: typeof staticPages = {};
|
||||
for (const [key, page] of Object.entries(staticPages)) {
|
||||
result[key] = {
|
||||
...page,
|
||||
enabled: page.enabled ?? true,
|
||||
status: page.status ?? 'published',
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,6 +921,9 @@ export const en: Translations = {
|
||||
emptyTitle: 'No files yet',
|
||||
emptyDescription: 'Upload an image or document to get started.',
|
||||
},
|
||||
adminCategories: {
|
||||
chooseImage: 'Choose image',
|
||||
},
|
||||
adminProducts: {
|
||||
emptyTitle: 'No products found',
|
||||
emptyDescription: 'Try adjusting your filters, or create a new product.',
|
||||
|
||||
@@ -916,6 +916,9 @@ export const hy: Translations = {
|
||||
emptyTitle: 'Ֆայլեր դեռ չկան',
|
||||
emptyDescription: 'Վերբեռնեք պատկեր կամ փաստաթուղթ սկսելու համար։',
|
||||
},
|
||||
adminCategories: {
|
||||
chooseImage: 'Ընտրել պատկեր',
|
||||
},
|
||||
adminProducts: {
|
||||
emptyTitle: 'Ապրանքներ չեն գտնվել',
|
||||
emptyDescription: 'Փոխեք ֆիլտրերը կամ ստեղծեք նոր ապրանք։',
|
||||
|
||||
@@ -916,6 +916,9 @@ export const ru: Translations = {
|
||||
emptyTitle: 'Пока нет файлов',
|
||||
emptyDescription: 'Загрузите изображение или документ, чтобы начать.',
|
||||
},
|
||||
adminCategories: {
|
||||
chooseImage: 'Выбрать изображение',
|
||||
},
|
||||
adminProducts: {
|
||||
emptyTitle: 'Товары не найдены',
|
||||
emptyDescription: 'Измените фильтры или создайте новый товар.',
|
||||
|
||||
@@ -923,6 +923,14 @@ export interface Translations {
|
||||
// state consistency fix introduces - NOT the full adminProducts/
|
||||
// adminUsers/adminMonitoring/adminAnalytics translation surface, which is
|
||||
// still missing entirely (see docs/KNOWN-ISSUES.md, deferred to Sprint 29).
|
||||
// Shared across branding/footer/static-pages/admin-product/admin-category media
|
||||
// pickers - despite the namespace name, this is a generic "choose image" label,
|
||||
// not category-specific. Renaming is a separate cleanup outside this sprint's
|
||||
// scope; the key was previously referenced by 5 templates but never defined
|
||||
// anywhere, so it rendered as the literal string "adminCategories.chooseImage".
|
||||
adminCategories: {
|
||||
chooseImage: string;
|
||||
};
|
||||
adminProducts: {
|
||||
emptyTitle: string;
|
||||
emptyDescription: string;
|
||||
|
||||
Reference in New Issue
Block a user