@planningcenter/core-automations 1.16.0 → 1.17.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"core-automations.modern.mjs","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/utils.ts","../../src/history.tsx","../../src/history_modal.tsx","../../src/utils/logos.ts","../../src/utils/response-labelers/people-form.ts","../../src/utils/resolve-response-details.ts","../../src/automation.tsx","../../src/utils/fetch-automations.ts","../../src/incoming_automations.tsx","../../src/definition.tsx","../../src/field.tsx","../../src/fields.tsx","../../src/new_automation.tsx","../../src/new_automation_modal.tsx","../../src/utils/theme.ts","../../src/automations.tsx"],"sourcesContent":["import React from \"react\"\n\nconst SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { cloneDeep, isBoolean, set } from \"lodash\"\nimport moment from \"moment\"\n\nexport async function deobfuscateDescriptions(\n subscriptions: AutomationInstance[]\n) {\n return Promise.all(\n subscriptions.map(async (subscription) => {\n if (isDeobfuscatable(subscription)) {\n const result = await deobfuscatedDescription(subscription)\n subscription.description = result.description\n subscription.actionResourceUrl = result.actionResourceUrl\n subscription.actionResourceName = result.actionResourceName\n }\n return subscription\n })\n )\n}\n\nfunction isDeobfuscatable(subscription: AutomationInstance) {\n const DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES = [\n \"AddToWorkflowOperationDefinition\",\n \"CustomFieldBooleanOperationDefinition\",\n \"CustomFieldCheckboxesOperationDefinition\",\n \"CustomFieldDateOperationDefinition\",\n \"CustomFieldNumberOperationDefinition\",\n \"CustomFieldSelectOperationDefinition\",\n \"CustomFieldStringOperationDefinition\",\n \"CustomFieldTextOperationDefinition\",\n ]\n \n return DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES.includes(\n subscription.operationDefinitionClassName\n )\n}\n\nasync function deobfuscatedDescription(subscription: AutomationInstance) {\n let description = \"\"\n if (\n subscription.operationDefinitionClassName ===\n \"AddToWorkflowOperationDefinition\"\n ) {\n const data = await fetchWorkflow(subscription.operationParams.workflowId!)\n const workflow = data[0]\n\n if (workflow?.name) {\n const workflowName = workflow.archivedAt\n ? `[archived] ${workflow.name}`\n : workflow.name\n\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n workflowName\n )\n return {\n description,\n actionResourceUrl: workflow.links.html,\n actionResourceName: workflowName,\n }\n }\n } else {\n // custom field\n const fieldDefinitionId =\n subscription.operationParams.definitionIdentifier.match(\n /(\\d+)_field_definition/\n )![1]\n const fieldDefinition = await fetchFieldDefinition(fieldDefinitionId)\n if (fieldDefinition.name) {\n description = subscription.description.replace(\n \"[Hidden Custom Field]\",\n fieldDefinition.name\n )\n description +=\n subscription.operationParams.values ||\n fieldDefinition.dataType !== \"checkboxes\"\n ? ` (${customFieldOptionDescription(subscription, fieldDefinition)})`\n : \"\"\n }\n }\n return { description: description || subscription.description }\n}\n\nfunction customFieldOptionDescription(\n subscription: AutomationInstance,\n fieldDefinition: {\n dataType: string\n fieldOptions: { id: number; value: string }[]\n }\n) {\n switch (fieldDefinition.dataType) {\n case \"checkboxes\":\n return Object.entries(subscription.operationParams.values ?? {})\n .map(([id, action]) => {\n const value =\n fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(id, 10)\n )?.value || \"[Hidden value]\"\n return `${capitalize(action)} ${value}`\n })\n .join(\", \")\n case \"select\": {\n const value = subscription.operationParams.value\n return value\n ? fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(value, 10)\n )?.value || \"[Hidden value]\"\n : \"Unanswered\"\n }\n case \"boolean\":\n switch (subscription.operationParams.value) {\n case \"true\":\n return \"Yes\"\n case \"false\":\n return \"No\"\n default:\n return \"Unanswered\"\n }\n default:\n return subscription.operationParams.value ?? \"Unanswered\"\n }\n}\n\nfunction capitalize(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\nasync function fetchWorkflow(workflowId: number) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: { Workflow: \"name,archived_at\" },\n where: { id: workflowId },\n },\n url: `workflows`,\n })\n .catch(() => [{ data: { name: \"\" } }])\n\n return data\n}\n\nasync function fetchFieldDefinition(fieldDefinitionId: string) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n },\n url: `field_definitions/${fieldDefinitionId}`,\n })\n .catch(() => ({ data: { name: \"\" } }))\n\n return data\n}\n\nexport function fieldListIdentifier(field: DefinitionField) {\n if (field.listClass) {\n return `${field.id}_${field.listClass}`\n } else if (field.kind === \"PersonSearch\") {\n return `${field.id}_PersonSearch`\n } else {\n return null\n }\n}\n\nexport function buildDescription({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n return {\n description: describeSelectedFields({\n loadedLists: loadedLists || {},\n selectedDefinition,\n selectedFieldOptions,\n }),\n name: buildDescriptionName(selectedDefinition),\n }\n}\n\nfunction obfuscateDescriptionName(definition: OperationDefinition) {\n if (definition.definitionClass.match(/^CustomField\\w+OperationDefinition$/)) {\n return \"Update [Hidden Custom Field]\"\n }\n}\n\nfunction buildDescriptionName(definition: OperationDefinition) {\n return obfuscateDescriptionName(definition) || definition.description\n}\n\nfunction hasOwnProperty(object: object, key: PropertyKey) {\n return Object.prototype.hasOwnProperty.call(object, key)\n}\n\nfunction getListForField({\n field,\n loadedLists,\n}: {\n field: DefinitionField\n loadedLists: { [k: string]: LoadedList[] }\n}) {\n if (field.list) {\n return field.list\n } else if (fieldListIdentifier(field)) {\n const identifier = fieldListIdentifier(field) as string\n const list = loadedLists[identifier]\n\n return list\n } else {\n throw new Error(`Don't know how to get list for ${JSON.stringify(field)}`)\n }\n}\n\nexport function buildTriggerConditions({\n baseConditions,\n dynamicConditions,\n dynamicTriggerConditions,\n}: {\n baseConditions: object\n dynamicConditions: DefinitionField[] | undefined\n dynamicTriggerConditions: SelectedFieldOptions\n}) {\n const triggerConditions = cloneDeep(baseConditions)\n const fields = dynamicConditions ?? []\n const writableFields = fields.filter((field) => {\n if (field.renderOnly) return false\n return renderIfChainSatisfied(field, fields, dynamicTriggerConditions)\n })\n\n for (const field of writableFields) {\n if (\n Object.prototype.hasOwnProperty.call(dynamicTriggerConditions, field.id)\n ) {\n set(triggerConditions, field.id, dynamicTriggerConditions[field.id])\n }\n }\n\n return triggerConditions\n}\n\nfunction shouldRender(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!Object.prototype.hasOwnProperty.call(field, \"renderIf\")) return true\n\n const renderIf = field.renderIf!\n if (isBoolean(renderIf)) return renderIf\n\n const conditionKey = Object.keys(renderIf)[0]\n return renderIf[conditionKey] === selectedFieldOptions[conditionKey]\n}\n\nfunction renderIfChainSatisfied(\n field: DefinitionField,\n allFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n): boolean {\n if (!shouldRender(field, selectedFieldOptions)) return false\n\n const renderIf = field.renderIf\n if (renderIf == null || renderIf === true) return true\n\n const upstreamId = Object.keys(renderIf)[0]\n const upstream = allFields.find((f) => f.id === upstreamId)\n if (!upstream) return true\n return renderIfChainSatisfied(upstream, allFields, selectedFieldOptions)\n}\n\nexport function getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter(\n (field) =>\n field.kind !== \"Hidden\" &&\n renderIfChainSatisfied(field, definitionFields, selectedFieldOptions)\n )\n}\n\nfunction describeSelectedFields({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n const description = selectedDefinition.definitionFields\n .map((field) => {\n if (!hasOwnProperty(selectedFieldOptions, field.id)) return null\n\n const value = selectedFieldOptions[field.id]\n let list\n\n switch (field.kind) {\n case \"Select\":\n case \"SelectSearch\":\n case \"PersonSearch\":\n case \"RadioButtons\":\n list = getListForField({ field, loadedLists })\n\n return (\n list && list.find((o) => o.value.toString() === value)?.description\n )\n case \"Checkbox\":\n return value && field.label\n case \"Checkboxes\":\n list = getListForField({ field, loadedLists })\n\n return list\n .filter((e) => hasOwnProperty(value as object, e.value))\n .map(\n (e) =>\n `${capitalize((value as Record<string, string>)[e.value])} ${\n e.description\n }`\n )\n .join(\", \")\n case \"NumberField\":\n case \"TextField\":\n case \"TextArea\":\n case \"DateField\":\n return value\n default:\n throw new Error(\n `Don't know how to build value for field with kind ${field.kind}`\n )\n }\n })\n .filter((x) => x)\n .join(\", \")\n\n return obfuscateSelectedFieldDescriptions({\n description,\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n}\n\nfunction obfuscateSelectedFieldDescriptions({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n description,\n}: {\n description: string\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n if (\n selectedDefinition.definitionClass === \"AddToWorkflowOperationDefinition\"\n ) {\n const list = loadedLists.workflow_id_WorkflowsList\n const sensitiveString =\n list &&\n list.find((o) => o.value.toString() === selectedFieldOptions.workflow_id)\n ?.description\n\n return sensitiveString\n ? description.replace(sensitiveString, \"[Hidden Workflow]\")\n : description\n } else if (\n selectedDefinition.definitionClass.match(\n /^CustomField\\w+OperationDefinition$/\n )\n ) {\n return \"\"\n } else {\n return description\n }\n}\n\nexport function dateFNSFormat(format: string) {\n return format\n .replace(/%m/, \"M\")\n .replace(/%d/, \"d\")\n .replace(/%Y/, \"y\")\n .replace(/%y/, \"yy\")\n}\n\nexport function momentDateFormat(format: string) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({\n dateFormat,\n twentyFourHourTime,\n}: {\n dateFormat: string\n twentyFourHourTime: boolean\n}) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date: string, dateFormat: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n if (!momentDate.isValid()) {\n return \"\"\n }\n\n const format = momentDateFormat(dateFormat)\n return momentDate.format(format)\n}\n\nexport function numDaysSince(date: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n return moment().diff(momentDate, \"days\")\n}\n\nexport function pluralize(count: number, word: string) {\n if (count === 1) {\n return `1 ${word}`\n } else {\n return `${count} ${word}s`\n }\n}\n\nexport function singularize(string: string) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nexport function triggerResourceParts(triggerResource: string) {\n const triggerParts = triggerResource.split(\"/\")\n\n return {\n appName: triggerParts[0],\n resourceId: triggerParts[triggerParts.length - 1],\n resourcePath: triggerParts.slice(2, -1).join(\"/\"),\n resourceType: triggerParts[triggerParts.length - 2],\n }\n}\n\nexport function forbiddenText(error: any, action?: string) {\n if (error.errors?.[0]?.status === \"403\") {\n return `You don't have permission to ${action || \"modify\"} this automation.`\n }\n return null\n}\n\nexport function parseDescription(description: string) {\n const match = /^(.+?)\\((.+)\\)$/.exec(description)\n\n if (match) {\n return { description: match[\"2\"], name: match[\"1\"].trim() }\n } else {\n return { name: description }\n }\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Badge,\n Box,\n Button,\n DataTable,\n Heading,\n Icon,\n Input,\n Link,\n Select,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport moment from \"moment-timezone\"\nimport React, { useCallback, useContext, useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n dateLocalized,\n momentDateTimeFormat,\n numDaysSince,\n parseDescription,\n} from \"./utils/utils\"\n\ndeclare global {\n interface Window {\n openHelpdesk: () => void\n }\n}\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2022-07-14\",\n})\n\n// values should match the webhooks Event `status` enum entries\nconst STATUS = {\n delivered: {\n label: \"Success\",\n value: [\"delivered\"],\n },\n failed: {\n label: \"Failed\",\n value: [\"failed\", \"duplicated\"],\n },\n ignored: {\n label: \"Ignored\",\n value: [\"ignored_duplicated\", \"ignored_failed\", \"ignored_skipped\"],\n },\n pending: {\n label: \"Pending\",\n value: [\"pending\"],\n },\n skipped: {\n label: \"Paused\",\n value: [\"skipped\"],\n },\n}\n\nasync function fetchEvents(\n triggerResource: EncryptedTriggerResource,\n automationId: number,\n params: {\n offset: number\n per_page: number\n where?: { status: string } | null\n }\n) {\n const response = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n Delivery: \"status,response_body,created_at\",\n Event: \"id,created_at,last_delivery,payload,status,uuid,person\",\n },\n include: \"last_delivery\",\n order: \"-created_at\",\n ...params,\n },\n url: `automation_subscriptions/${automationId}/events`,\n })\n\n return response\n}\n\nasync function fetchPeople(personIds) {\n const { data } = await peopleClient.get({\n data: {\n fields: {\n Person: \"id,name\",\n },\n where: { id: personIds.join(\",\") },\n },\n url: `people`,\n })\n\n return data\n}\n\nasync function fetchPeopleWhoTriggeredEvents(events) {\n const personIds = events.data.map((e) => eventPersonId(e))\n try {\n const people = await fetchPeople(personIds)\n return { events, people }\n } catch (error) {\n return { events, people: [] }\n }\n}\n\nfunction mergePeopleAndEvents({ events, people }) {\n const mergedData = events.data.reduce((result, e) => {\n const personId = eventPersonId(e)\n const foundPerson = people.find(\n (p) => personId.toString() === p.id.toString()\n )\n if (foundPerson) {\n result.push({\n ...e,\n person: { id: foundPerson.id, name: foundPerson.name },\n })\n } else {\n result.push({\n ...e,\n person: { id: personId, name: \"[Hidden]\" },\n })\n }\n return result\n }, [])\n\n return { ...events, data: mergedData }\n}\n\nfunction eventPersonId(event) {\n return event.personId\n}\n\nfunction useEvents(\n automationId: number,\n triggerResource: EncryptedTriggerResource,\n filterWhere?: string\n) {\n const perPage = 50\n const [_, setError] = useState()\n const [loading, setLoading] = useState(false)\n const [eventPages, setEventPages] = useState<{ [k: number]: EventPage[] }>({})\n const [params, setParams] = useState<{ where?: { status: string } | null }>(\n filterWhere ? { where: { status: filterWhere } } : {}\n )\n const [meta, setMeta] = useState<{ totalCount: number | any }>()\n const { offset, paginationProps, resetOffset } = usePagination(\n perPage,\n meta?.totalCount\n )\n useEffect(() => {\n if (loading || eventPages[offset]) return\n\n setLoading(true)\n\n fetchEvents(triggerResource, automationId, {\n offset,\n per_page: perPage,\n ...params,\n })\n .then(fetchPeopleWhoTriggeredEvents)\n .then(mergePeopleAndEvents)\n .then((events) => {\n setEventPages((pages) => ({ ...pages, [offset]: events.data }))\n setMeta(events.meta)\n setLoading(false)\n })\n .catch(bubbleErrorToBoundary)\n }, [automationId, triggerResource, loading, params, offset, eventPages])\n\n const refresh = useCallback(() => {\n setEventPages({})\n setMeta(undefined)\n resetOffset()\n }, [resetOffset])\n\n useEffect(() => {\n refresh()\n }, [refresh, params])\n\n function bubbleErrorToBoundary(error) {\n setError(() => {\n throw error\n })\n }\n\n return {\n events: eventPages[offset] || [],\n loading,\n paginationProps,\n params,\n refresh,\n setParams,\n }\n}\n\nfunction usePagination(perPage: number, totalCount: number) {\n const [offset, setOffset] = useState(0)\n\n const currentPage = Math.floor(offset / perPage) + 1\n const totalPages = Math.ceil(totalCount / perPage)\n const paginationProps = { currentPage, onPageChange, totalPages }\n\n function onPageChange(pageNum: number) {\n setOffset((pageNum - 1) * perPage)\n }\n\n const resetOffset = useCallback(() => {\n setOffset(0)\n }, [])\n\n return { offset, paginationProps, resetOffset }\n}\n\ntype HistoryProps = {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: HistoryProps) {\n const { events, loading, paginationProps, refresh, params, setParams } =\n useEvents(automation.id, triggerResource, filterWhere)\n const { dateFormat, olsonTimeZone, twentyFourHourTime } = useContext<{\n dateFormat: any\n olsonTimeZone: any\n twentyFourHourTime: any\n }>(OrganizationContext)\n\n const filteringEvents = params.where && Object.keys(params.where).length > 0\n const automationCreatedRecently = numDaysSince(automation.createdAt) <= 32\n const automationBeganOn = dateLocalized(automation.createdAt, dateFormat)\n const historyPreservationAlert = automationCreatedRecently\n ? `Automation history started on ${automationBeganOn}`\n : \"Automation history is saved for 32 days\"\n\n const showTzLabel =\n Intl.DateTimeFormat().resolvedOptions().timeZone !== olsonTimeZone\n\n const { name, description } = parseDescription(automation.description)\n const { actionResourceUrl, actionResourceName } = automation\n let before = \"\"\n let after = \"\"\n if (description && actionResourceName) {\n const nameIndex = description.indexOf(actionResourceName)\n if (nameIndex !== -1) {\n before = description.slice(0, nameIndex)\n after = description.slice(nameIndex + actionResourceName.length)\n }\n }\n\n const columns = [\n {\n cell: (event: EventPage) => <EventStatusBadge status={event.status} />,\n css: {\n padding: \"8px 12px\",\n },\n header: \"Status\",\n },\n {\n cell: (event: EventPage) => {\n const baseFormat = momentDateTimeFormat({ dateFormat, twentyFourHourTime })\n const format = showTzLabel ? `${baseFormat} z` : baseFormat\n return moment.tz(event.createdAt, olsonTimeZone).format(format)\n },\n header: \"Date and time\",\n },\n {\n cell: (event: EventPage) => (\n <Link to={`/people/AC${event.person.id}`}>{event.person.name}</Link>\n ),\n css: {\n maxWidth: \"33%\",\n },\n header: \"Profile\",\n },\n {\n cell: (event: EventPage) => <EventStatusMessage event={event} />,\n css: {\n flex: 1,\n },\n header: \"Message\",\n },\n {\n cell: (event: EventPage) =>\n ![...STATUS.delivered.value, ...STATUS.pending.value].includes(\n event.status\n ) && (\n <>\n <RetryEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n onEventsStatusChange={onEventsStatusChange}\n />\n {![...STATUS.ignored.value].includes(event.status) && (\n <IgnoreEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n refreshHistory={refresh}\n onEventsStatusChange={onEventsStatusChange}\n />\n )}\n </>\n ),\n css: {\n textAlign: \"right\",\n },\n header: \"\",\n minWidth: \"84px\",\n },\n ]\n\n return (\n <StackView spacing={token(\"--t-spacing-4\")}>\n <StackView spacing={token(\"--t-spacing-half\")}>\n <Heading\n level={3}\n size=\"16px\"\n color={token(\"--t-text-color-secondary\")}\n weight={token(\"--t-font-weight-medium\")}\n >\n {name}{description && (\n <>\n {\" \"}({actionResourceUrl && actionResourceName\n ? <>{before}<Link to={actionResourceUrl}>{actionResourceName}</Link>{after}</>\n : description\n })\n </>\n )}\n </Heading>\n <Text\n color={token(\"--t-text-color-secondary\")}\n size={token(\"--t-font-size-xs\")}\n italic\n >\n {historyPreservationAlert}\n </Text>\n </StackView>\n <StackView spacing={token(\"--t-spacing-2\")}>\n <Box minHeight={7}>\n {!loading && (events.length || filteringEvents) && (\n <StackView\n alignItems=\"end\"\n axis=\"horizontal\"\n distribution=\"space-between\"\n spacing={token(\"--t-spacing-1\")}\n >\n <StackView width=\"max-content\">\n <Input.InputLabel\n fontWeight={token(\"--t-font-weight-medium\")}\n color={token(\"--t-text-color\")}\n controls=\"select-status\"\n >\n Filter by status\n </Input.InputLabel>\n <Select\n id=\"select-status\"\n emptyValue={null}\n onChange={({ selectedValue }) => {\n const newWhere = selectedValue\n ? { status: selectedValue }\n : null\n setParams({ where: newWhere })\n }}\n title=\"Status\"\n value={params.where?.status}\n >\n <Select.Option value={null}>All</Select.Option>\n {Object.values(STATUS).map((status) => (\n <Select.Option\n key={status.value}\n value={status.value.join(\",\")}\n >\n {status.label}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n <Button\n iconLeft={{ name: \"general.refresh\" }}\n onClick={refresh}\n theme=\"primary\"\n variant=\"outline\"\n width={12}\n >\n Refresh\n </Button>\n </StackView>\n )}\n </Box>\n <Box maxHeight=\"70vh\" minHeight={36} overflow=\"auto\">\n <DataTable\n columns={columns}\n data={events}\n empty={\n <StackView\n alignment=\"center\"\n distribution=\"center\"\n minHeight={20}\n maxWidth={45}\n spacing={token(\"--t-spacing-1\")}\n marginTop={!filteringEvents ? -8 : -4}\n marginBottom={!filteringEvents ? undefined : 4}\n >\n <Box\n css={{\n svg: {\n height: 15,\n width: 20,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <Heading\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n level={4}\n size={token(\"--t-font-size-lg\")}\n >\n No history found\n </Heading>\n <Text fontSize={token(\"--t-font-size-md\")} textAlign=\"center\">\n No events {filteringEvents && \"matching your filters\"} were\n triggered for this automation{\" \"}\n {automationCreatedRecently\n ? `since ${automationBeganOn}.`\n : \"in the last 32 days.\"}\n </Text>\n {filteringEvents && (\n <Button\n marginTop={token(\"--t-spacing-1\")}\n onClick={() => setParams({})}\n theme=\"primary\"\n title=\"Clear filters\"\n variant=\"outline\"\n />\n )}\n </StackView>\n }\n loading={loading}\n loadingTitle=\"Loading automation history...\"\n variant={{\n bodyCell: {\n alignItems: \"start\",\n fontSize: token(\"--t-font-size-sm\"),\n lineHeight: \"20px\",\n padding: \"10px 12px\",\n },\n bodyRow: ({ rowData }) => {\n return {\n backgroundColor: [...STATUS.ignored.value].includes(\n rowData.status\n )\n ? token(\"--t-fill-color-neutral-090\")\n : undefined,\n minHeight: \"36px\",\n }\n },\n headerCell: {\n padding: \"8px 12px\",\n },\n headerRow: {\n minHeight: \"36px\",\n },\n }}\n {...paginationProps}\n />\n </Box>\n </StackView>\n </StackView>\n )\n}\n\nfunction RetryEventButton({\n automationId,\n event,\n triggerResource,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n triggerResource: EncryptedTriggerResource\n}) {\n const [status, setStatus] = useState(event.status)\n\n function handleRetry() {\n setStatus(STATUS.pending.value.join(\",\"))\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/redeliver`,\n })\n .then((response) => {\n setStatus(STATUS.delivered.value.join(\",\"))\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .catch(() => {\n setStatus(STATUS.failed.value.join(\",\"))\n alerts.alertError.fire({\n text: \"There was a problem retrying this automation. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n const retryTitleFromStatus = STATUS.pending.value.includes(status)\n ? \"Sending\"\n : STATUS.delivered.value.includes(status)\n ? \"Sent\"\n : STATUS.skipped.value.includes(status)\n ? \"Run now\"\n : \"Retry\"\n\n const statusIcon = STATUS.delivered.value.includes(status)\n ? { color: token(\"--t-text-color-status-success\"), name: \"general.check\" }\n : undefined\n\n return (\n <Button\n title={retryTitleFromStatus}\n onClick={handleRetry}\n iconLeft={statusIcon}\n disabled={status !== event.status}\n variant=\"naked\"\n color={\n STATUS.delivered.value.includes(status)\n ? token(\"--t-text-color-status-success\")\n : STATUS.pending.value.includes(status)\n ? token(\"--t-text-color-placeholder\")\n : token(\"--t-text-color-interaction\")\n }\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction IgnoreEventButton({\n automationId,\n event,\n triggerResource,\n refreshHistory,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n refreshHistory: Function\n triggerResource: EncryptedTriggerResource\n}) {\n function handleIgnore() {\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/ignore`,\n })\n .then((response) => {\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .then(() => refreshHistory())\n .catch(() => {\n alerts.alertError.fire({\n text: \"There was a problem ignoring this event. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n return (\n <Button\n title={\"Ignore\"}\n onClick={handleIgnore}\n variant=\"naked\"\n color={\"linkForeground\"}\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction EventStatusBadge({ status }: { status: string }) {\n const badgeColors = STATUS.pending.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color\"),\n }\n : STATUS.delivered.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-success\"),\n text: token(\"--t-text-color-status-success\"),\n }\n : STATUS.skipped.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-warning\"),\n text: token(\"--t-text-color-status-warning\"),\n }\n : STATUS.ignored.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color-secondary\"),\n }\n : {\n border: token(\"--t-border-color-status-error\"),\n text: token(\"--t-text-color-status-error\"),\n }\n\n const badgeIcon = STATUS.pending.value.includes(status)\n ? \"general.clock\"\n : STATUS.skipped.value.includes(status)\n ? \"services.pause\"\n : STATUS.delivered.value.includes(status)\n ? \"general.checkCircle\"\n : STATUS.ignored.value.includes(status)\n ? \"general.inactive\"\n : \"general.exclamationTriangle\"\n\n const badgeTitle = STATUS.failed.value.includes(status)\n ? STATUS.failed.label\n : STATUS.ignored.value.includes(status)\n ? STATUS.ignored.label\n : STATUS[status].label\n\n return (\n <Badge\n color={{ background: \"transparent\", foreground: badgeColors.text }}\n css={{ paddingLeft: 3.5, paddingRight: 1.5 }}\n fontSize={token(\"--t-font-size-xs\")}\n radius=\"pill\"\n renderLeft={\n <Icon\n name={badgeIcon}\n color={badgeColors.border}\n marginLeft={token(\"--t-spacing-1\")}\n />\n }\n size=\"sm\"\n stroke={badgeColors.border}\n strokeAlign=\"inside\"\n strokeWeight={1}\n title={badgeTitle}\n />\n )\n}\n\nfunction EventStatusMessage({ event }: { event: EventPage }) {\n const { status, lastDelivery } = event\n\n function statusMessage(status: string, lastDelivery: Delivery) {\n let message: string | JSX.Element | null = null\n\n switch (status) {\n case \"skipped\":\n case \"ignored_skipped\":\n message = \"Automation was paused and did not run on this profile\"\n break\n case \"failed\":\n case \"duplicated\":\n case \"ignored_failed\":\n case \"ignored_duplicated\":\n message = deliveryFailureReason(lastDelivery, status)\n }\n\n return message\n }\n\n function deliveryFailureReason(delivery: Delivery, status: string) {\n const ERRORS = {\n 403: \"Owner doesn't have permission to perform this action.\",\n 404: \"Owner lacks access to target product or resource doesn't exist.\",\n 422: \"The automation action failed to run\",\n default: \"An error occurred\",\n duplicated_event:\n \"Didn't run because the same action had already been performed less than 60 seconds ago\",\n failed_without_deliveries:\n \"Didn't run because the owner doesn't have permissions in this product.\",\n }\n\n function responseErrors(delivery: Delivery) {\n if (!delivery?.responseBody) return null\n let response\n\n try {\n response = JSON.parse(delivery.responseBody)\n } catch {\n response = { errors: [\"Server Error\"] }\n }\n\n return parsedErrors(response).join(\", \") || response?.message\n }\n\n function parsedErrors(response) {\n if (response?.errors) {\n return response.errors.map((error) =>\n typeof error === \"string\" && error.match(/Archived profiles/)\n ? error.replace(/Archived profiles/, \"Archived profiles.\")\n : error\n )\n } else {\n return []\n }\n }\n\n return (\n <StackView flex={1} whiteSpace=\"normal\">\n {!delivery ? (\n [\"duplicated\", \"ignored_duplicated\"].includes(status) ? (\n ERRORS.duplicated_event\n ) : (\n ERRORS.failed_without_deliveries\n )\n ) : (\n <ToggleableDetails\n details={responseErrors(delivery)}\n status={delivery.status}\n >\n {ERRORS[delivery.status] || ERRORS.default}\n </ToggleableDetails>\n )}\n </StackView>\n )\n }\n\n const message = statusMessage(status, lastDelivery)\n\n return message ? (\n <Box\n fontSize={token(\"--t-font-size-sm\")}\n fontStyle=\"italic\"\n lineHeight=\"16px\"\n maxWidth=\"100%\"\n paddingTop=\"1px\"\n whiteSpace=\"normal\"\n >\n {message}\n </Box>\n ) : null\n}\n\nfunction ToggleableDetails({\n children,\n details,\n status,\n}: {\n children: React.ReactNode\n details: string\n status: string\n}) {\n const [open, setOpen] = useState(false)\n\n function toggleOpen() {\n setOpen((was) => !was)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Box>\n {children}{\" \"}\n {details && (\n <Button\n inline\n onClick={toggleOpen}\n size=\"xs\"\n theme=\"primary\"\n variant=\"naked\"\n fontStyle=\"normal\"\n >\n Details\n </Button>\n )}\n </Box>\n {open ? (\n <Box padding={1} background={token(\"--t-fill-color-neutral-090\")}>\n <Text\n fontFamily=\"monospace\"\n fontSize={token(\"--t-font-size-xs\")}\n lineHeight=\"1.2\"\n >\n {status && `${status}: `}\n {details}\n </Text>\n </Box>\n ) : null}\n </StackView>\n )\n}\n\ntype ErrorBoundaryProps = {\n children: React.ReactNode\n onRequestClose?: () => void\n}\n\ntype ErrorBoundaryState = {\n hasError: boolean\n}\n\nclass ErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props) {\n super(props)\n this.state = { hasError: false }\n }\n\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n\n handleContactSupport = () => {\n if (this.props.onRequestClose) {\n this.props.onRequestClose()\n }\n window.openHelpdesk()\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <Alert\n type=\"error\"\n marginVertical={1}\n padding={1.5}\n css={{ boxShadow: \"none\" }}\n >\n <Text lineHeight=\"1.35\">\n The application hit an unexpected error. If this persists after a\n few minutes, please let us know so we can get it fixed for you.{\" \"}\n <button\n style={{\n color: token(\"--t-text-color-interaction\"),\n whiteSpace: \"nowrap\",\n }}\n onClick={this.handleContactSupport}\n >\n Contact support\n </button>\n .\n </Text>\n </Alert>\n )\n }\n\n return this.props.children\n }\n}\n\n// eslint-disable-next-line react/display-name\nexport default (props: HistoryProps) => (\n <ErrorBoundary onRequestClose={props.onRequestClose}>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-dim\"),\n name: \"general.x\",\n }}\n onClick={onClick}\n size=\"sm\"\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction HistoryModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={120}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Automation history\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default HistoryModal\n","import { Logo } from \"@planningcenter/tapestry-react\"\nimport { kebabCase } from \"lodash\"\nimport type { ComponentProps } from \"react\"\n\n// Extract valid logo names from the Logo component's props\ntype ValidLogoName = NonNullable<ComponentProps<typeof Logo>[\"name\"]>\n\n// List of valid logo names from @planningcenter/tapestry-react Logo component\n// Update this list when support for new products are added to tapestry-react\nconst VALID_LOGO_NAMES: ValidLogoName[] = [\n \"api\",\n \"calendar\",\n \"check-ins\",\n \"church-center\",\n \"giving\",\n \"groups\",\n \"headcounts\",\n \"home\",\n \"login\",\n \"music-stand\",\n \"people\",\n \"planning-center\",\n \"publishing\",\n \"registrations\",\n \"services\",\n]\n\nexport const isValidLogoName = (name: string): name is ValidLogoName => {\n return VALID_LOGO_NAMES.includes(name as ValidLogoName)\n}\n\nexport const getValidLogoName = (name: string): ValidLogoName => {\n const kebabName = kebabCase(name)\n return isValidLogoName(kebabName) ? kebabName : \"planning-center\"\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { uniq } from \"lodash\"\n\nimport type { ResponseLabeler } from \"./types\"\n\nconst HIDDEN_FIELD = \"[Hidden Field]\"\nconst HIDDEN_RESPONSE = \"[Hidden Response]\"\nconst FIELD_KEY_RE = /^field_(\\d+)$/\nconst SENTINEL_VALUES = new Set([\"no-option\"])\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\ntype FormFieldRecord = {\n fieldType: string\n fieldableId: number | null\n fieldableType: string | null\n id: number\n label: string | null\n options?: { id: number; label: string | null }[]\n}\n\ntype FieldDefinitionRecord = {\n dataType: string\n fieldOptions?: { id: number; value: string | null }[]\n id: number\n name: string | null\n}\n\ntype CampusRecord = {\n id: number\n name: string | null\n}\n\ntype ExtractedIds = {\n fieldId: string\n formId: string\n optionId: string | null\n}\n\nasync function resolve(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const extracted = subscriptions.map((sub) => ({\n ids: extractIds(sub),\n sub,\n }))\n const targets = extracted.filter(\n (entry): entry is { ids: ExtractedIds; sub: AutomationInstance } =>\n entry.ids !== null\n )\n if (targets.length === 0) return subscriptions\n\n const fieldsByForm = await fetchFormFields(\n uniq(targets.map((t) => t.ids.formId))\n )\n\n const fieldDefIds = new Set<string>()\n const campusIds = new Set<string>()\n for (const { ids } of targets) {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (field?.fieldType === \"custom_field\" && field.fieldableId != null) {\n fieldDefIds.add(String(field.fieldableId))\n } else if (field?.fieldType === \"primary_campus\" && ids.optionId != null) {\n campusIds.add(ids.optionId)\n }\n }\n const [fieldDefs, campuses] = await Promise.all([\n fetchFieldDefinitions([...fieldDefIds]),\n fetchCampuses([...campusIds]),\n ])\n\n return extracted.map(({ ids, sub }) => {\n if (!ids) return sub\n return {\n ...sub,\n responseDetails: buildResponseDetails(\n ids,\n fieldsByForm,\n fieldDefs,\n campuses\n ),\n }\n })\n}\n\nfunction extractIds(subscription: AutomationInstance): ExtractedIds | null {\n const conds = subscription.triggerConditions\n const formId = conds?.data?.relationships?.form?.data?.id\n const selectedOptionsByField = conds?.data?.attributes?.selectedOptionsByField\n if (\n formId == null ||\n !selectedOptionsByField ||\n typeof selectedOptionsByField !== \"object\"\n ) {\n return null\n }\n\n for (const [key, value] of Object.entries(selectedOptionsByField)) {\n const match = FIELD_KEY_RE.exec(key)\n if (!match) continue\n const raw = (value as { $in?: unknown })?.$in\n const optionIds = (Array.isArray(raw) ? raw : raw == null ? [] : [raw])\n .map((id) => (id == null ? null : String(id)))\n .filter((id): id is string => id != null && !SENTINEL_VALUES.has(id))\n return {\n fieldId: match[1],\n formId: String(formId),\n optionId: optionIds[0] ?? null,\n }\n }\n return null\n}\n\nasync function fetchFormFields(\n formIds: string[]\n): Promise<Map<string, Map<string, FormFieldRecord>>> {\n const result = new Map<string, Map<string, FormFieldRecord>>()\n await Promise.all(\n formIds.map(async (formId) => {\n try {\n const { data } = await peopleClient.get<{ data: FormFieldRecord[] }>({\n data: {\n fields: {\n FormField: \"label,field_type,fieldable,options\",\n FormFieldOption: \"label\",\n },\n include: \"options\",\n walk: true,\n },\n url: `forms/${formId}/fields`,\n })\n const byId = new Map<string, FormFieldRecord>()\n for (const field of data) {\n byId.set(String(field.id), field)\n }\n result.set(formId, byId)\n } catch {\n result.set(formId, new Map())\n }\n })\n )\n return result\n}\n\nasync function fetchFieldDefinitions(\n ids: string[]\n): Promise<Map<string, FieldDefinitionRecord>> {\n const result = new Map<string, FieldDefinitionRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: FieldDefinitionRecord[] }>({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"field_definitions\",\n })\n for (const fd of data) {\n result.set(String(fd.id), fd)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nasync function fetchCampuses(\n ids: string[]\n): Promise<Map<string, CampusRecord>> {\n const result = new Map<string, CampusRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: CampusRecord[] }>({\n data: {\n fields: { Campus: \"name\" },\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"campuses\",\n })\n for (const campus of data) {\n result.set(String(campus.id), campus)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nfunction buildResponseDetails(\n ids: ExtractedIds,\n fieldsByForm: Map<string, Map<string, FormFieldRecord>>,\n fieldDefs: Map<string, FieldDefinitionRecord>,\n campuses: Map<string, CampusRecord>\n): ResponseDetails {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (!field) return { fieldLabel: HIDDEN_FIELD, valueLabel: HIDDEN_RESPONSE }\n\n const fieldLabel = field.label || HIDDEN_FIELD\n\n if (field.fieldType === \"boolean\") {\n return { fieldLabel, valueLabel: null }\n }\n\n if (field.fieldType === \"custom_field\" && field.fieldableId != null) {\n const fd = fieldDefs.get(String(field.fieldableId))\n if (!fd) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n if (fd.dataType === \"boolean\") return { fieldLabel, valueLabel: null }\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const match = (fd.fieldOptions || []).find(\n (o) => String(o.id) === ids.optionId\n )\n return { fieldLabel, valueLabel: match?.value || HIDDEN_RESPONSE }\n }\n\n if (field.fieldType === \"primary_campus\") {\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const campus = campuses.get(ids.optionId)\n return { fieldLabel, valueLabel: campus?.name || HIDDEN_RESPONSE }\n }\n\n if (ids.optionId == null) {\n return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n }\n const match = (field.options || []).find((o) => String(o.id) === ids.optionId)\n return { fieldLabel, valueLabel: match?.label || HIDDEN_RESPONSE }\n}\n\nconst peopleFormLabeler: ResponseLabeler = { resolve }\n\nexport { peopleFormLabeler }\n","import { peopleFormLabeler } from \"./response-labelers/people-form\"\nimport type { ResponseLabeler } from \"./response-labelers/types\"\n\nconst labelers: Record<string, ResponseLabeler> = {\n \"people.v2.events.form_submission.created\": peopleFormLabeler,\n}\n\nasync function resolveResponseDetails(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const groups = new Map<string, AutomationInstance[]>()\n for (const sub of subscriptions) {\n if (!labelers[sub.name]) continue\n const group = groups.get(sub.name) ?? []\n group.push(sub)\n groups.set(sub.name, group)\n }\n if (groups.size === 0) return subscriptions\n\n const resolvedById = new Map<number, AutomationInstance>()\n await Promise.all(\n [...groups.entries()].map(async ([name, subs]) => {\n const resolved = await labelers[name].resolve(subs)\n for (const sub of resolved) resolvedById.set(sub.id, sub)\n })\n )\n\n return subscriptions.map((sub) => resolvedById.get(sub.id) ?? sub)\n}\n\nfunction formatResponseDetails(\n responseDetails: ResponseDetails | null | undefined\n): string {\n if (!responseDetails) return \"\"\n const { fieldLabel, valueLabel } = responseDetails\n if (valueLabel == null) return ` with \"${fieldLabel}\" selected`\n return ` with \"${fieldLabel}\" selected as \"${valueLabel}\"`\n}\n\nexport { formatResponseDetails, resolveResponseDetails }\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n Logo,\n StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { lowerFirst, truncate } from \"lodash\"\nimport React, { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { formatResponseDetails } from \"./utils/resolve-response-details\"\nimport { dateLocalized, forbiddenText, parseDescription } from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n disabled?: boolean\n disabledReason?: string\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationProps = {\n automation: IncomingAutomationInstance\n}\n\ntype EditableAutomationContextType = {\n automation: AutomationInstance\n currentPersonCanCreate?: boolean\n currentPersonId?: number\n theme: object\n trigger?: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation?: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationContextType = {\n automation: IncomingAutomationInstance\n}\n\nconst AutomationContext = createContext<\n EditableAutomationContextType | IncomingAutomationContextType\n>(null)\n\nfunction EditableAutomation({\n updateAutomation,\n onDelete,\n theme,\n openHistoryNow = false,\n disabled,\n disabledReason,\n ...props\n}: AutomationProps & {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper\n theme={theme}\n updateAutomation={updateAutomation}\n {...props}\n >\n <Header>\n <Icons />\n <Manage\n onDelete={onDelete}\n openHistoryNow={openHistoryNow}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n </Header>\n <Description />\n <EditableFooter />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingAutomation(props: IncomingAutomationProps) {\n return (\n <AutomationWrapper automation={props.automation}>\n <Header>\n <Icons />\n <LinkToAutomation />\n </Header>\n <IncomingDescription />\n <Footer />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingDescription() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n const triggerEventDescription = automation.triggerEventDescription\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-medium\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n {formatResponseDetails(automation.responseDetails)}, then{\" \"}\n {lowerFirst(name)} {conditionalSuffix(automation)}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction LinkToAutomation() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n return (\n <Button\n external\n iconLeft={{ name: \"general.newWindow\" }}\n variant=\"naked\"\n size=\"sm\"\n to={automation.triggerAdminUrl}\n disabled={!automation.canManage}\n tooltip={\n !automation.canManage\n ? \"You do not have access to this resource\"\n : undefined\n }\n color={token(\"--t-text-color-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-secondary\"),\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation,\n updateAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n updateAutomation?: (automation: AutomationInstance) => void\n}) {\n return (\n <AutomationContext.Provider\n value={{\n automation,\n theme,\n updateAutomation,\n ...rest,\n }}\n >\n <Card radius={4} padding={2}>\n {children}\n </Card>\n </AutomationContext.Provider>\n )\n}\n\nfunction Header({ children }: { children: React.ReactNode }) {\n const { automation } = useContext(AutomationContext)\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n padding={0}\n distribution=\"space-between\"\n opacity={cardOpacity}\n >\n {children}\n </StackView>\n )\n}\n\nfunction Manage({\n onDelete,\n openHistoryNow = false,\n disabled,\n disabledReason,\n}: {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n}) {\n const {\n automation,\n currentPersonCanCreate,\n currentPersonId,\n trigger,\n theme,\n updateAutomation,\n } = useContext(AutomationContext) as EditableAutomationContextType\n const [historyVisible, setHistoryVisible] = useState(openHistoryNow)\n const isActive = automation.active\n const { name } = parseDescription(automation.description)\n\n function showHistory() {\n setHistoryVisible(true)\n }\n\n function updateEventsStatus(newStatus: AutomationInstance[\"eventsStatus\"]) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n function handleToggleActive() {\n webhooksClient\n .patch({\n data: {\n _e: trigger.resource,\n data: {\n attributes: {\n active: !isActive,\n },\n },\n },\n url: `/automation_subscriptions/${automation.id}`,\n })\n .then((data: { data: { active: boolean } }) => {\n updateAutomation((prev) => ({ ...prev, active: data.data.active }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"pause\") ||\n `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handleReassign() {\n alerts.confirm\n .fire({\n text: \"This automation will run with your permission levels. Other administrators who can see this automation can grant it their permissions by reassigning it to themselves.\",\n title: \"Reassign automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) {\n webhooksClient\n .post({\n data: {\n _e: trigger.resource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automation.id}/self_assign`,\n })\n .then(({ data }) => fetchCurrentPersonAvatar(data))\n .then(({ subscription, avatar }) => {\n updateAutomation((prev) => ({\n ...prev,\n createdBy: { ...prev.createdBy, avatarUrl: avatar },\n createdById: subscription.createdById,\n createdByName: subscription.createdByName,\n }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"update\") ||\n \"There was a problem updating this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n })\n }\n\n function handleDelete() {\n alerts.confirmDestroy\n .fire({\n confirmButtonText: \"Yes, delete automation\",\n text: `Are you sure you want to delete the \"${name}\" automation? This cannot be undone.`,\n title: \"Delete this automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) onDelete(automation.id)\n })\n }\n\n return (\n <>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Dropdown\n icon={{\n color: token(\"--t-icon-color\"),\n name: \"churchCenter.threeDots\",\n }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\n disabled={disabled}\n >\n <Dropdown.Item onSelect={() => showHistory()}>History</Dropdown.Item>\n {currentPersonCanCreate &&\n (automation.createdById === currentPersonId ? (\n <Dropdown.Item disabled={true}>\n <Tooltip\n placement=\"left\"\n openDelay={250}\n title=\"This automation is already assigned to you.\"\n >\n <Text>Reassign to me...</Text>\n </Tooltip>\n </Dropdown.Item>\n ) : (\n <Dropdown.Item onSelect={handleReassign}>\n Reassign to me...\n </Dropdown.Item>\n ))}\n <Dropdown.Item onSelect={handleDelete}>Delete...</Dropdown.Item>\n </Dropdown>\n <ToggleSwitch\n isChecked={isActive}\n size=\"sm\"\n onClick={handleToggleActive}\n tooltip={\n disabled\n ? disabledReason\n : isActive\n ? \"Pause automation\"\n : \"Enable automation\"\n }\n disabled={disabled}\n />\n </StackView>\n\n <HistoryModal\n open={historyVisible}\n onRequestClose={() => setHistoryVisible(false)}\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n onEventsStatusChange={updateEventsStatus}\n onRequestClose={() => setHistoryVisible(false)}\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Icons() {\n const { automation } = useContext(AutomationContext)\n const triggerProductName = automation.name.split(\".\")[0]\n\n return (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.5}>\n <Logo\n markOnly={true}\n name={getValidLogoName(triggerProductName)}\n size=\"sm\"\n theme=\"color\"\n />\n <Icon name=\"general.rightArrow\" size={1.5} />\n <Logo\n markOnly={true}\n name={getValidLogoName(automation.operationAppName)}\n size=\"sm\"\n theme=\"color\"\n />\n </StackView>\n )\n}\nfunction Footer() {\n const { automation } = useContext(AutomationContext)\n const { dateFormat } = useContext(OrganizationContext)\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-half\")}\n maxWidth=\"calc(100% - 136px)\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={2}\n height={2}\n basis={2}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={5} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n </>\n )\n}\n\nfunction EditableFooter() {\n const { dateFormat } = useContext(OrganizationContext)\n const { automation, trigger, theme, updateAutomation } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n const buttonProps = {\n color: token(\"--t-text-color-secondary\"),\n fontSize: token(\"--t-font-size-xs\"),\n fontWeight: token(\"--t-font-weight-normal\"),\n paddingHorizontal: token(\"--t-spacing-1\"),\n radius: \"pill\",\n size: \"xs\",\n variant: \"naked\",\n }\n const [historyProps, setHistoryProps] = useState({\n filter: null,\n historyVisible: false,\n })\n\n function renderSkippedHistory() {\n setHistoryProps({ filter: \"skipped\", historyVisible: true })\n }\n\n function renderFailedOrDuplicatedHistory() {\n setHistoryProps({ filter: \"failed,duplicated\", historyVisible: true })\n }\n\n function handleEventsStatusChange(\n newStatus: AutomationInstance[\"eventsStatus\"]\n ) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-fourth\")}\n >\n {!!automation.eventsStatus?.skipped && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.skipped} skipped`}\n onClick={renderSkippedHistory}\n tooltip={`${automation.eventsStatus.skipped?.toLocaleString()} skipped events`}\n >\n <Box\n backgroundColor={token(\"--t-fill-color-status-warning\")}\n marginRight={token(\"--t-spacing-half\")}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding={token(\"--t-spacing-fourth\")}\n >\n <Icon\n name={\"services.pause\"}\n size={\"6px\"}\n title={\"Skipped\"}\n color=\"white\"\n />\n </Box>\n {`${automation.eventsStatus.skipped?.toLocaleString()}`}\n </Button>\n )}\n {!!automation.eventsStatus?.failed && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.failed} failed`}\n iconLeft={{\n color: token(\"--t-icon-color-status-error\"),\n marginRight: token(\"--t-spacing-half\"),\n name: \"general.exclamationTriangle\",\n size: \"10px\",\n title: \"Failed\",\n }}\n onClick={renderFailedOrDuplicatedHistory}\n title={`${automation.eventsStatus.failed?.toLocaleString()}`}\n tooltip={`${automation.eventsStatus.failed?.toLocaleString()} failed events`}\n />\n )}\n </StackView>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"end\"\n flex={1}\n spacing={token(\"--t-spacing-half\")}\n marginLeft=\"auto\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={token(\"--t-element-size-md\")}\n height={token(\"--t-element-size-md\")}\n basis={token(\"--t-element-size-md\")}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={token(\"--t-font-size-sm\")} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n\n <HistoryModal\n open={historyProps.historyVisible}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n filterWhere={historyProps.filter}\n onEventsStatusChange={handleEventsStatusChange}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Description() {\n const { automation, trigger } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n const triggerEventDescription = [\n \"When a person\",\n lowerFirst(trigger.event.description) +\n formatResponseDetails(automation.responseDetails) +\n \",\",\n \"then\",\n lowerFirst(name),\n conditionalSuffix(automation),\n ].join(\" \")\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-bold\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction optionallyPrettifyArchivedPrefix(description: string) {\n if (description?.startsWith(\"[archived]\")) {\n return description.replace(\"[archived]\", \"[Archived]\")\n } else {\n return description\n }\n}\n\nasync function fetchCurrentPersonAvatar(subscription: AutomationInstance) {\n const {\n data: { avatar },\n } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n },\n url: \"me\",\n })\n\n return { avatar, subscription }\n}\n\nexport { EditableAutomation, IncomingAutomation }\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { compact, uniq } from \"lodash\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\nasync function fetchAutomations(triggerResource: EncryptedTriggerResource) {\n const { data } = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,events_status,trigger_conditions,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { truncate, upperFirst } from \"lodash\"\nimport React, { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nasync function fetchIncomingAutomations(encryptedParam) {\n const { data } = await webhooksClient.get({\n data: {\n _e: encryptedParam,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,trigger_conditions,trigger_resource,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"incoming_automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchTriggerResources(automations) {\n // We can optimize the query by fetching all the resources at once if we know\n // that the endpoint supports querying by multiple ids. Otherwise, we'll have\n // to fetch each resource individually.\n const QUERYABLE_BY_MULTIPLE_IDS = {\n people: [\"forms\", \"lists\"],\n registrations: [\"events\"],\n services: [\"teams\"],\n }\n const NOT_QUERYABLE = [\"giving\"]\n\n const automationsByModel = automations.reduce((accumulator, automation) => {\n // registrations has a weird case of signup vs event\n const automationTriggerResource = automation.triggerResource.replace(\n /signup/,\n \"event\"\n )\n const { appName, resourceType, resourcePath, resourceId } =\n triggerResourceParts(automationTriggerResource)\n\n if (!accumulator[appName]) accumulator[appName] = {}\n if (!accumulator[appName][resourceType])\n accumulator[appName][resourceType] = {}\n if (!accumulator[appName][resourceType][\"resoucePath\"])\n accumulator[appName][resourceType][\"resourcePath\"] = resourcePath\n\n if (!accumulator[appName][resourceType][\"ids\"])\n accumulator[appName][resourceType][\"ids\"] = []\n\n accumulator[appName][resourceType][\"ids\"].push(resourceId)\n\n return accumulator\n }, {})\n\n const promises = Object.keys(automationsByModel).flatMap((appName) => {\n const automationsByResourceType = automationsByModel[appName]\n\n return Object.entries(automationsByResourceType).flatMap(\n ([resourceType, resourceParts]) => {\n const fetchFn = NOT_QUERYABLE.includes(appName)\n ? fetchNothing\n : QUERYABLE_BY_MULTIPLE_IDS[appName]?.includes(resourceType)\n ? fetchAllAtOnce\n : fetchOneAtATime\n\n return fetchFn({\n appName,\n ids: resourceParts[\"ids\"],\n resourcePath: resourceParts[\"resourcePath\"],\n resourceType,\n })\n }\n )\n })\n\n const results = await Promise.allSettled(promises)\n\n return {\n automations,\n triggerResources: collectSuccessfulResults(results),\n }\n}\n\nfunction collectSuccessfulResults(settledPromises) {\n return settledPromises\n .reduce((acc, result) => {\n if (result.status === \"fulfilled\") acc = acc.concat(result.value)\n\n return acc\n }, [])\n .flatMap((d) => d.data)\n}\n\nfunction fetchAllAtOnce({ appName, resourcePath, resourceType, ids }) {\n return fetchResourceName({\n appName,\n params: {\n where: { id: ids.join(\",\") },\n },\n path: resourcePath,\n resourceType,\n })\n}\n\nfunction fetchOneAtATime({ appName, resourcePath, resourceType, ids }) {\n return ids.map((id) =>\n fetchResourceName({\n appName,\n path: `${resourcePath}/${id}`,\n resourceType,\n })\n )\n}\n\nfunction fetchNothing(_props: object) {\n return new Promise((_, reject) => {\n reject()\n })\n}\n\n// TODO (maybe): move these to webhooks, return the verb in the API response,\n// so new events don't need a code change in both places\nfunction mapNameToVerb(messageName) {\n // e.g. \"groups.v2.events.membership.created\" => \"groups.membership.created\"\n const appResourceAction = messageName.replace(\"v2.events.\", \"\")\n\n switch (appResourceAction) {\n case \"groups.membership.created\":\n return \"joins\"\n case \"groups.membership.destroyed\":\n return \"leaves\"\n case \"people.list_result.created\":\n case \"services.team_person.created\":\n return \"is added to\"\n case \"people.list_result.destroyed\":\n case \"services.team_person.destroyed\":\n return \"is removed from\"\n case \"people.form_submission.created\":\n return \"submits\"\n case \"registrations.attendee.created\":\n return \"is registered as a new attendee for\"\n case \"registrations.attendee.cancelled\":\n return \"is canceled as an attendee for\"\n case \"registrations.registration.created\":\n return \"is the registration contact on a new registration for\"\n case \"registrations.registration.cancelled\":\n return \"is the registration contact on a canceled registration for\"\n default:\n return null\n }\n}\n\nfunction buildGivingDescription(automation: AutomationInstance) {\n const action = automation.name.replace(\"giving.v2.events.\", \"\")\n\n switch (action) {\n case \"donation.payment_successful\":\n return \"When a person gives\"\n case \"profile.first_donated_automation\":\n return \"When a person gives for the first time\"\n case \"recurring_donation.setup_successful\":\n return \"When a person sets up a recurring donation\"\n default:\n return null\n }\n}\n\nfunction buildDescription(automation, triggerResourceName) {\n const verb = mapNameToVerb(automation.name)\n\n const { resourceType } = triggerResourceParts(automation.triggerResource)\n\n if (!verb) {\n // No verb mapping for this message name, so just show something generic\n const resourceName = truncate(triggerResourceName, {\n length: 160,\n separator: \" \",\n })\n\n return `When the automation is triggered from ${singularize(\n resourceType\n )} \"${resourceName}\"`\n }\n\n return `When a person ${verb} ${singularize(\n resourceType\n )} \"${triggerResourceName}\"`\n}\n\nfunction fetchResourceName({\n appName,\n path,\n resourceType,\n params = {},\n}): Promise<any> {\n const client = new Client({ root: pcoApiUrl(appName, { squiggly: false }) })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color\")}`}\n marginBottom={token(\"--t-spacing-2\")}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n >\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text\n color={token(\"--t-text-color-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\nimport React from \"react\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => !od.section\n )\n\n const primarySectionOptions = uniqBy(operationDefinitions, \"section\")\n .filter((od) => !!od.section)\n .map((od) => ({\n group: od.sectionGroup,\n label: od.section,\n value: sectionId(od.section),\n }))\n\n const secondaryOperations = selectedSection\n ? operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === selectedSection\n )\n : []\n\n function handleAnySelectChange({ selectedValue }) {\n switch (idType(selectedValue)) {\n case \"section\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => sectionId(od.section) === selectedValue\n )\n )\n break\n case \"operation\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => operationDefinitionId(od) === selectedValue\n )\n )\n break\n case null:\n onOperationDefinitionChange(null)\n break\n }\n }\n\n function renderOperations(operations: OperationDefinition[]) {\n const operationsAsOptions = operations.map((o) => ({\n group: o.group,\n label: o.description,\n value: o.id,\n }))\n\n return renderOptions(operationsAsOptions)\n }\n\n const primarySelectedValue = selectedOperation\n ? !selectedOperation.section\n ? operationDefinitionId(selectedOperation)\n : sectionId(selectedOperation.section)\n : undefined\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Select\n emptyValue=\"Select an action\"\n id=\"select-action\"\n onChange={handleAnySelectChange}\n size=\"lg\"\n value={primarySelectedValue}\n data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n value={operationDefinitionId(selectedOperation)}\n onChange={handleAnySelectChange}\n size=\"lg\"\n >\n {renderOperations(secondaryOperations)}\n </Select>\n )}\n </StackView>\n )\n}\n\nexport default Definition\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Avatar,\n Badge,\n Box,\n Checkbox as TapestryCheckbox,\n Combobox as TapestryCombobox,\n DateField as TapestryDateField,\n HelperDrawer,\n Highlight,\n Icon,\n Input,\n Menu,\n NumberField as TapestryNumberField,\n Radio,\n Select as TapestrySelect,\n Spinner,\n StackView,\n Text,\n TextArea as TapestryTextArea,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, debounce, groupBy, isEqual, sortBy, uniqBy } from \"lodash\"\nimport moment from \"moment\"\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n if (field.kind === \"Hidden\") return null\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n disabled={field.disabled}\n />\n )\n case \"SelectSearch\":\n return (\n <SelectSearch\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"Checkbox\":\n return <Checkbox field={field} value={value} onChange={onChange} />\n case \"TextArea\":\n return <TextArea field={field} onChange={onChange} value={value} />\n\n case \"DateField\":\n return <DateField field={field} onChange={onChange} value={value} />\n case \"Checkboxes\":\n return (\n <Checkboxes\n fieldId={field.id}\n options={actionAllowedOptions}\n onChange={onChange}\n />\n )\n case \"NumberField\":\n return <NumberField field={field} onChange={onChange} value={value} />\n case \"PersonSearch\":\n return (\n <PersonSearch\n canAccessPeople={canAccessPeople}\n field={field}\n onChange={onChange}\n listOptions={listOptions}\n isLoading={loadingLists[fieldListIdentifier(field)]}\n loadListForField={loadListForField}\n value={value}\n />\n )\n case \"TextField\":\n return <TextField field={field} onChange={onChange} value={value} />\n case \"RadioButtons\":\n return (\n <RadioButtons\n field={field}\n options={listOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"StaticText\":\n return <Text dangerouslySetInnerHTML={{ __html: field.content }} />\n default:\n console.warn(`Unknown field kind \"${field.kind}\"`)\n return null\n }\n }\n\n return (\n <StackView marginBottom={2} spacing={0.5}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-sm\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n controls={field.id}\n >\n {field.description}\n {field.description && field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>\n {loading ? <Loading /> : renderField()}\n {!field.description && field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Box>\n {field.info && (\n <HelperDrawer\n id={`${field.id}_help`}\n marginTop={token(\"--t-spacing-half\")}\n >\n <Box dangerouslySetInnerHTML={{ __html: field.info }} />\n </HelperDrawer>\n )}\n </StackView>\n )\n}\n\nconst Select = ({\n fieldId,\n listOptions,\n onChange,\n value,\n description,\n disabled,\n}: {\n description?: string\n disabled?: boolean\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value: any\n}) => {\n const overridenEmptyValue = listOptions?.find(\n (option) => option.value === \"no-option\"\n )\n const groupedOptions = groupBy(listOptions, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n const renderOptions = () => {\n return groupTypes.map((gt) =>\n gt === \"null\" || gt === \"undefined\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <TapestrySelect.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </TapestrySelect.OptionGroup>\n )\n )\n }\n\n const renderOptionsWithoutConsideringGroup = (\n items: { description: string; disabled?: boolean; value: string | number }[]\n ) => {\n return items.map((item) => (\n <TapestrySelect.Option\n key={item.value}\n value={item.value.toString()}\n disabled={item.disabled}\n >\n {item.description}\n </TapestrySelect.Option>\n ))\n }\n\n const handleSelectedValueChange = ({ selectedValue }) => {\n onChange({ fieldId, value: selectedValue })\n }\n\n const generatePrompt = (word: string) => {\n let prompt = `Select `\n if (!word) {\n prompt += \"a value\"\n } else if ([\"a\", \"e\", \"i\", \"o\", \"u\"].includes(word.charAt(0))) {\n prompt += `an ${word}`\n } else {\n prompt += `a ${word}`\n }\n return prompt\n }\n\n const renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return (\n overridenEmptyValue?.description ||\n generatePrompt(description?.toLowerCase())\n )\n }\n\n return (\n <TapestrySelect\n id={fieldId}\n onChange={handleSelectedValueChange}\n disabled={renderOptions().length < 1 || !!disabled}\n emptyValue={renderEmptyValue()}\n size=\"lg\"\n value={value || overridenEmptyValue?.value || null}\n placement=\"bottom-start\"\n >\n {renderOptions()}\n </TapestrySelect>\n )\n}\n\nconst SelectSearch = ({\n fieldId,\n listOptions,\n onChange,\n value,\n}: {\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value?: string\n}) => {\n const selectedOption: LoadedList = listOptions.find(\n (option) => option.value?.toString() === value\n )\n const selectedLabel = selectedOption?.description || \"\"\n const [prevSelectedLabel, setPrevSelectedLabel] = useState(\"\")\n const [query, setQuery] = useState(selectedLabel)\n const [showFilteredOptions, setShowFilteredOptions] = useState(false)\n const [showClearButton, setShowClearButton] = useState(false)\n\n if (selectedLabel !== prevSelectedLabel) {\n setPrevSelectedLabel(selectedLabel)\n setQuery(selectedLabel)\n setShowFilteredOptions(false)\n }\n\n let filteredOptions = sortBy(uniqBy(listOptions, \"value\"), \"group\")\n\n if (showFilteredOptions) {\n const formattedQuery = query.toLowerCase()\n filteredOptions = filteredOptions.filter((option) => {\n const optionText = `${option.description} ${option.group}`.toLowerCase()\n return optionText.includes(formattedQuery)\n })\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n css={{\n \"[role='combobox']\": {\n cursor: listOptions.length > 0 ? \"pointer\" : \"not-allowed\",\n },\n }}\n cursor=\"pointer\"\n disabled={listOptions.length === 0}\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowFilteredOptions(true)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n setShowFilteredOptions(false)\n }\n : undefined\n }\n onFocus={(e: React.ChangeEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowFilteredOptions(false)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder={\n listOptions.length > 0 ? \"Select an option\" : \"No options available\"\n }\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={<Icon name=\"general.search\" size=\"md\" />}\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {listOptions.length > 0 && (\n <>\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option: LoadedList, index: number) => {\n const isCurrent = option.value.toString() === value\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n disabled={option.disabled}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Icon\n marginLeft={-0.5}\n name={isCurrent ? \"general.check\" : \"\"}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={{\n description: option.description,\n value: option.value.toString(),\n }}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n {option.group && (\n <Badge\n title={<Highlight text={option.group} query={query} />}\n size=\"sm\"\n marginLeft=\"auto\"\n />\n )}\n </TapestryCombobox.Item>\n )\n })\n ) : (\n <Menu.Item>\n <Text>No results for &quot;{query}&quot;</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value ?? \"\"}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import React, { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n // Merge: existing values (e.g. pre-populated from an existing automation)\n // take precedence over field defaults.\n onChange((prev: SelectedFieldOptions) => ({ ...newSelections, ...prev }))\n }, [definitionFields, onChange])\n\n const renderableFields = getRenderedFields(\n definitionFields,\n selectedFieldOptions\n )\n\n const handleSelectedFieldOptionsChange = ({ fieldId, value }) => {\n const newSelections = { ...selectedFieldOptions }\n const dependents = definitionFields.filter((field) => field.dependsOn)\n dependents.map((dependent) => {\n if (dependent.dependsOn.includes(fieldId)) {\n const deeper = dependents.find((d) =>\n d.dependsOn.includes(dependent.id)\n )\n if (deeper) {\n delete newSelections[deeper.id]\n }\n delete newSelections[dependent.id]\n\n if (\n dependent.defaultValue !== undefined &&\n newSelections[dependent.id] === undefined\n ) {\n newSelections[dependent.id] = dependent.defaultValue\n }\n }\n })\n\n if (value === \"no-option\") {\n delete newSelections[fieldId]\n } else {\n newSelections[fieldId] = value\n }\n\n onChange({ ...newSelections })\n }\n\n if (definitionFields.length) {\n return (\n <div>\n {renderableFields.map((field) => {\n return (\n <Field\n canAccessPeople={canAccessPeople}\n field={field}\n key={field.id}\n onChange={handleSelectedFieldOptionsChange}\n value={selectedFieldOptions[field.id]}\n selectedFieldOptions={selectedFieldOptions}\n loadListForField={loadListForField}\n loadedLists={loadedLists}\n loadingLists={loadingLists}\n />\n )\n })}\n </div>\n )\n } else {\n return null\n }\n}\n\nexport default Fields\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Icon,\n Input,\n Link,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n buildTriggerConditions,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] =\n useState<SelectedFieldOptions>({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{ [k: string]: LoadedList[] }>(\n {}\n )\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n const triggerConditions = buildTriggerConditions({\n baseConditions:\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions,\n dynamicConditions,\n dynamicTriggerConditions,\n })\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n alert(\"something even worse happened!\")\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color\"),\n fontSize: token(\"--t-font-size-md\"),\n lineHeight: 1.65,\n marginBottom: token(\"--t-spacing-2\"),\n }}\n >\n {description}{\" \"}\n <Link external to={blankStateLink}>\n Learn more\n </Link>\n </Text>\n </Box>\n )}\n {error.automation && (\n <Alert {...errorAlertProps}>\n <Text>\n There was an error creating your automation. Please change your\n selections and try again or contact support if the problem persists.\n </Text>\n </Alert>\n )}\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color\")}\n controls=\"select-trigger-event\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n When a person...\n </Input.InputLabel>\n <Select\n id=\"select-trigger-event\"\n onChange={({ selectedValue }) =>\n handleChangeTriggerEvent(selectedValue)\n }\n size=\"lg\"\n value={selectedTriggerEvent}\n >\n {trigger.events.map((triggerEvent, idx) => (\n <Select.Option\n key={`${triggerEvent.name}_${idx}`}\n value={triggerEvent}\n >\n {triggerEvent.description}\n </Select.Option>\n ))}\n </Select>\n\n {dynamicConditions?.length > 0 && (\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={dynamicConditions}\n selectedFieldOptions={dynamicTriggerConditions}\n onChange={setDynamicTriggerConditions}\n loadedLists={{}}\n loadingLists={{}}\n loadListForField={() => null}\n />\n )}\n </StackView>\n\n <StackView spacing={1}>\n {operationApps.length > 0 ? (\n <Application\n selectedApp={selectedApp}\n operationApps={operationApps}\n onOperationAppChange={handleChangeSelectedApp}\n />\n ) : (\n <StackView spacing={1}>\n <Text\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={4}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={token(\"--t-spacing-1\")} {...errorAlertProps}>\n <Text>\n There was a problem looking up automations. Please contact support\n if the problem persists.\n </Text>\n </Alert>\n ) : loadingOperationDefinitions ? (\n <LoadingOperationDefinitions />\n ) : (\n <Definition\n selectedOperation={selectedDefinition}\n operationDefinitions={operationDefinitions}\n onOperationDefinitionChange={handleSelectedDefinitionChange}\n />\n )}\n </StackView>\n\n {selectedDefinition &&\n (error.selected_definition ? (\n <Alert {...errorAlertProps}>\n <Text>\n There was a problem looking up automation options. Please contact\n support if the problem persists.\n </Text>\n </Alert>\n ) : (\n <>\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={selectedDefinition.definitionFields || []}\n onChange={setSelectedFieldOptions}\n selectedFieldOptions={selectedFieldOptions}\n loadedLists={loadedLists}\n loadListForField={loadListForField}\n loadingLists={loadingLists}\n />\n {afterCreateOptions?.label && (\n <Checkbox\n disabled={\n submitting ||\n disableSubmit(selectedDefinition, selectedFieldOptions)\n }\n label={afterCreateOptions.label}\n checked={callAfterCreate}\n onChange={() => setCallAfterCreate(!callAfterCreate)}\n />\n )}\n {selectedTriggerEvent?.triggerParams?.map((param, idx) => (\n <Checkbox\n key={`${param.key}_${idx}`}\n label={param.description}\n checked={\n (triggerParams && triggerParams[param.key]) ||\n param.defaultValue\n }\n onChange={(e) => {\n setTriggerParams((prev) => ({\n ...prev,\n [`${param.key}`]: e.target.checked,\n }))\n }}\n />\n ))}\n {dangerAlertPresent && (\n <Alert {...errorAlertProps}>\n <StackView axis=\"horizontal\" spacing={1.5}>\n <Icon\n size={token(\"--t-element-size-lg\")}\n name=\"general.exclamationTriangle\"\n color={token(\"--t-icon-color-status-error\")}\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${token(\"--t-border-color\")}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={token(\"--t-text-color-headline\")}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={token(\"--t-font-weight-normal\")}\n onClick={onRequestClose}\n size=\"md\"\n title=\"Cancel\"\n variant=\"naked\"\n />\n <Button\n disabled={\n submitting ||\n dangerAlertPresent ||\n disableSubmit(\n selectedDefinition,\n selectedFieldOptions,\n dynamicConditions,\n dynamicTriggerConditions\n )\n }\n onClick={handleSubmit}\n size=\"md\"\n theme=\"primary\"\n title={getButtonText(selectedDefinition, selectedFieldOptions)}\n variant=\"fill\"\n data-testid=\"create-automation\"\n />\n </StackView>\n </StackView>\n )\n}\n\nfunction disableSubmit(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions,\n dynamicConditions?: DefinitionField[],\n dynamicTriggerConditions?: SelectedFieldOptions\n) {\n if (!selectedDefinition) return true\n\n const operationFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n if (\n !operationFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n if (\n !operationFields\n .filter((field) => fieldIsSelect(field))\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n\n const triggerFields = getRenderedFields(\n dynamicConditions ?? [],\n dynamicTriggerConditions ?? {}\n )\n if (\n !triggerFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, dynamicTriggerConditions ?? {}))\n )\n return true\n\n return false\n}\n\nfunction fieldIsSelect(field: DefinitionField) {\n return field.kind === \"Select\" || field.kind === \"SelectSearch\"\n}\n\nfunction fieldIsFilled(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (fieldIsSelect(field)) {\n return selectedFieldOptions.hasOwnProperty(field.id)\n } else {\n return (\n selectedFieldOptions.hasOwnProperty(field.id) &&\n selectedFieldOptions[field.id] &&\n selectedFieldOptions[field.id].toString().trim() !== \"\"\n )\n }\n}\n\nfunction getNextRequiredDescription(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!selectedDefinition?.definitionFields) return\n\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n for (const field of renderedFields) {\n if (field.required && !fieldIsFilled(field, selectedFieldOptions))\n return field.description\n }\n}\n\nfunction getButtonText(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n const nextRequiredDescription = getNextRequiredDescription(\n selectedDefinition,\n selectedFieldOptions\n )\n\n if (!selectedDefinition) {\n return \"Select an action\"\n } else if (nextRequiredDescription) {\n return `Select a${\n nextRequiredDescription.charAt(0).match(/[aeiou]/i) ? \"n\" : \"\"\n } ${nextRequiredDescription.toLowerCase()}`\n } else {\n return \"Create automation\"\n }\n}\n\nconst Application = ({\n onOperationAppChange,\n operationApps,\n selectedApp,\n}: {\n onOperationAppChange: (selectedValue: string) => void\n operationApps: Array<{ id: string; name: string }>\n selectedApp: string\n}) => {\n const handleChange = ({ selectedValue }) => {\n onOperationAppChange(selectedValue)\n }\n\n return (\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n controls=\"select-product\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Input.InputLabel>\n <Select\n autoFocus\n id=\"select-product\"\n onChange={handleChange}\n size=\"lg\"\n value={selectedApp}\n >\n {operationApps.map((app) => (\n <Select.Option key={app.id} value={app.id}>\n {app.name}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n )\n}\n\nconst LoadingOperationDefinitions = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{ color: token(\"--t-icon-color-dim\"), name: \"general.x\" }}\n onClick={onClick}\n size={\"sm\"}\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction NewAutomationModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={75}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Create automation\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n <style>{`\n .swal2-container.swal2-backdrop-show { z-index: 10001 }\n `}</style>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default NewAutomationModal\n","import * as churchCenter from \"@planningcenter/icons/paths/church-center\"\nimport * as logomark from \"@planningcenter/icons/paths/logomark\"\nimport * as services from \"@planningcenter/icons/paths/services\"\n\nexport const icons = {\n churchCenter,\n logomark,\n services,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport sortBy from \"lodash/sortBy\"\nimport React, { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n forbiddenText,\n pluralize,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused ? undefined : `1px solid ${token(\"--t-border-color\")}`\n }\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={token(\"--t-spacing-2\")}\n marginTop={-3}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n spacing={token(\"--t-spacing-2\")}\n wrap\n zIndex={2}\n >\n {canCreate && !hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n marginHorizontal={1}\n spacing={1}\n >\n <Icon\n size={2}\n color={token(\"--t-icon-color-status-warning\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n disabled?: boolean\n disabledReason?: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color\"),\n level: 2,\n size: token(\"--t-font-size-2xl\"),\n weight: token(\"--t-font-weight-bold\"),\n }\n\n const BlankStateTextProps = {\n color: token(\"--t-text-color-secondary\"),\n lineHeight: 3,\n size: token(\"--t-font-size-md\"),\n }\n\n function automationTriggerEvent(automation: AutomationInstance) {\n return trigger.events.find((event) => event.name === automation.name)\n }\n\n const handleUpdateAutomation =\n (originalAutomation: AutomationInstance) =>\n (newState: React.SetStateAction<AutomationInstance>) => {\n const updated =\n typeof newState == \"function\" ? newState(originalAutomation) : newState\n const newAutomations = [\n ...automations.filter((automation) => automation.id !== updated.id),\n updated,\n ]\n\n setAutomations(newAutomations)\n }\n\n return (\n <ThemeProvider theme={customTheme}>\n <OrganizationContext.Provider\n value={{ dateFormat, olsonTimeZone, twentyFourHourTime }}\n >\n {trigger && (\n <Header\n automations={automations}\n blankStateLink={blankStateLink}\n canCreate={currentPersonCanCreate && !disabled}\n loading={loading}\n defaultApp={defaultApp}\n description={blankStateDescription}\n theme={customTheme}\n trigger={trigger}\n hasActiveAutomations={hasActiveAutomations}\n onPauseAutomations={handlePauseAutomations}\n afterCreateOptions={afterCreateOptions}\n />\n )}\n {loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading automations...\"}\n />\n ) : !trigger ? (\n <></>\n ) : (\n <Box data-testid=\"automations-section\">\n {automations?.length > 0 ? (\n <TileView spacing={3} marginVertical={3} minCellWidth={45}>\n {sortBy(automations, \"id\").map((a) => (\n <EditableAutomation\n key={a.id}\n automation={a}\n updateAutomation={handleUpdateAutomation(a)}\n onDelete={handleDelete}\n theme={customTheme}\n openHistoryNow={a.id === Number(automationId)}\n trigger={{\n event: automationTriggerEvent(a),\n resource: trigger.resource,\n }}\n currentPersonId={currentPersonId}\n currentPersonCanCreate={currentPersonCanCreate}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={token(\"--t-spacing-6\")}\n spacing={token(\"--t-spacing-2\")}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n spacing: token(\"--t-spacing-6\"),\n },\n }}\n >\n <Box\n css={{\n \".symbol\": {\n height: \"100%\",\n width: \"100%\",\n },\n }}\n maxWidth={24}\n mediaQueries={{\n lg: {\n maxWidth: 40,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <StackView\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n maxWidth={45}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n textAlign: \"left\",\n },\n }}\n textAlign=\"center\"\n >\n {currentPersonCanCreate ? (\n <>\n <Heading {...BlankStateHeadingProps}>\n Add an automation\n </Heading>\n <StackView\n alignment=\"center\"\n marginBottom={token(\"--t-spacing-1\")}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}\n </Text>\n </StackView>\n <StackView\n axis=\"horizontal\"\n spacing={token(\"--t-spacing-1\")}\n >\n <Button\n variant=\"outline\"\n to={blankStateLink}\n color={`${token(\n \"--t-text-color-status-neutral\"\n )} !important`}\n >\n Learn more\n </Button>\n <Button\n as=\"button\"\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n </StackView>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={customTheme}\n >\n <NewAutomation\n defaultApp={defaultApp}\n description={blankStateDescription}\n blankStateLink={blankStateLink}\n onRequestClose={() => setNewModalVisible(false)}\n trigger={trigger}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </>\n ) : (\n <>\n <Heading {...BlankStateHeadingProps}>Automations</Heading>\n <Text {...BlankStateTextProps}>\n {permissionDeniedReason}\n </Text>\n </>\n )}\n </StackView>\n </StackView>\n )}\n </Box>\n )}\n {incomingAutomationsParam && (\n <IncomingAutomations\n encryptedParam={incomingAutomationsParam}\n trigger={trigger}\n />\n )}\n </OrganizationContext.Provider>\n <style>{styles}</style>\n </ThemeProvider>\n )\n}\n"],"names":["SvgAutomations","React","createElement","id","xmlns","viewBox","className","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","async","deobfuscateDescriptions","subscriptions","Promise","all","map","subscription","includes","operationDefinitionClassName","isDeobfuscatable","result","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","replace","actionResourceUrl","links","html","actionResourceName","fieldDefinitionId","definitionIdentifier","match","fieldDefinition","FieldDefinition","FieldOption","include","fetchFieldDefinition","values","dataType","_subscription$operati","_subscription$operati2","Object","entries","action","_fieldDefinition$fiel","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","_fieldDefinition$fiel2","customFieldOptionDescription","deobfuscatedDescription","string","charAt","toUpperCase","slice","Client","root","pcoApiUrl","squiggly","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","renderIfChainSatisfied","allFields","selectedFieldOptions","renderIf","isBoolean","conditionKey","keys","shouldRender","upstreamId","upstream","f","getRenderedFields","definitionFields","filter","describeSelectedFields","selectedDefinition","_list$find2","workflow_id_WorkflowsList","sensitiveString","o","toString","workflow_id","obfuscateSelectedFieldDescriptions","_list$find","label","e","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","forbiddenText","error","_error$errors","errors","status","parseDescription","exec","trim","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","mergePeopleAndEvents","mergedData","reduce","personId","foundPerson","p","push","_extends","person","event","History","automation","filterWhere","onEventsStatusChange","_params$where","loading","paginationProps","refresh","params","setParams","automationId","_","setError","useState","setLoading","eventPages","setEventPages","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","_e","Delivery","Event","order","fetchEvents","per_page","then","pages","bubbleErrorToBoundary","undefined","useEvents","useContext","filteringEvents","automationCreatedRecently","diff","numDaysSince","createdAt","automationBeganOn","historyPreservationAlert","showTzLabel","Intl","DateTimeFormat","resolvedOptions","timeZone","before","after","nameIndex","indexOf","columns","cell","EventStatusBadge","css","padding","header","baseFormat","momentDateTimeFormat","tz","Link","to","maxWidth","EventStatusMessage","flex","Fragment","RetryEventButton","IgnoreEventButton","refreshHistory","textAlign","minWidth","StackView","spacing","token","Heading","level","size","color","weight","Text","italic","Box","minHeight","alignItems","axis","distribution","Input","InputLabel","fontWeight","controls","Select","emptyValue","onChange","selectedValue","title","Option","Button","iconLeft","onClick","theme","variant","maxHeight","overflow","DataTable","empty","alignment","marginTop","marginBottom","svg","fontSize","loadingTitle","bodyCell","lineHeight","bodyRow","rowData","backgroundColor","headerCell","headerRow","setStatus","retryTitleFromStatus","statusIcon","post","attributes","response","eventsStatus","alerts","fire","text","disabled","badgeColors","border","badgeIcon","badgeTitle","Badge","background","foreground","paddingLeft","paddingRight","radius","renderLeft","Icon","marginLeft","stroke","strokeAlign","strokeWeight","lastDelivery","message","delivery","ERRORS","default","duplicated_event","failed_without_deliveries","whiteSpace","ToggleableDetails","details","_response","responseBody","parse","_unused","parsedErrors","responseErrors","deliveryFailureReason","statusMessage","fontStyle","paddingTop","children","open","setOpen","inline","was","fontFamily","ErrorBoundary","Component","constructor","props","super","this","handleContactSupport","onRequestClose","window","openHelpdesk","state","hasError","static","render","Alert","type","marginVertical","boxShadow","style","History$1","CloseModalIcon","as","icon","HistoryModal","createPortal","ThemeProvider","Modal","paddingBottom","document","body","VALID_LOGO_NAMES","getValidLogoName","kebabName","kebabCase","isValidLogoName","HIDDEN_FIELD","HIDDEN_RESPONSE","FIELD_KEY_RE","SENTINEL_VALUES","Set","extractIds","_conds$data","_conds$data2","conds","triggerConditions","formId","relationships","form","selectedOptionsByField","_optionIds$","raw","$in","optionIds","Array","isArray","String","has","fieldId","optionId","fetchFieldDefinitions","ids","Map","walk","fd","set","_unused2","fetchCampuses","Campus","campus","_unused3","buildResponseDetails","fieldsByForm","fieldDefs","campuses","_fieldsByForm$get2","fieldLabel","valueLabel","fieldType","fieldableId","options","labelers","resolve","extracted","sub","targets","entry","formIds","FormField","FormFieldOption","byId","fetchFormFields","uniq","t","fieldDefIds","campusIds","_fieldsByForm$get","add","responseDetails","resolveResponseDetails","groups","_groups$get","group","resolvedById","subs","resolved","_resolvedById$get","formatResponseDetails","_excluded","_excluded2","AutomationContext","EditableAutomation","_ref","updateAutomation","onDelete","openHistoryNow","disabledReason","_objectWithoutPropertiesLoose","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","cardOpacity","active","paddingVertical","truncate","lowerFirst","conditionalSuffix","optionallyPrettifyArchivedPrefix","separator","external","triggerAdminUrl","canManage","tooltip","hover","_ref2","rest","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","avatar","fetchCurrentPersonAvatar","prev","createdBy","avatarUrl","createdByName","confirmButtonText","ToggleSwitch","isChecked","patch","newStatus","triggerProductName","Logo","markOnly","operationAppName","_automation$createdBy","_automation$createdBy2","createdBySuffix","Divider","marginHorizontal","Avatar","basis","source","_automation$createdBy3","_automation$eventsSta","_automation$eventsSta2","_automation$eventsSta3","_automation$eventsSta4","_automation$eventsSta5","_automation$eventsSta6","_automation$createdBy4","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","_automation$triggerPa","triggerParams","useTriggerPersonOverride","startsWith","fetchCreatorProfiles","compact","profiles","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","services","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","_QUERYABLE_BY_MULTIPL","fetchNothing","fetchAllAtOnce","fetchOneAtATime","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","app","toLowerCase","fetchPersonApps","operationApps","AutomationSubscription","fetchIncomingAutomations","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","primarySelectedValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","camelCase","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","SelectSearch","Checkbox","TextArea","DateField","Checkboxes","NumberField","PersonSearch","isLoading","TextField","RadioButtons","dangerouslySetInnerHTML","__html","content","console","warn","renderField","overridenEmptyValue","option","groupTypes","TapestrySelect","items","item","handleSelectedValueChange","prompt","generatePrompt","selectedOption","_option$value","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","_selectedOption$meta","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","_field$allowUnanswere","specificDate","setSpecificDate","todaysValue","customValue","dateBeforeValue","orgFormat","dateFieldValue","setDateFieldValue","toDate","allowUnansweredOption","handleSelectChange","TapestryDateField","defaultOpen","formatValue","selectedValues","setSelectedValues","handleCheckboxesChange","newSelectedValues","minimumValue","minValue","maximumValue","maxValue","inputValue","setInputValue","Number","defaultValue","InputBox","TapestryNumberField","newNumberValue","min","max","hasControls","display","handleCheckedChange","Radio","Fields","newSelections","renderableFields","handleSelectedFieldOptionsChange","dependents","dependent","deeper","errorAlertProps","borderRadius","getVisibleApps","Topbar","apps","a","getWebhooksApps","OperationApp","getOperationDefinitions","OperationDefinition","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","_selectedDefinition$f","_selectedTriggerEvent","_selectedDefinition$f2","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","dynamicConditions","baseConditions","cloneDeep","writableFields","renderOnly","buildTriggerConditions","conditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","operationFields","required","every","fieldIsFilled","fieldIsSelect","nextRequiredDescription","renderedFields","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg","styles"],"mappings":"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"}
1
+ {"version":3,"file":"core-automations.modern.mjs","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/utils.ts","../../src/history.tsx","../../src/history_modal.tsx","../../src/utils/logos.ts","../../src/utils/response-labelers/people-form.ts","../../src/utils/resolve-response-details.ts","../../src/automation.tsx","../../src/utils/fetch-automations.ts","../../src/incoming_automations.tsx","../../src/definition.tsx","../../src/field.tsx","../../src/fields.tsx","../../src/new_automation.tsx","../../src/new_automation_modal.tsx","../../src/utils/theme.ts","../../src/automations.tsx","../../src/single_action_inline.tsx"],"sourcesContent":["import React from \"react\"\n\nconst SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { cloneDeep, isBoolean, set } from \"lodash\"\nimport moment from \"moment\"\n\nexport async function deobfuscateDescriptions(\n subscriptions: AutomationInstance[]\n) {\n return Promise.all(\n subscriptions.map(async (subscription) => {\n if (isDeobfuscatable(subscription)) {\n const result = await deobfuscatedDescription(subscription)\n subscription.description = result.description\n subscription.actionResourceUrl = result.actionResourceUrl\n subscription.actionResourceName = result.actionResourceName\n }\n return subscription\n })\n )\n}\n\nfunction isDeobfuscatable(subscription: AutomationInstance) {\n const DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES = [\n \"AddToWorkflowOperationDefinition\",\n \"CustomFieldBooleanOperationDefinition\",\n \"CustomFieldCheckboxesOperationDefinition\",\n \"CustomFieldDateOperationDefinition\",\n \"CustomFieldNumberOperationDefinition\",\n \"CustomFieldSelectOperationDefinition\",\n \"CustomFieldStringOperationDefinition\",\n \"CustomFieldTextOperationDefinition\",\n ]\n \n return DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES.includes(\n subscription.operationDefinitionClassName\n )\n}\n\nasync function deobfuscatedDescription(subscription: AutomationInstance) {\n let description = \"\"\n if (\n subscription.operationDefinitionClassName ===\n \"AddToWorkflowOperationDefinition\"\n ) {\n const data = await fetchWorkflow(subscription.operationParams.workflowId!)\n const workflow = data[0]\n\n if (workflow?.name) {\n const workflowName = workflow.archivedAt\n ? `[archived] ${workflow.name}`\n : workflow.name\n\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n workflowName\n )\n return {\n description,\n actionResourceUrl: workflow.links.html,\n actionResourceName: workflowName,\n }\n }\n } else {\n // custom field\n const fieldDefinitionId =\n subscription.operationParams.definitionIdentifier.match(\n /(\\d+)_field_definition/\n )![1]\n const fieldDefinition = await fetchFieldDefinition(fieldDefinitionId)\n if (fieldDefinition.name) {\n description = subscription.description.replace(\n \"[Hidden Custom Field]\",\n fieldDefinition.name\n )\n description +=\n subscription.operationParams.values ||\n fieldDefinition.dataType !== \"checkboxes\"\n ? ` (${customFieldOptionDescription(subscription, fieldDefinition)})`\n : \"\"\n }\n }\n return { description: description || subscription.description }\n}\n\nfunction customFieldOptionDescription(\n subscription: AutomationInstance,\n fieldDefinition: {\n dataType: string\n fieldOptions: { id: number; value: string }[]\n }\n) {\n switch (fieldDefinition.dataType) {\n case \"checkboxes\":\n return Object.entries(subscription.operationParams.values ?? {})\n .map(([id, action]) => {\n const value =\n fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(id, 10)\n )?.value || \"[Hidden value]\"\n return `${capitalize(action)} ${value}`\n })\n .join(\", \")\n case \"select\": {\n const value = subscription.operationParams.value\n return value\n ? fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(value, 10)\n )?.value || \"[Hidden value]\"\n : \"Unanswered\"\n }\n case \"boolean\":\n switch (subscription.operationParams.value) {\n case \"true\":\n return \"Yes\"\n case \"false\":\n return \"No\"\n default:\n return \"Unanswered\"\n }\n default:\n return subscription.operationParams.value ?? \"Unanswered\"\n }\n}\n\nfunction capitalize(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\nasync function fetchWorkflow(workflowId: number) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: { Workflow: \"name,archived_at\" },\n where: { id: workflowId },\n },\n url: `workflows`,\n })\n .catch(() => [{ data: { name: \"\" } }])\n\n return data\n}\n\nasync function fetchFieldDefinition(fieldDefinitionId: string) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n },\n url: `field_definitions/${fieldDefinitionId}`,\n })\n .catch(() => ({ data: { name: \"\" } }))\n\n return data\n}\n\nexport function fieldListIdentifier(field: DefinitionField) {\n if (field.listClass) {\n return `${field.id}_${field.listClass}`\n } else if (field.kind === \"PersonSearch\") {\n return `${field.id}_PersonSearch`\n } else {\n return null\n }\n}\n\nexport function buildDescription({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n return {\n description: describeSelectedFields({\n loadedLists: loadedLists || {},\n selectedDefinition,\n selectedFieldOptions,\n }),\n name: buildDescriptionName(selectedDefinition),\n }\n}\n\nfunction obfuscateDescriptionName(definition: OperationDefinition) {\n if (definition.definitionClass.match(/^CustomField\\w+OperationDefinition$/)) {\n return \"Update [Hidden Custom Field]\"\n }\n}\n\nfunction buildDescriptionName(definition: OperationDefinition) {\n return obfuscateDescriptionName(definition) || definition.description\n}\n\nfunction hasOwnProperty(object: object, key: PropertyKey) {\n return Object.prototype.hasOwnProperty.call(object, key)\n}\n\nfunction getListForField({\n field,\n loadedLists,\n}: {\n field: DefinitionField\n loadedLists: { [k: string]: LoadedList[] }\n}) {\n if (field.list) {\n return field.list\n } else if (fieldListIdentifier(field)) {\n const identifier = fieldListIdentifier(field) as string\n const list = loadedLists[identifier]\n\n return list\n } else {\n throw new Error(`Don't know how to get list for ${JSON.stringify(field)}`)\n }\n}\n\nexport function buildTriggerConditions({\n baseConditions,\n dynamicConditions,\n dynamicTriggerConditions,\n}: {\n baseConditions: object\n dynamicConditions: DefinitionField[] | undefined\n dynamicTriggerConditions: SelectedFieldOptions\n}) {\n const triggerConditions = cloneDeep(baseConditions)\n const fields = dynamicConditions ?? []\n const writableFields = fields.filter((field) => {\n if (field.renderOnly) return false\n return renderIfChainSatisfied(field, fields, dynamicTriggerConditions)\n })\n\n for (const field of writableFields) {\n if (\n Object.prototype.hasOwnProperty.call(dynamicTriggerConditions, field.id)\n ) {\n set(triggerConditions, field.id, dynamicTriggerConditions[field.id])\n }\n }\n\n return triggerConditions\n}\n\nfunction shouldRender(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!Object.prototype.hasOwnProperty.call(field, \"renderIf\")) return true\n\n const renderIf = field.renderIf!\n if (isBoolean(renderIf)) return renderIf\n\n const conditionKey = Object.keys(renderIf)[0]\n return renderIf[conditionKey] === selectedFieldOptions[conditionKey]\n}\n\nfunction renderIfChainSatisfied(\n field: DefinitionField,\n allFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n): boolean {\n if (!shouldRender(field, selectedFieldOptions)) return false\n\n const renderIf = field.renderIf\n if (renderIf == null || renderIf === true) return true\n\n const upstreamId = Object.keys(renderIf)[0]\n const upstream = allFields.find((f) => f.id === upstreamId)\n if (!upstream) return true\n return renderIfChainSatisfied(upstream, allFields, selectedFieldOptions)\n}\n\nexport function getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter(\n (field) =>\n field.kind !== \"Hidden\" &&\n renderIfChainSatisfied(field, definitionFields, selectedFieldOptions)\n )\n}\n\nfunction describeSelectedFields({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n const description = selectedDefinition.definitionFields\n .map((field) => {\n if (!hasOwnProperty(selectedFieldOptions, field.id)) return null\n\n const value = selectedFieldOptions[field.id]\n let list\n\n switch (field.kind) {\n case \"Select\":\n case \"SelectSearch\":\n case \"PersonSearch\":\n case \"RadioButtons\":\n list = getListForField({ field, loadedLists })\n\n return (\n list && list.find((o) => o.value.toString() === value)?.description\n )\n case \"Checkbox\":\n return value && field.label\n case \"Checkboxes\":\n list = getListForField({ field, loadedLists })\n\n return list\n .filter((e) => hasOwnProperty(value as object, e.value))\n .map(\n (e) =>\n `${capitalize((value as Record<string, string>)[e.value])} ${\n e.description\n }`\n )\n .join(\", \")\n case \"NumberField\":\n case \"TextField\":\n case \"TextArea\":\n case \"DateField\":\n return value\n default:\n throw new Error(\n `Don't know how to build value for field with kind ${field.kind}`\n )\n }\n })\n .filter((x) => x)\n .join(\", \")\n\n return obfuscateSelectedFieldDescriptions({\n description,\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n}\n\nfunction obfuscateSelectedFieldDescriptions({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n description,\n}: {\n description: string\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n if (\n selectedDefinition.definitionClass === \"AddToWorkflowOperationDefinition\"\n ) {\n const list = loadedLists.workflow_id_WorkflowsList\n const sensitiveString =\n list &&\n list.find((o) => o.value.toString() === selectedFieldOptions.workflow_id)\n ?.description\n\n return sensitiveString\n ? description.replace(sensitiveString, \"[Hidden Workflow]\")\n : description\n } else if (\n selectedDefinition.definitionClass.match(\n /^CustomField\\w+OperationDefinition$/\n )\n ) {\n return \"\"\n } else {\n return description\n }\n}\n\nexport function dateFNSFormat(format: string) {\n return format\n .replace(/%m/, \"M\")\n .replace(/%d/, \"d\")\n .replace(/%Y/, \"y\")\n .replace(/%y/, \"yy\")\n}\n\nexport function momentDateFormat(format: string) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({\n dateFormat,\n twentyFourHourTime,\n}: {\n dateFormat: string\n twentyFourHourTime: boolean\n}) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date: string, dateFormat: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n if (!momentDate.isValid()) {\n return \"\"\n }\n\n const format = momentDateFormat(dateFormat)\n return momentDate.format(format)\n}\n\nexport function numDaysSince(date: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n return moment().diff(momentDate, \"days\")\n}\n\nexport function pluralize(count: number, word: string) {\n if (count === 1) {\n return `1 ${word}`\n } else {\n return `${count} ${word}s`\n }\n}\n\nexport function singularize(string: string) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nexport function triggerResourceParts(triggerResource: string) {\n const triggerParts = triggerResource.split(\"/\")\n\n return {\n appName: triggerParts[0],\n resourceId: triggerParts[triggerParts.length - 1],\n resourcePath: triggerParts.slice(2, -1).join(\"/\"),\n resourceType: triggerParts[triggerParts.length - 2],\n }\n}\n\nexport function forbiddenText(error: any, action?: string) {\n if (error.errors?.[0]?.status === \"403\") {\n return `You don't have permission to ${action || \"modify\"} this automation.`\n }\n return null\n}\n\nexport function parseDescription(description: string) {\n const match = /^(.+?)\\((.+)\\)$/.exec(description)\n\n if (match) {\n return { description: match[\"2\"], name: match[\"1\"].trim() }\n } else {\n return { name: description }\n }\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Badge,\n Box,\n Button,\n DataTable,\n Heading,\n Icon,\n Input,\n Link,\n Select,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport moment from \"moment-timezone\"\nimport React, { useCallback, useContext, useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n dateLocalized,\n momentDateTimeFormat,\n numDaysSince,\n parseDescription,\n} from \"./utils/utils\"\n\ndeclare global {\n interface Window {\n openHelpdesk: () => void\n }\n}\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2022-07-14\",\n})\n\n// values should match the webhooks Event `status` enum entries\nconst STATUS = {\n delivered: {\n label: \"Success\",\n value: [\"delivered\"],\n },\n failed: {\n label: \"Failed\",\n value: [\"failed\", \"duplicated\"],\n },\n ignored: {\n label: \"Ignored\",\n value: [\"ignored_duplicated\", \"ignored_failed\", \"ignored_skipped\"],\n },\n pending: {\n label: \"Pending\",\n value: [\"pending\"],\n },\n skipped: {\n label: \"Paused\",\n value: [\"skipped\"],\n },\n}\n\nasync function fetchEvents(\n triggerResource: EncryptedTriggerResource,\n automationId: number,\n params: {\n offset: number\n per_page: number\n where?: { status: string } | null\n }\n) {\n const response = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n Delivery: \"status,response_body,created_at\",\n Event: \"id,created_at,last_delivery,payload,status,uuid,person\",\n },\n include: \"last_delivery\",\n order: \"-created_at\",\n ...params,\n },\n url: `automation_subscriptions/${automationId}/events`,\n })\n\n return response\n}\n\nasync function fetchPeople(personIds) {\n const { data } = await peopleClient.get({\n data: {\n fields: {\n Person: \"id,name\",\n },\n where: { id: personIds.join(\",\") },\n },\n url: `people`,\n })\n\n return data\n}\n\nasync function fetchPeopleWhoTriggeredEvents(events) {\n const personIds = events.data.map((e) => eventPersonId(e))\n try {\n const people = await fetchPeople(personIds)\n return { events, people }\n } catch (error) {\n return { events, people: [] }\n }\n}\n\nfunction mergePeopleAndEvents({ events, people }) {\n const mergedData = events.data.reduce((result, e) => {\n const personId = eventPersonId(e)\n const foundPerson = people.find(\n (p) => personId.toString() === p.id.toString()\n )\n if (foundPerson) {\n result.push({\n ...e,\n person: { id: foundPerson.id, name: foundPerson.name },\n })\n } else {\n result.push({\n ...e,\n person: { id: personId, name: \"[Hidden]\" },\n })\n }\n return result\n }, [])\n\n return { ...events, data: mergedData }\n}\n\nfunction eventPersonId(event) {\n return event.personId\n}\n\nfunction useEvents(\n automationId: number,\n triggerResource: EncryptedTriggerResource,\n filterWhere?: string\n) {\n const perPage = 50\n const [_, setError] = useState()\n const [loading, setLoading] = useState(false)\n const [eventPages, setEventPages] = useState<{ [k: number]: EventPage[] }>({})\n const [params, setParams] = useState<{ where?: { status: string } | null }>(\n filterWhere ? { where: { status: filterWhere } } : {}\n )\n const [meta, setMeta] = useState<{ totalCount: number | any }>()\n const { offset, paginationProps, resetOffset } = usePagination(\n perPage,\n meta?.totalCount\n )\n useEffect(() => {\n if (loading || eventPages[offset]) return\n\n setLoading(true)\n\n fetchEvents(triggerResource, automationId, {\n offset,\n per_page: perPage,\n ...params,\n })\n .then(fetchPeopleWhoTriggeredEvents)\n .then(mergePeopleAndEvents)\n .then((events) => {\n setEventPages((pages) => ({ ...pages, [offset]: events.data }))\n setMeta(events.meta)\n setLoading(false)\n })\n .catch(bubbleErrorToBoundary)\n }, [automationId, triggerResource, loading, params, offset, eventPages])\n\n const refresh = useCallback(() => {\n setEventPages({})\n setMeta(undefined)\n resetOffset()\n }, [resetOffset])\n\n useEffect(() => {\n refresh()\n }, [refresh, params])\n\n function bubbleErrorToBoundary(error) {\n setError(() => {\n throw error\n })\n }\n\n return {\n events: eventPages[offset] || [],\n loading,\n paginationProps,\n params,\n refresh,\n setParams,\n }\n}\n\nfunction usePagination(perPage: number, totalCount: number) {\n const [offset, setOffset] = useState(0)\n\n const currentPage = Math.floor(offset / perPage) + 1\n const totalPages = Math.ceil(totalCount / perPage)\n const paginationProps = { currentPage, onPageChange, totalPages }\n\n function onPageChange(pageNum: number) {\n setOffset((pageNum - 1) * perPage)\n }\n\n const resetOffset = useCallback(() => {\n setOffset(0)\n }, [])\n\n return { offset, paginationProps, resetOffset }\n}\n\ntype HistoryProps = {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: HistoryProps) {\n const { events, loading, paginationProps, refresh, params, setParams } =\n useEvents(automation.id, triggerResource, filterWhere)\n const { dateFormat, olsonTimeZone, twentyFourHourTime } = useContext<{\n dateFormat: any\n olsonTimeZone: any\n twentyFourHourTime: any\n }>(OrganizationContext)\n\n const filteringEvents = params.where && Object.keys(params.where).length > 0\n const automationCreatedRecently = numDaysSince(automation.createdAt) <= 32\n const automationBeganOn = dateLocalized(automation.createdAt, dateFormat)\n const historyPreservationAlert = automationCreatedRecently\n ? `Automation history started on ${automationBeganOn}`\n : \"Automation history is saved for 32 days\"\n\n const showTzLabel =\n Intl.DateTimeFormat().resolvedOptions().timeZone !== olsonTimeZone\n\n const { name, description } = parseDescription(automation.description)\n const { actionResourceUrl, actionResourceName } = automation\n let before = \"\"\n let after = \"\"\n if (description && actionResourceName) {\n const nameIndex = description.indexOf(actionResourceName)\n if (nameIndex !== -1) {\n before = description.slice(0, nameIndex)\n after = description.slice(nameIndex + actionResourceName.length)\n }\n }\n\n const columns = [\n {\n cell: (event: EventPage) => <EventStatusBadge status={event.status} />,\n css: {\n padding: \"8px 12px\",\n },\n header: \"Status\",\n },\n {\n cell: (event: EventPage) => {\n const baseFormat = momentDateTimeFormat({\n dateFormat,\n twentyFourHourTime,\n })\n const format = showTzLabel ? `${baseFormat} z` : baseFormat\n return moment.tz(event.createdAt, olsonTimeZone).format(format)\n },\n header: \"Date and time\",\n },\n {\n cell: (event: EventPage) => (\n <Link to={`/people/AC${event.person.id}`}>{event.person.name}</Link>\n ),\n css: {\n maxWidth: \"33%\",\n },\n header: \"Profile\",\n },\n {\n cell: (event: EventPage) => <EventStatusMessage event={event} />,\n css: {\n flex: 1,\n },\n header: \"Message\",\n },\n {\n cell: (event: EventPage) =>\n ![...STATUS.delivered.value, ...STATUS.pending.value].includes(\n event.status\n ) && (\n <>\n <RetryEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n onEventsStatusChange={onEventsStatusChange}\n />\n {![...STATUS.ignored.value].includes(event.status) && (\n <IgnoreEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n refreshHistory={refresh}\n onEventsStatusChange={onEventsStatusChange}\n />\n )}\n </>\n ),\n css: {\n textAlign: \"right\",\n },\n header: \"\",\n minWidth: \"84px\",\n },\n ]\n\n return (\n <StackView spacing={token(\"--t-spacing-4\")}>\n <StackView spacing={token(\"--t-spacing-half\")}>\n <Heading\n level={3}\n size=\"16px\"\n color={token(\"--t-text-color-secondary\")}\n weight={token(\"--t-font-weight-medium\")}\n >\n {name}{description && (\n <>\n {\" \"}({actionResourceUrl && actionResourceName\n ? <>{before}<Link to={actionResourceUrl}>{actionResourceName}</Link>{after}</>\n : description\n })\n </>\n )}\n </Heading>\n <Text\n color={token(\"--t-text-color-secondary\")}\n size={token(\"--t-font-size-xs\")}\n italic\n >\n {historyPreservationAlert}\n </Text>\n </StackView>\n <StackView spacing={token(\"--t-spacing-2\")}>\n <Box minHeight={7}>\n {!loading && (events.length || filteringEvents) && (\n <StackView\n alignItems=\"end\"\n axis=\"horizontal\"\n distribution=\"space-between\"\n spacing={token(\"--t-spacing-1\")}\n >\n <StackView width=\"max-content\">\n <Input.InputLabel\n fontWeight={token(\"--t-font-weight-medium\")}\n color={token(\"--t-text-color\")}\n controls=\"select-status\"\n >\n Filter by status\n </Input.InputLabel>\n <Select\n id=\"select-status\"\n emptyValue={null}\n onChange={({ selectedValue }) => {\n const newWhere = selectedValue\n ? { status: selectedValue }\n : null\n setParams({ where: newWhere })\n }}\n title=\"Status\"\n value={params.where?.status}\n >\n <Select.Option value={null}>All</Select.Option>\n {Object.values(STATUS).map((status) => (\n <Select.Option\n key={status.value}\n value={status.value.join(\",\")}\n >\n {status.label}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n <Button\n iconLeft={{ name: \"general.refresh\" }}\n onClick={refresh}\n theme=\"primary\"\n variant=\"outline\"\n width={12}\n >\n Refresh\n </Button>\n </StackView>\n )}\n </Box>\n <Box maxHeight=\"70vh\" minHeight={36} overflow=\"auto\">\n <DataTable\n columns={columns}\n data={events}\n empty={\n <StackView\n alignment=\"center\"\n distribution=\"center\"\n minHeight={20}\n maxWidth={45}\n spacing={token(\"--t-spacing-1\")}\n marginTop={!filteringEvents ? -8 : -4}\n marginBottom={!filteringEvents ? undefined : 4}\n >\n <Box\n css={{\n svg: {\n height: 15,\n width: 20,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <Heading\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n level={4}\n size={token(\"--t-font-size-lg\")}\n >\n No history found\n </Heading>\n <Text fontSize={token(\"--t-font-size-md\")} textAlign=\"center\">\n No events {filteringEvents && \"matching your filters\"} were\n triggered for this automation{\" \"}\n {automationCreatedRecently\n ? `since ${automationBeganOn}.`\n : \"in the last 32 days.\"}\n </Text>\n {filteringEvents && (\n <Button\n marginTop={token(\"--t-spacing-1\")}\n onClick={() => setParams({})}\n theme=\"primary\"\n title=\"Clear filters\"\n variant=\"outline\"\n />\n )}\n </StackView>\n }\n loading={loading}\n loadingTitle=\"Loading automation history...\"\n variant={{\n bodyCell: {\n alignItems: \"start\",\n fontSize: token(\"--t-font-size-sm\"),\n lineHeight: \"20px\",\n padding: \"10px 12px\",\n },\n bodyRow: ({ rowData }) => {\n return {\n backgroundColor: [...STATUS.ignored.value].includes(\n rowData.status\n )\n ? token(\"--t-fill-color-neutral-090\")\n : undefined,\n minHeight: \"36px\",\n }\n },\n headerCell: {\n padding: \"8px 12px\",\n },\n headerRow: {\n minHeight: \"36px\",\n },\n }}\n {...paginationProps}\n />\n </Box>\n </StackView>\n </StackView>\n )\n}\n\nfunction RetryEventButton({\n automationId,\n event,\n triggerResource,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n triggerResource: EncryptedTriggerResource\n}) {\n const [status, setStatus] = useState(event.status)\n\n function handleRetry() {\n setStatus(STATUS.pending.value.join(\",\"))\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/redeliver`,\n })\n .then((response) => {\n setStatus(STATUS.delivered.value.join(\",\"))\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .catch(() => {\n setStatus(STATUS.failed.value.join(\",\"))\n alerts.alertError.fire({\n text: \"There was a problem retrying this automation. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n const retryTitleFromStatus = STATUS.pending.value.includes(status)\n ? \"Sending\"\n : STATUS.delivered.value.includes(status)\n ? \"Sent\"\n : STATUS.skipped.value.includes(status)\n ? \"Run now\"\n : \"Retry\"\n\n const statusIcon = STATUS.delivered.value.includes(status)\n ? { color: token(\"--t-text-color-status-success\"), name: \"general.check\" }\n : undefined\n\n return (\n <Button\n title={retryTitleFromStatus}\n onClick={handleRetry}\n iconLeft={statusIcon}\n disabled={status !== event.status}\n variant=\"naked\"\n color={\n STATUS.delivered.value.includes(status)\n ? token(\"--t-text-color-status-success\")\n : STATUS.pending.value.includes(status)\n ? token(\"--t-text-color-placeholder\")\n : token(\"--t-text-color-interaction\")\n }\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction IgnoreEventButton({\n automationId,\n event,\n triggerResource,\n refreshHistory,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n refreshHistory: Function\n triggerResource: EncryptedTriggerResource\n}) {\n function handleIgnore() {\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/ignore`,\n })\n .then((response) => {\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .then(() => refreshHistory())\n .catch(() => {\n alerts.alertError.fire({\n text: \"There was a problem ignoring this event. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n return (\n <Button\n title={\"Ignore\"}\n onClick={handleIgnore}\n variant=\"naked\"\n color={\"linkForeground\"}\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction EventStatusBadge({ status }: { status: string }) {\n const badgeColors = STATUS.pending.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color\"),\n }\n : STATUS.delivered.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-success\"),\n text: token(\"--t-text-color-status-success\"),\n }\n : STATUS.skipped.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-warning\"),\n text: token(\"--t-text-color-status-warning\"),\n }\n : STATUS.ignored.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color-secondary\"),\n }\n : {\n border: token(\"--t-border-color-status-error\"),\n text: token(\"--t-text-color-status-error\"),\n }\n\n const badgeIcon = STATUS.pending.value.includes(status)\n ? \"general.clock\"\n : STATUS.skipped.value.includes(status)\n ? \"services.pause\"\n : STATUS.delivered.value.includes(status)\n ? \"general.checkCircle\"\n : STATUS.ignored.value.includes(status)\n ? \"general.inactive\"\n : \"general.exclamationTriangle\"\n\n const badgeTitle = STATUS.failed.value.includes(status)\n ? STATUS.failed.label\n : STATUS.ignored.value.includes(status)\n ? STATUS.ignored.label\n : STATUS[status].label\n\n return (\n <Badge\n color={{ background: \"transparent\", foreground: badgeColors.text }}\n css={{ paddingLeft: 3.5, paddingRight: 1.5 }}\n fontSize={token(\"--t-font-size-xs\")}\n radius=\"pill\"\n renderLeft={\n <Icon\n name={badgeIcon}\n color={badgeColors.border}\n marginLeft={token(\"--t-spacing-1\")}\n />\n }\n size=\"sm\"\n stroke={badgeColors.border}\n strokeAlign=\"inside\"\n strokeWeight={1}\n title={badgeTitle}\n />\n )\n}\n\nfunction EventStatusMessage({ event }: { event: EventPage }) {\n const { status, lastDelivery } = event\n\n function statusMessage(status: string, lastDelivery: Delivery) {\n let message: string | JSX.Element | null = null\n\n switch (status) {\n case \"skipped\":\n case \"ignored_skipped\":\n message = \"Automation was paused and did not run on this profile\"\n break\n case \"failed\":\n case \"duplicated\":\n case \"ignored_failed\":\n case \"ignored_duplicated\":\n message = deliveryFailureReason(lastDelivery, status)\n }\n\n return message\n }\n\n function deliveryFailureReason(delivery: Delivery, status: string) {\n const ERRORS = {\n 403: \"Owner doesn't have permission to perform this action.\",\n 404: \"Owner lacks access to target product or resource doesn't exist.\",\n 422: \"The automation action failed to run\",\n default: \"An error occurred\",\n duplicated_event:\n \"Didn't run because the same action had already been performed less than 60 seconds ago\",\n failed_without_deliveries:\n \"Didn't run because the owner doesn't have permissions in this product.\",\n }\n\n function responseErrors(delivery: Delivery) {\n if (!delivery?.responseBody) return null\n let response\n\n try {\n response = JSON.parse(delivery.responseBody)\n } catch {\n response = { errors: [\"Server Error\"] }\n }\n\n return parsedErrors(response).join(\", \") || response?.message\n }\n\n function parsedErrors(response) {\n if (response?.errors) {\n return response.errors.map((error) =>\n typeof error === \"string\" && error.match(/Archived profiles/)\n ? error.replace(/Archived profiles/, \"Archived profiles.\")\n : error\n )\n } else {\n return []\n }\n }\n\n return (\n <StackView flex={1} whiteSpace=\"normal\">\n {!delivery ? (\n [\"duplicated\", \"ignored_duplicated\"].includes(status) ? (\n ERRORS.duplicated_event\n ) : (\n ERRORS.failed_without_deliveries\n )\n ) : (\n <ToggleableDetails\n details={responseErrors(delivery)}\n status={delivery.status}\n >\n {ERRORS[delivery.status] || ERRORS.default}\n </ToggleableDetails>\n )}\n </StackView>\n )\n }\n\n const message = statusMessage(status, lastDelivery)\n\n return message ? (\n <Box\n fontSize={token(\"--t-font-size-sm\")}\n fontStyle=\"italic\"\n lineHeight=\"16px\"\n maxWidth=\"100%\"\n paddingTop=\"1px\"\n whiteSpace=\"normal\"\n >\n {message}\n </Box>\n ) : null\n}\n\nfunction ToggleableDetails({\n children,\n details,\n status,\n}: {\n children: React.ReactNode\n details: string\n status: string\n}) {\n const [open, setOpen] = useState(false)\n\n function toggleOpen() {\n setOpen((was) => !was)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Box>\n {children}{\" \"}\n {details && (\n <Button\n inline\n onClick={toggleOpen}\n size=\"xs\"\n theme=\"primary\"\n variant=\"naked\"\n fontStyle=\"normal\"\n >\n Details\n </Button>\n )}\n </Box>\n {open ? (\n <Box padding={1} background={token(\"--t-fill-color-neutral-090\")}>\n <Text\n fontFamily=\"monospace\"\n fontSize={token(\"--t-font-size-xs\")}\n lineHeight=\"1.2\"\n >\n {status && `${status}: `}\n {details}\n </Text>\n </Box>\n ) : null}\n </StackView>\n )\n}\n\ntype ErrorBoundaryProps = {\n children: React.ReactNode\n onRequestClose?: () => void\n}\n\ntype ErrorBoundaryState = {\n hasError: boolean\n}\n\nclass ErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props) {\n super(props)\n this.state = { hasError: false }\n }\n\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n\n handleContactSupport = () => {\n if (this.props.onRequestClose) {\n this.props.onRequestClose()\n }\n window.openHelpdesk()\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <Alert\n type=\"error\"\n marginVertical={1}\n padding={1.5}\n css={{ boxShadow: \"none\" }}\n >\n <Text lineHeight=\"1.35\">\n The application hit an unexpected error. If this persists after a\n few minutes, please let us know so we can get it fixed for you.{\" \"}\n <button\n style={{\n color: token(\"--t-text-color-interaction\"),\n whiteSpace: \"nowrap\",\n }}\n onClick={this.handleContactSupport}\n >\n Contact support\n </button>\n .\n </Text>\n </Alert>\n )\n }\n\n return this.props.children\n }\n}\n\n// eslint-disable-next-line react/display-name\nexport default (props: HistoryProps) => (\n <ErrorBoundary onRequestClose={props.onRequestClose}>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-dim\"),\n name: \"general.x\",\n }}\n onClick={onClick}\n size=\"sm\"\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction HistoryModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={120}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Automation history\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default HistoryModal\n","import { Logo } from \"@planningcenter/tapestry-react\"\nimport { kebabCase } from \"lodash\"\nimport type { ComponentProps } from \"react\"\n\n// Extract valid logo names from the Logo component's props\ntype ValidLogoName = NonNullable<ComponentProps<typeof Logo>[\"name\"]>\n\n// List of valid logo names from @planningcenter/tapestry-react Logo component\n// Update this list when support for new products are added to tapestry-react\nconst VALID_LOGO_NAMES: ValidLogoName[] = [\n \"api\",\n \"calendar\",\n \"check-ins\",\n \"church-center\",\n \"giving\",\n \"groups\",\n \"headcounts\",\n \"home\",\n \"login\",\n \"music-stand\",\n \"people\",\n \"planning-center\",\n \"publishing\",\n \"registrations\",\n \"services\",\n]\n\nexport const isValidLogoName = (name: string): name is ValidLogoName => {\n return VALID_LOGO_NAMES.includes(name as ValidLogoName)\n}\n\nexport const getValidLogoName = (name: string): ValidLogoName => {\n const kebabName = kebabCase(name)\n return isValidLogoName(kebabName) ? kebabName : \"planning-center\"\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { uniq } from \"lodash\"\n\nimport type { ResponseLabeler } from \"./types\"\n\nconst HIDDEN_FIELD = \"[Hidden Field]\"\nconst HIDDEN_RESPONSE = \"[Hidden Response]\"\nconst FIELD_KEY_RE = /^field_(\\d+)$/\nconst SENTINEL_VALUES = new Set([\"no-option\"])\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\ntype FormFieldRecord = {\n fieldType: string\n fieldableId: number | null\n fieldableType: string | null\n id: number\n label: string | null\n options?: { id: number; label: string | null }[]\n}\n\ntype FieldDefinitionRecord = {\n dataType: string\n fieldOptions?: { id: number; value: string | null }[]\n id: number\n name: string | null\n}\n\ntype CampusRecord = {\n id: number\n name: string | null\n}\n\ntype ExtractedIds = {\n fieldId: string\n formId: string\n optionId: string | null\n}\n\nasync function resolve(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const extracted = subscriptions.map((sub) => ({\n ids: extractIds(sub),\n sub,\n }))\n const targets = extracted.filter(\n (entry): entry is { ids: ExtractedIds; sub: AutomationInstance } =>\n entry.ids !== null\n )\n if (targets.length === 0) return subscriptions\n\n const fieldsByForm = await fetchFormFields(\n uniq(targets.map((t) => t.ids.formId))\n )\n\n const fieldDefIds = new Set<string>()\n const campusIds = new Set<string>()\n for (const { ids } of targets) {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (field?.fieldType === \"custom_field\" && field.fieldableId != null) {\n fieldDefIds.add(String(field.fieldableId))\n } else if (field?.fieldType === \"primary_campus\" && ids.optionId != null) {\n campusIds.add(ids.optionId)\n }\n }\n const [fieldDefs, campuses] = await Promise.all([\n fetchFieldDefinitions([...fieldDefIds]),\n fetchCampuses([...campusIds]),\n ])\n\n return extracted.map(({ ids, sub }) => {\n if (!ids) return sub\n return {\n ...sub,\n responseDetails: buildResponseDetails(\n ids,\n fieldsByForm,\n fieldDefs,\n campuses\n ),\n }\n })\n}\n\nfunction extractIds(subscription: AutomationInstance): ExtractedIds | null {\n const conds = subscription.triggerConditions\n const formId = conds?.data?.relationships?.form?.data?.id\n const selectedOptionsByField = conds?.data?.attributes?.selectedOptionsByField\n if (\n formId == null ||\n !selectedOptionsByField ||\n typeof selectedOptionsByField !== \"object\"\n ) {\n return null\n }\n\n for (const [key, value] of Object.entries(selectedOptionsByField)) {\n const match = FIELD_KEY_RE.exec(key)\n if (!match) continue\n const raw = (value as { $in?: unknown })?.$in\n const optionIds = (Array.isArray(raw) ? raw : raw == null ? [] : [raw])\n .map((id) => (id == null ? null : String(id)))\n .filter((id): id is string => id != null && !SENTINEL_VALUES.has(id))\n return {\n fieldId: match[1],\n formId: String(formId),\n optionId: optionIds[0] ?? null,\n }\n }\n return null\n}\n\nasync function fetchFormFields(\n formIds: string[]\n): Promise<Map<string, Map<string, FormFieldRecord>>> {\n const result = new Map<string, Map<string, FormFieldRecord>>()\n await Promise.all(\n formIds.map(async (formId) => {\n try {\n const { data } = await peopleClient.get<{ data: FormFieldRecord[] }>({\n data: {\n fields: {\n FormField: \"label,field_type,fieldable,options\",\n FormFieldOption: \"label\",\n },\n include: \"options\",\n walk: true,\n },\n url: `forms/${formId}/fields`,\n })\n const byId = new Map<string, FormFieldRecord>()\n for (const field of data) {\n byId.set(String(field.id), field)\n }\n result.set(formId, byId)\n } catch {\n result.set(formId, new Map())\n }\n })\n )\n return result\n}\n\nasync function fetchFieldDefinitions(\n ids: string[]\n): Promise<Map<string, FieldDefinitionRecord>> {\n const result = new Map<string, FieldDefinitionRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: FieldDefinitionRecord[] }>({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"field_definitions\",\n })\n for (const fd of data) {\n result.set(String(fd.id), fd)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nasync function fetchCampuses(\n ids: string[]\n): Promise<Map<string, CampusRecord>> {\n const result = new Map<string, CampusRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: CampusRecord[] }>({\n data: {\n fields: { Campus: \"name\" },\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"campuses\",\n })\n for (const campus of data) {\n result.set(String(campus.id), campus)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nfunction buildResponseDetails(\n ids: ExtractedIds,\n fieldsByForm: Map<string, Map<string, FormFieldRecord>>,\n fieldDefs: Map<string, FieldDefinitionRecord>,\n campuses: Map<string, CampusRecord>\n): ResponseDetails {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (!field) return { fieldLabel: HIDDEN_FIELD, valueLabel: HIDDEN_RESPONSE }\n\n const fieldLabel = field.label || HIDDEN_FIELD\n\n if (field.fieldType === \"boolean\") {\n return { fieldLabel, valueLabel: null }\n }\n\n if (field.fieldType === \"custom_field\" && field.fieldableId != null) {\n const fd = fieldDefs.get(String(field.fieldableId))\n if (!fd) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n if (fd.dataType === \"boolean\") return { fieldLabel, valueLabel: null }\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const match = (fd.fieldOptions || []).find(\n (o) => String(o.id) === ids.optionId\n )\n return { fieldLabel, valueLabel: match?.value || HIDDEN_RESPONSE }\n }\n\n if (field.fieldType === \"primary_campus\") {\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const campus = campuses.get(ids.optionId)\n return { fieldLabel, valueLabel: campus?.name || HIDDEN_RESPONSE }\n }\n\n if (ids.optionId == null) {\n return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n }\n const match = (field.options || []).find((o) => String(o.id) === ids.optionId)\n return { fieldLabel, valueLabel: match?.label || HIDDEN_RESPONSE }\n}\n\nconst peopleFormLabeler: ResponseLabeler = { resolve }\n\nexport { peopleFormLabeler }\n","import { peopleFormLabeler } from \"./response-labelers/people-form\"\nimport type { ResponseLabeler } from \"./response-labelers/types\"\n\nconst labelers: Record<string, ResponseLabeler> = {\n \"people.v2.events.form_submission.created\": peopleFormLabeler,\n}\n\nasync function resolveResponseDetails(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const groups = new Map<string, AutomationInstance[]>()\n for (const sub of subscriptions) {\n if (!labelers[sub.name]) continue\n const group = groups.get(sub.name) ?? []\n group.push(sub)\n groups.set(sub.name, group)\n }\n if (groups.size === 0) return subscriptions\n\n const resolvedById = new Map<number, AutomationInstance>()\n await Promise.all(\n [...groups.entries()].map(async ([name, subs]) => {\n const resolved = await labelers[name].resolve(subs)\n for (const sub of resolved) resolvedById.set(sub.id, sub)\n })\n )\n\n return subscriptions.map((sub) => resolvedById.get(sub.id) ?? sub)\n}\n\nfunction formatResponseDetails(\n responseDetails: ResponseDetails | null | undefined\n): string {\n if (!responseDetails) return \"\"\n const { fieldLabel, valueLabel } = responseDetails\n if (valueLabel == null) return ` with \"${fieldLabel}\" selected`\n return ` with \"${fieldLabel}\" selected as \"${valueLabel}\"`\n}\n\nexport { formatResponseDetails, resolveResponseDetails }\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n Logo,\n StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { lowerFirst, truncate } from \"lodash\"\nimport React, { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { formatResponseDetails } from \"./utils/resolve-response-details\"\nimport { dateLocalized, forbiddenText, parseDescription } from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n disabled?: boolean\n disabledReason?: string\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationProps = {\n automation: IncomingAutomationInstance\n}\n\ntype EditableAutomationContextType = {\n automation: AutomationInstance\n currentPersonCanCreate?: boolean\n currentPersonId?: number\n theme: object\n trigger?: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation?: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationContextType = {\n automation: IncomingAutomationInstance\n}\n\nconst AutomationContext = createContext<\n EditableAutomationContextType | IncomingAutomationContextType\n>(null)\n\nfunction EditableAutomation({\n updateAutomation,\n onDelete,\n theme,\n openHistoryNow = false,\n disabled,\n disabledReason,\n ...props\n}: AutomationProps & {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper\n theme={theme}\n updateAutomation={updateAutomation}\n {...props}\n >\n <Header>\n <Icons />\n <Manage\n onDelete={onDelete}\n openHistoryNow={openHistoryNow}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n </Header>\n <Description />\n <EditableFooter />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingAutomation(props: IncomingAutomationProps) {\n return (\n <AutomationWrapper automation={props.automation}>\n <Header>\n <Icons />\n <LinkToAutomation />\n </Header>\n <IncomingDescription />\n <Footer />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingDescription() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n const triggerEventDescription = automation.triggerEventDescription\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-medium\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n {formatResponseDetails(automation.responseDetails)}, then{\" \"}\n {lowerFirst(name)} {conditionalSuffix(automation)}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction LinkToAutomation() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n return (\n <Button\n external\n iconLeft={{ name: \"general.newWindow\" }}\n variant=\"naked\"\n size=\"sm\"\n to={automation.triggerAdminUrl}\n disabled={!automation.canManage}\n tooltip={\n !automation.canManage\n ? \"You do not have access to this resource\"\n : undefined\n }\n color={token(\"--t-text-color-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-secondary\"),\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation,\n updateAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n updateAutomation?: (automation: AutomationInstance) => void\n}) {\n return (\n <AutomationContext.Provider\n value={{\n automation,\n theme,\n updateAutomation,\n ...rest,\n }}\n >\n <Card radius={4} padding={2}>\n {children}\n </Card>\n </AutomationContext.Provider>\n )\n}\n\nfunction Header({ children }: { children: React.ReactNode }) {\n const { automation } = useContext(AutomationContext)\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n padding={0}\n distribution=\"space-between\"\n opacity={cardOpacity}\n >\n {children}\n </StackView>\n )\n}\n\nfunction Manage({\n onDelete,\n openHistoryNow = false,\n disabled,\n disabledReason,\n}: {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n}) {\n const {\n automation,\n currentPersonCanCreate,\n currentPersonId,\n trigger,\n theme,\n updateAutomation,\n } = useContext(AutomationContext) as EditableAutomationContextType\n const [historyVisible, setHistoryVisible] = useState(openHistoryNow)\n const isActive = automation.active\n const { name } = parseDescription(automation.description)\n\n function showHistory() {\n setHistoryVisible(true)\n }\n\n function updateEventsStatus(newStatus: AutomationInstance[\"eventsStatus\"]) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n function handleToggleActive() {\n webhooksClient\n .patch({\n data: {\n _e: trigger.resource,\n data: {\n attributes: {\n active: !isActive,\n },\n },\n },\n url: `/automation_subscriptions/${automation.id}`,\n })\n .then((data: { data: { active: boolean } }) => {\n updateAutomation((prev) => ({ ...prev, active: data.data.active }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"pause\") ||\n `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handleReassign() {\n alerts.confirm\n .fire({\n text: \"This automation will run with your permission levels. Other administrators who can see this automation can grant it their permissions by reassigning it to themselves.\",\n title: \"Reassign automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) {\n webhooksClient\n .post({\n data: {\n _e: trigger.resource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automation.id}/self_assign`,\n })\n .then(({ data }) => fetchCurrentPersonAvatar(data))\n .then(({ subscription, avatar }) => {\n updateAutomation((prev) => ({\n ...prev,\n createdBy: { ...prev.createdBy, avatarUrl: avatar },\n createdById: subscription.createdById,\n createdByName: subscription.createdByName,\n }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"update\") ||\n \"There was a problem updating this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n })\n }\n\n function handleDelete() {\n alerts.confirmDestroy\n .fire({\n confirmButtonText: \"Yes, delete automation\",\n text: `Are you sure you want to delete the \"${name}\" automation? This cannot be undone.`,\n title: \"Delete this automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) onDelete(automation.id)\n })\n }\n\n return (\n <>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Dropdown\n icon={{\n color: token(\"--t-icon-color\"),\n name: \"churchCenter.threeDots\",\n }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\n disabled={disabled}\n >\n <Dropdown.Item onSelect={() => showHistory()}>History</Dropdown.Item>\n {currentPersonCanCreate &&\n (automation.createdById === currentPersonId ? (\n <Dropdown.Item disabled={true}>\n <Tooltip\n placement=\"left\"\n openDelay={250}\n title=\"This automation is already assigned to you.\"\n >\n <Text>Reassign to me...</Text>\n </Tooltip>\n </Dropdown.Item>\n ) : (\n <Dropdown.Item onSelect={handleReassign}>\n Reassign to me...\n </Dropdown.Item>\n ))}\n <Dropdown.Item onSelect={handleDelete}>Delete...</Dropdown.Item>\n </Dropdown>\n <ToggleSwitch\n isChecked={isActive}\n size=\"sm\"\n onClick={handleToggleActive}\n tooltip={\n disabled\n ? disabledReason\n : isActive\n ? \"Pause automation\"\n : \"Enable automation\"\n }\n disabled={disabled}\n />\n </StackView>\n\n <HistoryModal\n open={historyVisible}\n onRequestClose={() => setHistoryVisible(false)}\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n onEventsStatusChange={updateEventsStatus}\n onRequestClose={() => setHistoryVisible(false)}\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Icons() {\n const { automation } = useContext(AutomationContext)\n const triggerProductName = automation.name.split(\".\")[0]\n\n return (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.5}>\n <Logo\n markOnly={true}\n name={getValidLogoName(triggerProductName)}\n size=\"sm\"\n theme=\"color\"\n />\n <Icon name=\"general.rightArrow\" size={1.5} />\n <Logo\n markOnly={true}\n name={getValidLogoName(automation.operationAppName)}\n size=\"sm\"\n theme=\"color\"\n />\n </StackView>\n )\n}\nfunction Footer() {\n const { automation } = useContext(AutomationContext)\n const { dateFormat } = useContext(OrganizationContext)\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-half\")}\n maxWidth=\"calc(100% - 136px)\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={2}\n height={2}\n basis={2}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={5} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n </>\n )\n}\n\nfunction EditableFooter() {\n const { dateFormat } = useContext(OrganizationContext)\n const { automation, trigger, theme, updateAutomation } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n const buttonProps = {\n color: token(\"--t-text-color-secondary\"),\n fontSize: token(\"--t-font-size-xs\"),\n fontWeight: token(\"--t-font-weight-normal\"),\n paddingHorizontal: token(\"--t-spacing-1\"),\n radius: \"pill\",\n size: \"xs\",\n variant: \"naked\",\n }\n const [historyProps, setHistoryProps] = useState({\n filter: null,\n historyVisible: false,\n })\n\n function renderSkippedHistory() {\n setHistoryProps({ filter: \"skipped\", historyVisible: true })\n }\n\n function renderFailedOrDuplicatedHistory() {\n setHistoryProps({ filter: \"failed,duplicated\", historyVisible: true })\n }\n\n function handleEventsStatusChange(\n newStatus: AutomationInstance[\"eventsStatus\"]\n ) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-fourth\")}\n >\n {!!automation.eventsStatus?.skipped && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.skipped} skipped`}\n onClick={renderSkippedHistory}\n tooltip={`${automation.eventsStatus.skipped?.toLocaleString()} skipped events`}\n >\n <Box\n backgroundColor={token(\"--t-fill-color-status-warning\")}\n marginRight={token(\"--t-spacing-half\")}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding={token(\"--t-spacing-fourth\")}\n >\n <Icon\n name={\"services.pause\"}\n size={\"6px\"}\n title={\"Skipped\"}\n color=\"white\"\n />\n </Box>\n {`${automation.eventsStatus.skipped?.toLocaleString()}`}\n </Button>\n )}\n {!!automation.eventsStatus?.failed && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.failed} failed`}\n iconLeft={{\n color: token(\"--t-icon-color-status-error\"),\n marginRight: token(\"--t-spacing-half\"),\n name: \"general.exclamationTriangle\",\n size: \"10px\",\n title: \"Failed\",\n }}\n onClick={renderFailedOrDuplicatedHistory}\n title={`${automation.eventsStatus.failed?.toLocaleString()}`}\n tooltip={`${automation.eventsStatus.failed?.toLocaleString()} failed events`}\n />\n )}\n </StackView>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"end\"\n flex={1}\n spacing={token(\"--t-spacing-half\")}\n marginLeft=\"auto\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={token(\"--t-element-size-md\")}\n height={token(\"--t-element-size-md\")}\n basis={token(\"--t-element-size-md\")}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={token(\"--t-font-size-sm\")} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n\n <HistoryModal\n open={historyProps.historyVisible}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n filterWhere={historyProps.filter}\n onEventsStatusChange={handleEventsStatusChange}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Description() {\n const { automation, trigger } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n const triggerEventDescription = [\n \"When a person\",\n lowerFirst(trigger.event.description) +\n formatResponseDetails(automation.responseDetails) +\n \",\",\n \"then\",\n lowerFirst(name),\n conditionalSuffix(automation),\n ].join(\" \")\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-bold\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction optionallyPrettifyArchivedPrefix(description: string) {\n if (description?.startsWith(\"[archived]\")) {\n return description.replace(\"[archived]\", \"[Archived]\")\n } else {\n return description\n }\n}\n\nasync function fetchCurrentPersonAvatar(subscription: AutomationInstance) {\n const {\n data: { avatar },\n } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n },\n url: \"me\",\n })\n\n return { avatar, subscription }\n}\n\nexport { EditableAutomation, IncomingAutomation }\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { compact, uniq } from \"lodash\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\nasync function fetchAutomations(triggerResource: EncryptedTriggerResource) {\n const { data } = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,events_status,trigger_conditions,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { truncate, upperFirst } from \"lodash\"\nimport React, { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nasync function fetchIncomingAutomations(encryptedParam) {\n const { data } = await webhooksClient.get({\n data: {\n _e: encryptedParam,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,trigger_conditions,trigger_resource,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"incoming_automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchTriggerResources(automations) {\n // We can optimize the query by fetching all the resources at once if we know\n // that the endpoint supports querying by multiple ids. Otherwise, we'll have\n // to fetch each resource individually.\n const QUERYABLE_BY_MULTIPLE_IDS = {\n people: [\"forms\", \"lists\"],\n registrations: [\"events\"],\n services: [\"teams\"],\n }\n const NOT_QUERYABLE = [\"giving\"]\n\n const automationsByModel = automations.reduce((accumulator, automation) => {\n // registrations has a weird case of signup vs event\n const automationTriggerResource = automation.triggerResource.replace(\n /signup/,\n \"event\"\n )\n const { appName, resourceType, resourcePath, resourceId } =\n triggerResourceParts(automationTriggerResource)\n\n if (!accumulator[appName]) accumulator[appName] = {}\n if (!accumulator[appName][resourceType])\n accumulator[appName][resourceType] = {}\n if (!accumulator[appName][resourceType][\"resoucePath\"])\n accumulator[appName][resourceType][\"resourcePath\"] = resourcePath\n\n if (!accumulator[appName][resourceType][\"ids\"])\n accumulator[appName][resourceType][\"ids\"] = []\n\n accumulator[appName][resourceType][\"ids\"].push(resourceId)\n\n return accumulator\n }, {})\n\n const promises = Object.keys(automationsByModel).flatMap((appName) => {\n const automationsByResourceType = automationsByModel[appName]\n\n return Object.entries(automationsByResourceType).flatMap(\n ([resourceType, resourceParts]) => {\n const fetchFn = NOT_QUERYABLE.includes(appName)\n ? fetchNothing\n : QUERYABLE_BY_MULTIPLE_IDS[appName]?.includes(resourceType)\n ? fetchAllAtOnce\n : fetchOneAtATime\n\n return fetchFn({\n appName,\n ids: resourceParts[\"ids\"],\n resourcePath: resourceParts[\"resourcePath\"],\n resourceType,\n })\n }\n )\n })\n\n const results = await Promise.allSettled(promises)\n\n return {\n automations,\n triggerResources: collectSuccessfulResults(results),\n }\n}\n\nfunction collectSuccessfulResults(settledPromises) {\n return settledPromises\n .reduce((acc, result) => {\n if (result.status === \"fulfilled\") acc = acc.concat(result.value)\n\n return acc\n }, [])\n .flatMap((d) => d.data)\n}\n\nfunction fetchAllAtOnce({ appName, resourcePath, resourceType, ids }) {\n return fetchResourceName({\n appName,\n params: {\n where: { id: ids.join(\",\") },\n },\n path: resourcePath,\n resourceType,\n })\n}\n\nfunction fetchOneAtATime({ appName, resourcePath, resourceType, ids }) {\n return ids.map((id) =>\n fetchResourceName({\n appName,\n path: `${resourcePath}/${id}`,\n resourceType,\n })\n )\n}\n\nfunction fetchNothing(_props: object) {\n return new Promise((_, reject) => {\n reject()\n })\n}\n\n// TODO (maybe): move these to webhooks, return the verb in the API response,\n// so new events don't need a code change in both places\nfunction mapNameToVerb(messageName) {\n // e.g. \"groups.v2.events.membership.created\" => \"groups.membership.created\"\n const appResourceAction = messageName.replace(\"v2.events.\", \"\")\n\n switch (appResourceAction) {\n case \"groups.membership.created\":\n return \"joins\"\n case \"groups.membership.destroyed\":\n return \"leaves\"\n case \"people.list_result.created\":\n case \"services.team_person.created\":\n return \"is added to\"\n case \"people.list_result.destroyed\":\n case \"services.team_person.destroyed\":\n return \"is removed from\"\n case \"people.form_submission.created\":\n return \"submits\"\n case \"registrations.attendee.created\":\n return \"is registered as a new attendee for\"\n case \"registrations.attendee.cancelled\":\n return \"is canceled as an attendee for\"\n case \"registrations.registration.created\":\n return \"is the registration contact on a new registration for\"\n case \"registrations.registration.cancelled\":\n return \"is the registration contact on a canceled registration for\"\n default:\n return null\n }\n}\n\nfunction buildGivingDescription(automation: AutomationInstance) {\n const action = automation.name.replace(\"giving.v2.events.\", \"\")\n\n switch (action) {\n case \"donation.payment_successful\":\n return \"When a person gives\"\n case \"profile.first_donated_automation\":\n return \"When a person gives for the first time\"\n case \"recurring_donation.setup_successful\":\n return \"When a person sets up a recurring donation\"\n default:\n return null\n }\n}\n\nfunction buildDescription(automation, triggerResourceName) {\n const verb = mapNameToVerb(automation.name)\n\n const { resourceType } = triggerResourceParts(automation.triggerResource)\n\n if (!verb) {\n // No verb mapping for this message name, so just show something generic\n const resourceName = truncate(triggerResourceName, {\n length: 160,\n separator: \" \",\n })\n\n return `When the automation is triggered from ${singularize(\n resourceType\n )} \"${resourceName}\"`\n }\n\n return `When a person ${verb} ${singularize(\n resourceType\n )} \"${triggerResourceName}\"`\n}\n\nfunction fetchResourceName({\n appName,\n path,\n resourceType,\n params = {},\n}): Promise<any> {\n const client = new Client({ root: pcoApiUrl(appName, { squiggly: false }) })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color\")}`}\n marginBottom={token(\"--t-spacing-2\")}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n >\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text\n color={token(\"--t-text-color-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\nimport React from \"react\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => !od.section\n )\n\n const primarySectionOptions = uniqBy(operationDefinitions, \"section\")\n .filter((od) => !!od.section)\n .map((od) => ({\n group: od.sectionGroup,\n label: od.section,\n value: sectionId(od.section),\n }))\n\n const secondaryOperations = selectedSection\n ? operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === selectedSection\n )\n : []\n\n function handleAnySelectChange({ selectedValue }) {\n switch (idType(selectedValue)) {\n case \"section\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => sectionId(od.section) === selectedValue\n )\n )\n break\n case \"operation\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => operationDefinitionId(od) === selectedValue\n )\n )\n break\n case null:\n onOperationDefinitionChange(null)\n break\n }\n }\n\n function renderOperations(operations: OperationDefinition[]) {\n const operationsAsOptions = operations.map((o) => ({\n group: o.group,\n label: o.description,\n value: o.id,\n }))\n\n return renderOptions(operationsAsOptions)\n }\n\n const primarySelectedValue = selectedOperation\n ? !selectedOperation.section\n ? operationDefinitionId(selectedOperation)\n : sectionId(selectedOperation.section)\n : undefined\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Select\n emptyValue=\"Select an action\"\n id=\"select-action\"\n onChange={handleAnySelectChange}\n size=\"lg\"\n value={primarySelectedValue}\n data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n value={operationDefinitionId(selectedOperation)}\n onChange={handleAnySelectChange}\n size=\"lg\"\n >\n {renderOperations(secondaryOperations)}\n </Select>\n )}\n </StackView>\n )\n}\n\nexport default Definition\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Avatar,\n Badge,\n Box,\n Checkbox as TapestryCheckbox,\n Combobox as TapestryCombobox,\n DateField as TapestryDateField,\n HelperDrawer,\n Highlight,\n Icon,\n Input,\n Menu,\n NumberField as TapestryNumberField,\n Radio,\n Select as TapestrySelect,\n Spinner,\n StackView,\n Text,\n TextArea as TapestryTextArea,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, debounce, groupBy, isEqual, sortBy, uniqBy } from \"lodash\"\nimport moment from \"moment\"\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n if (field.kind === \"Hidden\") return null\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n disabled={field.disabled}\n />\n )\n case \"SelectSearch\":\n return (\n <SelectSearch\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"Checkbox\":\n return <Checkbox field={field} value={value} onChange={onChange} />\n case \"TextArea\":\n return <TextArea field={field} onChange={onChange} value={value} />\n\n case \"DateField\":\n return <DateField field={field} onChange={onChange} value={value} />\n case \"Checkboxes\":\n return (\n <Checkboxes\n fieldId={field.id}\n options={actionAllowedOptions}\n onChange={onChange}\n />\n )\n case \"NumberField\":\n return <NumberField field={field} onChange={onChange} value={value} />\n case \"PersonSearch\":\n return (\n <PersonSearch\n canAccessPeople={canAccessPeople}\n field={field}\n onChange={onChange}\n listOptions={listOptions}\n isLoading={loadingLists[fieldListIdentifier(field)]}\n loadListForField={loadListForField}\n value={value}\n />\n )\n case \"TextField\":\n return <TextField field={field} onChange={onChange} value={value} />\n case \"RadioButtons\":\n return (\n <RadioButtons\n field={field}\n options={listOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"StaticText\":\n return <Text dangerouslySetInnerHTML={{ __html: field.content }} />\n default:\n console.warn(`Unknown field kind \"${field.kind}\"`)\n return null\n }\n }\n\n return (\n <StackView marginBottom={2} spacing={0.5}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-sm\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n controls={field.id}\n >\n {field.description}\n {field.description && field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>\n {loading ? <Loading /> : renderField()}\n {!field.description && field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Box>\n {field.info && (\n <HelperDrawer\n id={`${field.id}_help`}\n marginTop={token(\"--t-spacing-half\")}\n >\n <Box dangerouslySetInnerHTML={{ __html: field.info }} />\n </HelperDrawer>\n )}\n </StackView>\n )\n}\n\nconst Select = ({\n fieldId,\n listOptions,\n onChange,\n value,\n description,\n disabled,\n}: {\n description?: string\n disabled?: boolean\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value: any\n}) => {\n const overridenEmptyValue = listOptions?.find(\n (option) => option.value === \"no-option\"\n )\n const groupedOptions = groupBy(listOptions, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n const renderOptions = () => {\n return groupTypes.map((gt) =>\n gt === \"null\" || gt === \"undefined\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <TapestrySelect.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </TapestrySelect.OptionGroup>\n )\n )\n }\n\n const renderOptionsWithoutConsideringGroup = (\n items: { description: string; disabled?: boolean; value: string | number }[]\n ) => {\n return items.map((item) => (\n <TapestrySelect.Option\n key={item.value}\n value={item.value.toString()}\n disabled={item.disabled}\n >\n {item.description}\n </TapestrySelect.Option>\n ))\n }\n\n const handleSelectedValueChange = ({ selectedValue }) => {\n onChange({ fieldId, value: selectedValue })\n }\n\n const generatePrompt = (word: string) => {\n let prompt = `Select `\n if (!word) {\n prompt += \"a value\"\n } else if ([\"a\", \"e\", \"i\", \"o\", \"u\"].includes(word.charAt(0))) {\n prompt += `an ${word}`\n } else {\n prompt += `a ${word}`\n }\n return prompt\n }\n\n const renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return (\n overridenEmptyValue?.description ||\n generatePrompt(description?.toLowerCase())\n )\n }\n\n return (\n <TapestrySelect\n id={fieldId}\n onChange={handleSelectedValueChange}\n disabled={renderOptions().length < 1 || !!disabled}\n emptyValue={renderEmptyValue()}\n size=\"lg\"\n value={value || overridenEmptyValue?.value || null}\n placement=\"bottom-start\"\n >\n {renderOptions()}\n </TapestrySelect>\n )\n}\n\nconst SelectSearch = ({\n fieldId,\n listOptions,\n onChange,\n value,\n}: {\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value?: string\n}) => {\n const selectedOption: LoadedList = listOptions.find(\n (option) => option.value?.toString() === value\n )\n const selectedLabel = selectedOption?.description || \"\"\n const [prevSelectedLabel, setPrevSelectedLabel] = useState(\"\")\n const [query, setQuery] = useState(selectedLabel)\n const [showFilteredOptions, setShowFilteredOptions] = useState(false)\n const [showClearButton, setShowClearButton] = useState(false)\n\n if (selectedLabel !== prevSelectedLabel) {\n setPrevSelectedLabel(selectedLabel)\n setQuery(selectedLabel)\n setShowFilteredOptions(false)\n }\n\n let filteredOptions = sortBy(uniqBy(listOptions, \"value\"), \"group\")\n\n if (showFilteredOptions) {\n const formattedQuery = query.toLowerCase()\n filteredOptions = filteredOptions.filter((option) => {\n const optionText = `${option.description} ${option.group}`.toLowerCase()\n return optionText.includes(formattedQuery)\n })\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n css={{\n \"[role='combobox']\": {\n cursor: listOptions.length > 0 ? \"pointer\" : \"not-allowed\",\n },\n }}\n cursor=\"pointer\"\n disabled={listOptions.length === 0}\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowFilteredOptions(true)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n setShowFilteredOptions(false)\n }\n : undefined\n }\n onFocus={(e: React.ChangeEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowFilteredOptions(false)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder={\n listOptions.length > 0 ? \"Select an option\" : \"No options available\"\n }\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={<Icon name=\"general.search\" size=\"md\" />}\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {listOptions.length > 0 && (\n <>\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option: LoadedList, index: number) => {\n const isCurrent = option.value.toString() === value\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n disabled={option.disabled}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Icon\n marginLeft={-0.5}\n name={isCurrent ? \"general.check\" : \"\"}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={{\n description: option.description,\n value: option.value.toString(),\n }}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n {option.group && (\n <Badge\n title={<Highlight text={option.group} query={query} />}\n size=\"sm\"\n marginLeft=\"auto\"\n />\n )}\n </TapestryCombobox.Item>\n )\n })\n ) : (\n <Menu.Item>\n <Text>No results for &quot;{query}&quot;</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value ?? \"\"}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import React, { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n // Merge: existing values (e.g. pre-populated from an existing automation)\n // take precedence over field defaults.\n onChange((prev: SelectedFieldOptions) => ({ ...newSelections, ...prev }))\n }, [definitionFields, onChange])\n\n const renderableFields = getRenderedFields(\n definitionFields,\n selectedFieldOptions\n )\n\n const handleSelectedFieldOptionsChange = ({ fieldId, value }) => {\n const newSelections = { ...selectedFieldOptions }\n const dependents = definitionFields.filter((field) => field.dependsOn)\n dependents.map((dependent) => {\n if (dependent.dependsOn.includes(fieldId)) {\n const deeper = dependents.find((d) =>\n d.dependsOn.includes(dependent.id)\n )\n if (deeper) {\n delete newSelections[deeper.id]\n }\n delete newSelections[dependent.id]\n\n if (\n dependent.defaultValue !== undefined &&\n newSelections[dependent.id] === undefined\n ) {\n newSelections[dependent.id] = dependent.defaultValue\n }\n }\n })\n\n if (value === \"no-option\") {\n delete newSelections[fieldId]\n } else {\n newSelections[fieldId] = value\n }\n\n onChange({ ...newSelections })\n }\n\n if (definitionFields.length) {\n return (\n <div>\n {renderableFields.map((field) => {\n return (\n <Field\n canAccessPeople={canAccessPeople}\n field={field}\n key={field.id}\n onChange={handleSelectedFieldOptionsChange}\n value={selectedFieldOptions[field.id]}\n selectedFieldOptions={selectedFieldOptions}\n loadListForField={loadListForField}\n loadedLists={loadedLists}\n loadingLists={loadingLists}\n />\n )\n })}\n </div>\n )\n } else {\n return null\n }\n}\n\nexport default Fields\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Icon,\n Input,\n Link,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n buildTriggerConditions,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = forwardRef(\n (\n {\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n hideFooter = false,\n onRequestClose,\n onSuccess,\n trigger,\n }: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n hideFooter?: boolean\n onRequestClose: () => void\n onSuccess?: () => void\n trigger: AutomationTrigger\n },\n ref: React.Ref<{ submit: () => void }>\n ) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] =\n useState<SelectedFieldOptions>({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{\n [k: string]: LoadedList[]\n }>({})\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>(\n {}\n )\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n useImperativeHandle(ref, () => ({ submit: handleSubmit }))\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n const triggerConditions = buildTriggerConditions({\n baseConditions:\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions,\n dynamicConditions,\n dynamicTriggerConditions,\n })\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else if (onSuccess) {\n onSuccess()\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n setError({ automation: \"something even worse happened!\" })\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color\"),\n fontSize: token(\"--t-font-size-md\"),\n lineHeight: 1.65,\n marginBottom: token(\"--t-spacing-2\"),\n }}\n >\n {description}{\" \"}\n <Link external to={blankStateLink}>\n Learn more\n </Link>\n </Text>\n </Box>\n )}\n {error.automation && (\n <Alert {...errorAlertProps}>\n <Text>\n There was an error creating your automation. Please change your\n selections and try again or contact support if the problem\n persists.\n </Text>\n </Alert>\n )}\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color\")}\n controls=\"select-trigger-event\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n When a person...\n </Input.InputLabel>\n <Select\n id=\"select-trigger-event\"\n onChange={({ selectedValue }) =>\n handleChangeTriggerEvent(selectedValue)\n }\n size=\"lg\"\n value={selectedTriggerEvent}\n >\n {trigger.events.map((triggerEvent, idx) => (\n <Select.Option\n key={`${triggerEvent.name}_${idx}`}\n value={triggerEvent}\n >\n {triggerEvent.description}\n </Select.Option>\n ))}\n </Select>\n\n {dynamicConditions?.length > 0 && (\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={dynamicConditions}\n selectedFieldOptions={dynamicTriggerConditions}\n onChange={setDynamicTriggerConditions}\n loadedLists={{}}\n loadingLists={{}}\n loadListForField={() => null}\n />\n )}\n </StackView>\n\n <StackView spacing={1}>\n {operationApps.length > 0 ? (\n <Application\n selectedApp={selectedApp}\n operationApps={operationApps}\n onOperationAppChange={handleChangeSelectedApp}\n />\n ) : (\n <StackView spacing={1}>\n <Text\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={4}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={token(\"--t-spacing-1\")} {...errorAlertProps}>\n <Text>\n There was a problem looking up automations. Please contact\n support if the problem persists.\n </Text>\n </Alert>\n ) : loadingOperationDefinitions ? (\n <LoadingOperationDefinitions />\n ) : (\n <Definition\n selectedOperation={selectedDefinition}\n operationDefinitions={operationDefinitions}\n onOperationDefinitionChange={handleSelectedDefinitionChange}\n />\n )}\n </StackView>\n\n {selectedDefinition &&\n (error.selected_definition ? (\n <Alert {...errorAlertProps}>\n <Text>\n There was a problem looking up automation options. Please\n contact support if the problem persists.\n </Text>\n </Alert>\n ) : (\n <>\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={selectedDefinition.definitionFields || []}\n onChange={setSelectedFieldOptions}\n selectedFieldOptions={selectedFieldOptions}\n loadedLists={loadedLists}\n loadListForField={loadListForField}\n loadingLists={loadingLists}\n />\n {afterCreateOptions?.label && (\n <Checkbox\n disabled={\n submitting ||\n disableSubmit(selectedDefinition, selectedFieldOptions)\n }\n label={afterCreateOptions.label}\n checked={callAfterCreate}\n onChange={() => setCallAfterCreate(!callAfterCreate)}\n />\n )}\n {selectedTriggerEvent?.triggerParams?.map((param, idx) => (\n <Checkbox\n key={`${param.key}_${idx}`}\n label={param.description}\n checked={\n (triggerParams && triggerParams[param.key]) ||\n param.defaultValue\n }\n onChange={(e) => {\n setTriggerParams((prev) => ({\n ...prev,\n [`${param.key}`]: e.target.checked,\n }))\n }}\n />\n ))}\n {dangerAlertPresent && (\n <Alert {...errorAlertProps}>\n <StackView axis=\"horizontal\" spacing={1.5}>\n <Icon\n size={token(\"--t-element-size-lg\")}\n name=\"general.exclamationTriangle\"\n color={token(\"--t-icon-color-status-error\")}\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n {!hideFooter && (\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${token(\"--t-border-color\")}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={token(\"--t-text-color-headline\")}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={token(\"--t-font-weight-normal\")}\n onClick={onRequestClose}\n size=\"md\"\n title=\"Cancel\"\n variant=\"naked\"\n />\n <Button\n disabled={\n submitting ||\n dangerAlertPresent ||\n disableSubmit(\n selectedDefinition,\n selectedFieldOptions,\n dynamicConditions,\n dynamicTriggerConditions\n )\n }\n onClick={handleSubmit}\n size=\"md\"\n theme=\"primary\"\n title={getButtonText(selectedDefinition, selectedFieldOptions)}\n variant=\"fill\"\n data-testid=\"create-automation\"\n />\n </StackView>\n )}\n </StackView>\n )\n }\n)\n\nNewAutomation.displayName = \"NewAutomation\"\n\nfunction disableSubmit(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions,\n dynamicConditions?: DefinitionField[],\n dynamicTriggerConditions?: SelectedFieldOptions\n) {\n if (!selectedDefinition) return true\n\n const operationFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n if (\n !operationFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n if (\n !operationFields\n .filter((field) => fieldIsSelect(field))\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n\n const triggerFields = getRenderedFields(\n dynamicConditions ?? [],\n dynamicTriggerConditions ?? {}\n )\n if (\n !triggerFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, dynamicTriggerConditions ?? {}))\n )\n return true\n\n return false\n}\n\nfunction fieldIsSelect(field: DefinitionField) {\n return field.kind === \"Select\" || field.kind === \"SelectSearch\"\n}\n\nfunction fieldIsFilled(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (fieldIsSelect(field)) {\n return selectedFieldOptions.hasOwnProperty(field.id)\n } else {\n return (\n selectedFieldOptions.hasOwnProperty(field.id) &&\n selectedFieldOptions[field.id] &&\n selectedFieldOptions[field.id].toString().trim() !== \"\"\n )\n }\n}\n\nfunction getNextRequiredDescription(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!selectedDefinition?.definitionFields) return\n\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n for (const field of renderedFields) {\n if (field.required && !fieldIsFilled(field, selectedFieldOptions))\n return field.description\n }\n}\n\nfunction getButtonText(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n const nextRequiredDescription = getNextRequiredDescription(\n selectedDefinition,\n selectedFieldOptions\n )\n\n if (!selectedDefinition) {\n return \"Select an action\"\n } else if (nextRequiredDescription) {\n return `Select a${\n nextRequiredDescription.charAt(0).match(/[aeiou]/i) ? \"n\" : \"\"\n } ${nextRequiredDescription.toLowerCase()}`\n } else {\n return \"Create automation\"\n }\n}\n\nconst Application = ({\n onOperationAppChange,\n operationApps,\n selectedApp,\n}: {\n onOperationAppChange: (selectedValue: string) => void\n operationApps: Array<{ id: string; name: string }>\n selectedApp: string\n}) => {\n const handleChange = ({ selectedValue }) => {\n onOperationAppChange(selectedValue)\n }\n\n return (\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n controls=\"select-product\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Input.InputLabel>\n <Select\n autoFocus\n id=\"select-product\"\n onChange={handleChange}\n size=\"lg\"\n value={selectedApp}\n >\n {operationApps.map((app) => (\n <Select.Option key={app.id} value={app.id}>\n {app.name}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n )\n}\n\nconst LoadingOperationDefinitions = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{ color: token(\"--t-icon-color-dim\"), name: \"general.x\" }}\n onClick={onClick}\n size={\"sm\"}\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction NewAutomationModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={75}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Create automation\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n <style>{`\n .swal2-container.swal2-backdrop-show { z-index: 10001 }\n `}</style>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default NewAutomationModal\n","import * as churchCenter from \"@planningcenter/icons/paths/church-center\"\nimport * as logomark from \"@planningcenter/icons/paths/logomark\"\nimport * as services from \"@planningcenter/icons/paths/services\"\n\nexport const icons = {\n churchCenter,\n logomark,\n services,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport sortBy from \"lodash/sortBy\"\nimport React, { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n forbiddenText,\n pluralize,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused ? undefined : `1px solid ${token(\"--t-border-color\")}`\n }\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={token(\"--t-spacing-2\")}\n marginTop={-3}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n spacing={token(\"--t-spacing-2\")}\n wrap\n zIndex={2}\n >\n {canCreate && !hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n marginHorizontal={1}\n spacing={1}\n >\n <Icon\n size={2}\n color={token(\"--t-icon-color-status-warning\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n disabled?: boolean\n disabledReason?: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color\"),\n level: 2,\n size: token(\"--t-font-size-2xl\"),\n weight: token(\"--t-font-weight-bold\"),\n }\n\n const BlankStateTextProps = {\n color: token(\"--t-text-color-secondary\"),\n lineHeight: 3,\n size: token(\"--t-font-size-md\"),\n }\n\n function automationTriggerEvent(automation: AutomationInstance) {\n return trigger.events.find((event) => event.name === automation.name)\n }\n\n const handleUpdateAutomation =\n (originalAutomation: AutomationInstance) =>\n (newState: React.SetStateAction<AutomationInstance>) => {\n const updated =\n typeof newState == \"function\" ? newState(originalAutomation) : newState\n const newAutomations = [\n ...automations.filter((automation) => automation.id !== updated.id),\n updated,\n ]\n\n setAutomations(newAutomations)\n }\n\n return (\n <ThemeProvider theme={customTheme}>\n <OrganizationContext.Provider\n value={{ dateFormat, olsonTimeZone, twentyFourHourTime }}\n >\n {trigger && (\n <Header\n automations={automations}\n blankStateLink={blankStateLink}\n canCreate={currentPersonCanCreate && !disabled}\n loading={loading}\n defaultApp={defaultApp}\n description={blankStateDescription}\n theme={customTheme}\n trigger={trigger}\n hasActiveAutomations={hasActiveAutomations}\n onPauseAutomations={handlePauseAutomations}\n afterCreateOptions={afterCreateOptions}\n />\n )}\n {loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading automations...\"}\n />\n ) : !trigger ? (\n <></>\n ) : (\n <Box data-testid=\"automations-section\">\n {automations?.length > 0 ? (\n <TileView spacing={3} marginVertical={3} minCellWidth={45}>\n {sortBy(automations, \"id\").map((a) => (\n <EditableAutomation\n key={a.id}\n automation={a}\n updateAutomation={handleUpdateAutomation(a)}\n onDelete={handleDelete}\n theme={customTheme}\n openHistoryNow={a.id === Number(automationId)}\n trigger={{\n event: automationTriggerEvent(a),\n resource: trigger.resource,\n }}\n currentPersonId={currentPersonId}\n currentPersonCanCreate={currentPersonCanCreate}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={token(\"--t-spacing-6\")}\n spacing={token(\"--t-spacing-2\")}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n spacing: token(\"--t-spacing-6\"),\n },\n }}\n >\n <Box\n css={{\n \".symbol\": {\n height: \"100%\",\n width: \"100%\",\n },\n }}\n maxWidth={24}\n mediaQueries={{\n lg: {\n maxWidth: 40,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <StackView\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n maxWidth={45}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n textAlign: \"left\",\n },\n }}\n textAlign=\"center\"\n >\n {currentPersonCanCreate ? (\n <>\n <Heading {...BlankStateHeadingProps}>\n Add an automation\n </Heading>\n <StackView\n alignment=\"center\"\n marginBottom={token(\"--t-spacing-1\")}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}\n </Text>\n </StackView>\n <StackView\n axis=\"horizontal\"\n spacing={token(\"--t-spacing-1\")}\n >\n <Button\n variant=\"outline\"\n to={blankStateLink}\n color={`${token(\n \"--t-text-color-status-neutral\"\n )} !important`}\n >\n Learn more\n </Button>\n <Button\n as=\"button\"\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n </StackView>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={customTheme}\n >\n <NewAutomation\n defaultApp={defaultApp}\n description={blankStateDescription}\n blankStateLink={blankStateLink}\n onRequestClose={() => setNewModalVisible(false)}\n trigger={trigger}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </>\n ) : (\n <>\n <Heading {...BlankStateHeadingProps}>Automations</Heading>\n <Text {...BlankStateTextProps}>\n {permissionDeniedReason}\n </Text>\n </>\n )}\n </StackView>\n </StackView>\n )}\n </Box>\n )}\n {incomingAutomationsParam && (\n <IncomingAutomations\n encryptedParam={incomingAutomationsParam}\n trigger={trigger}\n />\n )}\n </OrganizationContext.Provider>\n <style>{styles}</style>\n </ThemeProvider>\n )\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Button,\n Checkbox,\n Icon,\n Input,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { mapKeys, snakeCase } from \"lodash\"\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport { fetchAutomations } from \"./utils/fetch-automations\"\nimport {\n buildDescription,\n buildTriggerConditions,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\n\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\nasync function getVisibleApps() {\n return peopleClient\n .get<{ data: { apps: Array<{ name: string }>; type: \"Topbar\" } }>({\n data: { fields: { Topbar: \"apps\" } },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await peopleClient.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: { OperationDefinitionList: \"values\" },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst Application = ({\n onOperationAppChange,\n operationApps,\n selectedApp,\n}: {\n onOperationAppChange: (selectedValue: string) => void\n operationApps: Array<{ id: string; name: string }>\n selectedApp: string\n}) => {\n const handleChange = ({ selectedValue }) =>\n onOperationAppChange(selectedValue)\n return (\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n controls=\"select-product\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Input.InputLabel>\n <Select\n autoFocus\n id=\"select-product\"\n onChange={handleChange}\n size=\"lg\"\n value={selectedApp}\n >\n {operationApps.map((app) => (\n <Select.Option key={app.id} value={app.id}>\n {app.name}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n )\n}\n\nconst LoadingOperationDefinitions = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nconst SingleActionInline = forwardRef(\n (\n {\n blankStateLink,\n dateFormat = \"%m/%d/%Y\",\n defaultApp,\n description,\n olsonTimeZone = null,\n onLoad,\n onRequestClose,\n onSuccess,\n paddingTop = 0,\n trigger,\n twentyFourHourTime = null,\n }: {\n blankStateLink?: string\n dateFormat?: string\n defaultApp: string\n description?: string\n olsonTimeZone?: string\n onLoad?: (automation: AutomationInstance | null) => void\n onRequestClose: () => void\n onSuccess?: () => void\n paddingTop?: number\n trigger: AutomationTrigger\n twentyFourHourTime?: boolean\n },\n ref: React.Ref<{ submit: () => void }>\n ) => {\n const [loadingAutomation, setLoadingAutomation] = useState(true)\n const [existingAutomation, setExistingAutomation] =\n useState<AutomationInstance | null>(null)\n\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] =\n useState<SelectedFieldOptions>({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{\n [k: string]: LoadedList[]\n }>({})\n const [loadingLists, setLoadingLists] = useState<{\n [k: string]: boolean\n }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [triggerParams, setTriggerParams] = useState<{\n [k: string]: string\n }>({})\n\n const activeAppRef = useRef(null)\n const hasPrePopulatedRef = useRef(false)\n\n useImperativeHandle(ref, () => ({ submit: handleSubmit }))\n\n // Fetch the existing automation (if any) on mount.\n useEffect(() => {\n fetchAutomations(trigger.resource)\n .then((automations) => {\n const automation = automations[0] ?? null\n setExistingAutomation(automation)\n setLoadingAutomation(false)\n onLoad?.(automation)\n\n if (automation) {\n const matchingEvent = trigger.events.find(\n (e) => e.name === automation.name\n )\n if (matchingEvent) setSelectedTriggerEvent(matchingEvent)\n if (automation.triggerParams)\n setTriggerParams(\n automation.triggerParams as Record<string, string>\n )\n // Switch to the automation's app; the definitions effect will re-run.\n if (automation.operationAppName !== selectedApp) {\n setSelectedApp(automation.operationAppName)\n }\n }\n })\n .catch(() => {\n setLoadingAutomation(false)\n onLoad?.(null)\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [trigger.resource])\n\n // Load operation apps + definitions whenever selectedApp changes.\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const resolvedApp = apps.find((a) => a.id === selectedApp)\n ? selectedApp\n : apps[0]?.id ?? defaultApp\n if (resolvedApp !== selectedApp) setSelectedApp(resolvedApp)\n\n activeAppRef.current = null\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n\n getOperationDefinitions(resolvedApp)\n .then((definitions) => {\n if (activeAppRef.current) return // superseded by a manual app change\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n })\n .catch((err) => setError({ definitions: err }))\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedApp])\n\n // Pre-populate definition + field options once both the existing automation\n // and the definitions list are available. The hasPrePopulatedRef ensures this\n // runs exactly once so the user's subsequent changes aren't reset.\n useEffect(() => {\n if (hasPrePopulatedRef.current) return\n if (!existingAutomation) return\n if (loadingOperationDefinitions || operationDefinitions.length === 0)\n return\n\n hasPrePopulatedRef.current = true\n const match = operationDefinitions.find(\n (d) =>\n d.definitionClass === existingAutomation.operationDefinitionClassName\n )\n if (match) {\n setSelectedDefinition(match)\n // The API client camelCases operation_params keys (e.g. required_field → requiredField)\n // but field IDs are stored as snake_case string values. Convert back before pre-populating.\n const camelCasedParams =\n (existingAutomation.operationParams as Record<string, any>) ?? {}\n const snakeCasedParams = mapKeys(camelCasedParams, (_, key) =>\n snakeCase(key)\n )\n const { definition_identifier, ...fieldOptions } = snakeCasedParams\n setSelectedFieldOptions(fieldOptions as SelectedFieldOptions)\n }\n }, [existingAutomation, operationDefinitions, loadingOperationDefinitions])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((err) => setError({ selected_definition: err }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((err) => setError({ definitions: err }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n const triggerConditions = buildTriggerConditions({\n baseConditions:\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions,\n dynamicConditions,\n dynamicTriggerConditions,\n })\n\n const handleSelectedDefinitionChange = (newDef: OperationDefinition) => {\n setSelectedDefinition(newDef)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const parts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n return parts.description\n ? `${parts.name} (${parts.description})`\n : parts.name\n }\n\n function buildAttributes() {\n const operation_params: Record<string, any> = { ...selectedFieldOptions }\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n return {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n }\n }\n\n function handleSubmit() {\n if (submitting || !selectedDefinition) return\n\n if (existingAutomation) {\n submitUpdate()\n } else {\n submitCreate()\n }\n }\n\n function submitCreate() {\n setSubmitting(true)\n webhooksClient\n .post({\n data: {\n _e: trigger.resource,\n data: {\n attributes: buildAttributes(),\n type: \"AutomationSubscription\",\n },\n },\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n setSubmitting(false)\n if (onSuccess) {\n onSuccess()\n } else {\n window.location.reload()\n }\n })\n .catch(handleSubmitError)\n }\n\n function submitUpdate() {\n setSubmitting(true)\n webhooksClient\n .patch({\n data: {\n _e: trigger.resource,\n data: {\n attributes: buildAttributes(),\n id: String(existingAutomation.id),\n type: \"AutomationSubscription\",\n },\n },\n url: `/me/automation_subscriptions/${existingAutomation.id}`,\n })\n .then(() => {\n setSubmitting(false)\n if (onSuccess) {\n onSuccess()\n } else {\n window.location.reload()\n }\n })\n .catch(handleSubmitError)\n }\n\n function handleSubmitError(error) {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n setError({ automation: \"something even worse happened!\" })\n }\n }\n\n if (loadingAutomation) {\n return <Spinner size=\"xl\" />\n }\n\n return (\n <OrganizationContext.Provider\n value={{ dateFormat, olsonTimeZone, twentyFourHourTime }}\n >\n <StackView paddingTop={paddingTop} spacing={2}>\n {error.automation && (\n <Alert {...errorAlertProps}>\n <Text>\n There was an error saving your automation. Please change your\n selections and try again or contact support if the problem\n persists.\n </Text>\n </Alert>\n )}\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color\")}\n controls=\"select-trigger-event\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n When a person...\n </Input.InputLabel>\n <Select\n id=\"select-trigger-event\"\n onChange={({ selectedValue }) =>\n handleChangeTriggerEvent(selectedValue)\n }\n size=\"lg\"\n value={selectedTriggerEvent}\n >\n {trigger.events.map((triggerEvent, idx) => (\n <Select.Option\n key={`${triggerEvent.name}_${idx}`}\n value={triggerEvent}\n >\n {triggerEvent.description}\n </Select.Option>\n ))}\n </Select>\n {dynamicConditions?.length > 0 && (\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={dynamicConditions}\n selectedFieldOptions={dynamicTriggerConditions}\n onChange={setDynamicTriggerConditions}\n loadedLists={{}}\n loadingLists={{}}\n loadListForField={() => null}\n />\n )}\n </StackView>\n <StackView spacing={1}>\n {operationApps.length > 0 ? (\n <Application\n selectedApp={selectedApp}\n operationApps={operationApps}\n onOperationAppChange={handleChangeSelectedApp}\n />\n ) : (\n <StackView spacing={1}>\n <Text\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={4}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={token(\"--t-spacing-1\")} {...errorAlertProps}>\n <Text>\n There was a problem looking up automations. Please contact\n support if the problem persists.\n </Text>\n </Alert>\n ) : loadingOperationDefinitions ? (\n <LoadingOperationDefinitions />\n ) : (\n <Definition\n selectedOperation={selectedDefinition}\n operationDefinitions={operationDefinitions}\n onOperationDefinitionChange={handleSelectedDefinitionChange}\n />\n )}\n </StackView>\n {selectedDefinition &&\n (error.selected_definition ? (\n <Alert {...errorAlertProps}>\n <Text>\n There was a problem looking up automation options. Please\n contact support if the problem persists.\n </Text>\n </Alert>\n ) : (\n <>\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={selectedDefinition.definitionFields || []}\n onChange={setSelectedFieldOptions}\n selectedFieldOptions={selectedFieldOptions}\n loadedLists={loadedLists}\n loadListForField={loadListForField}\n loadingLists={loadingLists}\n />\n {selectedTriggerEvent?.triggerParams?.map((param, idx) => (\n <Checkbox\n key={`${param.key}_${idx}`}\n label={param.description}\n checked={\n (triggerParams && triggerParams[param.key]) ||\n param.defaultValue\n }\n onChange={(e) => {\n setTriggerParams((prev) => ({\n ...prev,\n [`${param.key}`]: e.target.checked,\n }))\n }}\n />\n ))}\n {dangerAlertPresent && (\n <Alert {...errorAlertProps}>\n <StackView axis=\"horizontal\" spacing={1.5}>\n <Icon\n size={token(\"--t-element-size-lg\")}\n name=\"general.exclamationTriangle\"\n color={token(\"--t-icon-color-status-error\")}\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n </StackView>\n </OrganizationContext.Provider>\n )\n }\n)\n\nSingleActionInline.displayName = \"SingleActionInline\"\n\nexport default SingleActionInline\n"],"names":["SvgAutomations","React","createElement","id","xmlns","viewBox","className","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","async","deobfuscateDescriptions","subscriptions","Promise","all","map","subscription","includes","operationDefinitionClassName","isDeobfuscatable","result","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","replace","actionResourceUrl","links","html","actionResourceName","fieldDefinitionId","definitionIdentifier","match","fieldDefinition","FieldDefinition","FieldOption","include","fetchFieldDefinition","values","dataType","_subscription$operati","_subscription$operati2","Object","entries","action","_fieldDefinition$fiel","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","_fieldDefinition$fiel2","customFieldOptionDescription","deobfuscatedDescription","string","charAt","toUpperCase","slice","Client","root","pcoApiUrl","squiggly","version","fieldListIdentifier","field","listClass","kind","buildDescription","selectedDefinition","selectedFieldOptions","loadedLists","describeSelectedFields","definition","obfuscateDescriptionName","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","list","Error","JSON","stringify","buildTriggerConditions","baseConditions","dynamicConditions","dynamicTriggerConditions","triggerConditions","cloneDeep","writableFields","filter","renderOnly","renderIfChainSatisfied","set","allFields","renderIf","isBoolean","conditionKey","keys","shouldRender","upstreamId","upstream","f","getRenderedFields","definitionFields","_list$find2","workflow_id_WorkflowsList","sensitiveString","o","toString","workflow_id","obfuscateSelectedFieldDescriptions","_list$find","label","e","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","forbiddenText","error","_error$errors","errors","status","parseDescription","exec","trim","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","mergePeopleAndEvents","mergedData","reduce","personId","foundPerson","p","push","_extends","person","event","History","automation","filterWhere","onEventsStatusChange","_params$where","loading","paginationProps","refresh","params","setParams","automationId","_","setError","useState","setLoading","eventPages","setEventPages","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","_e","Delivery","Event","order","fetchEvents","per_page","then","pages","bubbleErrorToBoundary","undefined","useEvents","useContext","filteringEvents","automationCreatedRecently","diff","numDaysSince","createdAt","automationBeganOn","historyPreservationAlert","showTzLabel","Intl","DateTimeFormat","resolvedOptions","timeZone","before","after","nameIndex","indexOf","columns","cell","EventStatusBadge","css","padding","header","baseFormat","momentDateTimeFormat","tz","Link","to","maxWidth","EventStatusMessage","flex","Fragment","RetryEventButton","IgnoreEventButton","refreshHistory","textAlign","minWidth","StackView","spacing","token","Heading","level","size","color","weight","Text","italic","Box","minHeight","alignItems","axis","distribution","Input","InputLabel","fontWeight","controls","Select","emptyValue","onChange","selectedValue","title","Option","Button","iconLeft","onClick","theme","variant","maxHeight","overflow","DataTable","empty","alignment","marginTop","marginBottom","svg","fontSize","loadingTitle","bodyCell","lineHeight","bodyRow","rowData","backgroundColor","headerCell","headerRow","setStatus","retryTitleFromStatus","statusIcon","post","attributes","response","eventsStatus","alerts","fire","text","disabled","badgeColors","border","badgeIcon","badgeTitle","Badge","background","foreground","paddingLeft","paddingRight","radius","renderLeft","Icon","marginLeft","stroke","strokeAlign","strokeWeight","lastDelivery","message","delivery","ERRORS","default","duplicated_event","failed_without_deliveries","whiteSpace","ToggleableDetails","details","_response","responseBody","parse","_unused","parsedErrors","responseErrors","deliveryFailureReason","statusMessage","fontStyle","paddingTop","children","open","setOpen","inline","was","fontFamily","ErrorBoundary","Component","constructor","props","super","this","handleContactSupport","onRequestClose","window","openHelpdesk","state","hasError","static","render","Alert","type","marginVertical","boxShadow","style","History$1","CloseModalIcon","as","icon","HistoryModal","createPortal","ThemeProvider","Modal","paddingBottom","document","body","VALID_LOGO_NAMES","getValidLogoName","kebabName","kebabCase","isValidLogoName","HIDDEN_FIELD","HIDDEN_RESPONSE","FIELD_KEY_RE","SENTINEL_VALUES","Set","extractIds","_conds$data","_conds$data2","conds","formId","relationships","form","selectedOptionsByField","_optionIds$","raw","$in","optionIds","Array","isArray","String","has","fieldId","optionId","fetchFieldDefinitions","ids","Map","walk","fd","_unused2","fetchCampuses","Campus","campus","_unused3","buildResponseDetails","fieldsByForm","fieldDefs","campuses","_fieldsByForm$get2","fieldLabel","valueLabel","fieldType","fieldableId","options","labelers","resolve","extracted","sub","targets","entry","formIds","FormField","FormFieldOption","byId","fetchFormFields","uniq","t","fieldDefIds","campusIds","_fieldsByForm$get","add","responseDetails","resolveResponseDetails","groups","_groups$get","group","resolvedById","subs","resolved","_resolvedById$get","formatResponseDetails","_excluded","_excluded2","AutomationContext","EditableAutomation","_ref","updateAutomation","onDelete","openHistoryNow","disabledReason","_objectWithoutPropertiesLoose","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","cardOpacity","active","paddingVertical","truncate","lowerFirst","conditionalSuffix","optionallyPrettifyArchivedPrefix","separator","external","triggerAdminUrl","canManage","tooltip","hover","_ref2","rest","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","avatar","fetchCurrentPersonAvatar","prev","createdBy","avatarUrl","createdByName","confirmButtonText","ToggleSwitch","isChecked","patch","newStatus","triggerProductName","Logo","markOnly","operationAppName","_automation$createdBy","_automation$createdBy2","createdBySuffix","Divider","marginHorizontal","Avatar","basis","source","_automation$createdBy3","_automation$eventsSta","_automation$eventsSta2","_automation$eventsSta3","_automation$eventsSta4","_automation$eventsSta5","_automation$eventsSta6","_automation$createdBy4","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","_automation$triggerPa","triggerParams","useTriggerPersonOverride","startsWith","fetchAutomations","AutomationSubscription","fetchCreatorProfiles","compact","profiles","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","services","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","_QUERYABLE_BY_MULTIPL","fetchNothing","fetchAllAtOnce","fetchOneAtATime","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","app","toLowerCase","fetchPersonApps","operationApps","fetchIncomingAutomations","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","primarySelectedValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","camelCase","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","SelectSearch","Checkbox","TextArea","DateField","Checkboxes","NumberField","PersonSearch","isLoading","TextField","RadioButtons","dangerouslySetInnerHTML","__html","content","console","warn","renderField","overridenEmptyValue","option","groupTypes","TapestrySelect","items","item","handleSelectedValueChange","prompt","generatePrompt","selectedOption","_option$value","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","_selectedOption$meta","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","_field$allowUnanswere","specificDate","setSpecificDate","todaysValue","customValue","dateBeforeValue","orgFormat","dateFieldValue","setDateFieldValue","toDate","allowUnansweredOption","handleSelectChange","TapestryDateField","defaultOpen","formatValue","selectedValues","setSelectedValues","handleCheckboxesChange","newSelectedValues","minimumValue","minValue","maximumValue","maxValue","inputValue","setInputValue","Number","defaultValue","InputBox","TapestryNumberField","newNumberValue","min","max","hasControls","display","handleCheckedChange","Radio","Fields","newSelections","renderableFields","handleSelectedFieldOptionsChange","dependents","dependent","deeper","errorAlertProps","borderRadius","getVisibleApps","Topbar","apps","a","getWebhooksApps","OperationApp","getOperationDefinitions","OperationDefinition","NewAutomation","forwardRef","afterCreateOptions","blankStateLink","debugMode","defaultApp","hideFooter","onSuccess","ref","_selectedDefinition$f","_selectedTriggerEvent","_selectedDefinition$f2","selectedTriggerEvent","setSelectedTriggerEvent","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","useImperativeHandle","submit","handleSubmit","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","conditions","getDescription","descriptionParts","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","submitCreate","onConfirm","location","reload","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","borderTop","getButtonText","operationFields","required","every","fieldIsFilled","fieldIsSelect","nextRequiredDescription","renderedFields","getNextRequiredDescription","displayName","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg","styles","SingleActionInline","onLoad","loadingAutomation","setLoadingAutomation","existingAutomation","setExistingAutomation","hasPrePopulatedRef","_automations$","matchingEvent","_apps$0$id","_apps$","resolvedApp","err","camelCasedParams","mapKeys","snakeCase","parts","buildAttributes","handleSubmitError","newDef"],"mappings":"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"}