@elevasis/ui 2.72.0 → 2.74.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.
- package/dist/api/index.js +3 -3
- package/dist/app/index.d.ts +172 -20
- package/dist/app/index.js +9 -10
- package/dist/auth/index.js +5 -6
- package/dist/charts/index.js +5 -6
- package/dist/chunk-2GIJBHZT.js +60 -0
- package/dist/{chunk-2454MK7P.js → chunk-2MRRDF32.js} +115 -8
- package/dist/chunk-3LOKYZJC.js +231 -0
- package/dist/chunk-3QHX4ZKV.js +224 -0
- package/dist/chunk-43LC6XAX.js +69 -0
- package/dist/chunk-4M2BSHVT.js +116 -0
- package/dist/{chunk-SV4M2BUI.js → chunk-4MXNHJTA.js} +111 -46
- package/dist/{chunk-LEQGGX2U.js → chunk-5A6KCFS5.js} +36 -43
- package/dist/{chunk-KIDZXZM5.js → chunk-6JN2TLV2.js} +1480 -4200
- package/dist/{chunk-UZ5JO5TK.js → chunk-7ARBBELS.js} +1 -1
- package/dist/{chunk-DJWIIPKW.js → chunk-7RJ7P6S6.js} +6 -3
- package/dist/chunk-ARAFQBNI.js +515 -0
- package/dist/{chunk-DKVGO6RJ.js → chunk-BA3AZJUR.js} +1 -1
- package/dist/chunk-BRTGCFBH.js +305 -0
- package/dist/{chunk-7ESZKTQG.js → chunk-CQPULKKL.js} +5 -3
- package/dist/chunk-CRA7WQZH.js +49 -0
- package/dist/{chunk-XZIOCB5D.js → chunk-DCQKTDIG.js} +2 -52
- package/dist/{chunk-A3JHFZDP.js → chunk-E6YGA5WH.js} +1 -1
- package/dist/chunk-FA7LMNQO.js +439 -0
- package/dist/chunk-FZSG6M6W.js +45 -0
- package/dist/chunk-GDOR57D7.js +165 -0
- package/dist/{chunk-RRS2QR3W.js → chunk-GO4XJ5D4.js} +1 -1
- package/dist/chunk-GPQQGQGT.js +645 -0
- package/dist/chunk-HYQOGRWG.js +54 -0
- package/dist/{chunk-LCHL5SM2.js → chunk-LN4UW6S4.js} +1 -1
- package/dist/chunk-N6K2Q5BM.js +393 -0
- package/dist/{chunk-Z2W5VNN3.js → chunk-O32UQ26A.js} +3 -2
- package/dist/{chunk-M7WWRZ5Z.js → chunk-QFGNRKIE.js} +1 -78
- package/dist/{chunk-Q3O3WY7Q.js → chunk-R5UGIFYU.js} +74 -18
- package/dist/{chunk-753MKWFV.js → chunk-RFNJ2PTO.js} +1 -1
- package/dist/chunk-VM2OWOXL.js +24 -0
- package/dist/{chunk-ZBXCEWKF.js → chunk-W2QRBQQA.js} +5 -3
- package/dist/chunk-WDBNW44Z.js +49 -0
- package/dist/{chunk-IXBRUIYI.js → chunk-WZU3MCKI.js} +1 -1
- package/dist/chunk-YQQ5GRUR.js +21 -0
- package/dist/{chunk-IMZTRDY2.js → chunk-ZFA56VSR.js} +2 -2
- package/dist/{chunk-AFBFSXP3.js → chunk-ZWI62BQ6.js} +7 -4
- package/dist/chunk-ZYNVCWDZ.js +286 -0
- package/dist/components/index.d.ts +490 -22
- package/dist/components/index.js +335 -35
- package/dist/components/navigation/index.js +6 -7
- package/dist/features/auth/index.d.ts +154 -2
- package/dist/features/auth/index.js +18 -9
- package/dist/features/clients/index.js +7 -7
- package/dist/features/content/index.d.ts +718 -34
- package/dist/features/content/index.js +1345 -51
- package/dist/features/crm/index.d.ts +172 -20
- package/dist/features/crm/index.js +10 -8
- package/dist/features/dashboard/index.d.ts +19 -10
- package/dist/features/dashboard/index.js +9 -8
- package/dist/features/delivery/index.d.ts +134 -0
- package/dist/features/delivery/index.js +23 -7
- package/dist/features/knowledge/index.js +5 -6
- package/dist/features/lead-gen/index.d.ts +47 -35
- package/dist/features/lead-gen/index.js +12 -8
- package/dist/features/monitoring/index.js +11 -9
- package/dist/features/monitoring/requests/index.js +8 -7
- package/dist/features/operations/index.d.ts +38 -20
- package/dist/features/operations/index.js +15 -11
- package/dist/features/public-agent-chat/index.js +3 -1
- package/dist/features/settings/index.d.ts +134 -0
- package/dist/features/settings/index.js +9 -8
- package/dist/hooks/access/index.js +5 -6
- package/dist/hooks/delivery/index.d.ts +134 -0
- package/dist/hooks/delivery/index.js +3 -2
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +20 -11
- package/dist/hooks/published.d.ts +1421 -29
- package/dist/hooks/published.js +22 -6
- package/dist/initialization/index.d.ts +134 -0
- package/dist/knowledge/index.d.ts +38 -20
- package/dist/knowledge/index.js +167 -11
- package/dist/{knowledge-search-index-RZLIVWPJ.js → knowledge-search-index-6GQK55IQ.js} +1 -1
- package/dist/layout/index.js +8 -9
- package/dist/profile/index.d.ts +134 -0
- package/dist/provider/index.d.ts +191 -21
- package/dist/provider/index.js +5 -6
- package/dist/provider/published.d.ts +219 -21
- package/dist/provider/published.js +5 -6
- package/dist/test-utils/index.d.ts +16 -5
- package/dist/test-utils/index.js +17 -18
- package/dist/types/index.d.ts +184 -14
- package/dist/utils/index.d.ts +102 -13
- package/dist/utils/index.js +1 -1
- package/package.json +7 -6
- package/dist/chunk-6M6OLGQY.js +0 -36
- package/dist/chunk-MKH2KOAO.js +0 -39
- package/dist/hooks/index.css +0 -659
- package/dist/hooks/index.d.ts +0 -12853
- package/dist/hooks/index.js +0 -27
- package/dist/supabase/index.d.ts +0 -6969
- package/dist/supabase/index.js +0 -3
- package/dist/typeform/index.d.ts +0 -462
- package/dist/typeform/index.js +0 -2051
- package/dist/typeform/schemas.d.ts +0 -67
- package/dist/typeform/schemas.js +0 -2
|
@@ -18,7 +18,9 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
18
18
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
19
19
|
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
20
20
|
storage: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
-
|
|
21
|
+
rowSchema: z.ZodOptional<z.ZodString>;
|
|
22
|
+
stateCatalogId: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strict>>>>;
|
|
22
24
|
linkTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
23
25
|
id: z.ZodString;
|
|
24
26
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -29,7 +31,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
29
31
|
to: z.ZodString;
|
|
30
32
|
cardinality: z.ZodOptional<z.ZodString>;
|
|
31
33
|
via: z.ZodOptional<z.ZodString>;
|
|
32
|
-
}, z.core.$
|
|
34
|
+
}, z.core.$strict>>>>;
|
|
33
35
|
actionTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
34
36
|
id: z.ZodString;
|
|
35
37
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -39,7 +41,11 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
39
41
|
actsOn: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
40
42
|
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
41
43
|
effects: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
42
|
-
|
|
44
|
+
resourceId: z.ZodOptional<z.ZodString>;
|
|
45
|
+
invocations: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
46
|
+
lifecycle: z.ZodOptional<z.ZodString>;
|
|
47
|
+
legacyActionId: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strict>>>>;
|
|
43
49
|
catalogTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
44
50
|
id: z.ZodString;
|
|
45
51
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -49,7 +55,10 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
49
55
|
kind: z.ZodOptional<z.ZodString>;
|
|
50
56
|
appliesTo: z.ZodOptional<z.ZodString>;
|
|
51
57
|
entries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
52
|
-
|
|
58
|
+
legacyCatalogKey: z.ZodOptional<z.ZodString>;
|
|
59
|
+
legacyPipelineKey: z.ZodOptional<z.ZodString>;
|
|
60
|
+
legacyEntityKey: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, z.core.$strict>>>>;
|
|
53
62
|
eventTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
54
63
|
id: z.ZodString;
|
|
55
64
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -57,7 +66,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
57
66
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
58
67
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
59
68
|
payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
60
|
-
}, z.core.$
|
|
69
|
+
}, z.core.$strict>>>>;
|
|
61
70
|
interfaceTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
62
71
|
id: z.ZodString;
|
|
63
72
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -65,7 +74,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
65
74
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
66
75
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
67
76
|
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
68
|
-
}, z.core.$
|
|
77
|
+
}, z.core.$strict>>>>;
|
|
69
78
|
valueTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
70
79
|
id: z.ZodString;
|
|
71
80
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -73,7 +82,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
73
82
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
74
83
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
75
84
|
primitive: z.ZodOptional<z.ZodString>;
|
|
76
|
-
}, z.core.$
|
|
85
|
+
}, z.core.$strict>>>>;
|
|
77
86
|
sharedProperties: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
78
87
|
id: z.ZodString;
|
|
79
88
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -83,7 +92,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
83
92
|
valueType: z.ZodOptional<z.ZodString>;
|
|
84
93
|
searchable: z.ZodOptional<z.ZodBoolean>;
|
|
85
94
|
pii: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
-
}, z.core.$
|
|
95
|
+
}, z.core.$strict>>>>;
|
|
87
96
|
groups: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
88
97
|
id: z.ZodString;
|
|
89
98
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -91,7 +100,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
91
100
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
92
101
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
93
102
|
members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
94
|
-
}, z.core.$
|
|
103
|
+
}, z.core.$strict>>>>;
|
|
95
104
|
endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
96
105
|
id: z.ZodString;
|
|
97
106
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -99,7 +108,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
|
|
|
99
108
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
100
109
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
101
110
|
route: z.ZodOptional<z.ZodString>;
|
|
102
|
-
}, z.core.$
|
|
111
|
+
}, z.core.$strict>>>>;
|
|
103
112
|
}, z.core.$strict>>;
|
|
104
113
|
type OntologyScope = z.infer<typeof OntologyScopeSchema>;
|
|
105
114
|
|
|
@@ -191,18 +200,46 @@ interface SidebarGroupNode {
|
|
|
191
200
|
}
|
|
192
201
|
type SidebarNode = SidebarSurfaceNode | SidebarGroupNode;
|
|
193
202
|
|
|
194
|
-
/**
|
|
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
|
+
*/
|
|
195
218
|
declare const ContentPipelineStepActorSchema: z.ZodEnum<{
|
|
196
219
|
agent: "agent";
|
|
197
220
|
workflow: "workflow";
|
|
221
|
+
human: "human";
|
|
198
222
|
vendor: "vendor";
|
|
199
223
|
}>;
|
|
200
224
|
type ContentPipelineStepActor = z.infer<typeof ContentPipelineStepActorSchema>;
|
|
201
|
-
/**
|
|
225
|
+
/**
|
|
226
|
+
* D5: whether a human decision gates this step's output.
|
|
227
|
+
*
|
|
228
|
+
* Two values, deliberately. This field used to be `'live' | 'queued' | 'none'`,
|
|
229
|
+
* which encoded two independent facts in one enum -- whether a person reviews,
|
|
230
|
+
* and where they do it. `'live'` and `'queued'` differed only in the second, and
|
|
231
|
+
* the second was already stored as `workspaceRoute`. One fact written twice in
|
|
232
|
+
* two vocabularies is what let two review rules disagree on exactly one value
|
|
233
|
+
* and render a false warning on a live tenant.
|
|
234
|
+
*
|
|
235
|
+
* Where review happens is now derived rather than declared -- see
|
|
236
|
+
* `resolveContentReviewVenue`. Kept a string enum rather than a boolean so a
|
|
237
|
+
* genuine third mode later (an automated check that gates progression without a
|
|
238
|
+
* person) is an added member rather than a second schema break on this field.
|
|
239
|
+
*/
|
|
202
240
|
declare const ContentPipelineStepReviewModeSchema: z.ZodEnum<{
|
|
241
|
+
required: "required";
|
|
203
242
|
none: "none";
|
|
204
|
-
live: "live";
|
|
205
|
-
queued: "queued";
|
|
206
243
|
}>;
|
|
207
244
|
type ContentPipelineStepReviewMode = z.infer<typeof ContentPipelineStepReviewModeSchema>;
|
|
208
245
|
/** D17: one entry in a step's template-declared serializable payload field list. */
|
|
@@ -220,6 +257,17 @@ declare const ContentPayloadFieldDeclarationSchema: z.ZodObject<{
|
|
|
220
257
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
221
258
|
}, z.core.$strip>;
|
|
222
259
|
type ContentPayloadFieldDeclaration = z.infer<typeof ContentPayloadFieldDeclarationSchema>;
|
|
260
|
+
/**
|
|
261
|
+
* Where the human decision a step gates on is actually made. Derived from
|
|
262
|
+
* `reviewMode` plus the resolved Workspace route -- see
|
|
263
|
+
* `resolveContentReviewVenue`. Never declared in a catalog.
|
|
264
|
+
*
|
|
265
|
+
* - `'none'` -- nobody is owed a decision on this step.
|
|
266
|
+
* - `'queue'` -- the shared review queue. The platform's own surfaces clear it.
|
|
267
|
+
* - `'workspace'` -- the tenant's own screen, named by `workspaceRoute`. The
|
|
268
|
+
* shared surfaces display state and link out; they do not clear it.
|
|
269
|
+
*/
|
|
270
|
+
type ContentReviewVenue = 'none' | 'queue' | 'workspace';
|
|
223
271
|
/** One step in a resolved content pipeline, as returned by `getContentBuildTemplates`. */
|
|
224
272
|
interface ContentPipelineStepEntry {
|
|
225
273
|
/** Matches the catalog entry id (the step's local id within its step catalog). */
|
|
@@ -232,8 +280,21 @@ interface ContentPipelineStepEntry {
|
|
|
232
280
|
order: number;
|
|
233
281
|
/** D5: who/what executes this step. */
|
|
234
282
|
actor: ContentPipelineStepActor;
|
|
235
|
-
/** D5:
|
|
283
|
+
/** D5: whether a human decision gates this step's output. */
|
|
236
284
|
reviewMode: ContentPipelineStepReviewMode;
|
|
285
|
+
/**
|
|
286
|
+
* Where that decision is made -- **derived, never authored.** Resolved once by
|
|
287
|
+
* `getContentBuildTemplates` via `resolveContentReviewVenue`, at the one
|
|
288
|
+
* boundary where a raw catalog becomes a resolved template and both the
|
|
289
|
+
* pipeline and the step are in hand. `ContentPipelineStepDeclarationSchema`
|
|
290
|
+
* has no such field, so no tenant can declare it and no second encoding of it
|
|
291
|
+
* can exist.
|
|
292
|
+
*
|
|
293
|
+
* Read this rather than re-deriving from `reviewMode` + `workspaceRoute` at a
|
|
294
|
+
* call site; recombining those two with `&&` at the point of use is the exact
|
|
295
|
+
* defect the content-review consolidation removed.
|
|
296
|
+
*/
|
|
297
|
+
reviewVenue: ContentReviewVenue;
|
|
237
298
|
/** D5: the step key this step advances to. Absent on a terminal step. */
|
|
238
299
|
advancesTo?: string;
|
|
239
300
|
/**
|
|
@@ -274,6 +335,15 @@ interface ContentStageCatalogEntry {
|
|
|
274
335
|
description: string;
|
|
275
336
|
order: number;
|
|
276
337
|
color?: string;
|
|
338
|
+
/**
|
|
339
|
+
* The entry's own `semanticClass` -- `'open' | 'active' | 'completed'` on the
|
|
340
|
+
* status catalog, absent on catalogs that do not declare one.
|
|
341
|
+
*
|
|
342
|
+
* Carried through so a consumer can ask "is this item finished?" without
|
|
343
|
+
* hardcoding which status ids mean finished. A tenant renaming `distributed`
|
|
344
|
+
* or adding a fifth status keeps working; a hardcoded id list would not.
|
|
345
|
+
*/
|
|
346
|
+
semanticClass?: string;
|
|
277
347
|
}
|
|
278
348
|
|
|
279
349
|
declare const OrganizationModelSchema: z.ZodObject<{
|
|
@@ -726,7 +796,9 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
726
796
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
727
797
|
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
728
798
|
storage: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
729
|
-
|
|
799
|
+
rowSchema: z.ZodOptional<z.ZodString>;
|
|
800
|
+
stateCatalogId: z.ZodOptional<z.ZodString>;
|
|
801
|
+
}, z.core.$strict>>>>;
|
|
730
802
|
linkTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
731
803
|
id: z.ZodString;
|
|
732
804
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -737,7 +809,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
737
809
|
to: z.ZodString;
|
|
738
810
|
cardinality: z.ZodOptional<z.ZodString>;
|
|
739
811
|
via: z.ZodOptional<z.ZodString>;
|
|
740
|
-
}, z.core.$
|
|
812
|
+
}, z.core.$strict>>>>;
|
|
741
813
|
actionTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
742
814
|
id: z.ZodString;
|
|
743
815
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -747,7 +819,11 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
747
819
|
actsOn: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
748
820
|
input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
749
821
|
effects: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
750
|
-
|
|
822
|
+
resourceId: z.ZodOptional<z.ZodString>;
|
|
823
|
+
invocations: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
824
|
+
lifecycle: z.ZodOptional<z.ZodString>;
|
|
825
|
+
legacyActionId: z.ZodOptional<z.ZodString>;
|
|
826
|
+
}, z.core.$strict>>>>;
|
|
751
827
|
catalogTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
752
828
|
id: z.ZodString;
|
|
753
829
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -757,7 +833,10 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
757
833
|
kind: z.ZodOptional<z.ZodString>;
|
|
758
834
|
appliesTo: z.ZodOptional<z.ZodString>;
|
|
759
835
|
entries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
760
|
-
|
|
836
|
+
legacyCatalogKey: z.ZodOptional<z.ZodString>;
|
|
837
|
+
legacyPipelineKey: z.ZodOptional<z.ZodString>;
|
|
838
|
+
legacyEntityKey: z.ZodOptional<z.ZodString>;
|
|
839
|
+
}, z.core.$strict>>>>;
|
|
761
840
|
eventTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
762
841
|
id: z.ZodString;
|
|
763
842
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -765,7 +844,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
765
844
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
766
845
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
767
846
|
payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
768
|
-
}, z.core.$
|
|
847
|
+
}, z.core.$strict>>>>;
|
|
769
848
|
interfaceTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
770
849
|
id: z.ZodString;
|
|
771
850
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -773,7 +852,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
773
852
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
774
853
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
775
854
|
properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
776
|
-
}, z.core.$
|
|
855
|
+
}, z.core.$strict>>>>;
|
|
777
856
|
valueTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
778
857
|
id: z.ZodString;
|
|
779
858
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -781,7 +860,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
781
860
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
782
861
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
783
862
|
primitive: z.ZodOptional<z.ZodString>;
|
|
784
|
-
}, z.core.$
|
|
863
|
+
}, z.core.$strict>>>>;
|
|
785
864
|
sharedProperties: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
786
865
|
id: z.ZodString;
|
|
787
866
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -791,7 +870,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
791
870
|
valueType: z.ZodOptional<z.ZodString>;
|
|
792
871
|
searchable: z.ZodOptional<z.ZodBoolean>;
|
|
793
872
|
pii: z.ZodOptional<z.ZodBoolean>;
|
|
794
|
-
}, z.core.$
|
|
873
|
+
}, z.core.$strict>>>>;
|
|
795
874
|
groups: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
796
875
|
id: z.ZodString;
|
|
797
876
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -799,7 +878,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
799
878
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
800
879
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
801
880
|
members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
802
|
-
}, z.core.$
|
|
881
|
+
}, z.core.$strict>>>>;
|
|
803
882
|
endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
804
883
|
id: z.ZodString;
|
|
805
884
|
label: z.ZodOptional<z.ZodString>;
|
|
@@ -807,7 +886,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
807
886
|
ownerSystemId: z.ZodOptional<z.ZodString>;
|
|
808
887
|
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
809
888
|
route: z.ZodOptional<z.ZodString>;
|
|
810
|
-
}, z.core.$
|
|
889
|
+
}, z.core.$strict>>>>;
|
|
811
890
|
}, z.core.$strict>>>;
|
|
812
891
|
resources: z.ZodDefault<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
813
892
|
id: z.ZodString;
|
|
@@ -1263,6 +1342,13 @@ declare const OrganizationModelSchema: z.ZodObject<{
|
|
|
1263
1342
|
type OrganizationModel = z.infer<typeof OrganizationModelSchema>;
|
|
1264
1343
|
type OrganizationModelResourceKind = z.infer<typeof ResourceKindSchema>;
|
|
1265
1344
|
|
|
1345
|
+
/** Response-side crop: unknown keys are stripped, not rejected, like every other response schema here. */
|
|
1346
|
+
declare const ContentAssetCropSchema: z.ZodObject<{
|
|
1347
|
+
x: z.ZodNumber;
|
|
1348
|
+
y: z.ZodNumber;
|
|
1349
|
+
width: z.ZodNumber;
|
|
1350
|
+
height: z.ZodNumber;
|
|
1351
|
+
}, z.core.$strip>;
|
|
1266
1352
|
declare const ContentItemResponseSchema: z.ZodObject<{
|
|
1267
1353
|
id: z.ZodString;
|
|
1268
1354
|
organizationId: z.ZodString;
|
|
@@ -1274,6 +1360,29 @@ declare const ContentItemResponseSchema: z.ZodObject<{
|
|
|
1274
1360
|
pipelineId: z.ZodNullable<z.ZodString>;
|
|
1275
1361
|
clientId: z.ZodNullable<z.ZodString>;
|
|
1276
1362
|
sourceAssetId: z.ZodNullable<z.ZodString>;
|
|
1363
|
+
sourceAssets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1364
|
+
id: z.ZodString;
|
|
1365
|
+
organizationId: z.ZodString;
|
|
1366
|
+
contentItemId: z.ZodString;
|
|
1367
|
+
sourceAssetId: z.ZodString;
|
|
1368
|
+
position: z.ZodNumber;
|
|
1369
|
+
crop: z.ZodNullable<z.ZodObject<{
|
|
1370
|
+
x: z.ZodNumber;
|
|
1371
|
+
y: z.ZodNumber;
|
|
1372
|
+
width: z.ZodNumber;
|
|
1373
|
+
height: z.ZodNumber;
|
|
1374
|
+
}, z.core.$strip>>;
|
|
1375
|
+
altText: z.ZodNullable<z.ZodString>;
|
|
1376
|
+
derivativePath: z.ZodNullable<z.ZodString>;
|
|
1377
|
+
derivativeCrop: z.ZodNullable<z.ZodObject<{
|
|
1378
|
+
x: z.ZodNumber;
|
|
1379
|
+
y: z.ZodNumber;
|
|
1380
|
+
width: z.ZodNumber;
|
|
1381
|
+
height: z.ZodNumber;
|
|
1382
|
+
}, z.core.$strip>>;
|
|
1383
|
+
derivativeRenderedAt: z.ZodNullable<z.ZodString>;
|
|
1384
|
+
createdAt: z.ZodString;
|
|
1385
|
+
}, z.core.$strip>>>;
|
|
1277
1386
|
processingState: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1278
1387
|
status: z.ZodEnum<{
|
|
1279
1388
|
error: "error";
|
|
@@ -1296,7 +1405,76 @@ declare const ContentItemResponseSchema: z.ZodObject<{
|
|
|
1296
1405
|
createdAt: z.ZodString;
|
|
1297
1406
|
updatedAt: z.ZodString;
|
|
1298
1407
|
}, z.core.$strip>;
|
|
1408
|
+
declare const ContentSourceAssetResponseSchema: z.ZodObject<{
|
|
1409
|
+
id: z.ZodString;
|
|
1410
|
+
organizationId: z.ZodString;
|
|
1411
|
+
kind: z.ZodString;
|
|
1412
|
+
title: z.ZodString;
|
|
1413
|
+
externalUrl: z.ZodNullable<z.ZodString>;
|
|
1414
|
+
storagePath: z.ZodNullable<z.ZodString>;
|
|
1415
|
+
durationSeconds: z.ZodNullable<z.ZodNumber>;
|
|
1416
|
+
metadata: z.ZodUnknown;
|
|
1417
|
+
payload: z.ZodUnknown;
|
|
1418
|
+
processingState: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1419
|
+
status: z.ZodEnum<{
|
|
1420
|
+
error: "error";
|
|
1421
|
+
success: "success";
|
|
1422
|
+
running: "running";
|
|
1423
|
+
no_result: "no_result";
|
|
1424
|
+
skipped: "skipped";
|
|
1425
|
+
}>;
|
|
1426
|
+
attemptId: z.ZodString;
|
|
1427
|
+
executionId: z.ZodNullable<z.ZodString>;
|
|
1428
|
+
attemptedAt: z.ZodString;
|
|
1429
|
+
data: z.ZodOptional<z.ZodUnknown>;
|
|
1430
|
+
}, z.core.$loose>>;
|
|
1431
|
+
createdAt: z.ZodString;
|
|
1432
|
+
updatedAt: z.ZodString;
|
|
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>;
|
|
1474
|
+
type ContentAssetCrop = z.infer<typeof ContentAssetCropSchema>;
|
|
1299
1475
|
type ContentItemResponse = z.infer<typeof ContentItemResponseSchema>;
|
|
1476
|
+
type ContentSourceAssetResponse = z.infer<typeof ContentSourceAssetResponseSchema>;
|
|
1477
|
+
type ContentDistributionResponse = z.infer<typeof ContentDistributionResponseSchema>;
|
|
1300
1478
|
|
|
1301
1479
|
/**
|
|
1302
1480
|
* `deriveContentBoard` -- a pure function of `(items, pipeline, now)`. No React, no
|
|
@@ -1344,15 +1522,23 @@ interface ContentBoardCard {
|
|
|
1344
1522
|
awaitingReview: boolean;
|
|
1345
1523
|
}
|
|
1346
1524
|
interface ContentBoardGate {
|
|
1347
|
-
/**
|
|
1348
|
-
|
|
1525
|
+
/**
|
|
1526
|
+
* Where this gate's review happens. Never `'none'` -- a step nobody reviews
|
|
1527
|
+
* has no gate at all.
|
|
1528
|
+
*
|
|
1529
|
+
* This replaced a `reviewMode` field when the enum collapsed to
|
|
1530
|
+
* `'none' | 'required'`, which would have left every gate reporting the same
|
|
1531
|
+
* constant. Venue is the fact a consumer actually renders: the CLI's board
|
|
1532
|
+
* label and the UI's column header both need to say *where*, not *whether*.
|
|
1533
|
+
*/
|
|
1534
|
+
venue: Exclude<ContentReviewVenue, 'none'>;
|
|
1349
1535
|
/** How many cards in the preceding column are awaiting review. */
|
|
1350
1536
|
waitingCount: number;
|
|
1351
1537
|
}
|
|
1352
1538
|
interface ContentBoardColumn {
|
|
1353
1539
|
step: ContentPipelineStepEntry;
|
|
1354
1540
|
cards: ContentBoardCard[];
|
|
1355
|
-
/** Present when this step's
|
|
1541
|
+
/** Present when this step's `reviewVenue` is not `'none'`. A step nobody reviews has no gate. */
|
|
1356
1542
|
gate?: ContentBoardGate;
|
|
1357
1543
|
}
|
|
1358
1544
|
interface ContentBoard {
|
|
@@ -1388,6 +1574,39 @@ declare function deriveContentBoard(items: ContentItemResponse[], pipeline: Cont
|
|
|
1388
1574
|
*/
|
|
1389
1575
|
declare function getContentItemIdentity(item: Pick<ContentItemResponse, 'title' | 'body' | 'payload'>, payloadFields?: ContentPayloadFieldDeclaration[], maxLength?: number): string;
|
|
1390
1576
|
|
|
1577
|
+
/**
|
|
1578
|
+
* Storage-neutral file descriptor.
|
|
1579
|
+
*
|
|
1580
|
+
* Dropbox and Google Drive (the foreseeable second provider) both ship
|
|
1581
|
+
* their own file/metadata shapes. Consumers on both sides of the wire —
|
|
1582
|
+
* a UI file browser and the API route that talks to the provider — need
|
|
1583
|
+
* to agree on one normalized shape, which is why it lives here instead
|
|
1584
|
+
* of being duplicated in each consumer.
|
|
1585
|
+
*
|
|
1586
|
+
* Adapters (`createDropboxAdapter`, a future Drive adapter) stay concrete
|
|
1587
|
+
* and keep their own provider-shaped responses. Normalization into this
|
|
1588
|
+
* type happens at the route/hook boundary — a few lines per provider,
|
|
1589
|
+
* not behind a shared `CloudStorageAdapter` interface.
|
|
1590
|
+
*/
|
|
1591
|
+
interface CloudStorageFile {
|
|
1592
|
+
id: string;
|
|
1593
|
+
name: string;
|
|
1594
|
+
kind: 'file' | 'folder';
|
|
1595
|
+
path?: string;
|
|
1596
|
+
mimeType?: string;
|
|
1597
|
+
sizeBytes?: number;
|
|
1598
|
+
width?: number;
|
|
1599
|
+
height?: number;
|
|
1600
|
+
/** ISO 8601 timestamp the asset was captured (e.g. photo EXIF date), when the provider exposes one. */
|
|
1601
|
+
capturedAt?: string;
|
|
1602
|
+
/**
|
|
1603
|
+
* Optional on purpose. Dropbox does not produce a thumbnail for HEIC or
|
|
1604
|
+
* for anything over 20 MB — "no thumbnail" is a normal state a consumer
|
|
1605
|
+
* renders a fallback for, not an error.
|
|
1606
|
+
*/
|
|
1607
|
+
thumbnailUrl?: string;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1391
1610
|
type SystemSidebarComponent = ComponentType;
|
|
1392
1611
|
type SystemIconComponent = ComponentType<{
|
|
1393
1612
|
size?: number;
|
|
@@ -1807,6 +2026,306 @@ interface ContentReviewCardProps {
|
|
|
1807
2026
|
*/
|
|
1808
2027
|
declare function ContentReviewCard({ title, body, onBodyChange, originalBody, onReset, payload, payloadFields, fidelity, checkFirst, hookOptions, closeOptions, onMoreHooks, onMoreCloses, alternatesRunning, alternatesElapsed, processingSteps, actions, onAction, actionsPending, readOnly }: ContentReviewCardProps): react_jsx_runtime.JSX.Element;
|
|
1809
2028
|
|
|
2029
|
+
interface SelectedAssetStripProps {
|
|
2030
|
+
/**
|
|
2031
|
+
* The selection, in carousel order. Index 0 is the cover slide -- there is no
|
|
2032
|
+
* separate `isCover` flag to keep in sync, because the planned
|
|
2033
|
+
* `content_item_source_assets` link table persists this same array as a `position`
|
|
2034
|
+
* column where `position = 0` IS the cover by definition.
|
|
2035
|
+
*/
|
|
2036
|
+
assets: CloudStorageFile[];
|
|
2037
|
+
/** Fires with the full reordered array whenever the user drags a slide to a new position. */
|
|
2038
|
+
onReorder: (assets: CloudStorageFile[]) => void;
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Ordered strip of the assets selected for a multi-asset content item (an Instagram
|
|
2042
|
+
* carousel post's slides). Presentational -- data in via `assets`, order changes out
|
|
2043
|
+
* via `onReorder`, no fetching. Drag-reorder uses native HTML5 drag events, matching
|
|
2044
|
+
* the pattern already established for `KanbanBoard` / `DealKanbanCard` rather than
|
|
2045
|
+
* introducing a new drag-and-drop dependency for one strip.
|
|
2046
|
+
*/
|
|
2047
|
+
declare function SelectedAssetStrip({ assets, onReorder }: SelectedAssetStripProps): react_jsx_runtime.JSX.Element;
|
|
2048
|
+
|
|
2049
|
+
interface SourceAssetsPanelProps {
|
|
2050
|
+
/** The content item whose membership this panel reads and writes. */
|
|
2051
|
+
itemId: string;
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Operator surface for a content item's ordered source-asset membership -- the
|
|
2055
|
+
* carousel. Reads `content_item_source_assets` and drives all four membership
|
|
2056
|
+
* writes: link, unlink, reorder, and per-slide alt text.
|
|
2057
|
+
*
|
|
2058
|
+
* This exists because the membership write path had no surface at all: it is not on
|
|
2059
|
+
* the CLI, the external API-key routes were deliberately not extended (Open Decision
|
|
2060
|
+
* 10), and the seed workflow still creates items through the legacy singular
|
|
2061
|
+
* `sourceAssetId`. Everything below the hooks was therefore covered by unit tests
|
|
2062
|
+
* only and had never been executed end to end. A basic table is enough to fix that,
|
|
2063
|
+
* and a tenant that wants a picture-first carousel editor builds its own on the same
|
|
2064
|
+
* hooks.
|
|
2065
|
+
*
|
|
2066
|
+
* Two ordering surfaces on purpose. `SelectedAssetStrip` is the picture-first one and
|
|
2067
|
+
* is what tenants get from the `./features/content` subpath, so it is mounted here
|
|
2068
|
+
* against real persisted membership rather than left to render only under test. The
|
|
2069
|
+
* table underneath keeps move up / move down because drag is unusable by keyboard and
|
|
2070
|
+
* unavailable to a screen reader. Both send the identical complete ordered list.
|
|
2071
|
+
*
|
|
2072
|
+
* The strip takes `CloudStorageFile`, which a membership is not -- the mapping below is
|
|
2073
|
+
* the whole adapter. Content source assets carry no thumbnail yet (that arrives with
|
|
2074
|
+
* Dropbox intake), so every tile renders the strip's no-thumbnail fallback today.
|
|
2075
|
+
*
|
|
2076
|
+
* The crop column opens `AssetCropEditor` against the original's bytes, resolved
|
|
2077
|
+
* one file at a time while the modal is open. Only an asset carrying a
|
|
2078
|
+
* cloud-storage reference can be cropped -- there is nothing to crop against
|
|
2079
|
+
* otherwise -- so a seeded or text-backed asset shows the button disabled.
|
|
2080
|
+
*
|
|
2081
|
+
* Positions are shown as stored, not as row indexes. Non-contiguous positions are
|
|
2082
|
+
* legal -- only uniqueness within an item is enforced -- so an item assembled by
|
|
2083
|
+
* individual links can legitimately have no `position` 0, and the cover is the lowest
|
|
2084
|
+
* position present rather than a literal 0.
|
|
2085
|
+
*/
|
|
2086
|
+
declare function SourceAssetsPanel({ itemId }: SourceAssetsPanelProps): react_jsx_runtime.JSX.Element;
|
|
2087
|
+
|
|
2088
|
+
/**
|
|
2089
|
+
* A carousel aspect option. `ratio` is width / height in PIXELS -- `null` means
|
|
2090
|
+
* "whatever the source already is", which is the only option that never crops.
|
|
2091
|
+
*/
|
|
2092
|
+
interface CropAspectOption {
|
|
2093
|
+
value: string;
|
|
2094
|
+
label: string;
|
|
2095
|
+
ratio: number | null;
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* The three shapes a photo post actually takes, plus the uncropped original.
|
|
2099
|
+
* Portrait 4:5 leads because it is the tallest a feed will show without
|
|
2100
|
+
* cropping the image itself, so it is the default for a carousel.
|
|
2101
|
+
*/
|
|
2102
|
+
declare const CROP_ASPECT_OPTIONS: CropAspectOption[];
|
|
2103
|
+
interface AssetCropEditorProps {
|
|
2104
|
+
/**
|
|
2105
|
+
* The FULL-RESOLUTION image. A thumbnail will not do: the crop is stored as
|
|
2106
|
+
* fractions of the source, and a downsampled copy shows the operator a
|
|
2107
|
+
* different frame from the one that gets published.
|
|
2108
|
+
*/
|
|
2109
|
+
imageUrl: string | null;
|
|
2110
|
+
/** The stored crop, or `null` for "uncropped". */
|
|
2111
|
+
value: ContentAssetCrop | null;
|
|
2112
|
+
/** Fires on every committed change. `null` clears the crop back to the full frame. */
|
|
2113
|
+
onChange: (crop: ContentAssetCrop | null) => void;
|
|
2114
|
+
/** Which aspect the control starts on. Defaults to the source's own shape. */
|
|
2115
|
+
defaultAspect?: string;
|
|
2116
|
+
/** Locks the aspect selector -- a carousel wants one ratio across every slide. */
|
|
2117
|
+
aspect?: string;
|
|
2118
|
+
disabled?: boolean;
|
|
2119
|
+
/** Shown above the frame, e.g. `Slide 1`. */
|
|
2120
|
+
label?: string;
|
|
2121
|
+
}
|
|
2122
|
+
/**
|
|
2123
|
+
* Picks the crop box out of a normalized frame, over the image itself.
|
|
2124
|
+
*
|
|
2125
|
+
* The emitted value is exactly what `ContentAssetCropInputSchema` validates:
|
|
2126
|
+
* `{ x, y, width, height }` as fractions of the source, `0,0` at the top-left.
|
|
2127
|
+
* Fractions rather than pixels because the same crop has to survive a resized
|
|
2128
|
+
* derivative, which is also why this needs the original rather than a thumbnail.
|
|
2129
|
+
*
|
|
2130
|
+
* **Aspect is expressed in pixels and stored in fractions**, and the two are not
|
|
2131
|
+
* the same number on a non-square image -- a 1:1 crop of a 4000x3000 photo is
|
|
2132
|
+
* `width: 0.75, height: 1`. `fitBox` is the whole of that conversion.
|
|
2133
|
+
*
|
|
2134
|
+
* Two controls, not a free-form rubber band: an aspect and a size, with the frame
|
|
2135
|
+
* dragged into place. A free rectangle lets an operator produce a shape no feed
|
|
2136
|
+
* will render, and the failure only shows up after posting.
|
|
2137
|
+
*/
|
|
2138
|
+
declare function AssetCropEditor({ imageUrl, value, onChange, defaultAspect, aspect, disabled, label }: AssetCropEditorProps): react_jsx_runtime.JSX.Element;
|
|
2139
|
+
|
|
2140
|
+
/** One slide, in carousel order. */
|
|
2141
|
+
interface PostPreviewSlide {
|
|
2142
|
+
/** Stable per-slide key -- the source asset id, or the storage file id before one exists. */
|
|
2143
|
+
id: string;
|
|
2144
|
+
/** The full-resolution image. `null` renders the empty frame rather than a broken one. */
|
|
2145
|
+
imageUrl: string | null;
|
|
2146
|
+
/** The stored crop, or `null` for the uncropped original. */
|
|
2147
|
+
crop?: ContentAssetCrop | null;
|
|
2148
|
+
altText?: string | null;
|
|
2149
|
+
}
|
|
2150
|
+
interface PostPreviewProps {
|
|
2151
|
+
slides: PostPreviewSlide[];
|
|
2152
|
+
/** The caption as it would post. `null` renders the "no caption yet" line. */
|
|
2153
|
+
caption?: string | null;
|
|
2154
|
+
hashtags?: string[];
|
|
2155
|
+
/** Frame shape, width / height in pixels. Defaults to the 4:5 portrait a carousel uses. */
|
|
2156
|
+
aspectRatio?: number;
|
|
2157
|
+
/** Shown above the frame, e.g. the item title. */
|
|
2158
|
+
title?: string;
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* The carousel as it will actually post: slides in position order, each one
|
|
2162
|
+
* showing only the part its crop keeps, with the caption underneath.
|
|
2163
|
+
*
|
|
2164
|
+
* **The crop is applied here, not baked into any file.** Nothing in this
|
|
2165
|
+
* pipeline writes a cropped derivative -- `content_item_source_assets.crop` is
|
|
2166
|
+
* a normalized box, and every surface that renders a slide applies it. This
|
|
2167
|
+
* component is the reference implementation of that, and the reason it is
|
|
2168
|
+
* shared rather than page-local.
|
|
2169
|
+
*
|
|
2170
|
+
* The technique is an oversized absolutely-positioned image inside an
|
|
2171
|
+
* overflow-hidden frame: an image scaled to `1 / crop.width` of the frame and
|
|
2172
|
+
* offset by `-crop.x / crop.width` puts exactly the kept region in view, in
|
|
2173
|
+
* pure CSS and with no canvas step. `object-fit: cover` stays on so a slide
|
|
2174
|
+
* whose crop aspect does not match the frame is trimmed rather than stretched.
|
|
2175
|
+
*/
|
|
2176
|
+
declare function PostPreview({ slides, caption, hashtags, aspectRatio, title }: PostPreviewProps): react_jsx_runtime.JSX.Element;
|
|
2177
|
+
/**
|
|
2178
|
+
* Positions the image so the frame shows only the crop's region.
|
|
2179
|
+
*
|
|
2180
|
+
* Exported for the unit test: the arithmetic is the one part of this component
|
|
2181
|
+
* that can be silently wrong, and asserting it through a rendered style string
|
|
2182
|
+
* is what catches an inverted sign.
|
|
2183
|
+
*/
|
|
2184
|
+
declare function cropStyle(crop: ContentAssetCrop | null): React.CSSProperties;
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Rendering a crop to an actual file.
|
|
2188
|
+
*
|
|
2189
|
+
* `cropStyle` in `PostPreview` renders the same crop with CSS, which is right for
|
|
2190
|
+
* a preview and useless for posting: the cropped image never exists as bytes, so
|
|
2191
|
+
* there is nothing to download and nothing to hand a platform. This module is the
|
|
2192
|
+
* other half -- the same four normalized numbers, resolved into a JPEG.
|
|
2193
|
+
*
|
|
2194
|
+
* It runs in the browser on purpose. The pixels are already decoded there (the
|
|
2195
|
+
* crop editor and the preview share one download of the original), the source is
|
|
2196
|
+
* a short-lived provider link the server would have to re-fetch, and no image
|
|
2197
|
+
* library exists anywhere in this monorepo -- putting this on the server would
|
|
2198
|
+
* mean adding the first native image binary to a service whose build is a no-op.
|
|
2199
|
+
* A spike on 2026-08-19 confirmed Dropbox's temporary-link hosts send permissive
|
|
2200
|
+
* CORS, so the canvas is not tainted and `toBlob` succeeds.
|
|
2201
|
+
*/
|
|
2202
|
+
/** The private, org-scoped, RLS-gated bucket derivatives live in. */
|
|
2203
|
+
declare const CONTENT_DERIVATIVES_BUCKET = "content-derivatives";
|
|
2204
|
+
/**
|
|
2205
|
+
* Widest edge a derivative is encoded at.
|
|
2206
|
+
*
|
|
2207
|
+
* 1080 is what Instagram renders a feed image at; anything wider is downsampled on
|
|
2208
|
+
* upload, so the extra bytes buy nothing. A crop smaller than this is never
|
|
2209
|
+
* upscaled to reach it -- see `renderCropToJpeg`.
|
|
2210
|
+
*/
|
|
2211
|
+
declare const DERIVATIVE_MAX_WIDTH = 1080;
|
|
2212
|
+
/** JPEG quality. 0.9 measured at 84-104 KB for a 1080x1350 slide. */
|
|
2213
|
+
declare const DERIVATIVE_JPEG_QUALITY = 0.9;
|
|
2214
|
+
/**
|
|
2215
|
+
* Object key for one slide's derivative, WITHOUT the `{organizationId}/` prefix --
|
|
2216
|
+
* `StorageService.buildPath` prepends that server-side, and the `storage.objects`
|
|
2217
|
+
* policies read the org back out of it.
|
|
2218
|
+
*
|
|
2219
|
+
* Keyed by item and source asset rather than by membership id so a re-render
|
|
2220
|
+
* overwrites the previous derivative instead of accumulating one file per edit.
|
|
2221
|
+
* The pair is unique within an item by database constraint, which is what makes
|
|
2222
|
+
* that safe.
|
|
2223
|
+
*/
|
|
2224
|
+
declare function derivativeObjectKey(contentItemId: string, sourceAssetId: string): string;
|
|
2225
|
+
/**
|
|
2226
|
+
* Whether the stored derivative no longer matches the crop it is supposed to show.
|
|
2227
|
+
*
|
|
2228
|
+
* Derived, never stored: a `derivativeIsStale` column would be a second encoding of
|
|
2229
|
+
* what these two values already say, and the two could disagree. A membership with
|
|
2230
|
+
* no crop has nothing to render, and one with no derivative is missing rather than
|
|
2231
|
+
* stale -- both return false, because neither is a file that needs replacing.
|
|
2232
|
+
*/
|
|
2233
|
+
declare function isDerivativeStale(crop: ContentAssetCrop | null, derivativeCrop: ContentAssetCrop | null, derivativePath: string | null): boolean;
|
|
2234
|
+
interface RenderCropOptions {
|
|
2235
|
+
/** Widest edge to encode at. Defaults to `DERIVATIVE_MAX_WIDTH`. */
|
|
2236
|
+
maxWidth?: number;
|
|
2237
|
+
/** JPEG quality, 0-1. Defaults to `DERIVATIVE_JPEG_QUALITY`. */
|
|
2238
|
+
quality?: number;
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* Render a crop box against its source image and return the cropped JPEG.
|
|
2242
|
+
*
|
|
2243
|
+
* `crop` is normalized fractions of the source, exactly as stored -- so this
|
|
2244
|
+
* survives the source being a different pixel size than it was when the crop was
|
|
2245
|
+
* drawn. A `null` crop renders the whole frame, which still does real work: it
|
|
2246
|
+
* normalizes the format and caps the size.
|
|
2247
|
+
*
|
|
2248
|
+
* The output is never upscaled past the cropped region's own pixel count. A tight
|
|
2249
|
+
* crop of a small original produces a smaller file rather than a blurry 1080px
|
|
2250
|
+
* one, and a platform that wants 1080 will upscale it either way.
|
|
2251
|
+
*
|
|
2252
|
+
* Throws rather than returning null on a tainted canvas or an unloadable URL:
|
|
2253
|
+
* silently storing no derivative is indistinguishable from never having tried.
|
|
2254
|
+
*/
|
|
2255
|
+
declare function renderCropToJpeg(imageUrl: string, crop: ContentAssetCrop | null, options?: RenderCropOptions): Promise<Blob>;
|
|
2256
|
+
|
|
2257
|
+
/** The `content:catalog/photo-carousel-steps` entry this panel drives. */
|
|
2258
|
+
declare const CAPTION_STEP_KEY = "caption-generation";
|
|
2259
|
+
/** The OM Resource bound to `content:action/caption-generation`. */
|
|
2260
|
+
declare const CAPTION_WORKFLOW_ID = "cnt-caption-generation-workflow";
|
|
2261
|
+
interface CaptionPanelProps {
|
|
2262
|
+
itemId: string;
|
|
2263
|
+
/** The item's current `body`, so the panel can mark which attempt is the live caption. */
|
|
2264
|
+
body?: string | null;
|
|
2265
|
+
/**
|
|
2266
|
+
* Called on every keystroke with the unsaved caption text.
|
|
2267
|
+
*
|
|
2268
|
+
* This exists so a preview rendered beside the editor updates as the operator
|
|
2269
|
+
* types rather than one autosave later. Consumers that only care about the
|
|
2270
|
+
* persisted value can ignore it and read `body` as before.
|
|
2271
|
+
*/
|
|
2272
|
+
onDraftChange?: (draft: string) => void;
|
|
2273
|
+
}
|
|
2274
|
+
/**
|
|
2275
|
+
* Generate a caption for a carousel, regenerate it, and pick which one becomes
|
|
2276
|
+
* the item's body.
|
|
2277
|
+
*
|
|
2278
|
+
* **Regeneration does not overwrite.** Every run of
|
|
2279
|
+
* `cnt-caption-generation-workflow` writes its own `content_item_attempts` row,
|
|
2280
|
+
* so a second caption competes with the first rather than replacing it, and the
|
|
2281
|
+
* one the operator liked stays reachable after they try something else. Nothing
|
|
2282
|
+
* here is promoted automatically: `content_items.body` changes only when someone
|
|
2283
|
+
* presses Use, which is exactly what the step's `reviewMode: 'required'` means.
|
|
2284
|
+
*
|
|
2285
|
+
* The workflow runs asynchronously and the panel polls its execution, because
|
|
2286
|
+
* a vision-informed caption over several slides regularly outruns the API's
|
|
2287
|
+
* 60-second synchronous request timeout.
|
|
2288
|
+
*/
|
|
2289
|
+
declare function CaptionPanel({ itemId, body, onDraftChange }: CaptionPanelProps): react_jsx_runtime.JSX.Element;
|
|
2290
|
+
|
|
2291
|
+
/** The OM Resource bound to `content:action/image-analysis`. */
|
|
2292
|
+
declare const IMAGE_ANALYSIS_WORKFLOW_ID = "cnt-image-analysis-workflow";
|
|
2293
|
+
interface SlideAnalysisPanelProps {
|
|
2294
|
+
itemId: string;
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* What `cnt-image-analysis-workflow` writes to `content_source_assets.metadata.analysis`.
|
|
2298
|
+
* Every field is read defensively: the column is free-form jsonb, so an older row, a
|
|
2299
|
+
* hand-edited one, or one written by a future version of the workflow may carry
|
|
2300
|
+
* anything at all.
|
|
2301
|
+
*/
|
|
2302
|
+
interface StoredSlideAnalysis {
|
|
2303
|
+
description?: string;
|
|
2304
|
+
subjects?: string[];
|
|
2305
|
+
setting?: string;
|
|
2306
|
+
mood?: string;
|
|
2307
|
+
textInImage?: string;
|
|
2308
|
+
altText?: string;
|
|
2309
|
+
model?: string;
|
|
2310
|
+
generatedAt?: string;
|
|
2311
|
+
}
|
|
2312
|
+
/** Reads the analysis off an asset, or `null` when it has never been analysed. */
|
|
2313
|
+
declare function readStoredAnalysis(asset: ContentSourceAssetResponse | undefined): StoredSlideAnalysis | null;
|
|
2314
|
+
/**
|
|
2315
|
+
* Runs image analysis over a carousel's slides and shows what came back.
|
|
2316
|
+
*
|
|
2317
|
+
* **The analysis lives on the ASSET, not on the membership** (Open Decision 14).
|
|
2318
|
+
* It describes the photograph, so it is written once per photo and every item
|
|
2319
|
+
* that uses that photo reads the same description -- and a re-crop does not
|
|
2320
|
+
* invalidate it. The per-slide fields beside it (`crop`, `altText`) stay on the
|
|
2321
|
+
* membership, where a slide's role in one particular carousel belongs.
|
|
2322
|
+
*
|
|
2323
|
+
* Re-running is a plain overwrite here, unlike captions: there is no competing
|
|
2324
|
+
* "which description is better" judgement to preserve, and an analysis is an
|
|
2325
|
+
* input to the caption rather than something anyone publishes.
|
|
2326
|
+
*/
|
|
2327
|
+
declare function SlideAnalysisPanel({ itemId }: SlideAnalysisPanelProps): react_jsx_runtime.JSX.Element;
|
|
2328
|
+
|
|
1810
2329
|
/** A single tenant-facing noun with singular and plural forms, e.g. `{ singular: 'Post', plural: 'Posts' }`. */
|
|
1811
2330
|
interface ContentNoun {
|
|
1812
2331
|
singular: string;
|
|
@@ -1975,7 +2494,7 @@ interface ContentSidebarProps {
|
|
|
1975
2494
|
declare const ContentSidebar: ({ workspaceItems, createItems, children }?: ContentSidebarProps) => react_jsx_runtime.JSX.Element;
|
|
1976
2495
|
|
|
1977
2496
|
/**
|
|
1978
|
-
* Static
|
|
2497
|
+
* Static three-entry default, built from {@link DEFAULT_CONTENT_VOCABULARY}. Exists for
|
|
1979
2498
|
* consumers that spread it at module load time (see `extend-content.md`), where a
|
|
1980
2499
|
* tenant's declared vocabulary isn't available. `ContentSidebarMiddle` itself renders
|
|
1981
2500
|
* the live, vocabulary-aware version instead of this constant.
|
|
@@ -2000,7 +2519,7 @@ interface ContentSidebarMiddleProps {
|
|
|
2000
2519
|
* that section now holds review too.
|
|
2001
2520
|
*/
|
|
2002
2521
|
createItems?: NavItem[];
|
|
2003
|
-
/** Override the pipeline nav items. Defaults to the
|
|
2522
|
+
/** Override the pipeline nav items. Defaults to the three-entry nav built from the tenant's declared vocabulary. */
|
|
2004
2523
|
items?: NavItem[];
|
|
2005
2524
|
}
|
|
2006
2525
|
/**
|
|
@@ -2038,8 +2557,8 @@ interface MyReviewQueuePanelProps {
|
|
|
2038
2557
|
* cross-pipeline "what needs review" view rather than a panel beside a table browser.
|
|
2039
2558
|
*
|
|
2040
2559
|
* The `/content/items` route accepts no "pending review" filter (only `reviewedBy`, not
|
|
2041
|
-
* a reviewed/unreviewed flag), so this fetches a page of items and filters to
|
|
2042
|
-
* `
|
|
2560
|
+
* a reviewed/unreviewed flag), so this fetches a page of items and filters to the ones
|
|
2561
|
+
* `isAwaitingReview` client-side. A future backend addition could push this
|
|
2043
2562
|
* server-side; documenting the gap here rather than silently over-claiming precision.
|
|
2044
2563
|
*
|
|
2045
2564
|
* Rows are ordered oldest-first by `updatedAt` -- finding 6 is that nothing on the
|
|
@@ -2048,5 +2567,170 @@ interface MyReviewQueuePanelProps {
|
|
|
2048
2567
|
*/
|
|
2049
2568
|
declare function MyReviewQueuePanel({ onItemClick, onSeeAll, showSectionLabel }: MyReviewQueuePanelProps): react_jsx_runtime.JSX.Element;
|
|
2050
2569
|
|
|
2051
|
-
|
|
2052
|
-
|
|
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 };
|