@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.
Files changed (241) hide show
  1. package/components/cms/phi-cms-layout-renderer.js +4 -3
  2. package/components/cms/phi-cms-page-render-scope.d.ts +4 -5
  3. package/components/cms/phi-cms-page-render-scope.js +43 -22
  4. package/components/cms/phi-cms-render-diagnostic-client.js +7 -3
  5. package/components/cms/phi-cms-render-error-boundary.js +2 -1
  6. package/components/controls/phi-bullet-list-control.js +31 -2
  7. package/components/controls/phi-ribbon-control.d.ts +29 -0
  8. package/components/controls/phi-ribbon-control.js +53 -0
  9. package/components/controls/phi-table-control.d.ts +3 -0
  10. package/components/controls/phi-table-control.js +13 -1
  11. package/components/controls/phi-tree-control.js +3 -3
  12. package/components/forms/shared-form-provider-registry.js +1 -4
  13. package/components/media/asset-collection-runtime.js +6 -16
  14. package/components/media/media-font-metrics.d.ts +3 -0
  15. package/components/media/media-font-metrics.js +43 -0
  16. package/components/media/phi-area-upload-widget.js +53 -97
  17. package/components/media/phi-image-preview-data.d.ts +13 -0
  18. package/components/media/phi-image-preview-data.js +184 -9
  19. package/components/media/phi-media-picker-binding.js +16 -13
  20. package/components/media/phi-media-upload.d.ts +15 -8
  21. package/components/media/phi-media-upload.js +18 -9
  22. package/components/media/phi-site-font-assets.js +7 -8
  23. package/components/overlays/phi-overlay-container-client.js +16 -1
  24. package/components/regions/presets/phi-settings-page-shell-tree.js +48 -1
  25. package/components/runtime/runtime-controller-materialization.js +12 -1
  26. package/components/state/scoped-state-store.js +20 -3
  27. package/components/tables/client/phi-table-binding.d.ts +2 -1
  28. package/components/tables/client/phi-table-binding.js +45 -21
  29. package/components/trees/client/phi-tree-binding.js +19 -11
  30. package/components/widgets/client/bullet-list-entries-editor.d.ts +26 -0
  31. package/components/widgets/client/bullet-list-entries-editor.js +103 -0
  32. package/components/widgets/config/choice-shared.js +12 -13
  33. package/components/widgets/config/command-buttons.d.ts +5 -1
  34. package/components/widgets/config/command-buttons.js +38 -81
  35. package/components/widgets/config/control-signal-config.d.ts +3 -1
  36. package/components/widgets/config/control-signal-config.js +19 -17
  37. package/components/widgets/config/image-source-parser.d.ts +1 -0
  38. package/components/widgets/config/image-source-parser.js +7 -8
  39. package/components/widgets/config/mask.d.ts +6 -1
  40. package/components/widgets/config/mask.js +24 -1
  41. package/components/widgets/config/parser-primitives.js +72 -0
  42. package/components/widgets/config/stack-tabs.d.ts +1 -1
  43. package/components/widgets/config/stack-tabs.js +2 -3
  44. package/components/widgets/config/strict-config-reader.d.ts +40 -0
  45. package/components/widgets/config/strict-config-reader.js +174 -0
  46. package/components/widgets/label-sets/effects.js +2 -0
  47. package/components/widgets/label-types/effects.d.ts +1 -0
  48. package/components/widgets/label-types/effects.js +1 -0
  49. package/components/widgets/navigation-descriptor-resolver.server.js +20 -8
  50. package/components/widgets/shared/bullet-list-vocabulary.d.ts +17 -1
  51. package/components/widgets/shared/bullet-list-vocabulary.js +19 -2
  52. package/components/widgets/shared/card-body-client.d.ts +16 -4
  53. package/components/widgets/shared/card-body-client.js +81 -24
  54. package/components/widgets/shared/card-vocabulary.d.ts +21 -4
  55. package/components/widgets/shared/card-vocabulary.js +28 -2
  56. package/components/widgets/signals/control-signal-capabilities.d.ts +0 -18
  57. package/components/widgets/signals/control-signal-capabilities.js +10 -22
  58. package/components/workspace/catalog-store.d.ts +4 -3
  59. package/components/workspace/catalog-store.js +6 -5
  60. package/gateway/dashboard-cards-route.js +1 -0
  61. package/gateway/internal-references.d.ts +6 -1
  62. package/gateway/internal-references.js +48 -23
  63. package/gateway/site-cms-write-validation.d.ts +9 -0
  64. package/gateway/site-cms-write-validation.js +78 -0
  65. package/gateway/site-proxy.js +19 -3
  66. package/helpers/renderable-block-serialization.js +1 -1
  67. package/next/config.d.mts +3 -0
  68. package/next/config.mjs +28 -1
  69. package/package.json +2 -2
  70. package/plugins/runtime/phi-slot-child-viewport-effects-observer.js +5 -1
  71. package/plugins/runtime-modules/accounting/presets.d.ts +9 -0
  72. package/plugins/runtime-modules/accounting/presets.js +37 -0
  73. package/plugins/runtime-modules/accounting/server.d.ts +1 -4
  74. package/plugins/runtime-modules/accounting/server.js +4 -7
  75. package/plugins/runtime-modules/app/presets.d.ts +18 -0
  76. package/plugins/runtime-modules/app/presets.js +67 -0
  77. package/plugins/runtime-modules/app/server.d.ts +1 -4
  78. package/plugins/runtime-modules/app/server.js +4 -7
  79. package/plugins/runtime-modules/asset/controller/runtime.js +2 -2
  80. package/plugins/runtime-modules/asset/services/collection.js +9 -1
  81. package/plugins/runtime-modules/asset/services/options.js +2 -2
  82. package/plugins/runtime-modules/builder/area-settings-answer.js +2 -1
  83. package/plugins/runtime-modules/builder/authoring-canvas.js +6 -6
  84. package/plugins/runtime-modules/builder/cards.js +3 -5
  85. package/plugins/runtime-modules/builder/clients/builder-region-overrides.js +3 -3
  86. package/plugins/runtime-modules/builder/clients/canvas-widget.js +15 -54
  87. package/plugins/runtime-modules/builder/clients/inspector-config-field.d.ts +4 -1
  88. package/plugins/runtime-modules/builder/clients/inspector-config-field.js +5 -34
  89. package/plugins/runtime-modules/builder/clients/inspector-link-target-field.js +1 -1
  90. package/plugins/runtime-modules/builder/clients/inspector-section-widget.js +8 -8
  91. package/plugins/runtime-modules/builder/clients/inspector-title.js +6 -6
  92. package/plugins/runtime-modules/builder/clients/layout-inspector.d.ts +1 -1
  93. package/plugins/runtime-modules/builder/clients/layout-inspector.js +11 -25
  94. package/plugins/runtime-modules/builder/clients/mode-switch.js +1 -1
  95. package/plugins/runtime-modules/builder/clients/pages-header.js +11 -11
  96. package/plugins/runtime-modules/builder/clients/pages-workspace.js +1 -1
  97. package/plugins/runtime-modules/builder/clients/region-visibility-fields.js +1 -1
  98. package/plugins/runtime-modules/builder/clients/runtime-module-authoring-boundary.js +1 -1
  99. package/plugins/runtime-modules/builder/clients/shells-workspace.js +15 -31
  100. package/plugins/runtime-modules/builder/clients/structure-canvas.js +1 -1
  101. package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.d.ts +26 -0
  102. package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.js +36 -0
  103. package/plugins/runtime-modules/builder/clients/widget-effects-editor.js +1 -1
  104. package/plugins/runtime-modules/builder/clients/widget-inspector.js +1 -0
  105. package/plugins/runtime-modules/builder/clients/workspace-scope-boundary.js +2 -2
  106. package/plugins/runtime-modules/builder/cms-instance-allocator.js +8 -28
  107. package/plugins/runtime-modules/builder/controller/client.d.ts +0 -15
  108. package/plugins/runtime-modules/builder/controller/definition.d.ts +0 -15
  109. package/plugins/runtime-modules/builder/controller/definition.js +0 -8
  110. package/plugins/runtime-modules/builder/controller/draft-command-controller.d.ts +1 -2
  111. package/plugins/runtime-modules/builder/controller/draft-command-controller.js +11 -30
  112. package/plugins/runtime-modules/builder/controller/draft-status-controller.js +15 -2
  113. package/plugins/runtime-modules/builder/controller/inspector-controller.d.ts +1 -2
  114. package/plugins/runtime-modules/builder/controller/inspector-controller.js +4 -7
  115. package/plugins/runtime-modules/builder/controller/page-controller.d.ts +1 -2
  116. package/plugins/runtime-modules/builder/controller/page-controller.js +16 -68
  117. package/plugins/runtime-modules/builder/controller/server-definition.d.ts +0 -15
  118. package/plugins/runtime-modules/builder/controller/signal-wiring-controller.d.ts +2 -5
  119. package/plugins/runtime-modules/builder/controller/signal-wiring-controller.js +6 -50
  120. package/plugins/runtime-modules/builder/controller/workspace-controller.d.ts +2 -3
  121. package/plugins/runtime-modules/builder/controller/workspace-controller.js +89 -153
  122. package/plugins/runtime-modules/builder/data-providers.d.ts +1 -0
  123. package/plugins/runtime-modules/builder/data-providers.js +1 -0
  124. package/plugins/runtime-modules/builder/definition.d.ts +1 -0
  125. package/plugins/runtime-modules/builder/developer-workspace-store.d.ts +64 -30
  126. package/plugins/runtime-modules/builder/developer-workspace-store.js +255 -61
  127. package/plugins/runtime-modules/builder/edit-scaffold-drawer.js +1 -1
  128. package/plugins/runtime-modules/builder/history.d.ts +3 -1
  129. package/plugins/runtime-modules/builder/options-providers.js +3 -2
  130. package/plugins/runtime-modules/builder/page-catalog-client.js +19 -7
  131. package/plugins/runtime-modules/builder/page-meta-form.js +1 -0
  132. package/plugins/runtime-modules/builder/page-references-provider.js +1 -1
  133. package/plugins/runtime-modules/builder/persistence.js +33 -69
  134. package/plugins/runtime-modules/builder/public-route-collisions.d.ts +2 -2
  135. package/plugins/runtime-modules/builder/public-route-collisions.js +6 -19
  136. package/plugins/runtime-modules/builder/render-root-node-preview.server.js +20 -3
  137. package/plugins/runtime-modules/builder/render-root-node-scaffold.js +3 -3
  138. package/plugins/runtime-modules/builder/runtime-module-selection.d.ts +2 -12
  139. package/plugins/runtime-modules/builder/runtime-module-selection.js +16 -42
  140. package/plugins/runtime-modules/builder/services/navigation-table.js +9 -15
  141. package/plugins/runtime-modules/builder/services/page-source-tree.js +8 -8
  142. package/plugins/runtime-modules/builder/services/runtime-modules-table.js +10 -10
  143. package/plugins/runtime-modules/builder/services/signal-routes-table.js +3 -3
  144. package/plugins/runtime-modules/builder/signal-route-selection.d.ts +1 -2
  145. package/plugins/runtime-modules/builder/signal-route-selection.js +2 -2
  146. package/plugins/runtime-modules/builder/signal-wiring-options.js +3 -2
  147. package/plugins/runtime-modules/builder/structure-dnd.js +8 -61
  148. package/plugins/runtime-modules/builder/trees/phi-default-builder-area-preset-tree.js +13 -10
  149. package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +12 -18
  150. package/plugins/runtime-modules/builder/workspace-catalog-actions.d.ts +55 -0
  151. package/plugins/runtime-modules/builder/workspace-catalog-actions.js +142 -0
  152. package/plugins/runtime-modules/client-manifests/common.js +1 -1
  153. package/plugins/runtime-modules/{runtime-calendar-adapters.js → core/calendar-adapters.js} +2 -2
  154. package/plugins/runtime-modules/{client-calendar-adapters/core.js → core/client-calendar-adapters.js} +1 -1
  155. package/plugins/runtime-modules/core/content-entries/table.js +1 -1
  156. package/plugins/runtime-modules/core/data-providers.d.ts +3 -0
  157. package/plugins/runtime-modules/core/data-providers.js +2 -1
  158. package/plugins/runtime-modules/core/definition.d.ts +3 -0
  159. package/plugins/runtime-modules/core/definition.js +1 -1
  160. package/plugins/runtime-modules/core/messaging/data-providers.d.ts +1 -0
  161. package/plugins/runtime-modules/core/messaging/data-providers.js +1 -0
  162. package/plugins/runtime-modules/core/messaging/thread-inbox-table.js +1 -1
  163. package/plugins/runtime-modules/core/server.js +1 -1
  164. package/plugins/runtime-modules/core/themes.d.ts +44 -0
  165. package/plugins/runtime-modules/core/themes.js +12 -0
  166. package/plugins/runtime-modules/core/widgets/card/collection-view-binding.js +25 -9
  167. package/plugins/runtime-modules/core/widgets/card/config.d.ts +296 -254
  168. package/plugins/runtime-modules/core/widgets/card/config.js +52 -3
  169. package/plugins/runtime-modules/core/widgets/card/editor.js +30 -3
  170. package/plugins/runtime-modules/core/widgets/card/server.d.ts +3 -0
  171. package/plugins/runtime-modules/core/widgets/card/server.js +31 -3
  172. package/plugins/runtime-modules/core/widgets/collection-view/asset-binding.js +7 -6
  173. package/plugins/runtime-modules/core/widgets/collection-view/config.js +9 -2
  174. package/plugins/runtime-modules/core/widgets/description/config.d.ts +1 -25
  175. package/plugins/runtime-modules/core/widgets/description/editor.js +4 -61
  176. package/plugins/runtime-modules/core/widgets/entry-list/config.d.ts +1 -25
  177. package/plugins/runtime-modules/core/widgets/gallery/config.d.ts +1 -25
  178. package/plugins/runtime-modules/core/widgets/image/config.js +2 -2
  179. package/plugins/runtime-modules/core/widgets/markdown/editor.js +2 -3
  180. package/plugins/runtime-modules/core/widgets/result/config.d.ts +4 -25
  181. package/plugins/runtime-modules/core/widgets/result/config.js +2 -0
  182. package/plugins/runtime-modules/core/widgets/result/server.js +25 -19
  183. package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +1 -25
  184. package/plugins/runtime-modules/core/widgets/slot-upload/client.js +11 -2
  185. package/plugins/runtime-modules/core/widgets/table/client.js +8 -4
  186. package/plugins/runtime-modules/core/widgets/table/config.d.ts +3 -83
  187. package/plugins/runtime-modules/core/widgets/table/config.js +302 -452
  188. package/plugins/runtime-modules/core/widgets/tree/config.js +5 -2
  189. package/plugins/runtime-modules/dashboard/card-rows.d.ts +5 -0
  190. package/plugins/runtime-modules/dashboard/card-rows.js +59 -0
  191. package/plugins/runtime-modules/dashboard/clients/dashboard-card-view.js +4 -6
  192. package/plugins/runtime-modules/dashboard/services/collection.js +17 -7
  193. package/plugins/runtime-modules/groups/data-providers.d.ts +2 -0
  194. package/plugins/runtime-modules/groups/data-providers.js +3 -3
  195. package/plugins/runtime-modules/groups/definition.d.ts +2 -0
  196. package/plugins/runtime-modules/localization/data-providers.d.ts +3 -0
  197. package/plugins/runtime-modules/localization/data-providers.js +2 -0
  198. package/plugins/runtime-modules/localization/definition.d.ts +3 -0
  199. package/plugins/runtime-modules/localization/services/table.js +3 -7
  200. package/plugins/runtime-modules/observability/data-providers.d.ts +1 -0
  201. package/plugins/runtime-modules/observability/data-providers.js +1 -0
  202. package/plugins/runtime-modules/observability/definition.d.ts +1 -0
  203. package/plugins/runtime-modules/observability/module.d.ts +1 -0
  204. package/plugins/runtime-modules/observability/services/table.js +1 -1
  205. package/plugins/runtime-modules/phi-default-site-area-preset-tree.js +2 -105
  206. package/plugins/runtime-modules/public/presets.d.ts +115 -0
  207. package/plugins/runtime-modules/{area-base-presets.js → public/presets.js} +19 -119
  208. package/plugins/runtime-modules/public/server.d.ts +1 -4
  209. package/plugins/runtime-modules/public/server.js +4 -7
  210. package/plugins/runtime-modules/public/trees/phi-default-pub-error-page-tree.js +7 -8
  211. package/plugins/runtime-modules/public-base-page-references.d.ts +1 -1
  212. package/plugins/runtime-modules/public-base-page-references.js +1 -1
  213. package/plugins/runtime-modules/revisions/controller/client.js +11 -11
  214. package/plugins/runtime-modules/revisions/services/table.js +3 -3
  215. package/plugins/runtime-modules/theme/trees/phi-default-builder-theme-page-tree.js +22 -0
  216. package/plugins/runtime-modules/theme/widgets/brand-controls/client.d.ts +2 -1
  217. package/plugins/runtime-modules/theme/widgets/brand-controls/client.js +93 -58
  218. package/plugins/runtime-modules/theme/widgets/brand-controls/config.d.ts +2 -1
  219. package/plugins/runtime-modules/theme/widgets/brand-controls/config.js +23 -22
  220. package/plugins/runtime-modules/theme/widgets/brand-controls/plugin.js +1 -1
  221. package/plugins/runtime-modules/theme-descriptors.js +1 -1
  222. package/plugins/runtime-modules/user-management/data-providers.d.ts +2 -0
  223. package/plugins/runtime-modules/user-management/data-providers.js +1 -0
  224. package/plugins/runtime-modules/user-management/definition.d.ts +2 -0
  225. package/styles/control-shape.css +11 -11
  226. package/styles/controls.css +3 -3
  227. package/styles/layout.css +16 -7
  228. package/types/cms-config.js +142 -185
  229. package/types/cms-plugins.d.ts +4 -11
  230. package/types/core-widget-placements.d.ts +14 -3
  231. package/types/dashboard-cards.d.ts +9 -0
  232. package/types/media.d.ts +0 -3
  233. package/types/renderable-block.d.ts +6 -1
  234. package/types/table-widget.d.ts +9 -0
  235. package/types/table-widget.js +20 -0
  236. package/types.d.ts +1 -1
  237. package/widget-config.d.ts +2 -0
  238. package/widget-config.js +6 -0
  239. package/plugins/runtime-modules/area-base-presets.d.ts +0 -139
  240. /package/plugins/runtime-modules/{runtime-calendar-adapters.d.ts → core/calendar-adapters.d.ts} +0 -0
  241. /package/plugins/runtime-modules/{client-calendar-adapters/core.d.ts → core/client-calendar-adapters.d.ts} +0 -0
@@ -56,11 +56,14 @@ function readBindingTools(value) {
56
56
  });
57
57
  }
58
58
  function readSource(value) {
59
- if (!isPhiRecord(value) || !isPhiRuntimeDataProviderKey(value.providerKey) || !readString(value.resourceKey))
59
+ if (!isPhiRecord(value) || !isPhiRuntimeDataProviderKey(value.providerKey))
60
+ return null;
61
+ const resourceKey = readString(value.resourceKey);
62
+ if (!resourceKey)
60
63
  return null;
61
64
  return {
62
65
  providerKey: value.providerKey,
63
- resourceKey: readString(value.resourceKey),
66
+ resourceKey,
64
67
  params: isPhiRecord(value.params) ? value.params : undefined,
65
68
  };
66
69
  }
@@ -0,0 +1,5 @@
1
+ import { type PhiDashboardCardPayload, type PhiDashboardCardRow } from "../../../types/dashboard-cards";
2
+ /** The card rows a list answer carries, or a Collection holds. */
3
+ export declare function readPhiDashboardCardRows(value: unknown, source?: string): PhiDashboardCardRow[];
4
+ /** One card's refreshed payload. */
5
+ export declare function readPhiDashboardCardPayload(value: unknown): PhiDashboardCardPayload;
@@ -0,0 +1,59 @@
1
+ import { readPhiTimelineEntry } from "@phis/contracts/timeline";
2
+ import { isPhiDashboardCardId, } from "../../../types/dashboard-cards";
3
+ import { createPhiResponseReader, requirePhiField, } from "../../../components/widgets/config/strict-config-reader";
4
+ /*
5
+ * The Dashboard's rows and payloads, read as the Site's door writes them (`gateway/dashboard-cards-route.ts`).
6
+ *
7
+ * Both came in by cast: the list's rows as "an object, so a row", and a refreshed payload as whatever
8
+ * the door answered. A row without its title then disappeared without a word, and a payload of the wrong
9
+ * shape rendered as an empty card. Read field by field now, a wrong answer is an error naming the field,
10
+ * which the Collection shows as the card list's error.
11
+ */
12
+ const PHI_DASHBOARD_CARD_FORMS = ["stat", "list"];
13
+ function readCardId(reader) {
14
+ return requirePhiField(reader, "cardId", "a Dashboard card id", (key) => reader.value(key, "a Dashboard card id", (value) => (isPhiDashboardCardId(value) ? value : undefined)));
15
+ }
16
+ function readTimelineEntry(reader, index) {
17
+ return readPhiTimelineEntry(reader.record) ?? reader.fail(String(index), "a timeline entry with a key", reader.record);
18
+ }
19
+ function readPayloadFields(reader) {
20
+ const value = reader.string("value");
21
+ const entries = reader.list("entries", readTimelineEntry);
22
+ const description = reader.string("description");
23
+ const meta = reader.string("meta");
24
+ const error = reader.string("error");
25
+ return {
26
+ cardId: readCardId(reader),
27
+ ...(value === undefined ? {} : { value }),
28
+ ...(entries === undefined ? {} : { entries }),
29
+ ...(description === undefined ? {} : { description }),
30
+ ...(meta === undefined ? {} : { meta }),
31
+ ...(error === undefined ? {} : { error }),
32
+ resolvedAt: requirePhiField(reader, "resolvedAt", "an instant", reader.string),
33
+ };
34
+ }
35
+ function readRowFields(reader) {
36
+ const eyebrow = reader.string("eyebrow");
37
+ const description = reader.string("description");
38
+ const mark = reader.string("mark");
39
+ const href = reader.string("href");
40
+ const payload = reader.object("payload", readPayloadFields);
41
+ return {
42
+ cardId: readCardId(reader),
43
+ form: requirePhiField(reader, "form", '"stat" or "list"', (key) => reader.oneOf(key, PHI_DASHBOARD_CARD_FORMS)),
44
+ title: requirePhiField(reader, "title", "a text", reader.string),
45
+ ...(eyebrow === undefined ? {} : { eyebrow }),
46
+ ...(description === undefined ? {} : { description }),
47
+ ...(mark === undefined ? {} : { mark }),
48
+ ...(href === undefined ? {} : { href }),
49
+ ...(payload === undefined ? {} : { payload }),
50
+ };
51
+ }
52
+ /** The card rows a list answer carries, or a Collection holds. */
53
+ export function readPhiDashboardCardRows(value, source = "The Dashboard card list") {
54
+ return createPhiResponseReader({ cards: value }, source).list("cards", readRowFields) ?? [];
55
+ }
56
+ /** One card's refreshed payload. */
57
+ export function readPhiDashboardCardPayload(value) {
58
+ return readPayloadFields(createPhiResponseReader(value, "The Dashboard card"));
59
+ }
@@ -9,8 +9,8 @@ import { PHI_SURFACE_CARD } from "../../../../helpers/surface-presets";
9
9
  import { PhiCollectionViewControl } from "../../../../components/controls/phi-collection-view-control";
10
10
  import { PhiAlertControl } from "../../../../components/controls/phi-alert-control";
11
11
  import { PhiEmptyControl } from "../../../../components/controls/phi-empty-control";
12
- import { isPhiRecord } from "../../../../helpers/is-record";
13
12
  import { usePhiPathname } from "../../../../components/runtime/use-phi-pathname";
13
+ import { readPhiDashboardCardPayload, readPhiDashboardCardRows } from "../card-rows";
14
14
  import { PhiTimelineControl } from "../../../../components/controls/phi-timeline-control";
15
15
  import { usePhiIntlLocale } from "../../../../components/root/phi-intl-locale";
16
16
  import { formatPhiRelativeTime } from "../../../../helpers/format-date-time";
@@ -63,10 +63,8 @@ function PhiDashboardCardList({ entries }) {
63
63
  })) }));
64
64
  }
65
65
  function readRows(binding) {
66
- return (binding.data?.items ?? [])
67
- .filter(isPhiRecord)
68
- .map((item) => item)
69
- .filter((row) => typeof row.cardId === "string" && typeof row.title === "string");
66
+ // A Collection holds items of no particular type; the rows are read again, not cast.
67
+ return readPhiDashboardCardRows(binding.data?.items ?? [], "The Dashboard Collection");
70
68
  }
71
69
  /**
72
70
  * One card, and its own request where the list did not bring its payload.
@@ -106,7 +104,7 @@ function PhiDashboardCard({ row, area, pathname, }) {
106
104
  if (!response.ok) {
107
105
  throw new Error(`Card payload request failed (${response.status}).`);
108
106
  }
109
- return (await response.json());
107
+ return readPhiDashboardCardPayload(await response.json());
110
108
  })
111
109
  .then((payload) => setResolved({ key: requestKey, payload, failure: null }))
112
110
  .catch((error) => {
@@ -3,13 +3,22 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useMemo } from "react";
4
4
  import { PHI_DASHBOARD_CARD_DATA_PROVIDER_KEY, PHI_DASHBOARD_CARD_ITEM_RENDERER_KEY, PHI_DASHBOARD_CARD_RESOURCE_KEY, } from "../../../../constants/dashboard-card-provider-keys";
5
5
  import { PhiCollectionProviderClient, } from "../../../../components/widgets/client/shared/phi-collection-provider";
6
+ import { readPhiDashboardCardRows } from "../card-rows";
6
7
  import { isPhiRecord } from "../../../../helpers/is-record";
7
8
  import { usePhiPathname } from "../../../../components/runtime/use-phi-pathname";
8
- function readCardRows(payload) {
9
- return Array.isArray(payload.cards)
10
- ? payload.cards.filter(isPhiRecord).map((card) => ({ ...card }))
11
- : [];
12
- }
9
+ /**
10
+ * The fan-in, from the browser's side: one request, and no idea what stands behind it.
11
+ *
12
+ * Everything that decides which cards exist -- the Area's Module catalog, each contributor's own list,
13
+ * who is looking -- is server knowledge, so this asks the Site's own door and passes the answer on as
14
+ * ordinary Collection rows. That is the whole reason the door exists: a Module definition must never
15
+ * reach the browser, and a provider that collected the contributions here would drag every one of them
16
+ * in with it.
17
+ *
18
+ * It sends where it stands. The Area is config, because a page belongs to one and the preset that
19
+ * placed this Widget knows which; the path is read live, because that is what changes when a Site puts
20
+ * a Dashboard somewhere else.
21
+ */
13
22
  async function queryDashboardCards(request, pathname) {
14
23
  if (request.resourceKey !== PHI_DASHBOARD_CARD_RESOURCE_KEY) {
15
24
  throw new Error(`Unknown Dashboard collection "${request.resourceKey}".`);
@@ -36,10 +45,11 @@ async function queryDashboardCards(request, pathname) {
36
45
  if (!response.ok) {
37
46
  throw new Error(`Dashboard cards request failed (${response.status}).`);
38
47
  }
39
- const rows = readCardRows((await response.json()));
48
+ const payload = await response.json();
49
+ const rows = readPhiDashboardCardRows(isPhiRecord(payload) ? payload.cards : undefined);
40
50
  return {
41
51
  resourceKey: request.resourceKey,
42
- items: rows,
52
+ items: rows.map((row) => ({ ...row })),
43
53
  total: rows.length,
44
54
  loading: false,
45
55
  error: null,
@@ -98,6 +98,7 @@ export declare const PHI_GROUPS_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
98
98
  search: false;
99
99
  sorting: "none";
100
100
  pagination: "offset";
101
+ total: true;
101
102
  filterFields?: undefined;
102
103
  };
103
104
  actions: ({
@@ -210,6 +211,7 @@ export declare const PHI_GROUPS_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
210
211
  filterFields: string[];
211
212
  sorting: "none";
212
213
  pagination: "offset";
214
+ total: true;
213
215
  search?: undefined;
214
216
  };
215
217
  actions: {
@@ -117,7 +117,7 @@ export const PHI_GROUPS_RUNTIME_DATA_PROVIDER_DESCRIPTORS = [
117
117
  { key: "spaceUsedBytes", title: "Space used", type: "number" },
118
118
  { key: "spaceQuotaBytes", title: "Space quota", type: "number" },
119
119
  ],
120
- query: { search: false, sorting: "none", pagination: "offset" },
120
+ query: { search: false, sorting: "none", pagination: "offset", total: true },
121
121
  actions: [
122
122
  { key: "refresh", title: "Refresh", scope: "resource" },
123
123
  { key: "create", title: "Create", scope: "resource", valueType: "json" },
@@ -196,7 +196,7 @@ export const PHI_GROUPS_RUNTIME_DATA_PROVIDER_DESCRIPTORS = [
196
196
  { key: "spaceUsedBytes", title: "Space used", type: "number" },
197
197
  { key: "spaceQuotaBytes", title: "Space quota", type: "number" },
198
198
  ],
199
- query: { search: false, sorting: "none", pagination: "offset" },
199
+ query: { search: false, sorting: "none", pagination: "offset", total: true },
200
200
  actions: [
201
201
  { key: "refresh", title: "Refresh", scope: "resource" },
202
202
  // A Manager runs the team and may end it. Putting one back is not offered here, because a
@@ -246,7 +246,7 @@ export const PHI_GROUPS_RUNTIME_DATA_PROVIDER_DESCRIPTORS = [
246
246
  { key: "sourceProviderId", title: "Source", type: "string" },
247
247
  { key: "createdAt", title: "Since", type: "datetime" },
248
248
  ],
249
- query: { filterFields: ["groupId"], sorting: "none", pagination: "offset" },
249
+ query: { filterFields: ["groupId"], sorting: "none", pagination: "offset", total: true },
250
250
  actions: [
251
251
  {
252
252
  key: "delete", title: "Remove", scope: "row",
@@ -110,6 +110,7 @@ export declare const PHI_GROUPS_RUNTIME_MODULE_DEFINITION: {
110
110
  search: false;
111
111
  sorting: "none";
112
112
  pagination: "offset";
113
+ total: true;
113
114
  filterFields?: undefined;
114
115
  };
115
116
  actions: ({
@@ -222,6 +223,7 @@ export declare const PHI_GROUPS_RUNTIME_MODULE_DEFINITION: {
222
223
  filterFields: string[];
223
224
  sorting: "none";
224
225
  pagination: "offset";
226
+ total: true;
225
227
  search?: undefined;
226
228
  };
227
229
  actions: {
@@ -57,6 +57,7 @@ export declare const PHI_LOCALIZATION_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
57
57
  filterFields: never[];
58
58
  sorting: "none";
59
59
  pagination: "none";
60
+ total?: undefined;
60
61
  facets?: undefined;
61
62
  };
62
63
  recordRead: true;
@@ -128,6 +129,7 @@ export declare const PHI_LOCALIZATION_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
128
129
  filterFields: string[];
129
130
  sorting: "none";
130
131
  pagination: "offset";
132
+ total: true;
131
133
  facets: string[];
132
134
  };
133
135
  actions: ({
@@ -206,6 +208,7 @@ export declare const PHI_LOCALIZATION_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
206
208
  filterFields: string[];
207
209
  sorting: "none";
208
210
  pagination: "offset";
211
+ total: true;
209
212
  facets: string[];
210
213
  };
211
214
  recordRead: true;
@@ -107,6 +107,7 @@ export const PHI_LOCALIZATION_RUNTIME_DATA_PROVIDER_DESCRIPTORS = [
107
107
  filterFields: ["locale"],
108
108
  sorting: "none",
109
109
  pagination: "offset",
110
+ total: true,
110
111
  facets: ["site", "platformLocales", "selectedLocale"],
111
112
  },
112
113
  actions: [
@@ -146,6 +147,7 @@ export const PHI_LOCALIZATION_RUNTIME_DATA_PROVIDER_DESCRIPTORS = [
146
147
  filterFields: ["locale", "context", "status"],
147
148
  sorting: "none",
148
149
  pagination: "offset",
150
+ total: true,
149
151
  facets: ["selectedLocale", "availableLocales", "contexts"],
150
152
  },
151
153
  recordRead: true,
@@ -85,6 +85,7 @@ export declare const PHI_LOCALIZATION_RUNTIME_MODULE_DEFINITION: {
85
85
  filterFields: never[];
86
86
  sorting: "none";
87
87
  pagination: "none";
88
+ total?: undefined;
88
89
  facets?: undefined;
89
90
  };
90
91
  recordRead: true;
@@ -156,6 +157,7 @@ export declare const PHI_LOCALIZATION_RUNTIME_MODULE_DEFINITION: {
156
157
  filterFields: string[];
157
158
  sorting: "none";
158
159
  pagination: "offset";
160
+ total: true;
159
161
  facets: string[];
160
162
  };
161
163
  actions: ({
@@ -234,6 +236,7 @@ export declare const PHI_LOCALIZATION_RUNTIME_MODULE_DEFINITION: {
234
236
  filterFields: string[];
235
237
  sorting: "none";
236
238
  pagination: "offset";
239
+ total: true;
237
240
  facets: string[];
238
241
  };
239
242
  recordRead: true;
@@ -37,12 +37,8 @@ async function loadSiteTranslations({ query, signal, }) {
37
37
  }));
38
38
  return {
39
39
  rows,
40
- total: typeof translations.total === "number" ? translations.total : rows.length,
41
- summary: {
42
- localeTotal: typeof translations.localeTotal === "number"
43
- ? translations.localeTotal
44
- : rows.length,
45
- },
40
+ total: typeof translations.total === "number" ? translations.total : undefined,
41
+ summary: typeof translations.localeTotal === "number" ? { localeTotal: translations.localeTotal } : {},
46
42
  resolvedQuery: selectedLocale
47
43
  ? { filters: { locale: selectedLocale } }
48
44
  : undefined,
@@ -74,7 +70,7 @@ async function loadEditorTranslations({ query, signal, }) {
74
70
  const site = isPhiRecord(result?.site) ? result.site : {};
75
71
  return {
76
72
  rows,
77
- total: typeof translations.total === "number" ? translations.total : rows.length,
73
+ total: typeof translations.total === "number" ? translations.total : undefined,
78
74
  resolvedQuery: selectedLocale
79
75
  ? { filters: { locale: selectedLocale } }
80
76
  : undefined,
@@ -41,6 +41,7 @@ export declare const PHI_OBSERVABILITY_RUNTIME_DATA_PROVIDER_DESCRIPTORS: {
41
41
  filterFields: string[];
42
42
  sorting: "none";
43
43
  pagination: "offset";
44
+ total: true;
44
45
  };
45
46
  recordRead: true;
46
47
  }[];
@@ -39,6 +39,7 @@ export const PHI_OBSERVABILITY_RUNTIME_DATA_PROVIDER_DESCRIPTORS = [
39
39
  filterFields: ["service", "level", "event", "area", "since"],
40
40
  sorting: "none",
41
41
  pagination: "offset",
42
+ total: true,
42
43
  },
43
44
  recordRead: true,
44
45
  }],
@@ -49,6 +49,7 @@ export declare const PHI_OBSERVABILITY_RUNTIME_MODULE_DEFINITION: {
49
49
  filterFields: string[];
50
50
  sorting: "none";
51
51
  pagination: "offset";
52
+ total: true;
52
53
  };
53
54
  recordRead: true;
54
55
  }[];
@@ -49,6 +49,7 @@ export declare const PHI_OBSERVABILITY_RUNTIME_MODULE: {
49
49
  filterFields: string[];
50
50
  sorting: "none";
51
51
  pagination: "offset";
52
+ total: true;
52
53
  };
53
54
  recordRead: true;
54
55
  }[];
@@ -44,7 +44,7 @@ async function loadRows({ resourceKey, query, signal, }) {
44
44
  const rows = readPhiTableRows(payload.rows);
45
45
  return {
46
46
  rows,
47
- total: typeof payload.total === "number" && Number.isFinite(payload.total) ? payload.total : rows.length,
47
+ total: typeof payload.total === "number" && Number.isFinite(payload.total) ? payload.total : undefined,
48
48
  };
49
49
  }
50
50
  async function readRecord({ resourceKey, rowIdentity, signal, }) {
@@ -17,8 +17,6 @@ import { PHI_DEFAULT_PUB_AREA_LAYOUT_NODE_KEYS, PHI_DEFAULT_PUB_AREA_WIDGET_NODE
17
17
  const SYNTHETIC_REGION_IDS = {
18
18
  regionHeaderTop: -1,
19
19
  regionHeaderMain: -2,
20
- regionHeaderBottom: -3,
21
- regionSiderRight: -24,
22
20
  regionFooterTop: -27,
23
21
  regionFooterMain: -28,
24
22
  regionFooterBottom: -33,
@@ -34,11 +32,8 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
34
32
  ownerModuleId,
35
33
  presetKey,
36
34
  }, PHI_DEFAULT_PUB_AREA_WIDGET_NODE_KEYS);
37
- const navigationArea = runtimeModuleArea === "public" ? "public" : runtimeModuleArea;
38
35
  const headerMainRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "header_main");
39
36
  const headerTopRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "header_top");
40
- const headerBottomRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "header_bottom");
41
- const siderRightRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "sider_right");
42
37
  const footerMainRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "footer_main");
43
38
  const footerTopRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "footer_top");
44
39
  const footerBottomRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "footer_bottom");
@@ -68,19 +63,6 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
68
63
  family: "header",
69
64
  region: "main",
70
65
  });
71
- const shellHeaderBottomHeight = resolvePhiShellHeaderHeight(runtime.site.theme?.shell, "bottom");
72
- const shellHeaderBottomOffsetTop = resolvePhiShellMetric(runtime.site.theme?.shell, "offsetTop", {
73
- family: "header",
74
- region: "bottom",
75
- });
76
- const shellSiderRightWidth = resolvePhiShellMetric(runtime.site.theme?.shell, "width", {
77
- family: "sider",
78
- region: "right",
79
- });
80
- const shellSiderRightOffsetTop = resolvePhiShellMetric(runtime.site.theme?.shell, "offsetTop", {
81
- family: "sider",
82
- region: "right",
83
- });
84
66
  const shellFooterMainHeight = resolvePhiShellMetric(runtime.site.theme?.shell, "height", {
85
67
  family: "footer",
86
68
  region: "main",
@@ -135,44 +117,6 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
135
117
  }),
136
118
  ]
137
119
  : []),
138
- ...(headerBottomRegion
139
- ? [
140
- nodes.region({
141
- id: SYNTHETIC_REGION_IDS.regionHeaderBottom,
142
- regionType: PhiCmsRegionType.HeaderBottom,
143
- rootLayoutNodeId: PHI_DEFAULT_PUB_AREA_LAYOUT_IDS.layoutHeaderBottom,
144
- status: headerBottomRegion.status,
145
- flags: headerBottomRegion.flags,
146
- visibilityMask: headerBottomRegion.visibilityMask,
147
- sortOrder: headerBottomRegion.sortOrder,
148
- config: {
149
- ...headerBottomRegion.config,
150
- size: { ...(headerBottomRegion.config.size ?? {}), height: `${shellHeaderBottomHeight}px` },
151
- ...(typeof shellHeaderBottomOffsetTop === "number" ? { offsetTop: shellHeaderBottomOffsetTop } : {}),
152
- },
153
- }),
154
- ]
155
- : []),
156
- ...(siderRightRegion
157
- ? [
158
- nodes.region({
159
- id: SYNTHETIC_REGION_IDS.regionSiderRight,
160
- regionType: PhiCmsRegionType.SiderRight,
161
- rootLayoutNodeId: PHI_DEFAULT_PUB_AREA_LAYOUT_IDS.layoutSiderRight,
162
- status: siderRightRegion.status,
163
- flags: siderRightRegion.flags,
164
- visibilityMask: siderRightRegion.visibilityMask,
165
- sortOrder: siderRightRegion.sortOrder,
166
- config: {
167
- ...siderRightRegion.config,
168
- ...(typeof shellSiderRightWidth === "number"
169
- ? { size: { ...(siderRightRegion.config.size ?? {}), width: `${shellSiderRightWidth}px` } }
170
- : {}),
171
- ...(typeof shellSiderRightOffsetTop === "number" ? { offsetTop: shellSiderRightOffsetTop } : {}),
172
- },
173
- }),
174
- ]
175
- : []),
176
120
  ...(footerTopRegion
177
121
  ? [
178
122
  nodes.region({
@@ -295,53 +239,6 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
295
239
  paddingRight: 0,
296
240
  },
297
241
  },
298
- ...(headerBottomRegion
299
- ? [
300
- {
301
- id: PHI_DEFAULT_PUB_AREA_LAYOUT_IDS.layoutHeaderBottom,
302
- siteId: page.siteId,
303
- parentLayoutNodeId: null,
304
- widgetType: buildPhiCmsLayoutNamespacedTypeKey(resolvePhiCmsLayoutPluginKey("flex"), "flex"),
305
- slotIndex: PHI_CMS_DEFAULT_SLOT_INDEX,
306
- sortOrder: 10,
307
- status: 1,
308
- flags: 0,
309
- visibilityMask: page.visibilityMask,
310
- label: "pub header bottom flex",
311
- config: {
312
- anchor: {
313
- horizontal: "left",
314
- vertical: "middle",
315
- },
316
- gap: 0,
317
- wrap: false,
318
- },
319
- },
320
- ]
321
- : []),
322
- ...(siderRightRegion
323
- ? [
324
- {
325
- id: PHI_DEFAULT_PUB_AREA_LAYOUT_IDS.layoutSiderRight,
326
- siteId: page.siteId,
327
- parentLayoutNodeId: null,
328
- widgetType: buildPhiCmsLayoutNamespacedTypeKey(resolvePhiCmsLayoutPluginKey("flex-vertical"), "flex-vertical"),
329
- slotIndex: PHI_CMS_DEFAULT_SLOT_INDEX,
330
- sortOrder: 16,
331
- status: 1,
332
- flags: 0,
333
- visibilityMask: page.visibilityMask,
334
- label: "pub sider right vertical",
335
- config: {
336
- anchor: {
337
- horizontal: "center",
338
- vertical: "top",
339
- },
340
- gap: 0,
341
- },
342
- },
343
- ]
344
- : []),
345
242
  ...(footerTopRegion
346
243
  ? [
347
244
  {
@@ -516,7 +413,7 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
516
413
  visibilityMask: page.visibilityMask,
517
414
  label: "pub header main navigation",
518
415
  config: {
519
- navKey: `${navigationArea}:header`,
416
+ navKey: `${runtimeModuleArea}:header`,
520
417
  },
521
418
  contentVersionId: null,
522
419
  },
@@ -588,7 +485,7 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
588
485
  config: {
589
486
  title: "Quick Links",
590
487
  textSource: PHI_TEXT_SOURCE_PRESET,
591
- navKey: `${navigationArea}:footer`,
488
+ navKey: `${runtimeModuleArea}:footer`,
592
489
  columns: 2,
593
490
  separator: true,
594
491
  },
@@ -0,0 +1,115 @@
1
+ import type { PhiCmsDescriptorBuildContext } from "../../../types/cms-module-descriptors";
2
+ export declare const PHI_PUBLIC_RUNTIME_MODULE_AREA_SHELLS: {
3
+ ownerModuleId: "@phis/ui/modules/public";
4
+ presetKey: string;
5
+ shellPresetVersion: number;
6
+ area: "public";
7
+ exportedNodeKeys: readonly ["widgetBrand", "widgetNav", "widgetLocale"];
8
+ loadTree: ({ page, runtime }: PhiCmsDescriptorBuildContext) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
9
+ }[];
10
+ export declare const PHI_PUBLIC_RUNTIME_MODULE_ROUTES: ({
11
+ ownerModuleId: "@phis/ui/modules/public";
12
+ presetKey: string;
13
+ presetVersion: number;
14
+ area: "public";
15
+ title: string;
16
+ path: string;
17
+ defaultPageFlags: number;
18
+ loadTree: ({ page }: PhiCmsDescriptorBuildContext) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
19
+ } | {
20
+ ownerModuleId: "@phis/ui/modules/public";
21
+ presetKey: "public-welcome-page";
22
+ presetVersion: number;
23
+ area: "public";
24
+ title: string;
25
+ path: string;
26
+ loadTree: ({ page, runtime }: PhiCmsDescriptorBuildContext) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
27
+ navigation?: undefined;
28
+ } | {
29
+ ownerModuleId: "@phis/ui/modules/public";
30
+ presetKey: "public-home-page";
31
+ presetVersion: number;
32
+ area: "public";
33
+ title: string;
34
+ path: string;
35
+ navigation: {
36
+ navKey: "public:header";
37
+ parentItemKey: null;
38
+ before: string;
39
+ item: {
40
+ itemKey: string;
41
+ label: {
42
+ defaultMessage: string;
43
+ };
44
+ icon: string;
45
+ routePresetKey: string;
46
+ };
47
+ }[];
48
+ loadTree: ({ page }: PhiCmsDescriptorBuildContext) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
49
+ } | {
50
+ ownerModuleId: "@phis/ui/modules/public";
51
+ presetKey: "public-terms-page";
52
+ presetVersion: number;
53
+ area: "public";
54
+ title: string;
55
+ path: string;
56
+ loadTree: ({ page }: PhiCmsDescriptorBuildContext & {
57
+ activeModuleIds: ReadonlySet<import("../contracts").PhiRuntimeModuleId>;
58
+ params: Readonly<Record<string, string>>;
59
+ }) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
60
+ navigation?: undefined;
61
+ })[];
62
+ /**
63
+ * The Public form pages, in their own list because they appear only where Forms are allowed. The
64
+ * contact page is Core's like the terms: every Site starts with a way to be reached, and neither is
65
+ * a landing -- the front door is the Site package's business.
66
+ */
67
+ export declare const PHI_PUBLIC_FORM_RUNTIME_MODULE_ROUTES: ({
68
+ ownerModuleId: "@phis/ui/modules/public";
69
+ presetKey: "public-contact-page";
70
+ presetVersion: number;
71
+ area: "public";
72
+ title: string;
73
+ path: string;
74
+ navigation: ({
75
+ navKey: "public:header";
76
+ parentItemKey: null;
77
+ after: string;
78
+ item: {
79
+ itemKey: string;
80
+ label: {
81
+ defaultMessage: string;
82
+ };
83
+ icon: string;
84
+ routePresetKey: string;
85
+ };
86
+ } | {
87
+ navKey: "public:footer";
88
+ parentItemKey: null;
89
+ after: string;
90
+ item: {
91
+ itemKey: string;
92
+ label: {
93
+ defaultMessage: string;
94
+ };
95
+ routePresetKey: string;
96
+ icon?: undefined;
97
+ };
98
+ })[];
99
+ loadTree: ({ page }: PhiCmsDescriptorBuildContext & {
100
+ activeModuleIds: ReadonlySet<import("../contracts").PhiRuntimeModuleId>;
101
+ params: Readonly<Record<string, string>>;
102
+ }) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
103
+ } | {
104
+ ownerModuleId: "@phis/ui/modules/public";
105
+ presetKey: "public-unsubscribe-page";
106
+ presetVersion: number;
107
+ area: "public";
108
+ title: string;
109
+ path: string;
110
+ navigation: never[];
111
+ loadTree: ({ page }: PhiCmsDescriptorBuildContext & {
112
+ activeModuleIds: ReadonlySet<import("../contracts").PhiRuntimeModuleId>;
113
+ params: Readonly<Record<string, string>>;
114
+ }) => Promise<import("../../../types").PhiResolvedCmsPageTree>;
115
+ })[];