@planningcenter/core-automations 1.13.9 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/cjs/core-automations.esm.js +1 -1
- package/dist/cjs/core-automations.esm.js.map +1 -1
- package/dist/cjs/core-automations.js +1 -1
- package/dist/cjs/core-automations.js.map +1 -1
- package/dist/cjs/core-automations.modern.mjs +1 -1
- package/dist/cjs/core-automations.modern.mjs.map +1 -1
- package/dist/cjs/core-automations.umd.js +1 -1
- package/dist/cjs/core-automations.umd.js.map +1 -1
- package/dist/types/src/automation.d.ts.map +1 -1
- package/dist/types/src/automations.d.ts.map +1 -1
- package/dist/types/src/field.d.ts.map +1 -1
- package/dist/types/src/history.d.ts +8 -1
- package/dist/types/src/history.d.ts.map +1 -1
- package/dist/types/src/incoming_automations.d.ts.map +1 -1
- package/dist/types/src/new_automation.d.ts.map +1 -1
- package/dist/types/src/utils/fetch-automations.d.ts +2 -0
- package/dist/types/src/utils/fetch-automations.d.ts.map +1 -1
- package/dist/types/src/utils/resolve-response-details.d.ts +4 -0
- package/dist/types/src/utils/resolve-response-details.d.ts.map +1 -0
- package/dist/types/src/utils/response-labelers/people-form.d.ts +4 -0
- package/dist/types/src/utils/response-labelers/people-form.d.ts.map +1 -0
- package/dist/types/src/utils/response-labelers/types.d.ts +5 -0
- package/dist/types/src/utils/response-labelers/types.d.ts.map +1 -0
- package/dist/types/src/utils/utils.d.ts +5 -0
- package/dist/types/src/utils/utils.d.ts.map +1 -1
- package/dist/types/tests/AutomationCard.test.d.ts +2 -0
- package/dist/types/tests/AutomationCard.test.d.ts.map +1 -0
- package/dist/types/tests/utils/response-labelers/people-form.test.d.ts +2 -0
- package/dist/types/tests/utils/response-labelers/people-form.test.d.ts.map +1 -0
- package/package.json +9 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-automations.esm.js","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":["import React from \"react\"\n\nconst SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { 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 React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-dim\"),\n name: \"general.x\",\n }}\n onClick={onClick}\n size=\"sm\"\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction HistoryModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={120}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Automation history\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default HistoryModal\n","import { Logo } from \"@planningcenter/tapestry-react\"\nimport { kebabCase } from \"lodash\"\nimport type { ComponentProps } from \"react\"\n\n// Extract valid logo names from the Logo component's props\ntype ValidLogoName = NonNullable<ComponentProps<typeof Logo>[\"name\"]>\n\n// List of valid logo names from @planningcenter/tapestry-react Logo component\n// Update this list when support for new products are added to tapestry-react\nconst VALID_LOGO_NAMES: ValidLogoName[] = [\n \"api\",\n \"calendar\",\n \"check-ins\",\n \"church-center\",\n \"giving\",\n \"groups\",\n \"headcounts\",\n \"home\",\n \"login\",\n \"music-stand\",\n \"people\",\n \"planning-center\",\n \"publishing\",\n \"registrations\",\n \"services\",\n]\n\nexport const isValidLogoName = (name: string): name is ValidLogoName => {\n return VALID_LOGO_NAMES.includes(name as ValidLogoName)\n}\n\nexport const getValidLogoName = (name: string): ValidLogoName => {\n const kebabName = kebabCase(name)\n return isValidLogoName(kebabName) ? kebabName : \"planning-center\"\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n Logo,\n StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { lowerFirst, truncate } from \"lodash\"\nimport React, { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { 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 React, { 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\"\nimport React from \"react\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === 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 React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n 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 "{query}"</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value ?? \"\"}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import React, { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n 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 React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] = 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 React, { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { 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","deobfuscateDescriptions","subscriptions","Promise","all","map","subscription","_temp","includes","operationDefinitionClassName","isDeobfuscatable","resolve","_temp3","description","_temp2","workflowId","peopleClient","get","data","fields","Workflow","where","url","catch","name","then","e","reject","fetchWorkflow","operationParams","workflow","workflowName","archivedAt","replace","fieldDefinitionId","definitionIdentifier","match","FieldDefinition","FieldOption","include","fetchFieldDefinition","fieldDefinition","values","dataType","Object","entries","action","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","customFieldOptionDescription","deobfuscatedDescription","_deobfuscatedDescript","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","workflow_id_WorkflowsList","sensitiveString","o","toString","workflow_id","obfuscateSelectedFieldDescriptions","label","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","forbiddenText","error","errors","status","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","body","recover","result","fetchPeople","people","_catch","Person","fetchEvents","automationId","params","webhooksClient","_e","Delivery","Event","order","STATUS","delivered","failed","ignored","pending","skipped","mergePeopleAndEvents","mergedData","reduce","personId","foundPerson","p","push","person","event","History","automation","filterWhere","onEventsStatusChange","loading","paginationProps","refresh","setParams","_","setError","useState","setLoading","eventPages","setEventPages","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","per_page","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","_extends","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","responseBody","parse","parsedErrors","responseErrors","deliveryFailureReason","statusMessage","fontStyle","paddingTop","children","open","setOpen","inline","was","fontFamily","ErrorBoundary","Component","constructor","props","super","this","handleContactSupport","onRequestClose","window","openHelpdesk","state","hasError","static","render","Alert","type","marginVertical","boxShadow","style","CloseModalIcon","as","icon","HistoryModal","createPortal","ThemeProvider","Modal","paddingBottom","document","VALID_LOGO_NAMES","getValidLogoName","kebabName","kebabCase","isValidLogoName","fetchCurrentPersonAvatar","avatar","AutomationContext","EditableAutomation","updateAutomation","onDelete","openHistoryNow","disabledReason","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","rest","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","prev","createdBy","avatarUrl","createdByName","confirmButtonText","ToggleSwitch","isChecked","patch","newStatus","triggerProductName","Logo","markOnly","operationAppName","Divider","marginHorizontal","Avatar","basis","source","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","triggerParams","useTriggerPersonOverride","exec","trim","startsWith","fetchPersonApps","App","PersonApp","personApp","allowPcoLogin","app","toLowerCase","fetchCreatorProfiles","compact","uniq","profiles","fetchAutomations","AutomationSubscription","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","services","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","fetchNothing","fetchAllAtOnce","fetchOneAtATime","ids","allSettled","results","triggerResources","settledPromises","acc","concat","fetchIncomingAutomations","encryptedParam","fetchResourceName","path","_props","client","model","upperFirst","IncomingAutomations","setAutomations","operationApps","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","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","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","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","getOperationDefinitions","OperationDefinition","walk","getWebhooksApps","OperationApp","a","getVisibleApps","Topbar","apps","errorAlertProps","borderRadius","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","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","getOperationApps","visibleApps","webhooksApps","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","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.esm.js","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/utils.ts","../../src/history.tsx","../../src/history_modal.tsx","../../src/utils/logos.ts","../../src/utils/response-labelers/people-form.ts","../../src/utils/resolve-response-details.ts","../../src/automation.tsx","../../src/utils/fetch-automations.ts","../../src/incoming_automations.tsx","../../src/definition.tsx","../../src/field.tsx","../../src/fields.tsx","../../src/new_automation.tsx","../../src/new_automation_modal.tsx","../../src/utils/theme.ts","../../src/automations.tsx"],"sourcesContent":["import React from \"react\"\n\nconst SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { cloneDeep, isBoolean, set } from \"lodash\"\nimport moment from \"moment\"\n\nexport async function deobfuscateDescriptions(\n subscriptions: AutomationInstance[]\n) {\n return Promise.all(\n subscriptions.map(async (subscription) => {\n if (isDeobfuscatable(subscription)) {\n 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 buildTriggerConditions({\n baseConditions,\n dynamicConditions,\n dynamicTriggerConditions,\n}: {\n baseConditions: object\n dynamicConditions: DefinitionField[] | undefined\n dynamicTriggerConditions: SelectedFieldOptions\n}) {\n const triggerConditions = cloneDeep(baseConditions)\n const fields = dynamicConditions ?? []\n const writableFields = fields.filter((field) => {\n if (field.renderOnly) return false\n return renderIfChainSatisfied(field, fields, dynamicTriggerConditions)\n })\n\n for (const field of writableFields) {\n if (\n Object.prototype.hasOwnProperty.call(dynamicTriggerConditions, field.id)\n ) {\n set(triggerConditions, field.id, dynamicTriggerConditions[field.id])\n }\n }\n\n return triggerConditions\n}\n\nfunction shouldRender(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!Object.prototype.hasOwnProperty.call(field, \"renderIf\")) return true\n\n const renderIf = field.renderIf!\n if (isBoolean(renderIf)) return renderIf\n\n const conditionKey = Object.keys(renderIf)[0]\n return renderIf[conditionKey] === selectedFieldOptions[conditionKey]\n}\n\nfunction renderIfChainSatisfied(\n field: DefinitionField,\n allFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n): boolean {\n if (!shouldRender(field, selectedFieldOptions)) return false\n\n const renderIf = field.renderIf\n if (renderIf == null || renderIf === true) return true\n\n const upstreamId = Object.keys(renderIf)[0]\n const upstream = allFields.find((f) => f.id === upstreamId)\n if (!upstream) return true\n return renderIfChainSatisfied(upstream, allFields, selectedFieldOptions)\n}\n\nexport function getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter(\n (field) =>\n field.kind !== \"Hidden\" &&\n renderIfChainSatisfied(field, definitionFields, selectedFieldOptions)\n )\n}\n\nfunction describeSelectedFields({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n const description = selectedDefinition.definitionFields\n .map((field) => {\n if (!hasOwnProperty(selectedFieldOptions, field.id)) return null\n\n const value = selectedFieldOptions[field.id]\n let list\n\n switch (field.kind) {\n case \"Select\":\n case \"SelectSearch\":\n case \"PersonSearch\":\n case \"RadioButtons\":\n list = getListForField({ field, loadedLists })\n\n return (\n list && list.find((o) => o.value.toString() === value)?.description\n )\n case \"Checkbox\":\n return value && field.label\n case \"Checkboxes\":\n list = getListForField({ field, loadedLists })\n\n return list\n .filter((e) => hasOwnProperty(value as object, e.value))\n .map(\n (e) =>\n `${capitalize((value as Record<string, string>)[e.value])} ${\n e.description\n }`\n )\n .join(\", \")\n case \"NumberField\":\n case \"TextField\":\n case \"TextArea\":\n case \"DateField\":\n return value\n default:\n throw new Error(\n `Don't know how to build value for field with kind ${field.kind}`\n )\n }\n })\n .filter((x) => x)\n .join(\", \")\n\n return obfuscateSelectedFieldDescriptions({\n description,\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n}\n\nfunction obfuscateSelectedFieldDescriptions({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n description,\n}: {\n description: string\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n if (\n selectedDefinition.definitionClass === \"AddToWorkflowOperationDefinition\"\n ) {\n const list = loadedLists.workflow_id_WorkflowsList\n const sensitiveString =\n list &&\n list.find((o) => o.value.toString() === selectedFieldOptions.workflow_id)\n ?.description\n\n return sensitiveString\n ? description.replace(sensitiveString, \"[Hidden Workflow]\")\n : description\n } else if (\n selectedDefinition.definitionClass.match(\n /^CustomField\\w+OperationDefinition$/\n )\n ) {\n return \"\"\n } else {\n return description\n }\n}\n\nexport function dateFNSFormat(format: string) {\n return format\n .replace(/%m/, \"M\")\n .replace(/%d/, \"d\")\n .replace(/%Y/, \"y\")\n .replace(/%y/, \"yy\")\n}\n\nexport function momentDateFormat(format: string) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({\n dateFormat,\n twentyFourHourTime,\n}: {\n dateFormat: string\n twentyFourHourTime: boolean\n}) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date: string, dateFormat: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n if (!momentDate.isValid()) {\n return \"\"\n }\n\n const format = momentDateFormat(dateFormat)\n return momentDate.format(format)\n}\n\nexport function numDaysSince(date: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n return moment().diff(momentDate, \"days\")\n}\n\nexport function pluralize(count: number, word: string) {\n if (count === 1) {\n return `1 ${word}`\n } else {\n return `${count} ${word}s`\n }\n}\n\nexport function singularize(string: string) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nexport function triggerResourceParts(triggerResource: string) {\n const triggerParts = triggerResource.split(\"/\")\n\n return {\n appName: triggerParts[0],\n resourceId: triggerParts[triggerParts.length - 1],\n resourcePath: triggerParts.slice(2, -1).join(\"/\"),\n resourceType: triggerParts[triggerParts.length - 2],\n }\n}\n\nexport function forbiddenText(error: any, action?: string) {\n if (error.errors?.[0]?.status === \"403\") {\n return `You don't have permission to ${action || \"modify\"} this automation.`\n }\n return null\n}\n","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\ntype HistoryProps = {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: HistoryProps) {\n const { events, loading, paginationProps, refresh, params, setParams } =\n useEvents(automation.id, triggerResource, filterWhere)\n const { dateFormat, olsonTimeZone, twentyFourHourTime } = useContext<{\n dateFormat: any\n olsonTimeZone: any\n twentyFourHourTime: any\n }>(OrganizationContext)\n\n const filteringEvents = params.where && Object.keys(params.where).length > 0\n const automationCreatedRecently = numDaysSince(automation.createdAt) <= 32\n const automationBeganOn = dateLocalized(automation.createdAt, dateFormat)\n const historyPreservationAlert = automationCreatedRecently\n ? `Automation history started on ${automationBeganOn}`\n : \"Automation history is saved for 32 days\"\n\n const 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: HistoryProps) => (\n <ErrorBoundary onRequestClose={props.onRequestClose}>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-dim\"),\n name: \"general.x\",\n }}\n onClick={onClick}\n size=\"sm\"\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction HistoryModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={120}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Automation history\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default HistoryModal\n","import { Logo } from \"@planningcenter/tapestry-react\"\nimport { kebabCase } from \"lodash\"\nimport type { ComponentProps } from \"react\"\n\n// Extract valid logo names from the Logo component's props\ntype ValidLogoName = NonNullable<ComponentProps<typeof Logo>[\"name\"]>\n\n// List of valid logo names from @planningcenter/tapestry-react Logo component\n// Update this list when support for new products are added to tapestry-react\nconst VALID_LOGO_NAMES: ValidLogoName[] = [\n \"api\",\n \"calendar\",\n \"check-ins\",\n \"church-center\",\n \"giving\",\n \"groups\",\n \"headcounts\",\n \"home\",\n \"login\",\n \"music-stand\",\n \"people\",\n \"planning-center\",\n \"publishing\",\n \"registrations\",\n \"services\",\n]\n\nexport const isValidLogoName = (name: string): name is ValidLogoName => {\n return VALID_LOGO_NAMES.includes(name as ValidLogoName)\n}\n\nexport const getValidLogoName = (name: string): ValidLogoName => {\n const kebabName = kebabCase(name)\n return isValidLogoName(kebabName) ? kebabName : \"planning-center\"\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { uniq } from \"lodash\"\n\nimport type { ResponseLabeler } from \"./types\"\n\nconst HIDDEN_FIELD = \"[Hidden Field]\"\nconst HIDDEN_RESPONSE = \"[Hidden Response]\"\nconst FIELD_KEY_RE = /^field_(\\d+)$/\nconst SENTINEL_VALUES = new Set([\"no-option\"])\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\ntype FormFieldRecord = {\n fieldType: string\n fieldableId: number | null\n fieldableType: string | null\n id: number\n label: string | null\n options?: { id: number; label: string | null }[]\n}\n\ntype FieldDefinitionRecord = {\n dataType: string\n fieldOptions?: { id: number; value: string | null }[]\n id: number\n name: string | null\n}\n\ntype CampusRecord = {\n id: number\n name: string | null\n}\n\ntype ExtractedIds = {\n fieldId: string\n formId: string\n optionId: string | null\n}\n\nasync function resolve(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const extracted = subscriptions.map((sub) => ({\n ids: extractIds(sub),\n sub,\n }))\n const targets = extracted.filter(\n (entry): entry is { ids: ExtractedIds; sub: AutomationInstance } =>\n entry.ids !== null\n )\n if (targets.length === 0) return subscriptions\n\n const fieldsByForm = await fetchFormFields(\n uniq(targets.map((t) => t.ids.formId))\n )\n\n const fieldDefIds = new Set<string>()\n const campusIds = new Set<string>()\n for (const { ids } of targets) {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (field?.fieldType === \"custom_field\" && field.fieldableId != null) {\n fieldDefIds.add(String(field.fieldableId))\n } else if (field?.fieldType === \"primary_campus\" && ids.optionId != null) {\n campusIds.add(ids.optionId)\n }\n }\n const [fieldDefs, campuses] = await Promise.all([\n fetchFieldDefinitions([...fieldDefIds]),\n fetchCampuses([...campusIds]),\n ])\n\n return extracted.map(({ ids, sub }) => {\n if (!ids) return sub\n return {\n ...sub,\n responseDetails: buildResponseDetails(\n ids,\n fieldsByForm,\n fieldDefs,\n campuses\n ),\n }\n })\n}\n\nfunction extractIds(subscription: AutomationInstance): ExtractedIds | null {\n const conds = subscription.triggerConditions\n const formId = conds?.data?.relationships?.form?.data?.id\n const selectedOptionsByField = conds?.data?.attributes?.selectedOptionsByField\n if (\n formId == null ||\n !selectedOptionsByField ||\n typeof selectedOptionsByField !== \"object\"\n ) {\n return null\n }\n\n for (const [key, value] of Object.entries(selectedOptionsByField)) {\n const match = FIELD_KEY_RE.exec(key)\n if (!match) continue\n const raw = (value as { $in?: unknown })?.$in\n const optionIds = (Array.isArray(raw) ? raw : raw == null ? [] : [raw])\n .map((id) => (id == null ? null : String(id)))\n .filter((id): id is string => id != null && !SENTINEL_VALUES.has(id))\n return {\n fieldId: match[1],\n formId: String(formId),\n optionId: optionIds[0] ?? null,\n }\n }\n return null\n}\n\nasync function fetchFormFields(\n formIds: string[]\n): Promise<Map<string, Map<string, FormFieldRecord>>> {\n const result = new Map<string, Map<string, FormFieldRecord>>()\n await Promise.all(\n formIds.map(async (formId) => {\n try {\n const { data } = await peopleClient.get<{ data: FormFieldRecord[] }>({\n data: {\n fields: {\n FormField: \"label,field_type,fieldable,options\",\n FormFieldOption: \"label\",\n },\n include: \"options\",\n walk: true,\n },\n url: `forms/${formId}/fields`,\n })\n const byId = new Map<string, FormFieldRecord>()\n for (const field of data) {\n byId.set(String(field.id), field)\n }\n result.set(formId, byId)\n } catch {\n result.set(formId, new Map())\n }\n })\n )\n return result\n}\n\nasync function fetchFieldDefinitions(\n ids: string[]\n): Promise<Map<string, FieldDefinitionRecord>> {\n const result = new Map<string, FieldDefinitionRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: FieldDefinitionRecord[] }>({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"field_definitions\",\n })\n for (const fd of data) {\n result.set(String(fd.id), fd)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nasync function fetchCampuses(\n ids: string[]\n): Promise<Map<string, CampusRecord>> {\n const result = new Map<string, CampusRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: CampusRecord[] }>({\n data: {\n fields: { Campus: \"name\" },\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"campuses\",\n })\n for (const campus of data) {\n result.set(String(campus.id), campus)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nfunction buildResponseDetails(\n ids: ExtractedIds,\n fieldsByForm: Map<string, Map<string, FormFieldRecord>>,\n fieldDefs: Map<string, FieldDefinitionRecord>,\n campuses: Map<string, CampusRecord>\n): ResponseDetails {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (!field) return { fieldLabel: HIDDEN_FIELD, valueLabel: HIDDEN_RESPONSE }\n\n const fieldLabel = field.label || HIDDEN_FIELD\n\n if (field.fieldType === \"boolean\") {\n return { fieldLabel, valueLabel: null }\n }\n\n if (field.fieldType === \"custom_field\" && field.fieldableId != null) {\n const fd = fieldDefs.get(String(field.fieldableId))\n if (!fd) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n if (fd.dataType === \"boolean\") return { fieldLabel, valueLabel: null }\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const match = (fd.fieldOptions || []).find(\n (o) => String(o.id) === ids.optionId\n )\n return { fieldLabel, valueLabel: match?.value || HIDDEN_RESPONSE }\n }\n\n if (field.fieldType === \"primary_campus\") {\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const campus = campuses.get(ids.optionId)\n return { fieldLabel, valueLabel: campus?.name || HIDDEN_RESPONSE }\n }\n\n if (ids.optionId == null) {\n return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n }\n const match = (field.options || []).find((o) => String(o.id) === ids.optionId)\n return { fieldLabel, valueLabel: match?.label || HIDDEN_RESPONSE }\n}\n\nconst peopleFormLabeler: ResponseLabeler = { resolve }\n\nexport { peopleFormLabeler }\n","import { peopleFormLabeler } from \"./response-labelers/people-form\"\nimport type { ResponseLabeler } from \"./response-labelers/types\"\n\nconst labelers: Record<string, ResponseLabeler> = {\n \"people.v2.events.form_submission.created\": peopleFormLabeler,\n}\n\nasync function resolveResponseDetails(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const groups = new Map<string, AutomationInstance[]>()\n for (const sub of subscriptions) {\n if (!labelers[sub.name]) continue\n const group = groups.get(sub.name) ?? []\n group.push(sub)\n groups.set(sub.name, group)\n }\n if (groups.size === 0) return subscriptions\n\n const resolvedById = new Map<number, AutomationInstance>()\n await Promise.all(\n [...groups.entries()].map(async ([name, subs]) => {\n const resolved = await labelers[name].resolve(subs)\n for (const sub of resolved) resolvedById.set(sub.id, sub)\n })\n )\n\n return subscriptions.map((sub) => resolvedById.get(sub.id) ?? sub)\n}\n\nfunction formatResponseDetails(\n responseDetails: ResponseDetails | null | undefined\n): string {\n if (!responseDetails) return \"\"\n const { fieldLabel, valueLabel } = responseDetails\n if (valueLabel == null) return ` with \"${fieldLabel}\" selected`\n return ` with \"${fieldLabel}\" selected as \"${valueLabel}\"`\n}\n\nexport { formatResponseDetails, resolveResponseDetails }\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n Logo,\n StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { lowerFirst, truncate } from \"lodash\"\nimport React, { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { formatResponseDetails } from \"./utils/resolve-response-details\"\nimport { dateLocalized, forbiddenText } from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n disabled?: boolean\n disabledReason?: string\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationProps = {\n automation: IncomingAutomationInstance\n}\n\ntype EditableAutomationContextType = {\n automation: AutomationInstance\n currentPersonCanCreate?: boolean\n currentPersonId?: number\n theme: object\n trigger?: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation?: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationContextType = {\n automation: IncomingAutomationInstance\n}\n\nconst AutomationContext = createContext<\n EditableAutomationContextType | IncomingAutomationContextType\n>(null)\n\nfunction EditableAutomation({\n updateAutomation,\n onDelete,\n theme,\n openHistoryNow = false,\n disabled,\n disabledReason,\n ...props\n}: AutomationProps & {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper\n theme={theme}\n updateAutomation={updateAutomation}\n {...props}\n >\n <Header>\n <Icons />\n <Manage\n onDelete={onDelete}\n openHistoryNow={openHistoryNow}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n </Header>\n <Description />\n <EditableFooter />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingAutomation(props: IncomingAutomationProps) {\n return (\n <AutomationWrapper automation={props.automation}>\n <Header>\n <Icons />\n <LinkToAutomation />\n </Header>\n <IncomingDescription />\n <Footer />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingDescription() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n const triggerEventDescription = automation.triggerEventDescription\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-medium\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n {formatResponseDetails(automation.responseDetails)}, then{\" \"}\n {lowerFirst(name)} {conditionalSuffix(automation)}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction LinkToAutomation() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n return (\n <Button\n external\n iconLeft={{ name: \"general.newWindow\" }}\n variant=\"naked\"\n size=\"sm\"\n to={automation.triggerAdminUrl}\n disabled={!automation.canManage}\n tooltip={\n !automation.canManage\n ? \"You do not have access to this resource\"\n : undefined\n }\n color={token(\"--t-text-color-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-secondary\"),\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation,\n updateAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n updateAutomation?: (automation: AutomationInstance) => void\n}) {\n return (\n <AutomationContext.Provider\n value={{\n automation,\n theme,\n updateAutomation,\n ...rest,\n }}\n >\n <Card radius={4} padding={2}>\n {children}\n </Card>\n </AutomationContext.Provider>\n )\n}\n\nfunction Header({ children }: { children: React.ReactNode }) {\n const { automation } = useContext(AutomationContext)\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n padding={0}\n distribution=\"space-between\"\n opacity={cardOpacity}\n >\n {children}\n </StackView>\n )\n}\n\nfunction Manage({\n onDelete,\n openHistoryNow = false,\n disabled,\n disabledReason,\n}: {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n}) {\n const {\n automation,\n currentPersonCanCreate,\n currentPersonId,\n trigger,\n theme,\n updateAutomation,\n } = useContext(AutomationContext) as EditableAutomationContextType\n const [historyVisible, setHistoryVisible] = useState(openHistoryNow)\n const isActive = automation.active\n const { name } = parseDescription(automation.description)\n\n function showHistory() {\n setHistoryVisible(true)\n }\n\n function updateEventsStatus(newStatus: AutomationInstance[\"eventsStatus\"]) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n function handleToggleActive() {\n webhooksClient\n .patch({\n data: {\n _e: trigger.resource,\n data: {\n attributes: {\n active: !isActive,\n },\n },\n },\n url: `/automation_subscriptions/${automation.id}`,\n })\n .then((data: { data: { active: boolean } }) => {\n updateAutomation((prev) => ({ ...prev, active: data.data.active }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"pause\") ||\n `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handleReassign() {\n alerts.confirm\n .fire({\n text: \"This automation will run with your permission levels. Other administrators who can see this automation can grant it their permissions by reassigning it to themselves.\",\n title: \"Reassign automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) {\n webhooksClient\n .post({\n data: {\n _e: trigger.resource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automation.id}/self_assign`,\n })\n .then(({ data }) => fetchCurrentPersonAvatar(data))\n .then(({ subscription, avatar }) => {\n updateAutomation((prev) => ({\n ...prev,\n createdBy: { ...prev.createdBy, avatarUrl: avatar },\n createdById: subscription.createdById,\n createdByName: subscription.createdByName,\n }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"update\") ||\n \"There was a problem updating this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n })\n }\n\n function handleDelete() {\n alerts.confirmDestroy\n .fire({\n confirmButtonText: \"Yes, delete automation\",\n text: `Are you sure you want to delete the \"${name}\" automation? This cannot be undone.`,\n title: \"Delete this automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) onDelete(automation.id)\n })\n }\n\n return (\n <>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Dropdown\n icon={{\n color: token(\"--t-icon-color\"),\n name: \"churchCenter.threeDots\",\n }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\n disabled={disabled}\n >\n <Dropdown.Item onSelect={() => showHistory()}>History</Dropdown.Item>\n {currentPersonCanCreate &&\n (automation.createdById === currentPersonId ? (\n <Dropdown.Item disabled={true}>\n <Tooltip\n placement=\"left\"\n openDelay={250}\n title=\"This automation is already assigned to you.\"\n >\n <Text>Reassign to me...</Text>\n </Tooltip>\n </Dropdown.Item>\n ) : (\n <Dropdown.Item onSelect={handleReassign}>\n Reassign to me...\n </Dropdown.Item>\n ))}\n <Dropdown.Item onSelect={handleDelete}>Delete...</Dropdown.Item>\n </Dropdown>\n <ToggleSwitch\n isChecked={isActive}\n size=\"sm\"\n onClick={handleToggleActive}\n tooltip={\n disabled\n ? disabledReason\n : isActive\n ? \"Pause automation\"\n : \"Enable automation\"\n }\n disabled={disabled}\n />\n </StackView>\n\n <HistoryModal\n open={historyVisible}\n onRequestClose={() => setHistoryVisible(false)}\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n onEventsStatusChange={updateEventsStatus}\n onRequestClose={() => setHistoryVisible(false)}\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Icons() {\n const { automation } = useContext(AutomationContext)\n const triggerProductName = automation.name.split(\".\")[0]\n\n return (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.5}>\n <Logo\n markOnly={true}\n name={getValidLogoName(triggerProductName)}\n size=\"sm\"\n theme=\"color\"\n />\n <Icon name=\"general.rightArrow\" size={1.5} />\n <Logo\n markOnly={true}\n name={getValidLogoName(automation.operationAppName)}\n size=\"sm\"\n theme=\"color\"\n />\n </StackView>\n )\n}\nfunction Footer() {\n const { automation } = useContext(AutomationContext)\n const { dateFormat } = useContext(OrganizationContext)\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-half\")}\n maxWidth=\"calc(100% - 136px)\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={2}\n height={2}\n basis={2}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={5} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n </>\n )\n}\n\nfunction EditableFooter() {\n const { dateFormat } = useContext(OrganizationContext)\n const { automation, trigger, theme, updateAutomation } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n const buttonProps = {\n color: token(\"--t-text-color-secondary\"),\n fontSize: token(\"--t-font-size-xs\"),\n fontWeight: token(\"--t-font-weight-normal\"),\n paddingHorizontal: token(\"--t-spacing-1\"),\n radius: \"pill\",\n size: \"xs\",\n variant: \"naked\",\n }\n const [historyProps, setHistoryProps] = useState({\n filter: null,\n historyVisible: false,\n })\n\n function renderSkippedHistory() {\n setHistoryProps({ filter: \"skipped\", historyVisible: true })\n }\n\n function renderFailedOrDuplicatedHistory() {\n setHistoryProps({ filter: \"failed,duplicated\", historyVisible: true })\n }\n\n function handleEventsStatusChange(\n newStatus: AutomationInstance[\"eventsStatus\"]\n ) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-fourth\")}\n >\n {!!automation.eventsStatus?.skipped && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.skipped} skipped`}\n onClick={renderSkippedHistory}\n tooltip={`${automation.eventsStatus.skipped?.toLocaleString()} skipped events`}\n >\n <Box\n backgroundColor={token(\"--t-fill-color-status-warning\")}\n marginRight={token(\"--t-spacing-half\")}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding={token(\"--t-spacing-fourth\")}\n >\n <Icon\n name={\"services.pause\"}\n size={\"6px\"}\n title={\"Skipped\"}\n color=\"white\"\n />\n </Box>\n {`${automation.eventsStatus.skipped?.toLocaleString()}`}\n </Button>\n )}\n {!!automation.eventsStatus?.failed && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.failed} failed`}\n iconLeft={{\n color: token(\"--t-icon-color-status-error\"),\n marginRight: token(\"--t-spacing-half\"),\n name: \"general.exclamationTriangle\",\n size: \"10px\",\n title: \"Failed\",\n }}\n onClick={renderFailedOrDuplicatedHistory}\n title={`${automation.eventsStatus.failed?.toLocaleString()}`}\n tooltip={`${automation.eventsStatus.failed?.toLocaleString()} failed events`}\n />\n )}\n </StackView>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"end\"\n flex={1}\n spacing={token(\"--t-spacing-half\")}\n marginLeft=\"auto\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={token(\"--t-element-size-md\")}\n height={token(\"--t-element-size-md\")}\n basis={token(\"--t-element-size-md\")}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={token(\"--t-font-size-sm\")} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n\n <HistoryModal\n open={historyProps.historyVisible}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n filterWhere={historyProps.filter}\n onEventsStatusChange={handleEventsStatusChange}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Description() {\n const { automation, trigger } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n const triggerEventDescription = [\n \"When a person\",\n lowerFirst(trigger.event.description) +\n formatResponseDetails(automation.responseDetails) +\n \",\",\n \"then\",\n lowerFirst(name),\n conditionalSuffix(automation),\n ].join(\" \")\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-bold\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction 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_conditions,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { truncate, upperFirst } from \"lodash\"\nimport React, { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nasync function fetchIncomingAutomations(encryptedParam) {\n const { data } = await webhooksClient.get({\n data: {\n _e: encryptedParam,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,trigger_conditions,trigger_resource,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"incoming_automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchTriggerResources(automations) {\n // We can optimize the query by fetching all the resources at once if we know\n // that the endpoint supports querying by multiple ids. Otherwise, we'll have\n // to fetch each resource individually.\n const QUERYABLE_BY_MULTIPLE_IDS = {\n people: [\"forms\", \"lists\"],\n registrations: [\"events\"],\n services: [\"teams\"],\n }\n const NOT_QUERYABLE = [\"giving\"]\n\n const automationsByModel = automations.reduce((accumulator, automation) => {\n // registrations has a weird case of signup vs event\n const automationTriggerResource = automation.triggerResource.replace(\n /signup/,\n \"event\"\n )\n const { appName, resourceType, resourcePath, resourceId } =\n triggerResourceParts(automationTriggerResource)\n\n if (!accumulator[appName]) accumulator[appName] = {}\n if (!accumulator[appName][resourceType])\n accumulator[appName][resourceType] = {}\n if (!accumulator[appName][resourceType][\"resoucePath\"])\n accumulator[appName][resourceType][\"resourcePath\"] = resourcePath\n\n if (!accumulator[appName][resourceType][\"ids\"])\n accumulator[appName][resourceType][\"ids\"] = []\n\n accumulator[appName][resourceType][\"ids\"].push(resourceId)\n\n return accumulator\n }, {})\n\n const promises = Object.keys(automationsByModel).flatMap((appName) => {\n const automationsByResourceType = automationsByModel[appName]\n\n return Object.entries(automationsByResourceType).flatMap(\n ([resourceType, resourceParts]) => {\n const fetchFn = NOT_QUERYABLE.includes(appName)\n ? fetchNothing\n : QUERYABLE_BY_MULTIPLE_IDS[appName]?.includes(resourceType)\n ? fetchAllAtOnce\n : fetchOneAtATime\n\n return fetchFn({\n appName,\n ids: resourceParts[\"ids\"],\n resourcePath: resourceParts[\"resourcePath\"],\n resourceType,\n })\n }\n )\n })\n\n const results = await Promise.allSettled(promises)\n\n return {\n automations,\n triggerResources: collectSuccessfulResults(results),\n }\n}\n\nfunction collectSuccessfulResults(settledPromises) {\n return settledPromises\n .reduce((acc, result) => {\n if (result.status === \"fulfilled\") acc = acc.concat(result.value)\n\n return acc\n }, [])\n .flatMap((d) => d.data)\n}\n\nfunction fetchAllAtOnce({ appName, resourcePath, resourceType, ids }) {\n return fetchResourceName({\n appName,\n params: {\n where: { id: ids.join(\",\") },\n },\n path: resourcePath,\n resourceType,\n })\n}\n\nfunction fetchOneAtATime({ appName, resourcePath, resourceType, ids }) {\n return ids.map((id) =>\n fetchResourceName({\n appName,\n path: `${resourcePath}/${id}`,\n resourceType,\n })\n )\n}\n\nfunction fetchNothing(_props: object) {\n return new Promise((_, reject) => {\n reject()\n })\n}\n\n// TODO (maybe): move these to webhooks, return the verb in the API response,\n// so new events don't need a code change in both places\nfunction mapNameToVerb(messageName) {\n // e.g. \"groups.v2.events.membership.created\" => \"groups.membership.created\"\n const appResourceAction = messageName.replace(\"v2.events.\", \"\")\n\n switch (appResourceAction) {\n case \"groups.membership.created\":\n return \"joins\"\n case \"groups.membership.destroyed\":\n return \"leaves\"\n case \"people.list_result.created\":\n case \"services.team_person.created\":\n return \"is added to\"\n case \"people.list_result.destroyed\":\n case \"services.team_person.destroyed\":\n return \"is removed from\"\n case \"people.form_submission.created\":\n return \"submits\"\n case \"registrations.attendee.created\":\n return \"is registered as a new attendee for\"\n case \"registrations.attendee.cancelled\":\n return \"is canceled as an attendee for\"\n case \"registrations.registration.created\":\n return \"is the registration contact on a new registration for\"\n case \"registrations.registration.cancelled\":\n return \"is the registration contact on a canceled registration for\"\n default:\n return null\n }\n}\n\nfunction buildGivingDescription(automation: AutomationInstance) {\n const action = automation.name.replace(\"giving.v2.events.\", \"\")\n\n switch (action) {\n case \"donation.payment_successful\":\n return \"When a person gives\"\n case \"profile.first_donated_automation\":\n return \"When a person gives for the first time\"\n case \"recurring_donation.setup_successful\":\n return \"When a person sets up a recurring donation\"\n default:\n return null\n }\n}\n\nfunction buildDescription(automation, triggerResourceName) {\n const verb = mapNameToVerb(automation.name)\n\n const { resourceType } = triggerResourceParts(automation.triggerResource)\n\n if (!verb) {\n // No verb mapping for this message name, so just show something generic\n const resourceName = truncate(triggerResourceName, {\n length: 160,\n separator: \" \",\n })\n\n return `When the automation is triggered from ${singularize(\n resourceType\n )} \"${resourceName}\"`\n }\n\n return `When a person ${verb} ${singularize(\n resourceType\n )} \"${triggerResourceName}\"`\n}\n\nfunction fetchResourceName({\n appName,\n path,\n resourceType,\n params = {},\n}): Promise<any> {\n const client = new Client({ root: pcoApiUrl(appName, { squiggly: false }) })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color\")}`}\n marginBottom={token(\"--t-spacing-2\")}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n >\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text\n color={token(\"--t-text-color-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\nimport React from \"react\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === 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 React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n if (field.kind === \"Hidden\") return null\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n />\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 "{query}"</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value ?? \"\"}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import React, { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n 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 React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n buildTriggerConditions,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] =\n useState<SelectedFieldOptions>({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{ [k: string]: LoadedList[] }>(\n {}\n )\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n const triggerConditions = buildTriggerConditions({\n baseConditions:\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions,\n dynamicConditions,\n dynamicTriggerConditions,\n })\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n alert(\"something even worse happened!\")\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color\"),\n fontSize: token(\"--t-font-size-md\"),\n lineHeight: 1.65,\n marginBottom: token(\"--t-spacing-2\"),\n }}\n >\n {description}{\" \"}\n <Link external to={blankStateLink}>\n Learn more\n </Link>\n </Text>\n </Box>\n )}\n {error.automation && (\n <Alert {...errorAlertProps}>\n <Text>\n There was an error creating your automation. Please change your\n selections and try again or contact support if the problem persists.\n </Text>\n </Alert>\n )}\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color\")}\n controls=\"select-trigger-event\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n When a person...\n </Input.InputLabel>\n <Select\n id=\"select-trigger-event\"\n onChange={({ selectedValue }) =>\n handleChangeTriggerEvent(selectedValue)\n }\n size=\"lg\"\n value={selectedTriggerEvent}\n >\n {trigger.events.map((triggerEvent, idx) => (\n <Select.Option\n key={`${triggerEvent.name}_${idx}`}\n value={triggerEvent}\n >\n {triggerEvent.description}\n </Select.Option>\n ))}\n </Select>\n\n {dynamicConditions?.length > 0 && (\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={dynamicConditions}\n selectedFieldOptions={dynamicTriggerConditions}\n onChange={setDynamicTriggerConditions}\n loadedLists={{}}\n loadingLists={{}}\n loadListForField={() => null}\n />\n )}\n </StackView>\n\n <StackView spacing={1}>\n {operationApps.length > 0 ? (\n <Application\n selectedApp={selectedApp}\n operationApps={operationApps}\n onOperationAppChange={handleChangeSelectedApp}\n />\n ) : (\n <StackView spacing={1}>\n <Text\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={4}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={token(\"--t-spacing-1\")} {...errorAlertProps}>\n <Text>\n There was a problem looking up automations. Please contact support\n if the problem persists.\n </Text>\n </Alert>\n ) : loadingOperationDefinitions ? (\n <LoadingOperationDefinitions />\n ) : (\n <Definition\n selectedOperation={selectedDefinition}\n operationDefinitions={operationDefinitions}\n onOperationDefinitionChange={handleSelectedDefinitionChange}\n />\n )}\n </StackView>\n\n {selectedDefinition &&\n (error.selected_definition ? (\n <Alert {...errorAlertProps}>\n <Text>\n There was a problem looking up automation options. Please contact\n support if the problem persists.\n </Text>\n </Alert>\n ) : (\n <>\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={selectedDefinition.definitionFields || []}\n onChange={setSelectedFieldOptions}\n selectedFieldOptions={selectedFieldOptions}\n loadedLists={loadedLists}\n loadListForField={loadListForField}\n loadingLists={loadingLists}\n />\n {afterCreateOptions?.label && (\n <Checkbox\n disabled={\n submitting ||\n disableSubmit(selectedDefinition, selectedFieldOptions)\n }\n label={afterCreateOptions.label}\n checked={callAfterCreate}\n onChange={() => setCallAfterCreate(!callAfterCreate)}\n />\n )}\n {selectedTriggerEvent?.triggerParams?.map((param, idx) => (\n <Checkbox\n key={`${param.key}_${idx}`}\n label={param.description}\n checked={\n (triggerParams && triggerParams[param.key]) ||\n param.defaultValue\n }\n onChange={(e) => {\n setTriggerParams((prev) => ({\n ...prev,\n [`${param.key}`]: e.target.checked,\n }))\n }}\n />\n ))}\n {dangerAlertPresent && (\n <Alert {...errorAlertProps}>\n <StackView axis=\"horizontal\" spacing={1.5}>\n <Icon\n size={token(\"--t-element-size-lg\")}\n name=\"general.exclamationTriangle\"\n color={token(\"--t-icon-color-status-error\")}\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${token(\"--t-border-color\")}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={token(\"--t-text-color-headline\")}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={token(\"--t-font-weight-normal\")}\n onClick={onRequestClose}\n size=\"md\"\n title=\"Cancel\"\n variant=\"naked\"\n />\n <Button\n disabled={\n submitting ||\n dangerAlertPresent ||\n disableSubmit(\n selectedDefinition,\n selectedFieldOptions,\n dynamicConditions,\n dynamicTriggerConditions\n )\n }\n onClick={handleSubmit}\n size=\"md\"\n theme=\"primary\"\n title={getButtonText(selectedDefinition, selectedFieldOptions)}\n variant=\"fill\"\n data-testid=\"create-automation\"\n />\n </StackView>\n </StackView>\n )\n}\n\nfunction disableSubmit(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions,\n dynamicConditions?: DefinitionField[],\n dynamicTriggerConditions?: SelectedFieldOptions\n) {\n if (!selectedDefinition) return true\n\n const operationFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n if (\n !operationFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n if (\n !operationFields\n .filter((field) => fieldIsSelect(field))\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n\n const triggerFields = getRenderedFields(\n dynamicConditions ?? [],\n dynamicTriggerConditions ?? {}\n )\n if (\n !triggerFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, dynamicTriggerConditions ?? {}))\n )\n return true\n\n return false\n}\n\nfunction fieldIsSelect(field: DefinitionField) {\n return field.kind === \"Select\" || field.kind === \"SelectSearch\"\n}\n\nfunction fieldIsFilled(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (fieldIsSelect(field)) {\n return selectedFieldOptions.hasOwnProperty(field.id)\n } else {\n return (\n selectedFieldOptions.hasOwnProperty(field.id) &&\n selectedFieldOptions[field.id] &&\n selectedFieldOptions[field.id].toString().trim() !== \"\"\n )\n }\n}\n\nfunction getNextRequiredDescription(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!selectedDefinition?.definitionFields) return\n\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n for (const field of renderedFields) {\n if (field.required && !fieldIsFilled(field, selectedFieldOptions))\n return field.description\n }\n}\n\nfunction getButtonText(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n const nextRequiredDescription = getNextRequiredDescription(\n selectedDefinition,\n selectedFieldOptions\n )\n\n if (!selectedDefinition) {\n return \"Select an action\"\n } else if (nextRequiredDescription) {\n return `Select a${\n nextRequiredDescription.charAt(0).match(/[aeiou]/i) ? \"n\" : \"\"\n } ${nextRequiredDescription.toLowerCase()}`\n } else {\n return \"Create automation\"\n }\n}\n\nconst Application = ({\n onOperationAppChange,\n operationApps,\n selectedApp,\n}: {\n onOperationAppChange: (selectedValue: string) => void\n operationApps: Array<{ id: string; name: string }>\n selectedApp: string\n}) => {\n const handleChange = ({ selectedValue }) => {\n onOperationAppChange(selectedValue)\n }\n\n return (\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n controls=\"select-product\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Input.InputLabel>\n <Select\n autoFocus\n id=\"select-product\"\n onChange={handleChange}\n size=\"lg\"\n value={selectedApp}\n >\n {operationApps.map((app) => (\n <Select.Option key={app.id} value={app.id}>\n {app.name}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n )\n}\n\nconst LoadingOperationDefinitions = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{ color: token(\"--t-icon-color-dim\"), name: \"general.x\" }}\n onClick={onClick}\n size={\"sm\"}\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction NewAutomationModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={75}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Create automation\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n <style>{`\n .swal2-container.swal2-backdrop-show { z-index: 10001 }\n `}</style>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default NewAutomationModal\n","import * as churchCenter from \"@planningcenter/icons/paths/church-center\"\nimport * as logomark from \"@planningcenter/icons/paths/logomark\"\nimport * as services from \"@planningcenter/icons/paths/services\"\n\nexport const icons = {\n churchCenter,\n logomark,\n services,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport sortBy from \"lodash/sortBy\"\nimport React, { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n forbiddenText,\n pluralize,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused ? undefined : `1px solid ${token(\"--t-border-color\")}`\n }\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={token(\"--t-spacing-2\")}\n marginTop={-3}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n spacing={token(\"--t-spacing-2\")}\n wrap\n zIndex={2}\n >\n {canCreate && !hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n marginHorizontal={1}\n spacing={1}\n >\n <Icon\n size={2}\n color={token(\"--t-icon-color-status-warning\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n disabled?: boolean\n disabledReason?: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color\"),\n level: 2,\n size: token(\"--t-font-size-2xl\"),\n weight: token(\"--t-font-weight-bold\"),\n }\n\n const BlankStateTextProps = {\n color: token(\"--t-text-color-secondary\"),\n lineHeight: 3,\n size: token(\"--t-font-size-md\"),\n }\n\n function automationTriggerEvent(automation: AutomationInstance) {\n return trigger.events.find((event) => event.name === automation.name)\n }\n\n const handleUpdateAutomation =\n (originalAutomation: AutomationInstance) =>\n (newState: React.SetStateAction<AutomationInstance>) => {\n const updated =\n typeof newState == \"function\" ? newState(originalAutomation) : newState\n const newAutomations = [\n ...automations.filter((automation) => automation.id !== updated.id),\n updated,\n ]\n\n setAutomations(newAutomations)\n }\n\n return (\n <ThemeProvider theme={customTheme}>\n <OrganizationContext.Provider\n value={{ dateFormat, olsonTimeZone, twentyFourHourTime }}\n >\n {trigger && (\n <Header\n automations={automations}\n blankStateLink={blankStateLink}\n canCreate={currentPersonCanCreate && !disabled}\n loading={loading}\n defaultApp={defaultApp}\n description={blankStateDescription}\n theme={customTheme}\n trigger={trigger}\n hasActiveAutomations={hasActiveAutomations}\n onPauseAutomations={handlePauseAutomations}\n afterCreateOptions={afterCreateOptions}\n />\n )}\n {loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading automations...\"}\n />\n ) : !trigger ? (\n <></>\n ) : (\n <Box data-testid=\"automations-section\">\n {automations?.length > 0 ? (\n <TileView spacing={3} marginVertical={3} minCellWidth={45}>\n {sortBy(automations, \"id\").map((a) => (\n <EditableAutomation\n key={a.id}\n automation={a}\n updateAutomation={handleUpdateAutomation(a)}\n onDelete={handleDelete}\n theme={customTheme}\n openHistoryNow={a.id === Number(automationId)}\n trigger={{\n event: automationTriggerEvent(a),\n resource: trigger.resource,\n }}\n currentPersonId={currentPersonId}\n currentPersonCanCreate={currentPersonCanCreate}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={token(\"--t-spacing-6\")}\n spacing={token(\"--t-spacing-2\")}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n spacing: token(\"--t-spacing-6\"),\n },\n }}\n >\n <Box\n css={{\n \".symbol\": {\n height: \"100%\",\n width: \"100%\",\n },\n }}\n maxWidth={24}\n mediaQueries={{\n lg: {\n maxWidth: 40,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <StackView\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n maxWidth={45}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n textAlign: \"left\",\n },\n }}\n textAlign=\"center\"\n >\n {currentPersonCanCreate ? (\n <>\n <Heading {...BlankStateHeadingProps}>\n Add an automation\n </Heading>\n <StackView\n alignment=\"center\"\n marginBottom={token(\"--t-spacing-1\")}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}\n </Text>\n </StackView>\n <StackView\n axis=\"horizontal\"\n spacing={token(\"--t-spacing-1\")}\n >\n <Button\n variant=\"outline\"\n to={blankStateLink}\n color={`${token(\n \"--t-text-color-status-neutral\"\n )} !important`}\n >\n Learn more\n </Button>\n <Button\n as=\"button\"\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n </StackView>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={customTheme}\n >\n <NewAutomation\n defaultApp={defaultApp}\n description={blankStateDescription}\n blankStateLink={blankStateLink}\n onRequestClose={() => setNewModalVisible(false)}\n trigger={trigger}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </>\n ) : (\n <>\n <Heading {...BlankStateHeadingProps}>Automations</Heading>\n <Text {...BlankStateTextProps}>\n {permissionDeniedReason}\n </Text>\n </>\n )}\n </StackView>\n </StackView>\n )}\n </Box>\n )}\n {incomingAutomationsParam && (\n <IncomingAutomations\n encryptedParam={incomingAutomationsParam}\n trigger={trigger}\n />\n )}\n </OrganizationContext.Provider>\n <style>{styles}</style>\n </ThemeProvider>\n )\n}\n"],"names":["SvgAutomations","React","createElement","id","xmlns","viewBox","className","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","deobfuscateDescriptions","subscriptions","Promise","all","map","subscription","_temp","isDeobfuscatable","includes","operationDefinitionClassName","resolve","deobfuscatedDescription","_temp3","description","_temp2","fetchWorkflow","workflowId","peopleClient","get","data","fields","Workflow","where","url","catch","name","then","e","reject","operationParams","workflow","workflowName","archivedAt","replace","fieldDefinitionId","definitionIdentifier","match","fetchFieldDefinition","FieldDefinition","FieldOption","include","fieldDefinition","values","dataType","Object","entries","action","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","customFieldOptionDescription","_deobfuscatedDescript","string","charAt","toUpperCase","slice","Client","root","pcoApiUrl","squiggly","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","renderIfChainSatisfied","allFields","selectedFieldOptions","renderIf","isBoolean","conditionKey","keys","shouldRender","upstreamId","upstream","f","getRenderedFields","definitionFields","filter","describeSelectedFields","selectedDefinition","workflow_id_WorkflowsList","sensitiveString","o","toString","workflow_id","obfuscateSelectedFieldDescriptions","label","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","forbiddenText","error","errors","status","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","body","recover","result","fetchPeople","people","_catch","Person","fetchEvents","automationId","params","webhooksClient","_e","Delivery","Event","order","STATUS","delivered","failed","ignored","pending","skipped","mergePeopleAndEvents","mergedData","reduce","personId","foundPerson","p","push","person","event","History","automation","filterWhere","onEventsStatusChange","loading","paginationProps","refresh","setParams","_","setError","useState","setLoading","eventPages","setEventPages","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","per_page","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","_extends","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","responseBody","parse","parsedErrors","responseErrors","deliveryFailureReason","statusMessage","fontStyle","paddingTop","children","open","setOpen","inline","was","fontFamily","ErrorBoundary","Component","constructor","props","super","this","handleContactSupport","onRequestClose","window","openHelpdesk","state","hasError","static","render","Alert","type","marginVertical","boxShadow","style","CloseModalIcon","as","icon","HistoryModal","createPortal","ThemeProvider","Modal","paddingBottom","document","VALID_LOGO_NAMES","getValidLogoName","kebabName","kebabCase","isValidLogoName","fetchCampuses","ids","Map","Campus","walk","campus","set","String","fetchFieldDefinitions","fd","HIDDEN_FIELD","HIDDEN_RESPONSE","FIELD_KEY_RE","SENTINEL_VALUES","Set","extractIds","conds","triggerConditions","formId","relationships","form","selectedOptionsByField","exec","raw","$in","optionIds","Array","isArray","has","fieldId","optionId","buildResponseDetails","fieldsByForm","fieldDefs","campuses","fieldLabel","valueLabel","fieldType","fieldableId","options","resolveResponseDetails","groups","sub","labelers","group","resolvedById","subs","resolved","extracted","targets","entry","formIds","FormField","FormFieldOption","byId","fetchFormFields","uniq","t","fieldDefIds","campusIds","add","responseDetails","formatResponseDetails","fetchCurrentPersonAvatar","avatar","AutomationContext","EditableAutomation","updateAutomation","onDelete","openHistoryNow","disabledReason","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","rest","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","prev","createdBy","avatarUrl","createdByName","confirmButtonText","ToggleSwitch","isChecked","patch","newStatus","triggerProductName","Logo","markOnly","operationAppName","Divider","marginHorizontal","Avatar","basis","source","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","triggerParams","useTriggerPersonOverride","trim","startsWith","fetchPersonApps","App","PersonApp","personApp","allowPcoLogin","app","toLowerCase","fetchCreatorProfiles","compact","profiles","fetchAutomations","AutomationSubscription","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","services","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","fetchNothing","fetchAllAtOnce","fetchOneAtATime","allSettled","results","triggerResources","settledPromises","acc","concat","fetchIncomingAutomations","encryptedParam","fetchResourceName","path","_props","client","model","upperFirst","IncomingAutomations","setAutomations","operationApps","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","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","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","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","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","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","getOperationDefinitions","OperationDefinition","getWebhooksApps","OperationApp","a","getVisibleApps","Topbar","apps","errorAlertProps","borderRadius","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","dynamicConditions","baseConditions","cloneDeep","writableFields","renderOnly","buildTriggerConditions","conditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","operationFields","required","every","fieldIsFilled","fieldIsSelect","nextRequiredDescription","renderedFields","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg","styles"],"mappings":"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"}
|