@aglyn/plugins-workflows 1.0.0-beta.229 → 1.0.0-beta.231

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/host-workflows-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 checkQuota,\n HOST_EVENT_TYPES,\n hostEventLabel,\n hostEventPayloadHint,\n type HostFunction,\n type HostVariable,\n pluginDocsHelp,\n triggerFilterProblem,\n} from '@aglyn/aglyn'\n/*\n * The MODULE, not the barrel, for the two PURE helpers — every spec that\n * renders this card mocks `@aglyn/tenant-feature-instance` wholesale to stage\n * its Firestore hooks, and a query builder imported through that barrel\n * disappears under the mock. Neither of these is a hook.\n */\nimport {\n ceilingedWindow,\n collectionCeiling,\n} from '@aglyn/tenant-feature-instance/hooks/host-collection-queries'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\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 QuotaReadoutComponent from '@aglyn/shared-ui-jsx/components/quota-readout.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { Timestamp } from '@aglyn/shared-util-timestamp'\nimport {\n Alert,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport {\n collection,\n doc,\n getCountFromServer,\n setDoc,\n updateDoc,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n useDuplicateResource,\n useFirestore,\n useFirestoreCollection,\n useHostResourceApi,\n useUser,\n writeGuardedBySeed,\n} from '@aglyn/tenant-feature-instance'\nimport {\n AutomationStepFields,\n type AutomationStepKind,\n defaultStep,\n} from './automation-step-fields.component'\nimport {\n type AutomationWorkflow,\n isWorkflowActionStep,\n validateWorkflowSteps,\n WORKFLOW_ACTION_STEP_TYPES,\n workflowFunctionCalls,\n type WorkflowStep,\n workflowStepTypeLabel,\n} from '../engine/workflow-steps'\nimport HostRunHistoryCard from './host-run-history-card.component'\nimport {\n EDITOR_OPTION_CEILING,\n useAutomationStepPickers,\n} from './use-automation-step-pickers'\nimport { listConsoleWidgets } from '@aglyn/aglyn'\nimport {\n fetchWhereUsed,\n summarizeDependents,\n type WhereUsedResult,\n} from '@aglyn/aglyn/app-utils/where-used'\nimport {\n AUTOMATION_EDITOR_ZONE,\n WORKFLOW_USAGE_ZONE,\n type AutomationTarget,\n} from './workflow-zones'\nimport {\n type HostWorkflowStep,\n runWorkflow,\n WORKFLOW_MAX_STEPS,\n} from '../model/workflows'\nimport {\n type HostActionStep,\n type HostActionStepType,\n stepRunsAfterWait,\n} from '../model/host-actions'\n\n/**\n * How many workflows the card reads.\n *\n * A CEILING, not a page size — see the query, which explains why this list\n * cannot be paged by the server without making the duplicate-name check lie.\n */\nconst WORKFLOW_CEILING = 100\n\n/** The \"Do\" entry for the step kind a workflow has always had: a call. */\nconst FUNCTION_CALL_KIND = 'functionCall'\n\n/**\n * What a step may be (AGL-3105).\n *\n * The function call comes first because it is what a workflow was before the\n * two engines became one, and is still what a new step is. After it comes\n * every Actions step a SERVER event can run — the client-only interactions\n * are absent, because a workflow runs where there is no page to run them on.\n */\nconst STEP_KINDS: AutomationStepKind[] = [\n { value: FUNCTION_CALL_KIND, label: 'Call a function' },\n ...WORKFLOW_ACTION_STEP_TYPES.map((value) => ({\n value,\n label: workflowStepTypeLabel(value),\n })),\n]\n\nexport interface HostWorkflowsCardProps {\n hostId: string\n /** Resolved entitlement source for quota checks (AGL-395). */\n org?: Partial<AglynOrgBilling>\n}\n\ninterface WorkflowDraft extends AutomationWorkflow {\n id: string | null\n}\n\n/**\n * Workflow builder v1 (AGL-101): pipelines of host-function calls — each\n * step's argument expressions see host variables and previous step results\n * (`step1`, or a custom result name). Runs through the pure `runWorkflow`\n * evaluator; test-run panel included. Plan-gated (`workflows` flag +\n * `workflowsPerHost` cap, AGL-99); site-event triggers are v2.\n */\nexport function HostWorkflowsCard(props: HostWorkflowsCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const createHostResource = useHostResourceApi()\n const { enqueueSnackbar } = useSnackbar()\n // Duplicate (AGL-2936): the copy keeps every step and arrives disarmed —\n // its trigger is cleared — so nothing runs twice until somebody arms it.\n const duplicate = useDuplicateResource({\n hostId,\n onDuplicated: (_kind, copy) =>\n enqueueSnackbar(\n `Duplicated as “${copy.name}” — arm its trigger to run it`,\n {\n variant: 'success',\n },\n ),\n })\n const { confirm } = useConfirmationContext()\n const { org } = props\n /**\n * The shell's zone renderer, for what other plugins add to a saved workflow's\n * editor (AGL-2919); `null` outside the console shell.\n */\n const ExtensionZone = useConsoleWidgetSlot()\n\n const {\n data: workflowDocs,\n status: workflowsStatus,\n /**\n * The rows this editor is seeded from are unconfirmed by the server\n * (AGL-1358). Editing destructures a whole stored workflow into `draft`\n * and writes `{...definition}` back, so `merge: true` protects nothing.\n * `trigger` is the field that makes this more than a lost edit: it is\n * `{event, filter}` or `null` for manual-only, and nothing else on this\n * card writes it, so a cached seed can re-arm an automation the author\n * disarmed — or disarm one running on a live site — and revert every\n * step of the pipeline with it.\n */\n fromCache: workflowsFromCache,\n } = useFirestoreCollection<any>(\n /*\n * ORDERED AND CEILINGED, deliberately not paged by the query (AGL-2501) —\n * the same decision as the logic plugin's two cards, for the same reasons.\n *\n * `limit(100)` alone is answered in DOCUMENT-ID order, so the window is a\n * pseudo-random hundred that the `localeCompare` below arranges\n * alphabetically, and nothing said the list was bounded.\n *\n * `collectionCeiling` does not change WHICH hundred — document-id order is\n * what the bare cap already returned. What it changes is that the order is\n * NAMED, so the obvious next edit is caught: ordering on `name` would HIDE\n * every workflow written without one rather than mis-sorting the list, and\n * `/api/hosts/resources` validates no field for presence while\n * `IMPORTABLE_FIELDS.workflows` copies one only if the export carried it.\n *\n * The QUERY is not paged because `nameTaken` below tests the draft against\n * these rows: computed variables look their workflow up BY NAME\n * (AGL-185/AGL-261), so a duplicate silently rebinds a live binding, and a\n * uniqueness check over a ten-row page would let one through.\n */\n () =>\n collectionCeiling(\n collection(firestore, 'hosts', hostId, 'workflows'),\n WORKFLOW_CEILING,\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const { rows: readWorkflows, truncated: workflowsTruncated } =\n ceilingedWindow<any>(workflowDocs, WORKFLOW_CEILING)\n const [draft, setDraft] = useState<WorkflowDraft | null>(null)\n /**\n * The editor has been opened at least once in this session.\n *\n * A LATCH rather than `draft` itself, because the two reads below key their\n * listeners on it. Tracking the dialog would tear those subscriptions down\n * on Cancel and pay for them again on the next Edit, so a merchant working\n * through ten actions would buy the same two windows ten times — worse than\n * the mount-time read this replaces. Latched, a reader who never edits pays\n * nothing and a reader who edits pays once.\n */\n const [editorOpened, setEditorOpened] = useState(false)\n if (draft && !editorOpened) setEditorOpened(true)\n /*\n * THE EDITOR'S WORKING SET, read when the editor opens.\n *\n * Nothing outside the dialog reads either of these: the table renders a\n * workflow's stored step names, and `runWorkflow` is only reachable from the\n * test-run button inside the dialog. Mounting them unconditionally charges\n * every visitor to this page two windows to fill a select and seed a\n * scratchpad most of them never open.\n *\n * Ceilinged and ordered for the reason the workflows query above gives: a\n * bare `limit` is answered in document-id order, so the `localeCompare` on\n * the options below would arrange a pseudo-random hundred into a convincing\n * alphabet, and a function past the window could not be picked with nothing\n * saying why.\n */\n const { data: functionRead } = useFirestoreCollection<any>(\n () =>\n editorOpened\n ? collectionCeiling(\n collection(firestore, 'hosts', hostId, 'functions'),\n EDITOR_OPTION_CEILING,\n )\n : null,\n [firestore, hostId, editorOpened],\n { idField: '$id' },\n )\n // Memoised so the window keeps one identity while the rows do — the option\n // list and the two lookup maps below are all built from it.\n const { rows: functionDocs, truncated: functionsTruncated } = useMemo(\n () => ceilingedWindow<any>(functionRead, EDITOR_OPTION_CEILING),\n [functionRead],\n )\n const { data: variableRead } = useFirestoreCollection<any>(\n () =>\n editorOpened\n ? collectionCeiling(\n collection(firestore, 'hosts', hostId, 'variables'),\n EDITOR_OPTION_CEILING,\n )\n : null,\n [firestore, hostId, editorOpened],\n { idField: '$id' },\n )\n const { rows: variableDocs, truncated: variablesTruncated } = useMemo(\n () => ceilingedWindow<any>(variableRead, EDITOR_OPTION_CEILING),\n [variableRead],\n )\n /*\n * What an ACTIONS step can be pointed at, on the same latch (AGL-3105).\n *\n * The hook the Actions builder uses, because a workflow step may be any\n * server-side Actions step and the two editors therefore offer one set of\n * records. Read on the editor's first open, like the two windows above, so\n * a reader who never edits a workflow still pays nothing for them.\n */\n const { pickers: stepPickers, truncated: truncatedPickers } =\n useAutomationStepPickers(hostId, editorOpened)\n // Sorting is safe here in a way it is not on a paged list: these rows are\n // the whole collection below the ceiling, not a slice of one.\n const workflows = useMemo(\n () =>\n readWorkflows\n .filter((workflow: any) => !workflow.deletedAt)\n .sort((a: any, b: any) =>\n String(a.name ?? '').localeCompare(String(b.name ?? '')),\n ),\n [readWorkflows],\n )\n // The page is a SLICE: the rows are already in hand and `nameTaken` needs\n // all of them.\n const [page, setPage] = useState(0)\n const [pageSize, setPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT)\n const visibleWorkflows = useMemo(\n () => workflows.slice(page * pageSize, page * pageSize + pageSize),\n [workflows, page, pageSize],\n )\n /**\n * The workflow HEAD-COUNT is a server aggregate, not the length of the\n * capped listener (AGL-1716, the AGL-1706 shape).\n *\n * The listener is `limit(100)` and `workflows.length` fed\n * `checkQuota(org, 'workflowsPerHost', …)`, whose bands are 0 / 3 / 25 /\n * 100 / 250 / 500. The window TIES Business's 100 and hides Scale's 250\n * and Advanced's 500, so on those plans the gate compared 100 against\n * hundreds and could never refuse — while `api/hosts/resources` counted\n * the collection and did. The card offered headroom that did not exist and\n * then failed the create.\n *\n * UNFILTERED, matching that route's plain `collection('workflows').count()`\n * — its `softDeletes` branch governs only the flat per-host webhook cap, so\n * soft-deleted workflows have always counted server-side while this card\n * excluded them. Only a create moves the number, so that is where it is\n * re-read.\n */\n const [workflowCountEpoch, setWorkflowCountEpoch] = useState(0)\n const [serverWorkflowCount, setServerWorkflowCount] = useState<number | null>(\n null,\n )\n useEffect(() => {\n let active = true\n void getCountFromServer(collection(firestore, 'hosts', hostId, 'workflows'))\n .then((snapshot) => {\n if (active) setServerWorkflowCount(snapshot.data().count)\n })\n .catch(() => {\n // Falls back to the loaded rows — a LOWER bound and the prior\n // behaviour, never 0, which `checkQuota` would answer as \"no usage\"\n // on a site that is over its band.\n })\n return () => {\n active = false\n }\n }, [firestore, hostId, workflowCountEpoch])\n const workflowCount = serverWorkflowCount ?? workflows.length\n // Double-keyed by doc id and name (AGL-261): id references are\n // rename-safe; legacy name references keep resolving.\n const functions = useMemo(() => {\n const map: Record<string, HostFunction> = {}\n for (const definition of functionDocs ?? []) {\n if (definition.deletedAt) continue\n if (definition.$id) map[definition.$id] = definition\n if (definition.name) map[definition.name] = definition\n }\n return map\n }, [functionDocs])\n const functionOptions = useMemo(\n () =>\n (functionDocs ?? [])\n .filter((definition: any) => !definition.deletedAt && definition.name)\n .map((definition: any) => ({\n id: definition.$id as string,\n name: definition.name as string,\n }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [functionDocs],\n )\n const variables = useMemo(() => {\n const map: Record<string, HostVariable> = {}\n for (const variable of variableDocs ?? []) {\n if (!variable.deletedAt && variable.name) map[variable.name] = variable\n }\n return map\n }, [variableDocs])\n\n // Where-used dialog (AGL-193).\n const [usage, setUsage] = useState<{\n name: string\n result: WhereUsedResult\n } | null>(null)\n const [usageLoading, setUsageLoading] = useState<string | null>(null)\n\n const [testResult, setTestResult] = useState<string | null>(null)\n const [runsFor, setRunsFor] = useState<any | null>(null)\n\n // Case-insensitive uniqueness (AGL-185): workflow names must stay\n // unambiguous for computed-variable lookups keyed by name.\n const nameTaken = Boolean(\n draft &&\n workflows.some(\n (definition: any) =>\n String(definition.name ?? '').toLowerCase() ===\n draft.name.trim().toLowerCase() && definition.$id !== draft.id,\n ),\n )\n\n const patch = useCallback(\n (updater: (previous: WorkflowDraft) => WorkflowDraft) =>\n setDraft((previous) => (previous ? updater(previous) : previous)),\n [],\n )\n\n /** The saved workflow the editor has open, as the `automationEditor` zone names it. */\n const draftId = draft?.id ?? null\n const draftName = draft?.name ?? ''\n const editorTarget = useMemo<AutomationTarget | null>(\n () => (draftId ? { type: 'workflow', id: draftId, name: draftName } : null),\n // The name the editor opened with: the zone reads the workflow as it is\n // stored, so a rename being typed does not make it a different one.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [draftId],\n )\n\n const handleAdd = useCallback(() => {\n // Feature + cap gate (AGL-99); dark-launch for plan-less workspaces.\n if (!checkEntitlement(org, 'workflows')) {\n return void enqueueSnackbar(\n 'Workflows require a Starter plan — see Billing to upgrade',\n { variant: 'warning', persist: false },\n )\n }\n // The site's workflows, not this page of them (AGL-1716).\n const quota = checkQuota(org, 'workflowsPerHost', workflowCount)\n if (!quota.allowed) {\n return void enqueueSnackbar(\n `Workflow limit reached (${quota.limit}) — upgrade in Billing`,\n { variant: 'warning', persist: false },\n )\n }\n setTestResult(null)\n setDraft({\n id: null,\n name: '',\n steps: [{ functionName: '', args: [], resultName: '' }],\n returnValue: '',\n trigger: null,\n })\n }, [org, workflowCount, enqueueSnackbar])\n\n /**\n * Every list the ceiling cut, named — the editor's two and the step\n * pickers' six, in one notice for the reason the Actions builder gives:\n * they are one read, and an author told the function list is short learns\n * nothing from being told again about datasets.\n */\n const shortLists = useMemo(\n () =>\n [\n functionsTruncated ? 'functions' : null,\n variablesTruncated ? 'variables' : null,\n ...truncatedPickers,\n ].filter((name): name is string => name !== null),\n [functionsTruncated, variablesTruncated, truncatedPickers],\n )\n\n /**\n * The first thing wrong with the steps, said the way the editors say it.\n *\n * The same check the engine makes of what it is handed: an Actions step is\n * held to the Actions validator, a call has to name a function, and a step\n * only a visitor's browser can run is refused. Said while the author is\n * still in the dialog rather than after a save that stores a step nothing\n * can run.\n */\n const stepProblem = useMemo(\n () =>\n draft\n ? // A filter the evaluator can never run saves fine and never fires\n // (AGL-3458), so it is refused with the steps.\n (triggerFilterProblem(draft.trigger?.filter, { remedy: 'action' }) ?? validateWorkflowSteps(draft.steps))\n : null,\n [draft],\n )\n\n const handleTestRun = useCallback(() => {\n if (!draft) return\n /*\n * The FUNCTION CALLS, evaluated. A test run is the pure evaluator, and\n * an Actions step is not something to evaluate — it sends, writes and\n * charges. Running one here would perform it against the live site from\n * a button labelled \"Test run\", so the calls are evaluated, each keeping\n * the result name it holds among all the steps, and the rest is left to\n * the run itself.\n */\n const run = runWorkflow(workflowFunctionCalls(draft), functions, variables)\n setTestResult(\n run.ok === false\n ? `Error: ${run.error}`\n : `Result: ${String(run.value)} (${Object.entries(run.results)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ')})`,\n )\n }, [draft, functions, variables])\n\n const handleSave = useCallback(async () => {\n if (!draft || !draft.name.trim() || nameTaken) return\n // The steps are checked at the door, not after the write: a stored step\n // nothing can run is a run that fails on the site rather than here.\n if (stepProblem) {\n return void enqueueSnackbar(stepProblem, {\n variant: 'warning',\n persist: false,\n })\n }\n const { id: draftId, ...definition } = draft\n const fields = { ...definition, name: draft.name.trim().slice(0, 60) }\n try {\n if (draftId) {\n /**\n * Edit stays client-direct (no quota consumed) — and is refused when\n * its seed was never confirmed by the server (AGL-1358). `fields` is\n * the whole definition spread out of the listener row, `trigger` and\n * `steps` included, so `merge: true` has nothing left to protect.\n *\n * The guard WRAPS the write. An early return is a shape you can keep\n * while losing the protection; here the write is only reachable\n * through the verdict.\n */\n const verdict = await writeGuardedBySeed(\n {\n subject: 'workflow',\n unreadable: workflowsStatus === 'error',\n fromCache: workflowsFromCache,\n },\n async () => {\n await setDoc(\n doc(firestore, 'hosts', hostId, 'workflows', draftId),\n { ...fields, updatedAt: Timestamp.now() },\n { merge: true },\n )\n },\n )\n // Before `setDraft(null)`, so a refusal keeps the dialog open with\n // every step that was built and its test run still on screen.\n if (!verdict.ok) {\n return void enqueueSnackbar(verdict.message, {\n variant: 'warning',\n persist: false,\n })\n }\n } else {\n // New workflow rides the quota-enforcing resources API (AGL-473) —\n // it also re-checks the `workflows` entitlement server-side.\n await createHostResource({ hostId, resource: 'workflow', data: fields })\n // A create moves the count; the one-shot aggregate below does not\n // refresh itself the way the listener refreshes the rows.\n setWorkflowCountEpoch((epoch) => epoch + 1)\n }\n setDraft(null)\n enqueueSnackbar('Workflow saved', { variant: 'success', persist: false })\n } catch (error: any) {\n console.error(error)\n enqueueSnackbar(error?.message ?? 'An error has occurred', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n }, [\n draft,\n nameTaken,\n stepProblem,\n firestore,\n hostId,\n createHostResource,\n enqueueSnackbar,\n workflowsStatus,\n workflowsFromCache,\n ])\n\n const handleShowUsage = useCallback(\n (workflow: any) => async () => {\n setUsageLoading(workflow.$id)\n const result = await fetchWhereUsed(user as any, {\n hostId,\n kind: 'workflow',\n id: workflow.$id,\n name: workflow.name,\n })\n setUsageLoading(null)\n // The rows and their deep links are drawn in a zone; with nothing\n // registered there the answer is still given, in words.\n if (listConsoleWidgets(WORKFLOW_USAGE_ZONE.id).length === 0) {\n enqueueSnackbar(\n result.total\n ? `\"${workflow.name}\" computes ${summarizeDependents(result)}`\n : `\"${workflow.name}\" is not referenced by anything published`,\n { variant: 'info', persist: false },\n )\n return\n }\n setUsage({ name: workflow.name, result })\n },\n [user, hostId, enqueueSnackbar],\n )\n\n const handleDelete = useCallback(\n (workflow: any) => async () => {\n // Dependents warning (AGL-187): computed variables backed by this\n // workflow keep their stored fallback value once it is gone.\n const scan = await fetchWhereUsed(user as any, {\n hostId,\n kind: 'workflow',\n id: workflow.$id,\n name: workflow.name,\n })\n const confirmed = await confirm({\n title: 'Delete this workflow?',\n description: scan.total\n ? `\"${workflow.name}\" computes ${summarizeDependents(scan)} — ` +\n 'those variables will fall back to their stored values.'\n : `\"${workflow.name}\" will no longer be runnable.`,\n confirmationText: 'Delete',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await updateDoc(\n doc(firestore, 'hosts', hostId, 'workflows', workflow.$id),\n { deletedAt: Timestamp.now() },\n )\n enqueueSnackbar('Workflow deleted', {\n variant: 'success',\n persist: false,\n })\n },\n [user, confirm, firestore, hostId, enqueueSnackbar],\n )\n\n return (\n <CardDisplay\n header={'Workflows'}\n help={pluginDocsHelp('buildAWorkflow', {\n anchor: '#1-open-the-workflows-page',\n })}\n contentGutterX\n contentGutterY\n >\n {duplicate.dialog}\n <Stack spacing={1}>\n {workflows.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Chain your functions into multi-step pipelines — each step ' +\n 'feeds the next. Site-event triggers are coming next.'}\n </Typography>\n ) : (\n visibleWorkflows.map((workflow: any) => (\n <Stack\n key={workflow.$id}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n <Stack sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {workflow.name}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {`${(workflow.steps ?? []).length} step${\n (workflow.steps ?? []).length === 1 ? '' : 's'\n }${\n workflow.trigger?.event\n ? ` · on ${hostEventLabel(workflow.trigger.event)}`\n : ''\n } · ${(workflow.steps ?? [])\n .map((step: any) => step.functionName)\n .join(' → ')}`}\n </Typography>\n </Stack>\n <Button\n size=\"small\"\n disabled={usageLoading === workflow.$id}\n onClick={handleShowUsage(workflow)}\n >\n {usageLoading === workflow.$id ? 'Scanning…' : 'Usage'}\n </Button>\n {/* Run history (wave v6): the event runner logs status +\n duration per run. */}\n <Button size=\"small\" onClick={() => setRunsFor(workflow)}>\n {'Runs'}\n </Button>\n <Button\n size=\"small\"\n onClick={() => {\n setTestResult(null)\n setDraft({\n id: workflow.$id,\n name: workflow.name ?? '',\n steps: workflow.steps ?? [],\n returnValue: workflow.returnValue ?? '',\n trigger: workflow.trigger ?? null,\n })\n }}\n >\n {'Edit'}\n </Button>\n <Button\n size=\"small\"\n onClick={() =>\n duplicate.request('workflow', {\n id: workflow.$id,\n name: workflow.name ?? '',\n })\n }\n >\n {'Duplicate…'}\n </Button>\n <Button\n size=\"small\"\n color=\"error\"\n onClick={handleDelete(workflow)}\n >\n {'Delete'}\n </Button>\n </Stack>\n ))\n )}\n {workflows.length === 0 ? null : (\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={visibleWorkflows.length}\n // The workflows the card HOLDS. Not `workflowCount`, which is the\n // site's total including soft-deleted rows and answers the quota's\n // question rather than the reader's.\n count={workflows.length}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n )}\n {workflowsTruncated ? (\n <Alert severity=\"info\">\n {`Showing ${WORKFLOW_CEILING} workflows, ordered by id. This site ` +\n 'has more — the duplicate-name check below only covers the ' +\n 'ones listed here, so a name may already be taken by one that ' +\n 'is not.'}\n </Alert>\n ) : null}\n <Button\n size=\"small\"\n color=\"primary\"\n sx={{ alignSelf: 'flex-start' }}\n onClick={handleAdd}\n >\n {'Add workflow'}\n </Button>\n {/* The cap, standing rather than only on refusal (AGL-2113).\n `workflowCount` is the server aggregate the gate uses, not\n `workflows.length` — the listener is `limit(100)` and its length\n saturates (AGL-1716). */}\n <QuotaReadoutComponent\n ready={org != null}\n used={workflowCount}\n limit={checkQuota(org, 'workflowsPerHost', workflowCount).limit}\n noun=\"workflow\"\n />\n </Stack>\n\n <Dialog\n open={Boolean(draft)}\n onClose={() => setDraft(null)}\n maxWidth=\"sm\"\n fullWidth\n >\n <DialogTitle>\n {draft?.id ? 'Edit Workflow' : 'Add Workflow'}\n </DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, pt: 1 }}\n >\n {ExtensionZone && editorTarget ? (\n <ExtensionZone\n slot={AUTOMATION_EDITOR_ZONE.id}\n hostId={hostId}\n orgId={org?.$id}\n target={editorTarget}\n />\n ) : null}\n <TextField\n label=\"Name\"\n helperText={\n nameTaken\n ? 'A workflow with this name already exists'\n : 'Used to identify the workflow'\n }\n error={nameTaken}\n value={draft?.name ?? ''}\n onChange={(event) =>\n patch((previous) => ({ ...previous, name: event.target.value }))\n }\n size=\"small\"\n autoFocus\n sx={{ mt: 1 }}\n />\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Steps'}\n </Typography>\n {/*\n The pickers and the test run speak only for what was read. A step\n calling a function past the ceiling still RUNS on the site — this\n editor simply cannot name it, and a test run resolves its\n expression against an incomplete variable set.\n */}\n {shortLists.length > 0 ? (\n <Alert severity=\"info\">\n {`Offering the first ${EDITOR_OPTION_CEILING} ` +\n `${shortLists.join(', ')} on this site, ordered by id. ` +\n 'There are more, so the pickers below are short and a test ' +\n 'run may not resolve every expression.'}\n </Alert>\n ) : null}\n {(draft?.steps ?? []).map((step, index) => {\n const call = isWorkflowActionStep(step)\n ? null\n : (step as HostWorkflowStep)\n const definition = call\n ? (functions[(call as any).functionId ?? ''] ??\n functions[call.functionName])\n : null\n return (\n <AutomationStepFields\n key={index}\n /*\n * The editor speaks the Actions vocabulary. A function call\n * has no Actions type, so it takes none of those fields and\n * renders its own through `fields` instead — which is what\n * keeps this one editor rather than two.\n */\n step={step as HostActionStep}\n index={index}\n kind={call ? FUNCTION_CALL_KIND : (step as HostActionStep).type}\n kinds={STEP_KINDS}\n stepForKind={(value) =>\n (value === FUNCTION_CALL_KIND\n ? { functionName: '', args: [], resultName: '' }\n : defaultStep(\n value as HostActionStepType,\n )) as HostActionStep\n }\n pickers={stepPickers}\n onSteps={(update) =>\n patch((previous) => ({\n ...previous,\n steps: update(\n previous.steps as HostActionStep[],\n ) as WorkflowStep[],\n }))\n }\n // A workflow with no trigger runs from another automation, so\n // its email step is a reply only on its own event.\n replyContext={{\n event: draft?.trigger?.event,\n afterWait: stepRunsAfterWait(draft?.steps as HostActionStep[], index),\n }}\n fields={\n call ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flex: 1, flexWrap: 'wrap' }}\n >\n <TextField\n label=\"Function\"\n // Stored by id (AGL-261); legacy steps carry only the\n // name and resolve through the double-keyed map.\n value={\n (call as any).functionId ??\n (functions[call.functionName] as any)?.$id ??\n ''\n }\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n steps: previous.steps.map((s, index2) =>\n index2 === index\n ? {\n ...s,\n functionId: event.target.value,\n functionName:\n functionOptions.find(\n (option) =>\n option.id === event.target.value,\n )?.name ??\n (s as HostWorkflowStep).functionName,\n }\n : s,\n ),\n }))\n }\n size=\"small\"\n select\n sx={{ minWidth: 160, flex: 1 }}\n >\n {functionOptions.map((option) => (\n <MenuItem key={option.id} value={option.id}>\n {option.name}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n label=\"Result name\"\n placeholder={`step${index + 1}`}\n value={call.resultName ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n steps: previous.steps.map((s, index2) =>\n index2 === index\n ? {\n ...s,\n resultName: event.target.value.replace(\n /[^a-zA-Z0-9_]/g,\n '',\n ),\n }\n : s,\n ),\n }))\n }\n size=\"small\"\n sx={{ width: 140 }}\n />\n {(definition?.parameters ?? []).map(\n (parameter, parameterIndex) => (\n <TextField\n key={parameter.name}\n label={`${parameter.name} expression`}\n placeholder={\n parameterIndex === 0 && index > 0\n ? `step${index}`\n : 'a variable, number, or expression'\n }\n value={call.args?.[parameterIndex] ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n steps: previous.steps.map((s, index2) => {\n if (index2 !== index) return s\n const args = [\n ...((s as HostWorkflowStep).args ?? []),\n ]\n args[parameterIndex] = event.target.value\n return { ...s, args }\n }),\n }))\n }\n size=\"small\"\n sx={{ minWidth: 180, flex: 1 }}\n />\n ),\n )}\n </Stack>\n ) : undefined\n }\n />\n )\n })}\n <Button\n size=\"small\"\n sx={{ alignSelf: 'flex-start' }}\n disabled={(draft?.steps.length ?? 0) >= WORKFLOW_MAX_STEPS}\n onClick={() =>\n patch((previous) => ({\n ...previous,\n steps: [\n ...previous.steps,\n { functionName: '', args: [], resultName: '' },\n ],\n }))\n }\n >\n {'Add step'}\n </Button>\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Trigger'}\n </Typography>\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Run on event\"\n value={draft?.trigger?.event ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n trigger: event.target.value\n ? {\n event: event.target.value as any,\n filter: previous.trigger?.filter ?? '',\n }\n : null,\n }))\n }\n size=\"small\"\n select\n sx={{ minWidth: 180 }}\n >\n <MenuItem value=\"\">{'Manual only'}</MenuItem>\n {HOST_EVENT_TYPES.map((eventType) => (\n <MenuItem key={eventType} value={eventType}>\n {hostEventLabel(eventType)}\n </MenuItem>\n ))}\n </TextField>\n {draft?.trigger ? (\n <TextField\n label=\"Filter (optional)\"\n placeholder=\"subscribe\"\n // The evaluator is arithmetic and has no comparison (AGL-3458):\n // `path == \"/pricing\"` throws on every event and never runs.\n error={Boolean(triggerFilterProblem(draft?.trigger?.filter, { remedy: 'action' }))}\n helperText={\n triggerFilterProblem(draft?.trigger?.filter, { remedy: 'action' }) ??\n [\n 'Runs only when this expression is truthy — a field name, or arithmetic. It cannot compare values.',\n hostEventPayloadHint(draft?.trigger?.event),\n ]\n .filter(Boolean)\n .join(' ')\n }\n value={draft?.trigger?.filter ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n trigger: previous.trigger\n ? { ...previous.trigger, filter: event.target.value }\n : previous.trigger,\n }))\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n ) : null}\n </Stack>\n <TextField\n label=\"Return value\"\n helperText=\"A step result name; defaults to the last step\"\n value={draft?.returnValue ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n returnValue: event.target.value,\n }))\n }\n size=\"small\"\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button size=\"small\" color=\"primary\" onClick={handleTestRun}>\n {'Test run'}\n </Button>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Uses current variable values'}\n </Typography>\n </Stack>\n {testResult ? (\n <Alert\n severity={testResult.startsWith('Error') ? 'warning' : 'success'}\n >\n {testResult}\n </Alert>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setDraft(null)}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!draft?.name.trim() || nameTaken}\n onClick={handleSave}\n >\n {'Done'}\n </Button>\n </DialogActions>\n </Dialog>\n {ExtensionZone ? (\n <ExtensionZone\n slot={WORKFLOW_USAGE_ZONE.id}\n hostId={hostId}\n usage={usage}\n onClose={() => setUsage(null)}\n />\n ) : null}\n <Dialog\n open={Boolean(runsFor)}\n onClose={() => setRunsFor(null)}\n // md: the history's four columns fit without the table scrolling.\n maxWidth=\"md\"\n fullWidth\n >\n <DialogTitle>{`Runs — ${runsFor?.name ?? ''}`}</DialogTitle>\n <DialogContent>\n {runsFor ? (\n <HostRunHistoryCard\n hostId={hostId}\n orgId={org?.$id}\n targetId={runsFor.$id}\n targetType=\"workflow\"\n targetName={runsFor.name ?? ''}\n header=\"Recent runs\"\n />\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button color=\"inherit\" onClick={() => setRunsFor(null)}>\n {'Close'}\n </Button>\n </DialogActions>\n </Dialog>\n </CardDisplay>\n )\n}\nHostWorkflowsCard.displayName = 'HostWorkflowsCard'\n\nexport default HostWorkflowsCard\n"],"names":["checkEntitlement","checkQuota","HOST_EVENT_TYPES","hostEventLabel","hostEventPayloadHint","pluginDocsHelp","triggerFilterProblem","ceilingedWindow","collectionCeiling","useConsoleWidgetSlot","CardDisplay","useConfirmationContext","ListPagination","TABLE_PAGE_SIZE_DEFAULT","QuotaReadoutComponent","useSnackbar","Timestamp","Alert","Button","Dialog","DialogActions","DialogContent","DialogTitle","MenuItem","Stack","TextField","Typography","collection","doc","getCountFromServer","setDoc","updateDoc","useCallback","useEffect","useMemo","useState","useDuplicateResource","useFirestore","useFirestoreCollection","useHostResourceApi","useUser","writeGuardedBySeed","AutomationStepFields","defaultStep","isWorkflowActionStep","validateWorkflowSteps","WORKFLOW_ACTION_STEP_TYPES","workflowFunctionCalls","workflowStepTypeLabel","HostRunHistoryCard","EDITOR_OPTION_CEILING","useAutomationStepPickers","listConsoleWidgets","fetchWhereUsed","summarizeDependents","AUTOMATION_EDITOR_ZONE","WORKFLOW_USAGE_ZONE","runWorkflow","WORKFLOW_MAX_STEPS","stepRunsAfterWait","WORKFLOW_CEILING","FUNCTION_CALL_KIND","STEP_KINDS","value","label","map","HostWorkflowsCard","props","runsFor","draft","hostId","firestore","data","user","createHostResource","enqueueSnackbar","duplicate","onDuplicated","_kind","copy","name","variant","confirm","org","ExtensionZone","workflowDocs","status","workflowsStatus","fromCache","workflowsFromCache","idField","rows","readWorkflows","truncated","workflowsTruncated","setDraft","editorOpened","setEditorOpened","functionRead","functionDocs","functionsTruncated","variableRead","variableDocs","variablesTruncated","pickers","stepPickers","truncatedPickers","workflows","filter","workflow","deletedAt","sort","a","b","String","localeCompare","page","setPage","pageSize","setPageSize","visibleWorkflows","slice","workflowCountEpoch","setWorkflowCountEpoch","serverWorkflowCount","setServerWorkflowCount","active","then","snapshot","count","catch","workflowCount","length","functions","definition","$id","functionOptions","id","variables","variable","usage","setUsage","usageLoading","setUsageLoading","testResult","setTestResult","setRunsFor","nameTaken","Boolean","some","toLowerCase","trim","patch","updater","previous","draftId","draftName","editorTarget","type","handleAdd","persist","quota","allowed","limit","steps","functionName","args","resultName","returnValue","trigger","shortLists","stepProblem","remedy","handleTestRun","run","ok","error","Object","entries","results","key","join","handleSave","fields","verdict","subject","unreadable","updatedAt","now","merge","message","resource","epoch","console","allowDuplicate","handleShowUsage","result","kind","total","handleDelete","scan","confirmed","title","description","confirmationText","confirmationButtonProps","color","header","help","anchor","contentGutterX","contentGutterY","dialog","spacing","direction","sx","alignItems","flex","minWidth","noWrap","event","step","size","disabled","onClick","request","rowCount","onPageChange","onPageSizeChange","severity","alignSelf","ready","used","noun","open","onClose","maxWidth","fullWidth","display","flexDirection","gap","pt","slot","orgId","target","helperText","onChange","autoFocus","mt","index","call","functionId","kinds","stepForKind","onSteps","update","replyContext","afterWait","flexWrap","s","index2","find","option","select","placeholder","replace","width","parameters","parameter","parameterIndex","undefined","eventType","startsWith","targetId","targetType","targetName","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;;AAEA,SAEEA,gBAAgB,EAChBC,UAAU,EACVC,gBAAgB,EAChBC,cAAc,EACdC,oBAAoB,EAGpBC,cAAc,EACdC,oBAAoB,QACf,eAAc;AACrB;;;;;CAKC,GACD,SACEC,eAAe,EACfC,iBAAiB,QACZ,+DAA8D;AACrE,SAASC,oBAAoB,QAAQ,qDAAoD;AACzF,SAASC,WAAW,EAAEC,sBAAsB,QAAQ,uBAAsB;AAC1E,SAASC,cAAc,QAAQ,4DAA2D;AAC1F,SAASC,uBAAuB,QAAQ,8CAA6C;AACrF,OAAOC,2BAA2B,0DAAyD;AAC3F,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,SAAS,QAAQ,+BAA8B;AACxD,SACEC,KAAK,EACLC,MAAM,EACNC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,WAAW,EACXC,QAAQ,EACRC,KAAK,EACLC,SAAS,EACTC,UAAU,QACL,gBAAe;AACtB,SACEC,UAAU,EACVC,GAAG,EACHC,kBAAkB,EAClBC,MAAM,EACNC,SAAS,QACJ,qBAAoB;AAC3B,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AACjE,SACEC,oBAAoB,EACpBC,YAAY,EACZC,sBAAsB,EACtBC,kBAAkB,EAClBC,OAAO,EACPC,kBAAkB,QACb,iCAAgC;AACvC,SACEC,oBAAoB,EAEpBC,WAAW,QACN,wCAAoC;AAC3C,SAEEC,oBAAoB,EACpBC,qBAAqB,EACrBC,0BAA0B,EAC1BC,qBAAqB,EAErBC,qBAAqB,QAChB,8BAA0B;AACjC,OAAOC,wBAAwB,uCAAmC;AAClE,SACEC,qBAAqB,EACrBC,wBAAwB,QACnB,mCAA+B;AACtC,SAASC,kBAAkB,QAAQ,eAAc;AACjD,SACEC,cAAc,EACdC,mBAAmB,QAEd,oCAAmC;AAC1C,SACEC,sBAAsB,EACtBC,mBAAmB,QAEd,sBAAkB;AACzB,SAEEC,WAAW,EACXC,kBAAkB,QACb,wBAAoB;AAC3B,SAGEC,iBAAiB,QACZ,2BAAuB;AAE9B;;;;;CAKC,GACD,MAAMC,mBAAmB;AAEzB,wEAAwE,GACxE,MAAMC,qBAAqB;AAE3B;;;;;;;CAOC,GACD,MAAMC,aAAmC;IACvC;QAAEC,OAAOF;QAAoBG,OAAO;IAAkB;OACnDlB,2BAA2BmB,GAAG,CAAC,CAACF,QAAW,CAAA;YAC5CA;YACAC,OAAOhB,sBAAsBe;QAC/B,CAAA;CACD;AAYD;;;;;;CAMC,GACD,OAAO,SAASG,kBAAkBC,KAA6B;iDA+1B7C7D,4CAqFQ8D;QApHLC,gBA6B+BA,iBAEbA,iBAGEA,iBAKlBA;IAt2BrB,MAAM,EAAEC,MAAM,EAAE,GAAGH;IACnB,MAAMI,YAAYlC;IAClB,MAAM,EAAEmC,MAAMC,IAAI,EAAE,GAAGjC;IACvB,MAAMkC,qBAAqBnC;IAC3B,MAAM,EAAEoC,eAAe,EAAE,GAAG5D;IAC5B,yEAAyE;IACzE,yEAAyE;IACzE,MAAM6D,YAAYxC,qBAAqB;QACrCkC;QACAO,cAAc,CAACC,OAAOC,OACpBJ,gBACE,CAAC,eAAe,EAAEI,KAAKC,IAAI,CAAC,6BAA6B,CAAC,EAC1D;gBACEC,SAAS;YACX;IAEN;IACA,MAAM,EAAEC,OAAO,EAAE,GAAGvE;IACpB,MAAM,EAAEwE,GAAG,EAAE,GAAGhB;IAChB;;;GAGC,GACD,MAAMiB,gBAAgB3E;IAEtB,MAAM,EACJ+D,MAAMa,YAAY,EAClBC,QAAQC,eAAe,EACvB;;;;;;;;;KASC,GACDC,WAAWC,kBAAkB,EAC9B,GAAGnD,uBACF;;;;;;;;;;;;;;;;;;;KAmBC,GACD,IACE9B,kBACEmB,WAAW4C,WAAW,SAASD,QAAQ,cACvCV,mBAEJ;QAACW;QAAWD;KAAO,EACnB;QAAEoB,SAAS;IAAM;IAEnB,MAAM,EAAEC,MAAMC,aAAa,EAAEC,WAAWC,kBAAkB,EAAE,GAC1DvF,gBAAqB8E,cAAczB;IACrC,MAAM,CAACS,OAAO0B,SAAS,GAAG5D,SAA+B;IACzD;;;;;;;;;GASC,GACD,MAAM,CAAC6D,cAAcC,gBAAgB,GAAG9D,SAAS;IACjD,IAAIkC,SAAS,CAAC2B,cAAcC,gBAAgB;IAC5C;;;;;;;;;;;;;;GAcC,GACD,MAAM,EAAEzB,MAAM0B,YAAY,EAAE,GAAG5D,uBAC7B,IACE0D,eACIxF,kBACEmB,WAAW4C,WAAW,SAASD,QAAQ,cACvCpB,yBAEF,MACN;QAACqB;QAAWD;QAAQ0B;KAAa,EACjC;QAAEN,SAAS;IAAM;IAEnB,2EAA2E;IAC3E,4DAA4D;IAC5D,MAAM,EAAEC,MAAMQ,YAAY,EAAEN,WAAWO,kBAAkB,EAAE,GAAGlE,QAC5D,IAAM3B,gBAAqB2F,cAAchD,wBACzC;QAACgD;KAAa;IAEhB,MAAM,EAAE1B,MAAM6B,YAAY,EAAE,GAAG/D,uBAC7B,IACE0D,eACIxF,kBACEmB,WAAW4C,WAAW,SAASD,QAAQ,cACvCpB,yBAEF,MACN;QAACqB;QAAWD;QAAQ0B;KAAa,EACjC;QAAEN,SAAS;IAAM;IAEnB,MAAM,EAAEC,MAAMW,YAAY,EAAET,WAAWU,kBAAkB,EAAE,GAAGrE,QAC5D,IAAM3B,gBAAqB8F,cAAcnD,wBACzC;QAACmD;KAAa;IAEhB;;;;;;;GAOC,GACD,MAAM,EAAEG,SAASC,WAAW,EAAEZ,WAAWa,gBAAgB,EAAE,GACzDvD,yBAAyBmB,QAAQ0B;IACnC,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAMW,YAAYzE,QAChB,IACE0D,cACGgB,MAAM,CAAC,CAACC,WAAkB,CAACA,SAASC,SAAS,EAC7CC,IAAI,CAAC,CAACC,GAAQC;gBACND,SAAmCC;mBAA1CC,QAAOF,UAAAA,EAAEhC,IAAI,YAANgC,UAAU,IAAIG,aAAa,CAACD,QAAOD,UAAAA,EAAEjC,IAAI,YAANiC,UAAU;YAE1D;QAACrB;KAAc;IAEjB,0EAA0E;IAC1E,eAAe;IACf,MAAM,CAACwB,MAAMC,QAAQ,GAAGlF,SAAS;IACjC,MAAM,CAACmF,UAAUC,YAAY,GAAGpF,SAAStB;IACzC,MAAM2G,mBAAmBtF,QACvB,IAAMyE,UAAUc,KAAK,CAACL,OAAOE,UAAUF,OAAOE,WAAWA,WACzD;QAACX;QAAWS;QAAME;KAAS;IAE7B;;;;;;;;;;;;;;;;;GAiBC,GACD,MAAM,CAACI,oBAAoBC,sBAAsB,GAAGxF,SAAS;IAC7D,MAAM,CAACyF,qBAAqBC,uBAAuB,GAAG1F,SACpD;IAEFF,UAAU;QACR,IAAI6F,SAAS;QACb,KAAKjG,mBAAmBF,WAAW4C,WAAW,SAASD,QAAQ,cAC5DyD,IAAI,CAAC,CAACC;YACL,IAAIF,QAAQD,uBAAuBG,SAASxD,IAAI,GAAGyD,KAAK;QAC1D,GACCC,KAAK,CAAC;QACL,8DAA8D;QAC9D,oEAAoE;QACpE,mCAAmC;QACrC;QACF,OAAO;YACLJ,SAAS;QACX;IACF,GAAG;QAACvD;QAAWD;QAAQoD;KAAmB;IAC1C,MAAMS,gBAAgBP,8BAAAA,sBAAuBjB,UAAUyB,MAAM;IAC7D,+DAA+D;IAC/D,sDAAsD;IACtD,MAAMC,YAAYnG,QAAQ;QACxB,MAAM+B,MAAoC,CAAC;QAC3C,KAAK,MAAMqE,cAAcnC,uBAAAA,eAAgB,EAAE,CAAE;YAC3C,IAAImC,WAAWxB,SAAS,EAAE;YAC1B,IAAIwB,WAAWC,GAAG,EAAEtE,GAAG,CAACqE,WAAWC,GAAG,CAAC,GAAGD;YAC1C,IAAIA,WAAWtD,IAAI,EAAEf,GAAG,CAACqE,WAAWtD,IAAI,CAAC,GAAGsD;QAC9C;QACA,OAAOrE;IACT,GAAG;QAACkC;KAAa;IACjB,MAAMqC,kBAAkBtG,QACtB,IACE,CAACiE,uBAAAA,eAAgB,EAAE,EAChBS,MAAM,CAAC,CAAC0B,aAAoB,CAACA,WAAWxB,SAAS,IAAIwB,WAAWtD,IAAI,EACpEf,GAAG,CAAC,CAACqE,aAAqB,CAAA;gBACzBG,IAAIH,WAAWC,GAAG;gBAClBvD,MAAMsD,WAAWtD,IAAI;YACvB,CAAA,GACC+B,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEhC,IAAI,CAACmC,aAAa,CAACF,EAAEjC,IAAI,IAC/C;QAACmB;KAAa;IAEhB,MAAMuC,YAAYxG,QAAQ;QACxB,MAAM+B,MAAoC,CAAC;QAC3C,KAAK,MAAM0E,YAAYrC,uBAAAA,eAAgB,EAAE,CAAE;YACzC,IAAI,CAACqC,SAAS7B,SAAS,IAAI6B,SAAS3D,IAAI,EAAEf,GAAG,CAAC0E,SAAS3D,IAAI,CAAC,GAAG2D;QACjE;QACA,OAAO1E;IACT,GAAG;QAACqC;KAAa;IAEjB,+BAA+B;IAC/B,MAAM,CAACsC,OAAOC,SAAS,GAAG1G,SAGhB;IACV,MAAM,CAAC2G,cAAcC,gBAAgB,GAAG5G,SAAwB;IAEhE,MAAM,CAAC6G,YAAYC,cAAc,GAAG9G,SAAwB;IAC5D,MAAM,CAACiC,SAAS8E,WAAW,GAAG/G,SAAqB;IAEnD,kEAAkE;IAClE,2DAA2D;IAC3D,MAAMgH,YAAYC,QAChB/E,SACAsC,UAAU0C,IAAI,CACZ,CAACf;YACQA;eAAPpB,QAAOoB,mBAAAA,WAAWtD,IAAI,YAAfsD,mBAAmB,IAAIgB,WAAW,OACvCjF,MAAMW,IAAI,CAACuE,IAAI,GAAGD,WAAW,MAAMhB,WAAWC,GAAG,KAAKlE,MAAMoE,EAAE;;IAItE,MAAMe,QAAQxH,YACZ,CAACyH,UACC1D,SAAS,CAAC2D,WAAcA,WAAWD,QAAQC,YAAYA,WACzD,EAAE;IAGJ,qFAAqF,GACrF,MAAMC,kBAAUtF,yBAAAA,MAAOoE,EAAE,mBAAI;IAC7B,MAAMmB,qBAAYvF,yBAAAA,MAAOW,IAAI,oBAAI;IACjC,MAAM6E,eAAe3H,QACnB,IAAOyH,UAAU;YAAEG,MAAM;YAAYrB,IAAIkB;YAAS3E,MAAM4E;QAAU,IAAI,MACtE,wEAAwE;IACxE,oEAAoE;IACpE,uDAAuD;IACvD;QAACD;KAAQ;IAGX,MAAMI,YAAY/H,YAAY;QAC5B,qEAAqE;QACrE,IAAI,CAAChC,iBAAiBmF,KAAK,cAAc;YACvC,OAAO,KAAKR,gBACV,6DACA;gBAAEM,SAAS;gBAAW+E,SAAS;YAAM;QAEzC;QACA,0DAA0D;QAC1D,MAAMC,QAAQhK,WAAWkF,KAAK,oBAAoBgD;QAClD,IAAI,CAAC8B,MAAMC,OAAO,EAAE;YAClB,OAAO,KAAKvF,gBACV,CAAC,wBAAwB,EAAEsF,MAAME,KAAK,CAAC,sBAAsB,CAAC,EAC9D;gBAAElF,SAAS;gBAAW+E,SAAS;YAAM;QAEzC;QACAf,cAAc;QACdlD,SAAS;YACP0C,IAAI;YACJzD,MAAM;YACNoF,OAAO;gBAAC;oBAAEC,cAAc;oBAAIC,MAAM,EAAE;oBAAEC,YAAY;gBAAG;aAAE;YACvDC,aAAa;YACbC,SAAS;QACX;IACF,GAAG;QAACtF;QAAKgD;QAAexD;KAAgB;IAExC;;;;;GAKC,GACD,MAAM+F,aAAaxI,QACjB,IACE;YACEkE,qBAAqB,cAAc;YACnCG,qBAAqB,cAAc;eAChCG;SACJ,CAACE,MAAM,CAAC,CAAC5B,OAAyBA,SAAS,OAC9C;QAACoB;QAAoBG;QAAoBG;KAAiB;IAG5D;;;;;;;;GAQC,GACD,MAAMiE,cAAczI,QAClB;YAGM,+CAA+C;QAC9C5B;YAAqB+D;eAH1BA,SAGK/D,wBAAAA,sBAAqB+D,iBAAAA,MAAMoG,OAAO,qBAAbpG,eAAeuC,MAAM,EAAE;YAAEgE,QAAQ;QAAS,cAA/DtK,wBAAqEuC,sBAAsBwB,MAAM+F,KAAK,IACvG;OACN;QAAC/F;KAAM;IAGT,MAAMwG,gBAAgB7I,YAAY;QAChC,IAAI,CAACqC,OAAO;QACZ;;;;;;;KAOC,GACD,MAAMyG,MAAMrH,YAAYV,sBAAsBsB,QAAQgE,WAAWK;QACjEO,cACE6B,IAAIC,EAAE,KAAK,QACP,CAAC,OAAO,EAAED,IAAIE,KAAK,EAAE,GACrB,CAAC,QAAQ,EAAE9D,OAAO4D,IAAI/G,KAAK,EAAE,EAAE,EAAEkH,OAAOC,OAAO,CAACJ,IAAIK,OAAO,EACxDlH,GAAG,CAAC,CAAC,CAACmH,KAAKrH,MAAM,GAAK,GAAGqH,IAAI,CAAC,EAAErH,OAAO,EACvCsH,IAAI,CAAC,MAAM,CAAC,CAAC;IAExB,GAAG;QAAChH;QAAOgE;QAAWK;KAAU;IAEhC,MAAM4C,aAAatJ,YAAY;QAC7B,IAAI,CAACqC,SAAS,CAACA,MAAMW,IAAI,CAACuE,IAAI,MAAMJ,WAAW;QAC/C,wEAAwE;QACxE,oEAAoE;QACpE,IAAIwB,aAAa;YACf,OAAO,KAAKhG,gBAAgBgG,aAAa;gBACvC1F,SAAS;gBACT+E,SAAS;YACX;QACF;QACA,MAAM,EAAEvB,IAAIkB,OAAO,EAAiB,GAAGtF,OAAfiE,8CAAejE;;;QACvC,MAAMkH,SAAS,aAAKjD;YAAYtD,MAAMX,MAAMW,IAAI,CAACuE,IAAI,GAAG9B,KAAK,CAAC,GAAG;;QACjE,IAAI;YACF,IAAIkC,SAAS;gBACX;;;;;;;;;SASC,GACD,MAAM6B,UAAU,MAAM/I,mBACpB;oBACEgJ,SAAS;oBACTC,YAAYnG,oBAAoB;oBAChCC,WAAWC;gBACb,GACA;oBACE,MAAM3D,OACJF,IAAI2C,WAAW,SAASD,QAAQ,aAAaqF,UAC7C,aAAK4B;wBAAQI,WAAW3K,UAAU4K,GAAG;wBACrC;wBAAEC,OAAO;oBAAK;gBAElB;gBAEF,mEAAmE;gBACnE,8DAA8D;gBAC9D,IAAI,CAACL,QAAQT,EAAE,EAAE;oBACf,OAAO,KAAKpG,gBAAgB6G,QAAQM,OAAO,EAAE;wBAC3C7G,SAAS;wBACT+E,SAAS;oBACX;gBACF;YACF,OAAO;gBACL,mEAAmE;gBACnE,6DAA6D;gBAC7D,MAAMtF,mBAAmB;oBAAEJ;oBAAQyH,UAAU;oBAAYvH,MAAM+G;gBAAO;gBACtE,kEAAkE;gBAClE,0DAA0D;gBAC1D5D,sBAAsB,CAACqE,QAAUA,QAAQ;YAC3C;YACAjG,SAAS;YACTpB,gBAAgB,kBAAkB;gBAAEM,SAAS;gBAAW+E,SAAS;YAAM;QACzE,EAAE,OAAOgB,OAAY;;YACnBiB,QAAQjB,KAAK,CAACA;YACdrG,wBAAgBqG,yBAAAA,MAAOc,OAAO,mBAAI,yBAAyB;gBACzD7G,SAAS;gBACTiH,gBAAgB;YAClB;QACF;IACF,GAAG;QACD7H;QACA8E;QACAwB;QACApG;QACAD;QACAI;QACAC;QACAY;QACAE;KACD;IAED,MAAM0G,kBAAkBnK,YACtB,CAAC6E,WAAkB;YACjBkC,gBAAgBlC,SAAS0B,GAAG;YAC5B,MAAM6D,SAAS,MAAM/I,eAAeoB,MAAa;gBAC/CH;gBACA+H,MAAM;gBACN5D,IAAI5B,SAAS0B,GAAG;gBAChBvD,MAAM6B,SAAS7B,IAAI;YACrB;YACA+D,gBAAgB;YAChB,kEAAkE;YAClE,wDAAwD;YACxD,IAAI3F,mBAAmBI,oBAAoBiF,EAAE,EAAEL,MAAM,KAAK,GAAG;gBAC3DzD,gBACEyH,OAAOE,KAAK,GACR,CAAC,CAAC,EAAEzF,SAAS7B,IAAI,CAAC,WAAW,EAAE1B,oBAAoB8I,SAAS,GAC5D,CAAC,CAAC,EAAEvF,SAAS7B,IAAI,CAAC,yCAAyC,CAAC,EAChE;oBAAEC,SAAS;oBAAQ+E,SAAS;gBAAM;gBAEpC;YACF;YACAnB,SAAS;gBAAE7D,MAAM6B,SAAS7B,IAAI;gBAAEoH;YAAO;QACzC,GACA;QAAC3H;QAAMH;QAAQK;KAAgB;IAGjC,MAAM4H,eAAevK,YACnB,CAAC6E,WAAkB;YACjB,kEAAkE;YAClE,6DAA6D;YAC7D,MAAM2F,OAAO,MAAMnJ,eAAeoB,MAAa;gBAC7CH;gBACA+H,MAAM;gBACN5D,IAAI5B,SAAS0B,GAAG;gBAChBvD,MAAM6B,SAAS7B,IAAI;YACrB;YACA,MAAMyH,YAAY,MAAMvH,QAAQ;gBAC9BwH,OAAO;gBACPC,aAAaH,KAAKF,KAAK,GACnB,CAAC,CAAC,EAAEzF,SAAS7B,IAAI,CAAC,WAAW,EAAE1B,oBAAoBkJ,MAAM,GAAG,CAAC,GAC7D,2DACA,CAAC,CAAC,EAAE3F,SAAS7B,IAAI,CAAC,6BAA6B,CAAC;gBACpD4H,kBAAkB;gBAClBC,yBAAyB;oBAAEC,OAAO;gBAAQ;YAC5C,GACG/E,IAAI,CAAC,IAAM,MACXG,KAAK,CAAC,IAAM;YACf,IAAI,CAACuE,WAAW;YAChB,MAAM1K,UACJH,IAAI2C,WAAW,SAASD,QAAQ,aAAauC,SAAS0B,GAAG,GACzD;gBAAEzB,WAAW9F,UAAU4K,GAAG;YAAG;YAE/BjH,gBAAgB,oBAAoB;gBAClCM,SAAS;gBACT+E,SAAS;YACX;QACF,GACA;QAACvF;QAAMS;QAASX;QAAWD;QAAQK;KAAgB;IAGrD,qBACE,MAACjE;QACCqM,QAAQ;QACRC,MAAM3M,eAAe,kBAAkB;YACrC4M,QAAQ;QACV;QACAC,cAAc;QACdC,cAAc;;YAEbvI,UAAUwI,MAAM;0BACjB,MAAC5L;gBAAM6L,SAAS;;oBACb1G,UAAUyB,MAAM,KAAK,kBACpB,KAAC1G;wBAAWuD,SAAQ;wBAAQ6H,OAAM;kCAC/B,gEACC;yBAGJtF,iBAAiBvD,GAAG,CAAC,CAAC4C;4BAYTA,iBACFA,kBAKIA;4BAHLA;6CAdR,MAACrF;4BAEC8L,WAAU;4BACVD,SAAS;4BACTE,IAAI;gCAAEC,YAAY;4BAAS;;8CAE3B,MAAChM;oCAAM+L,IAAI;wCAAEE,MAAM;wCAAGC,UAAU;oCAAE;;sDAChC,KAAChM;4CAAWuD,SAAQ;4CAAQ0I,MAAM;sDAC/B9G,SAAS7B,IAAI;;sDAEhB,KAACtD;4CAAWuD,SAAQ;4CAAU6H,OAAM;4CAAiBa,MAAM;sDACxD,GAAG,EAAC9G,kBAAAA,SAASuD,KAAK,YAAdvD,kBAAkB,EAAE,EAAEuB,MAAM,CAAC,KAAK,EACrC,EAACvB,mBAAAA,SAASuD,KAAK,YAAdvD,mBAAkB,EAAE,EAAEuB,MAAM,KAAK,IAAI,KAAK,MAE3CvB,EAAAA,oBAAAA,SAAS4D,OAAO,qBAAhB5D,kBAAkB+G,KAAK,IACnB,CAAC,MAAM,EAAEzN,eAAe0G,SAAS4D,OAAO,CAACmD,KAAK,GAAG,GACjD,GACL,GAAG,EAAE,EAAC/G,mBAAAA,SAASuD,KAAK,YAAdvD,mBAAkB,EAAE,EACxB5C,GAAG,CAAC,CAAC4J,OAAcA,KAAKxD,YAAY,EACpCgB,IAAI,CAAC,QAAQ;;;;8CAGpB,KAACnK;oCACC4M,MAAK;oCACLC,UAAUjF,iBAAiBjC,SAAS0B,GAAG;oCACvCyF,SAAS7B,gBAAgBtF;8CAExBiC,iBAAiBjC,SAAS0B,GAAG,GAAG,cAAc;;8CAIjD,KAACrH;oCAAO4M,MAAK;oCAAQE,SAAS,IAAM9E,WAAWrC;8CAC5C;;8CAEH,KAAC3F;oCACC4M,MAAK;oCACLE,SAAS;4CAICnH,gBACCA,iBACMA,uBACJA;wCANXoC,cAAc;wCACdlD,SAAS;4CACP0C,IAAI5B,SAAS0B,GAAG;4CAChBvD,IAAI,GAAE6B,iBAAAA,SAAS7B,IAAI,YAAb6B,iBAAiB;4CACvBuD,KAAK,GAAEvD,kBAAAA,SAASuD,KAAK,YAAdvD,kBAAkB,EAAE;4CAC3B2D,WAAW,GAAE3D,wBAAAA,SAAS2D,WAAW,YAApB3D,wBAAwB;4CACrC4D,OAAO,GAAE5D,oBAAAA,SAAS4D,OAAO,YAAhB5D,oBAAoB;wCAC/B;oCACF;8CAEC;;8CAEH,KAAC3F;oCACC4M,MAAK;oCACLE,SAAS;4CAGCnH;+CAFRjC,UAAUqJ,OAAO,CAAC,YAAY;4CAC5BxF,IAAI5B,SAAS0B,GAAG;4CAChBvD,IAAI,GAAE6B,iBAAAA,SAAS7B,IAAI,YAAb6B,iBAAiB;wCACzB;;8CAGD;;8CAEH,KAAC3F;oCACC4M,MAAK;oCACLhB,OAAM;oCACNkB,SAASzB,aAAa1F;8CAErB;;;2BAhEEA,SAAS0B,GAAG;;oBAqEtB5B,UAAUyB,MAAM,KAAK,IAAI,qBACxB,KAACxH;wBACCwG,MAAMA;wBACNE,UAAUA;wBACV4G,UAAU1G,iBAAiBY,MAAM;wBACjC,kEAAkE;wBAClE,mEAAmE;wBACnE,qCAAqC;wBACrCH,OAAOtB,UAAUyB,MAAM;wBACvB+F,cAAc9G;wBACd+G,kBAAkB7G;;oBAGrBzB,mCACC,KAAC7E;wBAAMoN,UAAS;kCACb,CAAC,QAAQ,EAAEzK,iBAAiB,qCAAqC,CAAC,GACjE,+DACA,kEACA;yBAEF;kCACJ,KAAC1C;wBACC4M,MAAK;wBACLhB,OAAM;wBACNS,IAAI;4BAAEe,WAAW;wBAAa;wBAC9BN,SAASjE;kCAER;;kCAMH,KAACjJ;wBACCyN,OAAOpJ,OAAO;wBACdqJ,MAAMrG;wBACNgC,OAAOlK,WAAWkF,KAAK,oBAAoBgD,eAAegC,KAAK;wBAC/DsE,MAAK;;;;0BAIT,MAACtN;gBACCuN,MAAMtF,QAAQ/E;gBACdsK,SAAS,IAAM5I,SAAS;gBACxB6I,UAAS;gBACTC,SAAS;;kCAET,KAACvN;kCACE+C,CAAAA,yBAAAA,MAAOoE,EAAE,IAAG,kBAAkB;;kCAEjC,MAACpH;wBACCkM,IAAI;4BAAEuB,SAAS;4BAAQC,eAAe;4BAAUC,KAAK;4BAAKC,IAAI;wBAAE;;4BAE/D7J,iBAAiByE,6BAChB,KAACzE;gCACC8J,MAAM3L,uBAAuBkF,EAAE;gCAC/BnE,QAAQA;gCACR6K,KAAK,EAAEhK,uBAAAA,IAAKoD,GAAG;gCACf6G,QAAQvF;iCAER;0CACJ,KAACpI;gCACCuC,OAAM;gCACNqL,YACElG,YACI,6CACA;gCAEN6B,OAAO7B;gCACPpF,KAAK,WAAEM,yBAAAA,MAAOW,IAAI,oBAAI;gCACtBsK,UAAU,CAAC1B,QACTpE,MAAM,CAACE,WAAc,aAAKA;4CAAU1E,MAAM4I,MAAMwB,MAAM,CAACrL,KAAK;;gCAE9D+J,MAAK;gCACLyB,SAAS;gCACThC,IAAI;oCAAEiC,IAAI;gCAAE;;0CAEd,KAAC9N;gCAAWuD,SAAQ;gCAAW6H,OAAM;0CAClC;;4BAQFpC,WAAWtC,MAAM,GAAG,kBACnB,KAACnH;gCAAMoN,UAAS;0CACb,CAAC,mBAAmB,EAAEnL,sBAAsB,CAAC,CAAC,GAC7C,GAAGwH,WAAWW,IAAI,CAAC,MAAM,8BAA8B,CAAC,GACxD,+DACA;iCAEF;4BACH,UAAChH,yBAAAA,MAAO+F,KAAK,oBAAI,EAAE,EAAEnG,GAAG,CAAC,CAAC4J,MAAM4B;oCAK1BpH,aAAU,kBAkDD,MAAA,mBAoCKqH;oCAnDNrL,gBAgBEgE;gCAvDf,MAAMqH,OAAO9M,qBAAqBiL,QAC9B,OACCA;gCACL,MAAMvF,aAAaoH,QACdrH,cAAAA,SAAS,EAAC,mBAAA,AAACqH,KAAaC,UAAU,YAAxB,mBAA4B,GAAG,YAAzCtH,cACDA,SAAS,CAACqH,KAAKrF,YAAY,CAAC,GAC5B;gCACJ,qBACE,KAAC3H;oCAEC;;;;;iBAKC,GACDmL,MAAMA;oCACN4B,OAAOA;oCACPpD,MAAMqD,OAAO7L,qBAAqB,AAACgK,KAAwB/D,IAAI;oCAC/D8F,OAAO9L;oCACP+L,aAAa,CAAC9L,QACXA,UAAUF,qBACP;4CAAEwG,cAAc;4CAAIC,MAAM,EAAE;4CAAEC,YAAY;wCAAG,IAC7C5H,YACEoB;oCAGRyC,SAASC;oCACTqJ,SAAS,CAACC,SACRvG,MAAM,CAACE,WAAc,aAChBA;gDACHU,OAAO2F,OACLrG,SAASU,KAAK;;oCAIpB,8DAA8D;oCAC9D,mDAAmD;oCACnD4F,cAAc;wCACZpC,KAAK,EAAEvJ,0BAAAA,iBAAAA,MAAOoG,OAAO,qBAAdpG,eAAgBuJ,KAAK;wCAC5BqC,WAAWtM,kBAAkBU,yBAAAA,MAAO+F,KAAK,EAAsBqF;oCACjE;oCACAlE,QACEmE,qBACE,MAAClO;wCACC8L,WAAU;wCACVD,SAAS;wCACTE,IAAI;4CAAEC,YAAY;4CAAUC,MAAM;4CAAGyC,UAAU;wCAAO;;0DAEtD,KAACzO;gDACCuC,OAAM;gDACN,sDAAsD;gDACtD,iDAAiD;gDACjDD,KAAK,GACH,QAAA,oBAAA,AAAC2L,KAAaC,UAAU,YAAxB,qBACCtH,+BAAAA,SAAS,CAACqH,KAAKrF,YAAY,CAAC,qBAA7B,AAAChC,6BAAsCE,GAAG,YAD1C,OAEA;gDAEF+G,UAAU,CAAC1B,QACTpE,MAAM,CAACE,WAAc,aAChBA;4DACHU,OAAOV,SAASU,KAAK,CAACnG,GAAG,CAAC,CAACkM,GAAGC;;oEAMpB5H;uEALR4H,WAAWX,QACP,aACKU;oEACHR,YAAY/B,MAAMwB,MAAM,CAACrL,KAAK;oEAC9BsG,YAAY,WACV7B,wBAAAA,gBAAgB6H,IAAI,CAClB,CAACC,SACCA,OAAO7H,EAAE,KAAKmF,MAAMwB,MAAM,CAACrL,KAAK,sBAFpCyE,sBAGGxD,IAAI,mBACP,AAACmL,EAAuB9F,YAAY;qEAExC8F;;;gDAIVrC,MAAK;gDACLyC,MAAM;gDACNhD,IAAI;oDAAEG,UAAU;oDAAKD,MAAM;gDAAE;0DAE5BjF,gBAAgBvE,GAAG,CAAC,CAACqM,uBACpB,KAAC/O;wDAAyBwC,OAAOuM,OAAO7H,EAAE;kEACvC6H,OAAOtL,IAAI;uDADCsL,OAAO7H,EAAE;;0DAK5B,KAAChH;gDACCuC,OAAM;gDACNwM,aAAa,CAAC,IAAI,EAAEf,QAAQ,GAAG;gDAC/B1L,KAAK,GAAE2L,mBAAAA,KAAKnF,UAAU,YAAfmF,mBAAmB;gDAC1BJ,UAAU,CAAC1B,QACTpE,MAAM,CAACE,WAAc,aAChBA;4DACHU,OAAOV,SAASU,KAAK,CAACnG,GAAG,CAAC,CAACkM,GAAGC,SAC5BA,WAAWX,QACP,aACKU;oEACH5F,YAAYqD,MAAMwB,MAAM,CAACrL,KAAK,CAAC0M,OAAO,CACpC,kBACA;qEAGJN;;gDAIVrC,MAAK;gDACLP,IAAI;oDAAEmD,OAAO;gDAAI;;4CAElB,UAACpI,8BAAAA,WAAYqI,UAAU,oBAAI,EAAE,EAAE1M,GAAG,CACjC,CAAC2M,WAAWC;;oDASDnB;qEART,KAACjO;oDAECuC,OAAO,GAAG4M,UAAU5L,IAAI,CAAC,WAAW,CAAC;oDACrCwL,aACEK,mBAAmB,KAAKpB,QAAQ,IAC5B,CAAC,IAAI,EAAEA,OAAO,GACd;oDAEN1L,KAAK,WAAE2L,aAAAA,KAAKpF,IAAI,qBAAToF,UAAW,CAACmB,eAAe,mBAAI;oDACtCvB,UAAU,CAAC1B,QACTpE,MAAM,CAACE,WAAc,aAChBA;gEACHU,OAAOV,SAASU,KAAK,CAACnG,GAAG,CAAC,CAACkM,GAAGC;wEAGtB;oEAFN,IAAIA,WAAWX,OAAO,OAAOU;oEAC7B,MAAM7F,OAAO;4EACP,UAAA,AAAC6F,EAAuB7F,IAAI,YAA5B,UAAgC,EAAE;qEACvC;oEACDA,IAAI,CAACuG,eAAe,GAAGjD,MAAMwB,MAAM,CAACrL,KAAK;oEACzC,OAAO,aAAKoM;wEAAG7F;;gEACjB;;oDAGJwD,MAAK;oDACLP,IAAI;wDAAEG,UAAU;wDAAKD,MAAM;oDAAE;mDAtBxBmD,UAAU5L,IAAI;;;yCA2BzB8L;mCAnIDrB;4BAuIX;0CACA,KAACvO;gCACC4M,MAAK;gCACLP,IAAI;oCAAEe,WAAW;gCAAa;gCAC9BP,UAAU,UAAC1J,yBAAAA,MAAO+F,KAAK,CAAChC,MAAM,oBAAI,MAAM1E;gCACxCsK,SAAS,IACPxE,MAAM,CAACE,WAAc,aAChBA;4CACHU,OAAO;mDACFV,SAASU,KAAK;gDACjB;oDAAEC,cAAc;oDAAIC,MAAM,EAAE;oDAAEC,YAAY;gDAAG;6CAC9C;;0CAIJ;;0CAEH,KAAC7I;gCAAWuD,SAAQ;gCAAW6H,OAAM;0CAClC;;0CAEH,MAACtL;gCAAM8L,WAAU;gCAAMD,SAAS;;kDAC9B,MAAC5L;wCACCuC,OAAM;wCACND,KAAK,WAAEM,0BAAAA,iBAAAA,MAAOoG,OAAO,qBAAdpG,eAAgBuJ,KAAK,oBAAI;wCAChC0B,UAAU,CAAC1B,QACTpE,MAAM,CAACE;;oDAKSA;uDALK,aAChBA;oDACHe,SAASmD,MAAMwB,MAAM,CAACrL,KAAK,GACvB;wDACE6J,OAAOA,MAAMwB,MAAM,CAACrL,KAAK;wDACzB6C,MAAM,WAAE8C,oBAAAA,SAASe,OAAO,qBAAhBf,kBAAkB9C,MAAM,mBAAI;oDACtC,IACA;;;wCAGRkH,MAAK;wCACLyC,MAAM;wCACNhD,IAAI;4CAAEG,UAAU;wCAAI;;0DAEpB,KAACnM;gDAASwC,OAAM;0DAAI;;4CACnB7D,iBAAiB+D,GAAG,CAAC,CAAC8M,0BACrB,KAACxP;oDAAyBwC,OAAOgN;8DAC9B5Q,eAAe4Q;mDADHA;;;oCAKlB1M,CAAAA,yBAAAA,MAAOoG,OAAO,kBACb,KAAChJ;wCACCuC,OAAM;wCACNwM,aAAY;wCACZ,gEAAgE;wCAChE,6DAA6D;wCAC7DxF,OAAO5B,QAAQ9I,qBAAqB+D,0BAAAA,kBAAAA,MAAOoG,OAAO,qBAAdpG,gBAAgBuC,MAAM,EAAE;4CAAEgE,QAAQ;wCAAS;wCAC/EyE,UAAU,GACR/O,wBAAAA,qBAAqB+D,0BAAAA,kBAAAA,MAAOoG,OAAO,qBAAdpG,gBAAgBuC,MAAM,EAAE;4CAAEgE,QAAQ;wCAAS,cAAhEtK,wBACA;4CACE;4CACAF,qBAAqBiE,0BAAAA,kBAAAA,MAAOoG,OAAO,qBAAdpG,gBAAgBuJ,KAAK;yCAC3C,CACEhH,MAAM,CAACwC,SACPiC,IAAI,CAAC;wCAEVtH,KAAK,WAAEM,0BAAAA,kBAAAA,MAAOoG,OAAO,qBAAdpG,gBAAgBuC,MAAM,oBAAI;wCACjC0I,UAAU,CAAC1B,QACTpE,MAAM,CAACE,WAAc,aAChBA;oDACHe,SAASf,SAASe,OAAO,GACrB,aAAKf,SAASe,OAAO;wDAAE7D,QAAQgH,MAAMwB,MAAM,CAACrL,KAAK;yDACjD2F,SAASe,OAAO;;wCAGxBqD,MAAK;wCACLP,IAAI;4CAAEE,MAAM;wCAAE;yCAEd;;;0CAEN,KAAChM;gCACCuC,OAAM;gCACNqL,YAAW;gCACXtL,KAAK,WAAEM,yBAAAA,MAAOmG,WAAW,oBAAI;gCAC7B8E,UAAU,CAAC1B,QACTpE,MAAM,CAACE,WAAc,aAChBA;4CACHc,aAAaoD,MAAMwB,MAAM,CAACrL,KAAK;;gCAGnC+J,MAAK;;0CAEP,MAACtM;gCAAM8L,WAAU;gCAAMD,SAAS;gCAAGE,IAAI;oCAAEC,YAAY;gCAAS;;kDAC5D,KAACtM;wCAAO4M,MAAK;wCAAQhB,OAAM;wCAAUkB,SAASnD;kDAC3C;;kDAEH,KAACnJ;wCAAWuD,SAAQ;wCAAU6H,OAAM;kDACjC;;;;4BAGJ9D,2BACC,KAAC/H;gCACCoN,UAAUrF,WAAWgI,UAAU,CAAC,WAAW,YAAY;0CAEtDhI;iCAED;;;kCAEN,MAAC5H;;0CACC,KAACF;gCAAO8M,SAAS,IAAMjI,SAAS;0CAAQ;;0CACxC,KAAC7E;gCACC+D,SAAQ;gCACR6H,OAAM;gCACNiB,UAAU,EAAC1J,yBAAAA,MAAOW,IAAI,CAACuE,IAAI,OAAMJ;gCACjC6E,SAAS1C;0CAER;;;;;;YAINlG,8BACC,KAACA;gBACC8J,MAAM1L,oBAAoBiF,EAAE;gBAC5BnE,QAAQA;gBACRsE,OAAOA;gBACP+F,SAAS,IAAM9F,SAAS;iBAExB;0BACJ,MAAC1H;gBACCuN,MAAMtF,QAAQhF;gBACduK,SAAS,IAAMzF,WAAW;gBAC1B,kEAAkE;gBAClE0F,UAAS;gBACTC,SAAS;;kCAET,KAACvN;kCAAa,CAAC,OAAO,WAAE8C,2BAAAA,QAASY,IAAI,oBAAI,IAAI;;kCAC7C,KAAC3D;kCACE+C,wBACC,KAACnB;4BACCqB,QAAQA;4BACR6K,KAAK,EAAEhK,uBAAAA,IAAKoD,GAAG;4BACf0I,UAAU7M,QAAQmE,GAAG;4BACrB2I,YAAW;4BACXC,UAAU,GAAE/M,gBAAAA,QAAQY,IAAI,YAAZZ,gBAAgB;4BAC5B2I,QAAO;6BAEP;;kCAEN,KAAC3L;kCACC,cAAA,KAACF;4BAAO4L,OAAM;4BAAUkB,SAAS,IAAM9E,WAAW;sCAC/C;;;;;;;AAMb;AACAhF,kBAAkBkN,WAAW,GAAG;AAEhC,eAAelN,kBAAiB"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/host-workflows-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 checkQuota,\n HOST_EVENT_TYPES,\n hostEventLabel,\n hostEventPayloadHint,\n type HostFunction,\n type HostVariable,\n pluginDocsHelp,\n triggerFilterProblem,\n} from '@aglyn/aglyn'\n/*\n * The MODULE, not the barrel, for the two PURE helpers — every spec that\n * renders this card mocks `@aglyn/tenant-feature-instance` wholesale to stage\n * its Firestore hooks, and a query builder imported through that barrel\n * disappears under the mock. Neither of these is a hook.\n */\nimport {\n ceilingedWindow,\n collectionCeiling,\n} from '@aglyn/tenant-feature-instance/hooks/host-collection-queries'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\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 QuotaReadoutComponent from '@aglyn/shared-ui-jsx/components/quota-readout.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { Timestamp } from '@aglyn/shared-util-timestamp'\nimport {\n Alert,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport {\n collection,\n doc,\n getCountFromServer,\n setDoc,\n updateDoc,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n useDuplicateResource,\n useFirestore,\n useFirestoreCollection,\n useHostResourceApi,\n useUser,\n writeGuardedBySeed,\n} from '@aglyn/tenant-feature-instance'\nimport {\n AutomationStepFields,\n type AutomationStepKind,\n defaultStep,\n} from './automation-step-fields.component'\nimport {\n type AutomationWorkflow,\n isWorkflowActionStep,\n validateWorkflowSteps,\n WORKFLOW_ACTION_STEP_TYPES,\n workflowFunctionCalls,\n type WorkflowStep,\n workflowStepTypeLabel,\n} from '../engine/workflow-steps'\nimport HostRunHistoryCard from './host-run-history-card.component'\nimport {\n EDITOR_OPTION_CEILING,\n useAutomationStepPickers,\n} from './use-automation-step-pickers'\nimport { listConsoleWidgets } from '@aglyn/aglyn'\nimport {\n fetchWhereUsed,\n summarizeDependents,\n type WhereUsedResult,\n} from '@aglyn/aglyn/app-utils/where-used'\nimport {\n AUTOMATION_EDITOR_ZONE,\n HOST_AUTOMATIONS_ZONE,\n openActionHref,\n WORKFLOW_USAGE_ZONE,\n type AutomationTarget,\n} from './workflow-zones'\nimport {\n type HostWorkflowStep,\n runWorkflow,\n WORKFLOW_MAX_STEPS,\n} from '../model/workflows'\nimport {\n type HostActionStep,\n type HostActionStepType,\n stepRunsAfterWait,\n} from '../model/host-actions'\n\n/**\n * How many workflows the card reads.\n *\n * A CEILING, not a page size — see the query, which explains why this list\n * cannot be paged by the server without making the duplicate-name check lie.\n */\nconst WORKFLOW_CEILING = 100\n\n/** The \"Do\" entry for the step kind a workflow has always had: a call. */\nconst FUNCTION_CALL_KIND = 'functionCall'\n\n/**\n * What a step may be (AGL-3105).\n *\n * The function call comes first because it is what a workflow was before the\n * two engines became one, and is still what a new step is. After it comes\n * every Actions step a SERVER event can run — the client-only interactions\n * are absent, because a workflow runs where there is no page to run them on.\n */\nconst STEP_KINDS: AutomationStepKind[] = [\n { value: FUNCTION_CALL_KIND, label: 'Call a function' },\n ...WORKFLOW_ACTION_STEP_TYPES.map((value) => ({\n value,\n label: workflowStepTypeLabel(value),\n })),\n]\n\nexport interface HostWorkflowsCardProps {\n hostId: string\n /** Resolved entitlement source for quota checks (AGL-395). */\n org?: Partial<AglynOrgBilling>\n /**\n * The Actions section's address (AGL-3603). A widget in the\n * `hostAutomations` zone drafts an ACTION, which lives there; opening it\n * goes to that section with the action named. Absent, the zone's\n * `openAction` answers `false` and the widget says where the draft went.\n */\n actionsHref?: string\n}\n\ninterface WorkflowDraft extends AutomationWorkflow {\n id: string | null\n}\n\n/**\n * Workflow builder v1 (AGL-101): pipelines of host-function calls — each\n * step's argument expressions see host variables and previous step results\n * (`step1`, or a custom result name). Runs through the pure `runWorkflow`\n * evaluator; test-run panel included. Plan-gated (`workflows` flag +\n * `workflowsPerHost` cap, AGL-99); site-event triggers are v2.\n */\nexport function HostWorkflowsCard(props: HostWorkflowsCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const createHostResource = useHostResourceApi()\n const { enqueueSnackbar } = useSnackbar()\n // Duplicate (AGL-2936): the copy keeps every step and arrives disarmed —\n // its trigger is cleared — so nothing runs twice until somebody arms it.\n const duplicate = useDuplicateResource({\n hostId,\n onDuplicated: (_kind, copy) =>\n enqueueSnackbar(\n `Duplicated as “${copy.name}” — arm its trigger to run it`,\n {\n variant: 'success',\n },\n ),\n })\n const { confirm } = useConfirmationContext()\n const { org } = props\n /**\n * The shell's zone renderer, for what other plugins add to a saved workflow's\n * editor (AGL-2919); `null` outside the console shell.\n */\n const ExtensionZone = useConsoleWidgetSlot()\n const { actionsHref } = props\n /*\n * For the `hostAutomations` zone (AGL-3603): what a widget drafts is an\n * action, listed on the Actions section rather than this card, so opening\n * it goes there and asks that section's editor to open it.\n */\n const openAction = useCallback(\n (actionId: string) => {\n if (!actionsHref) return false\n window.location.assign(openActionHref(actionsHref, actionId))\n return true\n },\n [actionsHref],\n )\n const automationsZone = ExtensionZone ? (\n <ExtensionZone\n slot={HOST_AUTOMATIONS_ZONE.id}\n hostId={hostId}\n orgId={org?.$id}\n openAction={openAction}\n />\n ) : null\n\n const {\n data: workflowDocs,\n status: workflowsStatus,\n /**\n * The rows this editor is seeded from are unconfirmed by the server\n * (AGL-1358). Editing destructures a whole stored workflow into `draft`\n * and writes `{...definition}` back, so `merge: true` protects nothing.\n * `trigger` is the field that makes this more than a lost edit: it is\n * `{event, filter}` or `null` for manual-only, and nothing else on this\n * card writes it, so a cached seed can re-arm an automation the author\n * disarmed — or disarm one running on a live site — and revert every\n * step of the pipeline with it.\n */\n fromCache: workflowsFromCache,\n } = useFirestoreCollection<any>(\n /*\n * ORDERED AND CEILINGED, deliberately not paged by the query (AGL-2501) —\n * the same decision as the logic plugin's two cards, for the same reasons.\n *\n * `limit(100)` alone is answered in DOCUMENT-ID order, so the window is a\n * pseudo-random hundred that the `localeCompare` below arranges\n * alphabetically, and nothing said the list was bounded.\n *\n * `collectionCeiling` does not change WHICH hundred — document-id order is\n * what the bare cap already returned. What it changes is that the order is\n * NAMED, so the obvious next edit is caught: ordering on `name` would HIDE\n * every workflow written without one rather than mis-sorting the list, and\n * `/api/hosts/resources` validates no field for presence while\n * `IMPORTABLE_FIELDS.workflows` copies one only if the export carried it.\n *\n * The QUERY is not paged because `nameTaken` below tests the draft against\n * these rows: computed variables look their workflow up BY NAME\n * (AGL-185/AGL-261), so a duplicate silently rebinds a live binding, and a\n * uniqueness check over a ten-row page would let one through.\n */\n () =>\n collectionCeiling(\n collection(firestore, 'hosts', hostId, 'workflows'),\n WORKFLOW_CEILING,\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const { rows: readWorkflows, truncated: workflowsTruncated } =\n ceilingedWindow<any>(workflowDocs, WORKFLOW_CEILING)\n const [draft, setDraft] = useState<WorkflowDraft | null>(null)\n /**\n * The editor has been opened at least once in this session.\n *\n * A LATCH rather than `draft` itself, because the two reads below key their\n * listeners on it. Tracking the dialog would tear those subscriptions down\n * on Cancel and pay for them again on the next Edit, so a merchant working\n * through ten actions would buy the same two windows ten times — worse than\n * the mount-time read this replaces. Latched, a reader who never edits pays\n * nothing and a reader who edits pays once.\n */\n const [editorOpened, setEditorOpened] = useState(false)\n if (draft && !editorOpened) setEditorOpened(true)\n /*\n * THE EDITOR'S WORKING SET, read when the editor opens.\n *\n * Nothing outside the dialog reads either of these: the table renders a\n * workflow's stored step names, and `runWorkflow` is only reachable from the\n * test-run button inside the dialog. Mounting them unconditionally charges\n * every visitor to this page two windows to fill a select and seed a\n * scratchpad most of them never open.\n *\n * Ceilinged and ordered for the reason the workflows query above gives: a\n * bare `limit` is answered in document-id order, so the `localeCompare` on\n * the options below would arrange a pseudo-random hundred into a convincing\n * alphabet, and a function past the window could not be picked with nothing\n * saying why.\n */\n const { data: functionRead } = useFirestoreCollection<any>(\n () =>\n editorOpened\n ? collectionCeiling(\n collection(firestore, 'hosts', hostId, 'functions'),\n EDITOR_OPTION_CEILING,\n )\n : null,\n [firestore, hostId, editorOpened],\n { idField: '$id' },\n )\n // Memoised so the window keeps one identity while the rows do — the option\n // list and the two lookup maps below are all built from it.\n const { rows: functionDocs, truncated: functionsTruncated } = useMemo(\n () => ceilingedWindow<any>(functionRead, EDITOR_OPTION_CEILING),\n [functionRead],\n )\n const { data: variableRead } = useFirestoreCollection<any>(\n () =>\n editorOpened\n ? collectionCeiling(\n collection(firestore, 'hosts', hostId, 'variables'),\n EDITOR_OPTION_CEILING,\n )\n : null,\n [firestore, hostId, editorOpened],\n { idField: '$id' },\n )\n const { rows: variableDocs, truncated: variablesTruncated } = useMemo(\n () => ceilingedWindow<any>(variableRead, EDITOR_OPTION_CEILING),\n [variableRead],\n )\n /*\n * What an ACTIONS step can be pointed at, on the same latch (AGL-3105).\n *\n * The hook the Actions builder uses, because a workflow step may be any\n * server-side Actions step and the two editors therefore offer one set of\n * records. Read on the editor's first open, like the two windows above, so\n * a reader who never edits a workflow still pays nothing for them.\n */\n const { pickers: stepPickers, truncated: truncatedPickers } =\n useAutomationStepPickers(hostId, editorOpened)\n // Sorting is safe here in a way it is not on a paged list: these rows are\n // the whole collection below the ceiling, not a slice of one.\n const workflows = useMemo(\n () =>\n readWorkflows\n .filter((workflow: any) => !workflow.deletedAt)\n .sort((a: any, b: any) =>\n String(a.name ?? '').localeCompare(String(b.name ?? '')),\n ),\n [readWorkflows],\n )\n // The page is a SLICE: the rows are already in hand and `nameTaken` needs\n // all of them.\n const [page, setPage] = useState(0)\n const [pageSize, setPageSize] = useState(TABLE_PAGE_SIZE_DEFAULT)\n const visibleWorkflows = useMemo(\n () => workflows.slice(page * pageSize, page * pageSize + pageSize),\n [workflows, page, pageSize],\n )\n /**\n * The workflow HEAD-COUNT is a server aggregate, not the length of the\n * capped listener (AGL-1716, the AGL-1706 shape).\n *\n * The listener is `limit(100)` and `workflows.length` fed\n * `checkQuota(org, 'workflowsPerHost', …)`, whose bands are 0 / 3 / 25 /\n * 100 / 250 / 500. The window TIES Business's 100 and hides Scale's 250\n * and Advanced's 500, so on those plans the gate compared 100 against\n * hundreds and could never refuse — while `api/hosts/resources` counted\n * the collection and did. The card offered headroom that did not exist and\n * then failed the create.\n *\n * UNFILTERED, matching that route's plain `collection('workflows').count()`\n * — its `softDeletes` branch governs only the flat per-host webhook cap, so\n * soft-deleted workflows have always counted server-side while this card\n * excluded them. Only a create moves the number, so that is where it is\n * re-read.\n */\n const [workflowCountEpoch, setWorkflowCountEpoch] = useState(0)\n const [serverWorkflowCount, setServerWorkflowCount] = useState<number | null>(\n null,\n )\n useEffect(() => {\n let active = true\n void getCountFromServer(collection(firestore, 'hosts', hostId, 'workflows'))\n .then((snapshot) => {\n if (active) setServerWorkflowCount(snapshot.data().count)\n })\n .catch(() => {\n // Falls back to the loaded rows — a LOWER bound and the prior\n // behaviour, never 0, which `checkQuota` would answer as \"no usage\"\n // on a site that is over its band.\n })\n return () => {\n active = false\n }\n }, [firestore, hostId, workflowCountEpoch])\n const workflowCount = serverWorkflowCount ?? workflows.length\n // Double-keyed by doc id and name (AGL-261): id references are\n // rename-safe; legacy name references keep resolving.\n const functions = useMemo(() => {\n const map: Record<string, HostFunction> = {}\n for (const definition of functionDocs ?? []) {\n if (definition.deletedAt) continue\n if (definition.$id) map[definition.$id] = definition\n if (definition.name) map[definition.name] = definition\n }\n return map\n }, [functionDocs])\n const functionOptions = useMemo(\n () =>\n (functionDocs ?? [])\n .filter((definition: any) => !definition.deletedAt && definition.name)\n .map((definition: any) => ({\n id: definition.$id as string,\n name: definition.name as string,\n }))\n .sort((a, b) => a.name.localeCompare(b.name)),\n [functionDocs],\n )\n const variables = useMemo(() => {\n const map: Record<string, HostVariable> = {}\n for (const variable of variableDocs ?? []) {\n if (!variable.deletedAt && variable.name) map[variable.name] = variable\n }\n return map\n }, [variableDocs])\n\n // Where-used dialog (AGL-193).\n const [usage, setUsage] = useState<{\n name: string\n result: WhereUsedResult\n } | null>(null)\n const [usageLoading, setUsageLoading] = useState<string | null>(null)\n\n const [testResult, setTestResult] = useState<string | null>(null)\n const [runsFor, setRunsFor] = useState<any | null>(null)\n\n // Case-insensitive uniqueness (AGL-185): workflow names must stay\n // unambiguous for computed-variable lookups keyed by name.\n const nameTaken = Boolean(\n draft &&\n workflows.some(\n (definition: any) =>\n String(definition.name ?? '').toLowerCase() ===\n draft.name.trim().toLowerCase() && definition.$id !== draft.id,\n ),\n )\n\n const patch = useCallback(\n (updater: (previous: WorkflowDraft) => WorkflowDraft) =>\n setDraft((previous) => (previous ? updater(previous) : previous)),\n [],\n )\n\n /** The saved workflow the editor has open, as the `automationEditor` zone names it. */\n const draftId = draft?.id ?? null\n const draftName = draft?.name ?? ''\n const editorTarget = useMemo<AutomationTarget | null>(\n () => (draftId ? { type: 'workflow', id: draftId, name: draftName } : null),\n // The name the editor opened with: the zone reads the workflow as it is\n // stored, so a rename being typed does not make it a different one.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [draftId],\n )\n\n const handleAdd = useCallback(() => {\n // Feature + cap gate (AGL-99); dark-launch for plan-less workspaces.\n if (!checkEntitlement(org, 'workflows')) {\n return void enqueueSnackbar(\n 'Workflows require a Starter plan — see Billing to upgrade',\n { variant: 'warning', persist: false },\n )\n }\n // The site's workflows, not this page of them (AGL-1716).\n const quota = checkQuota(org, 'workflowsPerHost', workflowCount)\n if (!quota.allowed) {\n return void enqueueSnackbar(\n `Workflow limit reached (${quota.limit}) — upgrade in Billing`,\n { variant: 'warning', persist: false },\n )\n }\n setTestResult(null)\n setDraft({\n id: null,\n name: '',\n steps: [{ functionName: '', args: [], resultName: '' }],\n returnValue: '',\n trigger: null,\n })\n }, [org, workflowCount, enqueueSnackbar])\n\n /**\n * Every list the ceiling cut, named — the editor's two and the step\n * pickers' six, in one notice for the reason the Actions builder gives:\n * they are one read, and an author told the function list is short learns\n * nothing from being told again about datasets.\n */\n const shortLists = useMemo(\n () =>\n [\n functionsTruncated ? 'functions' : null,\n variablesTruncated ? 'variables' : null,\n ...truncatedPickers,\n ].filter((name): name is string => name !== null),\n [functionsTruncated, variablesTruncated, truncatedPickers],\n )\n\n /**\n * The first thing wrong with the steps, said the way the editors say it.\n *\n * The same check the engine makes of what it is handed: an Actions step is\n * held to the Actions validator, a call has to name a function, and a step\n * only a visitor's browser can run is refused. Said while the author is\n * still in the dialog rather than after a save that stores a step nothing\n * can run.\n */\n const stepProblem = useMemo(\n () =>\n draft\n ? // A filter the evaluator can never run saves fine and never fires\n // (AGL-3458), so it is refused with the steps.\n (triggerFilterProblem(draft.trigger?.filter, { remedy: 'action' }) ?? validateWorkflowSteps(draft.steps))\n : null,\n [draft],\n )\n\n const handleTestRun = useCallback(() => {\n if (!draft) return\n /*\n * The FUNCTION CALLS, evaluated. A test run is the pure evaluator, and\n * an Actions step is not something to evaluate — it sends, writes and\n * charges. Running one here would perform it against the live site from\n * a button labelled \"Test run\", so the calls are evaluated, each keeping\n * the result name it holds among all the steps, and the rest is left to\n * the run itself.\n */\n const run = runWorkflow(workflowFunctionCalls(draft), functions, variables)\n setTestResult(\n run.ok === false\n ? `Error: ${run.error}`\n : `Result: ${String(run.value)} (${Object.entries(run.results)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ')})`,\n )\n }, [draft, functions, variables])\n\n const handleSave = useCallback(async () => {\n if (!draft || !draft.name.trim() || nameTaken) return\n // The steps are checked at the door, not after the write: a stored step\n // nothing can run is a run that fails on the site rather than here.\n if (stepProblem) {\n return void enqueueSnackbar(stepProblem, {\n variant: 'warning',\n persist: false,\n })\n }\n const { id: draftId, ...definition } = draft\n const fields = { ...definition, name: draft.name.trim().slice(0, 60) }\n try {\n if (draftId) {\n /**\n * Edit stays client-direct (no quota consumed) — and is refused when\n * its seed was never confirmed by the server (AGL-1358). `fields` is\n * the whole definition spread out of the listener row, `trigger` and\n * `steps` included, so `merge: true` has nothing left to protect.\n *\n * The guard WRAPS the write. An early return is a shape you can keep\n * while losing the protection; here the write is only reachable\n * through the verdict.\n */\n const verdict = await writeGuardedBySeed(\n {\n subject: 'workflow',\n unreadable: workflowsStatus === 'error',\n fromCache: workflowsFromCache,\n },\n async () => {\n await setDoc(\n doc(firestore, 'hosts', hostId, 'workflows', draftId),\n { ...fields, updatedAt: Timestamp.now() },\n { merge: true },\n )\n },\n )\n // Before `setDraft(null)`, so a refusal keeps the dialog open with\n // every step that was built and its test run still on screen.\n if (!verdict.ok) {\n return void enqueueSnackbar(verdict.message, {\n variant: 'warning',\n persist: false,\n })\n }\n } else {\n // New workflow rides the quota-enforcing resources API (AGL-473) —\n // it also re-checks the `workflows` entitlement server-side.\n await createHostResource({ hostId, resource: 'workflow', data: fields })\n // A create moves the count; the one-shot aggregate below does not\n // refresh itself the way the listener refreshes the rows.\n setWorkflowCountEpoch((epoch) => epoch + 1)\n }\n setDraft(null)\n enqueueSnackbar('Workflow saved', { variant: 'success', persist: false })\n } catch (error: any) {\n console.error(error)\n enqueueSnackbar(error?.message ?? 'An error has occurred', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n }, [\n draft,\n nameTaken,\n stepProblem,\n firestore,\n hostId,\n createHostResource,\n enqueueSnackbar,\n workflowsStatus,\n workflowsFromCache,\n ])\n\n const handleShowUsage = useCallback(\n (workflow: any) => async () => {\n setUsageLoading(workflow.$id)\n const result = await fetchWhereUsed(user as any, {\n hostId,\n kind: 'workflow',\n id: workflow.$id,\n name: workflow.name,\n })\n setUsageLoading(null)\n // The rows and their deep links are drawn in a zone; with nothing\n // registered there the answer is still given, in words.\n if (listConsoleWidgets(WORKFLOW_USAGE_ZONE.id).length === 0) {\n enqueueSnackbar(\n result.total\n ? `\"${workflow.name}\" computes ${summarizeDependents(result)}`\n : `\"${workflow.name}\" is not referenced by anything published`,\n { variant: 'info', persist: false },\n )\n return\n }\n setUsage({ name: workflow.name, result })\n },\n [user, hostId, enqueueSnackbar],\n )\n\n const handleDelete = useCallback(\n (workflow: any) => async () => {\n // Dependents warning (AGL-187): computed variables backed by this\n // workflow keep their stored fallback value once it is gone.\n const scan = await fetchWhereUsed(user as any, {\n hostId,\n kind: 'workflow',\n id: workflow.$id,\n name: workflow.name,\n })\n const confirmed = await confirm({\n title: 'Delete this workflow?',\n description: scan.total\n ? `\"${workflow.name}\" computes ${summarizeDependents(scan)} — ` +\n 'those variables will fall back to their stored values.'\n : `\"${workflow.name}\" will no longer be runnable.`,\n confirmationText: 'Delete',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await updateDoc(\n doc(firestore, 'hosts', hostId, 'workflows', workflow.$id),\n { deletedAt: Timestamp.now() },\n )\n enqueueSnackbar('Workflow deleted', {\n variant: 'success',\n persist: false,\n })\n },\n [user, confirm, firestore, hostId, enqueueSnackbar],\n )\n\n return (\n <CardDisplay\n header={'Workflows'}\n help={pluginDocsHelp('buildAWorkflow', {\n anchor: '#1-open-the-workflows-page',\n })}\n // Other ways to start an automation (AGL-3603), in the header while\n // the list has rows and in the empty state while it has none.\n actions={workflows.length === 0 ? undefined : automationsZone}\n contentGutterX\n contentGutterY\n >\n {duplicate.dialog}\n <Stack spacing={1}>\n {workflows.length === 0 ? (\n <Stack spacing={1} sx={{ alignItems: 'flex-start' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Chain your functions into multi-step pipelines — each step ' +\n 'feeds the next. Site-event triggers are coming next.'}\n </Typography>\n {automationsZone}\n </Stack>\n ) : (\n visibleWorkflows.map((workflow: any) => (\n <Stack\n key={workflow.$id}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n <Stack sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {workflow.name}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {`${(workflow.steps ?? []).length} step${\n (workflow.steps ?? []).length === 1 ? '' : 's'\n }${\n workflow.trigger?.event\n ? ` · on ${hostEventLabel(workflow.trigger.event)}`\n : ''\n } · ${(workflow.steps ?? [])\n .map((step: any) => step.functionName)\n .join(' → ')}`}\n </Typography>\n </Stack>\n <Button\n size=\"small\"\n disabled={usageLoading === workflow.$id}\n onClick={handleShowUsage(workflow)}\n >\n {usageLoading === workflow.$id ? 'Scanning…' : 'Usage'}\n </Button>\n {/* Run history (wave v6): the event runner logs status +\n duration per run. */}\n <Button size=\"small\" onClick={() => setRunsFor(workflow)}>\n {'Runs'}\n </Button>\n <Button\n size=\"small\"\n onClick={() => {\n setTestResult(null)\n setDraft({\n id: workflow.$id,\n name: workflow.name ?? '',\n steps: workflow.steps ?? [],\n returnValue: workflow.returnValue ?? '',\n trigger: workflow.trigger ?? null,\n })\n }}\n >\n {'Edit'}\n </Button>\n <Button\n size=\"small\"\n onClick={() =>\n duplicate.request('workflow', {\n id: workflow.$id,\n name: workflow.name ?? '',\n })\n }\n >\n {'Duplicate…'}\n </Button>\n <Button\n size=\"small\"\n color=\"error\"\n onClick={handleDelete(workflow)}\n >\n {'Delete'}\n </Button>\n </Stack>\n ))\n )}\n {workflows.length === 0 ? null : (\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={visibleWorkflows.length}\n // The workflows the card HOLDS. Not `workflowCount`, which is the\n // site's total including soft-deleted rows and answers the quota's\n // question rather than the reader's.\n count={workflows.length}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n )}\n {workflowsTruncated ? (\n <Alert severity=\"info\">\n {`Showing ${WORKFLOW_CEILING} workflows, ordered by id. This site ` +\n 'has more — the duplicate-name check below only covers the ' +\n 'ones listed here, so a name may already be taken by one that ' +\n 'is not.'}\n </Alert>\n ) : null}\n <Button\n size=\"small\"\n color=\"primary\"\n sx={{ alignSelf: 'flex-start' }}\n onClick={handleAdd}\n >\n {'Add workflow'}\n </Button>\n {/* The cap, standing rather than only on refusal (AGL-2113).\n `workflowCount` is the server aggregate the gate uses, not\n `workflows.length` — the listener is `limit(100)` and its length\n saturates (AGL-1716). */}\n <QuotaReadoutComponent\n ready={org != null}\n used={workflowCount}\n limit={checkQuota(org, 'workflowsPerHost', workflowCount).limit}\n noun=\"workflow\"\n />\n </Stack>\n\n <Dialog\n open={Boolean(draft)}\n onClose={() => setDraft(null)}\n maxWidth=\"sm\"\n fullWidth\n >\n <DialogTitle>\n {draft?.id ? 'Edit Workflow' : 'Add Workflow'}\n </DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, pt: 1 }}\n >\n {ExtensionZone && editorTarget ? (\n <ExtensionZone\n slot={AUTOMATION_EDITOR_ZONE.id}\n hostId={hostId}\n orgId={org?.$id}\n target={editorTarget}\n />\n ) : null}\n <TextField\n label=\"Name\"\n helperText={\n nameTaken\n ? 'A workflow with this name already exists'\n : 'Used to identify the workflow'\n }\n error={nameTaken}\n value={draft?.name ?? ''}\n onChange={(event) =>\n patch((previous) => ({ ...previous, name: event.target.value }))\n }\n size=\"small\"\n autoFocus\n sx={{ mt: 1 }}\n />\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Steps'}\n </Typography>\n {/*\n The pickers and the test run speak only for what was read. A step\n calling a function past the ceiling still RUNS on the site — this\n editor simply cannot name it, and a test run resolves its\n expression against an incomplete variable set.\n */}\n {shortLists.length > 0 ? (\n <Alert severity=\"info\">\n {`Offering the first ${EDITOR_OPTION_CEILING} ` +\n `${shortLists.join(', ')} on this site, ordered by id. ` +\n 'There are more, so the pickers below are short and a test ' +\n 'run may not resolve every expression.'}\n </Alert>\n ) : null}\n {(draft?.steps ?? []).map((step, index) => {\n const call = isWorkflowActionStep(step)\n ? null\n : (step as HostWorkflowStep)\n const definition = call\n ? (functions[(call as any).functionId ?? ''] ??\n functions[call.functionName])\n : null\n return (\n <AutomationStepFields\n key={index}\n /*\n * The editor speaks the Actions vocabulary. A function call\n * has no Actions type, so it takes none of those fields and\n * renders its own through `fields` instead — which is what\n * keeps this one editor rather than two.\n */\n step={step as HostActionStep}\n index={index}\n kind={call ? FUNCTION_CALL_KIND : (step as HostActionStep).type}\n kinds={STEP_KINDS}\n stepForKind={(value) =>\n (value === FUNCTION_CALL_KIND\n ? { functionName: '', args: [], resultName: '' }\n : defaultStep(\n value as HostActionStepType,\n )) as HostActionStep\n }\n pickers={stepPickers}\n onSteps={(update) =>\n patch((previous) => ({\n ...previous,\n steps: update(\n previous.steps as HostActionStep[],\n ) as WorkflowStep[],\n }))\n }\n // A workflow with no trigger runs from another automation, so\n // its email step is a reply only on its own event.\n replyContext={{\n event: draft?.trigger?.event,\n afterWait: stepRunsAfterWait(draft?.steps as HostActionStep[], index),\n }}\n fields={\n call ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flex: 1, flexWrap: 'wrap' }}\n >\n <TextField\n label=\"Function\"\n // Stored by id (AGL-261); legacy steps carry only the\n // name and resolve through the double-keyed map.\n value={\n (call as any).functionId ??\n (functions[call.functionName] as any)?.$id ??\n ''\n }\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n steps: previous.steps.map((s, index2) =>\n index2 === index\n ? {\n ...s,\n functionId: event.target.value,\n functionName:\n functionOptions.find(\n (option) =>\n option.id === event.target.value,\n )?.name ??\n (s as HostWorkflowStep).functionName,\n }\n : s,\n ),\n }))\n }\n size=\"small\"\n select\n sx={{ minWidth: 160, flex: 1 }}\n >\n {functionOptions.map((option) => (\n <MenuItem key={option.id} value={option.id}>\n {option.name}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n label=\"Result name\"\n placeholder={`step${index + 1}`}\n value={call.resultName ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n steps: previous.steps.map((s, index2) =>\n index2 === index\n ? {\n ...s,\n resultName: event.target.value.replace(\n /[^a-zA-Z0-9_]/g,\n '',\n ),\n }\n : s,\n ),\n }))\n }\n size=\"small\"\n sx={{ width: 140 }}\n />\n {(definition?.parameters ?? []).map(\n (parameter, parameterIndex) => (\n <TextField\n key={parameter.name}\n label={`${parameter.name} expression`}\n placeholder={\n parameterIndex === 0 && index > 0\n ? `step${index}`\n : 'a variable, number, or expression'\n }\n value={call.args?.[parameterIndex] ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n steps: previous.steps.map((s, index2) => {\n if (index2 !== index) return s\n const args = [\n ...((s as HostWorkflowStep).args ?? []),\n ]\n args[parameterIndex] = event.target.value\n return { ...s, args }\n }),\n }))\n }\n size=\"small\"\n sx={{ minWidth: 180, flex: 1 }}\n />\n ),\n )}\n </Stack>\n ) : undefined\n }\n />\n )\n })}\n <Button\n size=\"small\"\n sx={{ alignSelf: 'flex-start' }}\n disabled={(draft?.steps.length ?? 0) >= WORKFLOW_MAX_STEPS}\n onClick={() =>\n patch((previous) => ({\n ...previous,\n steps: [\n ...previous.steps,\n { functionName: '', args: [], resultName: '' },\n ],\n }))\n }\n >\n {'Add step'}\n </Button>\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Trigger'}\n </Typography>\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Run on event\"\n value={draft?.trigger?.event ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n trigger: event.target.value\n ? {\n event: event.target.value as any,\n filter: previous.trigger?.filter ?? '',\n }\n : null,\n }))\n }\n size=\"small\"\n select\n sx={{ minWidth: 180 }}\n >\n <MenuItem value=\"\">{'Manual only'}</MenuItem>\n {HOST_EVENT_TYPES.map((eventType) => (\n <MenuItem key={eventType} value={eventType}>\n {hostEventLabel(eventType)}\n </MenuItem>\n ))}\n </TextField>\n {draft?.trigger ? (\n <TextField\n label=\"Filter (optional)\"\n placeholder=\"subscribe\"\n // The evaluator is arithmetic and has no comparison (AGL-3458):\n // `path == \"/pricing\"` throws on every event and never runs.\n error={Boolean(triggerFilterProblem(draft?.trigger?.filter, { remedy: 'action' }))}\n helperText={\n triggerFilterProblem(draft?.trigger?.filter, { remedy: 'action' }) ??\n [\n 'Runs only when this expression is truthy — a field name, or arithmetic. It cannot compare values.',\n hostEventPayloadHint(draft?.trigger?.event),\n ]\n .filter(Boolean)\n .join(' ')\n }\n value={draft?.trigger?.filter ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n trigger: previous.trigger\n ? { ...previous.trigger, filter: event.target.value }\n : previous.trigger,\n }))\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n ) : null}\n </Stack>\n <TextField\n label=\"Return value\"\n helperText=\"A step result name; defaults to the last step\"\n value={draft?.returnValue ?? ''}\n onChange={(event) =>\n patch((previous) => ({\n ...previous,\n returnValue: event.target.value,\n }))\n }\n size=\"small\"\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button size=\"small\" color=\"primary\" onClick={handleTestRun}>\n {'Test run'}\n </Button>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Uses current variable values'}\n </Typography>\n </Stack>\n {testResult ? (\n <Alert\n severity={testResult.startsWith('Error') ? 'warning' : 'success'}\n >\n {testResult}\n </Alert>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setDraft(null)}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!draft?.name.trim() || nameTaken}\n onClick={handleSave}\n >\n {'Done'}\n </Button>\n </DialogActions>\n </Dialog>\n {ExtensionZone ? (\n <ExtensionZone\n slot={WORKFLOW_USAGE_ZONE.id}\n hostId={hostId}\n usage={usage}\n onClose={() => setUsage(null)}\n />\n ) : null}\n <Dialog\n open={Boolean(runsFor)}\n onClose={() => setRunsFor(null)}\n // md: the history's four columns fit without the table scrolling.\n maxWidth=\"md\"\n fullWidth\n >\n <DialogTitle>{`Runs — ${runsFor?.name ?? ''}`}</DialogTitle>\n <DialogContent>\n {runsFor ? (\n <HostRunHistoryCard\n hostId={hostId}\n orgId={org?.$id}\n targetId={runsFor.$id}\n targetType=\"workflow\"\n targetName={runsFor.name ?? ''}\n header=\"Recent runs\"\n />\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button color=\"inherit\" onClick={() => setRunsFor(null)}>\n {'Close'}\n </Button>\n </DialogActions>\n </Dialog>\n </CardDisplay>\n )\n}\nHostWorkflowsCard.displayName = 'HostWorkflowsCard'\n\nexport default HostWorkflowsCard\n"],"names":["checkEntitlement","checkQuota","HOST_EVENT_TYPES","hostEventLabel","hostEventPayloadHint","pluginDocsHelp","triggerFilterProblem","ceilingedWindow","collectionCeiling","useConsoleWidgetSlot","CardDisplay","useConfirmationContext","ListPagination","TABLE_PAGE_SIZE_DEFAULT","QuotaReadoutComponent","useSnackbar","Timestamp","Alert","Button","Dialog","DialogActions","DialogContent","DialogTitle","MenuItem","Stack","TextField","Typography","collection","doc","getCountFromServer","setDoc","updateDoc","useCallback","useEffect","useMemo","useState","useDuplicateResource","useFirestore","useFirestoreCollection","useHostResourceApi","useUser","writeGuardedBySeed","AutomationStepFields","defaultStep","isWorkflowActionStep","validateWorkflowSteps","WORKFLOW_ACTION_STEP_TYPES","workflowFunctionCalls","workflowStepTypeLabel","HostRunHistoryCard","EDITOR_OPTION_CEILING","useAutomationStepPickers","listConsoleWidgets","fetchWhereUsed","summarizeDependents","AUTOMATION_EDITOR_ZONE","HOST_AUTOMATIONS_ZONE","openActionHref","WORKFLOW_USAGE_ZONE","runWorkflow","WORKFLOW_MAX_STEPS","stepRunsAfterWait","WORKFLOW_CEILING","FUNCTION_CALL_KIND","STEP_KINDS","value","label","map","HostWorkflowsCard","props","runsFor","draft","hostId","firestore","data","user","createHostResource","enqueueSnackbar","duplicate","onDuplicated","_kind","copy","name","variant","confirm","org","ExtensionZone","actionsHref","openAction","actionId","window","location","assign","automationsZone","slot","id","orgId","$id","workflowDocs","status","workflowsStatus","fromCache","workflowsFromCache","idField","rows","readWorkflows","truncated","workflowsTruncated","setDraft","editorOpened","setEditorOpened","functionRead","functionDocs","functionsTruncated","variableRead","variableDocs","variablesTruncated","pickers","stepPickers","truncatedPickers","workflows","filter","workflow","deletedAt","sort","a","b","String","localeCompare","page","setPage","pageSize","setPageSize","visibleWorkflows","slice","workflowCountEpoch","setWorkflowCountEpoch","serverWorkflowCount","setServerWorkflowCount","active","then","snapshot","count","catch","workflowCount","length","functions","definition","functionOptions","variables","variable","usage","setUsage","usageLoading","setUsageLoading","testResult","setTestResult","setRunsFor","nameTaken","Boolean","some","toLowerCase","trim","patch","updater","previous","draftId","draftName","editorTarget","type","handleAdd","persist","quota","allowed","limit","steps","functionName","args","resultName","returnValue","trigger","shortLists","stepProblem","remedy","handleTestRun","run","ok","error","Object","entries","results","key","join","handleSave","fields","verdict","subject","unreadable","updatedAt","now","merge","message","resource","epoch","console","allowDuplicate","handleShowUsage","result","kind","total","handleDelete","scan","confirmed","title","description","confirmationText","confirmationButtonProps","color","header","help","anchor","actions","undefined","contentGutterX","contentGutterY","dialog","spacing","sx","alignItems","direction","flex","minWidth","noWrap","event","step","size","disabled","onClick","request","rowCount","onPageChange","onPageSizeChange","severity","alignSelf","ready","used","noun","open","onClose","maxWidth","fullWidth","display","flexDirection","gap","pt","target","helperText","onChange","autoFocus","mt","index","call","functionId","kinds","stepForKind","onSteps","update","replyContext","afterWait","flexWrap","s","index2","find","option","select","placeholder","replace","width","parameters","parameter","parameterIndex","eventType","startsWith","targetId","targetType","targetName","displayName"],"mappings":"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"}
@@ -3,6 +3,7 @@ import { type OrgAutomationRow, type OrgAutomationTriggerEvent } from '../model/
3
3
  import { type ConditionRowDraft } from './automation-trigger-conditions.component';
4
4
  import { type WorkflowsOrgMount } from './workflows-org-mount';
5
5
  import { type HostActionStep } from '../model/host-actions';
6
+ import type { OrgAutomationProposal } from './workflow-zones';
6
7
  /** An org automation as the editor holds it. */
7
8
  export interface OrgAutomationDraft {
8
9
  /** The stored document's id, or null for a new one. */
@@ -22,6 +23,14 @@ export interface OrgAutomationDraft {
22
23
  export declare function newOrgAutomationDraft(): OrgAutomationDraft;
23
24
  /** A stored org automation as the editor opens it. */
24
25
  export declare function orgAutomationDraft(row: OrgAutomationRow): OrgAutomationDraft;
26
+ /**
27
+ * An automation another plugin proposed (AGL-3603) as the editor opens it:
28
+ * NEW, switched off and placed on every site until the person chooses, or
29
+ * `null` when its trigger or a step is not one an org automation may hold.
30
+ * Nothing is stored; the editor's Save is the write, through the route's
31
+ * own reader.
32
+ */
33
+ export declare function orgAutomationDraftFromProposal(proposal: OrgAutomationProposal): OrgAutomationDraft | null;
25
34
  /** The placement a draft stores, as scope tokens. */
26
35
  export declare function draftPlacement(draft: OrgAutomationDraft): string[];
27
36
  /** The body `automations/manage` reads, from a draft. */
@@ -20,7 +20,7 @@ import { ACTION_MAX_STEPS, hostEventLabel, hostEventPayloadHint, triggerFilterPr
20
20
  import { hostIdsFromScope, hostScopeToken, isOrgWideScope, MAX_SCOPE_HOSTS, ORG_SCOPE_TOKEN } from "@aglyn/aglyn/app-utils/scope-tokens";
21
21
  import { Alert, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogTitle, FormControlLabel, FormGroup, MenuItem, Radio, RadioGroup, Stack, Switch, TextField, Typography } from "@mui/material";
22
22
  import { useMemo } from "react";
23
- import { isOrgAutomationTriggerEvent, ORG_AUTOMATION_STEP_KINDS, ORG_AUTOMATION_TRIGGER_EVENTS } from "../model/org-automations.js";
23
+ import { isOrgAutomationStepType, isOrgAutomationTriggerEvent, ORG_AUTOMATION_STEP_KINDS, ORG_AUTOMATION_TRIGGER_EVENTS } from "../model/org-automations.js";
24
24
  import { AutomationStepFields, defaultStep } from "./automation-step-fields.component.js";
25
25
  import { conditionRowsFromTrigger, conditionsFromRows, EMPTY_CONDITION_ROW, TriggerConditionRows } from "./automation-trigger-conditions.component.js";
26
26
  import { EDITOR_OPTION_CEILING } from "./use-automation-step-pickers.js";
@@ -64,6 +64,37 @@ import { stepRunsAfterWait } from "../model/host-actions.js";
64
64
  siteIds: hostIdsFromScope(row.visibleTo)
65
65
  };
66
66
  }
67
+ /**
68
+ * An automation another plugin proposed (AGL-3603) as the editor opens it:
69
+ * NEW, switched off and placed on every site until the person chooses, or
70
+ * `null` when its trigger or a step is not one an org automation may hold.
71
+ * Nothing is stored; the editor's Save is the write, through the route's
72
+ * own reader.
73
+ */ export function orgAutomationDraftFromProposal(proposal) {
74
+ var _proposal_steps, _proposal_name, _proposal_trigger_conditions;
75
+ var _proposal_trigger;
76
+ const event = (_proposal_trigger = proposal.trigger) == null ? void 0 : _proposal_trigger.event;
77
+ if (!isOrgAutomationTriggerEvent(event)) return null;
78
+ const steps = (_proposal_steps = proposal.steps) != null ? _proposal_steps : [];
79
+ if (!steps.length || !steps.every((step)=>isOrgAutomationStepType(step == null ? void 0 : step.type))) {
80
+ return null;
81
+ }
82
+ return _extends({}, newOrgAutomationDraft(), {
83
+ name: String((_proposal_name = proposal.name) != null ? _proposal_name : ''),
84
+ event,
85
+ conditionRows: conditionRowsFromTrigger({
86
+ conditions: ((_proposal_trigger_conditions = proposal.trigger.conditions) != null ? _proposal_trigger_conditions : []).map((condition)=>_extends({
87
+ field: condition.field,
88
+ op: condition.op
89
+ }, condition.value !== undefined ? {
90
+ value: condition.value
91
+ } : {}))
92
+ }),
93
+ conditionCombinator: proposal.trigger.combinator === 'or' ? 'or' : 'and',
94
+ steps: steps.map((step)=>_extends({}, step)),
95
+ enabled: false
96
+ });
97
+ }
67
98
  /** The placement a draft stores, as scope tokens. */ export function draftPlacement(draft) {
68
99
  return draft.placement === 'org' ? [
69
100
  ORG_SCOPE_TOKEN
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/org-automation-editor.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 ACTION_MAX_STEPS,\n hostEventLabel,\n hostEventPayloadHint,\n type TriggerCombinator,\n triggerFilterProblem,\n} from '@aglyn/aglyn'\nimport {\n hostIdsFromScope,\n hostScopeToken,\n isOrgWideScope,\n MAX_SCOPE_HOSTS,\n ORG_SCOPE_TOKEN,\n} from '@aglyn/aglyn/app-utils/scope-tokens'\nimport {\n Alert,\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n MenuItem,\n Radio,\n RadioGroup,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useMemo } from 'react'\nimport {\n isOrgAutomationTriggerEvent,\n ORG_AUTOMATION_STEP_KINDS,\n ORG_AUTOMATION_TRIGGER_EVENTS,\n type OrgAutomationRow,\n type OrgAutomationTriggerEvent,\n} from '../model/org-automations'\nimport {\n AutomationStepFields,\n defaultStep,\n} from './automation-step-fields.component'\nimport {\n conditionRowsFromTrigger,\n conditionsFromRows,\n type ConditionRowDraft,\n EMPTY_CONDITION_ROW,\n TriggerConditionRows,\n} from './automation-trigger-conditions.component'\nimport { EDITOR_OPTION_CEILING } from './use-automation-step-pickers'\nimport { useOrgAutomationStepPickers } from './use-org-automation-step-pickers'\nimport { orgSiteOptions, type WorkflowsOrgMount } from './workflows-org-mount'\nimport {\n type HostActionStep,\n type HostActionStepType,\n stepRunsAfterWait,\n} from '../model/host-actions'\n\n/** An org automation as the editor holds it. */\nexport interface OrgAutomationDraft {\n /** The stored document's id, or null for a new one. */\n id: string | null\n name: string\n event: OrgAutomationTriggerEvent\n filter: string\n conditionRows: ConditionRowDraft[]\n conditionCombinator: TriggerCombinator\n steps: HostActionStep[]\n enabled: boolean\n /** `org` runs on every site; `sites` on the ones in `siteIds`. */\n placement: 'org' | 'sites'\n siteIds: string[]\n}\n\n/** A blank draft: every site, one email step, switched on. */\nexport function newOrgAutomationDraft(): OrgAutomationDraft {\n return {\n id: null,\n name: '',\n event: 'formSubmission',\n filter: '',\n conditionRows: [EMPTY_CONDITION_ROW],\n conditionCombinator: 'and',\n steps: [defaultStep('sendEmail')],\n enabled: true,\n placement: 'org',\n siteIds: [],\n }\n}\n\n/** A stored org automation as the editor opens it. */\nexport function orgAutomationDraft(row: OrgAutomationRow): OrgAutomationDraft {\n const event = isOrgAutomationTriggerEvent(row.trigger?.event)\n ? row.trigger.event\n : 'formSubmission'\n return {\n id: row.$id,\n name: row.name ?? '',\n event,\n filter: row.trigger?.filter ?? '',\n conditionRows: conditionRowsFromTrigger(row.trigger),\n conditionCombinator: row.trigger?.combinator === 'or' ? 'or' : 'and',\n steps: [...(row.steps ?? [])],\n enabled: row.enabled !== false,\n placement: isOrgWideScope(row.visibleTo) ? 'org' : 'sites',\n siteIds: hostIdsFromScope(row.visibleTo),\n }\n}\n\n/** The placement a draft stores, as scope tokens. */\nexport function draftPlacement(draft: OrgAutomationDraft): string[] {\n return draft.placement === 'org'\n ? [ORG_SCOPE_TOKEN]\n : draft.siteIds.map(hostScopeToken)\n}\n\n/** The body `automations/manage` reads, from a draft. */\nexport function orgAutomationBody(\n draft: OrgAutomationDraft,\n): Record<string, unknown> {\n return {\n name: draft.name.trim(),\n trigger: {\n event: draft.event,\n ...(draft.filter.trim() ? { filter: draft.filter.trim() } : {}),\n ...conditionsFromRows(draft.conditionRows, draft.conditionCombinator),\n },\n steps: draft.steps,\n enabled: draft.enabled,\n visibleTo: draftPlacement(draft),\n }\n}\n\nexport interface OrgAutomationEditorProps {\n mount: WorkflowsOrgMount\n /** The draft being edited, or null when the dialog is closed. */\n draft: OrgAutomationDraft | null\n onDraft: (update: (previous: OrgAutomationDraft) => OrgAutomationDraft) => void\n /** The editor has been opened at least once: the latch the pickers read on. */\n opened: boolean\n saving: boolean\n onSave: () => void\n onClose: () => void\n}\n\n/**\n * The org automation editor (AGL-3302): a name, a trigger an org automation\n * can start on, the conditions, the steps from the org vocabulary, and the\n * sites it runs on.\n *\n * The same step rows and condition rows the actions builder uses, offered\n * only what an org automation may hold. Nothing is written from here: Save\n * hands the draft to `automations/manage`, which checks it again.\n */\nexport function OrgAutomationEditor(props: OrgAutomationEditorProps) {\n const { mount, draft, onDraft, opened, saving, onSave, onClose } = props\n const placement = useMemo(\n () => (draft ? draftPlacement(draft) : [ORG_SCOPE_TOKEN]),\n [draft],\n )\n const { pickers, truncated } = useOrgAutomationStepPickers(\n mount.orgId,\n opened,\n placement,\n )\n const sites = useMemo(() => orgSiteOptions(mount), [mount])\n const tooManySites = (draft?.siteIds.length ?? 0) > MAX_SCOPE_HOSTS\n return (\n <Dialog open={Boolean(draft)} onClose={onClose} maxWidth=\"md\" fullWidth>\n <DialogTitle>\n {draft?.id ? 'Edit org automation' : 'Add org automation'}\n </DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, pt: 1 }}\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Runs on every site you place it on, as that site: its email goes ' +\n 'from that site, its runs count on that site’s action runs, and ' +\n 'the site can pause it for itself.'}\n </Typography>\n {truncated.length > 0 ? (\n <Alert severity=\"info\">\n {`Offering the first ${EDITOR_OPTION_CEILING} rows, ordered by id, ` +\n `for: ${truncated.join(', ')}. The organization has more, so a ` +\n 'step target may not be listed below.'}\n </Alert>\n ) : null}\n <TextField\n label=\"Name\"\n value={draft?.name ?? ''}\n onChange={(event) =>\n onDraft((previous) => ({ ...previous, name: event.target.value }))\n }\n size=\"small\"\n autoFocus\n sx={{ mt: 1 }}\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n select\n label=\"Trigger event\"\n value={draft?.event ?? 'formSubmission'}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n event: event.target.value as OrgAutomationTriggerEvent,\n }))\n }\n size=\"small\"\n sx={{ minWidth: 200 }}\n >\n {ORG_AUTOMATION_TRIGGER_EVENTS.map((eventType) => (\n <MenuItem key={eventType} value={eventType}>\n {hostEventLabel(eventType)}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n label=\"Filter (optional)\"\n placeholder=\"subscribe\"\n // A comparison belongs in the conditions below (AGL-3458): the\n // filter's evaluator is arithmetic, and `source == \"form\"` throws\n // on every event, so it is refused here.\n error={Boolean(triggerFilterProblem(draft?.filter))}\n helperText={\n triggerFilterProblem(draft?.filter) ?? hostEventPayloadHint(draft?.event) ?? undefined\n }\n value={draft?.filter ?? ''}\n onChange={(event) =>\n onDraft((previous) => ({ ...previous, filter: event.target.value }))\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n </Stack>\n <TriggerConditionRows\n rows={draft?.conditionRows ?? []}\n combinator={draft?.conditionCombinator ?? 'and'}\n onRowsChange={(update) =>\n onDraft((previous) => ({\n ...previous,\n conditionRows: update(previous.conditionRows),\n }))\n }\n onCombinatorChange={(combinator) =>\n onDraft((previous) => ({\n ...previous,\n conditionCombinator: combinator,\n }))\n }\n />\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Runs on'}\n </Typography>\n <RadioGroup\n row\n value={draft?.placement ?? 'org'}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n placement: event.target.value === 'sites' ? 'sites' : 'org',\n }))\n }\n >\n <FormControlLabel\n value=\"org\"\n control={<Radio size=\"small\" />}\n label=\"Every site\"\n />\n <FormControlLabel\n value=\"sites\"\n control={<Radio size=\"small\" />}\n label=\"Chosen sites\"\n />\n </RadioGroup>\n {draft?.placement === 'sites' ? (\n <FormGroup aria-label=\"Sites it runs on\">\n {!mount.hostsReady ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'…'}\n </Typography>\n ) : !sites.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'This organization has no sites yet.'}\n </Typography>\n ) : (\n sites.map((site) => (\n <FormControlLabel\n key={site.value}\n control={\n <Checkbox\n size=\"small\"\n checked={draft.siteIds.includes(site.value)}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n siteIds: event.target.checked\n ? [...previous.siteIds, site.value]\n : previous.siteIds.filter((id) => id !== site.value),\n }))\n }\n />\n }\n label={site.label}\n />\n ))\n )}\n {tooManySites ? (\n <Typography variant=\"caption\" color=\"error\">\n {`Choose ${MAX_SCOPE_HOSTS} sites or fewer, or run it on every site.`}\n </Typography>\n ) : null}\n </FormGroup>\n ) : null}\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Steps (run in order)'}\n </Typography>\n {(draft?.steps ?? []).map((step, index) => (\n <AutomationStepFields\n key={index}\n step={step}\n index={index}\n kind={step.type}\n kinds={ORG_AUTOMATION_STEP_KINDS}\n stepForKind={(value) => defaultStep(value as HostActionStepType)}\n pickers={pickers}\n onSteps={(update) =>\n onDraft((previous) => ({\n ...previous,\n steps: update(previous.steps),\n }))\n }\n replyContext={{\n event: draft?.event,\n afterWait: stepRunsAfterWait(draft?.steps, index),\n }}\n />\n ))}\n <Button\n size=\"small\"\n sx={{ alignSelf: 'flex-start' }}\n disabled={(draft?.steps.length ?? 0) >= ACTION_MAX_STEPS}\n onClick={() =>\n onDraft((previous) => ({\n ...previous,\n steps: [...previous.steps, defaultStep('sendEmail')],\n }))\n }\n >\n {'Add step'}\n </Button>\n <FormControlLabel\n control={\n <Switch\n size=\"small\"\n checked={draft?.enabled !== false}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n enabled: event.target.checked,\n }))\n }\n />\n }\n label=\"Switched on\"\n />\n </DialogContent>\n <DialogActions>\n <Button color=\"inherit\" onClick={onClose}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!draft?.name.trim() || saving}\n onClick={onSave}\n >\n {saving ? 'Saving…' : 'Save org automation'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\nOrgAutomationEditor.displayName = 'OrgAutomationEditor'\n"],"names":["ACTION_MAX_STEPS","hostEventLabel","hostEventPayloadHint","triggerFilterProblem","hostIdsFromScope","hostScopeToken","isOrgWideScope","MAX_SCOPE_HOSTS","ORG_SCOPE_TOKEN","Alert","Button","Checkbox","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","MenuItem","Radio","RadioGroup","Stack","Switch","TextField","Typography","useMemo","isOrgAutomationTriggerEvent","ORG_AUTOMATION_STEP_KINDS","ORG_AUTOMATION_TRIGGER_EVENTS","AutomationStepFields","defaultStep","conditionRowsFromTrigger","conditionsFromRows","EMPTY_CONDITION_ROW","TriggerConditionRows","EDITOR_OPTION_CEILING","useOrgAutomationStepPickers","orgSiteOptions","stepRunsAfterWait","newOrgAutomationDraft","id","name","event","filter","conditionRows","conditionCombinator","steps","enabled","placement","siteIds","orgAutomationDraft","row","trigger","$id","combinator","visibleTo","draftPlacement","draft","map","orgAutomationBody","trim","OrgAutomationEditor","props","mount","onDraft","opened","saving","onSave","onClose","pickers","truncated","orgId","sites","tooManySites","length","open","Boolean","maxWidth","fullWidth","sx","display","flexDirection","gap","pt","variant","color","severity","join","label","value","onChange","previous","target","size","autoFocus","mt","direction","spacing","select","minWidth","eventType","placeholder","error","helperText","undefined","flex","rows","onRowsChange","update","onCombinatorChange","control","aria-label","hostsReady","site","checked","includes","step","index","kind","type","kinds","stepForKind","onSteps","replyContext","afterWait","alignSelf","disabled","onClick","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/org-automation-editor.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 ACTION_MAX_STEPS,\n hostEventLabel,\n hostEventPayloadHint,\n type TriggerCombinator,\n triggerFilterProblem,\n} from '@aglyn/aglyn'\nimport {\n hostIdsFromScope,\n hostScopeToken,\n isOrgWideScope,\n MAX_SCOPE_HOSTS,\n ORG_SCOPE_TOKEN,\n} from '@aglyn/aglyn/app-utils/scope-tokens'\nimport {\n Alert,\n Button,\n Checkbox,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n MenuItem,\n Radio,\n RadioGroup,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useMemo } from 'react'\nimport {\n isOrgAutomationStepType,\n isOrgAutomationTriggerEvent,\n ORG_AUTOMATION_STEP_KINDS,\n ORG_AUTOMATION_TRIGGER_EVENTS,\n type OrgAutomationRow,\n type OrgAutomationTriggerEvent,\n} from '../model/org-automations'\nimport {\n AutomationStepFields,\n defaultStep,\n} from './automation-step-fields.component'\nimport {\n conditionRowsFromTrigger,\n conditionsFromRows,\n type ConditionRowDraft,\n EMPTY_CONDITION_ROW,\n TriggerConditionRows,\n} from './automation-trigger-conditions.component'\nimport { EDITOR_OPTION_CEILING } from './use-automation-step-pickers'\nimport { useOrgAutomationStepPickers } from './use-org-automation-step-pickers'\nimport { orgSiteOptions, type WorkflowsOrgMount } from './workflows-org-mount'\nimport {\n type HostActionStep,\n type HostActionStepType,\n type HostActionTriggerCondition,\n stepRunsAfterWait,\n} from '../model/host-actions'\nimport type { OrgAutomationProposal } from './workflow-zones'\n\n/** An org automation as the editor holds it. */\nexport interface OrgAutomationDraft {\n /** The stored document's id, or null for a new one. */\n id: string | null\n name: string\n event: OrgAutomationTriggerEvent\n filter: string\n conditionRows: ConditionRowDraft[]\n conditionCombinator: TriggerCombinator\n steps: HostActionStep[]\n enabled: boolean\n /** `org` runs on every site; `sites` on the ones in `siteIds`. */\n placement: 'org' | 'sites'\n siteIds: string[]\n}\n\n/** A blank draft: every site, one email step, switched on. */\nexport function newOrgAutomationDraft(): OrgAutomationDraft {\n return {\n id: null,\n name: '',\n event: 'formSubmission',\n filter: '',\n conditionRows: [EMPTY_CONDITION_ROW],\n conditionCombinator: 'and',\n steps: [defaultStep('sendEmail')],\n enabled: true,\n placement: 'org',\n siteIds: [],\n }\n}\n\n/** A stored org automation as the editor opens it. */\nexport function orgAutomationDraft(row: OrgAutomationRow): OrgAutomationDraft {\n const event = isOrgAutomationTriggerEvent(row.trigger?.event)\n ? row.trigger.event\n : 'formSubmission'\n return {\n id: row.$id,\n name: row.name ?? '',\n event,\n filter: row.trigger?.filter ?? '',\n conditionRows: conditionRowsFromTrigger(row.trigger),\n conditionCombinator: row.trigger?.combinator === 'or' ? 'or' : 'and',\n steps: [...(row.steps ?? [])],\n enabled: row.enabled !== false,\n placement: isOrgWideScope(row.visibleTo) ? 'org' : 'sites',\n siteIds: hostIdsFromScope(row.visibleTo),\n }\n}\n\n/**\n * An automation another plugin proposed (AGL-3603) as the editor opens it:\n * NEW, switched off and placed on every site until the person chooses, or\n * `null` when its trigger or a step is not one an org automation may hold.\n * Nothing is stored; the editor's Save is the write, through the route's\n * own reader.\n */\nexport function orgAutomationDraftFromProposal(\n proposal: OrgAutomationProposal,\n): OrgAutomationDraft | null {\n const event = proposal.trigger?.event\n if (!isOrgAutomationTriggerEvent(event)) return null\n const steps = proposal.steps ?? []\n if (!steps.length || !steps.every((step) => isOrgAutomationStepType(step?.type))) {\n return null\n }\n return {\n ...newOrgAutomationDraft(),\n name: String(proposal.name ?? ''),\n event,\n conditionRows: conditionRowsFromTrigger({\n conditions: (proposal.trigger.conditions ?? []).map((condition) => ({\n field: condition.field,\n op: condition.op,\n ...(condition.value !== undefined ? { value: condition.value } : {}),\n })) as HostActionTriggerCondition[],\n }),\n conditionCombinator: proposal.trigger.combinator === 'or' ? 'or' : 'and',\n steps: steps.map((step) => ({ ...step }) as unknown as HostActionStep),\n enabled: false,\n }\n}\n\n/** The placement a draft stores, as scope tokens. */\nexport function draftPlacement(draft: OrgAutomationDraft): string[] {\n return draft.placement === 'org'\n ? [ORG_SCOPE_TOKEN]\n : draft.siteIds.map(hostScopeToken)\n}\n\n/** The body `automations/manage` reads, from a draft. */\nexport function orgAutomationBody(\n draft: OrgAutomationDraft,\n): Record<string, unknown> {\n return {\n name: draft.name.trim(),\n trigger: {\n event: draft.event,\n ...(draft.filter.trim() ? { filter: draft.filter.trim() } : {}),\n ...conditionsFromRows(draft.conditionRows, draft.conditionCombinator),\n },\n steps: draft.steps,\n enabled: draft.enabled,\n visibleTo: draftPlacement(draft),\n }\n}\n\nexport interface OrgAutomationEditorProps {\n mount: WorkflowsOrgMount\n /** The draft being edited, or null when the dialog is closed. */\n draft: OrgAutomationDraft | null\n onDraft: (update: (previous: OrgAutomationDraft) => OrgAutomationDraft) => void\n /** The editor has been opened at least once: the latch the pickers read on. */\n opened: boolean\n saving: boolean\n onSave: () => void\n onClose: () => void\n}\n\n/**\n * The org automation editor (AGL-3302): a name, a trigger an org automation\n * can start on, the conditions, the steps from the org vocabulary, and the\n * sites it runs on.\n *\n * The same step rows and condition rows the actions builder uses, offered\n * only what an org automation may hold. Nothing is written from here: Save\n * hands the draft to `automations/manage`, which checks it again.\n */\nexport function OrgAutomationEditor(props: OrgAutomationEditorProps) {\n const { mount, draft, onDraft, opened, saving, onSave, onClose } = props\n const placement = useMemo(\n () => (draft ? draftPlacement(draft) : [ORG_SCOPE_TOKEN]),\n [draft],\n )\n const { pickers, truncated } = useOrgAutomationStepPickers(\n mount.orgId,\n opened,\n placement,\n )\n const sites = useMemo(() => orgSiteOptions(mount), [mount])\n const tooManySites = (draft?.siteIds.length ?? 0) > MAX_SCOPE_HOSTS\n return (\n <Dialog open={Boolean(draft)} onClose={onClose} maxWidth=\"md\" fullWidth>\n <DialogTitle>\n {draft?.id ? 'Edit org automation' : 'Add org automation'}\n </DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 1.5, pt: 1 }}\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Runs on every site you place it on, as that site: its email goes ' +\n 'from that site, its runs count on that site’s action runs, and ' +\n 'the site can pause it for itself.'}\n </Typography>\n {truncated.length > 0 ? (\n <Alert severity=\"info\">\n {`Offering the first ${EDITOR_OPTION_CEILING} rows, ordered by id, ` +\n `for: ${truncated.join(', ')}. The organization has more, so a ` +\n 'step target may not be listed below.'}\n </Alert>\n ) : null}\n <TextField\n label=\"Name\"\n value={draft?.name ?? ''}\n onChange={(event) =>\n onDraft((previous) => ({ ...previous, name: event.target.value }))\n }\n size=\"small\"\n autoFocus\n sx={{ mt: 1 }}\n />\n <Stack direction=\"row\" spacing={1}>\n <TextField\n select\n label=\"Trigger event\"\n value={draft?.event ?? 'formSubmission'}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n event: event.target.value as OrgAutomationTriggerEvent,\n }))\n }\n size=\"small\"\n sx={{ minWidth: 200 }}\n >\n {ORG_AUTOMATION_TRIGGER_EVENTS.map((eventType) => (\n <MenuItem key={eventType} value={eventType}>\n {hostEventLabel(eventType)}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n label=\"Filter (optional)\"\n placeholder=\"subscribe\"\n // A comparison belongs in the conditions below (AGL-3458): the\n // filter's evaluator is arithmetic, and `source == \"form\"` throws\n // on every event, so it is refused here.\n error={Boolean(triggerFilterProblem(draft?.filter))}\n helperText={\n triggerFilterProblem(draft?.filter) ?? hostEventPayloadHint(draft?.event) ?? undefined\n }\n value={draft?.filter ?? ''}\n onChange={(event) =>\n onDraft((previous) => ({ ...previous, filter: event.target.value }))\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n </Stack>\n <TriggerConditionRows\n rows={draft?.conditionRows ?? []}\n combinator={draft?.conditionCombinator ?? 'and'}\n onRowsChange={(update) =>\n onDraft((previous) => ({\n ...previous,\n conditionRows: update(previous.conditionRows),\n }))\n }\n onCombinatorChange={(combinator) =>\n onDraft((previous) => ({\n ...previous,\n conditionCombinator: combinator,\n }))\n }\n />\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Runs on'}\n </Typography>\n <RadioGroup\n row\n value={draft?.placement ?? 'org'}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n placement: event.target.value === 'sites' ? 'sites' : 'org',\n }))\n }\n >\n <FormControlLabel\n value=\"org\"\n control={<Radio size=\"small\" />}\n label=\"Every site\"\n />\n <FormControlLabel\n value=\"sites\"\n control={<Radio size=\"small\" />}\n label=\"Chosen sites\"\n />\n </RadioGroup>\n {draft?.placement === 'sites' ? (\n <FormGroup aria-label=\"Sites it runs on\">\n {!mount.hostsReady ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'…'}\n </Typography>\n ) : !sites.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'This organization has no sites yet.'}\n </Typography>\n ) : (\n sites.map((site) => (\n <FormControlLabel\n key={site.value}\n control={\n <Checkbox\n size=\"small\"\n checked={draft.siteIds.includes(site.value)}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n siteIds: event.target.checked\n ? [...previous.siteIds, site.value]\n : previous.siteIds.filter((id) => id !== site.value),\n }))\n }\n />\n }\n label={site.label}\n />\n ))\n )}\n {tooManySites ? (\n <Typography variant=\"caption\" color=\"error\">\n {`Choose ${MAX_SCOPE_HOSTS} sites or fewer, or run it on every site.`}\n </Typography>\n ) : null}\n </FormGroup>\n ) : null}\n <Typography variant=\"overline\" color=\"text.secondary\">\n {'Steps (run in order)'}\n </Typography>\n {(draft?.steps ?? []).map((step, index) => (\n <AutomationStepFields\n key={index}\n step={step}\n index={index}\n kind={step.type}\n kinds={ORG_AUTOMATION_STEP_KINDS}\n stepForKind={(value) => defaultStep(value as HostActionStepType)}\n pickers={pickers}\n onSteps={(update) =>\n onDraft((previous) => ({\n ...previous,\n steps: update(previous.steps),\n }))\n }\n replyContext={{\n event: draft?.event,\n afterWait: stepRunsAfterWait(draft?.steps, index),\n }}\n />\n ))}\n <Button\n size=\"small\"\n sx={{ alignSelf: 'flex-start' }}\n disabled={(draft?.steps.length ?? 0) >= ACTION_MAX_STEPS}\n onClick={() =>\n onDraft((previous) => ({\n ...previous,\n steps: [...previous.steps, defaultStep('sendEmail')],\n }))\n }\n >\n {'Add step'}\n </Button>\n <FormControlLabel\n control={\n <Switch\n size=\"small\"\n checked={draft?.enabled !== false}\n onChange={(event) =>\n onDraft((previous) => ({\n ...previous,\n enabled: event.target.checked,\n }))\n }\n />\n }\n label=\"Switched on\"\n />\n </DialogContent>\n <DialogActions>\n <Button color=\"inherit\" onClick={onClose}>\n {'Cancel'}\n </Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!draft?.name.trim() || saving}\n onClick={onSave}\n >\n {saving ? 'Saving…' : 'Save org automation'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\nOrgAutomationEditor.displayName = 'OrgAutomationEditor'\n"],"names":["ACTION_MAX_STEPS","hostEventLabel","hostEventPayloadHint","triggerFilterProblem","hostIdsFromScope","hostScopeToken","isOrgWideScope","MAX_SCOPE_HOSTS","ORG_SCOPE_TOKEN","Alert","Button","Checkbox","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","MenuItem","Radio","RadioGroup","Stack","Switch","TextField","Typography","useMemo","isOrgAutomationStepType","isOrgAutomationTriggerEvent","ORG_AUTOMATION_STEP_KINDS","ORG_AUTOMATION_TRIGGER_EVENTS","AutomationStepFields","defaultStep","conditionRowsFromTrigger","conditionsFromRows","EMPTY_CONDITION_ROW","TriggerConditionRows","EDITOR_OPTION_CEILING","useOrgAutomationStepPickers","orgSiteOptions","stepRunsAfterWait","newOrgAutomationDraft","id","name","event","filter","conditionRows","conditionCombinator","steps","enabled","placement","siteIds","orgAutomationDraft","row","trigger","$id","combinator","visibleTo","orgAutomationDraftFromProposal","proposal","length","every","step","type","String","conditions","map","condition","field","op","value","undefined","draftPlacement","draft","orgAutomationBody","trim","OrgAutomationEditor","props","mount","onDraft","opened","saving","onSave","onClose","pickers","truncated","orgId","sites","tooManySites","open","Boolean","maxWidth","fullWidth","sx","display","flexDirection","gap","pt","variant","color","severity","join","label","onChange","previous","target","size","autoFocus","mt","direction","spacing","select","minWidth","eventType","placeholder","error","helperText","flex","rows","onRowsChange","update","onCombinatorChange","control","aria-label","hostsReady","site","checked","includes","index","kind","kinds","stepForKind","onSteps","replyContext","afterWait","alignSelf","disabled","onClick","displayName"],"mappings":"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"}