@planningcenter/core-automations 1.13.5 → 1.13.6

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/utils/pco-api-root.ts","../../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/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":["// Derives the API root URL from the current page's location, so that API\n// requests always use the same protocol as the page (preventing mixed content\n// errors when the page is served over HTTPS).\n//\n// For real hostnames (anything with a dot), the leading subdomain is replaced\n// with \"api\": e.g. people.pco.test → api.pco.test,\n// pco-box.pco.dev → api.pco.dev, people.planningcenteronline.com →\n// api.planningcenteronline.com.\n//\n// Hostnames without a dot (e.g. \"localhost\" in jsdom/test environments) fall\n// back to the production API with https, since there is no real subdomain to\n// derive from and no actual network request is made in tests.\nexport function pcoApiRoot(app: string): string {\n const { protocol, hostname } = window.location\n if (!hostname.includes(\".\")) {\n return `https://api.planningcenteronline.com/${app}/v2`\n }\n return `${protocol}//${hostname.replace(/^[^.]+/, \"api\")}/${app}/v2`\n}\n","const 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 { isBoolean } from \"lodash\"\nimport moment from \"moment\"\n\nimport { pcoApiRoot } from \"./pco-api-root\"\n\nexport async function deobfuscateDescriptions(\n subscriptions: AutomationInstance[]\n) {\n return Promise.all(\n subscriptions.map(async (subscription) => {\n if (isDeobfuscatable(subscription)) {\n subscription.description = await deobfuscatedDescription(subscription)\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 let workflowName\n\n if (workflow.archivedAt) {\n workflowName = `[archived] ${workflow.name}`\n } else {\n workflowName = workflow.name\n }\n\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n 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 || 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: pcoApiRoot(\"people\"),\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 getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter((field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"renderIf\")) {\n const renderIf = field.renderIf!\n const conditionKey = Object.keys(renderIf as object)[0]\n\n return isBoolean(renderIf)\n ? renderIf\n : (renderIf as { [k: string]: string | number | boolean })[\n conditionKey\n ] === selectedFieldOptions[conditionKey]\n } else {\n return true\n }\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","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiRoot } from \"./utils/pco-api-root\"\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 moment from \"moment\"\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} from \"./utils/utils\"\n\ndeclare global {\n interface Window {\n openHelpdesk: () => void\n }\n}\n\nconst webhooksClient = new Client({\n root: pcoApiRoot(\"webhooks\"),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({ root: pcoApiRoot(\"people\"), version: \"2022-07-14\" })\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\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}) {\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 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 moment(event.createdAt)\n .utcOffset(olsonTimeZone)\n .format(momentDateTimeFormat({ dateFormat, twentyFourHourTime })),\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 {automation.description}\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) => (\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 { 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 { pcoApiRoot } from \"./utils/pco-api-root\"\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 { lowerFirst, truncate } from \"lodash\"\nimport { 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 { dateLocalized, forbiddenText } from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiRoot(\"webhooks\"),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({ root: pcoApiRoot(\"people\") })\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}, then {lowerFirst(name)}{\" \"}\n {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 \"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 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\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 { compact, uniq } from \"lodash\"\n\nimport { pcoApiRoot } from \"./pco-api-root\"\n\nconst webhooksClient = new Client({\n root: pcoApiRoot(\"webhooks\"),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({ root: pcoApiRoot(\"people\") })\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_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 { pcoApiRoot } from \"./utils/pco-api-root\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { truncate, upperFirst } from \"lodash\"\nimport { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiRoot(\"webhooks\"),\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_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: pcoApiRoot(appName) })\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(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\"\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 === null\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 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 data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n defaultValue={secondaryOperations[0].id}\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 { useCallback, useContext, useEffect, useMemo, useState } 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 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 />\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.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>{loading ? <Loading /> : renderField()}</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}: {\n description?: string\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}\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 { 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 onChange(newSelections)\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 { pcoApiRoot } from \"./utils/pco-api-root\"\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 { cloneDeep, set } from \"lodash\"\nimport { 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 fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({ root: pcoApiRoot(\"people\"), version: \"LATEST\" })\nconst webhooksClient = new Client({\n root: pcoApiRoot(\"webhooks\"),\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 },\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] = useState({})\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 triggerConditions = cloneDeep(\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions\n )\n for (const key in dynamicTriggerConditions) {\n set(triggerConditions, key, dynamicTriggerConditions[key])\n }\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\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(selectedDefinition, selectedFieldOptions)\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) {\n if (selectedDefinition) {\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n const requiredFields = renderedFields.filter((field) => field.required)\n const selectFields = renderedFields.filter((field) => fieldIsSelect(field))\n\n return (\n !requiredFields.every((field) =>\n fieldIsFilled(field, selectedFieldOptions)\n ) ||\n !selectFields.every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n } else {\n return true\n }\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 { pcoApiRoot } from \"./utils/pco-api-root\"\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 { useEffect, useState } from \"react\"\nimport sortBy from \"lodash/sortBy\"\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 { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n forbiddenText,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiRoot(\"webhooks\"),\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\n ? undefined\n : `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 incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n disabled?: boolean\n disabledReason?: string\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\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":["pcoApiRoot","app","protocol","hostname","window","location","includes","replace","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","operationDefinitionClassName","isDeobfuscatable","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","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","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","getRenderedFields","definitionFields","selectedFieldOptions","filter","renderIf","conditionKey","keys","isBoolean","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","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","mergePeopleAndEvents","mergedData","reduce","result","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","columns","cell","EventStatusBadge","css","padding","header","utcOffset","momentDateTimeFormat","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","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","_excluded","_excluded2","AutomationContext","EditableAutomation","_ref","updateAutomation","onDelete","openHistoryNow","disabledReason","_objectWithoutPropertiesLoose","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","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","exec","trim","startsWith","fetchCreatorProfiles","compact","uniq","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","ids","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","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","options","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","group","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","defaultValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","camelCase","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","fieldId","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","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","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","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/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":["const 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 { isBoolean } 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 subscription.description = await deobfuscatedDescription(subscription)\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 let workflowName\n\n if (workflow.archivedAt) {\n workflowName = `[archived] ${workflow.name}`\n } else {\n workflowName = workflow.name\n }\n\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n 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 || 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 getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter((field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"renderIf\")) {\n const renderIf = field.renderIf!\n const conditionKey = Object.keys(renderIf as object)[0]\n\n return isBoolean(renderIf)\n ? renderIf\n : (renderIf as { [k: string]: string | number | boolean })[\n conditionKey\n ] === selectedFieldOptions[conditionKey]\n } else {\n return true\n }\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","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\"\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} 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\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}) {\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 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 moment(event.createdAt)\n .utcOffset(olsonTimeZone)\n .format(momentDateTimeFormat({ dateFormat, twentyFourHourTime })),\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 {automation.description}\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) => (\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 { 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 { 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 { 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 { dateLocalized, forbiddenText } 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}, then {lowerFirst(name)}{\" \"}\n {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 \"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 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\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_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 { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\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_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(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\"\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 === null\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 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 data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n defaultValue={secondaryOperations[0].id}\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 { useCallback, useContext, useEffect, useMemo, useState } 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 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 />\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.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>{loading ? <Loading /> : renderField()}</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}: {\n description?: string\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}\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 { 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 onChange(newSelections)\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 { cloneDeep, set } from \"lodash\"\nimport { 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 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 },\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] = useState({})\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 triggerConditions = cloneDeep(\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions\n )\n for (const key in dynamicTriggerConditions) {\n set(triggerConditions, key, dynamicTriggerConditions[key])\n }\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\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(selectedDefinition, selectedFieldOptions)\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) {\n if (selectedDefinition) {\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n const requiredFields = renderedFields.filter((field) => field.required)\n const selectFields = renderedFields.filter((field) => fieldIsSelect(field))\n\n return (\n !requiredFields.every((field) =>\n fieldIsFilled(field, selectedFieldOptions)\n ) ||\n !selectFields.every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n } else {\n return true\n }\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 { 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 { 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(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","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","replace","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","getRenderedFields","definitionFields","selectedFieldOptions","filter","renderIf","conditionKey","keys","isBoolean","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","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","mergePeopleAndEvents","mergedData","reduce","result","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","columns","cell","EventStatusBadge","css","padding","header","utcOffset","momentDateTimeFormat","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","handleContactSupport","this","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","_excluded","_excluded2","AutomationContext","EditableAutomation","_ref","updateAutomation","onDelete","openHistoryNow","disabledReason","_objectWithoutPropertiesLoose","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","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","exec","trim","startsWith","fetchCreatorProfiles","compact","uniq","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","ids","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","options","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","group","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","defaultValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","camelCase","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","fieldId","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","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","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","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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"}