@planningcenter/core-automations 1.9.0 → 1.9.1-qa-344.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"core-automations.modern.mjs","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/theme.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/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>people-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 />\n </g>\n <g opacity=\"0.2\">\n <path\n d=\"M63.086,84.317A43.515,43.515,0,0,1,42.87,79C34.056,74.379,24.712,67.422,14.3,57.728,6.616,50.227.284,43.348.489,35c.13-5.851,3.789-12.312,10.3-18.189l.951,1.054c-6.222,5.613-9.715,11.71-9.837,17.169C1.717,42.811,7.85,49.448,15.278,56.7c10.307,9.6,19.551,16.481,28.248,21.039,9.043,4.684,17.715,6.156,26.513,4.5l.262,1.4A38.914,38.914,0,0,1,63.086,84.317Z\"\n fill=\"#bac7d3\"\n />\n <path\n d=\"M81.105,80.147l-.587-1.292a56.6,56.6,0,0,0,23.515-19.828l1.183.786A58.03,58.03,0,0,1,81.105,80.147Z\"\n fill=\"#bac7d3\"\n />\n <path\n d=\"M110.025,49.27l-1.374-.356a28.351,28.351,0,0,0-4.014-22.991C97.189,14.135,82.488,5.177,66.267,2.538A66.6,66.6,0,0,0,25.738,8.55l-.622-1.275a68,68,0,0,1,41.39-6.136c16.6,2.7,31.672,11.905,39.327,24.019A29.732,29.732,0,0,1,110.025,49.27Z\"\n fill=\"#bac7d3\"\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 * 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\nexport const colors = {\n // Other necessary brand colors\n givingBrand31: \"hsl(36, 100%, 31%)\",\n\n // Grayscale\n neutral12: \"hsl(0, 0%, 12%)\",\n\n neutral24: \"hsl(0, 0%, 24%)\",\n\n neutral45: \"hsl(0, 0%, 45%)\",\n\n neutral62: \"hsl(0, 0%, 62%)\",\n\n neutral68: \"hsl(0, 0%, 68%)\",\n\n neutral88: \"hsl(0, 0%, 88%)\",\n\n neutral98: \"hsl(0, 0%, 98%)\",\n\n // Global `status` colors\n statusCreate23: \"hsl(86, 91%, 23%)\",\n\n statusCreate27: \"hsl(86, 91%, 27%)\",\n\n statusCreate35: \"hsl(86, 91%, 35%)\",\n\n statusDelete43: \"hsl(9, 61%, 43%)\",\n\n statusDelete47: \"hsl(8, 60%, 47%)\",\n\n statusWarning49: \"hsl(42, 84%, 49%)\",\n\n statusWarning63: \"hsl(42, 84%, 63%)\",\n\n statusWarning94: \"hsl(42, 87%, 94%)\", // warning text\n}\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 workflow = await fetchWorkflow(\n subscription.operationParams.workflowId\n )\n if (workflow.name) {\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n workflow.name\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: \"2022-07-14\" })\n\nasync function fetchWorkflow(workflowId: number) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: { Workflow: \"name\" },\n },\n url: `workflows/${workflowId}`,\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","import { Client } from \"@planningcenter/api-client\"\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 { colors } from \"./utils/theme\"\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={4}>\n <StackView spacing={0.5}>\n <Heading level={3} size=\"16px\" color={colors.neutral45} weight={500}>\n {automation.description}\n </Heading>\n <Text color={colors.neutral45} size={5} italic>\n {historyPreservationAlert}\n </Text>\n </StackView>\n <StackView 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={1}\n >\n <StackView width=\"max-content\">\n <Input.InputLabel\n fontWeight={500}\n color={colors.neutral24}\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={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={colors.neutral12}\n fontWeight={500}\n level={4}\n size={2}\n >\n No history found\n </Heading>\n <Text fontSize=\"16px\" 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={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: \"13px\",\n lineHeight: \"20px\",\n padding: \"10px 12px\",\n },\n bodyRow: ({ rowData }) => {\n return {\n backgroundColor: [...STATUS.ignored.value].includes(\n rowData.status\n )\n ? colors.neutral98\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: colors.statusCreate27, 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 ? colors.statusCreate27\n : STATUS.pending.value.includes(status)\n ? colors.neutral68\n : \"linkForeground\"\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 ? { border: colors.neutral62, text: colors.neutral24 }\n : STATUS.delivered.value.includes(status)\n ? { border: colors.statusCreate35, text: colors.statusCreate23 }\n : STATUS.skipped.value.includes(status)\n ? { border: colors.statusWarning63, text: colors.givingBrand31 }\n : STATUS.ignored.value.includes(status)\n ? { border: colors.neutral68, text: colors.neutral45 }\n : { border: colors.statusDelete47, text: colors.statusDelete43 }\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=\"12px\"\n radius=\"pill\"\n renderLeft={\n <Icon name={badgeIcon} color={badgeColors.border} marginLeft={1} />\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=\"13px\"\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={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={colors.neutral98}>\n <Text fontFamily=\"monospace\" fontSize=\"11px\" lineHeight=\"1.2\">\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={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 {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport { createPortal } from \"react-dom\"\n\nimport { colors } from \"./utils/theme\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={2}\n icon={{ color: colors.neutral62, name: \"general.x\" }}\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={4}\n paddingBottom={3}\n radius={8}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={colors.neutral12}\n fontWeight={500}\n fontSize=\"25px\"\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 {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n StackView,\n Text,\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 { colors } from \"./utils/theme\"\nimport { dateLocalized } 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}\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 onDelete,\n theme,\n openHistoryNow = false,\n ...props\n}: AutomationProps & {\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper theme={theme} {...props}>\n <Header>\n <Icons />\n <Manage onDelete={onDelete} openHistoryNow={openHistoryNow} />\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 paddingVertical={2} flex={1} opacity={cardOpacity}>\n <Heading level={3} size=\"21px\" weight={600} marginBottom={0.5} truncate>\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text size={4} color={colors.neutral24} lineHeight=\"1.2\">\n {triggerEventDescription}, then {lowerFirst(name)}{\" \"}\n {conditionalSuffix(automation)}\n </Text>\n <Text size={5} color={colors.neutral45} lineHeight=\"1.2\">\n {truncate(description, { length: 160, separator: \" \" })}\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={colors.neutral45}\n hover={{\n backgroundColor: \"highlight\",\n color: colors.neutral45,\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation: persistedAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n}) {\n const [automation, updateAutomation] = useState(persistedAutomation)\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}: {\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) {\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(() =>\n alerts.alertError.fire({\n text: `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`,\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(() =>\n alerts.alertError.fire({\n text: \"There was a problem updating this automation. Please try again in a few moments.\",\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={{ color: colors.neutral24, name: \"churchCenter.threeDots\" }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\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 {/* TODO: Convert to component */}\n <Button\n as=\"button\"\n theme={false}\n position=\"relative\"\n backgroundColor={isActive ? colors.statusCreate35 : colors.neutral62}\n radius=\"pill\"\n width={3.5}\n height={2}\n onClick={handleToggleActive}\n tooltip={isActive ? \"Pause automation\" : \"Enable automation\"}\n >\n <Box\n position=\"absolute\"\n pointerEvents=\"none\"\n top={0.25}\n left={0.25}\n width={1.5}\n height={1.5}\n background=\"#fff\"\n radius=\"circle\"\n transition=\"0.1s\"\n transform={`translateX(${isActive ? \"100%\" : \"0%\"})`}\n />\n </Button>\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={1}\n opacity={cardOpacity}\n >\n <Text size={6} color={colors.neutral62} whiteSpace=\"nowrap\">\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={0.5}\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: colors.neutral45,\n fontSize: 6,\n fontWeight: 400,\n paddingHorizontal: 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(newStatus) {\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={1}\n opacity={cardOpacity}\n >\n <Text size={6} color={colors.neutral62} whiteSpace=\"nowrap\">\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.25}>\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={colors.statusWarning63}\n marginRight={0.5}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding=\"2px\"\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: colors.statusDelete43,\n marginRight: 0.5,\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={0.5}\n marginLeft=\"auto\"\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 <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 paddingVertical={2} flex={1} opacity={cardOpacity}>\n <Heading level={3} size=\"21px\" weight={600} marginBottom={0.5} truncate>\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text size={4} color={colors.neutral24} lineHeight=\"1.2\">\n {triggerEventDescription}\n </Text>\n <Text size={5} color={colors.neutral45} lineHeight=\"1.2\">\n {truncate(description, { length: 160, separator: \" \" })}\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\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 {\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 { colors } from \"./utils/theme\"\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 ${colors.neutral88}`}\n marginBottom={2}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={3}\n paddingVertical={2}\n >\n <Heading color={colors.neutral12} level={2} size=\"18px\">\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text color={colors.neutral45} marginVertical={3}>\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 spacing={3} marginVertical={3} minCellWidth={45}>\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { 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={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 {\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 { colors } from \"./utils/theme\"\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 />\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 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={colors.neutral12}\n fontSize=\"14px\"\n fontWeight={500}\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 id={`${field.id}_help`} marginTop={0.5}>\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}: {\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 renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return overridenEmptyValue?.description || \"Select a value\"\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={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={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 || \"Date automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: todaysValue })\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 <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\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={1}\n paddingVertical={0.5}\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={4}>Value cannot exceed {maximumValue}.</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={1}\n paddingHorizontal={1.75}\n paddingVertical={1}\n radius={4}\n border={`1px solid ${colors.neutral88}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={16} 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 {\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 { colors } from \"./utils/theme\"\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: 4 },\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: colors.neutral24,\n fontSize: 16,\n lineHeight: 1.65,\n marginBottom: 16,\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={colors.neutral12}\n controls=\"select-trigger-event\"\n fontSize=\"16px\"\n fontWeight={600}\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 color={colors.neutral12} fontSize=\"16px\" fontWeight={600}>\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={1}\n paddingHorizontal={1.75}\n paddingVertical={1}\n radius={4}\n border={`1px solid ${colors.neutral88}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={16} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={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={3}\n name=\"general.exclamationTriangle\"\n color=\"error\"\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${colors.neutral88}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={colors.neutral12}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={400}\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={colors.neutral12}\n controls=\"select-product\"\n fontSize=\"16px\"\n fontWeight={600}\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={1}\n paddingHorizontal={1.75}\n paddingVertical={1}\n radius={4}\n border={`1px solid ${colors.neutral88}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={16} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import {\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\nimport { colors } from \"./utils/theme\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={2}\n icon={{ color: colors.neutral62, 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={4}\n paddingBottom={3}\n radius={8}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={colors.neutral12}\n fontWeight={500}\n fontSize=\"25px\"\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 { Client } from \"@planningcenter/api-client\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Link,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { colors, icons } from \"./utils/theme\"\nimport { deobfuscateDescriptions, pluralize } 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 headerButtonProps = {\n size: \"md\",\n theme: \"primary\",\n }\n const isPaused = canCreate && !hasActiveAutomations\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={isPaused ? colors.statusWarning94 : undefined}\n borderBottom={isPaused ? undefined : `1px solid ${colors.neutral88}`}\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={2}\n marginTop={-3}\n paddingHorizontal={3}\n paddingVertical={2}\n 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={colors.statusWarning49}\n name=\"general.exclamationTriangle\"\n />\n <Heading color={colors.neutral12} level={2} size=\"18px\">\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading color={colors.neutral12} level={2} size=\"18px\">\n {loading\n ? \"Active automations\"\n : pluralize(automations.length, \"active automation\")}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n {automations.length > 0 && (\n <Button\n onClick={onPauseAutomations}\n {...headerButtonProps}\n variant=\"outline\"\n >\n Pause automations\n </Button>\n )}\n <Button\n {...headerButtonProps}\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 {...headerButtonProps}\n backgroundColor=\"success\"\n hover={{ backgroundColor: \"success-dark\" }}\n active={{ backgroundColor: \"success-darker\" }}\n onClick={onPauseAutomations}\n >\n Enable automations\n </Button>\n <Button\n {...headerButtonProps}\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}: {\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}) {\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) {\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(() =>\n alerts.alertError.fire({\n text: \"There was a problem deleting this automation. Please try again in a few moments.\",\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: colors.neutral24,\n level: 2,\n size: \"25px\",\n weight: 700,\n }\n\n const BlankStateTextProps = {\n color: colors.neutral45,\n lineHeight: 3,\n size: 3,\n }\n\n function automationTriggerEvent(automation) {\n return trigger.events.find((event) => event.name === automation.name)\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}\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 {automations.map((a) => (\n <EditableAutomation\n key={a.id}\n automation={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 />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={6}\n spacing={2}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n 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={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={1}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}{\" \"}\n <Link inline external to={blankStateLink}>\n Learn more\n </Link>\n .\n </Text>\n </StackView>\n <Button\n as=\"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={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","id","xmlns","viewBox","className","children","_jsx","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","icons","churchCenter","logomark","services","colors","givingBrand31","neutral12","neutral24","neutral45","neutral62","neutral68","neutral88","neutral98","statusCreate23","statusCreate27","statusCreate35","statusDelete43","statusDelete47","statusWarning49","statusWarning63","statusWarning94","deobfuscateDescriptions","subscriptions","Promise","all","map","async","subscription","includes","operationDefinitionClassName","isDeobfuscatable","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","url","catch","name","fetchWorkflow","operationParams","replace","fieldDefinitionId","definitionIdentifier","match","fieldDefinition","FieldDefinition","FieldOption","include","fetchFieldDefinition","values","dataType","_fieldDefinition$fiel2","_subscription$operati","Object","entries","action","_fieldDefinition$fiel","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","toString","customFieldOptionDescription","deobfuscatedDescription","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","_list$find2","workflow_id_WorkflowsList","sensitiveString","o","workflow_id","obfuscateSelectedFieldDescriptions","_list$find","label","e","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","where","fetchPeople","error","mergePeopleAndEvents","mergedData","reduce","result","personId","foundPerson","p","push","_extends","person","event","History","automation","filterWhere","onEventsStatusChange","_params$where","loading","paginationProps","refresh","params","setParams","automationId","_","setError","useState","setLoading","eventPages","setEventPages","status","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","_e","Delivery","Event","order","fetchEvents","per_page","then","pages","bubbleErrorToBoundary","undefined","useEvents","useContext","filteringEvents","automationCreatedRecently","diff","numDaysSince","createdAt","automationBeganOn","historyPreservationAlert","columns","cell","EventStatusBadge","css","padding","header","utcOffset","momentDateTimeFormat","Link","to","maxWidth","EventStatusMessage","flex","_Fragment","RetryEventButton","IgnoreEventButton","refreshHistory","textAlign","minWidth","StackView","spacing","Heading","level","size","color","weight","Text","italic","Box","minHeight","alignItems","axis","distribution","Input","InputLabel","fontWeight","controls","Select","emptyValue","onChange","selectedValue","title","Option","Button","iconLeft","onClick","theme","variant","maxHeight","overflow","DataTable","empty","alignment","marginTop","marginBottom","svg","fontSize","loadingTitle","bodyCell","lineHeight","bodyRow","rowData","backgroundColor","headerCell","headerRow","setStatus","retryTitleFromStatus","statusIcon","post","attributes","response","eventsStatus","alerts","fire","text","disabled","badgeColors","border","badgeIcon","badgeTitle","Badge","background","foreground","paddingLeft","paddingRight","radius","renderLeft","Icon","marginLeft","stroke","strokeAlign","strokeWeight","lastDelivery","message","delivery","ERRORS","default","duplicated_event","failed_without_deliveries","whiteSpace","ToggleableDetails","details","_response","responseBody","parse","_unused","errors","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","AutomationContext","EditableAutomation","_ref","onDelete","openHistoryNow","_objectWithoutPropertiesLoose","_excluded","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","paddingVertical","active","truncate","lowerFirst","conditionalSuffix","separator","external","triggerAdminUrl","canManage","tooltip","hover","_ref2","persistedAutomation","rest","_excluded2","updateAutomation","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","avatar","fetchCurrentPersonAvatar","prev","createdBy","avatarUrl","createdByName","confirmButtonText","position","patch","pointerEvents","top","left","transition","newStatus","triggerProductName","camelCase","toLowerCase","operationAppName","_automation$createdBy","_automation$createdBy2","createdBySuffix","cardOpacity","Divider","marginHorizontal","Avatar","basis","source","_automation$createdBy3","_automation$eventsSta","_automation$eventsSta2","_automation$eventsSta3","_automation$eventsSta4","_automation$eventsSta5","_automation$eventsSta6","_automation$createdBy4","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","_automation$triggerPa","triggerParams","useTriggerPersonOverride","exec","trim","fetchCreatorProfiles","compact","uniq","profiles","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","_QUERYABLE_BY_MULTIPL","fetchNothing","fetchAllAtOnce","fetchOneAtATime","ids","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","fetchPersonApps","operationApps","AutomationSubscription","fetchIncomingAutomations","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","options","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","group","sectionGroup","secondaryOperations","handleAnySelectChange","startsWith","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","console","warn","renderField","dangerouslySetInnerHTML","__html","overridenEmptyValue","option","groupTypes","TapestrySelect","items","item","handleSelectedValueChange","selectedOption","_option$value","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","_selectedOption$meta","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","specificDate","setSpecificDate","todaysValue","customValue","orgFormat","dateFieldValue","setDateFieldValue","toDate","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","env","railsEnv","errorAlertProps","borderRadius","getVisibleApps","Topbar","apps","a","getWebhooksApps","OperationApp","getOperationDefinitions","OperationDefinition","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","_selectedDefinition$f","_selectedTriggerEvent","_selectedDefinition$f2","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","headerButtonProps","isPaused","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","margin","mediaQueries","lg","styles"],"mappings":"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"}
1
+ {"version":3,"file":"core-automations.modern.mjs","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/theme.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/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>people-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 />\n </g>\n <g opacity=\"0.2\">\n <path\n d=\"M63.086,84.317A43.515,43.515,0,0,1,42.87,79C34.056,74.379,24.712,67.422,14.3,57.728,6.616,50.227.284,43.348.489,35c.13-5.851,3.789-12.312,10.3-18.189l.951,1.054c-6.222,5.613-9.715,11.71-9.837,17.169C1.717,42.811,7.85,49.448,15.278,56.7c10.307,9.6,19.551,16.481,28.248,21.039,9.043,4.684,17.715,6.156,26.513,4.5l.262,1.4A38.914,38.914,0,0,1,63.086,84.317Z\"\n fill=\"#bac7d3\"\n />\n <path\n d=\"M81.105,80.147l-.587-1.292a56.6,56.6,0,0,0,23.515-19.828l1.183.786A58.03,58.03,0,0,1,81.105,80.147Z\"\n fill=\"#bac7d3\"\n />\n <path\n d=\"M110.025,49.27l-1.374-.356a28.351,28.351,0,0,0-4.014-22.991C97.189,14.135,82.488,5.177,66.267,2.538A66.6,66.6,0,0,0,25.738,8.55l-.622-1.275a68,68,0,0,1,41.39-6.136c16.6,2.7,31.672,11.905,39.327,24.019A29.732,29.732,0,0,1,110.025,49.27Z\"\n fill=\"#bac7d3\"\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 * 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\nexport const colors = {\n // Other necessary brand colors\n givingBrand31: \"hsl(36, 100%, 31%)\",\n\n // Grayscale\n neutral12: \"hsl(0, 0%, 12%)\",\n\n neutral24: \"hsl(0, 0%, 24%)\",\n\n neutral45: \"hsl(0, 0%, 45%)\",\n\n neutral62: \"hsl(0, 0%, 62%)\",\n\n neutral68: \"hsl(0, 0%, 68%)\",\n\n neutral88: \"hsl(0, 0%, 88%)\",\n\n neutral98: \"hsl(0, 0%, 98%)\",\n\n // Global `status` colors\n statusCreate23: \"hsl(86, 91%, 23%)\",\n\n statusCreate27: \"hsl(86, 91%, 27%)\",\n\n statusCreate35: \"hsl(86, 91%, 35%)\",\n\n statusDelete43: \"hsl(9, 61%, 43%)\",\n\n statusDelete47: \"hsl(8, 60%, 47%)\",\n\n statusWarning49: \"hsl(42, 84%, 49%)\",\n\n statusWarning63: \"hsl(42, 84%, 63%)\",\n\n statusWarning94: \"hsl(42, 87%, 94%)\", // warning text\n}\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: \"2022-07-14\" })\n\nasync function fetchWorkflow(workflowId: number) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: { Workflow: \"name,archived_at\" },\n filter: \"not_archived,archived\",\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","import { Client } from \"@planningcenter/api-client\"\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 { colors } from \"./utils/theme\"\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={4}>\n <StackView spacing={0.5}>\n <Heading level={3} size=\"16px\" color={colors.neutral45} weight={500}>\n {automation.description}\n </Heading>\n <Text color={colors.neutral45} size={5} italic>\n {historyPreservationAlert}\n </Text>\n </StackView>\n <StackView 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={1}\n >\n <StackView width=\"max-content\">\n <Input.InputLabel\n fontWeight={500}\n color={colors.neutral24}\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={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={colors.neutral12}\n fontWeight={500}\n level={4}\n size={2}\n >\n No history found\n </Heading>\n <Text fontSize=\"16px\" 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={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: \"13px\",\n lineHeight: \"20px\",\n padding: \"10px 12px\",\n },\n bodyRow: ({ rowData }) => {\n return {\n backgroundColor: [...STATUS.ignored.value].includes(\n rowData.status\n )\n ? colors.neutral98\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: colors.statusCreate27, 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 ? colors.statusCreate27\n : STATUS.pending.value.includes(status)\n ? colors.neutral68\n : \"linkForeground\"\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 ? { border: colors.neutral62, text: colors.neutral24 }\n : STATUS.delivered.value.includes(status)\n ? { border: colors.statusCreate35, text: colors.statusCreate23 }\n : STATUS.skipped.value.includes(status)\n ? { border: colors.statusWarning63, text: colors.givingBrand31 }\n : STATUS.ignored.value.includes(status)\n ? { border: colors.neutral68, text: colors.neutral45 }\n : { border: colors.statusDelete47, text: colors.statusDelete43 }\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=\"12px\"\n radius=\"pill\"\n renderLeft={\n <Icon name={badgeIcon} color={badgeColors.border} marginLeft={1} />\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=\"13px\"\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={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={colors.neutral98}>\n <Text fontFamily=\"monospace\" fontSize=\"11px\" lineHeight=\"1.2\">\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={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 {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport { createPortal } from \"react-dom\"\n\nimport { colors } from \"./utils/theme\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={2}\n icon={{ color: colors.neutral62, name: \"general.x\" }}\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={4}\n paddingBottom={3}\n radius={8}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={colors.neutral12}\n fontWeight={500}\n fontSize=\"25px\"\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 {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n StackView,\n Text,\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 { colors } from \"./utils/theme\"\nimport { dateLocalized } 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}\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 onDelete,\n theme,\n openHistoryNow = false,\n ...props\n}: AutomationProps & {\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper theme={theme} {...props}>\n <Header>\n <Icons />\n <Manage onDelete={onDelete} openHistoryNow={openHistoryNow} />\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 paddingVertical={2} flex={1} opacity={cardOpacity}>\n <Heading level={3} size=\"21px\" weight={600} marginBottom={0.5} truncate>\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text size={4} color={colors.neutral24} lineHeight=\"1.2\">\n {triggerEventDescription}, then {lowerFirst(name)}{\" \"}\n {conditionalSuffix(automation)}\n </Text>\n <Text size={5} color={colors.neutral45} lineHeight=\"1.2\">\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={colors.neutral45}\n hover={{\n backgroundColor: \"highlight\",\n color: colors.neutral45,\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation: persistedAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n}) {\n const [automation, updateAutomation] = useState(persistedAutomation)\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}: {\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) {\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(() =>\n alerts.alertError.fire({\n text: `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`,\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(() =>\n alerts.alertError.fire({\n text: \"There was a problem updating this automation. Please try again in a few moments.\",\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={{ color: colors.neutral24, name: \"churchCenter.threeDots\" }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\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 {/* TODO: Convert to component */}\n <Button\n as=\"button\"\n theme={false}\n position=\"relative\"\n backgroundColor={isActive ? colors.statusCreate35 : colors.neutral62}\n radius=\"pill\"\n width={3.5}\n height={2}\n onClick={handleToggleActive}\n tooltip={isActive ? \"Pause automation\" : \"Enable automation\"}\n >\n <Box\n position=\"absolute\"\n pointerEvents=\"none\"\n top={0.25}\n left={0.25}\n width={1.5}\n height={1.5}\n background=\"#fff\"\n radius=\"circle\"\n transition=\"0.1s\"\n transform={`translateX(${isActive ? \"100%\" : \"0%\"})`}\n />\n </Button>\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={1}\n opacity={cardOpacity}\n >\n <Text size={6} color={colors.neutral62} whiteSpace=\"nowrap\">\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={0.5}\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: colors.neutral45,\n fontSize: 6,\n fontWeight: 400,\n paddingHorizontal: 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(newStatus) {\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={1}\n opacity={cardOpacity}\n >\n <Text size={6} color={colors.neutral62} whiteSpace=\"nowrap\">\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.25}>\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={colors.statusWarning63}\n marginRight={0.5}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding=\"2px\"\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: colors.statusDelete43,\n marginRight: 0.5,\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={0.5}\n marginLeft=\"auto\"\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 <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 paddingVertical={2} flex={1} opacity={cardOpacity}>\n <Heading level={3} size=\"21px\" weight={600} marginBottom={0.5} truncate>\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text size={4} color={colors.neutral24} lineHeight=\"1.2\">\n {triggerEventDescription}\n </Text>\n <Text size={5} color={colors.neutral45} lineHeight=\"1.2\">\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 {\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 { colors } from \"./utils/theme\"\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 ${colors.neutral88}`}\n marginBottom={2}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={3}\n paddingVertical={2}\n >\n <Heading color={colors.neutral12} level={2} size=\"18px\">\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text color={colors.neutral45} marginVertical={3}>\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 spacing={3} marginVertical={3} minCellWidth={45}>\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { 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={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 {\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 { colors } from \"./utils/theme\"\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 />\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 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={colors.neutral12}\n fontSize=\"14px\"\n fontWeight={500}\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 id={`${field.id}_help`} marginTop={0.5}>\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}: {\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 renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return overridenEmptyValue?.description || \"Select a value\"\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={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={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 || \"Date automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: todaysValue })\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 <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\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={1}\n paddingVertical={0.5}\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={4}>Value cannot exceed {maximumValue}.</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={1}\n paddingHorizontal={1.75}\n paddingVertical={1}\n radius={4}\n border={`1px solid ${colors.neutral88}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={16} 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 {\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 { colors } from \"./utils/theme\"\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: 4 },\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: colors.neutral24,\n fontSize: 16,\n lineHeight: 1.65,\n marginBottom: 16,\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={colors.neutral12}\n controls=\"select-trigger-event\"\n fontSize=\"16px\"\n fontWeight={600}\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 color={colors.neutral12} fontSize=\"16px\" fontWeight={600}>\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={1}\n paddingHorizontal={1.75}\n paddingVertical={1}\n radius={4}\n border={`1px solid ${colors.neutral88}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={16} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={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={3}\n name=\"general.exclamationTriangle\"\n color=\"error\"\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${colors.neutral88}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={colors.neutral12}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={400}\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={colors.neutral12}\n controls=\"select-product\"\n fontSize=\"16px\"\n fontWeight={600}\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={1}\n paddingHorizontal={1.75}\n paddingVertical={1}\n radius={4}\n border={`1px solid ${colors.neutral88}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={16} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import {\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\nimport { colors } from \"./utils/theme\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={2}\n icon={{ color: colors.neutral62, 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={4}\n paddingBottom={3}\n radius={8}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={colors.neutral12}\n fontWeight={500}\n fontSize=\"25px\"\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 { Client } from \"@planningcenter/api-client\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Link,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { colors, icons } from \"./utils/theme\"\nimport { deobfuscateDescriptions, pluralize } 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 headerButtonProps = {\n size: \"md\",\n theme: \"primary\",\n }\n const isPaused = canCreate && !hasActiveAutomations\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={isPaused ? colors.statusWarning94 : undefined}\n borderBottom={isPaused ? undefined : `1px solid ${colors.neutral88}`}\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={2}\n marginTop={-3}\n paddingHorizontal={3}\n paddingVertical={2}\n 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={colors.statusWarning49}\n name=\"general.exclamationTriangle\"\n />\n <Heading color={colors.neutral12} level={2} size=\"18px\">\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading color={colors.neutral12} level={2} size=\"18px\">\n {loading\n ? \"Active automations\"\n : pluralize(automations.length, \"active automation\")}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n {automations.length > 0 && (\n <Button\n onClick={onPauseAutomations}\n {...headerButtonProps}\n variant=\"outline\"\n >\n Pause automations\n </Button>\n )}\n <Button\n {...headerButtonProps}\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 {...headerButtonProps}\n backgroundColor=\"success\"\n hover={{ backgroundColor: \"success-dark\" }}\n active={{ backgroundColor: \"success-darker\" }}\n onClick={onPauseAutomations}\n >\n Enable automations\n </Button>\n <Button\n {...headerButtonProps}\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}: {\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}) {\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) {\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(() =>\n alerts.alertError.fire({\n text: \"There was a problem deleting this automation. Please try again in a few moments.\",\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: colors.neutral24,\n level: 2,\n size: \"25px\",\n weight: 700,\n }\n\n const BlankStateTextProps = {\n color: colors.neutral45,\n lineHeight: 3,\n size: 3,\n }\n\n function automationTriggerEvent(automation) {\n return trigger.events.find((event) => event.name === automation.name)\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}\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 {automations.map((a) => (\n <EditableAutomation\n key={a.id}\n automation={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 />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={6}\n spacing={2}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n 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={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={1}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}{\" \"}\n <Link inline external to={blankStateLink}>\n Learn more\n </Link>\n .\n </Text>\n </StackView>\n <Button\n as=\"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={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","id","xmlns","viewBox","className","children","_jsx","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","icons","churchCenter","logomark","services","colors","givingBrand31","neutral12","neutral24","neutral45","neutral62","neutral68","neutral88","neutral98","statusCreate23","statusCreate27","statusCreate35","statusDelete43","statusDelete47","statusWarning49","statusWarning63","statusWarning94","deobfuscateDescriptions","subscriptions","Promise","all","map","async","subscription","includes","operationDefinitionClassName","isDeobfuscatable","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","filter","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","replace","fieldDefinitionId","definitionIdentifier","match","fieldDefinition","FieldDefinition","FieldOption","include","fetchFieldDefinition","values","dataType","_fieldDefinition$fiel2","_subscription$operati","Object","entries","action","_fieldDefinition$fiel","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","toString","customFieldOptionDescription","deobfuscatedDescription","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","renderIf","conditionKey","keys","isBoolean","describeSelectedFields","selectedDefinition","_list$find2","workflow_id_WorkflowsList","sensitiveString","o","workflow_id","obfuscateSelectedFieldDescriptions","_list$find","label","e","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","error","mergePeopleAndEvents","mergedData","reduce","result","personId","foundPerson","p","push","_extends","person","event","History","automation","filterWhere","onEventsStatusChange","_params$where","loading","paginationProps","refresh","params","setParams","automationId","_","setError","useState","setLoading","eventPages","setEventPages","status","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","_e","Delivery","Event","order","fetchEvents","per_page","then","pages","bubbleErrorToBoundary","undefined","useEvents","useContext","filteringEvents","automationCreatedRecently","diff","numDaysSince","createdAt","automationBeganOn","historyPreservationAlert","columns","cell","EventStatusBadge","css","padding","header","utcOffset","momentDateTimeFormat","Link","to","maxWidth","EventStatusMessage","flex","_Fragment","RetryEventButton","IgnoreEventButton","refreshHistory","textAlign","minWidth","StackView","spacing","Heading","level","size","color","weight","Text","italic","Box","minHeight","alignItems","axis","distribution","Input","InputLabel","fontWeight","controls","Select","emptyValue","onChange","selectedValue","title","Option","Button","iconLeft","onClick","theme","variant","maxHeight","overflow","DataTable","empty","alignment","marginTop","marginBottom","svg","fontSize","loadingTitle","bodyCell","lineHeight","bodyRow","rowData","backgroundColor","headerCell","headerRow","setStatus","retryTitleFromStatus","statusIcon","post","attributes","response","eventsStatus","alerts","fire","text","disabled","badgeColors","border","badgeIcon","badgeTitle","Badge","background","foreground","paddingLeft","paddingRight","radius","renderLeft","Icon","marginLeft","stroke","strokeAlign","strokeWeight","lastDelivery","message","delivery","ERRORS","default","duplicated_event","failed_without_deliveries","whiteSpace","ToggleableDetails","details","_response","responseBody","parse","_unused","errors","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","AutomationContext","EditableAutomation","_ref","onDelete","openHistoryNow","_objectWithoutPropertiesLoose","_excluded","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","paddingVertical","active","truncate","lowerFirst","conditionalSuffix","optionallyPrettifyArchivedPrefix","separator","external","triggerAdminUrl","canManage","tooltip","hover","_ref2","persistedAutomation","rest","_excluded2","updateAutomation","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","avatar","fetchCurrentPersonAvatar","prev","createdBy","avatarUrl","createdByName","confirmButtonText","position","patch","pointerEvents","top","left","transition","newStatus","triggerProductName","camelCase","toLowerCase","operationAppName","_automation$createdBy","_automation$createdBy2","createdBySuffix","cardOpacity","Divider","marginHorizontal","Avatar","basis","source","_automation$createdBy3","_automation$eventsSta","_automation$eventsSta2","_automation$eventsSta3","_automation$eventsSta4","_automation$eventsSta5","_automation$eventsSta6","_automation$createdBy4","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","_automation$triggerPa","triggerParams","useTriggerPersonOverride","exec","trim","startsWith","fetchCreatorProfiles","compact","uniq","profiles","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","_QUERYABLE_BY_MULTIPL","fetchNothing","fetchAllAtOnce","fetchOneAtATime","ids","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","fetchPersonApps","operationApps","AutomationSubscription","fetchIncomingAutomations","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","options","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","group","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","defaultValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","fieldId","SelectSearch","Checkbox","TextArea","DateField","Checkboxes","NumberField","PersonSearch","isLoading","TextField","RadioButtons","console","warn","renderField","dangerouslySetInnerHTML","__html","overridenEmptyValue","option","groupTypes","TapestrySelect","items","item","handleSelectedValueChange","selectedOption","_option$value","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","_selectedOption$meta","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","specificDate","setSpecificDate","todaysValue","customValue","orgFormat","dateFieldValue","setDateFieldValue","toDate","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","env","railsEnv","errorAlertProps","borderRadius","getVisibleApps","Topbar","apps","a","getWebhooksApps","OperationApp","getOperationDefinitions","OperationDefinition","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","_selectedDefinition$f","_selectedTriggerEvent","_selectedDefinition$f2","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","headerButtonProps","isPaused","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","margin","mediaQueries","lg","styles"],"mappings":"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"}