Skip to content

Commit 8210ded

Browse files
committed
Migrate pages to id-keyed maps
1 parent 8aa8c43 commit 8210ded

68 files changed

Lines changed: 2312 additions & 1723 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/builder/app/builder/builder.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import type { TokenPermissions } from "@webstudio-is/authorization-token";
5858
import { useToastErrors } from "~/shared/error/toast-error";
5959
import { initBuilderApi } from "~/shared/builder-api";
6060
import { updateWebstudioData } from "~/shared/instance-utils";
61-
import { migrateWebstudioDataMutable } from "~/shared/webstudio-data-migrator";
61+
import { migrateWebstudioDataMutable } from "@webstudio-is/sdk/migrations/webstudio-data";
6262
import { Loading, LoadingBackground } from "./shared/loading";
6363
import { mergeRefs } from "@react-aria/utils";
6464
import { CommandPanel } from "./features/command-panel";

apps/builder/app/builder/features/address-bar.stories.tsx

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,43 @@ registerContainers();
1616
$dataSources.set(new Map());
1717

1818
$pages.set({
19-
folders: [
20-
{
21-
id: "rootId",
22-
name: "",
23-
slug: "",
24-
children: ["homeId", "dynamicId"],
25-
},
26-
],
27-
homePage: {
28-
id: "homeId",
29-
path: "",
30-
name: "",
31-
title: "",
32-
meta: {},
33-
rootInstanceId: "",
34-
},
35-
pages: [
36-
{
37-
id: "dynamicId",
38-
path: "/blog/:date/post/:slug",
39-
name: "",
40-
title: "",
41-
meta: {},
42-
rootInstanceId: "rootInstanceId",
43-
},
44-
],
19+
homePageId: "homeId",
20+
rootFolderId: "rootId",
21+
folders: new Map([
22+
[
23+
"rootId",
24+
{
25+
id: "rootId",
26+
name: "",
27+
slug: "",
28+
children: ["homeId", "dynamicId"],
29+
},
30+
],
31+
]),
32+
pages: new Map([
33+
[
34+
"homeId",
35+
{
36+
id: "homeId",
37+
path: "",
38+
name: "",
39+
title: "",
40+
meta: {},
41+
rootInstanceId: "",
42+
},
43+
],
44+
[
45+
"dynamicId",
46+
{
47+
id: "dynamicId",
48+
path: "/blog/:date/post/:slug",
49+
name: "",
50+
title: "",
51+
meta: {},
52+
rootInstanceId: "rootInstanceId",
53+
},
54+
],
55+
]),
4556
});
4657

4758
const SystemInspect = () => {

apps/builder/app/builder/features/command-panel/command-panel.stories.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ $breakpoints.set(
3838
);
3939

4040
const pages = createDefaultPages({ rootInstanceId: "" });
41-
pages.pages.push({
41+
pages.pages.set("page2", {
4242
id: "page2",
4343
path: "",
4444
name: "Second Page",
4545
rootInstanceId: "",
4646
title: "",
4747
meta: {},
4848
});
49-
pages.pages.push({
49+
pages.pages.set("page3", {
5050
id: "page3",
5151
path: "",
5252
name: "Thrid Page",
@@ -55,7 +55,7 @@ pages.pages.push({
5555
meta: {},
5656
});
5757
$pages.set(pages);
58-
$selectedPageId.set(pages.homePage.id);
58+
$selectedPageId.set(pages.homePageId);
5959

6060
export const CommandPanel: StoryFn = () => {
6161
useEffect(() => {

apps/builder/app/builder/features/command-panel/groups/pages-group.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
useSelectedAction,
77
} from "@webstudio-is/design-system";
88
import { computed } from "nanostores";
9-
import type { Page } from "@webstudio-is/sdk";
9+
import { getAllPages, type Page } from "@webstudio-is/sdk";
1010
import { $pages } from "~/shared/sync/data-stores";
1111
import { $editingPageId } from "~/shared/nano-states";
1212
import { $selectedPage } from "~/shared/nano-states";
@@ -28,7 +28,7 @@ export const $pageOptions = computed(
2828
}
2929
const pageOptions: PageOption[] = [];
3030
if (pages) {
31-
for (const page of [pages.homePage, ...pages.pages]) {
31+
for (const page of getAllPages(pages)) {
3232
if (page.id === selectedPage?.id) {
3333
continue;
3434
}

apps/builder/app/builder/features/command-panel/shared/instance-list.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
useSelectedAction,
1414
useCommandState,
1515
} from "@webstudio-is/design-system";
16-
import type { Instance } from "@webstudio-is/sdk";
16+
import { getPageById, type Instance } from "@webstudio-is/sdk";
1717
import { $instances, $pages } from "~/shared/sync/data-stores";
1818
import { getInstanceLabel } from "~/builder/shared/instance-label";
1919
import { buildInstancePath } from "~/shared/instance-utils";
@@ -61,7 +61,7 @@ export const InstanceList = ({
6161
instances,
6262
instanceId
6363
);
64-
const page = pages.pages.find((p) => p.id === awareness.pageId);
64+
const page = getPageById(pages, awareness.pageId);
6565
usedInInstances.push({
6666
label: getInstanceLabel(instance),
6767
id: instance.id,

apps/builder/app/builder/features/marketplace/templates.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { ChevronLeftIcon, ExternalLinkIcon } from "@webstudio-is/icons";
1414
import {
1515
elementComponent,
16+
getAllPages,
1617
Instance,
1718
ROOT_FOLDER_ID,
1819
type Asset,
@@ -116,7 +117,7 @@ const getTemplatesDataByCategory = (
116117
if (data === undefined) {
117118
return new Map();
118119
}
119-
const pages = [data.pages.homePage, ...data.pages.pages]
120+
const pages = getAllPages(data.pages)
120121
.filter((page) => page.marketplace?.include)
121122
.map((page) => {
122123
// category can be empty string

apps/builder/app/builder/features/marketplace/utils.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
getStyleDeclKey,
3+
migratePages,
34
type Asset,
5+
type SerializedPages,
46
type WebstudioData,
57
} from "@webstudio-is/sdk";
68
import type { CompactBuild } from "@webstudio-is/project-build";
@@ -9,14 +11,17 @@ const getPair = <Item extends { id: string }>(item: Item) =>
911
[item.id, item] as const;
1012

1113
export const toWebstudioData = (
12-
data: CompactBuild & { assets: Asset[] }
14+
data: Omit<CompactBuild, "pages"> & {
15+
assets: Asset[];
16+
pages: SerializedPages;
17+
}
1318
): WebstudioData => ({
1419
assets: new Map(data.assets.map(getPair)),
1520
instances: new Map(data.instances.map(getPair)),
1621
dataSources: new Map(data.dataSources.map(getPair)),
1722
resources: new Map(data.resources.map(getPair)),
1823
props: new Map(data.props.map(getPair)),
19-
pages: data.pages,
24+
pages: migratePages(data.pages),
2025
breakpoints: new Map(data.breakpoints.map(getPair)),
2126
styleSources: new Map(data.styleSources.map(getPair)),
2227
styleSourceSelections: new Map(

apps/builder/app/builder/features/pages/folder-settings.tsx

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
Pages,
2222
ROOT_FOLDER_ID,
2323
findParentFolderByChildId,
24+
getFolderById,
2425
} from "@webstudio-is/sdk";
2526
import { nanoid } from "nanoid";
2627
import { useCallback, useState, type FocusEventHandler } from "react";
@@ -82,16 +83,14 @@ const validateValues = (
8283
return errors;
8384
};
8485

85-
const toFormValues = (
86-
folderId: Folder["id"],
87-
folders: Array<Folder>
88-
): Values => {
89-
const folder = folders.find(({ id }) => id === folderId);
86+
const toFormValues = (folderId: Folder["id"], pages: Pages): Values => {
87+
const { folders } = pages;
88+
const folder = folders.get(folderId);
9089
const parentFolder = findParentFolderByChildId(folderId, folders);
9190
return {
9291
name: folder?.name ?? "",
9392
slug: folder?.slug ?? "",
94-
parentFolderId: parentFolder?.id ?? ROOT_FOLDER_ID,
93+
parentFolderId: parentFolder?.id ?? pages.rootFolderId,
9594
};
9695
};
9796

@@ -211,6 +210,7 @@ export const NewFolderSettings = ({
211210

212211
const [values, setValues] = useState<Values>({
213212
...fieldDefaultValues,
213+
parentFolderId: pages?.rootFolderId ?? fieldDefaultValues.parentFolderId,
214214
slug: nameToSlug(fieldDefaultValues.name),
215215
});
216216

@@ -292,15 +292,15 @@ const createFolder = (folderId: Folder["id"], values: Values) => {
292292
if (pages === undefined) {
293293
return;
294294
}
295-
pages.folders.push({
295+
pages.folders.set(folderId, {
296296
id: folderId,
297297
name: values.name,
298298
slug: values.slug,
299299
children: [],
300300
} satisfies Folder);
301-
const parentFolder = pages.folders.find(
302-
({ id }) => id === values.parentFolderId
303-
);
301+
const parentFolder =
302+
getFolderById(pages, values.parentFolderId) ??
303+
getFolderById(pages, pages.rootFolderId);
304304
parentFolder?.children.push(folderId);
305305
});
306306
};
@@ -310,8 +310,8 @@ const updateFolder = (folderId: Folder["id"], values: Partial<Values>) => {
310310
if (pages === undefined) {
311311
return;
312312
}
313-
const folder = pages.folders.find((folder) => folder.id === folderId);
314-
if (folder === undefined) {
313+
const folder = getFolderById(pages, folderId);
314+
if (folder === undefined || folderId === pages.rootFolderId) {
315315
return;
316316
}
317317
if (values.name !== undefined) {
@@ -321,11 +321,7 @@ const updateFolder = (folderId: Folder["id"], values: Partial<Values>) => {
321321
folder.slug = values.slug;
322322
}
323323
if (values.parentFolderId !== undefined) {
324-
registerFolderChildMutable(
325-
pages.folders,
326-
folderId,
327-
values.parentFolderId
328-
);
324+
registerFolderChildMutable(pages, folderId, values.parentFolderId);
329325
}
330326
});
331327
};
@@ -342,12 +338,13 @@ export const FolderSettings = ({
342338
folderId: string;
343339
}) => {
344340
const pages = useStore($pages);
345-
const folder = pages?.folders.find(({ id }) => id === folderId);
341+
const folder =
342+
pages === undefined ? undefined : getFolderById(pages, folderId);
346343
const [unsavedValues, setUnsavedValues] = useState<Partial<Values>>({});
347344
const isDesignMode = useStore($isDesignMode);
348345

349346
const values: Values = {
350-
...(pages ? toFormValues(folderId, pages.folders) : fieldDefaultValues),
347+
...(pages ? toFormValues(folderId, pages) : fieldDefaultValues),
351348
...unsavedValues,
352349
};
353350

apps/builder/app/builder/features/pages/page-settings.stories.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
} from "@webstudio-is/design-system";
1010
import { $assets, $project } from "~/shared/sync/data-stores";
1111
import { createDefaultPages } from "@webstudio-is/project-build";
12-
import { isRootFolder } from "@webstudio-is/sdk";
1312

1413
export default {
1514
title: "Pages/Page Settings",
@@ -50,15 +49,15 @@ pages.meta = {
5049
faviconAssetId: "imageId",
5150
code: "code",
5251
};
53-
pages.pages.push({
52+
pages.pages.set("pageId", {
5453
id: "pageId",
5554
title: "Page title",
5655
path: "/page-path",
5756
name: "page-name",
5857
meta: {},
5958
rootInstanceId: "root-instance-id",
6059
});
61-
const rootFolder = pages.folders.find(isRootFolder);
60+
const rootFolder = pages.folders.get(pages.rootFolderId);
6261
rootFolder?.children.push("pageId");
6362

6463
$pages.set(pages);

0 commit comments

Comments
 (0)