@phis/ui 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/cms/phi-cms-layout-renderer.js +4 -3
- package/components/cms/phi-cms-page-render-scope.d.ts +4 -5
- package/components/cms/phi-cms-page-render-scope.js +43 -22
- package/components/cms/phi-cms-render-diagnostic-client.js +7 -3
- package/components/cms/phi-cms-render-error-boundary.js +2 -1
- package/components/controls/phi-bullet-list-control.js +31 -2
- package/components/controls/phi-ribbon-control.d.ts +29 -0
- package/components/controls/phi-ribbon-control.js +53 -0
- package/components/controls/phi-table-control.d.ts +3 -0
- package/components/controls/phi-table-control.js +13 -1
- package/components/controls/phi-tree-control.js +3 -3
- package/components/forms/shared-form-provider-registry.js +1 -4
- package/components/media/asset-collection-runtime.js +6 -16
- package/components/media/media-font-metrics.d.ts +3 -0
- package/components/media/media-font-metrics.js +43 -0
- package/components/media/phi-area-upload-widget.js +53 -97
- package/components/media/phi-image-preview-data.d.ts +13 -0
- package/components/media/phi-image-preview-data.js +184 -9
- package/components/media/phi-media-picker-binding.js +16 -13
- package/components/media/phi-media-upload.d.ts +15 -8
- package/components/media/phi-media-upload.js +18 -9
- package/components/media/phi-site-font-assets.js +7 -8
- package/components/overlays/phi-overlay-container-client.js +16 -1
- package/components/regions/presets/phi-settings-page-shell-tree.js +48 -1
- package/components/runtime/runtime-controller-materialization.js +12 -1
- package/components/state/scoped-state-store.js +20 -3
- package/components/tables/client/phi-table-binding.d.ts +2 -1
- package/components/tables/client/phi-table-binding.js +45 -21
- package/components/trees/client/phi-tree-binding.js +19 -11
- package/components/widgets/client/bullet-list-entries-editor.d.ts +26 -0
- package/components/widgets/client/bullet-list-entries-editor.js +103 -0
- package/components/widgets/config/choice-shared.js +12 -13
- package/components/widgets/config/command-buttons.d.ts +5 -1
- package/components/widgets/config/command-buttons.js +38 -81
- package/components/widgets/config/control-signal-config.d.ts +3 -1
- package/components/widgets/config/control-signal-config.js +19 -17
- package/components/widgets/config/image-source-parser.d.ts +1 -0
- package/components/widgets/config/image-source-parser.js +7 -8
- package/components/widgets/config/mask.d.ts +6 -1
- package/components/widgets/config/mask.js +24 -1
- package/components/widgets/config/parser-primitives.js +72 -0
- package/components/widgets/config/stack-tabs.d.ts +1 -1
- package/components/widgets/config/stack-tabs.js +2 -3
- package/components/widgets/config/strict-config-reader.d.ts +40 -0
- package/components/widgets/config/strict-config-reader.js +174 -0
- package/components/widgets/label-sets/effects.js +2 -0
- package/components/widgets/label-types/effects.d.ts +1 -0
- package/components/widgets/label-types/effects.js +1 -0
- package/components/widgets/navigation-descriptor-resolver.server.js +20 -8
- package/components/widgets/shared/bullet-list-vocabulary.d.ts +17 -1
- package/components/widgets/shared/bullet-list-vocabulary.js +19 -2
- package/components/widgets/shared/card-body-client.d.ts +16 -4
- package/components/widgets/shared/card-body-client.js +81 -24
- package/components/widgets/shared/card-vocabulary.d.ts +21 -4
- package/components/widgets/shared/card-vocabulary.js +28 -2
- package/components/widgets/signals/control-signal-capabilities.d.ts +0 -18
- package/components/widgets/signals/control-signal-capabilities.js +10 -22
- package/components/workspace/catalog-store.d.ts +4 -3
- package/components/workspace/catalog-store.js +6 -5
- package/gateway/dashboard-cards-route.js +1 -0
- package/gateway/internal-references.d.ts +6 -1
- package/gateway/internal-references.js +48 -23
- package/gateway/site-cms-write-validation.d.ts +9 -0
- package/gateway/site-cms-write-validation.js +78 -0
- package/gateway/site-proxy.js +19 -3
- package/helpers/renderable-block-serialization.js +1 -1
- package/next/config.d.mts +3 -0
- package/next/config.mjs +28 -1
- package/package.json +2 -2
- package/plugins/runtime/phi-slot-child-viewport-effects-observer.js +5 -1
- package/plugins/runtime-modules/accounting/presets.d.ts +9 -0
- package/plugins/runtime-modules/accounting/presets.js +37 -0
- package/plugins/runtime-modules/accounting/server.d.ts +1 -4
- package/plugins/runtime-modules/accounting/server.js +4 -7
- package/plugins/runtime-modules/app/presets.d.ts +18 -0
- package/plugins/runtime-modules/app/presets.js +67 -0
- package/plugins/runtime-modules/app/server.d.ts +1 -4
- package/plugins/runtime-modules/app/server.js +4 -7
- package/plugins/runtime-modules/asset/controller/runtime.js +2 -2
- package/plugins/runtime-modules/asset/services/collection.js +9 -1
- package/plugins/runtime-modules/asset/services/options.js +2 -2
- package/plugins/runtime-modules/builder/area-settings-answer.js +2 -1
- package/plugins/runtime-modules/builder/authoring-canvas.js +6 -6
- package/plugins/runtime-modules/builder/cards.js +3 -5
- package/plugins/runtime-modules/builder/clients/builder-region-overrides.js +3 -3
- package/plugins/runtime-modules/builder/clients/canvas-widget.js +15 -54
- package/plugins/runtime-modules/builder/clients/inspector-config-field.d.ts +4 -1
- package/plugins/runtime-modules/builder/clients/inspector-config-field.js +5 -34
- package/plugins/runtime-modules/builder/clients/inspector-link-target-field.js +1 -1
- package/plugins/runtime-modules/builder/clients/inspector-section-widget.js +8 -8
- package/plugins/runtime-modules/builder/clients/inspector-title.js +6 -6
- package/plugins/runtime-modules/builder/clients/layout-inspector.d.ts +1 -1
- package/plugins/runtime-modules/builder/clients/layout-inspector.js +11 -25
- package/plugins/runtime-modules/builder/clients/mode-switch.js +1 -1
- package/plugins/runtime-modules/builder/clients/pages-header.js +11 -11
- package/plugins/runtime-modules/builder/clients/pages-workspace.js +1 -1
- package/plugins/runtime-modules/builder/clients/region-visibility-fields.js +1 -1
- package/plugins/runtime-modules/builder/clients/runtime-module-authoring-boundary.js +1 -1
- package/plugins/runtime-modules/builder/clients/shells-workspace.js +15 -31
- package/plugins/runtime-modules/builder/clients/structure-canvas.js +1 -1
- package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.d.ts +26 -0
- package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.js +36 -0
- package/plugins/runtime-modules/builder/clients/widget-effects-editor.js +1 -1
- package/plugins/runtime-modules/builder/clients/widget-inspector.js +1 -0
- package/plugins/runtime-modules/builder/clients/workspace-scope-boundary.js +2 -2
- package/plugins/runtime-modules/builder/cms-instance-allocator.js +8 -28
- package/plugins/runtime-modules/builder/controller/client.d.ts +0 -15
- package/plugins/runtime-modules/builder/controller/definition.d.ts +0 -15
- package/plugins/runtime-modules/builder/controller/definition.js +0 -8
- package/plugins/runtime-modules/builder/controller/draft-command-controller.d.ts +1 -2
- package/plugins/runtime-modules/builder/controller/draft-command-controller.js +11 -30
- package/plugins/runtime-modules/builder/controller/draft-status-controller.js +15 -2
- package/plugins/runtime-modules/builder/controller/inspector-controller.d.ts +1 -2
- package/plugins/runtime-modules/builder/controller/inspector-controller.js +4 -7
- package/plugins/runtime-modules/builder/controller/page-controller.d.ts +1 -2
- package/plugins/runtime-modules/builder/controller/page-controller.js +16 -68
- package/plugins/runtime-modules/builder/controller/server-definition.d.ts +0 -15
- package/plugins/runtime-modules/builder/controller/signal-wiring-controller.d.ts +2 -5
- package/plugins/runtime-modules/builder/controller/signal-wiring-controller.js +6 -50
- package/plugins/runtime-modules/builder/controller/workspace-controller.d.ts +2 -3
- package/plugins/runtime-modules/builder/controller/workspace-controller.js +89 -153
- package/plugins/runtime-modules/builder/data-providers.d.ts +1 -0
- package/plugins/runtime-modules/builder/data-providers.js +1 -0
- package/plugins/runtime-modules/builder/definition.d.ts +1 -0
- package/plugins/runtime-modules/builder/developer-workspace-store.d.ts +64 -30
- package/plugins/runtime-modules/builder/developer-workspace-store.js +255 -61
- package/plugins/runtime-modules/builder/edit-scaffold-drawer.js +1 -1
- package/plugins/runtime-modules/builder/history.d.ts +3 -1
- package/plugins/runtime-modules/builder/options-providers.js +3 -2
- package/plugins/runtime-modules/builder/page-catalog-client.js +19 -7
- package/plugins/runtime-modules/builder/page-meta-form.js +1 -0
- package/plugins/runtime-modules/builder/page-references-provider.js +1 -1
- package/plugins/runtime-modules/builder/persistence.js +33 -69
- package/plugins/runtime-modules/builder/public-route-collisions.d.ts +2 -2
- package/plugins/runtime-modules/builder/public-route-collisions.js +6 -19
- package/plugins/runtime-modules/builder/render-root-node-preview.server.js +20 -3
- package/plugins/runtime-modules/builder/render-root-node-scaffold.js +3 -3
- package/plugins/runtime-modules/builder/runtime-module-selection.d.ts +2 -12
- package/plugins/runtime-modules/builder/runtime-module-selection.js +16 -42
- package/plugins/runtime-modules/builder/services/navigation-table.js +9 -15
- package/plugins/runtime-modules/builder/services/page-source-tree.js +8 -8
- package/plugins/runtime-modules/builder/services/runtime-modules-table.js +10 -10
- package/plugins/runtime-modules/builder/services/signal-routes-table.js +3 -3
- package/plugins/runtime-modules/builder/signal-route-selection.d.ts +1 -2
- package/plugins/runtime-modules/builder/signal-route-selection.js +2 -2
- package/plugins/runtime-modules/builder/signal-wiring-options.js +3 -2
- package/plugins/runtime-modules/builder/structure-dnd.js +8 -61
- package/plugins/runtime-modules/builder/trees/phi-default-builder-area-preset-tree.js +13 -10
- package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +12 -18
- package/plugins/runtime-modules/builder/workspace-catalog-actions.d.ts +55 -0
- package/plugins/runtime-modules/builder/workspace-catalog-actions.js +142 -0
- package/plugins/runtime-modules/client-manifests/common.js +1 -1
- package/plugins/runtime-modules/{runtime-calendar-adapters.js → core/calendar-adapters.js} +2 -2
- package/plugins/runtime-modules/{client-calendar-adapters/core.js → core/client-calendar-adapters.js} +1 -1
- package/plugins/runtime-modules/core/content-entries/table.js +1 -1
- package/plugins/runtime-modules/core/data-providers.d.ts +3 -0
- package/plugins/runtime-modules/core/data-providers.js +2 -1
- package/plugins/runtime-modules/core/definition.d.ts +3 -0
- package/plugins/runtime-modules/core/definition.js +1 -1
- package/plugins/runtime-modules/core/messaging/data-providers.d.ts +1 -0
- package/plugins/runtime-modules/core/messaging/data-providers.js +1 -0
- package/plugins/runtime-modules/core/messaging/thread-inbox-table.js +1 -1
- package/plugins/runtime-modules/core/server.js +1 -1
- package/plugins/runtime-modules/core/themes.d.ts +44 -0
- package/plugins/runtime-modules/core/themes.js +12 -0
- package/plugins/runtime-modules/core/widgets/card/collection-view-binding.js +25 -9
- package/plugins/runtime-modules/core/widgets/card/config.d.ts +296 -254
- package/plugins/runtime-modules/core/widgets/card/config.js +52 -3
- package/plugins/runtime-modules/core/widgets/card/editor.js +30 -3
- package/plugins/runtime-modules/core/widgets/card/server.d.ts +3 -0
- package/plugins/runtime-modules/core/widgets/card/server.js +31 -3
- package/plugins/runtime-modules/core/widgets/collection-view/asset-binding.js +7 -6
- package/plugins/runtime-modules/core/widgets/collection-view/config.js +9 -2
- package/plugins/runtime-modules/core/widgets/description/config.d.ts +1 -25
- package/plugins/runtime-modules/core/widgets/description/editor.js +4 -61
- package/plugins/runtime-modules/core/widgets/entry-list/config.d.ts +1 -25
- package/plugins/runtime-modules/core/widgets/gallery/config.d.ts +1 -25
- package/plugins/runtime-modules/core/widgets/image/config.js +2 -2
- package/plugins/runtime-modules/core/widgets/markdown/editor.js +2 -3
- package/plugins/runtime-modules/core/widgets/result/config.d.ts +4 -25
- package/plugins/runtime-modules/core/widgets/result/config.js +2 -0
- package/plugins/runtime-modules/core/widgets/result/server.js +25 -19
- package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +1 -25
- package/plugins/runtime-modules/core/widgets/slot-upload/client.js +11 -2
- package/plugins/runtime-modules/core/widgets/table/client.js +8 -4
- package/plugins/runtime-modules/core/widgets/table/config.d.ts +3 -83
- package/plugins/runtime-modules/core/widgets/table/config.js +302 -452
- package/plugins/runtime-modules/core/widgets/tree/config.js +5 -2
- package/plugins/runtime-modules/dashboard/card-rows.d.ts +5 -0
- package/plugins/runtime-modules/dashboard/card-rows.js +59 -0
- package/plugins/runtime-modules/dashboard/clients/dashboard-card-view.js +4 -6
- package/plugins/runtime-modules/dashboard/services/collection.js +17 -7
- package/plugins/runtime-modules/groups/data-providers.d.ts +2 -0
- package/plugins/runtime-modules/groups/data-providers.js +3 -3
- package/plugins/runtime-modules/groups/definition.d.ts +2 -0
- package/plugins/runtime-modules/localization/data-providers.d.ts +3 -0
- package/plugins/runtime-modules/localization/data-providers.js +2 -0
- package/plugins/runtime-modules/localization/definition.d.ts +3 -0
- package/plugins/runtime-modules/localization/services/table.js +3 -7
- package/plugins/runtime-modules/observability/data-providers.d.ts +1 -0
- package/plugins/runtime-modules/observability/data-providers.js +1 -0
- package/plugins/runtime-modules/observability/definition.d.ts +1 -0
- package/plugins/runtime-modules/observability/module.d.ts +1 -0
- package/plugins/runtime-modules/observability/services/table.js +1 -1
- package/plugins/runtime-modules/phi-default-site-area-preset-tree.js +2 -105
- package/plugins/runtime-modules/public/presets.d.ts +115 -0
- package/plugins/runtime-modules/{area-base-presets.js → public/presets.js} +19 -119
- package/plugins/runtime-modules/public/server.d.ts +1 -4
- package/plugins/runtime-modules/public/server.js +4 -7
- package/plugins/runtime-modules/public/trees/phi-default-pub-error-page-tree.js +7 -8
- package/plugins/runtime-modules/public-base-page-references.d.ts +1 -1
- package/plugins/runtime-modules/public-base-page-references.js +1 -1
- package/plugins/runtime-modules/revisions/controller/client.js +11 -11
- package/plugins/runtime-modules/revisions/services/table.js +3 -3
- package/plugins/runtime-modules/theme/trees/phi-default-builder-theme-page-tree.js +22 -0
- package/plugins/runtime-modules/theme/widgets/brand-controls/client.d.ts +2 -1
- package/plugins/runtime-modules/theme/widgets/brand-controls/client.js +93 -58
- package/plugins/runtime-modules/theme/widgets/brand-controls/config.d.ts +2 -1
- package/plugins/runtime-modules/theme/widgets/brand-controls/config.js +23 -22
- package/plugins/runtime-modules/theme/widgets/brand-controls/plugin.js +1 -1
- package/plugins/runtime-modules/theme-descriptors.js +1 -1
- package/plugins/runtime-modules/user-management/data-providers.d.ts +2 -0
- package/plugins/runtime-modules/user-management/data-providers.js +1 -0
- package/plugins/runtime-modules/user-management/definition.d.ts +2 -0
- package/styles/control-shape.css +11 -11
- package/styles/controls.css +3 -3
- package/styles/layout.css +16 -7
- package/types/cms-config.js +142 -185
- package/types/cms-plugins.d.ts +4 -11
- package/types/core-widget-placements.d.ts +14 -3
- package/types/dashboard-cards.d.ts +9 -0
- package/types/media.d.ts +0 -3
- package/types/renderable-block.d.ts +6 -1
- package/types/table-widget.d.ts +9 -0
- package/types/table-widget.js +20 -0
- package/types.d.ts +1 -1
- package/widget-config.d.ts +2 -0
- package/widget-config.js +6 -0
- package/plugins/runtime-modules/area-base-presets.d.ts +0 -139
- /package/plugins/runtime-modules/{runtime-calendar-adapters.d.ts → core/calendar-adapters.d.ts} +0 -0
- /package/plugins/runtime-modules/{client-calendar-adapters/core.d.ts → core/client-calendar-adapters.d.ts} +0 -0
|
@@ -13,8 +13,10 @@ import { resolvePhiCmsRegionType } from "../../../helpers/cms-region-keys";
|
|
|
13
13
|
import { resolvePhiAuthUiProviderModuleId, resolvePhiDeclaredMediaSpaces, resolvePhiDeclaredSeeds, resolvePhiDeclaredThreadKinds, resolvePhiRuntimeModuleIdsForArea, } from "../../../plugins/runtime-modules/settings";
|
|
14
14
|
import { isPhiRuntimeAreaBaseModuleId } from "../../../plugins/runtime-modules/area-definitions";
|
|
15
15
|
import { createPhiBuilderDraftAllocationKey } from "./draft-allocation-key";
|
|
16
|
-
import {
|
|
16
|
+
import { clearPhiBuilderDraftAllocation, storePhiBuilderDraftAllocation, commitPhiDeveloperBuilderAreaConfig, readPhiBuilderEffectiveAreaRootRoute, readPhiBuilderEffectiveAreaMeta, } from "./developer-workspace-store";
|
|
17
17
|
import { resolvePhiBuilderActivePageCatalog, resolvePhiBuilderPageDefaultFlags, resolvePhiBuilderPagePresetSource, } from "../../../helpers/cms-page-catalog";
|
|
18
|
+
import { isPhiRuntimeModuleId } from "../../../constants/module-identity";
|
|
19
|
+
import { createPhiResponseReader, requirePhiField } from "../../../components/widgets/config/strict-config-reader";
|
|
18
20
|
import { PHI_AREA_CONFIG_MODULES_NAMESPACE, PHI_AREA_CONFIG_SHELL_NAMESPACE, PHI_AREA_PUBLIC_ROUTE_PATHS_KEY, PHI_AREA_ROOT_ROUTE_KEY, PHI_AREA_META_KEY, normalizePhiAreaPublicRoutePaths, } from "../../../helpers/cms-area-config";
|
|
19
21
|
/**
|
|
20
22
|
* A save that was refused because there is nothing to patch yet -- an Area with no stored revision at
|
|
@@ -194,22 +196,33 @@ async function postCmsDraft(path, payload) {
|
|
|
194
196
|
const addressRefused = body?.error === "path_collision" || body?.error === "path_nested";
|
|
195
197
|
throw response.status === 409 && !addressRefused ? new CmsDraftConflictError(message) : new Error(message);
|
|
196
198
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
199
|
+
return readPhiDraftAllocation(body, "The CMS draft save");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* What a Draft save or read answers about the Draft it now stands on: its revision, version and node
|
|
203
|
+
* sequence, all positive, and the preset it came from -- stated as `null` when it came from none, never
|
|
204
|
+
* left out. Read field by field; each was checked before and then cast, and the preset source was not
|
|
205
|
+
* checked at all.
|
|
206
|
+
*/
|
|
207
|
+
function readPhiDraftAllocation(body, source) {
|
|
208
|
+
const reader = createPhiResponseReader(body, source);
|
|
209
|
+
const positive = (key) => {
|
|
210
|
+
const value = requirePhiField(reader, key, "a positive whole number", reader.integer);
|
|
211
|
+
return value >= 1 ? value : reader.fail(key, "a positive whole number");
|
|
212
|
+
};
|
|
213
|
+
if (!Object.prototype.hasOwnProperty.call(reader.record, "sourcePreset")) {
|
|
214
|
+
reader.fail("sourcePreset", "a preset source or null");
|
|
215
|
+
}
|
|
216
|
+
const sourcePreset = reader.object("sourcePreset", (preset) => ({
|
|
217
|
+
ownerModuleId: requirePhiField(preset, "ownerModuleId", "a Module id", (key) => preset.value(key, "a Module id", (value) => (isPhiRuntimeModuleId(value) ? value : undefined))),
|
|
218
|
+
presetKey: requirePhiField(preset, "presetKey", "a text", preset.string),
|
|
219
|
+
sourcePresetVersion: requirePhiField(preset, "sourcePresetVersion", "a whole number", preset.integer),
|
|
220
|
+
})) ?? null;
|
|
208
221
|
return {
|
|
209
|
-
revisionId:
|
|
210
|
-
version:
|
|
211
|
-
nextNodeSequence:
|
|
212
|
-
sourcePreset
|
|
222
|
+
revisionId: positive("revisionId"),
|
|
223
|
+
version: positive("version"),
|
|
224
|
+
nextNodeSequence: positive("nextNodeSequence"),
|
|
225
|
+
sourcePreset,
|
|
213
226
|
};
|
|
214
227
|
}
|
|
215
228
|
async function postCmsAction(path, payload) {
|
|
@@ -247,23 +260,7 @@ async function getCmsDraft(path, payload) {
|
|
|
247
260
|
const detail = body?.details?.length ? ` ${body.details.join(" ")}` : "";
|
|
248
261
|
throw new Error(`${body?.error ?? "CMS draft read failed."}${detail}`);
|
|
249
262
|
}
|
|
250
|
-
|
|
251
|
-
body?.revisionId < 1 ||
|
|
252
|
-
!Number.isSafeInteger(body?.version) ||
|
|
253
|
-
body?.version < 1 ||
|
|
254
|
-
!Number.isSafeInteger(body?.nextNodeSequence) ||
|
|
255
|
-
body?.nextNodeSequence < 1) {
|
|
256
|
-
throw new Error("CMS draft read returned invalid Draft allocation metadata.");
|
|
257
|
-
}
|
|
258
|
-
if (!Object.prototype.hasOwnProperty.call(body, "sourcePreset")) {
|
|
259
|
-
throw new Error("CMS draft read returned no preset source metadata.");
|
|
260
|
-
}
|
|
261
|
-
return {
|
|
262
|
-
revisionId: body.revisionId,
|
|
263
|
-
version: body.version,
|
|
264
|
-
nextNodeSequence: body.nextNodeSequence,
|
|
265
|
-
sourcePreset: body.sourcePreset ?? null,
|
|
266
|
-
};
|
|
263
|
+
return readPhiDraftAllocation(body, "The CMS draft read");
|
|
267
264
|
}
|
|
268
265
|
/**
|
|
269
266
|
* The href a preview opens, with no locale in it.
|
|
@@ -294,37 +291,11 @@ export function buildPhiBuilderLiveHref(area, pageKey, pages, workspaceKind) {
|
|
|
294
291
|
return `${url.pathname}${url.search}${url.hash}`;
|
|
295
292
|
}
|
|
296
293
|
function storePhiDeveloperBuilderDraftAllocation(allocationKey, saved) {
|
|
297
|
-
|
|
298
|
-
const currentAllocation = current.draftAllocations[allocationKey];
|
|
299
|
-
const nextNodeSequence = currentAllocation?.revisionId === saved.revisionId
|
|
300
|
-
? Math.max(currentAllocation.nextNodeSequence, saved.nextNodeSequence)
|
|
301
|
-
: saved.nextNodeSequence;
|
|
302
|
-
return {
|
|
303
|
-
...current,
|
|
304
|
-
draftAllocations: {
|
|
305
|
-
...current.draftAllocations,
|
|
306
|
-
[allocationKey]: {
|
|
307
|
-
revisionId: saved.revisionId,
|
|
308
|
-
version: currentAllocation?.revisionId === saved.revisionId
|
|
309
|
-
? Math.max(currentAllocation.version, saved.version)
|
|
310
|
-
: saved.version,
|
|
311
|
-
nextNodeSequence,
|
|
312
|
-
sourcePreset: saved.sourcePreset,
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
};
|
|
316
|
-
});
|
|
294
|
+
storePhiBuilderDraftAllocation(allocationKey, saved);
|
|
317
295
|
}
|
|
318
296
|
export function clearPhiDeveloperBuilderDraftAllocation(input) {
|
|
319
297
|
const allocationKey = createPhiBuilderDraftAllocationKey(input.area, input.pageKey, input.workspaceKind === "pages" ? "page" : "area");
|
|
320
|
-
|
|
321
|
-
if (!current.draftAllocations[allocationKey]) {
|
|
322
|
-
return current;
|
|
323
|
-
}
|
|
324
|
-
const draftAllocations = { ...current.draftAllocations };
|
|
325
|
-
delete draftAllocations[allocationKey];
|
|
326
|
-
return { ...current, draftAllocations };
|
|
327
|
-
});
|
|
298
|
+
clearPhiBuilderDraftAllocation(allocationKey);
|
|
328
299
|
}
|
|
329
300
|
export async function getPhiDeveloperBuilderDraftAllocation(input) {
|
|
330
301
|
const cmsArea = resolvePhiBuilderAreaAsCmsArea(input.area);
|
|
@@ -368,14 +339,7 @@ export async function getPhiDeveloperBuilderModulesDraftAllocation(input) {
|
|
|
368
339
|
}
|
|
369
340
|
function clearPhiDeveloperBuilderModulesDraftAllocation(area) {
|
|
370
341
|
const allocationKey = createPhiBuilderDraftAllocationKey(area, area, "modules");
|
|
371
|
-
|
|
372
|
-
if (!current.draftAllocations[allocationKey]) {
|
|
373
|
-
return current;
|
|
374
|
-
}
|
|
375
|
-
const draftAllocations = { ...current.draftAllocations };
|
|
376
|
-
delete draftAllocations[allocationKey];
|
|
377
|
-
return { ...current, draftAllocations };
|
|
378
|
-
});
|
|
342
|
+
clearPhiBuilderDraftAllocation(allocationKey);
|
|
379
343
|
}
|
|
380
344
|
/**
|
|
381
345
|
* What a tree tells its Controllers, as it arrived with the workspace. The Builder edits none of it but
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PhiRuntimeModuleId } from "../../../types";
|
|
2
|
-
import type { PhiBuilderPublicRouteCollisionAnswer, PhiBuilderPublicRouteCollisionRequest,
|
|
2
|
+
import type { PhiBuilderPublicRouteCollisionAnswer, PhiBuilderPublicRouteCollisionRequest, PhiDeveloperBuilderWorkspaceState } from "./developer-workspace-types";
|
|
3
3
|
/**
|
|
4
4
|
* The question to put to the Builder before a Module may be enabled for Public.
|
|
5
5
|
*
|
|
@@ -22,4 +22,4 @@ export declare function findPhiBuilderPublicRouteAnswerProblem(state: Pick<PhiDe
|
|
|
22
22
|
* alone, including those of Modules that are switched off -- an assignment outlives its Module being
|
|
23
23
|
* disabled, which is why nobody is asked the same question twice.
|
|
24
24
|
*/
|
|
25
|
-
export declare function applyPhiBuilderPublicRouteAssignments(
|
|
25
|
+
export declare function applyPhiBuilderPublicRouteAssignments(request: Pick<PhiBuilderPublicRouteCollisionRequest, "moduleId" | "answers">): void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { buildPhiRuntimeModulePackageRoutePrefix } from "../../../helpers/runtime-module-route-path";
|
|
2
2
|
import { buildPhiPublicRouteAddressMap, findPhiPublicRoutePathCollisions, } from "../../../helpers/public-route-claims";
|
|
3
|
-
import { isPhiAssignablePublicRoutePath,
|
|
4
|
-
import {
|
|
5
|
-
import { markPhiBuilderModuleAreasDirty } from "./
|
|
3
|
+
import { isPhiAssignablePublicRoutePath, } from "../../../helpers/cms-area-config";
|
|
4
|
+
import { assignPhiWorkspacePublicRoutePaths } from "./workspace-catalog-actions";
|
|
5
|
+
import { markPhiBuilderModuleAreasDirty } from "./developer-workspace-store";
|
|
6
6
|
/**
|
|
7
7
|
* Which Public addresses a Site Page already occupies.
|
|
8
8
|
*
|
|
@@ -121,21 +121,8 @@ export function findPhiBuilderPublicRouteAnswerProblem(state, request) {
|
|
|
121
121
|
* alone, including those of Modules that are switched off -- an assignment outlives its Module being
|
|
122
122
|
* disabled, which is why nobody is asked the same question twice.
|
|
123
123
|
*/
|
|
124
|
-
export function applyPhiBuilderPublicRouteAssignments(
|
|
124
|
+
export function applyPhiBuilderPublicRouteAssignments(request) {
|
|
125
125
|
const answered = new Map(request.answers.map((answer) => [answer.presetKey, answer.path.trim()]));
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
...catalog,
|
|
130
|
-
publicRoutePaths: normalizePhiAreaPublicRoutePaths([
|
|
131
|
-
...kept,
|
|
132
|
-
...[...answered.entries()].map(([presetKey, path]) => ({
|
|
133
|
-
ownerModuleId: request.moduleId,
|
|
134
|
-
presetKey,
|
|
135
|
-
path,
|
|
136
|
-
})),
|
|
137
|
-
]),
|
|
138
|
-
};
|
|
139
|
-
});
|
|
140
|
-
markPhiBuilderModuleAreasDirty(["public"], scopeKey);
|
|
126
|
+
assignPhiWorkspacePublicRoutePaths(request.moduleId, answered);
|
|
127
|
+
markPhiBuilderModuleAreasDirty(["public"]);
|
|
141
128
|
}
|
|
@@ -46,12 +46,29 @@ function mergePreviewTreeNodes(tree, extraPreviewNodes) {
|
|
|
46
46
|
function resolveRootNodeFromPreviewDraft(draft) {
|
|
47
47
|
return draft?.rootNode ? readPhiBuilderRootNodeDraft(draft.rootNode) : null;
|
|
48
48
|
}
|
|
49
|
+
/*
|
|
50
|
+
* The nodes of every Region in one preview snapshot, built once per snapshot.
|
|
51
|
+
*
|
|
52
|
+
* Each of the ten Region previews needs all of them -- a signal route may name a node in another Region
|
|
53
|
+
* -- and each used to build every Region's tree again: about a hundred tree builds for one preview
|
|
54
|
+
* request. A snapshot is one parsed object per request and nothing here writes the result, so it is kept
|
|
55
|
+
* by that object and dropped with it.
|
|
56
|
+
*/
|
|
57
|
+
const previewSnapshotNodes = new WeakMap();
|
|
49
58
|
function buildPreviewSnapshotNodes(snapshot) {
|
|
50
|
-
const layoutNodes = [];
|
|
51
|
-
const contentWidgets = [];
|
|
52
59
|
if (!snapshot) {
|
|
53
|
-
return { layoutNodes, contentWidgets };
|
|
60
|
+
return { layoutNodes: [], contentWidgets: [] };
|
|
61
|
+
}
|
|
62
|
+
let nodes = previewSnapshotNodes.get(snapshot);
|
|
63
|
+
if (!nodes) {
|
|
64
|
+
nodes = collectPreviewSnapshotNodes(snapshot);
|
|
65
|
+
previewSnapshotNodes.set(snapshot, nodes);
|
|
54
66
|
}
|
|
67
|
+
return nodes;
|
|
68
|
+
}
|
|
69
|
+
function collectPreviewSnapshotNodes(snapshot) {
|
|
70
|
+
const layoutNodes = [];
|
|
71
|
+
const contentWidgets = [];
|
|
55
72
|
for (const [draftKey, draft] of Object.entries(snapshot.regionDrafts)) {
|
|
56
73
|
const regionKey = draftKey.split(":").at(-1);
|
|
57
74
|
const rootNode = resolveRootNodeFromPreviewDraft(draft);
|
|
@@ -265,7 +265,7 @@ function findPhiWidgetAuthoringTextTarget(container, clientX, clientY) {
|
|
|
265
265
|
}
|
|
266
266
|
function PhiWidgetEffectsPreviewFrame({ kind, slotSizePolicy, surfacePolicy, blockId, regionKey, config: committedConfig, title, scaffoldLabel, editorInteraction = "inert", onSelect, dropTarget, tools, style, children, }) {
|
|
267
267
|
const { token } = usePhiConfig();
|
|
268
|
-
const selected = usePhiDeveloperBuilderStateValue(
|
|
268
|
+
const selected = usePhiDeveloperBuilderStateValue((state) => blockId != null &&
|
|
269
269
|
regionKey != null &&
|
|
270
270
|
state.selectedRootRegionKey === regionKey &&
|
|
271
271
|
state.nodeKind === "widget" &&
|
|
@@ -278,7 +278,7 @@ function PhiWidgetEffectsPreviewFrame({ kind, slotSizePolicy, surfacePolicy, blo
|
|
|
278
278
|
* still under the finger; the draft learns it when Save is pressed. Overlaying the whole `effects`
|
|
279
279
|
* rather than one property keeps this the editor's picture and not a second opinion about it.
|
|
280
280
|
*/
|
|
281
|
-
const effectsPreview = usePhiDeveloperBuilderStateValue(
|
|
281
|
+
const effectsPreview = usePhiDeveloperBuilderStateValue((state) => readPhiDeveloperBuilderEffectsPreview(state, "widget", blockId ?? null));
|
|
282
282
|
const config = effectsPreview
|
|
283
283
|
? { ...committedConfig, effects: effectsPreview }
|
|
284
284
|
: committedConfig;
|
|
@@ -493,7 +493,7 @@ function PhiWidgetEffectsPreviewFrame({ kind, slotSizePolicy, surfacePolicy, blo
|
|
|
493
493
|
}
|
|
494
494
|
function PhiLayoutEffectsPreviewFrame({ kind, slotSizePolicy, blockId, config: committedConfig, explicitInlineSize, explicitBlockSize, children, }) {
|
|
495
495
|
// The same live picture the Widget frame draws, for the Layout whose own toolbar opened the editor.
|
|
496
|
-
const effectsPreview = usePhiDeveloperBuilderStateValue(
|
|
496
|
+
const effectsPreview = usePhiDeveloperBuilderStateValue((state) => readPhiDeveloperBuilderEffectsPreview(state, "layout", blockId ?? null));
|
|
497
497
|
const config = effectsPreview
|
|
498
498
|
? { ...committedConfig, effects: effectsPreview }
|
|
499
499
|
: committedConfig;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { PhiRuntimeModuleId } from "../../../types";
|
|
2
1
|
import type { PhiDeveloperBuilderArea } from "./developer-workspace-types";
|
|
3
|
-
export declare function areRuntimeModuleIdsEqual(left: readonly PhiRuntimeModuleId[] | null | undefined, right: readonly PhiRuntimeModuleId[] | null | undefined): boolean;
|
|
4
2
|
/**
|
|
5
3
|
* Applies a new Module selection to one or more Areas: validates each Area's list, patches the
|
|
6
4
|
* catalog, and records the whole gesture as ONE history entry -- the one place all of this happens,
|
|
@@ -15,13 +13,5 @@ export declare function areRuntimeModuleIdsEqual(left: readonly PhiRuntimeModule
|
|
|
15
13
|
export declare function applyPhiBuilderRuntimeModuleSelectionChanges(changes: ReadonlyArray<{
|
|
16
14
|
area: PhiDeveloperBuilderArea;
|
|
17
15
|
selectedIds: readonly string[];
|
|
18
|
-
}
|
|
19
|
-
export declare function applyPhiBuilderRuntimeModuleSelectionChange(area: PhiDeveloperBuilderArea, selectedIds: readonly string[]
|
|
20
|
-
/**
|
|
21
|
-
* The Areas whose Module selection has unsaved edits, kept as Builder tool state so the Modules
|
|
22
|
-
* workspace commands know which Areas a site-wide save or publish has to reach. Undo does not clear
|
|
23
|
-
* an Area from here -- a save of an unchanged selection is a no-op draft, while a missed Area would
|
|
24
|
-
* silently publish stale state.
|
|
25
|
-
*/
|
|
26
|
-
export declare function markPhiBuilderModuleAreasDirty(areas: readonly PhiDeveloperBuilderArea[], defaultArea: PhiDeveloperBuilderArea): void;
|
|
27
|
-
export declare function clearPhiBuilderModuleAreasDirty(defaultArea: PhiDeveloperBuilderArea): void;
|
|
16
|
+
}>): void;
|
|
17
|
+
export declare function applyPhiBuilderRuntimeModuleSelectionChange(area: PhiDeveloperBuilderArea, selectedIds: readonly string[]): `${string}/${string}`[];
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { resolvePhiBuilderAreaAsCmsArea } from "../../../constants/cms-areas";
|
|
2
2
|
import { isPhiRuntimeAreaBaseModuleId, resolvePhiRuntimeAreaDefinition, } from "../area-definitions";
|
|
3
3
|
import { assertPhiRuntimeModuleIdsAllowedForArea } from "../settings";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { getPhiDeveloperBuilderStateSnapshot, markPhiBuilderModuleAreasDirty } from "./developer-workspace-store";
|
|
5
|
+
import { setPhiWorkspaceModuleSelection } from "./workspace-catalog-actions";
|
|
6
6
|
import { capturePhiBuilderModulesHistoryState, createPhiBuilderHistoryContext, phiBuilderHistory, } from "./history";
|
|
7
7
|
function serializeRuntimeModuleIds(moduleIds) {
|
|
8
8
|
return JSON.stringify(moduleIds ?? []);
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
function areRuntimeModuleIdsEqual(left, right) {
|
|
11
11
|
return serializeRuntimeModuleIds(left) === serializeRuntimeModuleIds(right);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -52,8 +52,8 @@ function normalizeRuntimeModuleSelection(selectedIds, area, definitions) {
|
|
|
52
52
|
* switched on in one Area and off in another is named once; the step's sentence says that the
|
|
53
53
|
* selection of these changed, not which way.
|
|
54
54
|
*/
|
|
55
|
-
function describeModuleSelectionChange(effective, before
|
|
56
|
-
const definitions = getPhiDeveloperBuilderStateSnapshot(
|
|
55
|
+
function describeModuleSelectionChange(effective, before) {
|
|
56
|
+
const definitions = getPhiDeveloperBuilderStateSnapshot().runtimeModuleDefinitions;
|
|
57
57
|
const titleById = new Map(definitions.map((definition) => [definition.moduleId, definition.title]));
|
|
58
58
|
const changed = new Set();
|
|
59
59
|
for (const { area, moduleIds } of effective) {
|
|
@@ -79,8 +79,8 @@ function describeModuleSelectionChange(effective, before, defaultArea) {
|
|
|
79
79
|
* the switch exists to avoid. Areas whose normalized list already matches what is live are dropped;
|
|
80
80
|
* if nothing remains, nothing is recorded.
|
|
81
81
|
*/
|
|
82
|
-
export function applyPhiBuilderRuntimeModuleSelectionChanges(changes
|
|
83
|
-
const current = getPhiDeveloperBuilderStateSnapshot(
|
|
82
|
+
export function applyPhiBuilderRuntimeModuleSelectionChanges(changes) {
|
|
83
|
+
const current = getPhiDeveloperBuilderStateSnapshot();
|
|
84
84
|
const effective = [];
|
|
85
85
|
for (const change of changes) {
|
|
86
86
|
const currentModuleIds = current.runtimeModuleIdsByArea?.[change.area] ?? [];
|
|
@@ -93,42 +93,16 @@ export function applyPhiBuilderRuntimeModuleSelectionChanges(changes, defaultAre
|
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
95
|
const changedAreas = effective.map(({ area }) => area);
|
|
96
|
-
const historyBefore = capturePhiBuilderModulesHistoryState(getPhiDeveloperBuilderStateSnapshot(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
...Object.fromEntries(effective.map(({ area, moduleIds }) => [area, moduleIds])),
|
|
102
|
-
},
|
|
103
|
-
}));
|
|
104
|
-
markPhiBuilderModuleAreasDirty(changedAreas, defaultArea);
|
|
105
|
-
phiBuilderHistory.record(createPhiBuilderHistoryContext({ workspace: "modules", area: defaultArea }), {
|
|
106
|
-
action: { key: "changeModules", subject: describeModuleSelectionChange(effective, historyBefore, defaultArea) },
|
|
96
|
+
const historyBefore = capturePhiBuilderModulesHistoryState(getPhiDeveloperBuilderStateSnapshot(), changedAreas);
|
|
97
|
+
setPhiWorkspaceModuleSelection(Object.fromEntries(effective.map(({ area, moduleIds }) => [area, moduleIds])));
|
|
98
|
+
markPhiBuilderModuleAreasDirty(changedAreas);
|
|
99
|
+
phiBuilderHistory.record(createPhiBuilderHistoryContext({ workspace: "modules" }), {
|
|
100
|
+
action: { key: "changeModules", subject: describeModuleSelectionChange(effective, historyBefore) },
|
|
107
101
|
before: historyBefore,
|
|
108
|
-
after: capturePhiBuilderModulesHistoryState(getPhiDeveloperBuilderStateSnapshot(
|
|
102
|
+
after: capturePhiBuilderModulesHistoryState(getPhiDeveloperBuilderStateSnapshot(), changedAreas),
|
|
109
103
|
});
|
|
110
104
|
}
|
|
111
|
-
export function applyPhiBuilderRuntimeModuleSelectionChange(area, selectedIds
|
|
112
|
-
applyPhiBuilderRuntimeModuleSelectionChanges([{ area, selectedIds }]
|
|
113
|
-
return getPhiDeveloperBuilderStateSnapshot(
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* The Areas whose Module selection has unsaved edits, kept as Builder tool state so the Modules
|
|
117
|
-
* workspace commands know which Areas a site-wide save or publish has to reach. Undo does not clear
|
|
118
|
-
* an Area from here -- a save of an unchanged selection is a no-op draft, while a missed Area would
|
|
119
|
-
* silently publish stale state.
|
|
120
|
-
*/
|
|
121
|
-
export function markPhiBuilderModuleAreasDirty(areas, defaultArea) {
|
|
122
|
-
builderWorkspaceStore.patch(defaultArea, (tool) => {
|
|
123
|
-
const next = new Set(tool.modulesDirtyAreas ?? []);
|
|
124
|
-
for (const area of areas) {
|
|
125
|
-
next.add(area);
|
|
126
|
-
}
|
|
127
|
-
return next.size === (tool.modulesDirtyAreas ?? []).length
|
|
128
|
-
? tool
|
|
129
|
-
: { ...tool, modulesDirtyAreas: [...next] };
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
export function clearPhiBuilderModuleAreasDirty(defaultArea) {
|
|
133
|
-
builderWorkspaceStore.patch(defaultArea, (tool) => (tool.modulesDirtyAreas?.length ?? 0) === 0 ? tool : { ...tool, modulesDirtyAreas: [] });
|
|
105
|
+
export function applyPhiBuilderRuntimeModuleSelectionChange(area, selectedIds) {
|
|
106
|
+
applyPhiBuilderRuntimeModuleSelectionChanges([{ area, selectedIds }]);
|
|
107
|
+
return getPhiDeveloperBuilderStateSnapshot().runtimeModuleIdsByArea?.[area] ?? [];
|
|
134
108
|
}
|
|
@@ -23,7 +23,7 @@ import { PHI_BUILDER_RUNTIME_DATA_PROVIDER_DESCRIPTORS } from "../../../../plugi
|
|
|
23
23
|
import { isPhiExternalHref } from "../../../../helpers/external-href";
|
|
24
24
|
import { createPhiPageUri, readPhiInternalReference } from "../../../../types/references";
|
|
25
25
|
import { buildPhiBuilderNavigationContainerFromCatalogFolder, findPhiBuilderCatalogNode, } from "../navigation-folder-drop";
|
|
26
|
-
import {
|
|
26
|
+
import { addPhiWorkspaceNavigationSurface } from "../workspace-catalog-actions";
|
|
27
27
|
/**
|
|
28
28
|
* The "404" choice of the Path cell. On a container it is how a folder address is cleared, and what a
|
|
29
29
|
* choice that is no longer a direct child reads as; on a page link it is what a deleted target reads as,
|
|
@@ -196,11 +196,11 @@ export function PhiBuilderNavigationTableProviderClient({ children }) {
|
|
|
196
196
|
* Inspector and every slider step -- each one a reload of the navigation. The functions below read the
|
|
197
197
|
* state snapshot when they run; these subscriptions only say when a change is worth a new registration.
|
|
198
198
|
*/
|
|
199
|
-
const area = usePhiDeveloperBuilderStateValue(
|
|
200
|
-
const customPages = usePhiDeveloperBuilderStateValue(
|
|
201
|
-
const modulePresetPagesByArea = usePhiDeveloperBuilderStateValue(
|
|
202
|
-
const persistedPageCatalogByArea = usePhiDeveloperBuilderStateValue(
|
|
203
|
-
const navigationSurfacesByArea = usePhiDeveloperBuilderStateValue(
|
|
199
|
+
const area = usePhiDeveloperBuilderStateValue((state) => state.area);
|
|
200
|
+
const customPages = usePhiDeveloperBuilderStateValue((state) => state.customPages);
|
|
201
|
+
const modulePresetPagesByArea = usePhiDeveloperBuilderStateValue((state) => state.modulePresetPagesByArea);
|
|
202
|
+
const persistedPageCatalogByArea = usePhiDeveloperBuilderStateValue((state) => state.persistedPageCatalogByArea);
|
|
203
|
+
const navigationSurfacesByArea = usePhiDeveloperBuilderStateValue((state) => state.navigationSurfacesByArea);
|
|
204
204
|
const activeNavigationKey = resolvePhiBuilderNavigationWidgetNavKey(undefined, navigationSearchValue, area);
|
|
205
205
|
const activeNavigationDraft = usePhiBuilderNavigationDraft(activeNavigationKey);
|
|
206
206
|
const loaded = useRef(new Map());
|
|
@@ -209,7 +209,7 @@ export function PhiBuilderNavigationTableProviderClient({ children }) {
|
|
|
209
209
|
const initializedHistoryScopes = useRef(new Set());
|
|
210
210
|
const registration = useMemo(() => {
|
|
211
211
|
const resolveScope = (params) => {
|
|
212
|
-
const state = getPhiDeveloperBuilderStateSnapshot(
|
|
212
|
+
const state = getPhiDeveloperBuilderStateSnapshot();
|
|
213
213
|
const requestedNavKey = typeof params?.navKey === "string" ? params.navKey : navigationSearchValue;
|
|
214
214
|
const navKey = resolvePhiBuilderNavigationWidgetNavKey(undefined, requestedNavKey ?? null, state.area);
|
|
215
215
|
const surfaces = state.navigationSurfacesByArea[state.area];
|
|
@@ -345,7 +345,7 @@ export function PhiBuilderNavigationTableProviderClient({ children }) {
|
|
|
345
345
|
if (!localKey) {
|
|
346
346
|
return { status: "rejected", invalidation: "none", errorCode: "invalid-navigation-key", message: "Navigation key is invalid." };
|
|
347
347
|
}
|
|
348
|
-
const state = getPhiDeveloperBuilderStateSnapshot(
|
|
348
|
+
const state = getPhiDeveloperBuilderStateSnapshot();
|
|
349
349
|
const cmsArea = resolvePhiBuilderAreaAsCmsArea(state.area);
|
|
350
350
|
const navKey = formatPhiBuilderNavigationScopeKey(cmsArea, localKey);
|
|
351
351
|
const surfaces = state.navigationSurfacesByArea[state.area] ?? [];
|
|
@@ -353,13 +353,7 @@ export function PhiBuilderNavigationTableProviderClient({ children }) {
|
|
|
353
353
|
return { status: "rejected", invalidation: "none", errorCode: "navigation-exists", message: "Navigation already exists." };
|
|
354
354
|
}
|
|
355
355
|
const surface = createPhiBuilderCustomNavigationSurface(navKey, localKey);
|
|
356
|
-
|
|
357
|
-
...current,
|
|
358
|
-
navigationSurfacesByArea: {
|
|
359
|
-
...current.navigationSurfacesByArea,
|
|
360
|
-
[state.area]: [...(current.navigationSurfacesByArea[state.area] ?? []), surface],
|
|
361
|
-
},
|
|
362
|
-
}));
|
|
356
|
+
addPhiWorkspaceNavigationSurface(state.area, surface);
|
|
363
357
|
const navigation = (await loadPhiBuilderNavigationScope(navKey, surface)).navigation;
|
|
364
358
|
const saved = await savePhiBuilderNavigationDraft(navigation);
|
|
365
359
|
setPhiBuilderNavigationDraft(navKey, {
|
|
@@ -47,13 +47,13 @@ export function PhiBuilderPageSourceTreeProviderClient({ children }) {
|
|
|
47
47
|
* The slices the offered catalog is built from; the query reads the state when it runs. Subscribed
|
|
48
48
|
* to the whole state, every selection renewed the registration and reloaded the tree.
|
|
49
49
|
*/
|
|
50
|
-
const area = usePhiDeveloperBuilderStateValue(
|
|
51
|
-
const customPages = usePhiDeveloperBuilderStateValue(
|
|
52
|
-
const modulePresetPagesByArea = usePhiDeveloperBuilderStateValue(
|
|
53
|
-
const navigationSurfacesByArea = usePhiDeveloperBuilderStateValue(
|
|
54
|
-
const persistedPageCatalogByArea = usePhiDeveloperBuilderStateValue(
|
|
55
|
-
const runtimeModuleIdsByArea = usePhiDeveloperBuilderStateValue(
|
|
56
|
-
const areaRootRoutes = usePhiDeveloperBuilderStateValue(
|
|
50
|
+
const area = usePhiDeveloperBuilderStateValue((state) => state.area);
|
|
51
|
+
const customPages = usePhiDeveloperBuilderStateValue((state) => state.customPages);
|
|
52
|
+
const modulePresetPagesByArea = usePhiDeveloperBuilderStateValue((state) => state.modulePresetPagesByArea);
|
|
53
|
+
const navigationSurfacesByArea = usePhiDeveloperBuilderStateValue((state) => state.navigationSurfacesByArea);
|
|
54
|
+
const persistedPageCatalogByArea = usePhiDeveloperBuilderStateValue((state) => state.persistedPageCatalogByArea);
|
|
55
|
+
const runtimeModuleIdsByArea = usePhiDeveloperBuilderStateValue((state) => state.runtimeModuleIdsByArea);
|
|
56
|
+
const areaRootRoutes = usePhiDeveloperBuilderStateValue((state) => state.areaRootRoutes);
|
|
57
57
|
const registration = useMemo(() => {
|
|
58
58
|
const descriptor = PHI_BUILDER_RUNTIME_DATA_PROVIDER_DESCRIPTORS.find((candidate) => candidate.key === PHI_BUILDER_RUNTIME_DATA_PROVIDER_KEYS.pageSourceTree);
|
|
59
59
|
return {
|
|
@@ -65,7 +65,7 @@ export function PhiBuilderPageSourceTreeProviderClient({ children }) {
|
|
|
65
65
|
: field),
|
|
66
66
|
})) : [],
|
|
67
67
|
query: async (request) => {
|
|
68
|
-
const state = getPhiDeveloperBuilderStateSnapshot(
|
|
68
|
+
const state = getPhiDeveloperBuilderStateSnapshot();
|
|
69
69
|
const requestedArea = isBuilderArea(request.params?.area) ? request.params.area : state.area;
|
|
70
70
|
/*
|
|
71
71
|
* What the Area answers with, not what is installed in it. The active catalog mirrors the route
|
|
@@ -293,10 +293,10 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
293
293
|
* they run -- which is also what a mutation has to do, since the answer it writes back is to the
|
|
294
294
|
* selection as it stands then, not as it stood when the provider registered.
|
|
295
295
|
*/
|
|
296
|
-
const runtimeModuleDefinitions = usePhiDeveloperBuilderStateValue(
|
|
297
|
-
const runtimeModuleIdsByArea = usePhiDeveloperBuilderStateValue(
|
|
298
|
-
const unresolvedModuleIdsByArea = usePhiDeveloperBuilderStateValue(
|
|
299
|
-
const serverUnavailableModules = usePhiDeveloperBuilderStateValue(
|
|
296
|
+
const runtimeModuleDefinitions = usePhiDeveloperBuilderStateValue((state) => state.runtimeModuleDefinitions);
|
|
297
|
+
const runtimeModuleIdsByArea = usePhiDeveloperBuilderStateValue((state) => state.runtimeModuleIdsByArea);
|
|
298
|
+
const unresolvedModuleIdsByArea = usePhiDeveloperBuilderStateValue((state) => state.unresolvedModuleIdsByArea);
|
|
299
|
+
const serverUnavailableModules = usePhiDeveloperBuilderStateValue((state) => state.serverUnavailableModules);
|
|
300
300
|
const registration = useMemo(() => {
|
|
301
301
|
const descriptor = PHI_BUILDER_RUNTIME_DATA_PROVIDER_DESCRIPTORS.find((candidate) => candidate.key === PHI_BUILDER_RUNTIME_DATA_PROVIDER_KEYS.runtimeModulesTable);
|
|
302
302
|
const resources = descriptor?.kind === "table" ? descriptor.resources : [];
|
|
@@ -309,7 +309,7 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
309
309
|
throw new Error("Runtime Modules Table provider descriptor has no resource.");
|
|
310
310
|
}
|
|
311
311
|
const query = async (request) => {
|
|
312
|
-
const builderState = getPhiDeveloperBuilderStateSnapshot(
|
|
312
|
+
const builderState = getPhiDeveloperBuilderStateSnapshot();
|
|
313
313
|
if (request.resourceKey === DETAIL_RESOURCE_KEY) {
|
|
314
314
|
const moduleId = typeof request.params?.moduleId === "string" ? request.params.moduleId : "";
|
|
315
315
|
const areaLabels = readAreaLabels(request.params);
|
|
@@ -360,7 +360,7 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
360
360
|
}, { ...request, query: filteredQuery });
|
|
361
361
|
};
|
|
362
362
|
const mutate = async (request) => {
|
|
363
|
-
const builderState = getPhiDeveloperBuilderStateSnapshot(
|
|
363
|
+
const builderState = getPhiDeveloperBuilderStateSnapshot();
|
|
364
364
|
if (request.resourceKey === MODULE_USAGE_RESOURCE_KEY) {
|
|
365
365
|
return { status: "rejected", invalidation: "none", errorCode: "unsupported-mutation" };
|
|
366
366
|
}
|
|
@@ -369,7 +369,7 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
369
369
|
return { status: "rejected", invalidation: "none", errorCode: "unsupported-mutation" };
|
|
370
370
|
}
|
|
371
371
|
const path = typeof request.proposedValue === "string" ? request.proposedValue.trim() : "";
|
|
372
|
-
answerPhiBuilderPublicRouteCollision(
|
|
372
|
+
answerPhiBuilderPublicRouteCollision(String(request.rowIdentity), path);
|
|
373
373
|
return { status: "accepted", invalidation: "none", rowPatch: { path } };
|
|
374
374
|
}
|
|
375
375
|
if (request.resourceKey !== RESOURCE_KEY) {
|
|
@@ -409,7 +409,7 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
409
409
|
if (answers.length === 0) {
|
|
410
410
|
return false;
|
|
411
411
|
}
|
|
412
|
-
openPhiBuilderPublicRouteCollisionRequest(
|
|
412
|
+
openPhiBuilderPublicRouteCollisionRequest({
|
|
413
413
|
moduleId: definition.moduleId,
|
|
414
414
|
moduleTitle: definition.title,
|
|
415
415
|
areas: cmsAreas.filter((areaKey) => isPhiBuilderAreaKey(areaKey)),
|
|
@@ -456,7 +456,7 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
456
456
|
if (usage.length === 0) {
|
|
457
457
|
return false;
|
|
458
458
|
}
|
|
459
|
-
openPhiBuilderModuleDeactivationRequest(
|
|
459
|
+
openPhiBuilderModuleDeactivationRequest({
|
|
460
460
|
moduleId: definition.moduleId,
|
|
461
461
|
moduleTitle: definition.title,
|
|
462
462
|
areas,
|
|
@@ -476,7 +476,7 @@ export function PhiBuilderRuntimeModulesTableProviderClient({ children }) {
|
|
|
476
476
|
: currentModuleIds.filter((candidateId) => candidateId !== definition.moduleId),
|
|
477
477
|
};
|
|
478
478
|
});
|
|
479
|
-
applyPhiBuilderRuntimeModuleSelectionChanges(changes
|
|
479
|
+
applyPhiBuilderRuntimeModuleSelectionChanges(changes);
|
|
480
480
|
};
|
|
481
481
|
// The row's switch: the Module as a whole, i.e. every eligible Area in one gesture.
|
|
482
482
|
if (request.fieldKey === "active") {
|
|
@@ -50,8 +50,8 @@ export function PhiBuilderSignalRoutesTableProviderClient({ children }) {
|
|
|
50
50
|
}
|
|
51
51
|
const sessionKey = readSessionKey(request);
|
|
52
52
|
const currentRoutes = sessionKey
|
|
53
|
-
? routeTableSessions.current.get(sessionKey) ?? getPhiDeveloperSelectedSignalRoutes(
|
|
54
|
-
: getPhiDeveloperSelectedSignalRoutes(
|
|
53
|
+
? routeTableSessions.current.get(sessionKey) ?? getPhiDeveloperSelectedSignalRoutes()
|
|
54
|
+
: getPhiDeveloperSelectedSignalRoutes();
|
|
55
55
|
if (sessionKey && !routeTableSessions.current.has(sessionKey)) {
|
|
56
56
|
routeTableSessions.current.set(sessionKey, currentRoutes ?? {});
|
|
57
57
|
}
|
|
@@ -72,7 +72,7 @@ export function PhiBuilderSignalRoutesTableProviderClient({ children }) {
|
|
|
72
72
|
throw new Error("Invalid Signal Routes Table mutation.");
|
|
73
73
|
}
|
|
74
74
|
const current = routeTableSessions.current.get(sessionKey) ??
|
|
75
|
-
getPhiDeveloperSelectedSignalRoutes(
|
|
75
|
+
getPhiDeveloperSelectedSignalRoutes() ?? {};
|
|
76
76
|
if (request.actionKey === "cancel") {
|
|
77
77
|
routeTableSessions.current.delete(sessionKey);
|
|
78
78
|
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import { type PhiSignalRouteSet } from "../../../types/signals";
|
|
2
|
-
|
|
3
|
-
export declare function getPhiDeveloperSelectedSignalRoutes(defaultArea: PhiDeveloperBuilderArea): PhiSignalRouteSet | null;
|
|
2
|
+
export declare function getPhiDeveloperSelectedSignalRoutes(): PhiSignalRouteSet | null;
|
|
@@ -25,7 +25,7 @@ function resolveSelectedSignalRouteConfig(state, drafts = getPhiDeveloperRegionD
|
|
|
25
25
|
}
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
|
-
export function getPhiDeveloperSelectedSignalRoutes(
|
|
29
|
-
const state = getPhiDeveloperBuilderStateSnapshot(
|
|
28
|
+
export function getPhiDeveloperSelectedSignalRoutes() {
|
|
29
|
+
const state = getPhiDeveloperBuilderStateSnapshot();
|
|
30
30
|
return readPhiSignalRouteSet(resolveSelectedSignalRouteConfig(state)?.signalRoutes);
|
|
31
31
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { PHI_WORKSPACE_CATALOG_SCOPE } from "../../../components/workspace/catalog-store";
|
|
2
3
|
import { PHI_BUILDER_RUNTIME_DATA_PROVIDER_KEYS } from "./ids";
|
|
3
4
|
import { createPhiControlOptionsProviderClient, } from "../../../components/controls/phi-options-provider";
|
|
4
5
|
import { readPhiBuilderBoundCollectionResource } from "./selected-collection-source";
|
|
@@ -193,8 +194,8 @@ function resolveReceiverCapabilityOptions(context) {
|
|
|
193
194
|
};
|
|
194
195
|
}
|
|
195
196
|
const wiringProviderStore = {
|
|
196
|
-
subscribe: (listener) => builderWorkspaceStore.subscribe(
|
|
197
|
-
getSnapshot: () => getPhiDeveloperBuilderStateSnapshot(
|
|
197
|
+
subscribe: (listener) => builderWorkspaceStore.subscribe(PHI_WORKSPACE_CATALOG_SCOPE, listener),
|
|
198
|
+
getSnapshot: () => getPhiDeveloperBuilderStateSnapshot(),
|
|
198
199
|
};
|
|
199
200
|
export const PhiBuilderSignalSendersOptionsProviderClient = createPhiControlOptionsProviderClient({
|
|
200
201
|
key: PHI_BUILDER_RUNTIME_DATA_PROVIDER_KEYS.signalSenders,
|