@aglyn/plugins-workflows 1.0.0-beta.178 → 1.0.0-beta.180

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 (52) hide show
  1. package/package.json +12 -11
  2. package/src/lib/components/automation-trigger-conditions.component.d.ts +43 -0
  3. package/src/lib/components/automation-trigger-conditions.component.js +189 -0
  4. package/src/lib/components/automation-trigger-conditions.component.js.map +1 -0
  5. package/src/lib/components/host-actions-card.component.js +27 -176
  6. package/src/lib/components/host-actions-card.component.js.map +1 -1
  7. package/src/lib/components/org-automation-editor.component.d.ts +51 -0
  8. package/src/lib/components/org-automation-editor.component.js +310 -0
  9. package/src/lib/components/org-automation-editor.component.js.map +1 -0
  10. package/src/lib/components/org-automations-card.component.d.ts +28 -0
  11. package/src/lib/components/org-automations-card.component.js +373 -0
  12. package/src/lib/components/org-automations-card.component.js.map +1 -0
  13. package/src/lib/components/org-site-automation-list.component.d.ts +43 -0
  14. package/src/lib/components/org-site-automation-list.component.js +289 -0
  15. package/src/lib/components/org-site-automation-list.component.js.map +1 -0
  16. package/src/lib/components/site-org-automations-panel.component.d.ts +22 -0
  17. package/src/lib/components/site-org-automations-panel.component.js +201 -0
  18. package/src/lib/components/site-org-automations-panel.component.js.map +1 -0
  19. package/src/lib/components/use-org-automation-step-pickers.d.ts +20 -0
  20. package/src/lib/components/use-org-automation-step-pickers.js +108 -0
  21. package/src/lib/components/use-org-automation-step-pickers.js.map +1 -0
  22. package/src/lib/components/use-org-automations-api.d.ts +16 -0
  23. package/src/lib/components/use-org-automations-api.js +55 -0
  24. package/src/lib/components/use-org-automations-api.js.map +1 -0
  25. package/src/lib/components/workflows-console-page.js +63 -1
  26. package/src/lib/components/workflows-console-page.js.map +1 -1
  27. package/src/lib/components/workflows-console-sections.d.ts +19 -1
  28. package/src/lib/components/workflows-console-sections.js +37 -2
  29. package/src/lib/components/workflows-console-sections.js.map +1 -1
  30. package/src/lib/components/workflows-org-mount.d.ts +52 -0
  31. package/src/lib/components/workflows-org-mount.js +49 -0
  32. package/src/lib/components/workflows-org-mount.js.map +1 -0
  33. package/src/lib/engine/flow-enrollments.d.ts +26 -10
  34. package/src/lib/engine/flow-enrollments.js +14 -7
  35. package/src/lib/engine/flow-enrollments.js.map +1 -1
  36. package/src/lib/engine/run-event-actions.d.ts +57 -4
  37. package/src/lib/engine/run-event-actions.js +119 -19
  38. package/src/lib/engine/run-event-actions.js.map +1 -1
  39. package/src/lib/engine/run-org-automations.d.ts +75 -0
  40. package/src/lib/engine/run-org-automations.js +154 -0
  41. package/src/lib/engine/run-org-automations.js.map +1 -0
  42. package/src/lib/model/org-automations.d.ts +232 -0
  43. package/src/lib/model/org-automations.js +423 -0
  44. package/src/lib/model/org-automations.js.map +1 -0
  45. package/src/lib/plugin.js +26 -1
  46. package/src/lib/plugin.js.map +1 -1
  47. package/src/lib/server/org-automations-routes.d.ts +88 -0
  48. package/src/lib/server/org-automations-routes.js +474 -0
  49. package/src/lib/server/org-automations-routes.js.map +1 -0
  50. package/src/lib/server-console.d.ts +2 -1
  51. package/src/lib/server-console.js +12 -2
  52. package/src/lib/server-console.js.map +1 -1
@@ -0,0 +1,373 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
19
+ import { checkEntitlement, HOST_ACTION_STEP_LABELS, hostEventLabel, pluginDocsHelp } from "@aglyn/aglyn";
20
+ import { hostIdsFromScope, isOrgWideScope } from "@aglyn/aglyn/app-utils/scope-tokens";
21
+ import { CardDisplay, useConfirmationContext } from "@aglyn/shared-ui-jsx";
22
+ import { ListPagination } from "@aglyn/shared-ui-jsx/components/list-pagination.component";
23
+ import { TABLE_PAGE_SIZE_DEFAULT } from "@aglyn/shared-ui-jsx/const/table-pagination";
24
+ import { useSnackbar } from "@aglyn/shared-ui-snackstack";
25
+ import { useFirestore, useFirestoreCollection } from "@aglyn/tenant-feature-instance";
26
+ import { Alert, Button, Chip, Menu, MenuItem, Stack, Switch, Typography } from "@mui/material";
27
+ import { collection, documentId, limit, orderBy, query, where } from "firebase/firestore";
28
+ import { useCallback, useMemo, useState } from "react";
29
+ import { ORG_AUTOMATIONS_COLLECTION, ORG_AUTOMATIONS_MAX, orgAutomationPausedHostIds, readOrgAutomation } from "../model/org-automations.js";
30
+ import { newOrgAutomationDraft, OrgAutomationEditor, orgAutomationBody, orgAutomationDraft } from "./org-automation-editor.component.js";
31
+ import { useOrgAutomationsApi } from "./use-org-automations-api.js";
32
+ import { orgSiteName } from "./workflows-org-mount.js";
33
+ /** The sites an automation runs on, by id: every org site for `['org']`. */ function placedSiteIds(row, mount) {
34
+ return isOrgWideScope(row.visibleTo) ? mount.hosts.map((host)=>host.id) : hostIdsFromScope(row.visibleTo);
35
+ }
36
+ /** "Runs on every site" or "Runs on Shop, Blog". */ function placementLine(row, mount) {
37
+ if (isOrgWideScope(row.visibleTo)) return 'Runs on every site';
38
+ const names = hostIdsFromScope(row.visibleTo).map((id)=>orgSiteName(mount, id));
39
+ return names.length ? `Runs on ${names.join(', ')}` : 'Runs on no site';
40
+ }
41
+ /**
42
+ * THE ORGANIZATION'S AUTOMATIONS (AGL-3302): what the organization runs on
43
+ * the sites it chooses.
44
+ *
45
+ * One ceilinged read of the live automations — the org hub admits only
46
+ * org-wide members, who read every one — and every write through
47
+ * `automations/manage` or `automations/pause`, because the collection is
48
+ * closed to client writes. Each row says where it runs and where it is
49
+ * paused; a paused site is resumed from its chip, and any placed site can be
50
+ * paused from the row, which is the same control the site's own hub offers.
51
+ */ export function OrgAutomationsCard(props) {
52
+ var _ref, _ref1;
53
+ const { mount, org, canEdit } = props;
54
+ const firestore = useFirestore();
55
+ const api = useOrgAutomationsApi();
56
+ const { enqueueSnackbar } = useSnackbar();
57
+ const { confirm } = useConfirmationContext();
58
+ /*
59
+ * Every LIVE automation, ceilinged at the organization's cap plus the probe
60
+ * row. `deletedAt` is always written — `null` while live — so equality asks
61
+ * for exactly the live ones and deleted documents never take a place in the
62
+ * window. Ordered by document id, which the automatic single-field index
63
+ * carries behind the equality, so the window is named rather than whatever
64
+ * order Firestore returns; the list is sorted by name once it is in hand.
65
+ */ const { data: rows } = useFirestoreCollection(()=>query(collection(firestore, 'orgs', mount.orgId, ORG_AUTOMATIONS_COLLECTION), where('deletedAt', '==', null), orderBy(documentId()), limit(ORG_AUTOMATIONS_MAX + 1)), [
66
+ firestore,
67
+ mount.orgId
68
+ ], {
69
+ idField: '$id'
70
+ });
71
+ const automations = useMemo(()=>[
72
+ ...rows != null ? rows : []
73
+ ].slice(0, ORG_AUTOMATIONS_MAX).sort((a, b)=>{
74
+ var _a_name, _b_name;
75
+ return String((_a_name = a.name) != null ? _a_name : '').localeCompare(String((_b_name = b.name) != null ? _b_name : ''));
76
+ }), [
77
+ rows
78
+ ]);
79
+ const [page, setPage] = useState(0);
80
+ const [pageSize, setPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT);
81
+ const shown = useMemo(()=>automations.slice(page * pageSize, page * pageSize + pageSize), [
82
+ automations,
83
+ page,
84
+ pageSize
85
+ ]);
86
+ const [draft, setDraft] = useState(null);
87
+ /**
88
+ * The editor has been opened at least once — the latch the pickers key on,
89
+ * so Cancel and the next Edit do not buy the option lists twice.
90
+ */ const [editorOpened, setEditorOpened] = useState(false);
91
+ if (draft && !editorOpened) setEditorOpened(true);
92
+ const [saving, setSaving] = useState(false);
93
+ const [pauseMenu, setPauseMenu] = useState(null);
94
+ const entitled = checkEntitlement(org, 'actions');
95
+ const fail = useCallback((error)=>enqueueSnackbar((error == null ? void 0 : error.message) || 'The request could not be completed', {
96
+ variant: 'warning',
97
+ persist: false
98
+ }), [
99
+ enqueueSnackbar
100
+ ]);
101
+ const handleAdd = useCallback(()=>{
102
+ if (!entitled) {
103
+ enqueueSnackbar('Org automations are built from the actions builder, which requires a Pro plan — see Billing to upgrade', {
104
+ variant: 'warning',
105
+ persist: false
106
+ });
107
+ return;
108
+ }
109
+ setDraft(newOrgAutomationDraft());
110
+ }, [
111
+ entitled,
112
+ enqueueSnackbar
113
+ ]);
114
+ const handleSave = useCallback(async ()=>{
115
+ if (!draft) return;
116
+ const body = orgAutomationBody(draft);
117
+ // The route's own reader, asked first so a mistake reads the same here as
118
+ // it would coming back from the server — and costs no round trip.
119
+ const read = readOrgAutomation(body);
120
+ if (read.ok === false) {
121
+ return void enqueueSnackbar(read.problem, {
122
+ variant: 'warning',
123
+ persist: false
124
+ });
125
+ }
126
+ setSaving(true);
127
+ try {
128
+ await api('manage', _extends({
129
+ orgId: mount.orgId,
130
+ action: draft.id ? 'update' : 'create'
131
+ }, draft.id ? {
132
+ automationId: draft.id
133
+ } : {}, {
134
+ automation: body
135
+ }));
136
+ setDraft(null);
137
+ enqueueSnackbar('Org automation saved', {
138
+ variant: 'success',
139
+ persist: false
140
+ });
141
+ } catch (error) {
142
+ fail(error);
143
+ } finally{
144
+ setSaving(false);
145
+ }
146
+ }, [
147
+ draft,
148
+ api,
149
+ mount.orgId,
150
+ enqueueSnackbar,
151
+ fail
152
+ ]);
153
+ const handleToggle = useCallback((row)=>async (event)=>{
154
+ try {
155
+ await api('manage', {
156
+ orgId: mount.orgId,
157
+ action: 'setEnabled',
158
+ automationId: row.$id,
159
+ enabled: event.target.checked
160
+ });
161
+ } catch (error) {
162
+ fail(error);
163
+ }
164
+ }, [
165
+ api,
166
+ mount.orgId,
167
+ fail
168
+ ]);
169
+ const handleDelete = useCallback((row)=>async ()=>{
170
+ const confirmed = await confirm({
171
+ title: 'Delete this org automation?',
172
+ description: `"${row.name}" stops running on every site it is placed on, and ` + 'anyone waiting inside it stops too.',
173
+ confirmationText: 'Delete',
174
+ confirmationButtonProps: {
175
+ color: 'error'
176
+ }
177
+ }).then(()=>true).catch(()=>false);
178
+ if (!confirmed) return;
179
+ try {
180
+ await api('manage', {
181
+ orgId: mount.orgId,
182
+ action: 'delete',
183
+ automationId: row.$id
184
+ });
185
+ } catch (error) {
186
+ fail(error);
187
+ }
188
+ }, [
189
+ confirm,
190
+ api,
191
+ mount.orgId,
192
+ fail
193
+ ]);
194
+ const setPaused = useCallback(async (row, hostId, paused)=>{
195
+ setPauseMenu(null);
196
+ try {
197
+ await api('pause', {
198
+ hostId,
199
+ automationId: row.$id,
200
+ paused
201
+ });
202
+ } catch (error) {
203
+ fail(error);
204
+ }
205
+ }, [
206
+ api,
207
+ fail
208
+ ]);
209
+ return /*#__PURE__*/ _jsxs(CardDisplay, {
210
+ header: 'Org automations',
211
+ help: pluginDocsHelp('orgAutomations', {
212
+ anchor: '#what-an-org-automation-is'
213
+ }),
214
+ contentGutterX: true,
215
+ contentGutterY: true,
216
+ children: [
217
+ /*#__PURE__*/ _jsxs(Stack, {
218
+ spacing: 1,
219
+ children: [
220
+ /*#__PURE__*/ _jsx(Typography, {
221
+ variant: "body2",
222
+ color: "text.secondary",
223
+ children: 'Write an automation once and run it on every site you choose. ' + 'Each run is that site’s own: its email goes from that site, it ' + 'counts on that site’s action runs, and the site can pause it ' + 'for itself. Pro plans and up.'
224
+ }),
225
+ shown.map((row)=>{
226
+ var _row_steps;
227
+ var _row_trigger;
228
+ const paused = orgAutomationPausedHostIds(row);
229
+ const placed = placedSiteIds(row, mount);
230
+ const pausable = placed.filter((hostId)=>!paused.includes(hostId));
231
+ return /*#__PURE__*/ _jsxs(Stack, {
232
+ direction: "row",
233
+ spacing: 1,
234
+ sx: {
235
+ alignItems: 'center'
236
+ },
237
+ children: [
238
+ /*#__PURE__*/ _jsx(Switch, {
239
+ size: "small",
240
+ checked: row.enabled !== false,
241
+ disabled: !canEdit,
242
+ onChange: handleToggle(row),
243
+ slotProps: {
244
+ input: {
245
+ 'aria-label': `Switch ${row.name} on or off`
246
+ }
247
+ }
248
+ }),
249
+ /*#__PURE__*/ _jsxs(Stack, {
250
+ sx: {
251
+ flex: 1,
252
+ minWidth: 0
253
+ },
254
+ spacing: 0.25,
255
+ children: [
256
+ /*#__PURE__*/ _jsx(Typography, {
257
+ variant: "body2",
258
+ noWrap: true,
259
+ children: row.name
260
+ }),
261
+ /*#__PURE__*/ _jsx(Typography, {
262
+ variant: "caption",
263
+ color: "text.secondary",
264
+ noWrap: true,
265
+ children: `on ${hostEventLabel((_row_trigger = row.trigger) == null ? void 0 : _row_trigger.event)} · ${((_row_steps = row.steps) != null ? _row_steps : []).map((step)=>{
266
+ var _HOST_ACTION_STEP_LABELS_step_type;
267
+ return (_HOST_ACTION_STEP_LABELS_step_type = HOST_ACTION_STEP_LABELS[step.type]) != null ? _HOST_ACTION_STEP_LABELS_step_type : step.type;
268
+ }).join(' → ')}`
269
+ }),
270
+ /*#__PURE__*/ _jsx(Typography, {
271
+ variant: "caption",
272
+ color: "text.secondary",
273
+ noWrap: true,
274
+ children: placementLine(row, mount)
275
+ }),
276
+ paused.length ? /*#__PURE__*/ _jsx(Stack, {
277
+ direction: "row",
278
+ spacing: 0.5,
279
+ sx: {
280
+ flexWrap: 'wrap',
281
+ gap: 0.5
282
+ },
283
+ children: paused.map((hostId)=>/*#__PURE__*/ _jsx(Chip, _extends({
284
+ size: "small",
285
+ variant: "outlined",
286
+ color: "warning",
287
+ label: `Paused on ${orgSiteName(mount, hostId)}`
288
+ }, canEdit ? {
289
+ onDelete: ()=>void setPaused(row, hostId, false)
290
+ } : {}), hostId))
291
+ }) : null
292
+ ]
293
+ }),
294
+ canEdit ? /*#__PURE__*/ _jsxs(_Fragment, {
295
+ children: [
296
+ /*#__PURE__*/ _jsx(Button, {
297
+ size: "small",
298
+ onClick: ()=>setDraft(orgAutomationDraft(row)),
299
+ children: 'Edit'
300
+ }),
301
+ /*#__PURE__*/ _jsx(Button, {
302
+ size: "small",
303
+ disabled: !pausable.length,
304
+ "aria-haspopup": "menu",
305
+ onClick: (event)=>setPauseMenu({
306
+ anchor: event.currentTarget,
307
+ row
308
+ }),
309
+ children: 'Pause on…'
310
+ }),
311
+ /*#__PURE__*/ _jsx(Button, {
312
+ size: "small",
313
+ color: "error",
314
+ onClick: handleDelete(row),
315
+ children: 'Delete'
316
+ })
317
+ ]
318
+ }) : null
319
+ ]
320
+ }, row.$id);
321
+ }),
322
+ automations.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
323
+ variant: "body2",
324
+ color: "text.secondary",
325
+ children: 'No org automations yet.'
326
+ }) : /*#__PURE__*/ _jsx(ListPagination, {
327
+ page: page,
328
+ pageSize: pageSize,
329
+ rowCount: shown.length,
330
+ count: automations.length,
331
+ onPageChange: setPage,
332
+ onPageSizeChange: setPageSize
333
+ }),
334
+ ((_ref = rows == null ? void 0 : rows.length) != null ? _ref : 0) > ORG_AUTOMATIONS_MAX ? /*#__PURE__*/ _jsx(Alert, {
335
+ severity: "info",
336
+ children: `Showing ${ORG_AUTOMATIONS_MAX} org automations, the most an ` + 'organization holds.'
337
+ }) : null,
338
+ canEdit ? /*#__PURE__*/ _jsx(Button, {
339
+ size: "small",
340
+ color: "primary",
341
+ sx: {
342
+ alignSelf: 'flex-start'
343
+ },
344
+ onClick: handleAdd,
345
+ children: 'Add org automation'
346
+ }) : null
347
+ ]
348
+ }),
349
+ /*#__PURE__*/ _jsx(Menu, {
350
+ anchorEl: (_ref1 = pauseMenu == null ? void 0 : pauseMenu.anchor) != null ? _ref1 : null,
351
+ open: Boolean(pauseMenu),
352
+ onClose: ()=>setPauseMenu(null),
353
+ children: pauseMenu ? placedSiteIds(pauseMenu.row, mount).filter((hostId)=>!orgAutomationPausedHostIds(pauseMenu.row).includes(hostId)).map((hostId)=>/*#__PURE__*/ _jsx(MenuItem, {
354
+ onClick: ()=>void setPaused(pauseMenu.row, hostId, true),
355
+ children: `Pause on ${orgSiteName(mount, hostId)}`
356
+ }, hostId)) : null
357
+ }),
358
+ /*#__PURE__*/ _jsx(OrgAutomationEditor, {
359
+ mount: mount,
360
+ draft: draft,
361
+ onDraft: (update)=>setDraft((previous)=>previous ? update(previous) : previous),
362
+ opened: editorOpened,
363
+ saving: saving,
364
+ onSave: ()=>void handleSave(),
365
+ onClose: ()=>setDraft(null)
366
+ })
367
+ ]
368
+ });
369
+ }
370
+ OrgAutomationsCard.displayName = 'OrgAutomationsCard';
371
+ export default OrgAutomationsCard;
372
+
373
+ //# sourceMappingURL=org-automations-card.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/org-automations-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n type AglynOrgBilling,\n checkEntitlement,\n HOST_ACTION_STEP_LABELS,\n type HostActionStepType,\n hostEventLabel,\n pluginDocsHelp,\n} from '@aglyn/aglyn'\nimport {\n hostIdsFromScope,\n isOrgWideScope,\n} from '@aglyn/aglyn/app-utils/scope-tokens'\nimport { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport { TABLE_PAGE_SIZE_DEFAULT } from '@aglyn/shared-ui-jsx/const/table-pagination'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n useFirestore,\n useFirestoreCollection,\n} from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Chip,\n Menu,\n MenuItem,\n Stack,\n Switch,\n Typography,\n} from '@mui/material'\nimport {\n collection,\n documentId,\n limit,\n orderBy,\n query,\n where,\n} from 'firebase/firestore'\nimport { useCallback, useMemo, useState } from 'react'\nimport {\n ORG_AUTOMATIONS_COLLECTION,\n ORG_AUTOMATIONS_MAX,\n orgAutomationPausedHostIds,\n type OrgAutomationRow,\n readOrgAutomation,\n} from '../model/org-automations'\nimport {\n newOrgAutomationDraft,\n OrgAutomationEditor,\n orgAutomationBody,\n type OrgAutomationDraft,\n orgAutomationDraft,\n} from './org-automation-editor.component'\nimport { useOrgAutomationsApi } from './use-org-automations-api'\nimport { orgSiteName, type WorkflowsOrgMount } from './workflows-org-mount'\n\nexport interface OrgAutomationsCardProps {\n mount: WorkflowsOrgMount\n org?: Partial<AglynOrgBilling>\n /**\n * Whether the reader may write the organization's automations — an owner,\n * admin or editor. The route decides; this keeps a viewer from being\n * offered controls that are about to refuse them.\n */\n canEdit: boolean\n}\n\n/** The sites an automation runs on, by id: every org site for `['org']`. */\nfunction placedSiteIds(\n row: Pick<OrgAutomationRow, 'visibleTo'>,\n mount: WorkflowsOrgMount,\n): string[] {\n return isOrgWideScope(row.visibleTo)\n ? mount.hosts.map((host) => host.id)\n : hostIdsFromScope(row.visibleTo)\n}\n\n/** \"Runs on every site\" or \"Runs on Shop, Blog\". */\nfunction placementLine(\n row: Pick<OrgAutomationRow, 'visibleTo'>,\n mount: WorkflowsOrgMount,\n): string {\n if (isOrgWideScope(row.visibleTo)) return 'Runs on every site'\n const names = hostIdsFromScope(row.visibleTo).map((id) => orgSiteName(mount, id))\n return names.length ? `Runs on ${names.join(', ')}` : 'Runs on no site'\n}\n\n/**\n * THE ORGANIZATION'S AUTOMATIONS (AGL-3302): what the organization runs on\n * the sites it chooses.\n *\n * One ceilinged read of the live automations — the org hub admits only\n * org-wide members, who read every one — and every write through\n * `automations/manage` or `automations/pause`, because the collection is\n * closed to client writes. Each row says where it runs and where it is\n * paused; a paused site is resumed from its chip, and any placed site can be\n * paused from the row, which is the same control the site's own hub offers.\n */\nexport function OrgAutomationsCard(props: OrgAutomationsCardProps) {\n const { mount, org, canEdit } = props\n const firestore = useFirestore()\n const api = useOrgAutomationsApi()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n\n /*\n * Every LIVE automation, ceilinged at the organization's cap plus the probe\n * row. `deletedAt` is always written — `null` while live — so equality asks\n * for exactly the live ones and deleted documents never take a place in the\n * window. Ordered by document id, which the automatic single-field index\n * carries behind the equality, so the window is named rather than whatever\n * order Firestore returns; the list is sorted by name once it is in hand.\n */\n const { data: rows } = useFirestoreCollection<OrgAutomationRow>(\n () =>\n query(\n collection(firestore, 'orgs', mount.orgId, ORG_AUTOMATIONS_COLLECTION),\n where('deletedAt', '==', null),\n orderBy(documentId()),\n limit(ORG_AUTOMATIONS_MAX + 1),\n ),\n [firestore, mount.orgId],\n { idField: '$id' },\n )\n const automations = useMemo(\n () =>\n [...(rows ?? [])]\n .slice(0, ORG_AUTOMATIONS_MAX)\n .sort((a, b) => String(a.name ?? '').localeCompare(String(b.name ?? ''))),\n [rows],\n )\n const [page, setPage] = useState(0)\n const [pageSize, setPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT)\n const shown = useMemo(\n () => automations.slice(page * pageSize, page * pageSize + pageSize),\n [automations, page, pageSize],\n )\n\n const [draft, setDraft] = useState<OrgAutomationDraft | null>(null)\n /**\n * The editor has been opened at least once — the latch the pickers key on,\n * so Cancel and the next Edit do not buy the option lists twice.\n */\n const [editorOpened, setEditorOpened] = useState(false)\n if (draft && !editorOpened) setEditorOpened(true)\n const [saving, setSaving] = useState(false)\n const [pauseMenu, setPauseMenu] = useState<{\n anchor: HTMLElement\n row: OrgAutomationRow\n } | null>(null)\n\n const entitled = checkEntitlement(org, 'actions')\n const fail = useCallback(\n (error: unknown) =>\n enqueueSnackbar((error as Error)?.message || 'The request could not be completed', {\n variant: 'warning',\n persist: false,\n }),\n [enqueueSnackbar],\n )\n\n const handleAdd = useCallback(() => {\n if (!entitled) {\n enqueueSnackbar(\n 'Org automations are built from the actions builder, which requires a Pro plan — see Billing to upgrade',\n { variant: 'warning', persist: false },\n )\n return\n }\n setDraft(newOrgAutomationDraft())\n }, [entitled, enqueueSnackbar])\n\n const handleSave = useCallback(async () => {\n if (!draft) return\n const body = orgAutomationBody(draft)\n // The route's own reader, asked first so a mistake reads the same here as\n // it would coming back from the server — and costs no round trip.\n const read = readOrgAutomation(body)\n if (read.ok === false) {\n return void enqueueSnackbar(read.problem, { variant: 'warning', persist: false })\n }\n setSaving(true)\n try {\n await api('manage', {\n orgId: mount.orgId,\n action: draft.id ? 'update' : 'create',\n ...(draft.id ? { automationId: draft.id } : {}),\n automation: body,\n })\n setDraft(null)\n enqueueSnackbar('Org automation saved', { variant: 'success', persist: false })\n } catch (error) {\n fail(error)\n } finally {\n setSaving(false)\n }\n }, [draft, api, mount.orgId, enqueueSnackbar, fail])\n\n const handleToggle = useCallback(\n (row: OrgAutomationRow) => async (event: { target: { checked: boolean } }) => {\n try {\n await api('manage', {\n orgId: mount.orgId,\n action: 'setEnabled',\n automationId: row.$id,\n enabled: event.target.checked,\n })\n } catch (error) {\n fail(error)\n }\n },\n [api, mount.orgId, fail],\n )\n\n const handleDelete = useCallback(\n (row: OrgAutomationRow) => async () => {\n const confirmed = await confirm({\n title: 'Delete this org automation?',\n description:\n `\"${row.name}\" stops running on every site it is placed on, and ` +\n 'anyone waiting inside it stops too.',\n confirmationText: 'Delete',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n try {\n await api('manage', {\n orgId: mount.orgId,\n action: 'delete',\n automationId: row.$id,\n })\n } catch (error) {\n fail(error)\n }\n },\n [confirm, api, mount.orgId, fail],\n )\n\n const setPaused = useCallback(\n async (row: OrgAutomationRow, hostId: string, paused: boolean) => {\n setPauseMenu(null)\n try {\n await api('pause', { hostId, automationId: row.$id, paused })\n } catch (error) {\n fail(error)\n }\n },\n [api, fail],\n )\n\n return (\n <CardDisplay\n header={'Org automations'}\n help={pluginDocsHelp('orgAutomations', { anchor: '#what-an-org-automation-is' })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Write an automation once and run it on every site you choose. ' +\n 'Each run is that site’s own: its email goes from that site, it ' +\n 'counts on that site’s action runs, and the site can pause it ' +\n 'for itself. Pro plans and up.'}\n </Typography>\n {shown.map((row) => {\n const paused = orgAutomationPausedHostIds(row)\n const placed = placedSiteIds(row, mount)\n const pausable = placed.filter((hostId) => !paused.includes(hostId))\n return (\n <Stack\n key={row.$id}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n <Switch\n size=\"small\"\n checked={row.enabled !== false}\n disabled={!canEdit}\n onChange={handleToggle(row)}\n slotProps={{ input: { 'aria-label': `Switch ${row.name} on or off` } }}\n />\n <Stack sx={{ flex: 1, minWidth: 0 }} spacing={0.25}>\n <Typography variant=\"body2\" noWrap>\n {row.name}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {`on ${hostEventLabel(row.trigger?.event)} · ${(row.steps ?? [])\n .map(\n (step) =>\n HOST_ACTION_STEP_LABELS[step.type as HostActionStepType] ??\n step.type,\n )\n .join(' → ')}`}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {placementLine(row, mount)}\n </Typography>\n {paused.length ? (\n <Stack direction=\"row\" spacing={0.5} sx={{ flexWrap: 'wrap', gap: 0.5 }}>\n {paused.map((hostId) => (\n <Chip\n key={hostId}\n size=\"small\"\n variant=\"outlined\"\n color=\"warning\"\n label={`Paused on ${orgSiteName(mount, hostId)}`}\n {...(canEdit\n ? { onDelete: () => void setPaused(row, hostId, false) }\n : {})}\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n {canEdit ? (\n <>\n <Button size=\"small\" onClick={() => setDraft(orgAutomationDraft(row))}>\n {'Edit'}\n </Button>\n <Button\n size=\"small\"\n disabled={!pausable.length}\n aria-haspopup=\"menu\"\n onClick={(event) =>\n setPauseMenu({ anchor: event.currentTarget, row })\n }\n >\n {'Pause on…'}\n </Button>\n <Button size=\"small\" color=\"error\" onClick={handleDelete(row)}>\n {'Delete'}\n </Button>\n </>\n ) : null}\n </Stack>\n )\n })}\n {automations.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No org automations yet.'}\n </Typography>\n ) : (\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={shown.length}\n count={automations.length}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n )}\n {(rows?.length ?? 0) > ORG_AUTOMATIONS_MAX ? (\n <Alert severity=\"info\">\n {`Showing ${ORG_AUTOMATIONS_MAX} org automations, the most an ` +\n 'organization holds.'}\n </Alert>\n ) : null}\n {canEdit ? (\n <Button\n size=\"small\"\n color=\"primary\"\n sx={{ alignSelf: 'flex-start' }}\n onClick={handleAdd}\n >\n {'Add org automation'}\n </Button>\n ) : null}\n </Stack>\n <Menu\n anchorEl={pauseMenu?.anchor ?? null}\n open={Boolean(pauseMenu)}\n onClose={() => setPauseMenu(null)}\n >\n {pauseMenu\n ? placedSiteIds(pauseMenu.row, mount)\n .filter(\n (hostId) =>\n !orgAutomationPausedHostIds(pauseMenu.row).includes(hostId),\n )\n .map((hostId) => (\n <MenuItem\n key={hostId}\n onClick={() => void setPaused(pauseMenu.row, hostId, true)}\n >\n {`Pause on ${orgSiteName(mount, hostId)}`}\n </MenuItem>\n ))\n : null}\n </Menu>\n <OrgAutomationEditor\n mount={mount}\n draft={draft}\n onDraft={(update) =>\n setDraft((previous) => (previous ? update(previous) : previous))\n }\n opened={editorOpened}\n saving={saving}\n onSave={() => void handleSave()}\n onClose={() => setDraft(null)}\n />\n </CardDisplay>\n )\n}\nOrgAutomationsCard.displayName = 'OrgAutomationsCard'\n\nexport default OrgAutomationsCard\n"],"names":["checkEntitlement","HOST_ACTION_STEP_LABELS","hostEventLabel","pluginDocsHelp","hostIdsFromScope","isOrgWideScope","CardDisplay","useConfirmationContext","ListPagination","TABLE_PAGE_SIZE_DEFAULT","useSnackbar","useFirestore","useFirestoreCollection","Alert","Button","Chip","Menu","MenuItem","Stack","Switch","Typography","collection","documentId","limit","orderBy","query","where","useCallback","useMemo","useState","ORG_AUTOMATIONS_COLLECTION","ORG_AUTOMATIONS_MAX","orgAutomationPausedHostIds","readOrgAutomation","newOrgAutomationDraft","OrgAutomationEditor","orgAutomationBody","orgAutomationDraft","useOrgAutomationsApi","orgSiteName","placedSiteIds","row","mount","visibleTo","hosts","map","host","id","placementLine","names","length","join","OrgAutomationsCard","props","org","canEdit","firestore","api","enqueueSnackbar","confirm","data","rows","orgId","idField","automations","slice","sort","a","b","String","name","localeCompare","page","setPage","pageSize","setPageSize","shown","draft","setDraft","editorOpened","setEditorOpened","saving","setSaving","pauseMenu","setPauseMenu","entitled","fail","error","message","variant","persist","handleAdd","handleSave","body","read","ok","problem","action","automationId","automation","handleToggle","event","$id","enabled","target","checked","handleDelete","confirmed","title","description","confirmationText","confirmationButtonProps","color","then","catch","setPaused","hostId","paused","header","help","anchor","contentGutterX","contentGutterY","spacing","placed","pausable","filter","includes","direction","sx","alignItems","size","disabled","onChange","slotProps","input","flex","minWidth","noWrap","trigger","steps","step","type","flexWrap","gap","label","onDelete","onClick","aria-haspopup","currentTarget","rowCount","count","onPageChange","onPageSizeChange","severity","alignSelf","anchorEl","open","Boolean","onClose","onDraft","update","previous","opened","onSave","displayName"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type WorkflowsOrgMount } from './workflows-org-mount';
2
+ /** The three site collections the org hub lists across its sites. */
3
+ export type OrgSiteAutomationKind = 'workflows' | 'actions' | 'webhooks';
4
+ /**
5
+ * How many sites a list opens with their rows read. The rest wait behind
6
+ * "Show more" — and, since each site's rows are read by the row group that
7
+ * shows them, are not read until then either.
8
+ */
9
+ export declare const ORG_SITE_LIST_OPEN_SITES = 5;
10
+ /**
11
+ * The most sites one list will read, however many the organization has —
12
+ * the platform's per-scan site bound. Past it the list says so and each
13
+ * site's own hub is the way in.
14
+ */
15
+ export declare const ORG_SITE_LIST_MAX_SITES = 25;
16
+ /**
17
+ * Rows read per site. A ceiling with a probe row, not a page: the org list is
18
+ * an index of where things are, and each site's own hub holds the full,
19
+ * editable list the row links to.
20
+ */
21
+ export declare const ORG_SITE_LIST_ROWS = 10;
22
+ /**
23
+ * EVERY SITE'S WORKFLOWS, ACTIONS OR WEBHOOKS, on the org hub (AGL-3302).
24
+ *
25
+ * Read-only and bounded: one ceilinged read per open site, the first
26
+ * {@link ORG_SITE_LIST_OPEN_SITES} sites on arrival and up to
27
+ * {@link ORG_SITE_LIST_MAX_SITES} when asked, each row naming its site and
28
+ * linking into that site's own Automation hub, where the thing is edited.
29
+ * "Add" asks which site and goes there.
30
+ *
31
+ * `canRead` gates the webhooks list: a webhook holds its site's secret and
32
+ * the rules admit only a site's admins and editors, so a reader who is
33
+ * neither is told so rather than handed listeners that would be refused.
34
+ */
35
+ export declare function OrgSiteAutomationList(props: {
36
+ mount: WorkflowsOrgMount;
37
+ kind: OrgSiteAutomationKind;
38
+ canRead: boolean;
39
+ }): import("react").JSX.Element;
40
+ export declare namespace OrgSiteAutomationList {
41
+ var displayName: string;
42
+ }
43
+ export default OrgSiteAutomationList;