@carlonicora/nextjs-jsonapi 5.2.0 → 5.3.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 (134) hide show
  1. package/dist/{BlockNoteEditor-EGY4ZAAM.js → BlockNoteEditor-UJ6363LC.js} +19 -19
  2. package/dist/{BlockNoteEditor-EGY4ZAAM.js.map → BlockNoteEditor-UJ6363LC.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-2QJVK2HH.mjs → BlockNoteEditor-WTSQANKI.mjs} +4 -4
  4. package/dist/{BlockNoteViewer-I2MMFH3S.js → BlockNoteViewer-EL4JFB6P.js} +3 -3
  5. package/dist/{BlockNoteViewer-I2MMFH3S.js.map → BlockNoteViewer-EL4JFB6P.js.map} +1 -1
  6. package/dist/{BlockNoteViewer-6BQXJ4TB.mjs → BlockNoteViewer-JVKWJZ6J.mjs} +2 -2
  7. package/dist/billing/index.js +441 -441
  8. package/dist/billing/index.mjs +3 -3
  9. package/dist/{chunk-3VEQ5JZJ.js → chunk-3BAM23VA.js} +847 -847
  10. package/dist/chunk-3BAM23VA.js.map +1 -0
  11. package/dist/{chunk-JEZQTZQ4.mjs → chunk-6WU74VFU.mjs} +2 -2
  12. package/dist/{chunk-S5MQDWWC.js → chunk-CRI4T47Y.js} +736 -176
  13. package/dist/chunk-CRI4T47Y.js.map +1 -0
  14. package/dist/{chunk-75MLT74B.js → chunk-EO75CV76.js} +8 -8
  15. package/dist/{chunk-75MLT74B.js.map → chunk-EO75CV76.js.map} +1 -1
  16. package/dist/{chunk-NPKFMRH5.mjs → chunk-FNTQQFLH.mjs} +2 -2
  17. package/dist/{chunk-HNOWSFM5.mjs → chunk-JQWI62NV.mjs} +563 -3
  18. package/dist/chunk-JQWI62NV.mjs.map +1 -0
  19. package/dist/{chunk-2Z3ZCYXX.mjs → chunk-MIZTWBPX.mjs} +5 -5
  20. package/dist/chunk-MIZTWBPX.mjs.map +1 -0
  21. package/dist/{chunk-YMUPTXOT.mjs → chunk-QKZUE5OF.mjs} +2 -2
  22. package/dist/{chunk-EXICQC4A.js → chunk-QQQE3N2X.js} +3 -3
  23. package/dist/{chunk-EXICQC4A.js.map → chunk-QQQE3N2X.js.map} +1 -1
  24. package/dist/{chunk-THKYH65N.js → chunk-XGTQWBDJ.js} +4 -4
  25. package/dist/{chunk-THKYH65N.js.map → chunk-XGTQWBDJ.js.map} +1 -1
  26. package/dist/client/index.d.mts +6 -39
  27. package/dist/client/index.d.ts +6 -39
  28. package/dist/client/index.js +4 -4
  29. package/dist/client/index.mjs +3 -3
  30. package/dist/components/index.d.mts +2 -2
  31. package/dist/components/index.d.ts +2 -2
  32. package/dist/components/index.js +4 -4
  33. package/dist/components/index.mjs +3 -3
  34. package/dist/contexts/index.js +4 -4
  35. package/dist/contexts/index.mjs +3 -3
  36. package/dist/core/index.d.mts +187 -1
  37. package/dist/core/index.d.ts +187 -1
  38. package/dist/core/index.js +30 -2
  39. package/dist/core/index.js.map +1 -1
  40. package/dist/core/index.mjs +29 -1
  41. package/dist/email-automation-enrollment.fields-BZvF14qx.d.mts +82 -0
  42. package/dist/email-automation-enrollment.fields-Cp3VMzFq.d.ts +82 -0
  43. package/dist/email-automations/index.css +30 -0
  44. package/dist/email-automations/index.css.map +1 -0
  45. package/dist/email-automations/index.d.mts +303 -0
  46. package/dist/email-automations/index.d.ts +303 -0
  47. package/dist/email-automations/index.js +1705 -0
  48. package/dist/email-automations/index.js.map +1 -0
  49. package/dist/email-automations/index.mjs +1705 -0
  50. package/dist/email-automations/index.mjs.map +1 -0
  51. package/dist/features/analytics/index.js +122 -122
  52. package/dist/features/analytics/index.mjs +4 -4
  53. package/dist/features/analytics/server.js +4 -4
  54. package/dist/features/analytics/server.mjs +2 -2
  55. package/dist/features/help/index.js +37 -37
  56. package/dist/features/help/index.mjs +3 -3
  57. package/dist/features/tokenusage/index.js +125 -125
  58. package/dist/features/tokenusage/index.mjs +4 -4
  59. package/dist/index.d.mts +2 -1
  60. package/dist/index.d.ts +2 -1
  61. package/dist/index.js +31 -3
  62. package/dist/index.js.map +1 -1
  63. package/dist/index.mjs +30 -2
  64. package/dist/server/index.js +3 -3
  65. package/dist/server/index.mjs +2 -2
  66. package/dist/types-70acd-8C.d.mts +39 -0
  67. package/dist/types-l8SFleXi.d.ts +39 -0
  68. package/messages/en.json +117 -0
  69. package/messages/it.json +117 -0
  70. package/package.json +11 -1
  71. package/src/components/forms/FormFieldWrapper.tsx +1 -1
  72. package/src/components/forms/FormTextarea.tsx +2 -1
  73. package/src/core/index.ts +8 -0
  74. package/src/core/registry/ModuleRegistry.ts +5 -0
  75. package/src/email-automations/index.ts +5 -0
  76. package/src/features/email-automation/EmailAutomationEnrollmentModule.ts +11 -0
  77. package/src/features/email-automation/EmailAutomationModule.ts +30 -0
  78. package/src/features/email-automation/EmailAutomationStepModule.ts +11 -0
  79. package/src/features/email-automation/EmailAutomationTriggerModule.ts +11 -0
  80. package/src/features/email-automation/components/__tests__/EmailAutomationEditor.spec.tsx +104 -0
  81. package/src/features/email-automation/components/canvas/EmailAutomationActiveSwitch.tsx +49 -0
  82. package/src/features/email-automation/components/canvas/EmailAutomationCanvas.tsx +474 -0
  83. package/src/features/email-automation/components/canvas/EmailAutomationCanvasInspector.tsx +89 -0
  84. package/src/features/email-automation/components/canvas/EmailAutomationCanvasTab.tsx +32 -0
  85. package/src/features/email-automation/components/canvas/__tests__/buildCanvasGraph.spec.ts +67 -0
  86. package/src/features/email-automation/components/canvas/buildCanvasGraph.ts +141 -0
  87. package/src/features/email-automation/components/canvas/edges/DelayEdge.tsx +68 -0
  88. package/src/features/email-automation/components/canvas/nodes/EmailStepNode.tsx +43 -0
  89. package/src/features/email-automation/components/canvas/nodes/TriggerNode.tsx +23 -0
  90. package/src/features/email-automation/components/canvas/shared/CanvasToolbar.tsx +53 -0
  91. package/src/features/email-automation/components/canvas/shared/EmptyCanvas.tsx +11 -0
  92. package/src/features/email-automation/components/canvas/shared/__tests__/autoLayout.spec.ts +42 -0
  93. package/src/features/email-automation/components/canvas/shared/__tests__/longPress.spec.ts +51 -0
  94. package/src/features/email-automation/components/canvas/shared/autoLayout.ts +55 -0
  95. package/src/features/email-automation/components/canvas/shared/index.ts +4 -0
  96. package/src/features/email-automation/components/canvas/shared/longPress.ts +57 -0
  97. package/src/features/email-automation/components/containers/EmailAutomationContainer.tsx +80 -0
  98. package/src/features/email-automation/components/containers/EmailAutomationsListContainer.tsx +27 -0
  99. package/src/features/email-automation/components/forms/EmailAutomationEditor.tsx +153 -0
  100. package/src/features/email-automation/components/forms/EmailStepEditor.tsx +151 -0
  101. package/src/features/email-automation/components/index.ts +15 -0
  102. package/src/features/email-automation/components/lists/EmailAutomationRecipientsList.tsx +90 -0
  103. package/src/features/email-automation/components/lists/EmailAutomationsList.tsx +76 -0
  104. package/src/features/email-automation/components/unsubscribe/EmailUnsubscribe.tsx +99 -0
  105. package/src/features/email-automation/components/unsubscribe/__tests__/EmailUnsubscribe.spec.tsx +55 -0
  106. package/src/features/email-automation/contexts/EmailAutomationContext.tsx +175 -0
  107. package/src/features/email-automation/data/EmailAutomation.ts +87 -0
  108. package/src/features/email-automation/data/EmailAutomationEnrollment.ts +105 -0
  109. package/src/features/email-automation/data/EmailAutomationEnrollmentInterface.ts +18 -0
  110. package/src/features/email-automation/data/EmailAutomationEnrollmentService.ts +31 -0
  111. package/src/features/email-automation/data/EmailAutomationInterface.ts +22 -0
  112. package/src/features/email-automation/data/EmailAutomationService.ts +106 -0
  113. package/src/features/email-automation/data/EmailAutomationStep.ts +104 -0
  114. package/src/features/email-automation/data/EmailAutomationStepInterface.ts +23 -0
  115. package/src/features/email-automation/data/EmailAutomationStepService.ts +80 -0
  116. package/src/features/email-automation/data/EmailAutomationTrigger.ts +28 -0
  117. package/src/features/email-automation/data/EmailAutomationTriggerInterface.ts +6 -0
  118. package/src/features/email-automation/data/__tests__/email-automation-models.spec.ts +103 -0
  119. package/src/features/email-automation/data/email-automation-enrollment.fields.ts +8 -0
  120. package/src/features/email-automation/data/email-automation.fields.ts +9 -0
  121. package/src/features/email-automation/data/index.ts +13 -0
  122. package/src/features/email-automation/hooks/index.ts +2 -0
  123. package/src/features/email-automation/hooks/useEmailAutomationEnrollmentTableStructure.tsx +126 -0
  124. package/src/features/email-automation/hooks/useEmailAutomationTableStructure.tsx +119 -0
  125. package/src/features/email-automation/index.ts +5 -0
  126. package/dist/chunk-2Z3ZCYXX.mjs.map +0 -1
  127. package/dist/chunk-3VEQ5JZJ.js.map +0 -1
  128. package/dist/chunk-HNOWSFM5.mjs.map +0 -1
  129. package/dist/chunk-S5MQDWWC.js.map +0 -1
  130. /package/dist/{BlockNoteEditor-2QJVK2HH.mjs.map → BlockNoteEditor-WTSQANKI.mjs.map} +0 -0
  131. /package/dist/{BlockNoteViewer-6BQXJ4TB.mjs.map → BlockNoteViewer-JVKWJZ6J.mjs.map} +0 -0
  132. /package/dist/{chunk-JEZQTZQ4.mjs.map → chunk-6WU74VFU.mjs.map} +0 -0
  133. /package/dist/{chunk-NPKFMRH5.mjs.map → chunk-FNTQQFLH.mjs.map} +0 -0
  134. /package/dist/{chunk-YMUPTXOT.mjs.map → chunk-QKZUE5OF.mjs.map} +0 -0
@@ -0,0 +1,303 @@
1
+ import * as React from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { a as EmailAutomationInterface, c as EmailAutomationStepInterface, b as EmailAutomationStepInput, f as EmailAutomationTriggerInterface, g as EmailAutomationFields, e as EmailAutomationEnrollmentInterface, h as EmailAutomationEnrollmentFields } from '../email-automation-enrollment.fields-BZvF14qx.mjs';
4
+ import { Node, Edge, NodeProps, EdgeProps } from '@xyflow/react';
5
+ import { U as UseTableStructureHook } from '../types-70acd-8C.mjs';
6
+ import '../ApiDataInterface-BcZeXy5X.mjs';
7
+ import '@tanstack/react-table';
8
+ import '../types-Bq_UA8Lg.mjs';
9
+ import 'lucide-react';
10
+ import '../ApiRequestDataTypeInterface-CYEcRUrh.mjs';
11
+ import '../useDataListRetriever-WEXL4bqB.mjs';
12
+
13
+ /**
14
+ * Page container for the administrative email-automation list.
15
+ *
16
+ * Client component by necessity: `module={Modules.EmailAutomation}` is a
17
+ * registry entry carrying an icon component and methods, which a Server
18
+ * Component cannot pass across the boundary. Routes mount this container
19
+ * instead — the same shape as every other list page.
20
+ *
21
+ * No `forceHeader`: ContentListTable draws its own header row with the title
22
+ * and the create action, exactly as the company and user list pages do.
23
+ */
24
+ declare function EmailAutomationsListContainer(): React.JSX.Element;
25
+
26
+ type EmailAutomationContainerProps = {
27
+ automationId: string;
28
+ };
29
+ declare function EmailAutomationContainer({ automationId }: EmailAutomationContainerProps): React.JSX.Element;
30
+
31
+ type EmailAutomationsListProps = {
32
+ /**
33
+ * Pass this whenever the list is the page's own content inside a
34
+ * `RoundPageContainer fullWidth`. Without it ContentListTable wraps itself in
35
+ * `rounded-md border`, drawing a second bordered card inside the page's
36
+ * rounded shell.
37
+ */
38
+ fullWidth?: boolean;
39
+ };
40
+ declare function EmailAutomationsList({ fullWidth }?: EmailAutomationsListProps): React.JSX.Element;
41
+
42
+ /**
43
+ * Read-only list of the people in this automation (owner decision 6: no row
44
+ * actions). Rendered inside a tab, so it keeps its own bordered card (no
45
+ * `fullWidth`), as PricesList does inside ProductContainer.
46
+ */
47
+ declare function EmailAutomationRecipientsList(): React.JSX.Element;
48
+
49
+ type EmailAutomationEditorProps = {
50
+ automation?: EmailAutomationInterface;
51
+ propagateChanges?: (automation: EmailAutomationInterface) => void;
52
+ onSuccess?: () => void | Promise<void>;
53
+ trigger?: ReactNode;
54
+ forceShow?: boolean;
55
+ onClose?: () => void;
56
+ dialogOpen?: boolean;
57
+ onDialogOpenChange?: (open: boolean) => void;
58
+ };
59
+ declare function EmailAutomationEditor(props: EmailAutomationEditorProps): React.JSX.Element;
60
+
61
+ type EmailStepEditorProps = {
62
+ step?: EmailAutomationStepInterface;
63
+ automationId: string;
64
+ /** Canvas position for a step created from the editor. */
65
+ initialPosition?: {
66
+ x: number;
67
+ y: number;
68
+ };
69
+ /** The head step's delay counts from entering the automation, not from a previous email. */
70
+ isHead?: boolean;
71
+ trigger?: ReactNode;
72
+ forceShow?: boolean;
73
+ onClose?: () => void;
74
+ dialogOpen?: boolean;
75
+ onDialogOpenChange?: (open: boolean) => void;
76
+ onSuccess?: () => void | Promise<void>;
77
+ };
78
+ declare function EmailStepEditor(props: EmailStepEditorProps): React.JSX.Element;
79
+
80
+ /**
81
+ * Inline on/off for the automation page header, so pausing never needs the
82
+ * editor sheet. Off holds every enrolment in place (spec § "Sending" 3).
83
+ */
84
+ declare function EmailAutomationActiveSwitch(): React.JSX.Element | null;
85
+
86
+ declare function EmailAutomationCanvasTab(): React.JSX.Element;
87
+
88
+ declare function EmailAutomationCanvas(): React.JSX.Element;
89
+
90
+ /**
91
+ * Mounts EmailStepEditor (the EditorSheet the step uses everywhere) on top of
92
+ * the canvas, driven by `selectedStepId` from EmailAutomationContext. Copy of
93
+ * the app's ScenarioCanvasInspector with one branch.
94
+ *
95
+ * - We control open state via `forceShow + dialogOpen + onDialogOpenChange`.
96
+ * - On `onSuccess` we reload the canvas.
97
+ * - The step comes from the context's `steps` (already loaded for the
98
+ * canvas), so there is no per-step fetch.
99
+ */
100
+ declare function EmailAutomationCanvasInspector(): React.JSX.Element | null;
101
+ /**
102
+ * Build an `onDialogOpenChange` callback that ignores the editor's
103
+ * initial `open=false` notification. `useEditorDialog` (the hook
104
+ * inside every EditorSheet) initialises `open` to `false`, then in
105
+ * an effect sets it to `dialogOpen` (true). The "open=false" effect
106
+ * fires synchronously on mount and would otherwise wipe our canvas
107
+ * selection before the editor ever paints.
108
+ */
109
+ declare function useUserClosedGuard(onClose: () => void): (open: boolean) => void;
110
+
111
+ declare const TRIGGER_NODE_ID = "trigger";
112
+ declare const TRIGGER_SOURCE_HANDLE = "trigger-source";
113
+ declare const STEP_NODE_PREFIX = "step:";
114
+ declare const STEP_SOURCE_HANDLE_PREFIX = "step-source-";
115
+ declare const STEP_TARGET_HANDLE_PREFIX = "step-target-";
116
+ declare const TRIGGER_NODE_WIDTH = 200;
117
+ declare const TRIGGER_NODE_HEIGHT = 56;
118
+ declare const STEP_NODE_WIDTH = 200;
119
+ declare const STEP_NODE_HEIGHT = 72;
120
+ /**
121
+ * The fields the canvas reads from a step. `EmailAutomationStepInterface`
122
+ * satisfies it structurally; the narrow shape keeps this function pure and
123
+ * testable with plain objects.
124
+ */
125
+ type CanvasStep = {
126
+ id: string;
127
+ subject: string;
128
+ delayHours: number;
129
+ positionX?: number;
130
+ positionY?: number;
131
+ sentCount: number;
132
+ next?: {
133
+ id: string;
134
+ };
135
+ };
136
+ type TriggerNodeData = {
137
+ label: string;
138
+ };
139
+ type EmailStepNodeData = {
140
+ stepId: string;
141
+ subject: string;
142
+ sentCount: number;
143
+ orphan: boolean;
144
+ manuallyPositioned: boolean;
145
+ };
146
+ type DelayEdgeData = {
147
+ targetStepId: string;
148
+ delayHours: number;
149
+ };
150
+ type CanvasGraph = {
151
+ nodes: Node[];
152
+ edges: Edge[];
153
+ orphanIds: string[];
154
+ };
155
+ /**
156
+ * The head is the oldest step with no incoming NEXT, exactly as the API picks
157
+ * it (`findHead`). `steps` arrive ordered by createdAt ASC from
158
+ * `findByAutomation`, so the first step nobody points at is the head.
159
+ */
160
+ declare function findHeadStepId(steps: CanvasStep[]): string | null;
161
+ /**
162
+ * Turns the automation's steps into React Flow nodes and edges: the trigger
163
+ * node, one node per step, a trigger→head edge, and one edge per NEXT link.
164
+ * Steps not reachable from the head (walking next→next) are orphans: they
165
+ * never send and render dashed.
166
+ */
167
+ declare function buildCanvasGraph(steps: CanvasStep[], triggerLabel: string): CanvasGraph;
168
+
169
+ type TriggerNodeType = Node<{
170
+ data: TriggerNodeData;
171
+ }>;
172
+ /**
173
+ * The fixed head of the chain (SecretTargetNode recipe). Source handle only:
174
+ * people enter here. Plain element, no Base UI inside the node; the click that
175
+ * opens EmailAutomationEditor is handled by the canvas (`onNodeClick`).
176
+ */
177
+ declare function TriggerNode({ data }: NodeProps<TriggerNodeType>): React.JSX.Element;
178
+
179
+ type EmailStepNodeType = Node<{
180
+ data: EmailStepNodeData;
181
+ }>;
182
+ /**
183
+ * 200px card (SceneNode recipe): subject bold, "sent N" muted. An orphan (not
184
+ * reachable from the trigger, so it never sends) is the dashed, faded variant
185
+ * with a caption. Plain elements only: Base UI menus/popovers do not work
186
+ * inside React Flow nodes; clicks and context menus are handled by the canvas.
187
+ */
188
+ declare function EmailStepNode({ data }: NodeProps<EmailStepNodeType>): React.JSX.Element;
189
+
190
+ type DelayEdgeType = Edge<DelayEdgeData>;
191
+ /**
192
+ * ClueEdge recipe: a bezier with a label chip at its midpoint. The chip shows
193
+ * the target step's delay and opens that step's editor. It is a plain
194
+ * <button>: Base UI popovers do not work inside the React Flow canvas.
195
+ */
196
+ declare function DelayEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, label, data, }: EdgeProps<DelayEdgeType>): React.JSX.Element;
197
+
198
+ type UnsubscribeScope = "automation" | "all";
199
+ interface Props {
200
+ token: string;
201
+ scope: UnsubscribeScope;
202
+ }
203
+ declare function EmailUnsubscribe({ token, scope }: Props): React.JSX.Element;
204
+
205
+ /** A new step: the provider always sets `automationId` and, when absent, a fresh `id`. */
206
+ type EmailAutomationStepCreateInput = Omit<EmailAutomationStepInput, "id" | "automationId"> & {
207
+ id?: string;
208
+ automationId?: string;
209
+ };
210
+ /** A step update: the provider always sets `automationId`. */
211
+ type EmailAutomationStepUpdateInput = Omit<EmailAutomationStepInput, "automationId"> & {
212
+ automationId?: string;
213
+ };
214
+ interface EmailAutomationContextType {
215
+ automation: EmailAutomationInterface | undefined;
216
+ steps: EmailAutomationStepInterface[];
217
+ reload: () => Promise<void>;
218
+ selectedStepId: string | null;
219
+ select: (id: string | null) => void;
220
+ createStep: (input: EmailAutomationStepCreateInput) => Promise<EmailAutomationStepInterface>;
221
+ updateStep: (input: EmailAutomationStepUpdateInput) => Promise<EmailAutomationStepInterface>;
222
+ deleteStep: (id: string) => Promise<void>;
223
+ setNext: (stepId: string, nextStepId: string | null) => Promise<void>;
224
+ updatePosition: (stepId: string, x: number, y: number) => Promise<void>;
225
+ tidy: () => Promise<void>;
226
+ triggers: EmailAutomationTriggerInterface[];
227
+ }
228
+ type EmailAutomationProviderProps = {
229
+ automationId: string;
230
+ children: ReactNode;
231
+ };
232
+ declare const EmailAutomationProvider: ({ automationId, children }: EmailAutomationProviderProps) => React.JSX.Element;
233
+ declare const useEmailAutomation: () => EmailAutomationContextType;
234
+
235
+ declare function CanvasToolbar({ onTidy }: {
236
+ onTidy: () => void | Promise<void>;
237
+ }): React.JSX.Element;
238
+
239
+ declare function EmptyCanvas({ children }: {
240
+ children: ReactNode;
241
+ }): React.JSX.Element;
242
+
243
+ type LayoutNode = {
244
+ id: string;
245
+ /** node body dimensions in canvas px — used by dagre to allocate space */
246
+ width: number;
247
+ height: number;
248
+ /** if true, dagre leaves position alone and uses these (x, y) verbatim */
249
+ manuallyPositioned: boolean;
250
+ x?: number;
251
+ y?: number;
252
+ };
253
+ type LayoutEdge = {
254
+ source: string;
255
+ target: string;
256
+ };
257
+ type LayoutResult = Record<string, {
258
+ x: number;
259
+ y: number;
260
+ }>;
261
+ /**
262
+ * Deterministic LR layout. Pinned nodes keep their (x, y). Unpinned nodes
263
+ * are laid out by dagre and returned in the result map.
264
+ */
265
+ declare function autoLayout(nodes: LayoutNode[], edges: LayoutEdge[]): LayoutResult;
266
+
267
+ declare const LONG_PRESS_MS = 500;
268
+ declare const LONG_PRESS_MOVE_TOLERANCE_PX = 10;
269
+ /**
270
+ * Touch long-press detector for canvas nodes. A finger held still for
271
+ * LONG_PRESS_MS on a node fires `onLongPress` with the press point; any move
272
+ * beyond the tolerance (a pan or a node drag), a lift or a cancel aborts it.
273
+ * After a fired press, `consumeClick()` returns true once, so the caller can
274
+ * swallow the click that the finger lift produces.
275
+ */
276
+ declare function createLongPressTracker(params: {
277
+ onLongPress: (press: {
278
+ target: string;
279
+ clientX: number;
280
+ clientY: number;
281
+ }) => void;
282
+ delayMs?: number;
283
+ moveTolerancePx?: number;
284
+ setTimer?: (fn: () => void, ms: number) => unknown;
285
+ clearTimer?: (handle: unknown) => void;
286
+ }): {
287
+ down(target: string, clientX: number, clientY: number): void;
288
+ move(clientX: number, clientY: number): void;
289
+ up: () => void;
290
+ cancel: () => void;
291
+ consumeClick(): boolean;
292
+ };
293
+
294
+ /**
295
+ * `context.triggerLabels` maps a trigger key to the label the API declares for
296
+ * it (EmailAutomationsList loads them). A key the app no longer declares falls
297
+ * back to the raw key, so a stale automation stays readable.
298
+ */
299
+ declare const useEmailAutomationTableStructure: UseTableStructureHook<EmailAutomationInterface, EmailAutomationFields>;
300
+
301
+ declare const useEmailAutomationEnrollmentTableStructure: UseTableStructureHook<EmailAutomationEnrollmentInterface, EmailAutomationEnrollmentFields>;
302
+
303
+ export { type CanvasGraph, type CanvasStep, CanvasToolbar, DelayEdge, type DelayEdgeData, EmailAutomationActiveSwitch, EmailAutomationCanvas, EmailAutomationCanvasInspector, EmailAutomationCanvasTab, EmailAutomationContainer, type EmailAutomationContainerProps, type EmailAutomationContextType, EmailAutomationEditor, type EmailAutomationEditorProps, EmailAutomationProvider, type EmailAutomationProviderProps, EmailAutomationRecipientsList, type EmailAutomationStepCreateInput, type EmailAutomationStepUpdateInput, EmailAutomationsList, EmailAutomationsListContainer, EmailStepEditor, type EmailStepEditorProps, EmailStepNode, type EmailStepNodeData, EmailUnsubscribe, EmptyCanvas, LONG_PRESS_MOVE_TOLERANCE_PX, LONG_PRESS_MS, type LayoutEdge, type LayoutNode, type LayoutResult, STEP_NODE_HEIGHT, STEP_NODE_PREFIX, STEP_NODE_WIDTH, STEP_SOURCE_HANDLE_PREFIX, STEP_TARGET_HANDLE_PREFIX, TRIGGER_NODE_HEIGHT, TRIGGER_NODE_ID, TRIGGER_NODE_WIDTH, TRIGGER_SOURCE_HANDLE, TriggerNode, type TriggerNodeData, autoLayout, buildCanvasGraph, createLongPressTracker, findHeadStepId, useEmailAutomation, useEmailAutomationEnrollmentTableStructure, useEmailAutomationTableStructure, useUserClosedGuard };
@@ -0,0 +1,303 @@
1
+ import * as React from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { a as EmailAutomationInterface, c as EmailAutomationStepInterface, b as EmailAutomationStepInput, f as EmailAutomationTriggerInterface, g as EmailAutomationFields, e as EmailAutomationEnrollmentInterface, h as EmailAutomationEnrollmentFields } from '../email-automation-enrollment.fields-Cp3VMzFq.js';
4
+ import { Node, Edge, NodeProps, EdgeProps } from '@xyflow/react';
5
+ import { U as UseTableStructureHook } from '../types-l8SFleXi.js';
6
+ import '../ApiDataInterface-BcZeXy5X.js';
7
+ import '@tanstack/react-table';
8
+ import '../types-bsm8Fp55.js';
9
+ import 'lucide-react';
10
+ import '../ApiRequestDataTypeInterface-CYEcRUrh.js';
11
+ import '../useDataListRetriever-WEXL4bqB.js';
12
+
13
+ /**
14
+ * Page container for the administrative email-automation list.
15
+ *
16
+ * Client component by necessity: `module={Modules.EmailAutomation}` is a
17
+ * registry entry carrying an icon component and methods, which a Server
18
+ * Component cannot pass across the boundary. Routes mount this container
19
+ * instead — the same shape as every other list page.
20
+ *
21
+ * No `forceHeader`: ContentListTable draws its own header row with the title
22
+ * and the create action, exactly as the company and user list pages do.
23
+ */
24
+ declare function EmailAutomationsListContainer(): React.JSX.Element;
25
+
26
+ type EmailAutomationContainerProps = {
27
+ automationId: string;
28
+ };
29
+ declare function EmailAutomationContainer({ automationId }: EmailAutomationContainerProps): React.JSX.Element;
30
+
31
+ type EmailAutomationsListProps = {
32
+ /**
33
+ * Pass this whenever the list is the page's own content inside a
34
+ * `RoundPageContainer fullWidth`. Without it ContentListTable wraps itself in
35
+ * `rounded-md border`, drawing a second bordered card inside the page's
36
+ * rounded shell.
37
+ */
38
+ fullWidth?: boolean;
39
+ };
40
+ declare function EmailAutomationsList({ fullWidth }?: EmailAutomationsListProps): React.JSX.Element;
41
+
42
+ /**
43
+ * Read-only list of the people in this automation (owner decision 6: no row
44
+ * actions). Rendered inside a tab, so it keeps its own bordered card (no
45
+ * `fullWidth`), as PricesList does inside ProductContainer.
46
+ */
47
+ declare function EmailAutomationRecipientsList(): React.JSX.Element;
48
+
49
+ type EmailAutomationEditorProps = {
50
+ automation?: EmailAutomationInterface;
51
+ propagateChanges?: (automation: EmailAutomationInterface) => void;
52
+ onSuccess?: () => void | Promise<void>;
53
+ trigger?: ReactNode;
54
+ forceShow?: boolean;
55
+ onClose?: () => void;
56
+ dialogOpen?: boolean;
57
+ onDialogOpenChange?: (open: boolean) => void;
58
+ };
59
+ declare function EmailAutomationEditor(props: EmailAutomationEditorProps): React.JSX.Element;
60
+
61
+ type EmailStepEditorProps = {
62
+ step?: EmailAutomationStepInterface;
63
+ automationId: string;
64
+ /** Canvas position for a step created from the editor. */
65
+ initialPosition?: {
66
+ x: number;
67
+ y: number;
68
+ };
69
+ /** The head step's delay counts from entering the automation, not from a previous email. */
70
+ isHead?: boolean;
71
+ trigger?: ReactNode;
72
+ forceShow?: boolean;
73
+ onClose?: () => void;
74
+ dialogOpen?: boolean;
75
+ onDialogOpenChange?: (open: boolean) => void;
76
+ onSuccess?: () => void | Promise<void>;
77
+ };
78
+ declare function EmailStepEditor(props: EmailStepEditorProps): React.JSX.Element;
79
+
80
+ /**
81
+ * Inline on/off for the automation page header, so pausing never needs the
82
+ * editor sheet. Off holds every enrolment in place (spec § "Sending" 3).
83
+ */
84
+ declare function EmailAutomationActiveSwitch(): React.JSX.Element | null;
85
+
86
+ declare function EmailAutomationCanvasTab(): React.JSX.Element;
87
+
88
+ declare function EmailAutomationCanvas(): React.JSX.Element;
89
+
90
+ /**
91
+ * Mounts EmailStepEditor (the EditorSheet the step uses everywhere) on top of
92
+ * the canvas, driven by `selectedStepId` from EmailAutomationContext. Copy of
93
+ * the app's ScenarioCanvasInspector with one branch.
94
+ *
95
+ * - We control open state via `forceShow + dialogOpen + onDialogOpenChange`.
96
+ * - On `onSuccess` we reload the canvas.
97
+ * - The step comes from the context's `steps` (already loaded for the
98
+ * canvas), so there is no per-step fetch.
99
+ */
100
+ declare function EmailAutomationCanvasInspector(): React.JSX.Element | null;
101
+ /**
102
+ * Build an `onDialogOpenChange` callback that ignores the editor's
103
+ * initial `open=false` notification. `useEditorDialog` (the hook
104
+ * inside every EditorSheet) initialises `open` to `false`, then in
105
+ * an effect sets it to `dialogOpen` (true). The "open=false" effect
106
+ * fires synchronously on mount and would otherwise wipe our canvas
107
+ * selection before the editor ever paints.
108
+ */
109
+ declare function useUserClosedGuard(onClose: () => void): (open: boolean) => void;
110
+
111
+ declare const TRIGGER_NODE_ID = "trigger";
112
+ declare const TRIGGER_SOURCE_HANDLE = "trigger-source";
113
+ declare const STEP_NODE_PREFIX = "step:";
114
+ declare const STEP_SOURCE_HANDLE_PREFIX = "step-source-";
115
+ declare const STEP_TARGET_HANDLE_PREFIX = "step-target-";
116
+ declare const TRIGGER_NODE_WIDTH = 200;
117
+ declare const TRIGGER_NODE_HEIGHT = 56;
118
+ declare const STEP_NODE_WIDTH = 200;
119
+ declare const STEP_NODE_HEIGHT = 72;
120
+ /**
121
+ * The fields the canvas reads from a step. `EmailAutomationStepInterface`
122
+ * satisfies it structurally; the narrow shape keeps this function pure and
123
+ * testable with plain objects.
124
+ */
125
+ type CanvasStep = {
126
+ id: string;
127
+ subject: string;
128
+ delayHours: number;
129
+ positionX?: number;
130
+ positionY?: number;
131
+ sentCount: number;
132
+ next?: {
133
+ id: string;
134
+ };
135
+ };
136
+ type TriggerNodeData = {
137
+ label: string;
138
+ };
139
+ type EmailStepNodeData = {
140
+ stepId: string;
141
+ subject: string;
142
+ sentCount: number;
143
+ orphan: boolean;
144
+ manuallyPositioned: boolean;
145
+ };
146
+ type DelayEdgeData = {
147
+ targetStepId: string;
148
+ delayHours: number;
149
+ };
150
+ type CanvasGraph = {
151
+ nodes: Node[];
152
+ edges: Edge[];
153
+ orphanIds: string[];
154
+ };
155
+ /**
156
+ * The head is the oldest step with no incoming NEXT, exactly as the API picks
157
+ * it (`findHead`). `steps` arrive ordered by createdAt ASC from
158
+ * `findByAutomation`, so the first step nobody points at is the head.
159
+ */
160
+ declare function findHeadStepId(steps: CanvasStep[]): string | null;
161
+ /**
162
+ * Turns the automation's steps into React Flow nodes and edges: the trigger
163
+ * node, one node per step, a trigger→head edge, and one edge per NEXT link.
164
+ * Steps not reachable from the head (walking next→next) are orphans: they
165
+ * never send and render dashed.
166
+ */
167
+ declare function buildCanvasGraph(steps: CanvasStep[], triggerLabel: string): CanvasGraph;
168
+
169
+ type TriggerNodeType = Node<{
170
+ data: TriggerNodeData;
171
+ }>;
172
+ /**
173
+ * The fixed head of the chain (SecretTargetNode recipe). Source handle only:
174
+ * people enter here. Plain element, no Base UI inside the node; the click that
175
+ * opens EmailAutomationEditor is handled by the canvas (`onNodeClick`).
176
+ */
177
+ declare function TriggerNode({ data }: NodeProps<TriggerNodeType>): React.JSX.Element;
178
+
179
+ type EmailStepNodeType = Node<{
180
+ data: EmailStepNodeData;
181
+ }>;
182
+ /**
183
+ * 200px card (SceneNode recipe): subject bold, "sent N" muted. An orphan (not
184
+ * reachable from the trigger, so it never sends) is the dashed, faded variant
185
+ * with a caption. Plain elements only: Base UI menus/popovers do not work
186
+ * inside React Flow nodes; clicks and context menus are handled by the canvas.
187
+ */
188
+ declare function EmailStepNode({ data }: NodeProps<EmailStepNodeType>): React.JSX.Element;
189
+
190
+ type DelayEdgeType = Edge<DelayEdgeData>;
191
+ /**
192
+ * ClueEdge recipe: a bezier with a label chip at its midpoint. The chip shows
193
+ * the target step's delay and opens that step's editor. It is a plain
194
+ * <button>: Base UI popovers do not work inside the React Flow canvas.
195
+ */
196
+ declare function DelayEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, label, data, }: EdgeProps<DelayEdgeType>): React.JSX.Element;
197
+
198
+ type UnsubscribeScope = "automation" | "all";
199
+ interface Props {
200
+ token: string;
201
+ scope: UnsubscribeScope;
202
+ }
203
+ declare function EmailUnsubscribe({ token, scope }: Props): React.JSX.Element;
204
+
205
+ /** A new step: the provider always sets `automationId` and, when absent, a fresh `id`. */
206
+ type EmailAutomationStepCreateInput = Omit<EmailAutomationStepInput, "id" | "automationId"> & {
207
+ id?: string;
208
+ automationId?: string;
209
+ };
210
+ /** A step update: the provider always sets `automationId`. */
211
+ type EmailAutomationStepUpdateInput = Omit<EmailAutomationStepInput, "automationId"> & {
212
+ automationId?: string;
213
+ };
214
+ interface EmailAutomationContextType {
215
+ automation: EmailAutomationInterface | undefined;
216
+ steps: EmailAutomationStepInterface[];
217
+ reload: () => Promise<void>;
218
+ selectedStepId: string | null;
219
+ select: (id: string | null) => void;
220
+ createStep: (input: EmailAutomationStepCreateInput) => Promise<EmailAutomationStepInterface>;
221
+ updateStep: (input: EmailAutomationStepUpdateInput) => Promise<EmailAutomationStepInterface>;
222
+ deleteStep: (id: string) => Promise<void>;
223
+ setNext: (stepId: string, nextStepId: string | null) => Promise<void>;
224
+ updatePosition: (stepId: string, x: number, y: number) => Promise<void>;
225
+ tidy: () => Promise<void>;
226
+ triggers: EmailAutomationTriggerInterface[];
227
+ }
228
+ type EmailAutomationProviderProps = {
229
+ automationId: string;
230
+ children: ReactNode;
231
+ };
232
+ declare const EmailAutomationProvider: ({ automationId, children }: EmailAutomationProviderProps) => React.JSX.Element;
233
+ declare const useEmailAutomation: () => EmailAutomationContextType;
234
+
235
+ declare function CanvasToolbar({ onTidy }: {
236
+ onTidy: () => void | Promise<void>;
237
+ }): React.JSX.Element;
238
+
239
+ declare function EmptyCanvas({ children }: {
240
+ children: ReactNode;
241
+ }): React.JSX.Element;
242
+
243
+ type LayoutNode = {
244
+ id: string;
245
+ /** node body dimensions in canvas px — used by dagre to allocate space */
246
+ width: number;
247
+ height: number;
248
+ /** if true, dagre leaves position alone and uses these (x, y) verbatim */
249
+ manuallyPositioned: boolean;
250
+ x?: number;
251
+ y?: number;
252
+ };
253
+ type LayoutEdge = {
254
+ source: string;
255
+ target: string;
256
+ };
257
+ type LayoutResult = Record<string, {
258
+ x: number;
259
+ y: number;
260
+ }>;
261
+ /**
262
+ * Deterministic LR layout. Pinned nodes keep their (x, y). Unpinned nodes
263
+ * are laid out by dagre and returned in the result map.
264
+ */
265
+ declare function autoLayout(nodes: LayoutNode[], edges: LayoutEdge[]): LayoutResult;
266
+
267
+ declare const LONG_PRESS_MS = 500;
268
+ declare const LONG_PRESS_MOVE_TOLERANCE_PX = 10;
269
+ /**
270
+ * Touch long-press detector for canvas nodes. A finger held still for
271
+ * LONG_PRESS_MS on a node fires `onLongPress` with the press point; any move
272
+ * beyond the tolerance (a pan or a node drag), a lift or a cancel aborts it.
273
+ * After a fired press, `consumeClick()` returns true once, so the caller can
274
+ * swallow the click that the finger lift produces.
275
+ */
276
+ declare function createLongPressTracker(params: {
277
+ onLongPress: (press: {
278
+ target: string;
279
+ clientX: number;
280
+ clientY: number;
281
+ }) => void;
282
+ delayMs?: number;
283
+ moveTolerancePx?: number;
284
+ setTimer?: (fn: () => void, ms: number) => unknown;
285
+ clearTimer?: (handle: unknown) => void;
286
+ }): {
287
+ down(target: string, clientX: number, clientY: number): void;
288
+ move(clientX: number, clientY: number): void;
289
+ up: () => void;
290
+ cancel: () => void;
291
+ consumeClick(): boolean;
292
+ };
293
+
294
+ /**
295
+ * `context.triggerLabels` maps a trigger key to the label the API declares for
296
+ * it (EmailAutomationsList loads them). A key the app no longer declares falls
297
+ * back to the raw key, so a stale automation stays readable.
298
+ */
299
+ declare const useEmailAutomationTableStructure: UseTableStructureHook<EmailAutomationInterface, EmailAutomationFields>;
300
+
301
+ declare const useEmailAutomationEnrollmentTableStructure: UseTableStructureHook<EmailAutomationEnrollmentInterface, EmailAutomationEnrollmentFields>;
302
+
303
+ export { type CanvasGraph, type CanvasStep, CanvasToolbar, DelayEdge, type DelayEdgeData, EmailAutomationActiveSwitch, EmailAutomationCanvas, EmailAutomationCanvasInspector, EmailAutomationCanvasTab, EmailAutomationContainer, type EmailAutomationContainerProps, type EmailAutomationContextType, EmailAutomationEditor, type EmailAutomationEditorProps, EmailAutomationProvider, type EmailAutomationProviderProps, EmailAutomationRecipientsList, type EmailAutomationStepCreateInput, type EmailAutomationStepUpdateInput, EmailAutomationsList, EmailAutomationsListContainer, EmailStepEditor, type EmailStepEditorProps, EmailStepNode, type EmailStepNodeData, EmailUnsubscribe, EmptyCanvas, LONG_PRESS_MOVE_TOLERANCE_PX, LONG_PRESS_MS, type LayoutEdge, type LayoutNode, type LayoutResult, STEP_NODE_HEIGHT, STEP_NODE_PREFIX, STEP_NODE_WIDTH, STEP_SOURCE_HANDLE_PREFIX, STEP_TARGET_HANDLE_PREFIX, TRIGGER_NODE_HEIGHT, TRIGGER_NODE_ID, TRIGGER_NODE_WIDTH, TRIGGER_SOURCE_HANDLE, TriggerNode, type TriggerNodeData, autoLayout, buildCanvasGraph, createLongPressTracker, findHeadStepId, useEmailAutomation, useEmailAutomationEnrollmentTableStructure, useEmailAutomationTableStructure, useUserClosedGuard };