fix(static-pages): stop createPage/duplicatePage from generating colliding slugs/routes
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
createPage() derived its slug from array length (custom-page-${length+1}):
create, delete, create again reliably reproduces a duplicate slug against a
surviving page. duplicatePage() had the same issue with a fixed '-copy'
suffix - duplicating the same page twice collides with the first duplicate.
Both trip the duplicate-slug/route validator on a page the user never
directly touched.
Added uniqueValue() (append -2, -3, ... until free) and used it for both.
Verified live via window.ng.getComponent(): reproduced the exact collision
scenario pre-fix, confirmed no duplicates post-fix (custom-page-6-2,
about-us-copy/about-us-copy-2).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -156,8 +156,28 @@ export class StaticPagesEditorComponent {
|
|||||||
this.mediaPickerOpen = false;
|
this.mediaPickerOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends `-2`, `-3`, ... to `candidate` until it's not in `existing`.
|
||||||
|
* createPage()/duplicatePage() both used to derive slugs/routes from array
|
||||||
|
* length or a fixed "-copy" suffix, which reproducibly collides with an
|
||||||
|
* existing page (create, delete, create again; or duplicate the same page
|
||||||
|
* twice) - the duplicate then trips the duplicate-slug/route validator
|
||||||
|
* on a page the user never touched.
|
||||||
|
*/
|
||||||
|
private uniqueValue(candidate: string, existing: Set<string>): string {
|
||||||
|
if (!existing.has(candidate)) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
let suffix = 2;
|
||||||
|
while (existing.has(`${candidate}-${suffix}`)) {
|
||||||
|
suffix++;
|
||||||
|
}
|
||||||
|
return `${candidate}-${suffix}`;
|
||||||
|
}
|
||||||
|
|
||||||
createPage(): void {
|
createPage(): void {
|
||||||
const slug = `custom-page-${this.allPages().length + 1}`;
|
const existingSlugs = new Set(this.allPages().map(page => page.slug));
|
||||||
|
const slug = this.uniqueValue(`custom-page-${this.allPages().length + 1}`, existingSlugs);
|
||||||
const page: ContentPage = {
|
const page: ContentPage = {
|
||||||
id: `page-${Date.now()}`,
|
id: `page-${Date.now()}`,
|
||||||
slug,
|
slug,
|
||||||
@@ -189,11 +209,13 @@ export class StaticPagesEditorComponent {
|
|||||||
if (!source) {
|
if (!source) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const existingSlugs = new Set(this.allPages().map(page => page.slug));
|
||||||
|
const existingRoutes = new Set(this.allPages().map(page => page.route));
|
||||||
const clone: ContentPage = {
|
const clone: ContentPage = {
|
||||||
...source,
|
...source,
|
||||||
id: `page-${Date.now()}`,
|
id: `page-${Date.now()}`,
|
||||||
slug: `${source.slug}-copy`,
|
slug: this.uniqueValue(`${source.slug}-copy`, existingSlugs),
|
||||||
route: `${source.route}-copy`,
|
route: this.uniqueValue(`${source.route}-copy`, existingRoutes),
|
||||||
order: this.allPages().length + 1,
|
order: this.allPages().length + 1,
|
||||||
status: 'draft',
|
status: 'draft',
|
||||||
translations: Object.fromEntries(Object.entries(source.translations).map(([locale, t]) => [locale, { ...t }])),
|
translations: Object.fromEntries(Object.entries(source.translations).map(([locale, t]) => [locale, { ...t }])),
|
||||||
|
|||||||
Reference in New Issue
Block a user