@planningcenter/core-automations 1.12.3-qa-402.0 → 1.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"core-automations.umd.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":["const SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { isBoolean } from \"lodash\"\nimport moment from \"moment\"\n\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 return subscription.operationParams.value\n ? fieldDefinition.fieldOptions.find(\n (fieldOption) =>\n fieldOption.id ===\n parseInt(subscription.operationParams.value.toString(), 10)\n )?.value || \"[Hidden value]\"\n : \"Unanswered\"\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({ app: \"people\", version: \"2025-03-20\" })\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 list = loadedLists[fieldListIdentifier(field)]\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)[0]\n\n return isBoolean(renderIf)\n ? renderIf\n : renderIf[conditionKey] === 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((e) => `${capitalize(value[e.value])} ${e.description}`)\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 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 description.replace(sensitiveString, \"[Hidden Workflow]\")\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) {\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) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({ dateFormat, twentyFourHourTime }) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date, dateFormat) {\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) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(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 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 Helpdesk: any\n }\n}\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\nconst peopleClient = new Client({ app: \"people\", version: \"2022-07-14\" })\n\n// values should match the webhooks Event `status` enum entries\nconst STATUS = {\n delivered: {\n label: \"Success\",\n value: [\"delivered\"],\n },\n failed: {\n label: \"Failed\",\n value: [\"failed\", \"duplicated\"],\n },\n ignored: {\n label: \"Ignored\",\n value: [\"ignored_duplicated\", \"ignored_failed\", \"ignored_skipped\"],\n },\n pending: {\n label: \"Pending\",\n value: [\"pending\"],\n },\n skipped: {\n label: \"Paused\",\n value: [\"skipped\"],\n },\n}\n\nasync function fetchEvents(\n triggerResource: EncryptedTriggerResource,\n automationId: number,\n params: {\n offset: number\n per_page: number\n where?: { status: string } | null\n }\n) {\n const response = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n Delivery: \"status,response_body,created_at\",\n Event: \"id,created_at,last_delivery,payload,status,uuid,person\",\n },\n include: \"last_delivery\",\n order: \"-created_at\",\n ...params,\n },\n url: `automation_subscriptions/${automationId}/events`,\n })\n\n return response\n}\n\nasync function fetchPeople(personIds) {\n const { data } = await peopleClient.get({\n data: {\n fields: {\n Person: \"id,name\",\n },\n where: { id: personIds.join(\",\") },\n },\n url: `people`,\n })\n\n return data\n}\n\nasync function fetchPeopleWhoTriggeredEvents(events) {\n const personIds = events.data.map((e) => eventPersonId(e))\n try {\n const people = await fetchPeople(personIds)\n return { events, people }\n } catch (error) {\n return { events, people: [] }\n }\n}\n\nfunction mergePeopleAndEvents({ events, people }) {\n const mergedData = events.data.reduce((result, e) => {\n const personId = eventPersonId(e)\n const foundPerson = people.find(\n (p) => personId.toString() === p.id.toString()\n )\n if (foundPerson) {\n result.push({\n ...e,\n person: { id: foundPerson.id, name: foundPerson.name },\n })\n } else {\n result.push({\n ...e,\n person: { id: personId, name: \"[Hidden]\" },\n })\n }\n return result\n }, [])\n\n return { ...events, data: mergedData }\n}\n\nfunction eventPersonId(event) {\n return event.personId\n}\n\nfunction useEvents(\n automationId: number,\n triggerResource: EncryptedTriggerResource,\n filterWhere?: string\n) {\n const perPage = 50\n const [_, setError] = useState()\n const [loading, setLoading] = useState(false)\n const [eventPages, setEventPages] = useState<{ [k: number]: EventPage[] }>({})\n const [params, setParams] = useState<{ where?: { status: string } | null }>(\n filterWhere ? { where: { status: filterWhere } } : {}\n )\n const [meta, setMeta] = useState<{ totalCount: number | any }>()\n const { offset, paginationProps, resetOffset } = usePagination(\n perPage,\n meta?.totalCount\n )\n useEffect(() => {\n if (loading || eventPages[offset]) return\n\n setLoading(true)\n\n fetchEvents(triggerResource, automationId, {\n offset,\n per_page: perPage,\n ...params,\n })\n .then(fetchPeopleWhoTriggeredEvents)\n .then(mergePeopleAndEvents)\n .then((events) => {\n setEventPages((pages) => ({ ...pages, [offset]: events.data }))\n setMeta(events.meta)\n setLoading(false)\n })\n .catch(bubbleErrorToBoundary)\n }, [automationId, triggerResource, loading, params, offset, eventPages])\n\n const refresh = useCallback(() => {\n setEventPages({})\n setMeta(undefined)\n resetOffset()\n }, [resetOffset])\n\n useEffect(() => {\n refresh()\n }, [refresh, params])\n\n function bubbleErrorToBoundary(error) {\n setError(() => {\n throw error\n })\n }\n\n return {\n events: eventPages[offset] || [],\n loading,\n paginationProps,\n params,\n refresh,\n setParams,\n }\n}\n\nfunction usePagination(perPage: number, totalCount: number) {\n const [offset, setOffset] = useState(0)\n\n const currentPage = Math.floor(offset / perPage) + 1\n const totalPages = Math.ceil(totalCount / perPage)\n const paginationProps = { currentPage, onPageChange, totalPages }\n\n function onPageChange(pageNum: number) {\n setOffset((pageNum - 1) * perPage)\n }\n\n const resetOffset = useCallback(() => {\n setOffset(0)\n }, [])\n\n return { offset, paginationProps, resetOffset }\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n 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-default-secondary\")}\n weight={token(\"--t-font-weight-medium\")}\n >\n {automation.description}\n </Heading>\n <Text\n color={token(\"--t-text-color-default-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-default-primary\")}\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-default-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-default-placeholder\")\n : token(\"--t-text-color-interaction-primary\")\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-default-dark\"),\n text: token(\"--t-text-color-default-primary\"),\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-default-dark\"),\n text: token(\"--t-text-color-default-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}\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 render() {\n if (this.state.hasError) {\n return (\n <Alert type=\"error\" marginVertical={token(\"--t-spacing-1\")}>\n The application hit an unexpected error. If this persists after a few\n minutes, please let us know so we can get it fixed for you.{\" \"}\n <a\n style={{ whiteSpace: \"nowrap\" }}\n onClick={() => window.Helpdesk.load()}\n >\n Contact support\n </a>\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>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-default-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-default-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 { lowerFirst, truncate } from \"lodash\"\nimport { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { dateLocalized, forbiddenText } from \"./utils/utils\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\nconst peopleClient = new Client({ app: \"people\" })\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n disabled?: boolean\n disabledReason?: string\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationProps = {\n automation: IncomingAutomationInstance\n}\n\ntype EditableAutomationContextType = {\n automation: AutomationInstance\n currentPersonCanCreate?: boolean\n currentPersonId?: number\n theme: object\n trigger?: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation?: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationContextType = {\n automation: IncomingAutomationInstance\n}\n\nconst AutomationContext = createContext<\n EditableAutomationContextType | IncomingAutomationContextType\n>(null)\n\nfunction EditableAutomation({\n updateAutomation,\n onDelete,\n theme,\n openHistoryNow = false,\n disabled,\n disabledReason,\n ...props\n}: AutomationProps & {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper\n theme={theme}\n updateAutomation={updateAutomation}\n {...props}\n >\n <Header>\n <Icons />\n <Manage\n onDelete={onDelete}\n openHistoryNow={openHistoryNow}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n </Header>\n <Description />\n <EditableFooter />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingAutomation(props: IncomingAutomationProps) {\n return (\n <AutomationWrapper automation={props.automation}>\n <Header>\n <Icons />\n <LinkToAutomation />\n </Header>\n <IncomingDescription />\n <Footer />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingDescription() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n const triggerEventDescription = automation.triggerEventDescription\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-medium\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color-default-primary\")}\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-default-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-default-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-default-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-default-primary\"),\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 />\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-default-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-default-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-default-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-solid\")}\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-primary\"),\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 />\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-default-primary\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-default-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction parseDescription(description: string) {\n const match = /^(.+?)\\(([^()]*?)\\)$/.exec(description)\n\n if (match) {\n return { description: match[\"2\"], name: match[\"1\"].trim() }\n } else {\n return { name: description }\n }\n}\n\nfunction optionallyPrettifyArchivedPrefix(description: string) {\n if (description?.startsWith(\"[archived]\")) {\n return description.replace(\"[archived]\", \"[Archived]\")\n } else {\n return description\n }\n}\n\nasync function fetchCurrentPersonAvatar(subscription: AutomationInstance) {\n const {\n data: { avatar },\n } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n },\n url: \"me\",\n })\n\n return { avatar, subscription }\n}\n\nexport { EditableAutomation, IncomingAutomation }\n","import { Client } from \"@planningcenter/api-client\"\nimport { compact, uniq } from \"lodash\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\nconst peopleClient = new Client({ app: \"people\" })\n\nasync function fetchAutomations(triggerResource: EncryptedTriggerResource) {\n const { data } = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,events_status,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { truncate, upperFirst } from \"lodash\"\nimport { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\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({ app: appName })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color-default-base\")}`}\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-default-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-default-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === null\n )\n\n const primarySectionOptions = uniqBy(operationDefinitions, \"section\")\n .filter((od) => !!od.section)\n .map((od) => ({\n group: od.sectionGroup,\n label: od.section,\n value: sectionId(od.section),\n }))\n\n const secondaryOperations = selectedSection\n ? operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === selectedSection\n )\n : []\n\n function handleAnySelectChange({ selectedValue }) {\n switch (idType(selectedValue)) {\n case \"section\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => sectionId(od.section) === selectedValue\n )\n )\n break\n case \"operation\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => operationDefinitionId(od) === selectedValue\n )\n )\n break\n case null:\n onOperationDefinitionChange(null)\n break\n }\n }\n\n function renderOperations(operations: OperationDefinition[]) {\n const operationsAsOptions = operations.map((o) => ({\n group: o.group,\n label: o.description,\n value: o.id,\n }))\n\n return renderOptions(operationsAsOptions)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Select\n emptyValue=\"Select an action\"\n id=\"select-action\"\n onChange={handleAnySelectChange}\n size=\"lg\"\n data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n defaultValue={secondaryOperations[0].id}\n onChange={handleAnySelectChange}\n size=\"lg\"\n >\n {renderOperations(secondaryOperations)}\n </Select>\n )}\n </StackView>\n )\n}\n\nexport default Definition\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Avatar,\n Badge,\n Box,\n Checkbox as TapestryCheckbox,\n Combobox as TapestryCombobox,\n DateField as TapestryDateField,\n HelperDrawer,\n Highlight,\n Icon,\n Input,\n Menu,\n NumberField as TapestryNumberField,\n Radio,\n Select as TapestrySelect,\n Spinner,\n StackView,\n Text,\n TextArea as TapestryTextArea,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, debounce, groupBy, isEqual, sortBy, uniqBy } from \"lodash\"\nimport moment from \"moment\"\nimport { useCallback, useContext, useEffect, useMemo, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n />\n )\n case \"SelectSearch\":\n return (\n <SelectSearch\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"Checkbox\":\n return <Checkbox field={field} value={value} onChange={onChange} />\n case \"TextArea\":\n return <TextArea field={field} onChange={onChange} value={value} />\n\n case \"DateField\":\n return <DateField field={field} onChange={onChange} value={value} />\n case \"Checkboxes\":\n return (\n <Checkboxes\n fieldId={field.id}\n options={actionAllowedOptions}\n onChange={onChange}\n />\n )\n case \"NumberField\":\n return <NumberField field={field} onChange={onChange} value={value} />\n case \"PersonSearch\":\n return (\n <PersonSearch\n canAccessPeople={canAccessPeople}\n field={field}\n onChange={onChange}\n listOptions={listOptions}\n isLoading={loadingLists[fieldListIdentifier(field)]}\n loadListForField={loadListForField}\n value={value}\n />\n )\n case \"TextField\":\n return <TextField field={field} onChange={onChange} value={value} />\n case \"RadioButtons\":\n return (\n <RadioButtons\n field={field}\n options={listOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"StaticText\":\n return <Text dangerouslySetInnerHTML={{ __html: field.content }} />\n default:\n console.warn(`Unknown field kind \"${field.kind}\"`)\n return null\n }\n }\n\n return (\n <StackView marginBottom={2} spacing={0.5}>\n <Input.InputLabel\n color={token(\"--t-text-color-default-headline\")}\n fontSize={token(\"--t-font-size-sm\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n controls={field.id}\n >\n {field.description}\n {field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>{loading ? <Loading /> : renderField()}</Box>\n {field.info && (\n <HelperDrawer\n id={`${field.id}_help`}\n marginTop={token(\"--t-spacing-half\")}\n >\n <Box dangerouslySetInnerHTML={{ __html: field.info }} />\n </HelperDrawer>\n )}\n </StackView>\n )\n}\n\nconst Select = ({\n fieldId,\n listOptions,\n onChange,\n value,\n description,\n}: {\n description?: string\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value: any\n}) => {\n const overridenEmptyValue = listOptions?.find(\n (option) => option.value === \"no-option\"\n )\n const groupedOptions = groupBy(listOptions, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n const renderOptions = () => {\n return groupTypes.map((gt) =>\n gt === \"null\" || gt === \"undefined\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <TapestrySelect.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </TapestrySelect.OptionGroup>\n )\n )\n }\n\n const renderOptionsWithoutConsideringGroup = (\n items: { description: string; disabled?: boolean; value: string | number }[]\n ) => {\n return items.map((item) => (\n <TapestrySelect.Option\n key={item.value}\n value={item.value.toString()}\n disabled={item.disabled}\n >\n {item.description}\n </TapestrySelect.Option>\n ))\n }\n\n const handleSelectedValueChange = ({ selectedValue }) => {\n onChange({ fieldId, value: selectedValue })\n }\n\n const generatePrompt = (word: string) => {\n let prompt = `Select `\n if (!word) {\n prompt += \"a value\"\n } else if ([\"a\", \"e\", \"i\", \"o\", \"u\"].includes(word.charAt(0))) {\n prompt += `an ${word}`\n } else {\n prompt += `a ${word}`\n }\n return prompt\n }\n\n const renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return (\n overridenEmptyValue?.description ||\n generatePrompt(description?.toLowerCase())\n )\n }\n\n return (\n <TapestrySelect\n id={fieldId}\n onChange={handleSelectedValueChange}\n disabled={renderOptions().length < 1}\n emptyValue={renderEmptyValue()}\n size=\"lg\"\n value={value || overridenEmptyValue?.value || null}\n placement=\"bottom-start\"\n >\n {renderOptions()}\n </TapestrySelect>\n )\n}\n\nconst SelectSearch = ({\n fieldId,\n listOptions,\n onChange,\n value,\n}: {\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value?: string\n}) => {\n const selectedOption: LoadedList = listOptions.find(\n (option) => option.value?.toString() === value\n )\n const selectedLabel = selectedOption?.description || \"\"\n const [prevSelectedLabel, setPrevSelectedLabel] = useState(\"\")\n const [query, setQuery] = useState(selectedLabel)\n const [showFilteredOptions, setShowFilteredOptions] = useState(false)\n const [showClearButton, setShowClearButton] = useState(false)\n\n if (selectedLabel !== prevSelectedLabel) {\n setPrevSelectedLabel(selectedLabel)\n setQuery(selectedLabel)\n setShowFilteredOptions(false)\n }\n\n let filteredOptions = sortBy(uniqBy(listOptions, \"value\"), \"group\")\n\n if (showFilteredOptions) {\n const formattedQuery = query.toLowerCase()\n filteredOptions = filteredOptions.filter((option) => {\n const optionText = `${option.description} ${option.group}`.toLowerCase()\n return optionText.includes(formattedQuery)\n })\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n css={{\n \"[role='combobox']\": {\n cursor: listOptions.length > 0 ? \"pointer\" : \"not-allowed\",\n },\n }}\n cursor=\"pointer\"\n disabled={listOptions.length === 0}\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowFilteredOptions(true)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n setShowFilteredOptions(false)\n }\n : undefined\n }\n onFocus={(e: React.ChangeEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowFilteredOptions(false)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder={\n listOptions.length > 0 ? \"Select an option\" : \"No options available\"\n }\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={<Icon name=\"general.search\" size=\"md\" />}\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {listOptions.length > 0 && (\n <>\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option: LoadedList, index: number) => {\n const isCurrent = option.value.toString() === value\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n disabled={option.disabled}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Icon\n marginLeft={-0.5}\n name={isCurrent ? \"general.check\" : \"\"}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={{\n description: option.description,\n value: option.value.toString(),\n }}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n {option.group && (\n <Badge\n title={<Highlight text={option.group} query={query} />}\n size=\"sm\"\n marginLeft=\"auto\"\n />\n )}\n </TapestryCombobox.Item>\n )\n })\n ) : (\n <Menu.Item>\n <Text>No results for &quot;{query}&quot;</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color-default-base\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n onChange(newSelections)\n }, [definitionFields, onChange])\n\n const renderableFields = getRenderedFields(\n definitionFields,\n selectedFieldOptions\n )\n\n const handleSelectedFieldOptionsChange = ({ fieldId, value }) => {\n const newSelections = { ...selectedFieldOptions }\n const dependents = definitionFields.filter((field) => field.dependsOn)\n dependents.map((dependent) => {\n if (dependent.dependsOn.includes(fieldId)) {\n const deeper = dependents.find((d) =>\n d.dependsOn.includes(dependent.id)\n )\n if (deeper) {\n delete newSelections[deeper.id]\n }\n delete newSelections[dependent.id]\n\n if (\n dependent.defaultValue !== undefined &&\n newSelections[dependent.id] === undefined\n ) {\n newSelections[dependent.id] = dependent.defaultValue\n }\n }\n })\n\n if (value === \"no-option\") {\n delete newSelections[fieldId]\n } else {\n newSelections[fieldId] = value\n }\n\n onChange({ ...newSelections })\n }\n\n if (definitionFields.length) {\n return (\n <div>\n {renderableFields.map((field) => {\n return (\n <Field\n canAccessPeople={canAccessPeople}\n field={field}\n key={field.id}\n onChange={handleSelectedFieldOptionsChange}\n value={selectedFieldOptions[field.id]}\n selectedFieldOptions={selectedFieldOptions}\n loadListForField={loadListForField}\n loadedLists={loadedLists}\n loadingLists={loadingLists}\n />\n )\n })}\n </div>\n )\n } else {\n return null\n }\n}\n\nexport default Fields\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Icon,\n Input,\n Link,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { cloneDeep, set } from \"lodash\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n app: \"people\",\n env: (window as any).railsEnv,\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n app: \"webhooks\",\n env: (window as any).railsEnv,\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] = useState({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{ [k: string]: LoadedList[] }>(\n {}\n )\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const triggerConditions = cloneDeep(\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions\n )\n for (const key in dynamicTriggerConditions) {\n set(triggerConditions, key, dynamicTriggerConditions[key])\n }\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n alert(\"something even worse happened!\")\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color-default-primary\"),\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-default-primary\")}\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-default-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-default-base\")}`}\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-primary\")}\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-default-base\")}`}\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-default-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-default-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-default-base\")}`}\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-default-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-default-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 { useEffect, useState } from \"react\"\nimport sortBy from \"lodash/sortBy\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n forbiddenText,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused\n ? undefined\n : `1px solid ${token(\"--t-border-color-default-base\")}`\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-primary\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-default-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-default-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n disabled?: boolean\n disabledReason?: string\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color-default-primary\"),\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-default-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","_jsxs","jsxs","id","xmlns","viewBox","className","children","_jsx","jsx","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal__default","mixin","standardAlertOptions","Swal","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","fetchFieldDefinition","FieldDefinition","FieldOption","include","fieldDefinition","values","dataType","Object","entries","action","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","toString","customFieldOptionDescription","deobfuscatedDescription","_deobfuscatedDescript","string","charAt","toUpperCase","slice","Client","app","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","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","fetchPeople","people","_catch","Person","fetchEvents","automationId","params","webhooksClient","_e","Delivery","Event","order","STATUS","delivered","failed","ignored","pending","skipped","mergePeopleAndEvents","mergedData","reduce","result","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","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","open","setOpen","inline","was","fontFamily","ErrorBoundary","React","Component","constructor","props","super","this","state","hasError","static","render","Alert","type","marginVertical","style","window","Helpdesk","load","History$1","CloseModalIcon","as","icon","HistoryModal","onRequestClose","createPortal","ThemeProvider","Modal","boxShadow","paddingBottom","document","body","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","toLowerCase","fetchCreatorProfiles","compact","uniq","profiles","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","AutomationSubscription","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","Combobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","Fragment","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","env","railsEnv","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","getListOptions","search_name_or_email","OperationDefinitionList","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg"],"mappings":"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"}
1
+ {"version":3,"file":"core-automations.umd.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/automation.tsx","../../src/utils/fetch-automations.ts","../../src/incoming_automations.tsx","../../src/definition.tsx","../../src/field.tsx","../../src/fields.tsx","../../src/new_automation.tsx","../../src/new_automation_modal.tsx","../../src/utils/theme.ts","../../src/automations.tsx"],"sourcesContent":["const SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { 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 return subscription.operationParams.value\n ? fieldDefinition.fieldOptions.find(\n (fieldOption) =>\n fieldOption.id ===\n parseInt(subscription.operationParams.value.toString(), 10)\n )?.value || \"[Hidden value]\"\n : \"Unanswered\"\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({ app: \"people\", version: \"2025-03-20\" })\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 list = loadedLists[fieldListIdentifier(field)]\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)[0]\n\n return isBoolean(renderIf)\n ? renderIf\n : renderIf[conditionKey] === 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((e) => `${capitalize(value[e.value])} ${e.description}`)\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 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 description.replace(sensitiveString, \"[Hidden Workflow]\")\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) {\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) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({ dateFormat, twentyFourHourTime }) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date, dateFormat) {\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) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(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 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 Helpdesk: any\n }\n}\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\nconst peopleClient = new Client({ app: \"people\", version: \"2022-07-14\" })\n\n// values should match the webhooks Event `status` enum entries\nconst STATUS = {\n delivered: {\n label: \"Success\",\n value: [\"delivered\"],\n },\n failed: {\n label: \"Failed\",\n value: [\"failed\", \"duplicated\"],\n },\n ignored: {\n label: \"Ignored\",\n value: [\"ignored_duplicated\", \"ignored_failed\", \"ignored_skipped\"],\n },\n pending: {\n label: \"Pending\",\n value: [\"pending\"],\n },\n skipped: {\n label: \"Paused\",\n value: [\"skipped\"],\n },\n}\n\nasync function fetchEvents(\n triggerResource: EncryptedTriggerResource,\n automationId: number,\n params: {\n offset: number\n per_page: number\n where?: { status: string } | null\n }\n) {\n const response = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n Delivery: \"status,response_body,created_at\",\n Event: \"id,created_at,last_delivery,payload,status,uuid,person\",\n },\n include: \"last_delivery\",\n order: \"-created_at\",\n ...params,\n },\n url: `automation_subscriptions/${automationId}/events`,\n })\n\n return response\n}\n\nasync function fetchPeople(personIds) {\n const { data } = await peopleClient.get({\n data: {\n fields: {\n Person: \"id,name\",\n },\n where: { id: personIds.join(\",\") },\n },\n url: `people`,\n })\n\n return data\n}\n\nasync function fetchPeopleWhoTriggeredEvents(events) {\n const personIds = events.data.map((e) => eventPersonId(e))\n try {\n const people = await fetchPeople(personIds)\n return { events, people }\n } catch (error) {\n return { events, people: [] }\n }\n}\n\nfunction mergePeopleAndEvents({ events, people }) {\n const mergedData = events.data.reduce((result, e) => {\n const personId = eventPersonId(e)\n const foundPerson = people.find(\n (p) => personId.toString() === p.id.toString()\n )\n if (foundPerson) {\n result.push({\n ...e,\n person: { id: foundPerson.id, name: foundPerson.name },\n })\n } else {\n result.push({\n ...e,\n person: { id: personId, name: \"[Hidden]\" },\n })\n }\n return result\n }, [])\n\n return { ...events, data: mergedData }\n}\n\nfunction eventPersonId(event) {\n return event.personId\n}\n\nfunction useEvents(\n automationId: number,\n triggerResource: EncryptedTriggerResource,\n filterWhere?: string\n) {\n const perPage = 50\n const [_, setError] = useState()\n const [loading, setLoading] = useState(false)\n const [eventPages, setEventPages] = useState<{ [k: number]: EventPage[] }>({})\n const [params, setParams] = useState<{ where?: { status: string } | null }>(\n filterWhere ? { where: { status: filterWhere } } : {}\n )\n const [meta, setMeta] = useState<{ totalCount: number | any }>()\n const { offset, paginationProps, resetOffset } = usePagination(\n perPage,\n meta?.totalCount\n )\n useEffect(() => {\n if (loading || eventPages[offset]) return\n\n setLoading(true)\n\n fetchEvents(triggerResource, automationId, {\n offset,\n per_page: perPage,\n ...params,\n })\n .then(fetchPeopleWhoTriggeredEvents)\n .then(mergePeopleAndEvents)\n .then((events) => {\n setEventPages((pages) => ({ ...pages, [offset]: events.data }))\n setMeta(events.meta)\n setLoading(false)\n })\n .catch(bubbleErrorToBoundary)\n }, [automationId, triggerResource, loading, params, offset, eventPages])\n\n const refresh = useCallback(() => {\n setEventPages({})\n setMeta(undefined)\n resetOffset()\n }, [resetOffset])\n\n useEffect(() => {\n refresh()\n }, [refresh, params])\n\n function bubbleErrorToBoundary(error) {\n setError(() => {\n throw error\n })\n }\n\n return {\n events: eventPages[offset] || [],\n loading,\n paginationProps,\n params,\n refresh,\n setParams,\n }\n}\n\nfunction usePagination(perPage: number, totalCount: number) {\n const [offset, setOffset] = useState(0)\n\n const currentPage = Math.floor(offset / perPage) + 1\n const totalPages = Math.ceil(totalCount / perPage)\n const paginationProps = { currentPage, onPageChange, totalPages }\n\n function onPageChange(pageNum: number) {\n setOffset((pageNum - 1) * perPage)\n }\n\n const resetOffset = useCallback(() => {\n setOffset(0)\n }, [])\n\n return { offset, paginationProps, resetOffset }\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n 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-default-secondary\")}\n weight={token(\"--t-font-weight-medium\")}\n >\n {automation.description}\n </Heading>\n <Text\n color={token(\"--t-text-color-default-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-default-primary\")}\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-default-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-default-placeholder\")\n : token(\"--t-text-color-interaction-primary\")\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-default-dark\"),\n text: token(\"--t-text-color-default-primary\"),\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-default-dark\"),\n text: token(\"--t-text-color-default-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}\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 render() {\n if (this.state.hasError) {\n return (\n <Alert type=\"error\" marginVertical={token(\"--t-spacing-1\")}>\n The application hit an unexpected error. If this persists after a few\n minutes, please let us know so we can get it fixed for you.{\" \"}\n <a\n style={{ whiteSpace: \"nowrap\" }}\n onClick={() => window.Helpdesk.load()}\n >\n Contact support\n </a>\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>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-default-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-default-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 { 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 StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, lowerFirst, truncate } from \"lodash\"\nimport { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { dateLocalized, forbiddenText } from \"./utils/utils\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\nconst peopleClient = new Client({ app: \"people\" })\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n disabled?: boolean\n disabledReason?: string\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 onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n disabled: boolean\n disabledReason: string\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-default-primary\")}\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-default-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-default-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-default-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 updateAutomation?: (automation: AutomationInstance) => void\n children: React.ReactNode\n theme?: object\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 onDelete: (id: number) => void\n openHistoryNow: boolean\n disabled: boolean\n disabledReason: string\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-default-primary\"),\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 />\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 {/* TODO: Add gradient for bg */}\n <Icon\n name={`logomark.${camelCase(triggerProductName)}`}\n size={2}\n color={triggerProductName.toLowerCase()}\n />\n <Icon name=\"general.rightArrow\" size={1.5} />\n <Icon\n name={`logomark.${camelCase(automation.operationAppName)}`}\n size={2}\n color={automation.operationAppName.toLowerCase()}\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-default-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-default-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-default-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-solid\")}\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-primary\"),\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 />\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-default-primary\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-default-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction parseDescription(description: string) {\n const match = /^(.+?)\\(([^()]*?)\\)$/.exec(description)\n\n if (match) {\n return { description: match[\"2\"], name: match[\"1\"].trim() }\n } else {\n return { name: description }\n }\n}\n\nfunction optionallyPrettifyArchivedPrefix(description: string) {\n if (description?.startsWith(\"[archived]\")) {\n return description.replace(\"[archived]\", \"[Archived]\")\n } else {\n return description\n }\n}\n\nasync function fetchCurrentPersonAvatar(subscription: AutomationInstance) {\n const {\n data: { avatar },\n } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n },\n url: \"me\",\n })\n\n return { avatar, subscription }\n}\n\nexport { EditableAutomation, IncomingAutomation }\n","import { Client } from \"@planningcenter/api-client\"\nimport { compact, uniq } from \"lodash\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\nconst peopleClient = new Client({ app: \"people\" })\n\nasync function fetchAutomations(triggerResource: EncryptedTriggerResource) {\n const { data } = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,events_status,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { truncate, upperFirst } from \"lodash\"\nimport { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\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({ app: appName })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color-default-base\")}`}\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-default-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-default-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === null\n )\n\n const primarySectionOptions = uniqBy(operationDefinitions, \"section\")\n .filter((od) => !!od.section)\n .map((od) => ({\n group: od.sectionGroup,\n label: od.section,\n value: sectionId(od.section),\n }))\n\n const secondaryOperations = selectedSection\n ? operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === selectedSection\n )\n : []\n\n function handleAnySelectChange({ selectedValue }) {\n switch (idType(selectedValue)) {\n case \"section\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => sectionId(od.section) === selectedValue\n )\n )\n break\n case \"operation\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => operationDefinitionId(od) === selectedValue\n )\n )\n break\n case null:\n onOperationDefinitionChange(null)\n break\n }\n }\n\n function renderOperations(operations: OperationDefinition[]) {\n const operationsAsOptions = operations.map((o) => ({\n group: o.group,\n label: o.description,\n value: o.id,\n }))\n\n return renderOptions(operationsAsOptions)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Select\n emptyValue=\"Select an action\"\n id=\"select-action\"\n onChange={handleAnySelectChange}\n size=\"lg\"\n data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n defaultValue={secondaryOperations[0].id}\n onChange={handleAnySelectChange}\n size=\"lg\"\n >\n {renderOperations(secondaryOperations)}\n </Select>\n )}\n </StackView>\n )\n}\n\nexport default Definition\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Avatar,\n Badge,\n Box,\n Checkbox as TapestryCheckbox,\n Combobox as TapestryCombobox,\n DateField as TapestryDateField,\n HelperDrawer,\n Highlight,\n Icon,\n Input,\n Menu,\n NumberField as TapestryNumberField,\n Radio,\n Select as TapestrySelect,\n Spinner,\n StackView,\n Text,\n TextArea as TapestryTextArea,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, debounce, groupBy, isEqual, sortBy, uniqBy } from \"lodash\"\nimport moment from \"moment\"\nimport { useCallback, useContext, useEffect, useMemo, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n />\n )\n case \"SelectSearch\":\n return (\n <SelectSearch\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"Checkbox\":\n return <Checkbox field={field} value={value} onChange={onChange} />\n case \"TextArea\":\n return <TextArea field={field} onChange={onChange} value={value} />\n\n case \"DateField\":\n return <DateField field={field} onChange={onChange} value={value} />\n case \"Checkboxes\":\n return (\n <Checkboxes\n fieldId={field.id}\n options={actionAllowedOptions}\n onChange={onChange}\n />\n )\n case \"NumberField\":\n return <NumberField field={field} onChange={onChange} value={value} />\n case \"PersonSearch\":\n return (\n <PersonSearch\n canAccessPeople={canAccessPeople}\n field={field}\n onChange={onChange}\n listOptions={listOptions}\n isLoading={loadingLists[fieldListIdentifier(field)]}\n loadListForField={loadListForField}\n value={value}\n />\n )\n case \"TextField\":\n return <TextField field={field} onChange={onChange} value={value} />\n case \"RadioButtons\":\n return (\n <RadioButtons\n field={field}\n options={listOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"StaticText\":\n return <Text dangerouslySetInnerHTML={{ __html: field.content }} />\n default:\n console.warn(`Unknown field kind \"${field.kind}\"`)\n return null\n }\n }\n\n return (\n <StackView marginBottom={2} spacing={0.5}>\n <Input.InputLabel\n color={token(\"--t-text-color-default-headline\")}\n fontSize={token(\"--t-font-size-sm\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n controls={field.id}\n >\n {field.description}\n {field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>{loading ? <Loading /> : renderField()}</Box>\n {field.info && (\n <HelperDrawer\n id={`${field.id}_help`}\n marginTop={token(\"--t-spacing-half\")}\n >\n <Box dangerouslySetInnerHTML={{ __html: field.info }} />\n </HelperDrawer>\n )}\n </StackView>\n )\n}\n\nconst Select = ({\n fieldId,\n listOptions,\n onChange,\n value,\n description,\n}: {\n description?: string\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value: any\n}) => {\n const overridenEmptyValue = listOptions?.find(\n (option) => option.value === \"no-option\"\n )\n const groupedOptions = groupBy(listOptions, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n const renderOptions = () => {\n return groupTypes.map((gt) =>\n gt === \"null\" || gt === \"undefined\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <TapestrySelect.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </TapestrySelect.OptionGroup>\n )\n )\n }\n\n const renderOptionsWithoutConsideringGroup = (\n items: { description: string; disabled?: boolean; value: string | number }[]\n ) => {\n return items.map((item) => (\n <TapestrySelect.Option\n key={item.value}\n value={item.value.toString()}\n disabled={item.disabled}\n >\n {item.description}\n </TapestrySelect.Option>\n ))\n }\n\n const handleSelectedValueChange = ({ selectedValue }) => {\n onChange({ fieldId, value: selectedValue })\n }\n\n const generatePrompt = (word: string) => {\n let prompt = `Select `\n if (!word) {\n prompt += \"a value\"\n } else if ([\"a\", \"e\", \"i\", \"o\", \"u\"].includes(word.charAt(0))) {\n prompt += `an ${word}`\n } else {\n prompt += `a ${word}`\n }\n return prompt\n }\n\n const renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return (\n overridenEmptyValue?.description ||\n generatePrompt(description?.toLowerCase())\n )\n }\n\n return (\n <TapestrySelect\n id={fieldId}\n onChange={handleSelectedValueChange}\n disabled={renderOptions().length < 1}\n emptyValue={renderEmptyValue()}\n size=\"lg\"\n value={value || overridenEmptyValue?.value || null}\n placement=\"bottom-start\"\n >\n {renderOptions()}\n </TapestrySelect>\n )\n}\n\nconst SelectSearch = ({\n fieldId,\n listOptions,\n onChange,\n value,\n}: {\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value?: string\n}) => {\n const selectedOption: LoadedList = listOptions.find(\n (option) => option.value?.toString() === value\n )\n const selectedLabel = selectedOption?.description || \"\"\n const [prevSelectedLabel, setPrevSelectedLabel] = useState(\"\")\n const [query, setQuery] = useState(selectedLabel)\n const [showFilteredOptions, setShowFilteredOptions] = useState(false)\n const [showClearButton, setShowClearButton] = useState(false)\n\n if (selectedLabel !== prevSelectedLabel) {\n setPrevSelectedLabel(selectedLabel)\n setQuery(selectedLabel)\n setShowFilteredOptions(false)\n }\n\n let filteredOptions = sortBy(uniqBy(listOptions, \"value\"), \"group\")\n\n if (showFilteredOptions) {\n const formattedQuery = query.toLowerCase()\n filteredOptions = filteredOptions.filter((option) => {\n const optionText = `${option.description} ${option.group}`.toLowerCase()\n return optionText.includes(formattedQuery)\n })\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n css={{\n \"[role='combobox']\": {\n cursor: listOptions.length > 0 ? \"pointer\" : \"not-allowed\",\n },\n }}\n cursor=\"pointer\"\n disabled={listOptions.length === 0}\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowFilteredOptions(true)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n setShowFilteredOptions(false)\n }\n : undefined\n }\n onFocus={(e: React.ChangeEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowFilteredOptions(false)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder={\n listOptions.length > 0 ? \"Select an option\" : \"No options available\"\n }\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={<Icon name=\"general.search\" size=\"md\" />}\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {listOptions.length > 0 && (\n <>\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option: LoadedList, index: number) => {\n const isCurrent = option.value.toString() === value\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n disabled={option.disabled}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Icon\n marginLeft={-0.5}\n name={isCurrent ? \"general.check\" : \"\"}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={{\n description: option.description,\n value: option.value.toString(),\n }}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n {option.group && (\n <Badge\n title={<Highlight text={option.group} query={query} />}\n size=\"sm\"\n marginLeft=\"auto\"\n />\n )}\n </TapestryCombobox.Item>\n )\n })\n ) : (\n <Menu.Item>\n <Text>No results for &quot;{query}&quot;</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color-default-base\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n onChange(newSelections)\n }, [definitionFields, onChange])\n\n const renderableFields = getRenderedFields(\n definitionFields,\n selectedFieldOptions\n )\n\n const handleSelectedFieldOptionsChange = ({ fieldId, value }) => {\n const newSelections = { ...selectedFieldOptions }\n const dependents = definitionFields.filter((field) => field.dependsOn)\n dependents.map((dependent) => {\n if (dependent.dependsOn.includes(fieldId)) {\n const deeper = dependents.find((d) =>\n d.dependsOn.includes(dependent.id)\n )\n if (deeper) {\n delete newSelections[deeper.id]\n }\n delete newSelections[dependent.id]\n\n if (\n dependent.defaultValue !== undefined &&\n newSelections[dependent.id] === undefined\n ) {\n newSelections[dependent.id] = dependent.defaultValue\n }\n }\n })\n\n if (value === \"no-option\") {\n delete newSelections[fieldId]\n } else {\n newSelections[fieldId] = value\n }\n\n onChange({ ...newSelections })\n }\n\n if (definitionFields.length) {\n return (\n <div>\n {renderableFields.map((field) => {\n return (\n <Field\n canAccessPeople={canAccessPeople}\n field={field}\n key={field.id}\n onChange={handleSelectedFieldOptionsChange}\n value={selectedFieldOptions[field.id]}\n selectedFieldOptions={selectedFieldOptions}\n loadListForField={loadListForField}\n loadedLists={loadedLists}\n loadingLists={loadingLists}\n />\n )\n })}\n </div>\n )\n } else {\n return null\n }\n}\n\nexport default Fields\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Icon,\n Input,\n Link,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { cloneDeep, set } from \"lodash\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n app: \"people\",\n env: (window as any).railsEnv,\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n app: \"webhooks\",\n env: (window as any).railsEnv,\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] = useState({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{ [k: string]: LoadedList[] }>(\n {}\n )\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const triggerConditions = cloneDeep(\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions\n )\n for (const key in dynamicTriggerConditions) {\n set(triggerConditions, key, dynamicTriggerConditions[key])\n }\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n alert(\"something even worse happened!\")\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color-default-primary\"),\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-default-primary\")}\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-default-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-default-base\")}`}\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-primary\")}\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-default-base\")}`}\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-default-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-default-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-default-base\")}`}\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-default-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-default-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 { useEffect, useState } from \"react\"\nimport sortBy from \"lodash/sortBy\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n forbiddenText,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({ app: \"webhooks\", version: \"2022-10-20\" })\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused\n ? undefined\n : `1px solid ${token(\"--t-border-color-default-base\")}`\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-primary\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-default-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-default-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n disabled?: boolean\n disabledReason?: string\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color-default-primary\"),\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-default-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","_jsxs","jsxs","id","xmlns","viewBox","className","children","_jsx","jsx","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal__default","mixin","standardAlertOptions","Swal","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","fetchFieldDefinition","FieldDefinition","FieldOption","include","fieldDefinition","values","dataType","Object","entries","action","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","toString","customFieldOptionDescription","deobfuscatedDescription","_deobfuscatedDescript","string","charAt","toUpperCase","slice","Client","app","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","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","fetchPeople","people","_catch","Person","fetchEvents","automationId","params","webhooksClient","_e","Delivery","Event","order","STATUS","delivered","failed","ignored","pending","skipped","mergePeopleAndEvents","mergedData","reduce","result","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","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","open","setOpen","inline","was","fontFamily","ErrorBoundary","React","Component","constructor","props","super","this","state","hasError","static","render","Alert","type","marginVertical","style","window","Helpdesk","load","History$1","CloseModalIcon","as","icon","HistoryModal","onRequestClose","createPortal","ThemeProvider","Modal","boxShadow","paddingBottom","document","body","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","camelCase","toLowerCase","operationAppName","Fragment","Divider","marginHorizontal","Avatar","basis","source","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","triggerParams","useTriggerPersonOverride","exec","trim","startsWith","fetchPersonApps","App","PersonApp","personApp","allowPcoLogin","fetchCreatorProfiles","compact","uniq","profiles","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","AutomationSubscription","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","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","Combobox","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","env","railsEnv","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","getListOptions","search_name_or_email","OperationDefinitionList","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg"],"mappings":"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"}