@nyaruka/temba-components 0.66.0 → 0.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/{6b3d6099.js → cec7ed95.js} +134 -62
- package/dist/index.js +134 -62
- package/dist/static/svg/index.svg +1 -1
- package/dist/sw.js +1 -1
- package/dist/sw.js.map +1 -1
- package/dist/templates/components-body.html +1 -1
- package/dist/templates/components-head.html +1 -1
- package/out-tsc/src/compose/Compose.js +1 -1
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +9 -1
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactTickets.js +1 -1
- package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
- package/out-tsc/src/contacts/events.js +0 -1
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/dropdown/Dropdown.js +45 -8
- package/out-tsc/src/dropdown/Dropdown.js.map +1 -1
- package/out-tsc/src/list/NotificationList.js +133 -0
- package/out-tsc/src/list/NotificationList.js.map +1 -0
- package/out-tsc/src/list/TembaList.js +8 -0
- package/out-tsc/src/list/TembaList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +44 -11
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/options/Options.js +47 -25
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/select/Select.js +8 -8
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +1 -0
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +5 -2
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/out-tsc/temba-modules.js +2 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/compose/chatbox-attachments-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-no-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-no-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-no-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-no-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-failure-files.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-spaces.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-url.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-no-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-failure-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-no-spaces.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text.png +0 -0
- package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
- package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
- package/screenshots/truth/contacts/contact-active-default.png +0 -0
- package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
- package/src/compose/Compose.ts +1 -1
- package/src/contacts/ContactChat.ts +9 -1
- package/src/contacts/ContactTickets.ts +1 -1
- package/src/contacts/events.ts +0 -1
- package/src/dropdown/Dropdown.ts +48 -10
- package/src/list/NotificationList.ts +154 -0
- package/src/list/TembaList.ts +9 -1
- package/src/list/TembaMenu.ts +48 -11
- package/src/list/TicketList.ts +0 -1
- package/src/options/Options.ts +49 -27
- package/src/select/Select.ts +10 -8
- package/src/textinput/TextInput.ts +1 -0
- package/src/vectoricon/index.ts +5 -2
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/users-down.svg +1 -0
- package/static/svg/work/traced/users-up.svg +1 -0
- package/static/svg/work/used/users-down.svg +3 -0
- package/static/svg/work/used/users-up.svg +3 -0
- package/temba-modules.ts +2 -0
- package/screenshots/truth/contacts/details.png +0 -0
- package/screenshots/truth/contacts/fields-updated.png +0 -0
- package/screenshots/truth/contacts/fields.png +0 -0
- package/static/svg/work/traced/volume-min.svg +0 -1
- package/static/svg/work/used/volume-min.svg +0 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/contacts/events.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, EventPart, html, TemplateResult } from 'lit';\nimport { Msg, ObjectReference, User } from '../interfaces';\nimport {\n getClasses,\n NamedObject,\n oxford,\n oxfordFn,\n oxfordNamed,\n renderAvatar,\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 max-width: 100%;\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 .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 .queued {\n opacity: 0.3;\n }\n\n .optin_requested {\n --icon-color: var(--color-primary-dark);\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 .ticket_note_added {\n max-width: 300px;\n }\n\n .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 .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 font-weight: 400;\n color: rgba(0, 0, 0, 0.6);\n border-radius: calc(var(--curvature) * 2.5);\n }\n\n .channel_event {\n --icon-color: rgb(200, 200, 200);\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_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 }\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 .optin {\n align-items: center;\n padding: 0 0.2em;\n }\n\n .time {\n padding: 0.3em 1px;\n }\n\n .subtext .time {\n padding: 0em;\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 word-break: break-all;\n white-space: break-spaces;\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\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 OPTIN_REQUESTED = 'optin_requested',\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 event: {\n type: string;\n channel: { uuid: string; name: string };\n duration?: number;\n optin?: {\n uuid: string;\n name: string;\n };\n };\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface OptinRequestedEvent extends ContactEvent {\n optin: {\n uuid: string;\n name: string;\n };\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 optin?: ObjectReference;\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 body: string;\n topic?: ObjectReference;\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\n switch (event.type) {\n case Events.TICKET_ASSIGNED:\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 case Events.TICKET_NOTE_ADDED:\n case Events.NOTE_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&layer=mapnik&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\n if (event.type == 'broadcast_created') {\n summary.push(html`<temba-icon\n size=\"1\"\n class=\"broadcast\"\n name=\"${Icon.broadcast}\"\n ></temba-icon>`);\n\n if (event.recipient_count > 1) {\n summary.push(\n html`<div class=\"recipients\">${event.recipient_count} contacts</div>`\n );\n }\n summary.push(html`<div class=\"separator\">•</div>`);\n }\n\n if (event.optin) {\n summary.push(\n html`<div class=\"optin\">${event.optin.name}</div>\n <div class=\"separator\">•</div>`\n );\n }\n\n if (event.status === 'Q') {\n summary.push(html`<div>Queued</div>`);\n }\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\n style=\"display:flex;align-items:flex-start\"\n class=${getClasses({ queued: event.status === 'Q' })}\n >\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.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\n ${!event.msg.text && !event.msg.attachments && !event.optin\n ? html`<div class=\"unsupported\">Unsupported Message</div>`\n : null}\n\n <div\n class=\"msg-summary\"\n style=\"align-items:center;flex-direction:row${isInbound\n ? '-reverse'\n : ''}\"\n >\n <div style=\"flex-grow:1\"></div>\n ${summary}\n </div>\n </div>\n\n ${!isInbound && event.created_by\n ? html`<div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.9em\">\n ${renderUserAvatar(event.created_by)}\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\nexport const renderTicketAction = (\n event: TicketEvent,\n action: string,\n grouped: boolean\n): TemplateResult => {\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${Icon.inbox}\"></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 ${event.created_by\n ? html` ${getDisplayName(event.created_by)} ${action} this ticket `\n : html` This ticket was ${action} `}\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 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 if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${Icon.inbox}\"></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 <div>\n <div style=\"text-align:center\">\n ${getDisplayName(event.created_by)} opened 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};\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 renderOptinRequested = (\n event: OptinRequestedEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.optin_requested}\"></temba-icon>\n <div class=\"description\">\n Requested opt-in for <span class=\"attn\">${event.optin.name}</span>\n </div>`;\n};\n\nexport const renderChannelEvent = (event: ChannelEvent): TemplateResult => {\n let eventMessage: string | TemplateResult = '';\n let icon = Icon.call;\n\n if (event.event.type === 'mt_miss') {\n eventMessage = 'Missed outgoing call';\n icon = Icon.call_missed;\n } else if (event.event.type === 'mo_miss') {\n eventMessage = 'Missed incoming call';\n icon = Icon.call_missed;\n } else if (event.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.event.type === 'referral') {\n eventMessage = 'Referred';\n icon = Icon.event;\n } else if (event.event.type === 'follow') {\n eventMessage = 'Followed';\n icon = Icon.event;\n } else if (event.event.type === 'stop_contact') {\n eventMessage = 'Stopped';\n icon = Icon.contact_stopped;\n } else if (event.event.type === 'mt_call') {\n eventMessage = 'Outgoing Phone Call';\n } else if (event.event.type == 'mo_call') {\n eventMessage = 'Incoming Phone call';\n } else if (event.event.type == 'optin') {\n eventMessage = html`Opted in to\n <span class=\"attn\">${event.event.optin?.name}</span>`;\n icon = Icon.optin;\n } else if (event.event.type == 'optout') {\n eventMessage = html`Opted out of\n <span class=\"attn\">${event.event.optin?.name}</span>`;\n icon = Icon.optout;\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"]}
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/contacts/events.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, EventPart, html, TemplateResult } from 'lit';\nimport { Msg, ObjectReference, User } from '../interfaces';\nimport {\n getClasses,\n NamedObject,\n oxford,\n oxfordFn,\n oxfordNamed,\n renderAvatar,\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 max-width: 100%;\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 }\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 .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 .queued {\n opacity: 0.3;\n }\n\n .optin_requested {\n --icon-color: var(--color-primary-dark);\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 .ticket_note_added {\n max-width: 300px;\n }\n\n .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 .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 font-weight: 400;\n color: rgba(0, 0, 0, 0.6);\n border-radius: calc(var(--curvature) * 2.5);\n }\n\n .channel_event {\n --icon-color: rgb(200, 200, 200);\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_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 }\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 .optin {\n align-items: center;\n padding: 0 0.2em;\n }\n\n .time {\n padding: 0.3em 1px;\n }\n\n .subtext .time {\n padding: 0em;\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 word-break: break-all;\n white-space: break-spaces;\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\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 OPTIN_REQUESTED = 'optin_requested',\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 event: {\n type: string;\n channel: { uuid: string; name: string };\n duration?: number;\n optin?: {\n uuid: string;\n name: string;\n };\n };\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface OptinRequestedEvent extends ContactEvent {\n optin: {\n uuid: string;\n name: string;\n };\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 optin?: ObjectReference;\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 body: string;\n topic?: ObjectReference;\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\n switch (event.type) {\n case Events.TICKET_ASSIGNED:\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 case Events.TICKET_NOTE_ADDED:\n case Events.NOTE_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&layer=mapnik&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\n if (event.type == 'broadcast_created') {\n summary.push(html`<temba-icon\n size=\"1\"\n class=\"broadcast\"\n name=\"${Icon.broadcast}\"\n ></temba-icon>`);\n\n if (event.recipient_count > 1) {\n summary.push(\n html`<div class=\"recipients\">${event.recipient_count} contacts</div>`\n );\n }\n summary.push(html`<div class=\"separator\">•</div>`);\n }\n\n if (event.optin) {\n summary.push(\n html`<div class=\"optin\">${event.optin.name}</div>\n <div class=\"separator\">•</div>`\n );\n }\n\n if (event.status === 'Q') {\n summary.push(html`<div>Queued</div>`);\n }\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\n style=\"display:flex;align-items:flex-start\"\n class=${getClasses({ queued: event.status === 'Q' })}\n >\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.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\n ${!event.msg.text && !event.msg.attachments && !event.optin\n ? html`<div class=\"unsupported\">Unsupported Message</div>`\n : null}\n\n <div\n class=\"msg-summary\"\n style=\"align-items:center;flex-direction:row${isInbound\n ? '-reverse'\n : ''}\"\n >\n <div style=\"flex-grow:1\"></div>\n ${summary}\n </div>\n </div>\n\n ${!isInbound && event.created_by\n ? html`<div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.9em\">\n ${renderUserAvatar(event.created_by)}\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\nexport const renderTicketAction = (\n event: TicketEvent,\n action: string,\n grouped: boolean\n): TemplateResult => {\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${Icon.inbox}\"></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 ${event.created_by\n ? html` ${getDisplayName(event.created_by)} ${action} this ticket `\n : html` This ticket was ${action} `}\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 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 if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${Icon.inbox}\"></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 <div>\n <div style=\"text-align:center\">\n ${getDisplayName(event.created_by)} opened 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};\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 renderOptinRequested = (\n event: OptinRequestedEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.optin_requested}\"></temba-icon>\n <div class=\"description\">\n Requested opt-in for <span class=\"attn\">${event.optin.name}</span>\n </div>`;\n};\n\nexport const renderChannelEvent = (event: ChannelEvent): TemplateResult => {\n let eventMessage: string | TemplateResult = '';\n let icon = Icon.call;\n\n if (event.event.type === 'mt_miss') {\n eventMessage = 'Missed outgoing call';\n icon = Icon.call_missed;\n } else if (event.event.type === 'mo_miss') {\n eventMessage = 'Missed incoming call';\n icon = Icon.call_missed;\n } else if (event.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.event.type === 'referral') {\n eventMessage = 'Referred';\n icon = Icon.event;\n } else if (event.event.type === 'follow') {\n eventMessage = 'Followed';\n icon = Icon.event;\n } else if (event.event.type === 'stop_contact') {\n eventMessage = 'Stopped';\n icon = Icon.contact_stopped;\n } else if (event.event.type === 'mt_call') {\n eventMessage = 'Outgoing Phone Call';\n } else if (event.event.type == 'mo_call') {\n eventMessage = 'Incoming Phone call';\n } else if (event.event.type == 'optin') {\n eventMessage = html`Opted in to\n <span class=\"attn\">${event.event.optin?.name}</span>`;\n icon = Icon.optin;\n } else if (event.event.type == 'optout') {\n eventMessage = html`Opted out of\n <span class=\"attn\">${event.event.optin?.name}</span>`;\n icon = Icon.optout;\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"]}
|
|
@@ -2,11 +2,15 @@ import { __decorate } from "tslib";
|
|
|
2
2
|
import { css, html } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
4
|
import { RapidElement } from '../RapidElement';
|
|
5
|
+
import { getClasses } from '../utils';
|
|
5
6
|
export class Dropdown extends RapidElement {
|
|
6
7
|
constructor() {
|
|
7
8
|
super(...arguments);
|
|
8
9
|
this.open = false;
|
|
9
|
-
this.
|
|
10
|
+
this.top = false;
|
|
11
|
+
this.bottom = false;
|
|
12
|
+
this.left = false;
|
|
13
|
+
this.right = false;
|
|
10
14
|
this.arrowSize = 6;
|
|
11
15
|
this.arrowOffset = this.arrowSize * 2;
|
|
12
16
|
this.offsetX = 0;
|
|
@@ -76,12 +80,17 @@ export class Dropdown extends RapidElement {
|
|
|
76
80
|
opacity: 0;
|
|
77
81
|
transition: opacity var(--transition-speed) ease-in-out;
|
|
78
82
|
pointer-events: none;
|
|
83
|
+
z-index: 1;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
.mask.open {
|
|
82
87
|
opacity: 1;
|
|
83
88
|
pointer-events: auto;
|
|
84
89
|
}
|
|
90
|
+
|
|
91
|
+
.right {
|
|
92
|
+
right: 0;
|
|
93
|
+
}
|
|
85
94
|
`;
|
|
86
95
|
}
|
|
87
96
|
firstUpdated(props) {
|
|
@@ -96,7 +105,7 @@ export class Dropdown extends RapidElement {
|
|
|
96
105
|
arrow.style.left = this.arrowOffset + 'px';
|
|
97
106
|
}
|
|
98
107
|
const dropdown = this.shadowRoot.querySelector('.dropdown');
|
|
99
|
-
dropdown.addEventListener('blur', (
|
|
108
|
+
dropdown.addEventListener('blur', () => {
|
|
100
109
|
// we nest this to deal with clicking the toggle to close
|
|
101
110
|
// as we don't want it to toggle an immediate open, probably
|
|
102
111
|
// a better way to deal with this
|
|
@@ -109,15 +118,15 @@ export class Dropdown extends RapidElement {
|
|
|
109
118
|
}
|
|
110
119
|
updated(changedProperties) {
|
|
111
120
|
super.updated(changedProperties);
|
|
121
|
+
const dropdown = this.shadowRoot.querySelector('.dropdown');
|
|
112
122
|
if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {
|
|
113
|
-
const dropdown = this.shadowRoot.querySelector('.dropdown');
|
|
114
123
|
dropdown.style.marginTop = this.offsetY + 'px';
|
|
115
124
|
if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
|
|
116
125
|
dropdown.style.marginLeft =
|
|
117
126
|
'-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
|
|
118
127
|
}
|
|
119
128
|
else {
|
|
120
|
-
if (this.
|
|
129
|
+
if (this.right) {
|
|
121
130
|
dropdown.style.marginRight = this.offsetX + 'px';
|
|
122
131
|
}
|
|
123
132
|
else {
|
|
@@ -132,8 +141,22 @@ export class Dropdown extends RapidElement {
|
|
|
132
141
|
else {
|
|
133
142
|
this.classList.remove('open');
|
|
134
143
|
}
|
|
144
|
+
this.ensureOnScreen();
|
|
135
145
|
}
|
|
136
146
|
}
|
|
147
|
+
ensureOnScreen() {
|
|
148
|
+
window.setTimeout(() => {
|
|
149
|
+
const dropdown = this.shadowRoot.querySelector('.dropdown');
|
|
150
|
+
if (dropdown) {
|
|
151
|
+
// dropdown will go off the screen, let's push it up
|
|
152
|
+
if (dropdown.getBoundingClientRect().bottom > window.innerHeight) {
|
|
153
|
+
const toggle = this.querySelector('div[slot="toggle"]');
|
|
154
|
+
dropdown.style.bottom =
|
|
155
|
+
this.offsetY + toggle.clientHeight + 10 + 'px';
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}, 100);
|
|
159
|
+
}
|
|
137
160
|
handleToggleClicked(event) {
|
|
138
161
|
event.preventDefault();
|
|
139
162
|
event.stopPropagation();
|
|
@@ -161,10 +184,15 @@ export class Dropdown extends RapidElement {
|
|
|
161
184
|
@click=${this.handleToggleClicked}
|
|
162
185
|
></slot>
|
|
163
186
|
<div
|
|
164
|
-
class="
|
|
187
|
+
class="${getClasses({
|
|
188
|
+
dropdown: true,
|
|
189
|
+
right: this.right,
|
|
190
|
+
left: this.left,
|
|
191
|
+
top: this.top,
|
|
192
|
+
bottom: this.bottom,
|
|
193
|
+
})}"
|
|
165
194
|
tabindex="0"
|
|
166
195
|
@mousedown=${this.handleDropdownMouseDown}
|
|
167
|
-
style="${this.dropAlign == 'right' ? 'right:0' : ''}"
|
|
168
196
|
>
|
|
169
197
|
<div class="arrow"></div>
|
|
170
198
|
<div class="dropdown-wrapper">
|
|
@@ -179,8 +207,17 @@ __decorate([
|
|
|
179
207
|
property({ type: Boolean })
|
|
180
208
|
], Dropdown.prototype, "open", void 0);
|
|
181
209
|
__decorate([
|
|
182
|
-
property({ type:
|
|
183
|
-
], Dropdown.prototype, "
|
|
210
|
+
property({ type: Boolean })
|
|
211
|
+
], Dropdown.prototype, "top", void 0);
|
|
212
|
+
__decorate([
|
|
213
|
+
property({ type: Boolean })
|
|
214
|
+
], Dropdown.prototype, "bottom", void 0);
|
|
215
|
+
__decorate([
|
|
216
|
+
property({ type: Boolean })
|
|
217
|
+
], Dropdown.prototype, "left", void 0);
|
|
218
|
+
__decorate([
|
|
219
|
+
property({ type: Boolean })
|
|
220
|
+
], Dropdown.prototype, "right", void 0);
|
|
184
221
|
__decorate([
|
|
185
222
|
property({ type: Number })
|
|
186
223
|
], Dropdown.prototype, "arrowSize", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.js","sourceRoot":"","sources":["../../../src/dropdown/Dropdown.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,OAAO,QAAS,SAAQ,YAAY;IAA1C;;QA0EE,SAAI,GAAG,KAAK,CAAC;QAGb,cAAS,GAAG,MAAM,CAAC;QAGnB,cAAS,GAAG,CAAC,CAAC;QAGd,gBAAW,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAGjC,YAAO,GAAG,CAAC,CAAC;QAGZ,YAAO,GAAG,CAAC,CAAC;QAGZ,SAAI,GAAG,KAAK,CAAC;IA0Gf,CAAC;IArMC,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoET,CAAC;IACJ,CAAC;IAuBM,YAAY,CAAC,KAAU;QAC5B,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAmB,CAAC;QACxE,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAChD,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAE9C,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE;YACxB,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;SACvD;aAAM;YACL,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;SAC5C;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAC5C,WAAW,CACM,CAAC;QAEpB,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,KAAU,EAAE,EAAE;YAC/C,yDAAyD;YACzD,4DAA4D;YAC5D,iCAAiC;YACjC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBACrB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;gBAClB,4BAA4B;gBAC3B,IAAI,CAAC,UAAU,CAAC,IAAuB,CAAC,IAAI,EAAE,CAAC;YAClD,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAEjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAC5C,WAAW,CACM,CAAC;YAEpB,QAAQ,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAC/C,IAAI,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE;gBAClE,QAAQ,CAAC,KAAK,CAAC,UAAU;oBACvB,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;aACzE;iBAAM;gBACL,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO,EAAE;oBAC9B,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;iBAClD;qBAAM;oBACL,QAAQ,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;iBACjD;aACF;SACF;QAED,IAAI,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YACjC,IAAI,IAAI,CAAC,IAAI,EAAE;gBACb,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;aAC5B;iBAAM;gBACL,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;aAC/B;SACF;IACH,CAAC;IAEM,mBAAmB,CAAC,KAAiB;QAC1C,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAC5C,WAAW,CACM,CAAC;YACpB,QAAQ,CAAC,KAAK,EAAE,CAAC;SAClB;IACH,CAAC;IAEO,uBAAuB,CAAC,KAAiB;QAC/C,4EAA4E;QAC5E,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;IAC1B,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,IAAI;YACT,CAAC,CAAC,IAAI,CAAA,qBAAqB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM;YACxD,CAAC,CAAC,IAAI;;4BAEc,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;;;;mBAIhC,IAAI,CAAC,mBAAmB;;;;;uBAKpB,IAAI,CAAC,uBAAuB;mBAChC,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;;;;;;;;KAQxD,CAAC;IACJ,CAAC;CACF;AA5HC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;sCACf;AAGb;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;2CACjC;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACb;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6CACM;AAGjC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yCACf;AAGZ;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yCACf;AAGZ;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;sCACf","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\n\nexport class Dropdown extends RapidElement {\n static get styles() {\n return css`\n .wrapper {\n position: relative;\n }\n\n .toggle {\n cursor: pointer;\n }\n\n .dropdown-wrapper {\n position: relative;\n overflow: auto;\n }\n\n .dropdown {\n position: absolute;\n opacity: 0;\n z-index: 2;\n pointer-events: none;\n padding: 0;\n border-radius: var(--curvature);\n background: #fff;\n transform: translateY(1em) scale(0.9);\n transition: all calc(0.8 * var(--transition-speed)) var(--bounce);\n user-select: none;\n margin-top: 0px;\n margin-left: 0px;\n box-shadow: var(--dropdown-shadow);\n }\n\n .dropdown:focus {\n outline: none;\n }\n\n .arrow {\n content: '';\n width: 0px;\n height: 0;\n top: -6px;\n z-index: 10;\n position: absolute;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid white;\n }\n\n .open .dropdown {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0.5em) scale(1);\n }\n\n .mask {\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n opacity: 0;\n transition: opacity var(--transition-speed) ease-in-out;\n pointer-events: none;\n }\n\n .mask.open {\n opacity: 1;\n pointer-events: auto;\n }\n `;\n }\n\n @property({ type: Boolean })\n open = false;\n\n @property({ type: String, attribute: 'drop_align' })\n dropAlign = 'left';\n\n @property({ type: Number })\n arrowSize = 6;\n\n @property({ type: Number })\n arrowOffset = this.arrowSize * 2;\n\n @property({ type: Number })\n offsetX = 0;\n\n @property({ type: Number })\n offsetY = 0;\n\n @property({ type: Boolean })\n mask = false;\n\n public firstUpdated(props: any) {\n super.firstUpdated(props);\n\n const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;\n arrow.style.borderWidth = this.arrowSize + 'px';\n arrow.style.top = '-' + this.arrowSize + 'px';\n\n if (this.arrowOffset < 0) {\n arrow.style.right = Math.abs(this.arrowOffset) + 'px';\n } else {\n arrow.style.left = this.arrowOffset + 'px';\n }\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n dropdown.addEventListener('blur', (event: any) => {\n // we nest this to deal with clicking the toggle to close\n // as we don't want it to toggle an immediate open, probably\n // a better way to deal with this\n window.setTimeout(() => {\n this.open = false;\n // blur our host element too\n (this.shadowRoot.host as HTMLDivElement).blur();\n }, 200);\n });\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n dropdown.style.marginTop = this.offsetY + 'px';\n if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {\n dropdown.style.marginLeft =\n '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';\n } else {\n if (this.dropAlign === 'right') {\n dropdown.style.marginRight = this.offsetX + 'px';\n } else {\n dropdown.style.marginLeft = this.offsetX + 'px';\n }\n }\n }\n\n if (changedProperties.has('open')) {\n if (this.open) {\n this.classList.add('open');\n } else {\n this.classList.remove('open');\n }\n }\n }\n\n public handleToggleClicked(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n if (!this.open) {\n this.open = true;\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n dropdown.focus();\n }\n }\n\n private handleDropdownMouseDown(event: MouseEvent): void {\n // block mouse down when clicking inside dropdown so we don't lose focus yet\n event.preventDefault();\n event.stopPropagation();\n }\n\n public render(): TemplateResult {\n return html`\n ${this.mask\n ? html`<div class=\"mask ${this.open ? 'open' : ''}\" />`\n : null}\n\n <div class=\"wrapper ${this.open ? 'open' : ''}\">\n <slot\n name=\"toggle\"\n class=\"toggle\"\n @click=${this.handleToggleClicked}\n ></slot>\n <div\n class=\"dropdown\"\n tabindex=\"0\"\n @mousedown=${this.handleDropdownMouseDown}\n style=\"${this.dropAlign == 'right' ? 'right:0' : ''}\"\n >\n <div class=\"arrow\"></div>\n <div class=\"dropdown-wrapper\">\n <slot name=\"dropdown\" tabindex=\"1\"></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Dropdown.js","sourceRoot":"","sources":["../../../src/dropdown/Dropdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\n\nexport class Dropdown extends RapidElement {\n static get styles() {\n return css`\n .wrapper {\n position: relative;\n }\n\n .toggle {\n cursor: pointer;\n }\n\n .dropdown-wrapper {\n position: relative;\n overflow: auto;\n }\n\n .dropdown {\n position: absolute;\n opacity: 0;\n z-index: 2;\n pointer-events: none;\n padding: 0;\n border-radius: var(--curvature);\n background: #fff;\n transform: translateY(1em) scale(0.9);\n transition: all calc(0.8 * var(--transition-speed)) var(--bounce);\n user-select: none;\n margin-top: 0px;\n margin-left: 0px;\n box-shadow: var(--dropdown-shadow);\n }\n\n .dropdown:focus {\n outline: none;\n }\n\n .arrow {\n content: '';\n width: 0px;\n height: 0;\n top: -6px;\n z-index: 10;\n position: absolute;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid white;\n }\n\n .open .dropdown {\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0.5em) scale(1);\n }\n\n .mask {\n position: absolute;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n opacity: 0;\n transition: opacity var(--transition-speed) ease-in-out;\n pointer-events: none;\n z-index: 1;\n }\n\n .mask.open {\n opacity: 1;\n pointer-events: auto;\n }\n\n .right {\n right: 0;\n }\n `;\n }\n\n @property({ type: Boolean })\n open = false;\n\n @property({ type: Boolean })\n top = false;\n\n @property({ type: Boolean })\n bottom = false;\n\n @property({ type: Boolean })\n left = false;\n\n @property({ type: Boolean })\n right = false;\n\n @property({ type: Number })\n arrowSize = 6;\n\n @property({ type: Number })\n arrowOffset = this.arrowSize * 2;\n\n @property({ type: Number })\n offsetX = 0;\n\n @property({ type: Number })\n offsetY = 0;\n\n @property({ type: Boolean })\n mask = false;\n\n public firstUpdated(props: any) {\n super.firstUpdated(props);\n\n const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;\n arrow.style.borderWidth = this.arrowSize + 'px';\n arrow.style.top = '-' + this.arrowSize + 'px';\n\n if (this.arrowOffset < 0) {\n arrow.style.right = Math.abs(this.arrowOffset) + 'px';\n } else {\n arrow.style.left = this.arrowOffset + 'px';\n }\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n dropdown.addEventListener('blur', () => {\n // we nest this to deal with clicking the toggle to close\n // as we don't want it to toggle an immediate open, probably\n // a better way to deal with this\n window.setTimeout(() => {\n this.open = false;\n // blur our host element too\n (this.shadowRoot.host as HTMLDivElement).blur();\n }, 200);\n });\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {\n dropdown.style.marginTop = this.offsetY + 'px';\n if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {\n dropdown.style.marginLeft =\n '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';\n } else {\n if (this.right) {\n dropdown.style.marginRight = this.offsetX + 'px';\n } else {\n dropdown.style.marginLeft = this.offsetX + 'px';\n }\n }\n }\n\n if (changedProperties.has('open')) {\n if (this.open) {\n this.classList.add('open');\n } else {\n this.classList.remove('open');\n }\n\n this.ensureOnScreen();\n }\n }\n\n public ensureOnScreen() {\n window.setTimeout(() => {\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n\n if (dropdown) {\n // dropdown will go off the screen, let's push it up\n if (dropdown.getBoundingClientRect().bottom > window.innerHeight) {\n const toggle = this.querySelector('div[slot=\"toggle\"]');\n dropdown.style.bottom =\n this.offsetY + toggle.clientHeight + 10 + 'px';\n }\n }\n }, 100);\n }\n\n public handleToggleClicked(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n if (!this.open) {\n this.open = true;\n\n const dropdown = this.shadowRoot.querySelector(\n '.dropdown'\n ) as HTMLDivElement;\n dropdown.focus();\n }\n }\n\n private handleDropdownMouseDown(event: MouseEvent): void {\n // block mouse down when clicking inside dropdown so we don't lose focus yet\n event.preventDefault();\n event.stopPropagation();\n }\n\n public render(): TemplateResult {\n return html`\n ${this.mask\n ? html`<div class=\"mask ${this.open ? 'open' : ''}\" />`\n : null}\n\n <div class=\"wrapper ${this.open ? 'open' : ''}\">\n <slot\n name=\"toggle\"\n class=\"toggle\"\n @click=${this.handleToggleClicked}\n ></slot>\n <div\n class=\"${getClasses({\n dropdown: true,\n right: this.right,\n left: this.left,\n top: this.top,\n bottom: this.bottom,\n })}\"\n tabindex=\"0\"\n @mousedown=${this.handleDropdownMouseDown}\n >\n <div class=\"arrow\"></div>\n <div class=\"dropdown-wrapper\">\n <slot name=\"dropdown\" tabindex=\"1\"></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { css, html } from 'lit';
|
|
2
|
+
import { TembaList } from './TembaList';
|
|
3
|
+
import { Icon } from '../vectoricon';
|
|
4
|
+
const getNotification = (notification) => {
|
|
5
|
+
let icon = null;
|
|
6
|
+
let body = null;
|
|
7
|
+
let color = '#333';
|
|
8
|
+
if (notification.type === 'incident:started') {
|
|
9
|
+
color = 'tomato';
|
|
10
|
+
if (notification.incident.type === 'org:flagged') {
|
|
11
|
+
icon = Icon.incidents;
|
|
12
|
+
body =
|
|
13
|
+
'Your workspace was flagged, please contact support for assistance.';
|
|
14
|
+
}
|
|
15
|
+
else if (notification.incident.type === 'org:suspended') {
|
|
16
|
+
icon = Icon.incidents;
|
|
17
|
+
body =
|
|
18
|
+
'Your workspace was suspended, please contact support for assistance.';
|
|
19
|
+
}
|
|
20
|
+
else if (notification.incident.type === 'channel:disconnected') {
|
|
21
|
+
icon = Icon.channel;
|
|
22
|
+
body = 'Your android channel is not connected';
|
|
23
|
+
}
|
|
24
|
+
else if (notification.incident.type === 'webhooks:unhealthy') {
|
|
25
|
+
icon = Icon.webhook;
|
|
26
|
+
body = 'Your webhook calls are not working properly.';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (notification.type === 'import:finished') {
|
|
30
|
+
if (notification.import.type === 'contact') {
|
|
31
|
+
icon = Icon.contact_import;
|
|
32
|
+
body = `Imported ${notification.import.num_records.toLocaleString()} contacts`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (notification.type === 'export:finished') {
|
|
36
|
+
if (notification.export.type === 'contact') {
|
|
37
|
+
icon = Icon.contact_export;
|
|
38
|
+
body = 'Contacts exported';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (notification.type === 'tickets:activity') {
|
|
42
|
+
icon = Icon.tickets;
|
|
43
|
+
body = 'New ticket activity';
|
|
44
|
+
}
|
|
45
|
+
else if (notification.type === 'tickets:opened') {
|
|
46
|
+
icon = Icon.tickets;
|
|
47
|
+
body = 'New unassigned ticket';
|
|
48
|
+
}
|
|
49
|
+
return html `<div
|
|
50
|
+
style="color:${color};display:flex;align-items:flex-start;flex-direction:row;font-weight:${notification.is_seen
|
|
51
|
+
? 300
|
|
52
|
+
: 400}"
|
|
53
|
+
>
|
|
54
|
+
${icon
|
|
55
|
+
? html `<div style="margin-right:0.6em">
|
|
56
|
+
<temba-icon name="${icon}"></temba-icon>
|
|
57
|
+
</div>`
|
|
58
|
+
: null}
|
|
59
|
+
<div style="display:flex;flex-direction:column">
|
|
60
|
+
<div style="line-height:1.1em">${body}</div>
|
|
61
|
+
<temba-date
|
|
62
|
+
style="font-size:80%"
|
|
63
|
+
value=${notification.created_on}
|
|
64
|
+
display="duration"
|
|
65
|
+
></temba-date>
|
|
66
|
+
</div>
|
|
67
|
+
</div>`;
|
|
68
|
+
};
|
|
69
|
+
export class NotificationList extends TembaList {
|
|
70
|
+
static get styles() {
|
|
71
|
+
return css `
|
|
72
|
+
:host {
|
|
73
|
+
--option-hover-bg: #f9f9f9;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.header {
|
|
77
|
+
padding: 0.25em 1em;
|
|
78
|
+
background: #f9f9f9;
|
|
79
|
+
border-top-left-radius: var(--curvature);
|
|
80
|
+
border-top-right-radius: var(--curvature);
|
|
81
|
+
display: flex;
|
|
82
|
+
color: #999;
|
|
83
|
+
border-bottom: 1px solid #f3f3f3;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.header temba-icon {
|
|
87
|
+
margin-right: 0.35em;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.footer {
|
|
91
|
+
background: #f9f9f9;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.title {
|
|
95
|
+
font-weight: normal;
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
}
|
|
99
|
+
constructor() {
|
|
100
|
+
super();
|
|
101
|
+
this.reverseRefresh = false;
|
|
102
|
+
this.internalFocusDisabled = true;
|
|
103
|
+
this.valueKey = 'target_url';
|
|
104
|
+
this.renderOption = (notification) => {
|
|
105
|
+
const styles = {
|
|
106
|
+
display: 'flex',
|
|
107
|
+
alignItems: 'flex-start',
|
|
108
|
+
justifyContent: 'flex-start',
|
|
109
|
+
};
|
|
110
|
+
if (!notification.is_seen) {
|
|
111
|
+
styles['fontWeight'] = '400';
|
|
112
|
+
}
|
|
113
|
+
return html ` ${getNotification(notification)} `;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
renderHeader() {
|
|
117
|
+
return html `<div class="header">
|
|
118
|
+
<temba-icon name="notification"></temba-icon>
|
|
119
|
+
<div class="title">Notifications</div>
|
|
120
|
+
</div>`;
|
|
121
|
+
}
|
|
122
|
+
handleSelection(event) {
|
|
123
|
+
super.handleSelected(event);
|
|
124
|
+
}
|
|
125
|
+
scrollToTop() {
|
|
126
|
+
// scroll back to the top
|
|
127
|
+
window.setTimeout(() => {
|
|
128
|
+
const options = this.shadowRoot.querySelector('temba-options');
|
|
129
|
+
options.scrollToTop();
|
|
130
|
+
}, 1000);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=NotificationList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationList.js","sourceRoot":"","sources":["../../../src/list/NotificationList.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { TembaList } from './TembaList';\nimport { StyleInfo } from 'lit-html/directives/style-map.js';\nimport { Options } from '../options/Options';\nimport { Icon } from '../vectoricon';\n\ninterface Notification {\n created_on: string;\n type: string;\n target_url: string;\n is_seen: boolean;\n export?: {\n type: string;\n };\n import?: {\n type: string;\n num_records: number;\n };\n incident?: {\n type: string;\n started_on: string;\n ended_on?: string;\n };\n}\n\nconst getNotification = (notification: Notification) => {\n let icon = null;\n let body = null;\n let color = '#333';\n\n if (notification.type === 'incident:started') {\n color = 'tomato';\n if (notification.incident.type === 'org:flagged') {\n icon = Icon.incidents;\n body =\n 'Your workspace was flagged, please contact support for assistance.';\n } else if (notification.incident.type === 'org:suspended') {\n icon = Icon.incidents;\n body =\n 'Your workspace was suspended, please contact support for assistance.';\n } else if (notification.incident.type === 'channel:disconnected') {\n icon = Icon.channel;\n body = 'Your android channel is not connected';\n } else if (notification.incident.type === 'webhooks:unhealthy') {\n icon = Icon.webhook;\n body = 'Your webhook calls are not working properly.';\n }\n } else if (notification.type === 'import:finished') {\n if (notification.import.type === 'contact') {\n icon = Icon.contact_import;\n body = `Imported ${notification.import.num_records.toLocaleString()} contacts`;\n }\n } else if (notification.type === 'export:finished') {\n if (notification.export.type === 'contact') {\n icon = Icon.contact_export;\n body = 'Contacts exported';\n }\n } else if (notification.type === 'tickets:activity') {\n icon = Icon.tickets;\n body = 'New ticket activity';\n } else if (notification.type === 'tickets:opened') {\n icon = Icon.tickets;\n body = 'New unassigned ticket';\n }\n return html`<div\n style=\"color:${color};display:flex;align-items:flex-start;flex-direction:row;font-weight:${notification.is_seen\n ? 300\n : 400}\"\n >\n ${icon\n ? html`<div style=\"margin-right:0.6em\">\n <temba-icon name=\"${icon}\"></temba-icon>\n </div>`\n : null}\n <div style=\"display:flex;flex-direction:column\">\n <div style=\"line-height:1.1em\">${body}</div>\n <temba-date\n style=\"font-size:80%\"\n value=${notification.created_on}\n display=\"duration\"\n ></temba-date>\n </div>\n </div>`;\n};\n\nexport class NotificationList extends TembaList {\n reverseRefresh = false;\n internalFocusDisabled = true;\n static get styles() {\n return css`\n :host {\n --option-hover-bg: #f9f9f9;\n }\n\n .header {\n padding: 0.25em 1em;\n background: #f9f9f9;\n border-top-left-radius: var(--curvature);\n border-top-right-radius: var(--curvature);\n display: flex;\n color: #999;\n border-bottom: 1px solid #f3f3f3;\n }\n\n .header temba-icon {\n margin-right: 0.35em;\n }\n\n .footer {\n background: #f9f9f9;\n }\n\n .title {\n font-weight: normal;\n }\n `;\n }\n\n constructor() {\n super();\n this.valueKey = 'target_url';\n this.renderOption = (notification: Notification): TemplateResult => {\n const styles: StyleInfo = {\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'flex-start',\n };\n\n if (!notification.is_seen) {\n styles['fontWeight'] = '400';\n }\n return html` ${getNotification(notification)} `;\n };\n }\n\n public renderHeader(): TemplateResult {\n return html`<div class=\"header\">\n <temba-icon name=\"notification\"></temba-icon>\n <div class=\"title\">Notifications</div>\n </div>`;\n }\n\n protected handleSelection(event: CustomEvent) {\n super.handleSelected(event);\n }\n\n public scrollToTop(): void {\n // scroll back to the top\n window.setTimeout(() => {\n const options = this.shadowRoot.querySelector('temba-options') as Options;\n options.scrollToTop();\n }, 1000);\n }\n}\n"]}
|
|
@@ -23,6 +23,7 @@ export class TembaList extends RapidElement {
|
|
|
23
23
|
this.valueKey = 'id';
|
|
24
24
|
this.loading = false;
|
|
25
25
|
this.paused = false;
|
|
26
|
+
this.internalFocusDisabled = false;
|
|
26
27
|
// changes to the refresh key force a refresh
|
|
27
28
|
this.refreshKey = '0';
|
|
28
29
|
this.reverseRefresh = true;
|
|
@@ -77,6 +78,9 @@ export class TembaList extends RapidElement {
|
|
|
77
78
|
this.handleSelected(this.selected);
|
|
78
79
|
}
|
|
79
80
|
}
|
|
81
|
+
if (changedProperties.has('items')) {
|
|
82
|
+
//
|
|
83
|
+
}
|
|
80
84
|
}
|
|
81
85
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
82
86
|
handleSelected(selected) {
|
|
@@ -324,6 +328,7 @@ export class TembaList extends RapidElement {
|
|
|
324
328
|
?hideShadow=${this.hideShadow}
|
|
325
329
|
?collapsed=${this.collapsed}
|
|
326
330
|
?loading=${this.loading}
|
|
331
|
+
?internalFocusDisabled=${this.internalFocusDisabled}
|
|
327
332
|
.renderOption=${this.renderOption}
|
|
328
333
|
.renderOptionDetail=${this.renderOptionDetail}
|
|
329
334
|
@temba-scroll-threshold=${this.handleScrollThreshold}
|
|
@@ -373,6 +378,9 @@ __decorate([
|
|
|
373
378
|
__decorate([
|
|
374
379
|
property({ type: Boolean })
|
|
375
380
|
], TembaList.prototype, "paused", void 0);
|
|
381
|
+
__decorate([
|
|
382
|
+
property({ type: Boolean })
|
|
383
|
+
], TembaList.prototype, "internalFocusDisabled", void 0);
|
|
376
384
|
__decorate([
|
|
377
385
|
property({ attribute: false })
|
|
378
386
|
], TembaList.prototype, "getNextRefresh", void 0);
|