@nyaruka/temba-components 0.42.1 → 0.43.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{dae3a0ce.js → 481989ca.js} +464 -444
  3. package/dist/index.js +464 -444
  4. package/dist/sw.js +1 -1
  5. package/dist/sw.js.map +1 -1
  6. package/dist/templates/components-body.html +1 -1
  7. package/dist/templates/components-head.html +1 -1
  8. package/out-tsc/src/compose/Compose.js +21 -19
  9. package/out-tsc/src/compose/Compose.js.map +1 -1
  10. package/out-tsc/src/contacts/ContactChat.js +3 -4
  11. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  12. package/out-tsc/src/contacts/ContactHistory.js +17 -1
  13. package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
  14. package/out-tsc/src/contacts/events.js +64 -58
  15. package/out-tsc/src/contacts/events.js.map +1 -1
  16. package/out-tsc/src/lightbox/Lightbox.js +149 -0
  17. package/out-tsc/src/lightbox/Lightbox.js.map +1 -0
  18. package/out-tsc/src/list/ContentMenu.js +0 -4
  19. package/out-tsc/src/list/ContentMenu.js.map +1 -1
  20. package/out-tsc/src/list/TembaMenu.js +2 -42
  21. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  22. package/out-tsc/src/list/TicketList.js +2 -2
  23. package/out-tsc/src/list/TicketList.js.map +1 -1
  24. package/out-tsc/src/utils/index.js +64 -2
  25. package/out-tsc/src/utils/index.js.map +1 -1
  26. package/out-tsc/src/vectoricon/index.js +1 -1
  27. package/out-tsc/src/vectoricon/index.js.map +1 -1
  28. package/out-tsc/temba-modules.js +2 -0
  29. package/out-tsc/temba-modules.js.map +1 -1
  30. package/out-tsc/test/temba-compose.test.js +5 -6
  31. package/out-tsc/test/temba-compose.test.js.map +1 -1
  32. package/out-tsc/test/temba-contact-chat.test.js +28 -14
  33. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  34. package/out-tsc/test/temba-contact-history.test.js +1 -1
  35. package/out-tsc/test/temba-contact-history.test.js.map +1 -1
  36. package/out-tsc/test/temba-lightbox.test.js +28 -0
  37. package/out-tsc/test/temba-lightbox.test.js.map +1 -0
  38. package/out-tsc/test/utils.test.js +1 -2
  39. package/out-tsc/test/utils.test.js.map +1 -1
  40. package/package.json +1 -1
  41. package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
  42. package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
  43. package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
  44. package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
  45. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
  46. package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
  47. package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
  48. package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
  49. package/screenshots/truth/contacts/contact-active-default.png +0 -0
  50. package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
  51. package/screenshots/truth/contacts/contact-active-ticket-closed-show-reopen-button.png +0 -0
  52. package/screenshots/truth/contacts/contact-active-ticket-open-show-chatbox.png +0 -0
  53. package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
  54. package/screenshots/truth/contacts/contact-archived-ticket-closed-hide-chatbox.png +0 -0
  55. package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
  56. package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
  57. package/screenshots/truth/contacts/history.png +0 -0
  58. package/screenshots/truth/lightbox/img-zoomed.png +0 -0
  59. package/screenshots/truth/lightbox/img.png +0 -0
  60. package/screenshots/truth/menu/menu-focused-with items.png +0 -0
  61. package/screenshots/truth/menu/menu-refresh-1.png +0 -0
  62. package/screenshots/truth/menu/menu-refresh-2.png +0 -0
  63. package/screenshots/truth/menu/menu-root.png +0 -0
  64. package/screenshots/truth/menu/menu-submenu.png +0 -0
  65. package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
  66. package/screenshots/truth/menu/menu-tasks.png +0 -0
  67. package/src/compose/Compose.ts +25 -23
  68. package/src/contacts/ContactChat.ts +3 -4
  69. package/src/contacts/ContactHistory.ts +19 -1
  70. package/src/contacts/events.ts +79 -64
  71. package/src/lightbox/Lightbox.ts +165 -0
  72. package/src/list/ContentMenu.ts +0 -4
  73. package/src/list/TembaMenu.ts +2 -45
  74. package/src/list/TicketList.ts +2 -2
  75. package/src/untyped.d.ts +1 -0
  76. package/src/utils/index.ts +76 -3
  77. package/src/vectoricon/index.ts +1 -1
  78. package/static/css/temba-components.css +4 -1
  79. package/temba-modules.ts +2 -0
  80. package/test/temba-compose.test.ts +5 -7
  81. package/test/temba-contact-chat.test.ts +28 -15
  82. package/test/temba-contact-history.test.ts +1 -1
  83. package/test/temba-lightbox.test.ts +35 -0
  84. package/test/utils.test.ts +1 -2
  85. package/test-assets/img/meow.jpg +0 -0
  86. package/test-assets/style.css +1 -0
  87. package/web-test-runner.config.mjs +4 -0
  88. package/screenshots/truth/menu/menu-focus.png +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/contacts/events.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { Msg, ObjectReference, User } from '../interfaces';\nimport { getClasses, oxford, oxfordFn, oxfordNamed, timeSince } from '../utils';\nimport { Icon } from '../vectoricon';\nimport { getDisplayName } from './helpers';\n\nexport const getEventStyles = () => {\n return css`\n .grouping {\n margin-top: 1em;\n }\n\n .grouping.verbose {\n background: #f9f9f9;\n color: var(--color-dark);\n --color-link-primary: rgba(38, 166, 230, 1);\n pointer-events: none;\n background: #fefefe;\n box-shadow: -8px 0px 8px 1px rgba(0, 0, 0, 0.05) inset;\n margin-right: -16px;\n padding-right: 16px;\n margin-bottom: 1.3em;\n }\n\n .grouping .items {\n display: block;\n }\n\n .grouping.verbose .items {\n opacity: 0;\n max-height: 0;\n display: flex;\n flex-direction: column;\n user-select: none;\n }\n\n .grouping.flows .items {\n padding: 0;\n }\n\n .grouping.messages .items {\n display: flex;\n flex-direction: column;\n margin: 0em 0.75em;\n }\n\n .grouping.verbose.expanded .items {\n transition: max-height var(--transition-speed) ease-in-out,\n opacity var(--transition-speed) ease-in-out;\n opacity: 1;\n max-height: 1000px;\n padding: 1em 1em;\n }\n\n .grouping.verbose.expanded {\n border-top: 1px solid #f3f3f3;\n border-bottom: 1px solid #f3f3f3;\n }\n\n .grouping.verbose.expanded,\n .grouping.verbose .event-count {\n pointer-events: auto;\n }\n\n .grouping.verbose temba-icon {\n }\n\n .grouping.verbose > .event,\n .grouping.verbose > pre {\n max-height: 0px;\n padding-top: 0;\n padding-bottom: 0;\n margin-top: 0;\n margin-bottom: 0;\n opacity: 0;\n }\n\n .grouping.verbose .attn {\n color: #666;\n }\n\n .event-count {\n position: relative;\n font-size: 0.8em;\n text-align: center;\n margin: 0 auto;\n display: table;\n padding: 3px 10px;\n font-weight: 400;\n color: #999;\n cursor: pointer;\n width: 100%;\n opacity: 1;\n z-index: 1;\n }\n\n .event-count temba-icon {\n display: inline-block;\n position: absolute;\n right: 5px;\n top: 5px;\n }\n\n .event-count:hover {\n color: var(--color-link-primary-hover);\n }\n\n .expanded .event-count {\n padding: 0;\n pointer-events: none;\n }\n\n .grouping.flows {\n margin-left: 1em;\n margin-right: 1em;\n margin-bottom: 1.5em;\n\n border: 1px solid #f2f2f2;\n border-radius: var(--curvature);\n padding: 0.5em 1em;\n }\n\n .grouping.flows .event {\n margin: 0;\n padding: 0;\n }\n\n .grouping.tickets {\n margin-bottom: 2em;\n }\n\n pre {\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n\n .grouping.verbose.expanded .event,\n .grouping.verbose.expanded pre {\n max-height: 500px;\n opacity: 1;\n }\n\n .grouping-close-button {\n position: relative;\n display: inline-block;\n opacity: 0;\n float: right;\n --icon-color: #666;\n }\n\n .grouping.verbose.expanded:hover .grouping-close-button {\n opacity: 1;\n }\n\n .grouping.messages,\n .grouping.tickets {\n display: flex;\n flex-direction: column;\n }\n\n .event {\n margin: 0.25em 0.5em;\n border-radius: var(--curvature);\n flex-grow: 1;\n }\n\n .msg {\n padding: var(--event-padding);\n border-radius: 8px;\n border: 2px solid rgba(100, 100, 100, 0.1);\n max-width: 300px;\n word-break: break-word;\n }\n\n .event.msg_received .msg {\n background: rgba(200, 200, 200, 0.1);\n }\n\n .event.msg_created,\n .event.broadcast_created,\n .event.ivr_created,\n .tickets .event.ticket_note_added {\n align-self: flex-end;\n }\n\n .event.msg_created .msg,\n .event.broadcast_created .msg,\n .event.ivr_created .msg {\n background: rgb(231, 243, 255);\n }\n\n .webhook_called {\n --icon-color: #e68628;\n word-break: break-all;\n }\n\n .webhook_called .failed {\n --icon-color: var(--color-error);\n color: var(--color-error);\n }\n\n .input_labels_added,\n .contact_name_changed,\n .contact_field_changed,\n .contact_urns_changed,\n .contact_language_changed,\n .run_result_changed {\n --icon-color: rgba(1, 193, 175, 1);\n }\n\n .email_sent {\n --icon-color: #8e5ea7;\n }\n\n .contact_groups_changed .added {\n --icon-color: #309c42;\n }\n .contact_groups_changed .removed {\n --icon-color: var(--color-error);\n }\n\n .event.error .description,\n .event.failure .description {\n color: var(--color-error);\n }\n\n .description.error {\n color: var(--color-error);\n }\n\n .info {\n border: 1px solid rgba(100, 100, 100, 0.2);\n background: rgba(10, 10, 10, 0.02);\n }\n\n .tickets .ticket_note_added {\n max-width: 300px;\n }\n\n .tickets .note-summary {\n display: flex;\n flex-direction: row;\n font-size: 85%;\n margin-top: -0.5em;\n color: rgba(0, 0, 0, 0.6);\n padding: 8px 3px;\n }\n\n .tickets .ticket_note_added .description {\n border: 2px solid rgba(100, 100, 100, 0.1);\n background: rgb(255, 249, 194);\n padding: var(--event-padding);\n border-radius: 8px;\n }\n\n .channel_event {\n --icon-color: rgb(230, 230, 230);\n }\n\n .airtime_transferred,\n .flow_exited,\n .flow_entered,\n .ticket_opened,\n .ticket_reopened,\n .ticket_closed,\n .call_started,\n .campaign_fired {\n --icon-color: rgba(223, 65, 159, 1);\n }\n\n .active-ticket.ticket_opened {\n padding: 0em 1em;\n }\n\n .ticket_opened temba-icon.clickable[name='check'] {\n --icon-color: rgba(100, 100, 100, 1);\n }\n\n .ticket_opened .active {\n color: var(--color-text);\n }\n\n .ticket_closed .inactive .subtext {\n display: none;\n }\n\n .attn {\n color: var(--color-text);\n }\n\n .flow_exited,\n .flow_entered {\n align-self: center;\n max-width: 80%;\n display: flex;\n flex-direction: row;\n }\n\n .flow_exited temba-icon,\n .flow_entered temba-icon {\n }\n\n .event {\n display: flex;\n align-items: center;\n }\n\n .event .description {\n flex-grow: 1;\n word-break: break-all;\n }\n\n .msg-summary {\n display: flex;\n font-size: 85%;\n color: rgba(0, 0, 0, 0.6);\n padding: 6px 3px;\n margin-bottom: 0.5em;\n margin-top: -0.5em;\n }\n\n .msg-summary temba-icon.log {\n --icon-color: rgba(0, 0, 0, 0.2);\n }\n\n .msg-summary temba-icon.log:hover {\n --icon-color: var(--color-link-primary-hover);\n cursor: pointer;\n }\n\n .msg-summary temba-icon.error {\n --icon-color: rgba(var(--error-rgb), 0.75);\n }\n\n .msg-summary temba-icon.error:hover {\n --icon-color: var(--color-error);\n cursor: pointer;\n }\n\n .msg-summary temba-icon.broadcast {\n --icon-color: rgba(90, 90, 90, 0.5);\n }\n\n .msg-summary * {\n display: flex;\n margin-right: 1px;\n margin-left: 1px;\n }\n\n .unsupported {\n border: 1px solid #f2f2f2;\n color: #999;\n padding: 0.5em 1em;\n border-radius: var(--curvature);\n }\n\n .time {\n padding: 0.3em 1px;\n }\n\n .status {\n padding: 0.3em 3px;\n }\n\n .separator {\n padding: 0.3em 0px;\n }\n\n .recipients {\n padding: 0.3em 3px;\n }\n\n .verbose temba-icon,\n .flows temba-icon,\n .tickets temba-icon {\n margin-right: 0.75em;\n }\n\n .attn {\n display: inline-block;\n font-weight: 500;\n margin: 0px 2px;\n }\n\n .subtext {\n font-size: 80%;\n }\n\n .body-pre {\n white-space: pre-wrap;\n word-wrap: break-word;\n font-size: 90%;\n }\n\n a,\n .linked {\n color: var(--color-link-primary);\n cursor: pointer;\n }\n\n a:hover,\n .linked:hover {\n text-decoration: underline;\n color: var(--color-link-primary-hover);\n }\n\n temba-icon.error {\n --icon-color: var(--color-error);\n }\n\n .delivery-error {\n --icon-color: var(--color-error);\n margin-right: 0.25em;\n }\n\n .flow {\n --icon-color: #ddd;\n background: #fff;\n width: 18px;\n height: 18px;\n padding-top: 4px;\n padding-left: 9px;\n border: 0px solid #f3f3f3;\n }\n\n .assigned {\n color: #777;\n max-width: 300px;\n margin-left: auto;\n margin-right: auto;\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 10px;\n }\n\n .assigned .attn {\n color: #777;\n }\n\n .attachments {\n margin-top: 1em;\n }\n `;\n};\n\nconst FLOW_USER_ID = 'flow';\n\nexport interface EventGroup {\n type: string;\n events: ContactEvent[];\n open: boolean;\n}\n\nexport enum Events {\n MESSAGE_CREATED = 'msg_created',\n MESSAGE_RECEIVED = 'msg_received',\n BROADCAST_CREATED = 'broadcast_created',\n IVR_CREATED = 'ivr_created',\n FLOW_ENTERED = 'flow_entered',\n FLOW_EXITED = 'flow_exited',\n RUN_RESULT_CHANGED = 'run_result_changed',\n CONTACT_FIELD_CHANGED = 'contact_field_changed',\n CONTACT_GROUPS_CHANGED = 'contact_groups_changed',\n CONTACT_NAME_CHANGED = 'contact_name_changed',\n CONTACT_URNS_CHANGED = 'contact_urns_changed',\n CAMPAIGN_FIRED = 'campaign_fired',\n CHANNEL_EVENT = 'channel_event',\n CONTACT_LANGUAGE_CHANGED = 'contact_language_changed',\n WEBHOOK_CALLED = 'webhook_called',\n AIRTIME_TRANSFERRED = 'airtime_transferred',\n CALL_STARTED = 'call_started',\n EMAIL_SENT = 'email_sent',\n INPUT_LABELS_ADDED = 'input_labels_added',\n NOTE_CREATED = 'note_created',\n TICKET_ASSIGNED = 'ticket_assigned',\n TICKET_NOTE_ADDED = 'ticket_note_added',\n TICKET_CLOSED = 'ticket_closed',\n TICKET_OPENED = 'ticket_opened',\n TICKET_REOPENED = 'ticket_reopened',\n ERROR = 'error',\n FAILURE = 'failure',\n}\n\nexport interface ContactEvent {\n type: string;\n created_on: string;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n msg_type: string;\n recipient_count?: number;\n created_by?: User;\n}\n\nexport interface FlowEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface EmailSentEvent extends ContactEvent {\n to: string[];\n subject: string;\n body: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n ticketer: ObjectReference;\n body: string;\n topic?: ObjectReference;\n external_id?: string;\n closed_on?: string;\n opened_on?: string;\n };\n created_by?: User;\n}\n\nexport interface LabelsAddedEvent extends ContactEvent {\n labels: ObjectReference[];\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ErrorMessageEvent extends ContactEvent {\n text: string;\n}\n\nexport interface UpdateResultEvent extends ContactEvent {\n name: string;\n value: string;\n category: string;\n input: string;\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface WebhookEvent extends ContactEvent {\n status: string;\n status_code: number;\n elapsed_ms: number;\n logs_url: string;\n url: string;\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n desired_amount: string;\n actual_amount: string;\n logs_url: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\nexport interface CampaignFiredEvent extends ContactEvent {\n campaign: { uuid: string; id: number; name: string };\n campaign_event: {\n id: number;\n offset_display: string;\n relative_to: { key: string; name: string };\n };\n fired_result: string;\n}\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n\nexport const getEventGroupType = (event: ContactEvent, ticket: string) => {\n if (!event) {\n return 'messages';\n }\n switch (event.type) {\n case Events.TICKET_ASSIGNED:\n case Events.TICKET_NOTE_ADDED:\n case Events.TICKET_OPENED:\n case Events.TICKET_CLOSED:\n case Events.TICKET_REOPENED:\n if (!ticket) {\n return 'verbose';\n }\n\n if ((event as TicketEvent).ticket.uuid === ticket) {\n return 'tickets';\n }\n\n break;\n case Events.FLOW_ENTERED:\n case Events.FLOW_EXITED:\n return 'flows';\n case Events.BROADCAST_CREATED:\n case Events.MESSAGE_CREATED:\n case Events.MESSAGE_RECEIVED:\n case Events.IVR_CREATED:\n return 'messages';\n }\n return 'verbose';\n};\n\nexport const renderAvatar = (user: User, agent = '') => {\n const current = user && user.email === agent;\n if (user.email === FLOW_USER_ID || !user || !user.first_name) {\n return html`<temba-tip text=\"Automated message\" position=\"top\"\n ><div class=\"avatar flow\" style=\"margin-top:0.5em\">\n <temba-icon size=\"1\" name=\"${Icon.flow_user}\" /></div\n ></temba-tip>`;\n } else {\n return html`<temba-tip\n text=\"${user.first_name + ' ' + user.last_name}\"\n position=\"top\"\n >\n <div\n class=\"avatar\"\n style=\"\n border-radius: 9999px; \n display:flex;\n align-items:center;\n border: 2px solid rgba(0,0,0,.05);\n background: ${current ? 'var(--color-primary-dark)' : '#eee'};\n color: ${current ? '#fff' : '#999'} ;\n font-weight: 400;\n padding: 0.5em;\n line-height:1.2em;\n \"\n >\n ${user.first_name[0] + user.last_name[0]}\n </div>\n </temba-tip>`;\n }\n};\n\nexport const renderAttachment = (attachment: string): TemplateResult => {\n const idx = attachment.indexOf(':');\n const attType = attachment.substr(0, idx);\n const url = attachment.substr(idx + 1);\n const [mediaType, ext] = attType.split('/', 2);\n\n let inner = null;\n if (mediaType === 'image') {\n inner = html`<div class=\"linked\" onclick=\"goto(event)\" href=\"${url}\"><img src=\"${url}\" style=\"width:100%;height:auto;display:block\"></img></a>`;\n } else if (ext === 'pdf') {\n return html`<div\n style=\"width:100%;height:300px;border-radius:var(--curvature);box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);overflow:hidden\"\n ><embed src=\"${url}#view=Fit\" type=\"application/pdf\" frameBorder=\"0\" scrolling=\"auto\" height=\"100%\" width=\"100%\"></embed></div>`;\n } else if (mediaType === 'video') {\n return html`<video\n style=\"border-radius:var(--curvature);box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);max-width:400px\"\n height=\"auto\"\n controls\n >\n <source src=\"${url}\" type=\"video/mp4\" />\n </video> `;\n } else if (mediaType === 'audio') {\n return html`<audio\n style=\"border-radius: 99px; box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);\"\n src=\"${url}\"\n type=\"${attType}\"\n controls\n >\n <a target=\"_\" href=\"${url}\">${url}</a>\n </audio>`;\n } else if (attType === 'geo') {\n const [lat, long] = url.split(',');\n const latFloat = parseFloat(lat);\n const longFloat = parseFloat(long);\n const geo = `${lat}000000%2C${long}000000`;\n\n return html` <iframe\n style=\"border-radius: var(--curvature);box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);\"\n width=\"300\"\n height=\"300\"\n frameborder=\"0\"\n scrolling=\"no\"\n marginheight=\"0\"\n marginwidth=\"0\"\n src=\"https://www.openstreetmap.org/export/embed.html?bbox=${longFloat -\n 0.005}000000%2C${latFloat - 0.005}%2C${longFloat +\n 0.005}000000%2C${latFloat +\n 0.005}000000&amp;layer=mapnik&amp;marker=${geo}\"\n ></iframe>`;\n } else {\n return html`<div style=\"display:flex\">\n <temba-icon name=\"${Icon.download}\"></temba-icon>\n <div>Attachment ${ext}</div>\n </div>`;\n }\n\n return html`<div\n style=\"width:100%;max-width:300px;border-radius:var(--curvature); box-shadow:0px 0px 6px 0px rgba(0,0,0,.15);overflow:hidden\"\n >\n ${inner}\n </div>`;\n};\n\nexport const renderMsgEvent = (\n event: MsgEvent,\n agent: string\n): TemplateResult => {\n const isInbound = event.type === Events.MESSAGE_RECEIVED;\n const isError = event.status === 'E';\n const isFailure = event.status === 'F';\n\n // summary items which appear under the message bubble\n const summary: TemplateResult[] = [];\n if (event.logs_url) {\n summary.push(html` <div class=\"icon-link\">\n <temba-icon\n onclick=\"goto(event)\"\n href=\"${event.logs_url}\"\n name=\"${Icon.log}\"\n class=\"log ${isError || isFailure ? 'error' : ''}\"\n ></temba-icon>\n </div>`);\n } else if (isError) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery error\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n } else if (isFailure) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery failure: ${event.failed_reason_display}\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n }\n if (event.recipient_count > 1) {\n summary.push(html`<temba-icon\n size=\"1\"\n class=\"broadcast\"\n name=\"${Icon.broadcast}\"\n ></temba-icon>\n <div class=\"recipients\">${event.recipient_count} contacts</div>\n <div class=\"separator\">•</div>`);\n }\n summary.push(\n html`<temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>`\n );\n\n return html`<div style=\"display:flex;align-items:flex-start\">\n <div style=\"display:flex;flex-direction:column\">\n ${event.msg.text ? html`<div class=\"msg\">${event.msg.text}</div>` : null}\n ${event.msg.attachments\n ? html`<div class=\"attachments\">\n ${event.msg.attachments.map(attachment =>\n renderAttachment(attachment)\n )}\n </div> `\n : null}\n ${!event.msg.text && !event.msg.attachments\n ? html`<div class=\"unsupported\">Unsupported Message</div>`\n : null}\n <div\n class=\"msg-summary\"\n style=\"flex-direction:row${isInbound ? '-reverse' : ''}\"\n >\n <div style=\"flex-grow:1\"></div>\n ${summary}\n </div>\n </div>\n\n ${!isInbound\n ? html`<div style=\"margin-left:0.8em;margin-top:0.3em\">\n ${event.msg.created_by\n ? html`<div style=\"font-size:0.8em\">\n ${renderAvatar(event.msg.created_by, agent)}\n </div>`\n : renderAvatar({ email: FLOW_USER_ID })}\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderFlowEvent = (event: FlowEvent): TemplateResult => {\n let verb = 'Interrupted';\n let icon = Icon.flow_interrupted;\n\n if (event.status !== 'I') {\n if (event.type === Events.FLOW_ENTERED) {\n verb = 'Started';\n icon = Icon.flow;\n } else {\n verb = 'Completed';\n icon = Icon.flow;\n }\n }\n\n return html`\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${verb}\n <span\n class=\"linked\"\n href=\"/flow/editor/${event.flow.uuid}/\"\n onclick=\"goto(event)\"\n >\n ${event.flow.name}\n </span>\n </div>\n `;\n};\n\nexport const renderResultEvent = (event: UpdateResultEvent): TemplateResult => {\n if (event.name.startsWith('_')) {\n return null;\n }\n return html`\n <temba-icon name=\"${Icon.updated}\"></temba-icon>\n <div class=\"description\">\n Updated\n <div class=\"attn\">${event.name}</div>\n to\n <div class=\"attn\">${event.value}</div>\n ${event.category\n ? html`with category\n <div class=\"attn\">${event.category}</div>`\n : null}\n </div>\n `;\n};\n\nexport const renderUpdateEvent = (event: UpdateFieldEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n ${event.value\n ? html`Updated\n <div class=\"attn\">${event.field.name}</div>\n to\n <div class=\"attn\">${event.value.text}</div>`\n : html`Cleared\n <div class=\"attn\">${event.field.name}</div>`}\n </div>\n `;\n};\n\nexport const renderNameChanged = (event: NameChangedEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n Updated\n <div class=\"attn\">Name</div>\n to\n <div class=\"attn\">${event.name}</div>\n </div>\n `;\n};\n\nexport const renderContactURNsChanged = (\n event: URNsChangedEvent\n): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n Updated\n <div class=\"attn\">URNs</div>\n to\n ${oxfordFn(\n event.urns,\n (urn: string) =>\n html`<div class=\"attn\">${urn.split(':')[1].split('?')[0]}</div>`\n )}\n </div>\n </div>\n `;\n};\n\nexport const renderEmailSent = (event: EmailSentEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.email}\"></temba-icon>\n <div class=\"description\">\n Email sent to\n <div class=\"attn\">${oxford(event.to, 'and')}</div>\n with subject\n <div class=\"attn\">${event.subject}</div>\n </div>\n `;\n};\n\nexport const renderLabelsAdded = (event: LabelsAddedEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.label}\"></temba-icon>\n <div class=\"description\">\n Message labeled with\n <div class=\"attn\">${oxfordNamed(event.labels, 'and')}</div>\n </div>\n `;\n};\n\nexport const renderNoteCreated = (\n event: TicketEvent,\n agent: string\n): TemplateResult => {\n return html`<div style=\"display:flex;align-items:flex-start\">\n <div style=\"display:flex;flex-direction:column\">\n <div class=\"description\">${event.note}</div>\n <div class=\"note-summary\">\n <div style=\"flex-grow:1\"></div>\n <temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>\n </div>\n </div>\n <div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.8em\">\n ${renderAvatar(event.created_by, agent)}\n </div>\n </div>`;\n};\n\nconst getTicketIcon = (event: TicketEvent) => {\n let icon = Icon.inbox;\n if (event.ticket.ticketer.name.indexOf('Email') > -1) {\n icon = Icon.email;\n } else if (event.ticket.ticketer.name.indexOf('Zendesk') > -1) {\n icon = Icon.zendesk;\n }\n return icon;\n};\n\nexport const renderTicketAction = (\n event: TicketEvent,\n action: string,\n grouped: boolean\n): TemplateResult => {\n const reopened = new Date(event.created_on);\n const icon = getTicketIcon(event);\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${getDisplayName(event.created_by)} ${action} a\n <span\n onclick=\"goto(event)\"\n class=\"linked\"\n href=\"/ticket/all/open/${event.ticket.uuid}\"\n >\n ticket\n </span>\n </div>\n </div>`;\n }\n\n return html`\n <div class=\"assigned active\">\n <div style=\"text-align:center\">\n ${getDisplayName(event.created_by)} ${action} this ticket\n </div>\n <div class=\"subtext\" style=\"justify-content:center\">\n <temba-date\n class=\"time\"\n value=\"${reopened}\"\n display=\"duration\"\n ></temba-date>\n </div>\n </div>\n `;\n};\n\nexport const renderTicketAssigned = (event: TicketEvent): TemplateResult => {\n return html`\n <div class=\"assigned active\">\n <div style=\"text-align:center\">\n ${event.assignee\n ? event.assignee.id === event.created_by.id\n ? html`${getDisplayName(event.created_by)} took this ticket`\n : html`${getDisplayName(event.created_by)} assigned this ticket to\n <div class=\"attn\">${getDisplayName(event.assignee)}</div>`\n : html`${getDisplayName(event.created_by)} unassigned this ticket`}\n </div>\n <div class=\"subtext\" style=\"justify-content:center\">\n <temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>\n </div>\n </div>\n `;\n};\n\nexport const renderTicketOpened = (\n event: TicketEvent,\n handleClose: (uuid: string) => void,\n grouped: boolean\n): TemplateResult => {\n const icon = getTicketIcon(event);\n\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${event.ticket.topic.name}\n <span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/ticket/all/open/${event.ticket.uuid}\"\n >ticket</span\n >\n was opened\n </div>\n </div>`;\n } else {\n return html`\n <temba-icon size=\"1.5\" name=\"${icon}\"></temba-icon>\n\n <div class=\"active\" style=\"flex-grow:1;\">\n Opened\n <div class=\"attn\">\n ${event.ticket.topic ? event.ticket.topic.name : 'General'}\n </div>\n <div class=\"subtext\">${timeSince(new Date(event.created_on))}</div>\n </div>\n ${handleClose\n ? html`\n <temba-tip text=\"Resolve\" position=\"left\" style=\"width:1.5em\">\n <temba-icon\n class=\"clickable\"\n size=\"1.5\"\n name=\"${Icon.check}\"\n @click=${() => {\n handleClose(event.ticket.uuid);\n }}\n ?clickable=${open}\n />\n </temba-tip>\n `\n : null}\n `;\n }\n};\n\nexport const renderErrorMessage = (\n event: ErrorMessageEvent\n): TemplateResult => {\n return html`\n <temba-icon\n name=\"${Icon.error}\"\n style=\"--icon-color:var(--color-error)\"\n ></temba-icon>\n <div class=\"description\">\n ${event.text}\n ${event.type === Events.FAILURE\n ? html`<div>Run ended prematurely, check the flow design.</div>`\n : null}\n </div>\n `;\n};\n\nexport const renderWebhookEvent = (event: WebhookEvent): TemplateResult => {\n return html`\n <div\n class=\"${event.status === 'success' ? '' : 'failed'}\"\n style=\"display: flex\"\n >\n <temba-icon name=\"${Icon.webhook}\"></temba-icon>\n <div class=\"description\">\n ${event.status === 'success'\n ? html`Successfully called ${event.url}`\n : html`Failed to call ${event.url}`}\n </div>\n </div>\n `;\n};\n\nexport const renderAirtimeTransferredEvent = (\n event: AirtimeTransferredEvent\n): TemplateResult => {\n if (parseFloat(event.actual_amount) === 0) {\n return html`<temba-icon\n name=\"${Icon.error}\"\n style=\"--icon-color: var(--color-error)\"\n ></temba-icon>\n <div class=\"description error\">Airtime transfer failed</div>`;\n }\n\n return html`<temba-icon name=\"${Icon.airtime}\"></temba-icon>\n <div class=\"description\">\n Transferred\n <div class=\"attn\">${event.actual_amount} ${event.currency}</div>\n of airtime\n </div>`;\n};\n\nexport const renderCallStartedEvent = (): TemplateResult => {\n return html`<temba-icon name=\"${Icon.call}\"></temba-icon>\n <div class=\"description\">Call Started</div>`;\n};\n\nexport const renderContactLanguageChangedEvent = (\n event: ContactLanguageChangedEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n Language updated to <span class=\"attn\">${event.language}</span>\n </div>`;\n};\n\nexport const renderChannelEvent = (event: ChannelEvent): TemplateResult => {\n let eventMessage = '';\n let icon = Icon.call;\n\n if (event.channel_event_type === 'mt_miss') {\n eventMessage = 'Missed outgoing call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'mo_miss') {\n eventMessage = 'Missed incoming call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'new_conversation') {\n eventMessage = 'Started Conversation';\n icon = Icon.event;\n } else if (event.channel_event_type === 'welcome_message') {\n eventMessage = 'Welcome Message Sent';\n icon = Icon.event;\n } else if (event.channel_event_type === 'referral') {\n eventMessage = 'Referred';\n icon = Icon.event;\n } else if (event.channel_event_type === 'follow') {\n eventMessage = 'Followed';\n icon = Icon.event;\n } else if (event.channel_event_type === 'stop_contact') {\n eventMessage = 'Stopped';\n icon = Icon.contact_stopped;\n } else if (event.channel_event_type === 'mt_call') {\n eventMessage = 'Outgoing Phone Call';\n } else if (event.channel_event_type == 'mo_call') {\n eventMessage = 'Incoming Phone call';\n }\n\n return html`<temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">${eventMessage}</div>`;\n};\n\nexport const renderCampaignFiredEvent = (\n event: CampaignFiredEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.campaign}\"></temba-icon>\n <div class=\"description\">\n Campaign\n <span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/campaign/read/${event.campaign.uuid}\"\n >${event.campaign.name}</span\n >\n ${event.fired_result === 'S' ? 'skipped' : 'triggered'}\n <span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/campaignevent/read/${event.campaign.uuid}/${event.campaign_event\n .id}\"\n >\n ${event.campaign_event.offset_display}\n ${event.campaign_event.relative_to.name}</span\n >\n </div>`;\n};\n\nexport const renderContactGroupsEvent = (\n event: ContactGroupsEvent\n): TemplateResult => {\n const groups = event.groups_added || event.groups_removed;\n const added = !!event.groups_added;\n return html`\n <temba-icon\n name=\"${Icon.users}\"\n class=\"${getClasses({ added: added, removed: !added })}\"\n ></temba-icon>\n <div class=\"description\">\n ${added ? 'Added to' : 'Removed from'}\n ${oxfordFn(\n groups,\n (group: ObjectReference) =>\n html`<span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/contact/filter/${group.uuid}\"\n >${group.name}</span\n >`\n )}\n ${event.type === Events.FAILURE\n ? html`<div>Run ended prematurely, check the flow design.</div>`\n : null}\n </div>\n `;\n};\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/contacts/events.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { Msg, ObjectReference, User } from '../interfaces';\nimport {\n getClasses,\n oxford,\n oxfordFn,\n oxfordNamed,\n renderAvatar,\n timeSince,\n} from '../utils';\nimport { Icon } from '../vectoricon';\nimport { getDisplayName } from './helpers';\n\nexport const getEventStyles = () => {\n return css`\n .grouping {\n margin-top: 1em;\n }\n\n .grouping.verbose {\n background: #f9f9f9;\n color: var(--color-dark);\n --color-link-primary: rgba(38, 166, 230, 1);\n pointer-events: none;\n background: #fefefe;\n box-shadow: -8px 0px 8px 1px rgba(0, 0, 0, 0.05) inset;\n margin-right: -16px;\n padding-right: 16px;\n margin-bottom: 1.3em;\n }\n\n .grouping .items {\n display: block;\n }\n\n .grouping.verbose .items {\n opacity: 0;\n max-height: 0;\n display: flex;\n flex-direction: column;\n user-select: none;\n }\n\n .grouping.flows .items {\n padding: 0;\n }\n\n .grouping.messages .items {\n display: flex;\n flex-direction: column;\n margin: 0em 0.75em;\n }\n\n .grouping.verbose.expanded .items {\n transition: max-height var(--transition-speed) ease-in-out,\n opacity var(--transition-speed) ease-in-out;\n opacity: 1;\n max-height: 1000px;\n padding: 1em 1em;\n }\n\n .grouping.verbose.expanded {\n border-top: 1px solid #f3f3f3;\n border-bottom: 1px solid #f3f3f3;\n }\n\n .grouping.verbose.expanded,\n .grouping.verbose .event-count {\n pointer-events: auto;\n }\n\n .grouping.verbose temba-icon {\n }\n\n .grouping.verbose > .event,\n .grouping.verbose > pre {\n max-height: 0px;\n padding-top: 0;\n padding-bottom: 0;\n margin-top: 0;\n margin-bottom: 0;\n opacity: 0;\n }\n\n .grouping.verbose .attn {\n color: #666;\n }\n\n .event-count {\n position: relative;\n font-size: 0.8em;\n text-align: center;\n margin: 0 auto;\n display: table;\n padding: 3px 10px;\n font-weight: 400;\n color: #999;\n cursor: pointer;\n width: 100%;\n opacity: 1;\n z-index: 1;\n }\n\n .event-count temba-icon {\n display: inline-block;\n position: absolute;\n right: 5px;\n top: 5px;\n }\n\n .event-count:hover {\n color: var(--color-link-primary-hover);\n }\n\n .expanded .event-count {\n padding: 0;\n pointer-events: none;\n }\n\n .grouping.flows {\n margin-left: 1em;\n margin-right: 1em;\n margin-bottom: 1.5em;\n\n border: 1px solid #f2f2f2;\n border-radius: var(--curvature);\n padding: 0.5em 1em;\n }\n\n .grouping.flows .event {\n margin: 0;\n padding: 0;\n }\n\n .grouping.tickets {\n margin-bottom: 2em;\n }\n\n pre {\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n\n .grouping.verbose.expanded .event,\n .grouping.verbose.expanded pre {\n max-height: 500px;\n opacity: 1;\n }\n\n .grouping-close-button {\n position: relative;\n display: inline-block;\n opacity: 0;\n float: right;\n --icon-color: #666;\n }\n\n .grouping.verbose.expanded:hover .grouping-close-button {\n opacity: 1;\n }\n\n .grouping.messages,\n .grouping.tickets {\n display: flex;\n flex-direction: column;\n }\n\n .event {\n margin: 0.25em 0.5em;\n border-radius: var(--curvature);\n flex-grow: 1;\n }\n\n .msg {\n border-radius: calc(var(--curvature) * 2.5);\n border: 2px solid rgba(100, 100, 100, 0.1);\n max-width: 300px;\n word-break: break-word;\n overflow: hidden;\n }\n\n .msg.attachments-1.no-message {\n border: 2px solid transparent;\n background-color: transparent !important;\n }\n\n .msg .text {\n padding: var(--event-padding);\n }\n\n .event.msg_received .msg {\n background: rgba(200, 200, 200, 0.1);\n }\n\n .event.msg_created,\n .event.broadcast_created,\n .event.ivr_created,\n .tickets .event.ticket_note_added {\n align-self: flex-end;\n }\n\n .event.msg_created .msg,\n .event.broadcast_created .msg,\n .event.ivr_created .msg {\n background: var(--color-primary-dark);\n color: white;\n font-weight: 400;\n }\n\n .msg.automated {\n background: var(--color-automated) !important;\n }\n\n .webhook_called {\n --icon-color: #e68628;\n word-break: break-all;\n }\n\n .webhook_called .failed {\n --icon-color: var(--color-error);\n color: var(--color-error);\n }\n\n .input_labels_added,\n .contact_name_changed,\n .contact_field_changed,\n .contact_urns_changed,\n .contact_language_changed,\n .run_result_changed {\n --icon-color: rgba(1, 193, 175, 1);\n }\n\n .email_sent {\n --icon-color: #8e5ea7;\n }\n\n .contact_groups_changed .added {\n --icon-color: #309c42;\n }\n .contact_groups_changed .removed {\n --icon-color: var(--color-error);\n }\n\n .event.error .description,\n .event.failure .description {\n color: var(--color-error);\n }\n\n .description.error {\n color: var(--color-error);\n }\n\n .info {\n border: 1px solid rgba(100, 100, 100, 0.2);\n background: rgba(10, 10, 10, 0.02);\n }\n\n .tickets .ticket_note_added {\n max-width: 300px;\n }\n\n .tickets .note-summary {\n display: flex;\n flex-direction: row;\n font-size: 85%;\n margin-top: -0.5em;\n color: rgba(0, 0, 0, 0.6);\n padding: 8px 3px;\n }\n\n .tickets .ticket_note_added .description {\n border: 2px solid rgba(100, 100, 100, 0.1);\n background: rgb(255, 249, 194);\n padding: var(--event-padding);\n border-radius: 8px;\n }\n\n .channel_event {\n --icon-color: rgb(230, 230, 230);\n }\n\n .airtime_transferred,\n .flow_exited,\n .flow_entered,\n .ticket_opened,\n .ticket_reopened,\n .ticket_closed,\n .call_started,\n .campaign_fired {\n --icon-color: rgba(223, 65, 159, 1);\n }\n\n .active-ticket.ticket_opened {\n padding: 0em 1em;\n }\n\n .ticket_opened temba-icon.clickable[name='check'] {\n --icon-color: rgba(100, 100, 100, 1);\n }\n\n .ticket_opened .active {\n color: var(--color-text);\n }\n\n .ticket_closed .inactive .subtext {\n display: none;\n }\n\n .attn {\n color: var(--color-text);\n }\n\n .flow_exited,\n .flow_entered {\n align-self: center;\n max-width: 80%;\n display: flex;\n flex-direction: row;\n }\n\n .flow_exited temba-icon,\n .flow_entered temba-icon {\n }\n\n .event {\n display: flex;\n align-items: center;\n }\n\n .event .description {\n flex-grow: 1;\n word-break: break-all;\n }\n\n .msg-summary {\n display: flex;\n font-size: 85%;\n color: rgba(0, 0, 0, 0.6);\n padding: 6px 3px;\n margin-bottom: 0.5em;\n margin-top: -0.5em;\n }\n\n .msg-summary temba-icon.log {\n --icon-color: rgba(0, 0, 0, 0.2);\n }\n\n .msg-summary temba-icon.log:hover {\n --icon-color: var(--color-link-primary-hover);\n cursor: pointer;\n }\n\n .msg-summary temba-icon.error {\n --icon-color: rgba(var(--error-rgb), 0.75);\n }\n\n .msg-summary temba-icon.error:hover {\n --icon-color: var(--color-error);\n cursor: pointer;\n }\n\n .msg-summary temba-icon.broadcast {\n --icon-color: rgba(90, 90, 90, 0.5);\n }\n\n .msg-summary * {\n display: flex;\n margin-right: 1px;\n margin-left: 1px;\n }\n\n .unsupported {\n border: 1px solid #f2f2f2;\n color: #999;\n padding: 0.5em 1em;\n border-radius: var(--curvature);\n }\n\n .time {\n padding: 0.3em 1px;\n }\n\n .status {\n padding: 0.3em 3px;\n }\n\n .separator {\n padding: 0.3em 0px;\n }\n\n .recipients {\n padding: 0.3em 3px;\n }\n\n .verbose temba-icon,\n .flows temba-icon,\n .tickets temba-icon {\n margin-right: 0.75em;\n }\n\n .attn {\n display: inline-block;\n font-weight: 500;\n margin: 0px 2px;\n }\n\n .subtext {\n font-size: 80%;\n }\n\n .body-pre {\n white-space: pre-wrap;\n word-wrap: break-word;\n font-size: 90%;\n }\n\n a,\n .linked {\n color: var(--color-link-primary);\n cursor: pointer;\n }\n\n a:hover,\n .linked:hover {\n text-decoration: underline;\n color: var(--color-link-primary-hover);\n }\n\n temba-icon.error {\n --icon-color: var(--color-error);\n }\n\n .delivery-error {\n --icon-color: var(--color-error);\n margin-right: 0.25em;\n }\n\n .flow {\n --icon-color: #ddd;\n background: #fff;\n width: 18px;\n height: 18px;\n padding-top: 4px;\n padding-left: 9px;\n border: 0px solid #f3f3f3;\n }\n\n .assigned {\n color: #777;\n max-width: 300px;\n margin-left: auto;\n margin-right: auto;\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 10px;\n }\n\n .assigned .attn {\n color: #777;\n }\n\n .attachments {\n display: flex;\n flex-wrap: wrap;\n margin: -0.2em;\n }\n\n .attachment {\n flex: 1 0 45%;\n border-top: 0.05em solid transparent;\n border-left: 0.05em solid transparent;\n margin-top: 0.05em;\n margin-left: 0.05em;\n }\n `;\n};\n\nconst FLOW_USER_ID = 'flow';\n\nexport interface EventGroup {\n type: string;\n events: ContactEvent[];\n open: boolean;\n}\n\nexport enum Events {\n MESSAGE_CREATED = 'msg_created',\n MESSAGE_RECEIVED = 'msg_received',\n BROADCAST_CREATED = 'broadcast_created',\n IVR_CREATED = 'ivr_created',\n FLOW_ENTERED = 'flow_entered',\n FLOW_EXITED = 'flow_exited',\n RUN_RESULT_CHANGED = 'run_result_changed',\n CONTACT_FIELD_CHANGED = 'contact_field_changed',\n CONTACT_GROUPS_CHANGED = 'contact_groups_changed',\n CONTACT_NAME_CHANGED = 'contact_name_changed',\n CONTACT_URNS_CHANGED = 'contact_urns_changed',\n CAMPAIGN_FIRED = 'campaign_fired',\n CHANNEL_EVENT = 'channel_event',\n CONTACT_LANGUAGE_CHANGED = 'contact_language_changed',\n WEBHOOK_CALLED = 'webhook_called',\n AIRTIME_TRANSFERRED = 'airtime_transferred',\n CALL_STARTED = 'call_started',\n EMAIL_SENT = 'email_sent',\n INPUT_LABELS_ADDED = 'input_labels_added',\n NOTE_CREATED = 'note_created',\n TICKET_ASSIGNED = 'ticket_assigned',\n TICKET_NOTE_ADDED = 'ticket_note_added',\n TICKET_CLOSED = 'ticket_closed',\n TICKET_OPENED = 'ticket_opened',\n TICKET_REOPENED = 'ticket_reopened',\n ERROR = 'error',\n FAILURE = 'failure',\n}\n\nexport interface ContactEvent {\n type: string;\n created_on: string;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n msg_type: string;\n recipient_count?: number;\n created_by?: User;\n}\n\nexport interface FlowEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface EmailSentEvent extends ContactEvent {\n to: string[];\n subject: string;\n body: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n ticketer: ObjectReference;\n body: string;\n topic?: ObjectReference;\n external_id?: string;\n closed_on?: string;\n opened_on?: string;\n };\n created_by?: User;\n}\n\nexport interface LabelsAddedEvent extends ContactEvent {\n labels: ObjectReference[];\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ErrorMessageEvent extends ContactEvent {\n text: string;\n}\n\nexport interface UpdateResultEvent extends ContactEvent {\n name: string;\n value: string;\n category: string;\n input: string;\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface WebhookEvent extends ContactEvent {\n status: string;\n status_code: number;\n elapsed_ms: number;\n logs_url: string;\n url: string;\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n desired_amount: string;\n actual_amount: string;\n logs_url: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\nexport interface CampaignFiredEvent extends ContactEvent {\n campaign: { uuid: string; id: number; name: string };\n campaign_event: {\n id: number;\n offset_display: string;\n relative_to: { key: string; name: string };\n };\n fired_result: string;\n}\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n\nexport const getEventGroupType = (event: ContactEvent, ticket: string) => {\n if (!event) {\n return 'messages';\n }\n switch (event.type) {\n case Events.TICKET_ASSIGNED:\n case Events.TICKET_NOTE_ADDED:\n case Events.TICKET_OPENED:\n case Events.TICKET_CLOSED:\n case Events.TICKET_REOPENED:\n if (!ticket) {\n return 'verbose';\n }\n\n if ((event as TicketEvent).ticket.uuid === ticket) {\n return 'tickets';\n }\n\n break;\n case Events.FLOW_ENTERED:\n case Events.FLOW_EXITED:\n return 'flows';\n case Events.BROADCAST_CREATED:\n case Events.MESSAGE_CREATED:\n case Events.MESSAGE_RECEIVED:\n case Events.IVR_CREATED:\n return 'messages';\n }\n return 'verbose';\n};\n\nexport const renderUserAvatar = (user: User) => {\n return html`<div style=\"width:3.5em;font-size:0.8em\">\n ${renderAvatar({ user, position: 'left' })}\n </div>`;\n};\n\nexport const renderAttachment = (attachment: string): TemplateResult => {\n const idx = attachment.indexOf(':');\n const attType = attachment.substr(0, idx);\n const url = attachment.substr(idx + 1);\n const [mediaType, ext] = attType.split('/', 2);\n\n let inner = null;\n if (mediaType === 'image') {\n inner = html`\n <img src=\"${url}\" style=\"height:auto;width:100%;display:block;\" />\n `;\n } else if (ext === 'pdf') {\n return html`<div\n style=\"width:100%;height:300px;border-radius:calc(var(--curvature) * 2.5);box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);overflow:hidden\"\n ><embed src=\"${url}#view=Fit\" type=\"application/pdf\" frameBorder=\"0\" scrolling=\"auto\" height=\"100%\" width=\"100%\"></embed></div>`;\n } else if (mediaType === 'video') {\n return html`<video\n style=\"border-radius:var(--curvature);box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);max-width:400px\"\n height=\"auto\"\n controls\n >\n <source src=\"${url}\" type=\"video/mp4\" />\n </video> `;\n } else if (mediaType === 'audio') {\n return html`<audio\n style=\"border-radius: 99px; box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);\"\n src=\"${url}\"\n type=\"${attType}\"\n controls\n >\n <a target=\"_\" href=\"${url}\">${url}</a>\n </audio>`;\n } else if (attType === 'geo') {\n const [lat, long] = url.split(',');\n const latFloat = parseFloat(lat);\n const longFloat = parseFloat(long);\n const geo = `${lat}000000%2C${long}000000`;\n\n return html` <iframe\n style=\"border-radius: var(--curvature);box-shadow:0px 0px 12px 0px rgba(0,0,0,.1), 0px 0px 2px 0px rgba(0,0,0,.15);\"\n width=\"300\"\n height=\"300\"\n frameborder=\"0\"\n scrolling=\"no\"\n marginheight=\"0\"\n marginwidth=\"0\"\n src=\"https://www.openstreetmap.org/export/embed.html?bbox=${longFloat -\n 0.005}000000%2C${latFloat - 0.005}%2C${longFloat +\n 0.005}000000%2C${latFloat +\n 0.005}000000&amp;layer=mapnik&amp;marker=${geo}\"\n ></iframe>`;\n } else {\n return html`<div style=\"display:flex\">\n <temba-icon name=\"${Icon.download}\"></temba-icon>\n <div>Attachment ${ext}</div>\n </div>`;\n }\n\n return html`<div style=\"\">${inner}</div>`;\n};\n\nexport const renderMsgEvent = (\n event: MsgEvent,\n agent: string\n): TemplateResult => {\n const isInbound = event.type === Events.MESSAGE_RECEIVED;\n const isError = event.status === 'E';\n const isFailure = event.status === 'F';\n\n // summary items which appear under the message bubble\n const summary: TemplateResult[] = [];\n\n if (event.logs_url) {\n summary.push(html` <div class=\"icon-link\">\n <temba-icon\n onclick=\"goto(event)\"\n href=\"${event.logs_url}\"\n name=\"${Icon.log}\"\n class=\"log ${isError || isFailure ? 'error' : ''}\"\n ></temba-icon>\n </div>`);\n } else if (isError) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery error\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n } else if (isFailure) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery failure: ${event.failed_reason_display}\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n }\n if (event.recipient_count > 1) {\n summary.push(html`<temba-icon\n size=\"1\"\n class=\"broadcast\"\n name=\"${Icon.broadcast}\"\n ></temba-icon>\n <div class=\"recipients\">${event.recipient_count} contacts</div>\n <div class=\"separator\">•</div>`);\n }\n summary.push(\n html`<temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>`\n );\n\n return html`<div style=\"display:flex;align-items:flex-start\">\n <div style=\"display:flex;flex-direction:column\">\n <div\n class=\"${event.msg.text ? '' : 'no-message'} attachments-${(\n event.msg.attachments || []\n ).length} ${getClasses({\n msg: true,\n automated: !isInbound && !event.msg.created_by,\n })}\"\n >\n ${event.msg.text\n ? html` <div class=\"text\">${event.msg.text}</div> `\n : null}\n ${event.msg.attachments\n ? html`<div class=\"attachments\">\n ${event.msg.attachments.map(\n attachment =>\n html` <div class=\"attachment\">\n ${renderAttachment(attachment)}\n </div>`\n )}\n </div> `\n : null}\n </div>\n ${!event.msg.text && !event.msg.attachments\n ? html`<div class=\"unsupported\">Unsupported Message</div>`\n : null}\n\n <div\n class=\"msg-summary\"\n style=\"flex-direction:row${isInbound ? '-reverse' : ''}\"\n >\n <div style=\"flex-grow:1\"></div>\n ${summary}\n </div>\n </div>\n\n ${!isInbound\n ? html`<div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.9em\">\n ${event.msg.created_by\n ? renderUserAvatar(event.msg.created_by)\n : renderUserAvatar(null)}\n </div>`\n : null}\n </div>`;\n};\n\nexport const renderFlowEvent = (event: FlowEvent): TemplateResult => {\n let verb = 'Interrupted';\n let icon = Icon.flow_interrupted;\n\n if (event.status !== 'I') {\n if (event.type === Events.FLOW_ENTERED) {\n verb = 'Started';\n icon = Icon.flow;\n } else {\n verb = 'Completed';\n icon = Icon.flow;\n }\n }\n\n return html`\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${verb}\n <span\n class=\"linked\"\n href=\"/flow/editor/${event.flow.uuid}/\"\n onclick=\"goto(event)\"\n >\n ${event.flow.name}\n </span>\n </div>\n `;\n};\n\nexport const renderResultEvent = (event: UpdateResultEvent): TemplateResult => {\n if (event.name.startsWith('_')) {\n return null;\n }\n return html`\n <temba-icon name=\"${Icon.updated}\"></temba-icon>\n <div class=\"description\">\n Updated\n <div class=\"attn\">${event.name}</div>\n to\n <div class=\"attn\">${event.value}</div>\n ${event.category\n ? html`with category\n <div class=\"attn\">${event.category}</div>`\n : null}\n </div>\n `;\n};\n\nexport const renderUpdateEvent = (event: UpdateFieldEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n ${event.value\n ? html`Updated\n <div class=\"attn\">${event.field.name}</div>\n to\n <div class=\"attn\">${event.value.text}</div>`\n : html`Cleared\n <div class=\"attn\">${event.field.name}</div>`}\n </div>\n `;\n};\n\nexport const renderNameChanged = (event: NameChangedEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n Updated\n <div class=\"attn\">Name</div>\n to\n <div class=\"attn\">${event.name}</div>\n </div>\n `;\n};\n\nexport const renderContactURNsChanged = (\n event: URNsChangedEvent\n): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n Updated\n <div class=\"attn\">URNs</div>\n to\n ${oxfordFn(\n event.urns,\n (urn: string) =>\n html`<div class=\"attn\">${urn.split(':')[1].split('?')[0]}</div>`\n )}\n </div>\n </div>\n `;\n};\n\nexport const renderEmailSent = (event: EmailSentEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.email}\"></temba-icon>\n <div class=\"description\">\n Email sent to\n <div class=\"attn\">${oxford(event.to, 'and')}</div>\n with subject\n <div class=\"attn\">${event.subject}</div>\n </div>\n `;\n};\n\nexport const renderLabelsAdded = (event: LabelsAddedEvent): TemplateResult => {\n return html`\n <temba-icon name=\"${Icon.label}\"></temba-icon>\n <div class=\"description\">\n Message labeled with\n <div class=\"attn\">${oxfordNamed(event.labels, 'and')}</div>\n </div>\n `;\n};\n\nexport const renderNoteCreated = (event: TicketEvent): TemplateResult => {\n return html`<div style=\"display:flex;align-items:flex-start\">\n <div style=\"display:flex;flex-direction:column\">\n <div class=\"description\">${event.note}</div>\n <div class=\"note-summary\">\n <div style=\"flex-grow:1\"></div>\n <temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>\n </div>\n </div>\n <div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.8em\">\n ${renderUserAvatar(event.created_by)}\n </div>\n </div>`;\n};\n\nconst getTicketIcon = (event: TicketEvent) => {\n let icon = Icon.inbox;\n if (event.ticket.ticketer.name.indexOf('Email') > -1) {\n icon = Icon.email;\n } else if (event.ticket.ticketer.name.indexOf('Zendesk') > -1) {\n icon = Icon.zendesk;\n }\n return icon;\n};\n\nexport const renderTicketAction = (\n event: TicketEvent,\n action: string,\n grouped: boolean\n): TemplateResult => {\n const reopened = new Date(event.created_on);\n const icon = getTicketIcon(event);\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${getDisplayName(event.created_by)} ${action} a\n <span\n onclick=\"goto(event)\"\n class=\"linked\"\n href=\"/ticket/all/open/${event.ticket.uuid}\"\n >\n ticket\n </span>\n </div>\n </div>`;\n }\n\n return html`\n <div class=\"assigned active\">\n <div style=\"text-align:center\">\n ${getDisplayName(event.created_by)} ${action} this ticket\n </div>\n <div class=\"subtext\" style=\"justify-content:center\">\n <temba-date\n class=\"time\"\n value=\"${reopened}\"\n display=\"duration\"\n ></temba-date>\n </div>\n </div>\n `;\n};\n\nexport const renderTicketAssigned = (event: TicketEvent): TemplateResult => {\n return html`\n <div class=\"assigned active\">\n <div style=\"text-align:center\">\n ${event.assignee\n ? event.assignee.id === event.created_by.id\n ? html`${getDisplayName(event.created_by)} took this ticket`\n : html`${getDisplayName(event.created_by)} assigned this ticket to\n <div class=\"attn\">${getDisplayName(event.assignee)}</div>`\n : html`${getDisplayName(event.created_by)} unassigned this ticket`}\n </div>\n <div class=\"subtext\" style=\"justify-content:center\">\n <temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>\n </div>\n </div>\n `;\n};\n\nexport const renderTicketOpened = (\n event: TicketEvent,\n handleClose: (uuid: string) => void,\n grouped: boolean\n): TemplateResult => {\n const icon = getTicketIcon(event);\n\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${event.ticket.topic.name}\n <span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/ticket/all/open/${event.ticket.uuid}\"\n >ticket</span\n >\n was opened\n </div>\n </div>`;\n } else {\n return html`\n <temba-icon size=\"1.5\" name=\"${icon}\"></temba-icon>\n\n <div class=\"active\" style=\"flex-grow:1;\">\n Opened\n <div class=\"attn\">\n ${event.ticket.topic ? event.ticket.topic.name : 'General'}\n </div>\n <div class=\"subtext\">${timeSince(new Date(event.created_on))}</div>\n </div>\n ${handleClose\n ? html`\n <temba-tip text=\"Resolve\" position=\"left\" style=\"width:1.5em\">\n <temba-icon\n class=\"clickable\"\n size=\"1.5\"\n name=\"${Icon.check}\"\n @click=${() => {\n handleClose(event.ticket.uuid);\n }}\n ?clickable=${open}\n />\n </temba-tip>\n `\n : null}\n `;\n }\n};\n\nexport const renderErrorMessage = (\n event: ErrorMessageEvent\n): TemplateResult => {\n return html`\n <temba-icon\n name=\"${Icon.error}\"\n style=\"--icon-color:var(--color-error)\"\n ></temba-icon>\n <div class=\"description\">\n ${event.text}\n ${event.type === Events.FAILURE\n ? html`<div>Run ended prematurely, check the flow design.</div>`\n : null}\n </div>\n `;\n};\n\nexport const renderWebhookEvent = (event: WebhookEvent): TemplateResult => {\n return html`\n <div\n class=\"${event.status === 'success' ? '' : 'failed'}\"\n style=\"display: flex\"\n >\n <temba-icon name=\"${Icon.webhook}\"></temba-icon>\n <div class=\"description\">\n ${event.status === 'success'\n ? html`Successfully called ${event.url}`\n : html`Failed to call ${event.url}`}\n </div>\n </div>\n `;\n};\n\nexport const renderAirtimeTransferredEvent = (\n event: AirtimeTransferredEvent\n): TemplateResult => {\n if (parseFloat(event.actual_amount) === 0) {\n return html`<temba-icon\n name=\"${Icon.error}\"\n style=\"--icon-color: var(--color-error)\"\n ></temba-icon>\n <div class=\"description error\">Airtime transfer failed</div>`;\n }\n\n return html`<temba-icon name=\"${Icon.airtime}\"></temba-icon>\n <div class=\"description\">\n Transferred\n <div class=\"attn\">${event.actual_amount} ${event.currency}</div>\n of airtime\n </div>`;\n};\n\nexport const renderCallStartedEvent = (): TemplateResult => {\n return html`<temba-icon name=\"${Icon.call}\"></temba-icon>\n <div class=\"description\">Call Started</div>`;\n};\n\nexport const renderContactLanguageChangedEvent = (\n event: ContactLanguageChangedEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.contact_updated}\"></temba-icon>\n <div class=\"description\">\n Language updated to <span class=\"attn\">${event.language}</span>\n </div>`;\n};\n\nexport const renderChannelEvent = (event: ChannelEvent): TemplateResult => {\n let eventMessage = '';\n let icon = Icon.call;\n\n if (event.channel_event_type === 'mt_miss') {\n eventMessage = 'Missed outgoing call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'mo_miss') {\n eventMessage = 'Missed incoming call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'new_conversation') {\n eventMessage = 'Started Conversation';\n icon = Icon.event;\n } else if (event.channel_event_type === 'welcome_message') {\n eventMessage = 'Welcome Message Sent';\n icon = Icon.event;\n } else if (event.channel_event_type === 'referral') {\n eventMessage = 'Referred';\n icon = Icon.event;\n } else if (event.channel_event_type === 'follow') {\n eventMessage = 'Followed';\n icon = Icon.event;\n } else if (event.channel_event_type === 'stop_contact') {\n eventMessage = 'Stopped';\n icon = Icon.contact_stopped;\n } else if (event.channel_event_type === 'mt_call') {\n eventMessage = 'Outgoing Phone Call';\n } else if (event.channel_event_type == 'mo_call') {\n eventMessage = 'Incoming Phone call';\n }\n\n return html`<temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">${eventMessage}</div>`;\n};\n\nexport const renderCampaignFiredEvent = (\n event: CampaignFiredEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.campaign}\"></temba-icon>\n <div class=\"description\">\n Campaign\n <span\n class=\"linked\"\n onclick=\"goto(event, this)\"\n href=\"/campaign/read/${event.campaign.uuid}/\"\n >${event.campaign.name}</span\n >\n ${event.fired_result === 'S' ? 'skipped' : 'triggered'}\n <span\n class=\"linked\"\n onclick=\"goto(event, this)\"\n href=\"/campaignevent/read/${event.campaign.uuid}/${event.campaign_event\n .id}/\"\n >\n ${event.campaign_event.offset_display}\n ${event.campaign_event.relative_to.name}</span\n >\n </div>`;\n};\n\nexport const renderContactGroupsEvent = (\n event: ContactGroupsEvent\n): TemplateResult => {\n const groups = event.groups_added || event.groups_removed;\n const added = !!event.groups_added;\n return html`\n <temba-icon\n name=\"${Icon.users}\"\n class=\"${getClasses({ added: added, removed: !added })}\"\n ></temba-icon>\n <div class=\"description\">\n ${added ? 'Added to' : 'Removed from'}\n ${oxfordFn(\n groups,\n (group: ObjectReference) =>\n html`<span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/contact/filter/${group.uuid}\"\n >${group.name}</span\n >`\n )}\n ${event.type === Events.FAILURE\n ? html`<div>Run ended prematurely, check the flow design.</div>`\n : null}\n </div>\n `;\n};\n"]}
@@ -0,0 +1,149 @@
1
+ import { __decorate } from "tslib";
2
+ import { css, html } from 'lit';
3
+ import { property } from 'lit/decorators.js';
4
+ import { RapidElement } from '../RapidElement';
5
+ import { getClasses } from '../utils';
6
+ import { styleMap } from 'lit-html/directives/style-map.js';
7
+ /**
8
+ * This component relies on a bit of sleight of hand magic
9
+ * to achieve it's effect. As such, it requires the use of
10
+ * computed animation times and window.setTimeout().
11
+ */
12
+ export class Lightbox extends RapidElement {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.animationTime = 300;
16
+ this.show = false;
17
+ this.zoom = false;
18
+ this.zoomPct = 0.9;
19
+ this.scale = 1;
20
+ this.xTrans = '0px';
21
+ this.yTrans = '0px';
22
+ }
23
+ static get styles() {
24
+ return css `
25
+ :host {
26
+ position: absolute;
27
+ }
28
+
29
+ .mask {
30
+ display: flex;
31
+ opacity: 0;
32
+ background: rgba(0, 0, 0, 0.5);
33
+ position: absolute;
34
+ height: 100vh;
35
+ width: 100vw;
36
+ pointer-events: none;
37
+ }
38
+
39
+ .zoom .mask {
40
+ opacity: 1;
41
+ pointer-events: auto;
42
+ }
43
+
44
+ .matte {
45
+ position: absolute;
46
+ transform: translate(400, 400) scale(3, 3);
47
+ border-radius: 2%;
48
+ overflow: hidden;
49
+ box-shadow: 0 0 12px 3px rgba(0, 0, 0, 0.15);
50
+ }
51
+ `;
52
+ }
53
+ updated(changed) {
54
+ if (changed.has('show') && this.show) {
55
+ window.setTimeout(() => {
56
+ this.zoom = true;
57
+ }, 0);
58
+ }
59
+ if (changed.has('zoom') && !this.zoom && this.show) {
60
+ window.setTimeout(() => {
61
+ this.show = false;
62
+ }, this.animationTime);
63
+ }
64
+ }
65
+ showElement(ele) {
66
+ // size our matte according to the ele's boundaries
67
+ const bounds = ele.getBoundingClientRect();
68
+ this.ele = ele.cloneNode();
69
+ this.left = bounds.left;
70
+ this.top = bounds.top;
71
+ this.width = bounds.width;
72
+ this.height = bounds.height;
73
+ this.xTrans = '0px';
74
+ this.yTrans = '0px';
75
+ this.scale = 1;
76
+ let desiredWidth = this.width;
77
+ let desiredHeight = this.height;
78
+ let desiredScale = this.scale;
79
+ const maxHeight = window.innerHeight * this.zoomPct;
80
+ const maxWidth = window.innerWidth * this.zoomPct;
81
+ // if the width fits, constrain by height
82
+ if (this.width * (maxHeight / this.height) < maxWidth) {
83
+ desiredHeight = window.innerHeight * this.zoomPct;
84
+ desiredScale = desiredHeight / this.height;
85
+ desiredWidth = this.width * desiredScale;
86
+ }
87
+ else {
88
+ desiredWidth = window.innerWidth * this.zoomPct;
89
+ desiredScale = desiredWidth / this.width;
90
+ desiredHeight = this.height * desiredScale;
91
+ }
92
+ const xGrowth = (desiredWidth - this.width) / 2;
93
+ const xDest = (window.innerWidth - desiredWidth) / 2;
94
+ this.xTrans = xDest - this.left + xGrowth + 'px';
95
+ const yGrowth = (desiredHeight - this.height) / 2;
96
+ const yDest = (window.innerHeight - desiredHeight) / 2;
97
+ this.yTrans = yDest - this.top + yGrowth + 'px';
98
+ this.scale = desiredScale;
99
+ this.show = true;
100
+ }
101
+ handleClick() {
102
+ this.zoom = false;
103
+ }
104
+ render() {
105
+ const styles = {
106
+ transition: `transform ${this.animationTime}ms ease, box-shadow ${this.animationTime}ms ease`,
107
+ };
108
+ if (this.show) {
109
+ styles['left'] = this.left + 'px';
110
+ styles['top'] = this.top + 'px';
111
+ styles['width'] = this.width + 'px';
112
+ styles['height'] = this.height + 'px';
113
+ }
114
+ if (this.zoom) {
115
+ styles['transform'] = `translate(${this.xTrans}, ${this.yTrans}) scale(${this.scale}, ${this.scale})`;
116
+ }
117
+ return html `
118
+ <div
119
+ class=${getClasses({
120
+ container: true,
121
+ show: this.show,
122
+ zoom: this.zoom,
123
+ })}
124
+ @click=${this.handleClick}
125
+ >
126
+ <div
127
+ class=${getClasses({ mask: true })}
128
+ style="transition: all ${this.animationTime}ms; ease"
129
+ ></div>
130
+ <div class=${getClasses({ matte: true })} style=${styleMap(styles)}>
131
+ ${this.show ? this.ele : null}
132
+ </div>
133
+ </div>
134
+ `;
135
+ }
136
+ }
137
+ __decorate([
138
+ property({ type: Number })
139
+ ], Lightbox.prototype, "animationTime", void 0);
140
+ __decorate([
141
+ property({ type: Boolean })
142
+ ], Lightbox.prototype, "show", void 0);
143
+ __decorate([
144
+ property({ type: Boolean })
145
+ ], Lightbox.prototype, "zoom", void 0);
146
+ __decorate([
147
+ property({ type: Number })
148
+ ], Lightbox.prototype, "zoomPct", void 0);
149
+ //# sourceMappingURL=Lightbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lightbox.js","sourceRoot":"","sources":["../../../src/lightbox/Lightbox.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { styleMap } from 'lit-html/directives/style-map.js';\n\n/**\n * This component relies on a bit of sleight of hand magic\n * to achieve it's effect. As such, it requires the use of\n * computed animation times and window.setTimeout().\n */\nexport class Lightbox extends RapidElement {\n static get styles() {\n return css`\n :host {\n position: absolute;\n }\n\n .mask {\n display: flex;\n opacity: 0;\n background: rgba(0, 0, 0, 0.5);\n position: absolute;\n height: 100vh;\n width: 100vw;\n pointer-events: none;\n }\n\n .zoom .mask {\n opacity: 1;\n pointer-events: auto;\n }\n\n .matte {\n position: absolute;\n transform: translate(400, 400) scale(3, 3);\n border-radius: 2%;\n overflow: hidden;\n box-shadow: 0 0 12px 3px rgba(0, 0, 0, 0.15);\n }\n `;\n }\n\n @property({ type: Number })\n animationTime = 300;\n\n @property({ type: Boolean })\n show = false;\n\n @property({ type: Boolean })\n zoom = false;\n\n @property({ type: Number })\n zoomPct = 0.9;\n\n private ele: HTMLElement;\n private left: number;\n private top: number;\n private height: number;\n private width: number;\n private scale = 1;\n private xTrans = '0px';\n private yTrans = '0px';\n\n protected updated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n if (changed.has('show') && this.show) {\n window.setTimeout(() => {\n this.zoom = true;\n }, 0);\n }\n\n if (changed.has('zoom') && !this.zoom && this.show) {\n window.setTimeout(() => {\n this.show = false;\n }, this.animationTime);\n }\n }\n\n public showElement(ele: HTMLElement) {\n // size our matte according to the ele's boundaries\n const bounds = ele.getBoundingClientRect();\n this.ele = ele.cloneNode() as HTMLElement;\n this.left = bounds.left;\n this.top = bounds.top;\n this.width = bounds.width;\n this.height = bounds.height;\n\n this.xTrans = '0px';\n this.yTrans = '0px';\n this.scale = 1;\n\n let desiredWidth = this.width;\n let desiredHeight = this.height;\n let desiredScale = this.scale;\n\n const maxHeight = window.innerHeight * this.zoomPct;\n const maxWidth = window.innerWidth * this.zoomPct;\n\n // if the width fits, constrain by height\n if (this.width * (maxHeight / this.height) < maxWidth) {\n desiredHeight = window.innerHeight * this.zoomPct;\n desiredScale = desiredHeight / this.height;\n desiredWidth = this.width * desiredScale;\n } else {\n desiredWidth = window.innerWidth * this.zoomPct;\n desiredScale = desiredWidth / this.width;\n desiredHeight = this.height * desiredScale;\n }\n\n const xGrowth = (desiredWidth - this.width) / 2;\n const xDest = (window.innerWidth - desiredWidth) / 2;\n this.xTrans = xDest - this.left + xGrowth + 'px';\n\n const yGrowth = (desiredHeight - this.height) / 2;\n const yDest = (window.innerHeight - desiredHeight) / 2;\n this.yTrans = yDest - this.top + yGrowth + 'px';\n\n this.scale = desiredScale;\n this.show = true;\n }\n\n public handleClick() {\n this.zoom = false;\n }\n\n public render() {\n const styles = {\n transition: `transform ${this.animationTime}ms ease, box-shadow ${this.animationTime}ms ease`,\n };\n\n if (this.show) {\n styles['left'] = this.left + 'px';\n styles['top'] = this.top + 'px';\n styles['width'] = this.width + 'px';\n styles['height'] = this.height + 'px';\n }\n\n if (this.zoom) {\n styles[\n 'transform'\n ] = `translate(${this.xTrans}, ${this.yTrans}) scale(${this.scale}, ${this.scale})`;\n }\n\n return html`\n <div\n class=${getClasses({\n container: true,\n show: this.show,\n zoom: this.zoom,\n })}\n @click=${this.handleClick}\n >\n <div\n class=${getClasses({ mask: true })}\n style=\"transition: all ${this.animationTime}ms; ease\"\n ></div>\n <div class=${getClasses({ matte: true })} style=${styleMap(styles)}>\n ${this.show ? this.ele : null}\n </div>\n </div>\n `;\n }\n}\n"]}
@@ -70,10 +70,6 @@ export class ContentMenu extends RapidElement {
70
70
  .item:hover {
71
71
  color: rgb(var(--primary-rgb));
72
72
  }
73
-
74
- temba-dropdown {
75
- z-index: 20;
76
- }
77
73
  `;
78
74
  }
79
75
  fetchContentMenu() {
@@ -1 +1 @@
1
- {"version":3,"file":"ContentMenu.js","sourceRoot":"","sources":["../../../src/list/ContentMenu.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\n\nimport { RapidElement } from '../RapidElement';\nimport { getUrl, WebResponse } from '../utils';\n\nconst HEADERS = {\n 'Temba-Content-Menu': '1',\n 'Temba-Spa': '1',\n};\nexport interface ContentMenuItem {\n type: string;\n as_button: boolean;\n label: string;\n url: string;\n disabled: boolean;\n modal_id: string;\n on_submit: string;\n primary: boolean;\n title: string;\n on_click: null;\n link_class: string;\n}\n\nexport enum ContentMenuItemType {\n LINK = 'link',\n JS = 'js',\n URL_POST = 'url_post',\n MODAX = 'modax',\n DIVIDER = 'divider',\n}\n\nexport class ContentMenu extends RapidElement {\n static get styles() {\n return css`\n .container {\n --button-y: 0.4em;\n --button-x: 1em;\n display: flex;\n }\n\n .button_item,\n .primary_button_item {\n margin-left: 1rem;\n }\n\n .toggle {\n --icon-color: rgb(102, 102, 102);\n padding: 0.5rem;\n margin-left: 0.5rem;\n }\n\n .toggle:hover {\n background: rgba(0, 0, 0, 0.05);\n border-radius: var(--curvature);\n --icon-color: rgb(136, 136, 136);\n }\n\n .dropdown {\n padding: 1rem 1.5rem;\n color: rgb(45, 45, 45);\n z-index: 50;\n min-width: 200px;\n }\n\n .divider {\n border-bottom: 1px solid rgb(237, 237, 237);\n margin: 1rem -1.5em;\n }\n\n .item {\n white-space: nowrap;\n margin: 0.2em 0em;\n font-size: 1.1rem;\n cursor: pointer;\n font-weight: 400;\n }\n\n .item:hover {\n color: rgb(var(--primary-rgb));\n }\n\n temba-dropdown {\n z-index: 20;\n }\n `;\n }\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Number })\n legacy: number;\n\n @property({ type: Array, attribute: false })\n buttons: ContentMenuItem[] = [];\n\n @property({ type: Array, attribute: false })\n items: ContentMenuItem[] = [];\n\n private fetchContentMenu() {\n const url = this.endpoint;\n if (url) {\n const legacy = this.legacy;\n const headers = HEADERS;\n if (legacy) {\n delete headers['Temba-Spa'];\n }\n\n //ok, fetch the content menu\n getUrl(url, null, headers)\n .then((response: WebResponse) => {\n const json = response.json;\n const contentMenu = json.items as ContentMenuItem[];\n\n //populate (or initialize) the buttons and items\n if (contentMenu) {\n this.buttons = contentMenu.filter(item => item.as_button);\n this.items = contentMenu.filter(item => !item.as_button);\n } else {\n this.buttons = [];\n this.items = [];\n }\n\n //fire custom loaded event type when we're finished\n this.fireCustomEvent(CustomEventType.Loaded, {\n buttons: this.buttons,\n items: this.items,\n });\n })\n .catch((error: any) => {\n console.error(error);\n });\n }\n }\n\n public refresh() {\n this.fetchContentMenu();\n }\n\n protected updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('endpoint') || changes.has('legacy')) {\n this.fetchContentMenu();\n }\n }\n\n private handleItemClicked(item: ContentMenuItem) {\n this.fireCustomEvent(CustomEventType.Selection, item);\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"container\">\n ${this.buttons.map(button => {\n return html`<temba-button\n class=\"${button.primary ? 'primary_button_item' : 'button_item'}\"\n name=${button.label}\n @click=${() => this.handleItemClicked(button)}\n >\n ${button.label}\n </temba-button>`;\n })}\n ${this.items && this.items.length > 0\n ? html` <temba-dropdown\n arrowsize=\"8\"\n arrowoffset=\"-12\"\n offsetx=\"-200\"\n offsety=\"6\"\n >\n <div slot=\"toggle\" class=\"toggle\">\n <temba-icon name=\"menu\" size=\"1.5\"></temba-icon>\n </div>\n <div slot=\"dropdown\" class=\"dropdown\">\n ${this.items.map(item => {\n if (item.type === ContentMenuItemType.DIVIDER) {\n return html` <div class=\"divider\"></div>`;\n } else {\n return html` <div\n class=\"item\"\n name=${item.label}\n @click=${() => this.handleItemClicked(item)}\n >\n ${item.label}\n </div>`;\n }\n })}\n </div>\n </temba-dropdown>`\n : null}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"ContentMenu.js","sourceRoot":"","sources":["../../../src/list/ContentMenu.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\n\nimport { RapidElement } from '../RapidElement';\nimport { getUrl, WebResponse } from '../utils';\n\nconst HEADERS = {\n 'Temba-Content-Menu': '1',\n 'Temba-Spa': '1',\n};\nexport interface ContentMenuItem {\n type: string;\n as_button: boolean;\n label: string;\n url: string;\n disabled: boolean;\n modal_id: string;\n on_submit: string;\n primary: boolean;\n title: string;\n on_click: null;\n link_class: string;\n}\n\nexport enum ContentMenuItemType {\n LINK = 'link',\n JS = 'js',\n URL_POST = 'url_post',\n MODAX = 'modax',\n DIVIDER = 'divider',\n}\n\nexport class ContentMenu extends RapidElement {\n static get styles() {\n return css`\n .container {\n --button-y: 0.4em;\n --button-x: 1em;\n display: flex;\n }\n\n .button_item,\n .primary_button_item {\n margin-left: 1rem;\n }\n\n .toggle {\n --icon-color: rgb(102, 102, 102);\n padding: 0.5rem;\n margin-left: 0.5rem;\n }\n\n .toggle:hover {\n background: rgba(0, 0, 0, 0.05);\n border-radius: var(--curvature);\n --icon-color: rgb(136, 136, 136);\n }\n\n .dropdown {\n padding: 1rem 1.5rem;\n color: rgb(45, 45, 45);\n z-index: 50;\n min-width: 200px;\n }\n\n .divider {\n border-bottom: 1px solid rgb(237, 237, 237);\n margin: 1rem -1.5em;\n }\n\n .item {\n white-space: nowrap;\n margin: 0.2em 0em;\n font-size: 1.1rem;\n cursor: pointer;\n font-weight: 400;\n }\n\n .item:hover {\n color: rgb(var(--primary-rgb));\n }\n `;\n }\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Number })\n legacy: number;\n\n @property({ type: Array, attribute: false })\n buttons: ContentMenuItem[] = [];\n\n @property({ type: Array, attribute: false })\n items: ContentMenuItem[] = [];\n\n private fetchContentMenu() {\n const url = this.endpoint;\n if (url) {\n const legacy = this.legacy;\n const headers = HEADERS;\n if (legacy) {\n delete headers['Temba-Spa'];\n }\n\n //ok, fetch the content menu\n getUrl(url, null, headers)\n .then((response: WebResponse) => {\n const json = response.json;\n const contentMenu = json.items as ContentMenuItem[];\n\n //populate (or initialize) the buttons and items\n if (contentMenu) {\n this.buttons = contentMenu.filter(item => item.as_button);\n this.items = contentMenu.filter(item => !item.as_button);\n } else {\n this.buttons = [];\n this.items = [];\n }\n\n //fire custom loaded event type when we're finished\n this.fireCustomEvent(CustomEventType.Loaded, {\n buttons: this.buttons,\n items: this.items,\n });\n })\n .catch((error: any) => {\n console.error(error);\n });\n }\n }\n\n public refresh() {\n this.fetchContentMenu();\n }\n\n protected updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('endpoint') || changes.has('legacy')) {\n this.fetchContentMenu();\n }\n }\n\n private handleItemClicked(item: ContentMenuItem) {\n this.fireCustomEvent(CustomEventType.Selection, item);\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"container\">\n ${this.buttons.map(button => {\n return html`<temba-button\n class=\"${button.primary ? 'primary_button_item' : 'button_item'}\"\n name=${button.label}\n @click=${() => this.handleItemClicked(button)}\n >\n ${button.label}\n </temba-button>`;\n })}\n ${this.items && this.items.length > 0\n ? html` <temba-dropdown\n arrowsize=\"8\"\n arrowoffset=\"-12\"\n offsetx=\"-200\"\n offsety=\"6\"\n >\n <div slot=\"toggle\" class=\"toggle\">\n <temba-icon name=\"menu\" size=\"1.5\"></temba-icon>\n </div>\n <div slot=\"dropdown\" class=\"dropdown\">\n ${this.items.map(item => {\n if (item.type === ContentMenuItemType.DIVIDER) {\n return html` <div class=\"divider\"></div>`;\n } else {\n return html` <div\n class=\"item\"\n name=${item.label}\n @click=${() => this.handleItemClicked(item)}\n >\n ${item.label}\n </div>`;\n }\n })}\n </div>\n </temba-dropdown>`\n : null}\n </div>\n `;\n }\n}\n"]}
@@ -3,9 +3,8 @@ import { css, html } from 'lit';
3
3
  import { property } from 'lit/decorators.js';
4
4
  import { CustomEventType } from '../interfaces';
5
5
  import { RapidElement } from '../RapidElement';
6
- import { debounce, fetchResults, getClasses } from '../utils';
6
+ import { debounce, fetchResults, getClasses, renderAvatar } from '../utils';
7
7
  import { Icon } from '../vectoricon';
8
- import ColorHash from 'color-hash';
9
8
  const findItem = (items, id) => {
10
9
  const search = items || [];
11
10
  const index = search.findIndex((item) => {
@@ -131,19 +130,6 @@ export class TembaMenu extends RapidElement {
131
130
  align-items: center;
132
131
  }
133
132
 
134
- .avatar-circle {
135
- box-shadow: 0 0 0px 3px rgba(0, 0, 0, 0.075);
136
- display: flex;
137
- margin: 0.4em 0em;
138
- height: 2em;
139
- width: 2em;
140
- flex-direction: row;
141
- align-items: center;
142
- color: #fff;
143
- border-radius: 100%;
144
- font-weight: 400;
145
- }
146
-
147
133
  temba-dropdown > div[slot='dropdown'] .avatar .avatar-circle {
148
134
  font-size: 0.7em;
149
135
  }
@@ -505,7 +491,7 @@ export class TembaMenu extends RapidElement {
505
491
  pressed: this.pressedItem && this.pressedItem.id == menuItem.id,
506
492
  });
507
493
  if (menuItem.avatar) {
508
- icon = this.renderAvatar(menuItem.avatar);
494
+ icon = renderAvatar({ name: menuItem.avatar });
509
495
  }
510
496
  const item = html ` <div
511
497
  class="item-top ${isSelected ? 'selected' : null} "
@@ -848,32 +834,6 @@ export class TembaMenu extends RapidElement {
848
834
  const expanded = !!this.selection.find(id => id === menuItem.vanity_id || menuItem.id);
849
835
  return expanded;
850
836
  }
851
- renderAvatar(avatar) {
852
- const hash = new ColorHash();
853
- const color = hash.hex(avatar);
854
- let second = avatar.indexOf(' ') + 1;
855
- if (second < 1) {
856
- second = avatar.length > 1 ? 1 : 0;
857
- }
858
- let name = avatar.substring(0, 1) + avatar.substring(second, second + 1);
859
- name = name.toUpperCase();
860
- return html `
861
- <div
862
- style="border: 0px solid red; display:flex; flex-direction: column; align-items:center;"
863
- >
864
- <div
865
- class="avatar-circle"
866
- style="border: 0px solid rgba(0,0,0,.1);background:${color}"
867
- >
868
- <div
869
- style="border: 0px solid red; display:flex; flex-direction: column; align-items:center;flex-grow:1"
870
- >
871
- <div style="border:0px solid blue;">${name}</div>
872
- </div>
873
- </div>
874
- </div>
875
- `;
876
- }
877
837
  render() {
878
838
  if (!this.root || !this.root.items) {
879
839
  return html `<temba-loading