@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.esm.js","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","subscription","_temp","includes","operationDefinitionClassName","isDeobfuscatable","resolve","deobfuscatedDescription","_temp3","description","_temp2","workflowId","peopleClient","get","data","fields","Workflow","url","catch","name","then","e","reject","fetchWorkflow","operationParams","workflow","replace","fieldDefinitionId","definitionIdentifier","match","FieldDefinition","FieldOption","include","fetchFieldDefinition","fieldDefinition","values","dataType","Object","entries","action","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","toString","customFieldOptionDescription","_deobfuscatedDescript","string","charAt","toUpperCase","slice","Client","app","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","getRenderedFields","definitionFields","selectedFieldOptions","filter","renderIf","conditionKey","keys","isBoolean","describeSelectedFields","selectedDefinition","workflow_id_WorkflowsList","sensitiveString","o","workflow_id","obfuscateSelectedFieldDescriptions","label","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","fetchPeople","people","_catch","Person","where","fetchEvents","automationId","params","webhooksClient","_e","Delivery","Event","order","STATUS","delivered","failed","ignored","pending","skipped","mergePeopleAndEvents","mergedData","reduce","result","personId","foundPerson","p","push","person","event","History","automation","filterWhere","onEventsStatusChange","loading","paginationProps","refresh","setParams","_","setError","useState","setLoading","eventPages","setEventPages","status","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","per_page","pages","bubbleErrorToBoundary","undefined","error","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","responseBody","parse","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","fetchCurrentPersonAvatar","avatar","AutomationContext","EditableAutomation","onDelete","openHistoryNow","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","paddingVertical","active","truncate","lowerFirst","conditionalSuffix","separator","external","triggerAdminUrl","canManage","tooltip","hover","persistedAutomation","rest","updateAutomation","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","prev","createdBy","avatarUrl","createdByName","confirmButtonText","position","patch","pointerEvents","top","left","transition","newStatus","triggerProductName","camelCase","toLowerCase","operationAppName","cardOpacity","Divider","marginHorizontal","Avatar","basis","source","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","triggerParams","useTriggerPersonOverride","exec","trim","fetchPersonApps","App","PersonApp","personApp","allowPcoLogin","fetchCreatorProfiles","compact","uniq","profiles","fetchAutomations","AutomationSubscription","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","fetchNothing","fetchAllAtOnce","fetchOneAtATime","ids","allSettled","results","triggerResources","settledPromises","acc","concat","fetchIncomingAutomations","encryptedParam","fetchResourceName","path","_props","client","model","upperFirst","IncomingAutomations","setAutomations","operationApps","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","options","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","group","sectionGroup","secondaryOperations","handleAnySelectChange","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","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","specificDate","setSpecificDate","todaysValue","customValue","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","getOperationDefinitions","OperationDefinition","getWebhooksApps","OperationApp","a","getVisibleApps","Topbar","apps","env","railsEnv","errorAlertProps","borderRadius","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","getOperationApps","visibleApps","webhooksApps","defaultSelection","definitions","current","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","headerButtonProps","isPaused","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","margin","mediaQueries","lg","styles"],"mappings":"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"}
1
+ {"version":3,"file":"core-automations.esm.js","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/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","subscription","_temp","isDeobfuscatable","includes","operationDefinitionClassName","resolve","_temp3","description","_temp2","fetchWorkflow","workflowId","peopleClient","get","data","fields","Workflow","filter","where","url","catch","name","then","e","reject","operationParams","workflow","workflowName","archivedAt","replace","fieldDefinitionId","definitionIdentifier","match","fetchFieldDefinition","FieldDefinition","FieldOption","include","fieldDefinition","values","dataType","Object","entries","action","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","toString","customFieldOptionDescription","deobfuscatedDescription","_deobfuscatedDescript","string","charAt","toUpperCase","slice","Client","app","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","getRenderedFields","definitionFields","selectedFieldOptions","renderIf","conditionKey","keys","isBoolean","describeSelectedFields","selectedDefinition","workflow_id_WorkflowsList","sensitiveString","o","workflow_id","obfuscateSelectedFieldDescriptions","label","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","fetchPeople","people","_catch","Person","fetchEvents","automationId","params","webhooksClient","_e","Delivery","Event","order","STATUS","delivered","failed","ignored","pending","skipped","mergePeopleAndEvents","mergedData","reduce","result","personId","foundPerson","p","push","person","event","History","automation","filterWhere","onEventsStatusChange","loading","paginationProps","refresh","setParams","_","setError","useState","setLoading","eventPages","setEventPages","status","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","per_page","pages","bubbleErrorToBoundary","undefined","error","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","responseBody","parse","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","fetchCurrentPersonAvatar","avatar","AutomationContext","EditableAutomation","onDelete","openHistoryNow","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","paddingVertical","active","truncate","lowerFirst","conditionalSuffix","optionallyPrettifyArchivedPrefix","separator","external","triggerAdminUrl","canManage","tooltip","hover","persistedAutomation","rest","updateAutomation","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","prev","createdBy","avatarUrl","createdByName","confirmButtonText","position","patch","pointerEvents","top","left","transition","newStatus","triggerProductName","camelCase","toLowerCase","operationAppName","cardOpacity","Divider","marginHorizontal","Avatar","basis","source","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","triggerParams","useTriggerPersonOverride","exec","trim","startsWith","fetchPersonApps","App","PersonApp","personApp","allowPcoLogin","fetchCreatorProfiles","compact","uniq","profiles","fetchAutomations","AutomationSubscription","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","fetchNothing","fetchAllAtOnce","fetchOneAtATime","ids","allSettled","results","triggerResources","settledPromises","acc","concat","fetchIncomingAutomations","encryptedParam","fetchResourceName","path","_props","client","model","upperFirst","IncomingAutomations","setAutomations","operationApps","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","options","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","group","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","defaultValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","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","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","specificDate","setSpecificDate","todaysValue","customValue","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","getOperationDefinitions","OperationDefinition","getWebhooksApps","OperationApp","a","getVisibleApps","Topbar","apps","env","railsEnv","errorAlertProps","borderRadius","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","getOperationApps","visibleApps","webhooksApps","defaultSelection","definitions","current","triggerConditions","cloneDeep","conditions","set","dynamicConditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","renderedFields","requiredFields","required","selectFields","fieldIsSelect","every","fieldIsFilled","nextRequiredDescription","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","headerButtonProps","isPaused","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","margin","mediaQueries","lg","styles"],"mappings":"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"}