@elevasis/ui 2.73.0 → 2.75.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 (97) hide show
  1. package/dist/api/index.js +3 -3
  2. package/dist/app/index.d.ts +58 -0
  3. package/dist/app/index.js +9 -10
  4. package/dist/auth/index.js +5 -6
  5. package/dist/charts/index.js +5 -6
  6. package/dist/chunk-2GIJBHZT.js +60 -0
  7. package/dist/{chunk-Z4ICFQXG.js → chunk-2ZRY3ARL.js} +1 -1
  8. package/dist/{chunk-5B2ZFO44.js → chunk-3H5DIJN7.js} +1 -1
  9. package/dist/{chunk-LZT2H2MA.js → chunk-47YJVIZE.js} +36 -43
  10. package/dist/{chunk-3TS5U5BL.js → chunk-5RH6NYZH.js} +1 -1
  11. package/dist/chunk-5SLRGUC4.js +224 -0
  12. package/dist/{chunk-JYBJMVNY.js → chunk-5VF5LPYS.js} +1 -1
  13. package/dist/{chunk-SWKAH2YM.js → chunk-6BJ5HMMC.js} +282 -553
  14. package/dist/{chunk-NI37YNRP.js → chunk-7OOFMEX6.js} +11 -5
  15. package/dist/{chunk-IBCEAVB2.js → chunk-A2SB32YV.js} +65 -5
  16. package/dist/{chunk-CJ2232PQ.js → chunk-CRPH5AAB.js} +1 -1
  17. package/dist/chunk-D3XXPCCK.js +69 -0
  18. package/dist/chunk-DMSTDZCJ.js +305 -0
  19. package/dist/chunk-DTEGVSJ6.js +645 -0
  20. package/dist/chunk-DVAOCHIF.js +165 -0
  21. package/dist/chunk-G7O4CBMC.js +231 -0
  22. package/dist/{chunk-IGBPWD6S.js → chunk-GDTK33QT.js} +5 -3
  23. package/dist/chunk-ICHDIVQO.js +54 -0
  24. package/dist/{chunk-U2H3TIHD.js → chunk-IYATYH5I.js} +2 -52
  25. package/dist/chunk-L3NBMLRN.js +49 -0
  26. package/dist/{chunk-LEPYXLJ2.js → chunk-LFLM723H.js} +1 -1
  27. package/dist/chunk-M6VAZAQW.js +45 -0
  28. package/dist/{chunk-AJOVWB47.js → chunk-MLHZUN2X.js} +6 -3
  29. package/dist/chunk-N6K2Q5BM.js +393 -0
  30. package/dist/chunk-NMHQAYZU.js +439 -0
  31. package/dist/chunk-NYIIRZSA.js +286 -0
  32. package/dist/{chunk-ETN3TTRT.js → chunk-OGHTJKBV.js} +115 -8
  33. package/dist/{chunk-M7WWRZ5Z.js → chunk-QFGNRKIE.js} +1 -78
  34. package/dist/chunk-QFS2GZMV.js +515 -0
  35. package/dist/{chunk-OCVSPAKM.js → chunk-SB3IHM5Y.js} +1150 -4346
  36. package/dist/{chunk-4CW2C5BD.js → chunk-SEYOVNS5.js} +1 -1
  37. package/dist/chunk-SN7X5N2A.js +116 -0
  38. package/dist/{chunk-PQ4B62HH.js → chunk-TX3UHDL5.js} +2 -2
  39. package/dist/chunk-VM2OWOXL.js +24 -0
  40. package/dist/{chunk-ZDKPHFTH.js → chunk-VWGCURZF.js} +5 -3
  41. package/dist/chunk-WDBNW44Z.js +49 -0
  42. package/dist/chunk-YQQ5GRUR.js +21 -0
  43. package/dist/{chunk-NHNTX6ZL.js → chunk-ZG6YJUT4.js} +3 -2
  44. package/dist/components/index.d.ts +228 -6
  45. package/dist/components/index.js +321 -35
  46. package/dist/components/navigation/index.js +6 -7
  47. package/dist/features/auth/index.d.ts +78 -2
  48. package/dist/features/auth/index.js +18 -9
  49. package/dist/features/clients/index.js +7 -7
  50. package/dist/features/content/index.d.ts +226 -5
  51. package/dist/features/content/index.js +270 -19
  52. package/dist/features/crm/index.d.ts +58 -0
  53. package/dist/features/crm/index.js +10 -8
  54. package/dist/features/dashboard/index.js +9 -8
  55. package/dist/features/delivery/index.d.ts +58 -0
  56. package/dist/features/delivery/index.js +23 -7
  57. package/dist/features/knowledge/index.js +5 -6
  58. package/dist/features/lead-gen/index.d.ts +9 -15
  59. package/dist/features/lead-gen/index.js +12 -8
  60. package/dist/features/monitoring/index.js +11 -9
  61. package/dist/features/monitoring/requests/index.js +8 -7
  62. package/dist/features/operations/index.js +15 -11
  63. package/dist/features/public-agent-chat/index.js +3 -1
  64. package/dist/features/settings/index.d.ts +66 -3
  65. package/dist/features/settings/index.js +9 -8
  66. package/dist/hooks/access/index.js +5 -6
  67. package/dist/hooks/delivery/index.d.ts +58 -0
  68. package/dist/hooks/delivery/index.js +3 -2
  69. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +1 -1
  70. package/dist/hooks/published.d.ts +181 -5
  71. package/dist/hooks/published.js +22 -6
  72. package/dist/initialization/index.d.ts +58 -0
  73. package/dist/knowledge/index.js +167 -11
  74. package/dist/{knowledge-search-index-RZLIVWPJ.js → knowledge-search-index-6GQK55IQ.js} +1 -1
  75. package/dist/layout/index.js +8 -9
  76. package/dist/profile/index.d.ts +58 -0
  77. package/dist/provider/index.d.ts +77 -1
  78. package/dist/provider/index.js +5 -6
  79. package/dist/provider/published.d.ts +105 -1
  80. package/dist/provider/published.js +5 -6
  81. package/dist/test-utils/index.d.ts +16 -5
  82. package/dist/test-utils/index.js +17 -18
  83. package/dist/types/index.d.ts +73 -1
  84. package/dist/utils/index.d.ts +83 -3
  85. package/dist/utils/index.js +1 -1
  86. package/package.json +10 -5
  87. package/dist/chunk-6M6OLGQY.js +0 -36
  88. package/dist/chunk-MKH2KOAO.js +0 -39
  89. package/dist/hooks/index.css +0 -659
  90. package/dist/hooks/index.d.ts +0 -14073
  91. package/dist/hooks/index.js +0 -27
  92. package/dist/supabase/index.d.ts +0 -7118
  93. package/dist/supabase/index.js +0 -3
  94. package/dist/typeform/index.d.ts +0 -462
  95. package/dist/typeform/index.js +0 -2051
  96. package/dist/typeform/schemas.d.ts +0 -67
  97. package/dist/typeform/schemas.js +0 -2
@@ -200,10 +200,25 @@ interface SidebarGroupNode {
200
200
  }
201
201
  type SidebarNode = SidebarSurfaceNode | SidebarGroupNode;
202
202
 
203
- /** D5: who/what executes a content pipeline step. */
203
+ /**
204
+ * D5: who/what executes a content pipeline step.
205
+ *
206
+ * `'human'` was added on 2026-08-21, when the workspace shell started rendering its
207
+ * stepper from `steps[]`. Before that a step meant "a pass that writes a
208
+ * `content_item_attempts` row", so the stages a person walks -- picking files,
209
+ * framing them, sending the post -- were declared nowhere and lived as integer
210
+ * constants in one tenant's page. A catalog that describes only the automated half
211
+ * of a pipeline cannot be the thing a workspace renders, so the vocabulary widened
212
+ * to cover the whole sequence rather than the shell inventing a second one.
213
+ *
214
+ * A `'human'` step writes no attempt. That is expected, not a gap: `reviewMode`
215
+ * still says whether a decision gates it, and the surfaces that group by
216
+ * `stepKey` simply find no rows against it.
217
+ */
204
218
  declare const ContentPipelineStepActorSchema: z.ZodEnum<{
205
219
  agent: "agent";
206
220
  workflow: "workflow";
221
+ human: "human";
207
222
  vendor: "vendor";
208
223
  }>;
209
224
  type ContentPipelineStepActor = z.infer<typeof ContentPipelineStepActorSchema>;
@@ -1416,9 +1431,50 @@ declare const ContentSourceAssetResponseSchema: z.ZodObject<{
1416
1431
  createdAt: z.ZodString;
1417
1432
  updatedAt: z.ZodString;
1418
1433
  }, z.core.$strip>;
1434
+ declare const ContentDistributionResponseSchema: z.ZodObject<{
1435
+ id: z.ZodString;
1436
+ organizationId: z.ZodString;
1437
+ contentItemId: z.ZodString;
1438
+ platform: z.ZodString;
1439
+ format: z.ZodString;
1440
+ status: z.ZodString;
1441
+ adaptedBody: z.ZodNullable<z.ZodString>;
1442
+ platformContent: z.ZodNullable<z.ZodUnknown>;
1443
+ checklist: z.ZodNullable<z.ZodUnknown>;
1444
+ mediaUrls: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1445
+ kind: z.ZodLiteral<"storage">;
1446
+ bucket: z.ZodString;
1447
+ path: z.ZodString;
1448
+ }, z.core.$strict>, z.ZodObject<{
1449
+ kind: z.ZodLiteral<"url">;
1450
+ url: z.ZodString;
1451
+ }, z.core.$strict>], "kind">>;
1452
+ processingState: z.ZodRecord<z.ZodString, z.ZodObject<{
1453
+ status: z.ZodEnum<{
1454
+ error: "error";
1455
+ success: "success";
1456
+ running: "running";
1457
+ no_result: "no_result";
1458
+ skipped: "skipped";
1459
+ }>;
1460
+ attemptId: z.ZodString;
1461
+ executionId: z.ZodNullable<z.ZodString>;
1462
+ attemptedAt: z.ZodString;
1463
+ data: z.ZodOptional<z.ZodUnknown>;
1464
+ }, z.core.$loose>>;
1465
+ publishMethod: z.ZodNullable<z.ZodString>;
1466
+ publishedAt: z.ZodNullable<z.ZodString>;
1467
+ platformPostId: z.ZodNullable<z.ZodString>;
1468
+ platformUrl: z.ZodNullable<z.ZodString>;
1469
+ metrics: z.ZodUnknown;
1470
+ metricsUpdatedAt: z.ZodNullable<z.ZodString>;
1471
+ createdAt: z.ZodString;
1472
+ updatedAt: z.ZodString;
1473
+ }, z.core.$strip>;
1419
1474
  type ContentAssetCrop = z.infer<typeof ContentAssetCropSchema>;
1420
1475
  type ContentItemResponse = z.infer<typeof ContentItemResponseSchema>;
1421
1476
  type ContentSourceAssetResponse = z.infer<typeof ContentSourceAssetResponseSchema>;
1477
+ type ContentDistributionResponse = z.infer<typeof ContentDistributionResponseSchema>;
1422
1478
 
1423
1479
  /**
1424
1480
  * `deriveContentBoard` -- a pure function of `(items, pipeline, now)`. No React, no
@@ -2438,7 +2494,7 @@ interface ContentSidebarProps {
2438
2494
  declare const ContentSidebar: ({ workspaceItems, createItems, children }?: ContentSidebarProps) => react_jsx_runtime.JSX.Element;
2439
2495
 
2440
2496
  /**
2441
- * Static two-entry default, built from {@link DEFAULT_CONTENT_VOCABULARY}. Exists for
2497
+ * Static three-entry default, built from {@link DEFAULT_CONTENT_VOCABULARY}. Exists for
2442
2498
  * consumers that spread it at module load time (see `extend-content.md`), where a
2443
2499
  * tenant's declared vocabulary isn't available. `ContentSidebarMiddle` itself renders
2444
2500
  * the live, vocabulary-aware version instead of this constant.
@@ -2463,7 +2519,7 @@ interface ContentSidebarMiddleProps {
2463
2519
  * that section now holds review too.
2464
2520
  */
2465
2521
  createItems?: NavItem[];
2466
- /** Override the pipeline nav items. Defaults to the two-entry nav built from the tenant's declared vocabulary. */
2522
+ /** Override the pipeline nav items. Defaults to the three-entry nav built from the tenant's declared vocabulary. */
2467
2523
  items?: NavItem[];
2468
2524
  }
2469
2525
  /**
@@ -2511,5 +2567,170 @@ interface MyReviewQueuePanelProps {
2511
2567
  */
2512
2568
  declare function MyReviewQueuePanel({ onItemClick, onSeeAll, showSectionLabel }: MyReviewQueuePanelProps): react_jsx_runtime.JSX.Element;
2513
2569
 
2514
- export { AlternatesPanel, AssetCropEditor, CAPTION_STEP_KEY, CAPTION_WORKFLOW_ID, CONTENT_DERIVATIVES_BUCKET, CONTENT_ITEMS, CROP_ASPECT_OPTIONS, CaptionPanel, ContentDistributionDetailPage, ContentDistributionsPage, ContentItemReviewPage, ContentItemsPage, ContentOverviewPage, ContentPipelineBoardPage, ContentPipelineBoardPage as ContentPipelineWorkspacePage, ContentPipelinesPage, ContentReviewCard, ContentSidebar, ContentSidebarMiddle, DEFAULT_CONTENT_VOCABULARY, DERIVATIVE_JPEG_QUALITY, DERIVATIVE_MAX_WIDTH, IMAGE_ANALYSIS_WORKFLOW_ID, MyReviewQueuePanel, PayloadBody, PostPreview, ProcessingStateStrip, ReviewActionBar, SelectedAssetStrip, SlideAnalysisPanel, SourceAssetsPanel, contentManifest, cropStyle, derivativeObjectKey, deriveContentBoard, firstLine, formatElapsed, getContentItemIdentity, isDerivativeStale, lastLine, readStoredAnalysis, renderCropToJpeg, resolveContentStepResource, resolveContentVocabulary, swapFirstLine, swapLastLine, useContentConfig };
2515
- export type { AlternatesPanelProps, AssetCropEditorProps, CaptionPanelProps, ContentAlternateOption, ContentBoard, ContentBoardCard, ContentBoardColumn, ContentBoardGate, ContentConfig, ContentDistributionDetailPageSlots, ContentDistributionsPageSlots, ContentFidelityCheck, ContentItemReviewPageSlots, ContentItemsPageSlots, ContentNoun, ContentOverviewPageSlots, ContentPayloadField, ContentPipelineBoardPageSlots, ContentPipelineBoardPageSlots as ContentPipelineWorkspacePageSlots, ContentPipelinesPageSlots, ContentProcessingStatus, ContentProcessingStep, ContentReviewAction, ContentReviewCardProps, ContentSidebarMiddleProps, ContentSidebarProps, ContentStepResourceBinding, ContentVocabulary, CropAspectOption, MyReviewQueuePanelProps, PayloadBodyProps, PostPreviewProps, PostPreviewSlide, ProcessingStateStripProps, RenderCropOptions, ReviewActionBarProps, ReviewMode, SelectedAssetStripProps, SlideAnalysisPanelProps, SourceAssetsPanelProps, StoredSlideAnalysis };
2570
+ /**
2571
+ * What every step panel is handed, and the only thing the workspace shell owns.
2572
+ *
2573
+ * The shell fixes four things and nothing else: it remembers the work in progress,
2574
+ * it moves between steps, it draws the stepper from the tenant's own step list, and
2575
+ * it renders the panel that tenant's map names for the active step. Step count, step
2576
+ * order, labels, actors, review modes, statuses, platforms and every screen a step
2577
+ * puts up come from the model and from the composing app.
2578
+ *
2579
+ * `TDraft` is whatever the composing app's panels share and the shell has no opinion
2580
+ * about -- a cloud-storage selection, per-slide crops, a chosen platform. It is
2581
+ * carried, never read.
2582
+ */
2583
+ interface ContentWorkspaceState<TDraft> {
2584
+ /** The pipeline being walked, resolved from the organization model. */
2585
+ pipeline: ContentPipelineTemplate;
2586
+ /** Its steps, in declared order. Never assume a length or a particular member. */
2587
+ steps: ContentPipelineStepEntry[];
2588
+ /** The step on screen. */
2589
+ step: ContentPipelineStepEntry;
2590
+ /** Its index within {@link steps}. */
2591
+ stepIndex: number;
2592
+ /**
2593
+ * The item, once something has written one. `null` before that.
2594
+ *
2595
+ * Kept live rather than held as the create response: a caption promoted by a panel
2596
+ * changes `body`, and a preview reading the create snapshot would show the old one.
2597
+ */
2598
+ item: ContentItemResponse | null;
2599
+ /** Adopt a written item -- after creating one, or on resuming an existing one. */
2600
+ setItem: (item: ContentItemResponse | null) => void;
2601
+ /**
2602
+ * The item's body as it stands: the unsaved draft when a panel has reported one,
2603
+ * the saved body otherwise.
2604
+ *
2605
+ * This is shell state rather than tenant draft state because every pipeline that
2606
+ * writes a body has an in-progress one, and more than one step reads it -- the step
2607
+ * that writes it, the preview beside it, and the step that sends it out. Leaving it
2608
+ * to each app is how the two disagree.
2609
+ */
2610
+ body: string;
2611
+ /** The unsaved body, or `null` when no panel has reported one. */
2612
+ bodyDraft: string | null;
2613
+ setBodyDraft: (draft: string | null) => void;
2614
+ /**
2615
+ * The distribution row for this item, or `null`. First row only -- a second
2616
+ * platform is a second distribution and nothing here creates one yet.
2617
+ */
2618
+ distribution: ContentDistributionResponse | null;
2619
+ /** Re-read the distributions after a panel has written one. */
2620
+ refetchDistributions: () => void;
2621
+ /** Whatever the composing app's own panels share. */
2622
+ draft: TDraft;
2623
+ /** Merge a patch, or replace via an updater. */
2624
+ setDraft: (update: Partial<TDraft> | ((current: TDraft) => TDraft)) => void;
2625
+ /** Move to a step by key. Ignored when the key names no step in this pipeline. */
2626
+ goToStep: (stepKey: string) => void;
2627
+ goToNextStep: () => void;
2628
+ goToPreviousStep: () => void;
2629
+ /** Whether a step can be opened right now, per the composing app's own rule. */
2630
+ canOpenStep: (step: ContentPipelineStepEntry) => boolean;
2631
+ /**
2632
+ * Install a guard the shell awaits before leaving the active step, or clear it
2633
+ * with `null`.
2634
+ *
2635
+ * This exists because some steps have work that only makes sense to finish on the
2636
+ * way out -- rendering a crop, flushing an edit -- and the panel is the only thing
2637
+ * that knows what that work is. Install it from an effect and clear it on unmount.
2638
+ */
2639
+ registerLeaveGuard: (guard: ((to: ContentPipelineStepEntry) => Promise<void> | void) | null) => void;
2640
+ /** Drop everything and return to the start. */
2641
+ restart: () => void;
2642
+ }
2643
+ /** A component registered to render one step. */
2644
+ type ContentStepPanel<TDraft> = ComponentType<ContentWorkspaceState<TDraft>>;
2645
+ /**
2646
+ * Which panel renders which step, keyed by step key.
2647
+ *
2648
+ * An explicit map rather than a convention on the step key: a tenant that renames a
2649
+ * step would otherwise silently lose its panel with nothing on screen to say so,
2650
+ * whereas a missing entry here is reported. It also takes any component, so a tenant
2651
+ * can use published panels for some steps and its own for the rest.
2652
+ */
2653
+ type ContentStepPanelMap<TDraft> = Record<string, ContentStepPanel<TDraft>>;
2654
+ /** What the opening screen can do, when the composing app renders one. */
2655
+ interface ContentWorkspaceStartControls {
2656
+ /** Begin a new item at the first step. */
2657
+ onStartNew: () => void;
2658
+ /** Pick up an existing item. The shell adopts it and opens `resumeAtStepKey`. */
2659
+ onResume: (item: ContentItemResponse, resumeAtStepKey?: string) => void;
2660
+ }
2661
+ interface ContentWorkspaceShellProps<TDraft> {
2662
+ /**
2663
+ * Which pipeline to walk. Defaults to the content System's own
2664
+ * `config.defaultPipelineId` when omitted.
2665
+ */
2666
+ pipelineId?: string;
2667
+ /** See {@link ContentStepPanelMap}. */
2668
+ panels: ContentStepPanelMap<TDraft>;
2669
+ /** The starting value of the app's own shared draft. Also what `restart` returns to. */
2670
+ initialDraft: TDraft;
2671
+ title: string;
2672
+ caption?: string;
2673
+ /** Rendered at the right of the page title -- a credential badge, a mode switch. */
2674
+ headerRight?: ReactNode;
2675
+ /**
2676
+ * The opening screen, before any step is shown: a resume picker, a template
2677
+ * chooser, or nothing. Omit it and the shell opens on the first step.
2678
+ */
2679
+ renderStart?: (controls: ContentWorkspaceStartControls) => ReactNode;
2680
+ /**
2681
+ * Rendered on every step whatever panel is active, between the stepper and the
2682
+ * panel. For the banner naming the work in progress, and for cross-step effects
2683
+ * that must outlive the panel that started them.
2684
+ */
2685
+ renderPersistent?: (state: ContentWorkspaceState<TDraft>) => ReactNode;
2686
+ /**
2687
+ * The column beside the active panel -- typically the thing being built. Return
2688
+ * `null` for a step that wants the full width, and the shell drops the column
2689
+ * rather than rendering an empty one.
2690
+ */
2691
+ renderAside?: (state: ContentWorkspaceState<TDraft>) => ReactNode;
2692
+ /**
2693
+ * Whether a step is openable. Defaults to "any step at or before the furthest one
2694
+ * reached", which is what makes going back free and going forward deliberate.
2695
+ */
2696
+ canOpenStep?: (step: ContentPipelineStepEntry, state: ContentWorkspaceState<TDraft>) => boolean;
2697
+ /** Test id on the page root, so a composing app's tests can find its own workspace. */
2698
+ testId?: string;
2699
+ }
2700
+
2701
+ /**
2702
+ * The frame a tenant's content pipeline is walked in.
2703
+ *
2704
+ * **It draws the stepper from the model, not from itself.** One `Stepper.Step` per
2705
+ * entry in `ContentPipelineTemplate.steps`, using that entry's own label and order,
2706
+ * its description below the row once the step is active, and the panel the composing
2707
+ * app registered for its key. A pipeline with
2708
+ * three steps renders three; one with seven renders seven; one that puts the caption
2709
+ * second renders it second. Nothing here knows what a crop or a carousel is.
2710
+ *
2711
+ * **It owns only what every step shares** -- the item, its unsaved body, the
2712
+ * distribution row, and where in the sequence you are. Everything else is the
2713
+ * composing app's, carried through `draft` untouched. The panels are stateless and
2714
+ * take this object; the app decides what they are.
2715
+ *
2716
+ * The reason the frame owns that much rather than less: those are exactly the values
2717
+ * more than one step reads, and the two live defects in the page this replaced were
2718
+ * both cross-step state bugs. Pushing them into each app reproduces those bugs once
2719
+ * per tenant.
2720
+ */
2721
+ declare function ContentWorkspaceShell<TDraft>({ pipelineId, panels, initialDraft, title, caption, headerRight, renderStart, renderPersistent, renderAside, canOpenStep, testId }: ContentWorkspaceShellProps<TDraft>): react_jsx_runtime.JSX.Element;
2722
+
2723
+ /**
2724
+ * The analysis step, ready to register.
2725
+ *
2726
+ * `SlideAnalysisPanel` was already universal -- it takes an item id and nothing else
2727
+ * -- so what was missing was only the shape the shell calls it with. That is all this
2728
+ * is: the panel, plus the two moves either side of it.
2729
+ *
2730
+ * Registers under whatever key the tenant's own step catalog uses; nothing here reads
2731
+ * a step key.
2732
+ */
2733
+ declare function ContentAnalysisStepPanel<TDraft>(state: ContentWorkspaceState<TDraft>): react_jsx_runtime.JSX.Element;
2734
+
2735
+ export { AlternatesPanel, AssetCropEditor, CAPTION_STEP_KEY, CAPTION_WORKFLOW_ID, CONTENT_DERIVATIVES_BUCKET, CONTENT_ITEMS, CROP_ASPECT_OPTIONS, CaptionPanel, ContentAnalysisStepPanel, ContentDistributionDetailPage, ContentDistributionsPage, ContentItemReviewPage, ContentItemsPage, ContentOverviewPage, ContentPipelineBoardPage, ContentPipelineBoardPage as ContentPipelineWorkspacePage, ContentPipelinesPage, ContentReviewCard, ContentSidebar, ContentSidebarMiddle, ContentWorkspaceShell, DEFAULT_CONTENT_VOCABULARY, DERIVATIVE_JPEG_QUALITY, DERIVATIVE_MAX_WIDTH, IMAGE_ANALYSIS_WORKFLOW_ID, MyReviewQueuePanel, PayloadBody, PostPreview, ProcessingStateStrip, ReviewActionBar, SelectedAssetStrip, SlideAnalysisPanel, SourceAssetsPanel, contentManifest, cropStyle, derivativeObjectKey, deriveContentBoard, firstLine, formatElapsed, getContentItemIdentity, isDerivativeStale, lastLine, readStoredAnalysis, renderCropToJpeg, resolveContentStepResource, resolveContentVocabulary, swapFirstLine, swapLastLine, useContentConfig };
2736
+ export type { AlternatesPanelProps, AssetCropEditorProps, CaptionPanelProps, ContentAlternateOption, ContentBoard, ContentBoardCard, ContentBoardColumn, ContentBoardGate, ContentConfig, ContentDistributionDetailPageSlots, ContentDistributionsPageSlots, ContentFidelityCheck, ContentItemReviewPageSlots, ContentItemsPageSlots, ContentNoun, ContentOverviewPageSlots, ContentPayloadField, ContentPipelineBoardPageSlots, ContentPipelineBoardPageSlots as ContentPipelineWorkspacePageSlots, ContentPipelinesPageSlots, ContentProcessingStatus, ContentProcessingStep, ContentReviewAction, ContentReviewCardProps, ContentSidebarMiddleProps, ContentSidebarProps, ContentStepPanel, ContentStepPanelMap, ContentStepResourceBinding, ContentVocabulary, ContentWorkspaceShellProps, ContentWorkspaceStartControls, ContentWorkspaceState, CropAspectOption, MyReviewQueuePanelProps, PayloadBodyProps, PostPreviewProps, PostPreviewSlide, ProcessingStateStripProps, RenderCropOptions, ReviewActionBarProps, ReviewMode, SelectedAssetStripProps, SlideAnalysisPanelProps, SourceAssetsPanelProps, StoredSlideAnalysis };
@@ -1,18 +1,18 @@
1
+ import { useCloudStorageTemporaryLinks, useStorageSignedUrls, storageObjectRefKey } from '../../chunk-5SLRGUC4.js';
1
2
  import { PageContainer } from '../../chunk-BZZCNLT6.js';
2
3
  import '../../chunk-TUMSNGTX.js';
3
4
  import { FilterBar } from '../../chunk-PDHTXPSF.js';
4
- import { CustomModal, useContentItemSourceAssetDetails, useContentSourceAssets, useAddContentItemSourceAsset, useRemoveContentItemSourceAsset, useReorderContentItemSourceAssets, useUpdateContentItemSourceAsset, useCloudStorageTemporaryLinks, useContentItemAttempts, useExecuteAsync, useUpdateContentItem, useExecution, contentKeys, useContentItems, useContentDistributions, useContentConfig, isAwaitingReview, SubshellContentContainer, PageTitleCaption, CenteredErrorState, EmptyState, StatCard, getContentItemIdentity, usePaginationState, resolveCurrentContentStep, useContentItem, useReviewContentItem, resolveReviewTarget, useContentDistribution, useStorageSignedUrls, storageObjectRefKey, useContentPipelineSummary, deriveContentBoard, resolveContentWorkspaceRoute, useExecutions } from '../../chunk-OCVSPAKM.js';
5
- export { CONTENT_ITEMS, ContentSidebar, ContentSidebarMiddle, DEFAULT_CONTENT_VOCABULARY, MyReviewQueuePanel, contentManifest, deriveContentBoard, getContentItemIdentity, resolveContentStepResource, resolveContentVocabulary, useContentConfig } from '../../chunk-OCVSPAKM.js';
5
+ import { CustomModal, useContentItemSourceAssetDetails, useContentSourceAssets, useAddContentItemSourceAsset, useRemoveContentItemSourceAsset, useReorderContentItemSourceAssets, useUpdateContentItemSourceAsset, useContentItemAttempts, useExecuteAsync, useUpdateContentItem, useExecution, contentKeys, useContentItems, useContentDistributions, useContentConfig, isAwaitingReview, SubshellContentContainer, PageTitleCaption, CenteredErrorState, EmptyState, StatCard, getContentItemIdentity, usePaginationState, resolveCurrentContentStep, useContentItem, useReviewContentItem, resolveReviewTarget, useContentDistribution, useContentDistributionMetrics, useContentPipelineSummary, deriveContentBoard, resolveContentWorkspaceRoute, useExecutions } from '../../chunk-SB3IHM5Y.js';
6
+ export { CONTENT_ITEMS, ContentSidebar, ContentSidebarMiddle, DEFAULT_CONTENT_VOCABULARY, MyReviewQueuePanel, contentManifest, deriveContentBoard, getContentItemIdentity, resolveContentStepResource, resolveContentVocabulary, useContentConfig } from '../../chunk-SB3IHM5Y.js';
6
7
  import '../../chunk-R6NMRXNO.js';
7
8
  import '../../chunk-RBGVNPA6.js';
8
- import '../../chunk-MKH2KOAO.js';
9
- import '../../chunk-NHNTX6ZL.js';
9
+ import '../../chunk-ZG6YJUT4.js';
10
10
  import '../../chunk-L7BZZ4SI.js';
11
- import { showSuccessNotification } from '../../chunk-U2H3TIHD.js';
11
+ import { showSuccessNotification } from '../../chunk-ICHDIVQO.js';
12
12
  import '../../chunk-MISHPEJX.js';
13
13
  import { CardHeader } from '../../chunk-62GVNH5U.js';
14
14
  import '../../chunk-P45GQ3ZW.js';
15
- import '../../chunk-M7WWRZ5Z.js';
15
+ import '../../chunk-2GIJBHZT.js';
16
16
  import '../../chunk-3KMDHCAR.js';
17
17
  import '../../chunk-2IFYDILW.js';
18
18
  import '../../chunk-BLXJEIQS.js';
@@ -20,7 +20,7 @@ import '../../chunk-UD657ICS.js';
20
20
  import '../../chunk-DD3CCMCZ.js';
21
21
  import '../../chunk-RNP5R5I3.js';
22
22
  import '../../chunk-RT4KRGZT.js';
23
- import { formatTimeAgo, formatRelativeTime } from '../../chunk-IBCEAVB2.js';
23
+ import { formatTimeAgo, formatRelativeTime } from '../../chunk-A2SB32YV.js';
24
24
  import '../../chunk-Y6I3IC45.js';
25
25
  import '../../chunk-6SSQGWK7.js';
26
26
  import '../../chunk-BI5VDO2K.js';
@@ -29,7 +29,7 @@ import '../../chunk-TVTSASST.js';
29
29
  import '../../chunk-BRJ3QZ4E.js';
30
30
  import '../../chunk-Q7DJKLEN.js';
31
31
  import '../../chunk-I2KLQ2HA.js';
32
- import { Stack, Group, Text, Badge, Button, Textarea, Box, Loader, Accordion, Tooltip, Card, Alert, List, Paper, SegmentedControl, Slider, Title, Table, TextInput, Select, Modal, ActionIcon, Center, SimpleGrid, Pagination, Tabs, Anchor, Divider, Progress, Image as Image$1, UnstyledButton, ScrollArea } from '@mantine/core';
32
+ import { Stack, Group, Text, Badge, Button, Textarea, Box, Loader, Accordion, Tooltip, Card, Alert, List, Paper, SegmentedControl, Slider, Title, Table, TextInput, Select, Modal, ActionIcon, Center, SimpleGrid, Pagination, Tabs, Anchor, Divider, Progress, Image as Image$1, Stepper, Grid, UnstyledButton, ScrollArea } from '@mantine/core';
33
33
  import { IconAlertTriangle, IconShieldCheck, IconShieldX, IconPhoto, IconGripVertical, IconCrop, IconArrowUp, IconArrowDown, IconUnlink, IconLink, IconPhotoOff, IconChevronLeft, IconChevronRight, IconCheck, IconSparkles, IconEye, IconArticle, IconArrowRight, IconClock, IconSend, IconSearch, IconFileText, IconExternalLink, IconListDetails, IconAlertCircle, IconLayoutGrid, IconShare, IconPlayerPlay, IconCircleCheck, IconCircleDashed, IconMaximize, IconCopy, IconDownload, IconArrowLeft, IconArrowsExchange, IconX, IconChecklist, IconRoute, IconInfoCircle, IconClockHour4 } from '@tabler/icons-react';
34
34
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
35
35
  import { useState, useRef, useCallback, useMemo, useEffect, Fragment as Fragment$1 } from 'react';
@@ -961,10 +961,13 @@ function SourceAssetsPanel({ itemId }) {
961
961
  size: "xs",
962
962
  placeholder: "Describe this slide",
963
963
  value: draft ?? storedAltText,
964
- onChange: (event) => setAltDrafts((drafts) => ({
965
- ...drafts,
966
- [membership.sourceAssetId]: event.currentTarget.value
967
- }))
964
+ onChange: (event) => {
965
+ const value = event.currentTarget.value;
966
+ setAltDrafts((drafts) => ({
967
+ ...drafts,
968
+ [membership.sourceAssetId]: value
969
+ }));
970
+ }
968
971
  }
969
972
  ),
970
973
  draft !== void 0 && draft !== storedAltText && /* @__PURE__ */ jsx(
@@ -2314,17 +2317,18 @@ function ContentPipelinesPage({ headerActions } = {}) {
2314
2317
  ] }) }) });
2315
2318
  }
2316
2319
  var ACTOR_LEAD = {
2317
- vendor: "An outside service",
2318
- workflow: "An automated workflow",
2319
- agent: "An AI agent"
2320
+ vendor: "An outside service handles",
2321
+ workflow: "An automated workflow handles",
2322
+ agent: "An AI agent handles",
2323
+ human: "You do"
2320
2324
  };
2321
2325
  var REVIEW_VENUE_TAIL = {
2322
2326
  workspace: "and you review it on your own screen, in the moment",
2323
2327
  queue: "then it waits for your review",
2324
- none: "and moves on without review"
2328
+ none: "with no review after it"
2325
2329
  };
2326
2330
  function describeStep(step) {
2327
- return `${ACTOR_LEAD[step.actor]} handles "${step.label}," ${REVIEW_VENUE_TAIL[step.reviewVenue]}.`;
2331
+ return `${ACTOR_LEAD[step.actor]} "${step.label}," ${REVIEW_VENUE_TAIL[step.reviewVenue]}.`;
2328
2332
  }
2329
2333
  function StepRow({ step, resourceId }) {
2330
2334
  return /* @__PURE__ */ jsxs(Group, { gap: "sm", align: "flex-start", wrap: "nowrap", children: [
@@ -2740,6 +2744,13 @@ var QUERY_LIMIT = 100;
2740
2744
  function formatDate(value) {
2741
2745
  return value ? new Date(value).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) : "\u2014";
2742
2746
  }
2747
+ function summarizeMetrics2(metrics) {
2748
+ if (!metrics || typeof metrics !== "object" || Array.isArray(metrics)) return "\u2014";
2749
+ const entries = Object.entries(metrics);
2750
+ if (entries.length === 0) return "\u2014";
2751
+ const shown = entries.slice(0, 2).map(([key, value]) => `${key} ${String(value)}`).join(" \xB7 ");
2752
+ return entries.length > 2 ? `${shown} +${entries.length - 2}` : shown;
2753
+ }
2743
2754
  function ContentDistributionsPage({ headerActions } = {}) {
2744
2755
  const navigate = useNavigate();
2745
2756
  const contentConfig = useContentConfig();
@@ -2835,7 +2846,10 @@ function ContentDistributionsPage({ headerActions } = {}) {
2835
2846
  /* @__PURE__ */ jsx(Table.Th, { children: "Platform" }),
2836
2847
  /* @__PURE__ */ jsx(Table.Th, { children: "Format" }),
2837
2848
  /* @__PURE__ */ jsx(Table.Th, { children: "Status" }),
2838
- /* @__PURE__ */ jsx(Table.Th, { children: "Publish Method" }),
2849
+ /* @__PURE__ */ jsx(Table.Th, { style: { whiteSpace: "nowrap" }, children: "Publish Method" }),
2850
+ /* @__PURE__ */ jsx(Table.Th, { style: { whiteSpace: "nowrap" }, children: "Platform post ID" }),
2851
+ /* @__PURE__ */ jsx(Table.Th, { children: "Metrics" }),
2852
+ /* @__PURE__ */ jsx(Table.Th, { style: { whiteSpace: "nowrap" }, children: "Metrics updated" }),
2839
2853
  /* @__PURE__ */ jsx(Table.Th, { children: "Published" }),
2840
2854
  /* @__PURE__ */ jsx(Table.Th, {})
2841
2855
  ] }) }),
@@ -2866,6 +2880,9 @@ function ContentDistributionsPage({ headerActions } = {}) {
2866
2880
  /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: distribution.format }) }),
2867
2881
  /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", children: distribution.status }) }),
2868
2882
  /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: distribution.publishMethod ?? "\u2014" }) }),
2883
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: distribution.platformPostId ?? "\u2014" }) }),
2884
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: summarizeMetrics2(distribution.metrics) }) }),
2885
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: formatDate(distribution.metricsUpdatedAt) }) }),
2869
2886
  /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: formatDate(distribution.publishedAt) }) }),
2870
2887
  /* @__PURE__ */ jsx(Table.Td, { children: distribution.platformUrl && /* @__PURE__ */ jsx(
2871
2888
  Anchor,
@@ -2962,6 +2979,22 @@ function MetricsDisplay({ metrics }) {
2962
2979
  /* @__PURE__ */ jsx(Text, { size: "sm", children: String(value) })
2963
2980
  ] }, key)) });
2964
2981
  }
2982
+ var METRIC_HISTORY_COLUMNS = [
2983
+ { key: "views", label: "Views" },
2984
+ { key: "reach", label: "Reach" },
2985
+ { key: "likes", label: "Likes" },
2986
+ { key: "comments", label: "Comments" },
2987
+ { key: "shares", label: "Shares" },
2988
+ { key: "saves", label: "Saves" },
2989
+ { key: "engagements", label: "Engagements" },
2990
+ { key: "profile_visits", label: "Profile Visits" },
2991
+ { key: "profile_activity", label: "Profile Activity" },
2992
+ { key: "follows", label: "Follows" },
2993
+ { key: "clicks", label: "Clicks" }
2994
+ ];
2995
+ function formatMetricValue(value) {
2996
+ return value === void 0 ? "\u2014" : value.toLocaleString();
2997
+ }
2965
2998
  function ContentDistributionDetailPage({
2966
2999
  distributionId,
2967
3000
  headerActions
@@ -2971,6 +3004,8 @@ function ContentDistributionDetailPage({
2971
3004
  const distributionQuery = useContentDistribution(distributionId);
2972
3005
  const dist = distributionQuery.data;
2973
3006
  const itemQuery = useContentItem(dist?.contentItemId);
3007
+ const metricsHistoryQuery = useContentDistributionMetrics(distributionId);
3008
+ const metricsHistory = metricsHistoryQuery.data?.data ?? [];
2974
3009
  const [mediaOpened, { open: openMedia, close: closeMedia }] = useDisclosure(false);
2975
3010
  const [previewUrl, setPreviewUrl] = useState(null);
2976
3011
  const mediaEntries = useMemo(() => dist?.mediaUrls ?? [], [dist]);
@@ -3125,6 +3160,23 @@ function ContentDistributionDetailPage({
3125
3160
  /* @__PURE__ */ jsx(Divider, {}),
3126
3161
  /* @__PURE__ */ jsx(MetricsDisplay, { metrics: dist.metrics })
3127
3162
  ] }) }),
3163
+ /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3164
+ /* @__PURE__ */ jsx(Title, { order: 3, children: "Metrics History" }),
3165
+ /* @__PURE__ */ jsx(Divider, {}),
3166
+ metricsHistoryQuery.isLoading ? /* @__PURE__ */ jsx(Center, { p: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : metricsHistoryQuery.isError ? /* @__PURE__ */ jsx(CenteredErrorState, { error: metricsHistoryQuery.error, title: "Failed to load metrics history" }) : metricsHistory.length === 0 ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No metrics readings captured yet." }) : /* @__PURE__ */ jsx(Table.ScrollContainer, { minWidth: 900, children: /* @__PURE__ */ jsxs(Table, { children: [
3167
+ /* @__PURE__ */ jsx(Table.Thead, { children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
3168
+ /* @__PURE__ */ jsx(Table.Th, { children: "Captured" }),
3169
+ /* @__PURE__ */ jsx(Table.Th, { children: "Source" }),
3170
+ METRIC_HISTORY_COLUMNS.map((column) => /* @__PURE__ */ jsx(Table.Th, { children: column.label }, column.key))
3171
+ ] }) }),
3172
+ /* @__PURE__ */ jsx(Table.Tbody, { children: metricsHistory.map((reading) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
3173
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: formatDateTime3(reading.capturedAt) }) }),
3174
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: reading.source }) }),
3175
+ METRIC_HISTORY_COLUMNS.map((column) => /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { size: "sm", children: formatMetricValue(reading.metrics[column.key]) }) }, column.key))
3176
+ ] }, reading.id)) })
3177
+ ] }) }),
3178
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "An em dash means this platform does not report that metric -- it is never the same as zero." })
3179
+ ] }) }),
3128
3180
  checklist.length > 0 ? /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3129
3181
  /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
3130
3182
  /* @__PURE__ */ jsx(Title, { order: 3, children: "Checklist" }),
@@ -3251,5 +3303,204 @@ function ContentDistributionDetailPage({
3251
3303
  /* @__PURE__ */ jsx(CustomModal, { opened: mediaOpened, onClose: closeMedia, size: "xl", children: previewUrl ? /* @__PURE__ */ jsx(Image$1, { src: previewUrl, alt: "Media preview", fit: "contain" }) : null })
3252
3304
  ] });
3253
3305
  }
3306
+ function ContentWorkspaceShell({
3307
+ pipelineId,
3308
+ panels,
3309
+ initialDraft,
3310
+ title,
3311
+ caption,
3312
+ headerRight,
3313
+ renderStart,
3314
+ renderPersistent,
3315
+ renderAside,
3316
+ canOpenStep,
3317
+ testId
3318
+ }) {
3319
+ const { pipelines, defaultPipelineId } = useContentConfig();
3320
+ const resolvedPipelineId = pipelineId ?? defaultPipelineId;
3321
+ const pipeline = useMemo(
3322
+ () => pipelines.find((entry) => entry.id === resolvedPipelineId),
3323
+ [pipelines, resolvedPipelineId]
3324
+ );
3325
+ const steps = useMemo(() => pipeline?.steps ?? [], [pipeline]);
3326
+ const [isStarted, setIsStarted] = useState(renderStart === void 0);
3327
+ const [activeStepKey, setActiveStepKey] = useState(null);
3328
+ const [furthestIndex, setFurthestIndex] = useState(0);
3329
+ const [adoptedItem, setAdoptedItem] = useState(null);
3330
+ const [bodyDraft, setBodyDraft] = useState(null);
3331
+ const [draft, setDraftState] = useState(initialDraft);
3332
+ const leaveGuardRef = useRef(null);
3333
+ const itemId = adoptedItem?.id;
3334
+ const liveItem = useContentItem(itemId);
3335
+ const distributions = useContentDistributions({ contentItemId: itemId });
3336
+ const item = useMemo(() => {
3337
+ const live = liveItem.data;
3338
+ return live !== void 0 && live.id === itemId ? live : adoptedItem;
3339
+ }, [liveItem.data, itemId, adoptedItem]);
3340
+ const distribution = useMemo(() => {
3341
+ if (itemId === void 0) return null;
3342
+ return distributions.data?.data.find((row) => row.contentItemId === itemId) ?? null;
3343
+ }, [distributions.data, itemId]);
3344
+ const stepIndex = useMemo(() => {
3345
+ const index = steps.findIndex((step2) => step2.key === activeStepKey);
3346
+ return index === -1 ? 0 : index;
3347
+ }, [steps, activeStepKey]);
3348
+ const step = steps[stepIndex];
3349
+ const setDraft = useCallback((update) => {
3350
+ setDraftState(
3351
+ (current) => typeof update === "function" ? update(current) : { ...current, ...update }
3352
+ );
3353
+ }, []);
3354
+ const setItem = useCallback((next) => {
3355
+ setAdoptedItem(next);
3356
+ setBodyDraft(null);
3357
+ }, []);
3358
+ const refetchDistributionsQuery = distributions.refetch;
3359
+ const refetchDistributions = useCallback(() => void refetchDistributionsQuery(), [refetchDistributionsQuery]);
3360
+ const registerLeaveGuard = useCallback((guard) => {
3361
+ leaveGuardRef.current = guard;
3362
+ }, []);
3363
+ const goToStep = useCallback(
3364
+ (stepKey) => {
3365
+ const nextIndex = steps.findIndex((entry) => entry.key === stepKey);
3366
+ const next = steps[nextIndex];
3367
+ if (next === void 0) return;
3368
+ const guard = leaveGuardRef.current;
3369
+ void (async () => {
3370
+ if (guard !== null && nextIndex > stepIndex) await guard(next);
3371
+ setActiveStepKey(next.key);
3372
+ setFurthestIndex((current) => Math.max(current, nextIndex));
3373
+ })();
3374
+ },
3375
+ [steps, stepIndex]
3376
+ );
3377
+ const goToNextStep = useCallback(() => {
3378
+ const next = steps[stepIndex + 1];
3379
+ if (next !== void 0) goToStep(next.key);
3380
+ }, [steps, stepIndex, goToStep]);
3381
+ const goToPreviousStep = useCallback(() => {
3382
+ const previous = steps[stepIndex - 1];
3383
+ if (previous !== void 0) goToStep(previous.key);
3384
+ }, [steps, stepIndex, goToStep]);
3385
+ const restart = useCallback(() => {
3386
+ setAdoptedItem(null);
3387
+ setBodyDraft(null);
3388
+ setDraftState(initialDraft);
3389
+ setActiveStepKey(null);
3390
+ setFurthestIndex(0);
3391
+ leaveGuardRef.current = null;
3392
+ setIsStarted(renderStart === void 0);
3393
+ }, [initialDraft, renderStart]);
3394
+ const state = useMemo(() => {
3395
+ if (pipeline === void 0 || step === void 0) return null;
3396
+ const base = {
3397
+ pipeline,
3398
+ steps,
3399
+ step,
3400
+ stepIndex,
3401
+ item,
3402
+ setItem,
3403
+ body: bodyDraft ?? item?.body ?? "",
3404
+ bodyDraft,
3405
+ setBodyDraft,
3406
+ distribution,
3407
+ refetchDistributions,
3408
+ draft,
3409
+ setDraft,
3410
+ goToStep,
3411
+ goToNextStep,
3412
+ goToPreviousStep,
3413
+ registerLeaveGuard,
3414
+ restart
3415
+ };
3416
+ const resolved = {
3417
+ ...base,
3418
+ canOpenStep: (candidate) => canOpenStep === void 0 ? steps.indexOf(candidate) <= furthestIndex : canOpenStep(candidate, resolved)
3419
+ };
3420
+ return resolved;
3421
+ }, [
3422
+ pipeline,
3423
+ steps,
3424
+ step,
3425
+ stepIndex,
3426
+ item,
3427
+ setItem,
3428
+ bodyDraft,
3429
+ distribution,
3430
+ refetchDistributions,
3431
+ draft,
3432
+ setDraft,
3433
+ goToStep,
3434
+ goToNextStep,
3435
+ goToPreviousStep,
3436
+ registerLeaveGuard,
3437
+ restart,
3438
+ canOpenStep,
3439
+ furthestIndex
3440
+ ]);
3441
+ const startControls = useMemo(
3442
+ () => ({
3443
+ onStartNew: () => setIsStarted(true),
3444
+ onResume: (resumed, resumeAtStepKey) => {
3445
+ setItem(resumed);
3446
+ setDraftState(initialDraft);
3447
+ setFurthestIndex(steps.length === 0 ? 0 : steps.length - 1);
3448
+ setActiveStepKey(resumeAtStepKey ?? steps[0]?.key ?? null);
3449
+ setIsStarted(true);
3450
+ }
3451
+ }),
3452
+ [setItem, initialDraft, steps]
3453
+ );
3454
+ const body = (() => {
3455
+ if (pipeline === void 0) {
3456
+ return /* @__PURE__ */ jsx(Alert, { color: "yellow", icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }), children: resolvedPipelineId === void 0 ? "The deployed Organization Model declares no content pipelines, so there is nothing to walk through here." : `The deployed Organization Model does not declare a "${resolvedPipelineId}" pipeline.` });
3457
+ }
3458
+ if (steps.length === 0 || state === null || step === void 0) {
3459
+ return /* @__PURE__ */ jsxs(Alert, { color: "yellow", icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }), children: [
3460
+ "The ",
3461
+ /* @__PURE__ */ jsx("strong", { children: pipeline.label }),
3462
+ " pipeline declares no steps, so there is nothing to render."
3463
+ ] });
3464
+ }
3465
+ const Panel = panels[step.key];
3466
+ const panelNode = Panel === void 0 ? /* @__PURE__ */ jsxs(Alert, { color: "yellow", icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }), children: [
3467
+ "No panel is registered for the ",
3468
+ /* @__PURE__ */ jsx("strong", { children: step.label }),
3469
+ " step (",
3470
+ /* @__PURE__ */ jsx("code", { children: step.key }),
3471
+ "). Add one to the workspace's panel map."
3472
+ ] }) : /* @__PURE__ */ jsx(Panel, { ...state });
3473
+ const aside = renderAside?.(state) ?? null;
3474
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3475
+ /* @__PURE__ */ jsx(Stepper, { active: stepIndex, onStepClick: (next) => goToStep(steps[next]?.key ?? step.key), size: "sm", children: steps.map((entry) => /* @__PURE__ */ jsx(Stepper.Step, { label: entry.label, allowStepSelect: state.canOpenStep(entry) }, entry.key)) }),
3476
+ step.description === void 0 || step.description === "" ? null : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: step.description }),
3477
+ renderPersistent?.(state),
3478
+ aside === null ? panelNode : /* @__PURE__ */ jsxs(Grid, { gutter: "md", align: "flex-start", children: [
3479
+ /* @__PURE__ */ jsx(Grid.Col, { span: { base: 12, lg: 7 }, children: panelNode }),
3480
+ /* @__PURE__ */ jsx(Grid.Col, { span: { base: 12, lg: 5 }, children: /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", children: aside }) })
3481
+ ] })
3482
+ ] });
3483
+ })();
3484
+ return /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { "data-testid": testId, children: [
3485
+ /* @__PURE__ */ jsx(PageTitleCaption, { title, caption, rightSection: headerRight }),
3486
+ !isStarted && renderStart !== void 0 ? renderStart(startControls) : body
3487
+ ] }) }) });
3488
+ }
3489
+ function ContentAnalysisStepPanel(state) {
3490
+ const { item, stepIndex, steps, goToNextStep, goToPreviousStep } = state;
3491
+ if (item === null) {
3492
+ return /* @__PURE__ */ jsx(Alert, { color: "yellow", icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16 }), children: "Nothing has been created yet, so there is nothing to analyse. Go back and finish the earlier steps first." });
3493
+ }
3494
+ return /* @__PURE__ */ jsxs(Stack, { children: [
3495
+ /* @__PURE__ */ jsx(SlideAnalysisPanel, { itemId: item.id }),
3496
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
3497
+ stepIndex > 0 ? /* @__PURE__ */ jsxs(Button, { variant: "default", leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }), onClick: goToPreviousStep, children: [
3498
+ "Back to ",
3499
+ steps[stepIndex - 1]?.label
3500
+ ] }) : /* @__PURE__ */ jsx("span", {}),
3501
+ stepIndex < steps.length - 1 && /* @__PURE__ */ jsx(Button, { rightSection: /* @__PURE__ */ jsx(IconArrowRight, { size: 16 }), onClick: goToNextStep, children: steps[stepIndex + 1]?.label })
3502
+ ] })
3503
+ ] });
3504
+ }
3254
3505
 
3255
- export { AlternatesPanel, AssetCropEditor, CAPTION_STEP_KEY, CAPTION_WORKFLOW_ID, CONTENT_DERIVATIVES_BUCKET, CROP_ASPECT_OPTIONS, CaptionPanel, ContentDistributionDetailPage, ContentDistributionsPage, ContentItemReviewPage, ContentItemsPage, ContentOverviewPage, ContentPipelineBoardPage, ContentPipelineBoardPage as ContentPipelineWorkspacePage, ContentPipelinesPage, ContentReviewCard, DERIVATIVE_JPEG_QUALITY, DERIVATIVE_MAX_WIDTH, IMAGE_ANALYSIS_WORKFLOW_ID, PayloadBody, PostPreview, ProcessingStateStrip, ReviewActionBar, SelectedAssetStrip, SlideAnalysisPanel, SourceAssetsPanel, cropStyle, derivativeObjectKey, firstLine, formatElapsed, isDerivativeStale, lastLine, readStoredAnalysis, renderCropToJpeg, swapFirstLine, swapLastLine };
3506
+ export { AlternatesPanel, AssetCropEditor, CAPTION_STEP_KEY, CAPTION_WORKFLOW_ID, CONTENT_DERIVATIVES_BUCKET, CROP_ASPECT_OPTIONS, CaptionPanel, ContentAnalysisStepPanel, ContentDistributionDetailPage, ContentDistributionsPage, ContentItemReviewPage, ContentItemsPage, ContentOverviewPage, ContentPipelineBoardPage, ContentPipelineBoardPage as ContentPipelineWorkspacePage, ContentPipelinesPage, ContentReviewCard, ContentWorkspaceShell, DERIVATIVE_JPEG_QUALITY, DERIVATIVE_MAX_WIDTH, IMAGE_ANALYSIS_WORKFLOW_ID, PayloadBody, PostPreview, ProcessingStateStrip, ReviewActionBar, SelectedAssetStrip, SlideAnalysisPanel, SourceAssetsPanel, cropStyle, derivativeObjectKey, firstLine, formatElapsed, isDerivativeStale, lastLine, readStoredAnalysis, renderCropToJpeg, swapFirstLine, swapLastLine };