@pitcher/js-api 1.29.0 → 1.31.0

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 (158) hide show
  1. package/js-api.esm.js +488 -56
  2. package/js-api.esm.js.map +1 -1
  3. package/js-api.umd.min.js +32 -11
  4. package/js-api.umd.min.js.map +1 -1
  5. package/lib/ai-tasks/__tests__/weekly-focus.spec.d.ts +1 -0
  6. package/lib/ai-tasks/weekly-focus.d.ts +241 -0
  7. package/lib/apps/browser/appTypes.d.ts +28 -0
  8. package/lib/apps/browser/components/ContextMenu/TranslateFileButton.test.d.ts +1 -0
  9. package/lib/apps/browser/stores/api.d.ts +6 -1
  10. package/lib/apps/browser/stores/api.filesFoldersDeleter.test.d.ts +1 -0
  11. package/lib/apps/browser/stores/app.d.ts +5 -0
  12. package/lib/apps/browser/stores/app.selectionPruneScope.test.d.ts +1 -0
  13. package/lib/apps/browser/stores/upload.d.ts +26 -1
  14. package/lib/apps/browser/stores/upload.types.d.ts +9 -0
  15. package/lib/apps/browser/util/lifecycle.d.ts +57 -0
  16. package/lib/apps/browser/util/lifecycle.test.d.ts +1 -0
  17. package/lib/apps/canvas-builder/components/container/PopupApps/PopupAppModal.spec.d.ts +1 -0
  18. package/lib/apps/canvas-builder/components/container/PresentationTools/PresentationToolsButtons.spec.d.ts +1 -0
  19. package/lib/apps/canvas-builder/components/ui/BottomSheetModal/BottomSheetModal.integration.spec.d.ts +1 -0
  20. package/lib/apps/canvas-builder/components/ui/BottomSheetModal/BottomSheetModal.spec.d.ts +1 -0
  21. package/lib/apps/canvas-builder/components/ui/DynamicContent/section-component-bindings.util.d.ts +32 -0
  22. package/lib/apps/canvas-builder/components/ui/DynamicContent/useDynamicContent.d.ts +6 -0
  23. package/lib/apps/canvas-builder/components/ui/Link/Link.util.d.ts +8 -1
  24. package/lib/apps/canvas-builder/components/ui/Link/Link.util.test.d.ts +1 -0
  25. package/lib/apps/canvas-builder/components/ui/Multimedia/Multimedia.ldAsset.spec.d.ts +1 -0
  26. package/lib/apps/canvas-builder/components/ui/SectionList/SectionItemModal.spec.d.ts +1 -0
  27. package/lib/apps/canvas-builder/composables/useCanvas.d.ts +286 -10
  28. package/lib/apps/canvas-builder/composables/useCanvas.saveEcho.spec.d.ts +1 -0
  29. package/lib/apps/canvas-builder/composables/useCanvasBlocks.d.ts +40 -2
  30. package/lib/apps/canvas-builder/composables/useCanvasExit.d.ts +1 -0
  31. package/lib/apps/canvas-builder/composables/useCanvasHistory.d.ts +38 -2
  32. package/lib/apps/canvas-builder/composables/useCanvasTheme.d.ts +4 -2
  33. package/lib/apps/canvas-builder/composables/useContentSelector.d.ts +8 -1
  34. package/lib/apps/canvas-builder/composables/useInstalledEmbeddables.d.ts +1 -1
  35. package/lib/apps/canvas-builder/composables/useNavigatorDrawer.d.ts +27 -0
  36. package/lib/apps/canvas-builder/composables/useNavigatorDrawer.spec.d.ts +1 -0
  37. package/lib/apps/canvas-builder/composables/usePopupApps.d.ts +43 -4
  38. package/lib/apps/canvas-builder/composables/usePopupApps.spec.d.ts +1 -0
  39. package/lib/apps/canvas-builder/composables/usePresentationTools.d.ts +112 -0
  40. package/lib/apps/canvas-builder/composables/usePresentationTools.spec.d.ts +1 -0
  41. package/lib/apps/canvas-builder/types/canvas.d.ts +66 -3
  42. package/lib/apps/canvas-builder/util/canvas.util.d.ts +12 -0
  43. package/lib/apps/canvas-builder/util/completionWizard.util.d.ts +347 -0
  44. package/lib/apps/canvas-builder/util/completionWizard.util.test.d.ts +1 -0
  45. package/lib/apps/canvas-builder/util/fullscreenMode.util.d.ts +7 -0
  46. package/lib/apps/canvas-builder/util/fullscreenMode.util.test.d.ts +1 -0
  47. package/lib/apps/canvas-builder/util/iframe.util.d.ts +24 -2
  48. package/lib/apps/canvas-builder/util/iframe.util.test.d.ts +1 -0
  49. package/lib/apps/canvas-builder/util/lazySections.util.d.ts +35 -0
  50. package/lib/apps/canvas-builder/util/lazySections.util.test.d.ts +1 -0
  51. package/lib/apps/canvas-selector/stores/app.d.ts +14 -0
  52. package/lib/apps/collection-player/components/AppHeader.spec.d.ts +1 -0
  53. package/lib/apps/collection-player/composables/collection-navigation.util.d.ts +27 -0
  54. package/lib/apps/collection-player/composables/collection-navigation.util.spec.d.ts +1 -0
  55. package/lib/apps/collection-player/composables/speaker-notes.use.d.ts +14 -0
  56. package/lib/apps/collection-player/composables/speaker-notes.use.spec.d.ts +1 -0
  57. package/lib/apps/collection-player/stores/app.store.d.ts +8 -1
  58. package/lib/apps/collection-player/stores/showNotesToggle.spec.d.ts +1 -0
  59. package/lib/apps/content-selector/appTypes.d.ts +16 -0
  60. package/lib/apps/content-selector/components/Assets.uploaderRefresh.spec.d.ts +1 -0
  61. package/lib/apps/content-selector/components/Content/AllContent/List/expandFileGuard.spec.d.ts +1 -0
  62. package/lib/apps/content-selector/stores/app.d.ts +1 -1
  63. package/lib/apps/notes/NotesApp.accountNotes.spec.d.ts +1 -0
  64. package/lib/apps/notes/NotesApp.speakerNotes.spec.d.ts +1 -0
  65. package/lib/apps/notes/composables/useAccountNotes.d.ts +14 -0
  66. package/lib/apps/notes/composables/useAccountNotes.spec.d.ts +1 -0
  67. package/lib/apps/notes/composables/useAccountOnlyNotesGate.d.ts +21 -0
  68. package/lib/apps/notes/composables/useAccountOnlyNotesGate.spec.d.ts +1 -0
  69. package/lib/apps/notes/composables/useActiveSlideNotes.d.ts +42 -0
  70. package/lib/apps/notes/composables/useActiveSlideNotes.spec.d.ts +1 -0
  71. package/lib/components/CFileAccessManagement/collaborationApi.d.ts +2 -0
  72. package/lib/components/CFilePanel/Details.spec.d.ts +1 -0
  73. package/lib/components/CFilePanel/KeyMessages.spec.d.ts +1 -0
  74. package/lib/components/CFilePanel/Summary.spec.d.ts +1 -0
  75. package/lib/components/CFileViewer/pdf/CFileViewer.pdf.annotations.use.d.ts +5 -1
  76. package/lib/components/CFileViewer/pdf/CFileViewer.pdf.formFields.use.d.ts +8 -0
  77. package/lib/components/CFileViewer/pdf/CFileViewer.pdf.link.use.d.ts +1 -1
  78. package/lib/components/CFileViewer/pdf/CFileViewer.pdf.overlayItems.use.d.ts +1 -1
  79. package/lib/components/CFileViewer/pdf/CFileViewer.pdf.use.d.ts +4 -9
  80. package/lib/components/CFileViewer/pdf/CFileViewer.pdf.util.d.ts +53 -1
  81. package/lib/components/CFileViewer/pdf/CFileViewerFullscreen.pdf.use.d.ts +1 -1
  82. package/lib/components/CFileViewer/pdf/__tests__/CFileViewer.pdf.annotations.text.test.d.ts +1 -0
  83. package/lib/components/CGlobalLoader/CGlobalLoaderMark.spec.d.ts +1 -0
  84. package/lib/components/CGlobalLoader/globalLoader.paths.d.ts +2 -0
  85. package/lib/components/CGlobalSearch/globalSearchTarget.util.d.ts +31 -0
  86. package/lib/components/CGlobalSearch/globalSearchTarget.util.test.d.ts +1 -0
  87. package/lib/components/CRichTextEditor/extensions/paragraphExtended.d.ts +7 -1
  88. package/lib/components/CRichTextEditor/extensions/paragraphExtended.test.d.ts +1 -0
  89. package/lib/components/canvases/CanvasesManagementBulk.use.d.ts +12 -2
  90. package/lib/components/masterCanvases/CMasterCanvasesManagement.use.d.ts +86 -0
  91. package/lib/components/masterCanvases/CMasterCanvasesManagement.use.spec.d.ts +1 -0
  92. package/lib/components/masterCanvases/CMasterCanvasesPendingShareCell.spec.d.ts +1 -0
  93. package/lib/components/masterCanvases/CMasterCanvasesSharedWithCell.use.d.ts +39 -0
  94. package/lib/components/masterCanvases/CMasterCanvasesSharedWithCell.use.spec.d.ts +1 -0
  95. package/lib/components/masterCanvases/createFromMaster.use.d.ts +255 -0
  96. package/lib/components/masterCanvases/createFromMaster.use.spec.d.ts +1 -0
  97. package/lib/components/masterCanvases/masterCanvasDocuments.use.d.ts +56 -0
  98. package/lib/components/masterCanvases/masterCanvasDocuments.use.spec.d.ts +1 -0
  99. package/lib/components/masterCanvases/masterCanvasShares.use.d.ts +103 -0
  100. package/lib/components/masterCanvases/masterCanvasShares.use.spec.d.ts +1 -0
  101. package/lib/components/masterCanvases/masterFromCanvas.use.d.ts +122 -0
  102. package/lib/components/masterCanvases/masterFromCanvas.use.spec.d.ts +1 -0
  103. package/lib/components/masterCanvases/masterFromTemplate.use.d.ts +50 -0
  104. package/lib/components/masterCanvases/masterFromTemplate.use.spec.d.ts +1 -0
  105. package/lib/components/savedCanvases/CSavedCanvasesManagement.use.d.ts +204 -0
  106. package/lib/components/savedCanvases/savedCanvasDocuments.use.d.ts +111 -0
  107. package/lib/components/savedCanvases/savedCanvasDocuments.use.spec.d.ts +1 -0
  108. package/lib/components/savedCanvases/smartFolders/SmartFolders.use.d.ts +4 -0
  109. package/lib/composables/useCourseOnlyApps.d.ts +1 -1
  110. package/lib/composables/usePdfInterpolation.d.ts +2 -2
  111. package/lib/composables/useWindowEvents.d.ts +1 -1
  112. package/lib/constants/cdp.const.d.ts +2 -0
  113. package/lib/constants/translationLanguages.const.d.ts +150 -0
  114. package/lib/constants/translationLanguages.const.spec.d.ts +1 -0
  115. package/lib/main.lib.d.ts +7 -0
  116. package/lib/sdk/api/HighLevelApi.d.ts +19 -6
  117. package/lib/sdk/api/modules/ai.d.ts +43 -1
  118. package/lib/sdk/api/modules/ai.spec.d.ts +1 -0
  119. package/lib/sdk/api/modules/appsDb.d.ts +4 -4
  120. package/lib/sdk/api/modules/canvas.d.ts +20 -0
  121. package/lib/sdk/api/modules/ui/types.ui.d.ts +25 -0
  122. package/lib/sdk/interfaces.d.ts +31 -1
  123. package/lib/sdk/main.d.ts +46 -0
  124. package/lib/sdk/payload.types.d.ts +149 -0
  125. package/lib/sdk/platform.d.ts +27 -0
  126. package/lib/sdk/platform.spec.d.ts +1 -0
  127. package/lib/sdk/singleton-scope.spec.d.ts +1 -0
  128. package/lib/sdk/utils/httpFetch.spec.d.ts +1 -0
  129. package/lib/theme/canvasUiUnoPreset.test.d.ts +1 -0
  130. package/lib/types/ai-tasks.const.d.ts +39 -1
  131. package/lib/types/app.d.ts +55 -1
  132. package/lib/types/call.d.ts +14 -0
  133. package/lib/types/canvases.d.ts +15 -0
  134. package/lib/types/launchDarkly.types.d.ts +8 -3
  135. package/lib/types/organizationSettings.types.d.ts +39 -0
  136. package/lib/util/aiSummary.d.ts +30 -0
  137. package/lib/util/aiSummary.spec.d.ts +1 -0
  138. package/lib/util/network.d.ts +35 -0
  139. package/lib/util/user.d.ts +18 -0
  140. package/lib/util/user.test.d.ts +1 -0
  141. package/package.json +1 -1
  142. package/types/openapi/models/Canvas.d.ts +1 -0
  143. package/types/openapi/models/CanvasCreate.d.ts +1 -0
  144. package/types/openapi/models/CanvasCreateRequest.d.ts +1 -0
  145. package/types/openapi/models/CanvasRecommendedFile.d.ts +1 -1
  146. package/types/openapi/models/CanvasRetrieve.d.ts +1 -0
  147. package/types/openapi/models/CanvasUpdate.d.ts +1 -0
  148. package/types/openapi/models/CanvasUpdateRequest.d.ts +1 -0
  149. package/types/openapi/models/DeletedCanvas.d.ts +1 -0
  150. package/types/openapi/models/DeletedEnvironment.d.ts +0 -1
  151. package/types/openapi/models/Environment.d.ts +0 -1
  152. package/types/openapi/models/EnvironmentRequest.d.ts +0 -1
  153. package/types/openapi/models/File.d.ts +3 -1
  154. package/types/openapi/models/FileRetrieve.d.ts +2 -0
  155. package/types/openapi/models/PatchedCanvasUpdateRequest.d.ts +1 -0
  156. package/types/openapi/models/PatchedEnvironmentRequest.d.ts +0 -1
  157. package/types/openapi/models/SharedLink.d.ts +6 -0
  158. package/types/openapi/models/SharedLinkCreateRequest.d.ts +5 -0
@@ -172,12 +172,33 @@ export interface CanvasFile {
172
172
  declare const MULTIMEDIA_IMG_TYPE: {
173
173
  readonly external: "external";
174
174
  readonly pitcher_asset: "pitcher_asset";
175
+ readonly ld_asset: "ld_asset";
175
176
  };
176
177
  export declare enum MultimediaHorizontalAlignmentOptions {
177
178
  LEFT = "left",
178
179
  CENTER = "center",
179
180
  RIGHT = "right"
180
181
  }
182
+ /**
183
+ * Where a Multimedia `poster_url` came from — shared by every asset variant, because a poster's origin is
184
+ * independent of the media's (an `external` video can carry an L&D-hosted poster).
185
+ *
186
+ * `poster_url` alone is unrefreshable: a short-lived source (an L&D presigned URL, 900s) rots and the
187
+ * canvas has no record of what it was, so nothing can re-resolve it — unlike `file.content_url`, which
188
+ * `Multimedia.vue` refreshes at render off `file.id`. Recording the id plus its backend is what keeps a
189
+ * poster recoverable.
190
+ *
191
+ * Both are absent for an external-link/Pexels poster (long-lived URL, no Pitcher id to resolve).
192
+ *
193
+ * `poster_asset_type` lives on the NODE rather than being read from host state at render, because the
194
+ * render path must work in COURSE (rep playback) — the mode where a poster is *guaranteed* to be past its
195
+ * TTL — and COURSE cannot supply `CanvasBuilderProps.assetType` at all (it's `?: never` there).
196
+ * (T1.7b / PIT-7742, R4-F1.)
197
+ */
198
+ type MultimediaPosterProvenance = {
199
+ poster_file_id?: string;
200
+ poster_asset_type?: 'pitcher_asset' | 'ld_asset';
201
+ };
181
202
  export type ExternalMultimediaAssetType = {
182
203
  asset_type: typeof MULTIMEDIA_IMG_TYPE.external;
183
204
  external_url: string;
@@ -186,7 +207,7 @@ export type ExternalMultimediaAssetType = {
186
207
  from?: 'custom' | 'pexels' | 'unsplash' | 'ai';
187
208
  poster_url?: string;
188
209
  poster_background_size?: BackgroundSize;
189
- };
210
+ } & MultimediaPosterProvenance;
190
211
  export type PitcherMultimediaAssetType = {
191
212
  asset_type: typeof MULTIMEDIA_IMG_TYPE.pitcher_asset;
192
213
  file: {
@@ -198,8 +219,20 @@ export type PitcherMultimediaAssetType = {
198
219
  horizontal_alignment?: MultimediaHorizontalAlignmentOptions;
199
220
  poster_url?: string;
200
221
  poster_background_size?: BackgroundSize;
201
- };
202
- export type MultimediaProps = ExternalMultimediaAssetType | PitcherMultimediaAssetType;
222
+ } & MultimediaPosterProvenance;
223
+ export interface LdMultimediaAssetType extends MultimediaPosterProvenance {
224
+ asset_type: typeof MULTIMEDIA_IMG_TYPE.ld_asset;
225
+ file: {
226
+ id: File['id'];
227
+ name: File['name'];
228
+ content_url?: File['content_url'];
229
+ };
230
+ type: 'image' | 'video';
231
+ horizontal_alignment?: MultimediaHorizontalAlignmentOptions;
232
+ poster_url?: string;
233
+ poster_background_size?: BackgroundSize;
234
+ }
235
+ export type MultimediaProps = ExternalMultimediaAssetType | PitcherMultimediaAssetType | LdMultimediaAssetType;
203
236
  export type ContentGridCommonFileProps = {
204
237
  id: FileRetrieve['id'];
205
238
  snapshot_id?: FileRetrieve['id'];
@@ -599,6 +632,7 @@ export type SharingBuilderProps = NoCRMBuilderProps & {
599
632
  };
600
633
  activeCanvas: CanvasRetrieve;
601
634
  onExit: () => void;
635
+ onEndCall?: () => void | Promise<void>;
602
636
  onSave?: never;
603
637
  onEnter?: () => void;
604
638
  onPageEnter?: (data: ComponentNode[], pageIndex: number) => void;
@@ -626,6 +660,7 @@ export type SharingBuilderProps = NoCRMBuilderProps & {
626
660
  listRecommendedFiles?: never;
627
661
  listCanvases?: never;
628
662
  fetchFolder?: never;
663
+ assetType?: never;
629
664
  fetchFile: (fileId: FileRetrieve['id']) => Promise<FileRetrieve>;
630
665
  fetchInstanceMetadataTemplate?: never;
631
666
  fetchCanvas?: (canvasId: CanvasRetrieve['id'], params?: Record<string, any>) => Promise<CanvasRetrieve>;
@@ -677,6 +712,7 @@ type AdminImpactCommonBuilderProps = {
677
712
  };
678
713
  activeCanvas: CanvasRetrieve;
679
714
  onExit: () => void;
715
+ onEndCall?: () => void | Promise<void>;
680
716
  onEnter?: () => void;
681
717
  onComponentEnter?: (data: ComponentNode | CanvasRetrieve, params: ComponentTrackingParams) => void;
682
718
  onComponentExit?: (data: ComponentNode | CanvasRetrieve, params: ComponentTrackingParams) => void;
@@ -735,6 +771,31 @@ type AdminImpactCommonBuilderProps = {
735
771
  isAnyTypeOfAdmin: boolean;
736
772
  canvasMetadata: CanvasMetadataRetrieve | null;
737
773
  hideEdit?: boolean;
774
+ /**
775
+ * PIT-8361 QA — the host cannot yet tell whether this canvas is frozen, so its `hideEdit` is a
776
+ * fail-safe placeholder rather than an answer.
777
+ *
778
+ * Only `isWizardOwnedEditSurface` reads it, and only to avoid concluding "not a wizard surface"
779
+ * from a `hideEdit` that means "don't know yet" — which dropped the rep into the RAW canvas
780
+ * editor on a wizard-driven canvas for the length of one API call. The WRITE guard
781
+ * (`shouldAutoOpenCompletionWizard`) deliberately still refuses while `hideEdit` is true.
782
+ *
783
+ * Falsy default is the safe one — a host that never sets it behaves exactly as before, which
784
+ * also keeps it clear of Vue's absent-boolean-is-`false` casting.
785
+ */
786
+ isFreezePending?: boolean;
787
+ /**
788
+ * Which asset backend the Assets tab's files come from, stamped onto a Multimedia node on selection
789
+ * (`prepareMultimediaNodeData`). Defaults to `'pitcher_asset'`, so every existing sales/DSR/admin
790
+ * mount is unchanged — only the L&D course host (course-canvas-host) opts into `'ld_asset'`.
791
+ *
792
+ * Lives on the Admin/Impact/Home common props because those are the only modes that can open the
793
+ * content selector; SHARING/COURSE type-block it with `?: never`.
794
+ *
795
+ * It does NOT affect rendering — Multimedia keys its render-time URL re-resolution off the node's
796
+ * own `asset_type`, so an `ld_asset` node renders correctly wherever it is mounted. (T1.7b/PIT-7742)
797
+ */
798
+ assetType?: 'pitcher_asset' | 'ld_asset';
738
799
  };
739
800
  type AdminBuilderProps = AdminImpactCommonBuilderProps & (CRMBuilderProps | NoCRMBuilderProps) & {
740
801
  isRedirectEvent?: never;
@@ -784,6 +845,7 @@ export type CourseBuilderProps = NoCRMBuilderProps & {
784
845
  };
785
846
  activeCanvas: CanvasRetrieve;
786
847
  onExit: () => void;
848
+ onEndCall?: () => void | Promise<void>;
787
849
  onSave?: (canvasId: CanvasRetrieve['id'], canvas: PatchedCanvasUpdateRequest & {
788
850
  fields?: string;
789
851
  include_expired_files?: boolean;
@@ -814,6 +876,7 @@ export type CourseBuilderProps = NoCRMBuilderProps & {
814
876
  listRecommendedFiles?: never;
815
877
  listCanvases?: never;
816
878
  fetchFolder?: never;
879
+ assetType?: never;
817
880
  fetchFile: (fileId: FileRetrieve['id']) => Promise<FileRetrieve>;
818
881
  fetchInstanceMetadataTemplate?: never;
819
882
  fetchCanvas?: (canvasId: CanvasRetrieve['id'], params?: Record<string, any>) => Promise<CanvasRetrieve>;
@@ -57,6 +57,18 @@ type FoundComponent = {
57
57
  } | null;
58
58
  export declare function findEmbeddableInSectionsContent(canvasPages: ComponentNode[][], sectionComponentNodesBySectionId: UnwrapRef<SectionComponentNodesBySectionId>, appName: string): FoundComponent;
59
59
  export declare function findAllEmbeddableTypesInCanvasContent(componentNodesById: UnwrapRef<ComponentNodesById>): Set<string>;
60
+ /**
61
+ * Section ids the deck's OWN content references (SectionList/ContentList `data.sections`).
62
+ *
63
+ * `activeCanvas.sections` is a strict SUPERSET of these: Django's `prefetch_sections`
64
+ * deliberately merges the TEMPLATE's sections in (so wizard steps and pickers can offer
65
+ * them), and the presentation-tools modal registers lookup-only entries (PIT-8031).
66
+ * Anything that means "what is actually presentable in this deck" — the embeddable
67
+ * shortcut icons chiefly — must filter the lookup through these ids, or it renders
68
+ * affordances for slides that do not exist (PIT-8031 QA Q1: dead tool shortcuts on any
69
+ * deck whose template carries tool groups the rep never selected).
70
+ */
71
+ export declare function findReferencedSectionIdsInCanvasContent(componentNodesById: UnwrapRef<ComponentNodesById>): Set<string>;
60
72
  export declare function findAllEmbeddableTypesInSectionsContent(sectionComponentNodesBySectionId: UnwrapRef<SectionComponentNodesBySectionId>): Set<string>;
61
73
  export declare function findEmbeddableInCanvasContent(componentNodesById: UnwrapRef<ComponentNodesById>, appName: string): FoundComponent;
62
74
  export declare function scrollToComponentById(id: ComponentNode['id'] | null | undefined, sectionId?: string, sectionIndex?: number, instant?: boolean, delay?: number): void;
@@ -0,0 +1,347 @@
1
+ import { CanvasActions } from '../../../types/canvasActions';
2
+ import { ComponentNode } from '../types/canvas';
3
+ import { AppFile } from '../../../types/app';
4
+ /** Installable-app name of the React pitchdeck wizard (PIT-7510). */
5
+ export declare const REACT_COMPLETION_WIZARD_APP_NAME = "pitchdeck-wizard-ng";
6
+ export interface ResolveCompletionWizardVariantParams {
7
+ /** `canvas.enable_react_completion_wizard` org/instance setting — opt-in, default off. */
8
+ isReactWizardSettingEnabled: boolean;
9
+ /** The React wizard app resolved to a loadable URL (installed or local dev override). */
10
+ isReactWizardAvailable: boolean;
11
+ /**
12
+ * The host has not delivered the installed-apps roster yet (PIT-7992): `undefined` apps,
13
+ * as opposed to a loaded-but-empty list. While pending, "no React app" cannot be told
14
+ * apart from "not loaded yet", so the decision is deferred rather than falling back.
15
+ */
16
+ isRosterPending?: boolean;
17
+ }
18
+ /**
19
+ * PIT-7510: which completion-wizard implementation to render where the wizard opens today.
20
+ * The setting is the only switch (no LaunchDarkly flag); an enabled setting without an
21
+ * installed app falls back to the Vue wizard so no flow is ever lost.
22
+ *
23
+ * An enabled instance NEVER sees the Vue wizard for config reasons (PIT-8021 QA Q3,
24
+ * decided by Bastien in comment 515871): templates carrying group features the React
25
+ * wizard does not implement — visibility rules, repetition rules — still open the React
26
+ * wizard, which simply does not apply them (the groups behave as ordinary groups). The
27
+ * earlier per-deck fallback honored those rules but meant an admin ticking one condition
28
+ * silently swapped every rep back to the legacy flow, which reads as a regression.
29
+ *
30
+ * `'pending'` (PIT-7992): the React setting is on but the host's app roster hasn't loaded,
31
+ * so availability is unknowable. Deciding 'vue' here is what flashed the LEGACY wizard on
32
+ * templates with a non-app step ('wizard' strategy passes `getCompletionWizardStepNodes`
33
+ * without the roster, so the overlay condition goes true before the roster lands) — the
34
+ * caller must render NEITHER wizard until the roster resolves the real variant.
35
+ */
36
+ export declare function resolveCompletionWizardVariant(p: ResolveCompletionWizardVariantParams): 'vue' | 'react' | 'pending';
37
+ /**
38
+ * Resolve the React wizard app's iframe URL: local dev override first (same mechanism as
39
+ * every installable app), else the installed app's `content_url`.
40
+ */
41
+ export declare function resolveReactCompletionWizardSrc(apps: AppFile[]): string | null;
42
+ /**
43
+ * PIT-7030: what cancelling the completion wizard means depends on how it was entered.
44
+ *
45
+ * Create flow (never-completed deck): cancel abandons the deck — the host emits
46
+ * `cancelCanvasCompletionWizard`, which slotty treats as "leave the canvas" (and deletes the
47
+ * deck when it came from the create-canvas modal).
48
+ *
49
+ * Edit flow (`completion_wizard.edited` — set by `retriggerWizard()`, i.e. the "Edit Wizard"
50
+ * button or the Edit-action auto-open): the wizard was opened over a deck that was already
51
+ * completed, and entering it persisted `completed: false`. Cancel must restore
52
+ * `completed: true` and reload into the canvas editor — exactly what the Vue wizard's
53
+ * `confirmCancel()` → `completeWizard()` does. Emitting the cancel event here instead exits
54
+ * the canvas entirely and leaves the deck stuck "In-progress" (the QA regression on the
55
+ * React wizard).
56
+ */
57
+ interface WizardCancelCanvasContext {
58
+ pitcher?: {
59
+ /** `edited` is written only by `retriggerWizard()` — the same signal the Vue wizard's `isEditWizard` reads. */
60
+ completion_wizard?: {
61
+ edited?: boolean;
62
+ completed?: boolean;
63
+ };
64
+ };
65
+ }
66
+ export declare function shouldCompleteWizardOnCancel(canvasContext: WizardCancelCanvasContext | null | undefined): boolean;
67
+ export interface IsWizardOwnedEditSurfaceParams {
68
+ /** `canvas.enable_edit_opens_completion_wizard` — the opt-in. */
69
+ isSettingEnabled: boolean;
70
+ isImpact: boolean;
71
+ isCanvas: boolean;
72
+ isCanvasPreviewMode: boolean;
73
+ /** The host's "this canvas is not editable" signal (frozen / RBAC / lock). */
74
+ hideEdit: boolean;
75
+ /**
76
+ * The host cannot yet tell whether the canvas is frozen, so `hideEdit` is a placeholder rather
77
+ * than an answer. See the doc comment for why this exists.
78
+ */
79
+ isFreezePending?: boolean;
80
+ /** The deck carries wizard steps, or wizard state from a previous session. */
81
+ hasWizardState: boolean;
82
+ }
83
+ /**
84
+ * PIT-7992 — whether the WIZARD owns this canvas's edit surface, i.e. a rep must never land in the
85
+ * raw canvas editor here because the wizard IS the deck's edit surface.
86
+ *
87
+ * PIT-8361 QA — `isFreezePending` is why this is a function rather than an inline `&&` chain.
88
+ * slotty computes `hideEdit` as `props.hideEdit || isCanvasFrozen`, and `isCanvasFrozen` is SEEDED
89
+ * TRUE for any org with the freeze flag, then corrected by an API round-trip. In that window
90
+ * `hideEdit: true` means "not yet known to be editable" — a fail-safe about WRITING, not a
91
+ * statement that this is not a wizard surface. Reading it as the latter released the surface, so
92
+ * nothing demoted the builder out of edit mode and the rep was dropped into the raw editor on a
93
+ * wizard-driven canvas for the length of one network call.
94
+ *
95
+ * Holding the surface while pending is safe either way it resolves: not frozen → the wizard opens
96
+ * as intended; genuinely frozen → the canvas has already been demoted out of edit mode, which is
97
+ * where a frozen canvas belongs. Note this only ever excuses `hideEdit` — it can never resurrect a
98
+ * surface the other gates rejected.
99
+ *
100
+ * The WRITE guard is deliberately NOT relaxed the same way: `shouldAutoOpenCompletionWizard` keeps
101
+ * its hard `hideEdit` bail, because `retriggerWizard()` persists `completed: false` and must not
102
+ * touch a canvas that may turn out to be frozen. It re-runs once the status resolves.
103
+ */
104
+ export declare function isWizardOwnedEditSurface(p: IsWizardOwnedEditSurfaceParams): boolean;
105
+ /**
106
+ * PIT-8361 — whether COMPLETING the wizard should EXIT the builder instead of reloading it.
107
+ *
108
+ * The complete path ends in `reloadAfterCompletionWizard()`, and for a DECK that is right: the
109
+ * wizard just rewrote the deck's `content`, the rep stays in the builder to present it, and one
110
+ * page load is the cheapest way to guarantee every component re-renders from the saved artifact.
111
+ *
112
+ * For a MASTER it is wrong, and visibly so. A master's builder is a place the rep is LEAVING —
113
+ * `savedCanvasCompletionWizard` already returns them to "My Master Pitchdecks", which refetches on
114
+ * arrival (`shouldRefetchOnMasterBuilderReturn`), so the freshly authored master is on screen
115
+ * without a reload. Reloading instead reboots the whole slotty iframe on the master builder URL,
116
+ * so the rep gets a flash of the master's own view state (the `enable_edit_opens_completion_wizard`
117
+ * demote watcher in `App.vue` rewrites edit -> present on the way back up), then the app's boot
118
+ * spinner, then a rebuilt sidebar — the reported defect, and never the tab they asked for.
119
+ *
120
+ * **Orthogonal to `resolveWizardFlow`**, which deliberately STOPPED special-casing masters
121
+ * (PIT-7488 QA Q9). That decision is about how a wizard session OPENS — create vs restore — and
122
+ * forcing masters to `edit` there restored them from an artifact that did not exist yet. This one
123
+ * is about how a session ENDS. The two read as contradictory only if you miss that distinction.
124
+ *
125
+ * Callers must also skip `markCompletionWizardAutoOpened()` on the exit branch: that marker exists
126
+ * purely to suppress one auto-open on the post-reload mount, so with no reload it survives and
127
+ * swallows the rep's next deliberate Edit (PIT-7510 Q12).
128
+ */
129
+ export declare function shouldExitBuilderOnWizardComplete(p: {
130
+ isMaster?: boolean | null;
131
+ }): boolean;
132
+ /** The wizard state the flow decision reads — `context.pitcher.completion_wizard`. */
133
+ export interface WizardFlowState {
134
+ /** Set by `retriggerWizard()` — the wizard was reopened over an already-completed deck. */
135
+ edited?: boolean;
136
+ completed?: boolean;
137
+ /** A Save & Exit draft: restores like an edit session but cancels like a draft. */
138
+ react_saved?: boolean;
139
+ /**
140
+ * PIT-8399 — this canvas's content was COPIED from a curated source (a master), so its own
141
+ * persisted artifact is the authoritative agenda even though it carries no wizard progress.
142
+ *
143
+ * Written by `buildContextFromMaster` (master -> deck) and next-core's `buildSharedCopyContext`
144
+ * (master -> shared copy), which both reset the source's progress so the wizard runs. It is
145
+ * deliberately not one of the three flags above: see `resolveWizardAgendaSource`.
146
+ */
147
+ from_master?: boolean;
148
+ }
149
+ export interface ResolveWizardFlowParams {
150
+ wizardState?: WizardFlowState | null;
151
+ }
152
+ /**
153
+ * Which flow the React wizard is opened in: `'edit'` restores from the canvas's own artifact,
154
+ * `'create'` seeds a fresh one.
155
+ *
156
+ * Masters are NOT special-cased here, deliberately (PIT-7488 QA Q9). They were briefly forced to
157
+ * `'edit'` to dodge the app's account-demanding entry dialog, and it worked — but restoring a
158
+ * master that had never been through the wizard meant an empty cover, an agenda rebuilt by
159
+ * attribution rather than seeded from the admin groups, and an "Update Pitchdeck" button, since
160
+ * `editorLabelKeys` reads this very value. Suppressing that dialog is now `skipEntry`'s job, which
161
+ * leaves this answering the only question it should: has this canvas been through the wizard
162
+ * before? A fresh master says no and gets `'create'`; once saved it says yes and `'edit'` restores
163
+ * something that actually exists.
164
+ */
165
+ export declare function resolveWizardFlow(p: ResolveWizardFlowParams): 'create' | 'edit';
166
+ /**
167
+ * PIT-8399 — where the CREATE flow's agenda comes from: the admin group config, or this deck's own
168
+ * persisted artifact.
169
+ *
170
+ * A second declared fact rather than a lookup on `resolveWizardFlow`, for the reason `target_kind`
171
+ * is one (PIT-8361): the flow says whether the deck has been through the wizard, this says whether
172
+ * its content was authored somewhere else first. Both are true of a deck built from a master —
173
+ * never wizarded ITSELF, but carrying a complete artifact copied from the master — and that pair is
174
+ * exactly what one boolean could not express. Overloading `completion_wizard`'s presence to answer
175
+ * both is the reported defect: stripping it made the deck look never-curated, so the wizard reseeded
176
+ * its agenda from the admin groups and every custom agenda point the master carried vanished.
177
+ *
178
+ * `'artifact'` therefore requires `from_master` AND no progress of the deck's own. Progress means
179
+ * `resolveWizardFlow` already answers `'edit'`, whose full restore supersedes this — the deck has
180
+ * been saved since it was copied, so its artifact is its own rather than the master's. Stating the
181
+ * precedence here keeps the app's gate a plain equality check instead of a second copy of this rule.
182
+ */
183
+ export declare function resolveWizardAgendaSource(p: ResolveWizardFlowParams): 'config' | 'artifact';
184
+ /**
185
+ * The `completed: true` write that undoes `retriggerWizard()`'s `completed: false`.
186
+ *
187
+ * Both wizard hosts persist it on the edit-cancel and the torn-down-mid-session paths, and both
188
+ * must write context AND metadata (the deck's In-progress/Completed badge reads `metadata`, the
189
+ * wizard's own guards read `context` — leaving one behind desyncs the badge from the flow).
190
+ */
191
+ export declare function buildCompletedStateRestore(canvasContext: Record<string, any> | null | undefined, canvasMetadata: Record<string, any> | null | undefined): {
192
+ context: Record<string, any>;
193
+ metadata: Record<string, any>;
194
+ };
195
+ /**
196
+ * The SectionList/ContentList nodes that become completion-wizard steps — the single source of
197
+ * truth behind `useCanvasCompletionWizard`'s `sectionListNodes` (and so `isCompletionWizardEnabled`).
198
+ *
199
+ * Extracted as a pure function because hosts need the same answer BEFORE the canvas-builder mounts:
200
+ * slotty decides whether to auto-enter fullscreen while it still only has the raw canvas record
201
+ * (PIT-7720 Q1). Duplicating the predicate there would silently drift from the wizard's own gate.
202
+ *
203
+ * A step whose `app` strategy points at an app that is not installed (and has no local dev override)
204
+ * does NOT count — the wizard skips it, so a deck made only of those never opens a wizard at all.
205
+ */
206
+ export declare function getCompletionWizardStepNodes(canvasContent: ComponentNode[] | null | undefined, sectionSelectorApps: AppFile[]): ComponentNode[];
207
+ export interface HasPendingCompletionWizardParams {
208
+ /** The deck's component tree (`canvas.content`). */
209
+ canvasContent: ComponentNode[] | null | undefined;
210
+ /** Installed section-selector apps — the same list the builder provides as `sectionSelectorApps`. */
211
+ sectionSelectorApps: AppFile[];
212
+ /** The deck's `canvas.context`; `pitcher.completion_wizard.completed` decides "still pending". */
213
+ canvasContext: {
214
+ pitcher?: {
215
+ completion_wizard?: {
216
+ completed?: boolean;
217
+ };
218
+ };
219
+ } | null | undefined;
220
+ }
221
+ /**
222
+ * Whether opening this deck lands the rep in the completion wizard — the host-side mirror of
223
+ * `isCompletionWizardShowing` (`wizard has steps && !completed`), answerable from the raw canvas
224
+ * record alone.
225
+ *
226
+ * PIT-7720 Q1: used to suppress the PIT-7029 auto-fullscreen, which otherwise wraps the WIZARD in
227
+ * native browser fullscreen on open — the rep is still building the deck, not presenting it.
228
+ */
229
+ export declare function hasPendingCompletionWizard(p: HasPendingCompletionWizardParams): boolean;
230
+ export declare function isCompletionWizardReloadInProgress(): boolean;
231
+ /**
232
+ * Drop the slide-anchor query params (`section` + `component`, written by the present
233
+ * view's `router.replace`) from a URL, wherever the host's router keeps its query:
234
+ * slotty is hash-history (the params sit INSIDE `#/...?...`), other hosts are plain
235
+ * history (real `?...`). Both places are cleaned; everything else is preserved.
236
+ */
237
+ export declare function stripWizardSlideAnchor(href: string): string;
238
+ /**
239
+ * One-shot reload-survival marker paired with the URL strip below, consumed by the HOST's
240
+ * builder boot (slotty `CanvasBuilder.vue`): ignore any slide anchor on the route for the
241
+ * one boot that follows a post-wizard reload. The strip alone is not enough — slotty runs
242
+ * inside the Impact shell, and the shell's location ROOT survives the iframe reload and
243
+ * RESTORES the pre-wizard route (query included) into slotty's router before the builder
244
+ * mounts, resurrecting the anchor the strip just removed (PIT-8021 QA Q5 round 2: the
245
+ * regenerated deck opened mid-deck again with the strip deployed). sessionStorage so it
246
+ * survives exactly the reload and nothing else; consumed on first read so a later manual
247
+ * navigation with a real anchor works normally.
248
+ */
249
+ export declare function consumeWizardReloadAnchorSkip(): boolean;
250
+ /** `reload` is injectable only because jsdom's `window.location` is unforgeable in tests. */
251
+ export declare function reloadAfterCompletionWizard(reload?: () => void): void;
252
+ export declare function wasCompletionWizardAutoOpened(canvasId: string): boolean;
253
+ export declare function markCompletionWizardAutoOpened(canvasId: string | undefined): void;
254
+ /**
255
+ * Read AND clear the auto-opened marker (PIT-7510 QA Q12). The marker exists to survive the
256
+ * `window.location.reload()` that follows completing/cancelling the wizard — one page load.
257
+ * Left in place it suppressed every LATER Edit action for the rest of the browser session,
258
+ * so the wizard never auto-opened again. Consuming it on read keeps the reload covered
259
+ * (the fresh mount still sees it once) while the next explicit Edit navigation starts
260
+ * clean. Callers cache the consumed value per mount so re-running watcher ticks within the
261
+ * same mount stay suppressed.
262
+ */
263
+ export declare function consumeCompletionWizardAutoOpened(canvasId: string): boolean;
264
+ export interface ShouldAutoOpenCompletionWizardParams {
265
+ /** `canvas.enable_edit_opens_completion_wizard` org/instance setting — opt-in, default off. */
266
+ isSettingEnabled: boolean;
267
+ /** Impact only — the wizard is a rep-facing flow and `retriggerWizard()` bails elsewhere anyway. */
268
+ isImpact: boolean;
269
+ /** Canvases only, never templates / sections / blocks. */
270
+ isCanvas: boolean;
271
+ /** Canvas preview is read-only playback; never auto-open there. */
272
+ isCanvasPreviewMode: boolean;
273
+ /** The mode the builder was opened in (`metadata.startInMode`). */
274
+ startInMode?: CanvasActions;
275
+ /** Editing is unavailable: RBAC, `disable_canvas_edit_for_reps`, or a frozen canvas. */
276
+ hideEdit: boolean;
277
+ /** `canRetriggerWizard()` — the canvas has wizard steps AND the wizard is already completed. */
278
+ canRetriggerWizard: boolean;
279
+ /** Active canvas id — required so the caller can persist the per-canvas dedup marker. */
280
+ canvasId?: string;
281
+ /**
282
+ * Whether this canvas was already auto-opened in the CURRENT page load (PIT-7510 Q12). The
283
+ * caller reads this via `consumeCompletionWizardAutoOpened` — a read-and-clear `sessionStorage`
284
+ * marker (keyed by canvas id) rather than mount-local state, because the wizard completion path
285
+ * (`completeWizard()`) runs `window.location.reload()`, which remounts the whole builder. A
286
+ * mount-local flag would reset on that reload and the `{ immediate: true }` watcher would
287
+ * auto-reopen the wizard, producing the open→cancel→reload→reopen flash loop (PIT-7030). The
288
+ * marker is consumed per mount, so a LATER Edit open of the same deck auto-opens again.
289
+ */
290
+ alreadyAutoOpened: boolean;
291
+ }
292
+ /**
293
+ * PIT-7030: decide whether opening a canvas via the Edit action should reopen the completion
294
+ * wizard instead of landing in the canvas editor.
295
+ *
296
+ * Pure so the guard chain is unit-testable — the caller performs the (async, persisting)
297
+ * `retriggerWizard()` side effect.
298
+ *
299
+ * A never-completed deck already shows the wizard through `isCompletionWizardShowing`, so this
300
+ * only covers the completed case, which is what `canRetriggerWizard` encodes.
301
+ */
302
+ export declare function shouldAutoOpenCompletionWizard(p: ShouldAutoOpenCompletionWizardParams): boolean;
303
+ /**
304
+ * PIT-8361 QA Q2 — remember the mode each canvas was ENTERED in, because `startInMode` does not
305
+ * stay still long enough for the auto-open to read it.
306
+ *
307
+ * The defect it fixes is a race between two `{ immediate: true }` watchers in `App.vue` and slotty's
308
+ * URL rewrite, which is why QA saw the wizard open on some master Edits and not others:
309
+ *
310
+ * 1. The auto-open watcher runs first and bails while `completionWizardVariant` is `'pending'` —
311
+ * i.e. until the HOST's installed-app roster lands (a network round-trip on a cold boot; warm
312
+ * and synchronous once slotty has it, which is the "sometimes it works" half).
313
+ * 2. The demote watcher then fires on the same mount and sets `isEditMode = false` (correctly — the
314
+ * wizard owns this surface). Slotty turns that into a new `startInMode` **through the URL**:
315
+ * `edit-mode-changed` → `onEditModeChanged` → `CanvasBuilderModalView`'s local `isEditMode` →
316
+ * its watcher → `debouncedUpdateUrl` (**250 ms**) → `router.replace` to the twin *present*
317
+ * route → `CanvasBuilder.getStartMode()`, which on a routed open has `props.initialEditMode ===
318
+ * undefined` and falls through to `isCanvasBuilderPresentRoute(route.name)` → `Present`.
319
+ * (`:initialEditMode` is bound from the PROP, never from that local ref — there is no prop echo.)
320
+ * 3. The roster lands, the auto-open watcher re-runs — and now rejects its own canvas on
321
+ * `startInMode !== Edit`. The rep is left on the raw canvas surface with no wizard, on a deck
322
+ * the platform has just decided the wizard owns.
323
+ *
324
+ * So the race window is that **250 ms debounce**: a roster resolving inside it auto-opens with or
325
+ * without this helper, one resolving after it used to be rejected. Anyone shortening, removing or
326
+ * relocating `updateUrl`'s debounce is changing the wizard's behaviour. Both master child routes
327
+ * render the same `CanvasBuilderModalView` under an unkeyed `<RouterView>`, so step 2's `replace`
328
+ * patches the component in place rather than remounting it — which is what lets a latch survive
329
+ * the rewrite at all.
330
+ *
331
+ * Latching restores what `startInMode` is documented to mean ("the mode the builder was opened
332
+ * in"), which is a fact about an ENTRY and can only be observed before the host starts rewriting
333
+ * the URL under it. Keyed by canvas id rather than latched once per mount so that
334
+ * `useCanvasOverlay`, which swaps canvases in place without remounting, still gets a fresh reading
335
+ * per canvas — the same reason `autoOpenInFlightCanvasIds` is a set of ids.
336
+ *
337
+ * Pass-through (no latching) while the canvas id is unknown: there is nothing to key on yet, and
338
+ * the auto-open needs an id anyway.
339
+ *
340
+ * An UNKNOWN mode is not latched either. `startInMode` is optional on `CanvasBuilderProps`, so a
341
+ * host can hand over a canvas id before it has an entry mode — and latching `undefined` there would
342
+ * pin it forever, so the Edit that arrived a tick later could never open the wizard. That is the
343
+ * same defect this helper exists to fix, one layer up. Latch the first mode that is actually
344
+ * KNOWN, not the first observation.
345
+ */
346
+ export declare function createEntryModeLatch(): (canvasId: string | undefined, startInMode: CanvasActions | undefined) => CanvasActions | undefined;
347
+ export {};
@@ -0,0 +1,7 @@
1
+ import { FullscreenMode } from '../../../types/organizationSettings.types';
2
+ /**
3
+ * The presentation fullscreen mode to use: the rep's explicit in-presentation
4
+ * choice wins; otherwise the org/instance default; otherwise 'fullscreen'
5
+ * (preserving PIT-7029's auto-enter-native behaviour).
6
+ */
7
+ export declare function resolvePresentationFullscreenMode(repChosen: FullscreenMode | null, defaultSetting: FullscreenMode | undefined): FullscreenMode;
@@ -1,13 +1,35 @@
1
1
  /**
2
2
  * Utility functions for iframe full screen mode positioning
3
3
  */
4
+ /**
5
+ * Marker class on `SectionItemModal`'s scrollable body. A section canvas rendered in that
6
+ * modal (presentation tools, DynamicContent's section preview, SectionList/ContentList item
7
+ * modals) is NOT inside the deck's content box, so a full-screen embeddable must size itself
8
+ * against the modal body instead — see `positionFullScreenIframe`.
9
+ */
10
+ export declare const SECTION_MODAL_CONTENT_SELECTOR = ".section-item-modal__content";
4
11
  export interface FullScreenPositionOptions {
5
12
  container: HTMLElement;
6
13
  canvasContentSelector?: string;
14
+ /** Ancestor that, when present, owns the geometry instead of the deck content box. */
15
+ modalContentSelector?: string;
7
16
  }
8
17
  /**
9
- * Positions an iframe container in full screen mode
10
- * Calculates height from current position to bottom of parent window
18
+ * Positions an iframe container in full screen mode.
19
+ *
20
+ * Two hosts, two coordinate systems (PIT-8147):
21
+ *
22
+ * - **Deck** — the component renders inside the running presentation, so the container is
23
+ * pinned (`fixed`) to the deck content box and stretched to the bottom of the window.
24
+ * - **Section modal** — the component renders in `SectionItemModal`, an overlay ON TOP of the
25
+ * deck. Copying the deck's box there lands the app under the modal's dead space (offset
26
+ * right/down) and runs it past the modal body's bottom edge, where `overflow-auto` clips it.
27
+ * `fixed` is wrong twice over: while the modal panel slides in or out it carries a `transform`,
28
+ * which makes it the containing block for fixed descendants, so "viewport" coordinates flip
29
+ * meaning between mid-slide and at rest. The modal body IS the
30
+ * full-screen surface, so stay in flow and take exactly its height — no coordinates to get
31
+ * wrong, and the modal's own max-width/centering keeps applying. `relative` is kept so the
32
+ * container still anchors its own absolutely positioned children (the loading overlay).
11
33
  */
12
34
  export declare function positionFullScreenIframe(options: FullScreenPositionOptions): void;
13
35
  /**
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ import { CanvasSection } from '../../../../types/openapi';
2
+ /**
3
+ * Helpers for opt-in lazy section loading (`?lazy_sections=true`, PIT-7073).
4
+ *
5
+ * A lazy shell response carries ordered `section_ids` plus lightweight section
6
+ * STUBS — `{ id, name, thumbnail_url, metadata, is_draft, content: { data: [] } }`
7
+ * — so list views (ToC, section rail) render immediately while the real bodies
8
+ * stream in via the batch endpoint.
9
+ */
10
+ /**
11
+ * A stub carries an empty placeholder `content`; a hydrated body has components.
12
+ * This is how we tell "not fetched yet" from "fetched".
13
+ */
14
+ export declare const isHydratedSection: (section?: CanvasSection | null) => boolean;
15
+ /**
16
+ * Merge an incoming shell's sections over what we already hold, keeping any body
17
+ * we've already hydrated.
18
+ *
19
+ * A shell gets RE-APPLIED constantly: every embedded-app canvas update (each
20
+ * Shopping Cart change in the PRH apps) round-trips the canvas through the host,
21
+ * which hands back the lazy shell. Applying it verbatim would wipe the hydrated
22
+ * bodies, so the deck blanks and visibly BLINKS while it re-fetches them.
23
+ *
24
+ * Section bodies are separate canvases, so a deck-level update never invalidates
25
+ * them — carrying them forward is safe. An incoming section that IS hydrated
26
+ * always wins, so a genuine section refresh still lands.
27
+ */
28
+ export declare const preserveHydratedSections: (previous: CanvasSection[] | undefined, incoming: CanvasSection[]) => CanvasSection[];
29
+ /**
30
+ * The subset of `section_ids` that still needs fetching.
31
+ *
32
+ * Without this a re-applied shell would re-download every body on each
33
+ * interaction — on a 1k-section deck that's a full request storm per cart click.
34
+ */
35
+ export declare const pendingSectionIds: (sectionIds: string[], sections: CanvasSection[] | undefined) => string[];