@nyaruka/temba-components 0.68.0 → 0.71.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{dd629ee4.js → 2b9b9834.js} +274 -212
  3. package/dist/index.js +274 -212
  4. package/dist/sw.js +1 -1
  5. package/dist/sw.js.map +1 -1
  6. package/dist/templates/components-body.html +1 -1
  7. package/dist/templates/components-head.html +1 -1
  8. package/out-tsc/src/contacts/ContactHistory.js +20 -13
  9. package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
  10. package/out-tsc/src/contacts/ContactTickets.js +27 -23
  11. package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
  12. package/out-tsc/src/contacts/events.js +7 -8
  13. package/out-tsc/src/contacts/events.js.map +1 -1
  14. package/out-tsc/src/imagepicker/ImagePicker.js +3 -6
  15. package/out-tsc/src/imagepicker/ImagePicker.js.map +1 -1
  16. package/out-tsc/src/list/TicketList.js +4 -5
  17. package/out-tsc/src/list/TicketList.js.map +1 -1
  18. package/out-tsc/src/store/Store.js +3 -0
  19. package/out-tsc/src/store/Store.js.map +1 -1
  20. package/out-tsc/src/store/StoreElement.js +11 -30
  21. package/out-tsc/src/store/StoreElement.js.map +1 -1
  22. package/out-tsc/src/store/StoreMonitorElement.js +50 -0
  23. package/out-tsc/src/store/StoreMonitorElement.js.map +1 -0
  24. package/out-tsc/src/user/TembaUser.js +107 -0
  25. package/out-tsc/src/user/TembaUser.js.map +1 -0
  26. package/out-tsc/src/utils/index.js +1 -1
  27. package/out-tsc/src/utils/index.js.map +1 -1
  28. package/out-tsc/temba-modules.js +2 -0
  29. package/out-tsc/temba-modules.js.map +1 -1
  30. package/out-tsc/test/temba-contact-tickets.test.js +1 -1
  31. package/out-tsc/test/temba-contact-tickets.test.js.map +1 -1
  32. package/package.json +1 -1
  33. package/rollup.config.js +3 -0
  34. package/screenshots/truth/contacts/tickets-assignment.png +0 -0
  35. package/screenshots/truth/contacts/tickets.png +0 -0
  36. package/src/contacts/ContactHistory.ts +28 -14
  37. package/src/contacts/ContactTickets.ts +28 -34
  38. package/src/contacts/events.ts +8 -19
  39. package/src/imagepicker/ImagePicker.ts +3 -7
  40. package/src/list/TicketList.ts +4 -5
  41. package/src/store/Store.ts +4 -0
  42. package/src/store/StoreElement.ts +13 -38
  43. package/src/store/StoreMonitorElement.ts +61 -0
  44. package/src/user/TembaUser.ts +111 -0
  45. package/src/utils/index.ts +1 -2
  46. package/temba-modules.ts +2 -0
  47. package/templates/index.html +7 -4
  48. package/test/temba-contact-tickets.test.ts +1 -3
package/dist/sw.js CHANGED
@@ -1,2 +1,2 @@
1
- if(!self.define){let e,t={};const o=(o,n)=>(o=new URL(o+".js",n).href,t[o]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=o,e.onload=t,document.head.appendChild(e)}else e=o,importScripts(o),t()})).then((()=>{let e=t[o];if(!e)throw new Error(`Module ${o} didn’t register its module`);return e})));self.define=(n,s)=>{const i=e||("document"in self?document.currentScript.src:"")||location.href;if(t[i])return;let r={};const d=e=>o(e,i),l={module:{uri:i},exports:r,require:d};t[i]=Promise.all(n.map((e=>l[e]||d(e)))).then((e=>(s(...e),r)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"dd629ee4.js",revision:"1dd4d02eac90e5e53470db61f5183366"},{url:"templates/components-body.html",revision:"2ec165e7b667c426d2558f08a3ed4c07"},{url:"templates/components-head.html",revision:"da8d486792fa71cf6572a4a0eb06e79c"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
1
+ if(!self.define){let e,t={};const o=(o,n)=>(o=new URL(o+".js",n).href,t[o]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=o,e.onload=t,document.head.appendChild(e)}else e=o,importScripts(o),t()})).then((()=>{let e=t[o];if(!e)throw new Error(`Module ${o} didn’t register its module`);return e})));self.define=(n,s)=>{const i=e||("document"in self?document.currentScript.src:"")||location.href;if(t[i])return;let c={};const r=e=>o(e,i),l={module:{uri:i},exports:c,require:r};t[i]=Promise.all(n.map((e=>l[e]||r(e)))).then((e=>(s(...e),c)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"2b9b9834.js",revision:"ac2f9c0dc507dfddab143a8b3ff45137"},{url:"templates/components-body.html",revision:"3877aaccf6ea77d190424df4e4ba332f"},{url:"templates/components-head.html",revision:"1654695625dcc9df0cc4a46c69b360cb"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
2
2
  //# sourceMappingURL=sw.js.map
package/dist/sw.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sw.js","sources":["../../tmp/860406e69004523f3f91550eb665cca0/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/workspaces/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/workspaces/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/workspaces/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/workspaces/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/workspaces/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/workspaces/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"dd629ee4.js\",\n \"revision\": \"1dd4d02eac90e5e53470db61f5183366\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"2ec165e7b667c426d2558f08a3ed4c07\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"da8d486792fa71cf6572a4a0eb06e79c\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,CAAE,GAEwBC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}
1
+ {"version":3,"file":"sw.js","sources":["../../tmp/3dab8c9681201fa38692494e608b05ab/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/workspaces/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/workspaces/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/workspaces/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/workspaces/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/workspaces/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/workspaces/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"2b9b9834.js\",\n \"revision\": \"ac2f9c0dc507dfddab143a8b3ff45137\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"3877aaccf6ea77d190424df4e4ba332f\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"1654695625dcc9df0cc4a46c69b360cb\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,CAAE,GAEwBC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}
@@ -1 +1 @@
1
- <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/dd629ee4.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.68.0"</script>
1
+ <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/2b9b9834.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.71.0"</script>
@@ -1 +1 @@
1
- <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/dd629ee4.js" crossorigin="anonymous">
1
+ <script src="{{STATIC_URL}}croppie/croppie.js"></script><link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/2b9b9834.js" crossorigin="anonymous">
@@ -40,6 +40,7 @@ export class ContactHistory extends RapidElement {
40
40
  connectedCallback() {
41
41
  super.connectedCallback();
42
42
  this.shadowRoot.addEventListener('load', loadHandler, true);
43
+ this.store = document.querySelector('temba-store');
43
44
  }
44
45
  disconnectedCallback() {
45
46
  super.disconnectedCallback();
@@ -445,7 +446,10 @@ export class ContactHistory extends RapidElement {
445
446
  case Events.MESSAGE_CREATED:
446
447
  case Events.MESSAGE_RECEIVED:
447
448
  case Events.BROADCAST_CREATED:
448
- return renderMsgEvent(event, this.agent);
449
+ if (event.created_by) {
450
+ event.created_by = this.store.getUser(event.created_by.email);
451
+ }
452
+ return renderMsgEvent(event);
449
453
  case Events.FLOW_ENTERED:
450
454
  case Events.FLOW_EXITED:
451
455
  return renderFlowEvent(event);
@@ -621,18 +625,21 @@ export class ContactHistory extends RapidElement {
621
625
  })}
622
626
  </div>
623
627
 
624
- <div class="new-messages-container">
625
- <div
626
- @click=${() => {
627
- this.scrollToBottom(true);
628
- }}
629
- class="new-messages ${getClasses({
630
- expanded: this.showMessageAlert,
631
- })}"
632
- >
633
- New Messages
634
- </div>
635
- </div>
628
+ ${this.contact && this.contact.status === 'active'
629
+ ? html `<div class="new-messages-container">
630
+ <div
631
+ @click=${() => {
632
+ this.scrollToBottom(true);
633
+ }}
634
+ class="new-messages ${getClasses({
635
+ expanded: this.showMessageAlert,
636
+ })}"
637
+ >
638
+ New Messages
639
+ </div>
640
+ </div>`
641
+ : null}
642
+
636
643
  </div>
637
644
  `;
638
645
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ContactHistory.js","sourceRoot":"","sources":["../../../src/contacts/ContactHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import { css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { html, TemplateResult } from 'lit-html';\nimport { Contact, CustomEventType, Ticket } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\nimport { Asset, getAssets, getClasses, postJSON, throttle } from '../utils';\n\nimport {\n AirtimeTransferredEvent,\n CampaignFiredEvent,\n ChannelEvent,\n ContactEvent,\n ContactGroupsEvent,\n ContactHistoryPage,\n ContactLanguageChangedEvent,\n EmailSentEvent,\n ErrorMessageEvent,\n EventGroup,\n Events,\n FlowEvent,\n getEventGroupType,\n getEventStyles,\n LabelsAddedEvent,\n MsgEvent,\n NameChangedEvent,\n OptinRequestedEvent,\n renderAirtimeTransferredEvent,\n renderCallStartedEvent,\n renderCampaignFiredEvent,\n renderChannelEvent,\n renderContactGroupsEvent,\n renderContactLanguageChangedEvent,\n renderContactURNsChanged,\n renderEmailSent,\n renderErrorMessage,\n renderFlowEvent,\n renderLabelsAdded,\n renderMsgEvent,\n renderNameChanged,\n renderNoteCreated,\n renderOptinRequested,\n renderResultEvent,\n renderTicketAction,\n renderTicketAssigned,\n renderTicketOpened,\n renderUpdateEvent,\n renderWebhookEvent,\n TicketEvent,\n UpdateFieldEvent,\n UpdateResultEvent,\n URNsChangedEvent,\n WebhookEvent,\n} from './events';\nimport {\n fetchContactHistory,\n MAX_CHAT_REFRESH,\n MIN_CHAT_REFRESH,\n SCROLL_THRESHOLD,\n} from './helpers';\nimport { Lightbox } from '../lightbox/Lightbox';\n\n// when images load, make sure we are on the bottom of the scroll window if necessary\nexport const loadHandler = function (event) {\n const target = event.target as HTMLElement;\n const events = this.host.getEventsPane();\n if (target.tagName == 'IMG') {\n if (!this.host.showMessageAlert) {\n if (\n events.scrollTop > target.offsetTop - 1000 &&\n target.offsetTop > events.scrollHeight - 500\n ) {\n this.host.scrollToBottom();\n }\n }\n }\n};\n\nexport class ContactHistory extends RapidElement {\n public httpComplete: Promise<void | ContactHistoryPage>;\n\n public constructor() {\n super();\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.shadowRoot.addEventListener('load', loadHandler, true);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.shadowRoot.removeEventListener('load', loadHandler, true);\n }\n\n private getTicketForEvent(event: TicketEvent) {\n return this.getTicket((event as TicketEvent).ticket.uuid);\n }\n\n private getTicket(uuid: string) {\n return (this.tickets || []).find(ticket => ticket.uuid === uuid);\n }\n\n static get styles() {\n return css`\n ${getEventStyles()}\n\n .wrapper {\n border: 0px solid green;\n display: flex;\n flex-direction: column;\n align-items: items-stretch;\n flex-grow: 1;\n min-height: 0;\n }\n\n .events {\n overflow-y: scroll;\n overflow-x: hidden;\n background: #fff;\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n min-height: 0;\n padding-top: 3em;\n padding-bottom: 1em;\n }\n\n temba-loading {\n align-self: center;\n margin-top: 0.025em;\n position: absolute;\n z-index: 250;\n padding-top: 1em;\n }\n\n .new-messages-container {\n display: flex;\n z-index: 1;\n background: pink;\n margin-bottom: 0px;\n }\n\n .new-messages {\n pointer-events: none;\n margin: 0 auto;\n margin-top: 0em;\n margin-bottom: -2.5em;\n padding: 0.25em 1em;\n border-radius: var(--curvature);\n background: var(--color-primary-dark);\n color: var(--color-text-light);\n opacity: 0;\n cursor: pointer;\n transition: all var(--transition-speed) ease-in-out;\n box-shadow: rgb(0 0 0 / 15%) 0px 3px 3px 0px;\n }\n\n .new-messages.expanded {\n margin-top: -2.5em;\n margin-bottom: 0.5em;\n pointer-events: auto;\n opacity: 1;\n pointer: cursor;\n }\n\n .scroll-title {\n display: flex;\n flex-direction: column;\n z-index: 2;\n border-top-left-radius: var(--curvature);\n overflow: hidden;\n box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.15);\n background: rgb(240, 240, 240);\n padding: 1em 1.2em;\n font-size: 1.2em;\n font-weight: 400;\n }\n\n .attachment img {\n cursor: pointer;\n }\n `;\n }\n\n @property({ type: Object })\n contact: Contact;\n\n @property({ type: String })\n uuid: string;\n\n @property({ type: String })\n agent: string;\n\n @property({ type: Array })\n eventGroups: EventGroup[] = [];\n\n @property({ type: Boolean })\n refreshing = false;\n\n @property({ type: Boolean })\n fetching = false;\n\n @property({ type: Boolean })\n complete = false;\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Boolean })\n debug = false;\n\n @property({ type: Boolean })\n showMessageAlert = false;\n\n @property({ attribute: false, type: Object })\n mostRecentEvent: ContactEvent;\n\n @property({ type: String })\n ticket: string = null;\n\n @property({ type: String })\n endDate: string = null;\n\n @property({ type: Array })\n tickets: Ticket[] = null;\n\n ticketEvents: { [uuid: string]: TicketEvent } = {};\n\n nextBefore: number;\n nextAfter: number;\n lastHeight = 0;\n lastRefreshAdded: number;\n refreshTimeout: any = null;\n empty = false;\n\n public firstUpdated(changedProperties: Map<string, any>) {\n super.firstUpdated(changedProperties);\n this.handleClose = this.handleClose.bind(this);\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n // fire an event if we get a new event\n if (\n changedProperties.has('mostRecentEvent') &&\n changedProperties.get('mostRecentEvent') &&\n this.mostRecentEvent\n ) {\n this.fireCustomEvent(CustomEventType.Refreshed);\n }\n\n if (changedProperties.has('endDate')) {\n if (this.refreshTimeout && this.endDate) {\n window.clearTimeout(this.refreshTimeout);\n }\n }\n\n // if we don't have an endpoint infer one\n if (changedProperties.has('uuid')) {\n if (this.uuid == null) {\n this.reset();\n } else {\n const endpoint = `/contact/history/${this.uuid}/?_format=json`;\n\n if (this.endpoint !== endpoint) {\n this.reset();\n\n if (this.endDate) {\n const before = new Date(this.endDate);\n this.nextBefore = before.getTime() * 1000 + 1000;\n }\n\n this.endpoint = endpoint;\n this.refreshTickets();\n }\n }\n }\n\n if (changedProperties.has('ticket')) {\n this.endpoint = null;\n this.requestUpdate('uuid');\n }\n\n if (\n changedProperties.has('refreshing') &&\n this.refreshing &&\n this.endpoint &&\n !this.endDate\n ) {\n const after = (this.getLastEventTime() - 1) * 1000;\n let forceOpen = false;\n\n fetchContactHistory(false, this.endpoint, this.ticket, null, after)\n .then((results: ContactHistoryPage) => {\n if (results.events && results.events.length > 0) {\n this.updateMostRecent(results.events[0]);\n }\n\n // keep track of any ticket events\n results.events.forEach((event: ContactEvent) => {\n if (event.type === Events.TICKET_OPENED) {\n const ticketEvent = event as TicketEvent;\n this.ticketEvents[ticketEvent.ticket.uuid] = ticketEvent;\n }\n });\n\n const fetchedEvents = results.events.reverse();\n\n // dedupe any events we get from the server\n // TODO: perhaps make this a little less crazy\n let removed = 0;\n this.eventGroups.forEach(g => {\n const before = g.events.length;\n g.events = g.events.filter(\n prev =>\n !fetchedEvents.find(fetched => {\n return (\n prev.created_on == fetched.created_on &&\n prev.type === fetched.type\n );\n })\n );\n removed += before - g.events.length;\n });\n\n this.lastRefreshAdded = fetchedEvents.length - removed;\n\n // reflow our most recent event group in case it merges with our new groups\n const previousGroups = [...this.eventGroups];\n\n if (this.eventGroups.length > 0) {\n const sliced = previousGroups.splice(\n previousGroups.length - 1,\n 1\n )[0];\n\n forceOpen = sliced.open;\n fetchedEvents.splice(0, 0, ...sliced.events);\n }\n\n const grouped = this.getEventGroups(fetchedEvents);\n if (grouped.length) {\n if (forceOpen) {\n grouped[grouped.length - 1].open = forceOpen;\n }\n this.eventGroups = [...previousGroups, ...grouped];\n }\n this.refreshing = false;\n this.scheduleRefresh();\n })\n .catch(() => {\n this.refreshing = false;\n this.scheduleRefresh();\n });\n }\n\n if (changedProperties.has('fetching') && this.fetching) {\n if (!this.nextBefore) {\n this.nextBefore = new Date().getTime() * 1000 - 1000;\n }\n\n this.httpComplete = fetchContactHistory(\n this.empty,\n this.endpoint,\n this.ticket,\n this.nextBefore,\n this.nextAfter\n ).then((results: ContactHistoryPage) => {\n // see if we have a new event\n if (results.events && results.events.length > 0) {\n this.updateMostRecent(results.events[0]);\n\n // keep track of any ticket events\n results.events.forEach((event: ContactEvent) => {\n if (event.type === Events.TICKET_OPENED) {\n const ticketEvent = event as TicketEvent;\n this.ticketEvents[ticketEvent.ticket.uuid] = ticketEvent;\n }\n });\n }\n\n let forceOpen = false;\n const fetchedEvents = results.events ? results.events.reverse() : [];\n\n // reflow our last event group in case it merges with our new groups\n if (this.eventGroups.length > 0) {\n const sliced = this.eventGroups.splice(0, 1)[0];\n forceOpen = sliced.open;\n fetchedEvents.push(...sliced.events);\n }\n\n const grouped = this.getEventGroups(fetchedEvents);\n if (grouped.length) {\n if (forceOpen) {\n grouped[grouped.length - 1].open = forceOpen;\n }\n\n this.eventGroups = [...grouped, ...this.eventGroups];\n }\n\n if (results.next_before === this.nextBefore) {\n this.complete = true;\n }\n\n this.nextBefore = results.next_before;\n this.nextAfter = results.next_after;\n this.fetching = false;\n this.empty = false;\n });\n }\n\n if (changedProperties.has('refreshing') && !this.refreshing) {\n if (this.lastRefreshAdded > 0) {\n const events = this.getEventsPane();\n\n // if we are near the bottom, push us to the bottom to show new stuff\n if (this.lastHeight > 0) {\n const addedHeight = events.scrollHeight - this.lastHeight;\n\n const distanceFromBottom =\n events.scrollHeight -\n events.scrollTop -\n addedHeight -\n events.clientHeight;\n\n if (distanceFromBottom < 500) {\n this.scrollToBottom();\n } else {\n this.showMessageAlert = true;\n }\n }\n\n if (this.eventGroups.length > 0) {\n this.lastHeight = events.scrollHeight;\n }\n }\n }\n\n if (\n changedProperties.has('fetching') &&\n !this.fetching &&\n changedProperties.get('fetching') !== undefined\n ) {\n const events = this.getEventsPane();\n\n if (this.lastHeight && events.scrollHeight > this.lastHeight) {\n const scrollTop =\n events.scrollTop + events.scrollHeight - this.lastHeight;\n events.scrollTop = scrollTop;\n }\n\n // scroll to the bottom if it's our first fetch\n if (!this.lastHeight) {\n this.scrollToBottom();\n }\n\n // don't record our scroll height until we have history\n if (this.eventGroups.length > 0) {\n this.lastHeight = events.scrollHeight;\n }\n }\n\n if (changedProperties.has('endpoint') && this.endpoint) {\n this.fetching = true;\n this.empty = true;\n }\n }\n\n private refreshTickets() {\n if (this.ticket) {\n let url = `/api/v2/tickets.json?contact=${this.uuid}`;\n if (this.ticket) {\n url = `${url}&ticket=${this.ticket}`;\n }\n\n getAssets(url).then((tickets: Ticket[]) => {\n this.tickets = tickets.reverse();\n });\n }\n }\n\n public getEventsPane() {\n return this.getDiv('.events');\n }\n\n public scrollToBottom(smooth = false) {\n const events = this.getEventsPane();\n events.scrollTo({\n top: events.scrollHeight,\n behavior: smooth ? 'smooth' : 'auto',\n });\n this.showMessageAlert = false;\n\n window.setTimeout(() => {\n events.scrollTo({\n top: events.scrollHeight,\n behavior: smooth ? 'smooth' : 'auto',\n });\n }, 0);\n }\n\n public refresh(): void {\n this.scheduleRefresh(500);\n }\n\n private getEventGroups(events: ContactEvent[]): EventGroup[] {\n const grouped: EventGroup[] = [];\n let eventGroup: EventGroup = undefined;\n for (const event of events) {\n const currentEventGroupType = getEventGroupType(event, this.ticket);\n // see if we need a new event group\n if (!eventGroup || eventGroup.type !== currentEventGroupType) {\n // we have a new type, save our last group\n if (eventGroup) {\n grouped.push(eventGroup);\n }\n eventGroup = {\n open: false,\n events: [event],\n type: currentEventGroupType,\n };\n } else {\n // our event matches the current group, stuff it in there\n eventGroup.events.push(event);\n }\n }\n\n if (eventGroup && eventGroup.events.length > 0) {\n grouped.push(eventGroup);\n }\n return grouped;\n }\n\n private scheduleRefresh(wait = -1) {\n if (this.endDate) {\n return;\n }\n\n let refreshWait = wait;\n\n if (wait === -1) {\n const lastEventTime = this.getLastEventTime();\n refreshWait = Math.max(\n Math.min((new Date().getTime() - lastEventTime) / 2, MAX_CHAT_REFRESH),\n MIN_CHAT_REFRESH\n );\n }\n\n // cancel any outstanding timeout\n if (wait > -1 && this.refreshTimeout) {\n window.clearTimeout(this.refreshTimeout);\n }\n\n this.refreshTimeout = window.setTimeout(() => {\n if (this.refreshing) {\n this.scheduleRefresh();\n this.refreshing = false;\n } else {\n this.refreshing = true;\n }\n }, refreshWait);\n }\n\n private reset() {\n this.endpoint = null;\n this.tickets = null;\n this.ticketEvents = {};\n this.eventGroups = [];\n this.fetching = false;\n this.complete = false;\n this.nextBefore = null;\n this.nextAfter = null;\n this.lastHeight = 0;\n }\n\n private handleEventGroupShow(event: MouseEvent) {\n const grouping = event.currentTarget as HTMLDivElement;\n const groupIndex = parseInt(grouping.getAttribute('data-group-index'));\n const eventGroup =\n this.eventGroups[this.eventGroups.length - groupIndex - 1];\n eventGroup.open = true;\n this.requestUpdate('eventGroups');\n }\n\n private handleEventGroupHide(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n const grouping = event.currentTarget as HTMLDivElement;\n const groupIndex = parseInt(grouping.getAttribute('data-group-index'));\n const eventGroup =\n this.eventGroups[this.eventGroups.length - groupIndex - 1];\n\n eventGroup.open = false;\n\n this.requestUpdate('eventGroups');\n }\n\n private handleScroll() {\n const events = this.getEventsPane();\n if (events.scrollTop <= SCROLL_THRESHOLD) {\n if (this.eventGroups.length > 0 && !this.fetching && !this.complete) {\n this.fetching = true;\n }\n }\n }\n\n private updateMostRecent(newEvent: ContactEvent) {\n if (\n !this.mostRecentEvent ||\n this.mostRecentEvent.type !== newEvent.type ||\n this.mostRecentEvent.created_on !== newEvent.created_on\n ) {\n this.mostRecentEvent = newEvent;\n }\n }\n\n private getLastEventTime(): number {\n const mostRecentGroup = this.eventGroups[this.eventGroups.length - 1];\n if (mostRecentGroup) {\n const mostRecentEvent =\n mostRecentGroup.events[mostRecentGroup.events.length - 1];\n return new Date(mostRecentEvent.created_on).getTime();\n }\n return 0;\n }\n\n public renderEvent(event: ContactEvent): any {\n switch (event.type) {\n case Events.IVR_CREATED:\n case Events.MESSAGE_CREATED:\n case Events.MESSAGE_RECEIVED:\n case Events.BROADCAST_CREATED:\n return renderMsgEvent(event as MsgEvent, this.agent);\n\n case Events.FLOW_ENTERED:\n case Events.FLOW_EXITED:\n return renderFlowEvent(event as FlowEvent);\n\n case Events.RUN_RESULT_CHANGED:\n return renderResultEvent(event as UpdateResultEvent);\n\n case Events.CONTACT_FIELD_CHANGED:\n return renderUpdateEvent(event as UpdateFieldEvent);\n\n case Events.CONTACT_NAME_CHANGED:\n return renderNameChanged(event as NameChangedEvent);\n\n case Events.CONTACT_URNS_CHANGED:\n return renderContactURNsChanged(event as URNsChangedEvent);\n\n case Events.EMAIL_SENT:\n return renderEmailSent(event as EmailSentEvent);\n\n case Events.INPUT_LABELS_ADDED:\n return renderLabelsAdded(event as LabelsAddedEvent);\n\n case Events.TICKET_OPENED: {\n return renderTicketAction(event as TicketEvent, 'opened', !this.ticket);\n }\n case Events.TICKET_NOTE_ADDED:\n return renderNoteCreated(event as TicketEvent);\n\n case Events.TICKET_ASSIGNED:\n return renderTicketAssigned(event as TicketEvent);\n case Events.TICKET_REOPENED: {\n return renderTicketAction(\n event as TicketEvent,\n 'reopened',\n !this.ticket\n );\n }\n case Events.TICKET_CLOSED:\n return renderTicketAction(event as TicketEvent, 'closed', !this.ticket);\n\n case Events.ERROR:\n case Events.FAILURE:\n return renderErrorMessage(event as ErrorMessageEvent);\n case Events.CONTACT_GROUPS_CHANGED:\n return renderContactGroupsEvent(event as ContactGroupsEvent);\n case Events.WEBHOOK_CALLED:\n return renderWebhookEvent(event as WebhookEvent);\n case Events.AIRTIME_TRANSFERRED:\n return renderAirtimeTransferredEvent(event as AirtimeTransferredEvent);\n case Events.CALL_STARTED:\n return renderCallStartedEvent();\n case Events.CAMPAIGN_FIRED:\n return renderCampaignFiredEvent(event as CampaignFiredEvent);\n case Events.CHANNEL_EVENT:\n return renderChannelEvent(event as ChannelEvent);\n case Events.CONTACT_LANGUAGE_CHANGED:\n return renderContactLanguageChangedEvent(\n event as ContactLanguageChangedEvent\n );\n case Events.OPTIN_REQUESTED:\n return renderOptinRequested(event as OptinRequestedEvent);\n }\n\n return html`<temba-icon\n name=\"alert-triangle\"\n style=\"fill:var(--color-error)\"\n ></temba-icon>\n <div class=\"description\">${event.type}</div>`;\n }\n\n private handleClose(uuid: string) {\n this.httpComplete = postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'close',\n })\n .then(() => {\n this.refreshTickets();\n this.refresh();\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: { uuid, status: 'closed' },\n });\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n public checkForAgentAssignmentEvent(agent: string) {\n this.httpComplete = getAssets(\n `/api/v2/tickets.json?uuid=${this.ticket}`\n ).then((assets: Asset[]) => {\n if (assets.length === 1) {\n const ticket = assets[0] as Ticket;\n if (ticket.assignee && ticket.assignee.email === agent) {\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: { uuid: this.ticket, assigned: 'self' },\n });\n } else {\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: {\n uuid: this.ticket,\n assigned: ticket.assignee ? ticket.assignee : null,\n },\n });\n }\n }\n });\n }\n\n public getEventHandlers() {\n return [\n {\n event: 'scroll',\n method: throttle(this.handleScroll, 50),\n },\n ];\n }\n\n /** Check if a ticket event is no longer represented in a session */\n private isPurged(ticket: Ticket): boolean {\n return !this.ticketEvents[ticket.uuid];\n }\n\n private handleEventClicked(event) {\n const ele = event.target as HTMLDivElement;\n if (ele.tagName == 'IMG') {\n // if we have one, show in our lightbox\n const lightbox = document.querySelector('temba-lightbox') as Lightbox;\n if (lightbox) {\n lightbox.showElement(ele);\n }\n }\n }\n\n private renderEventContainer(event: ContactEvent) {\n const renderedEvent = html`\n <div\n @click=${this.handleEventClicked}\n class=\"${this.ticket ? 'active-ticket' : ''} event ${event.type}\"\n >\n ${this.renderEvent(event)}\n </div>\n ${this.debug ? html`<pre>${JSON.stringify(event, null, 2)}</pre>` : null}\n `;\n return renderedEvent;\n }\n\n public render(): TemplateResult {\n return html`\n ${\n this.fetching\n ? html`<temba-loading units=\"5\" size=\"10\"></temba-loading>`\n : html`<div style=\"height:0em\"></div>`\n }\n <div class=\"events\" @scroll=${this.handleScroll}>\n ${this.eventGroups.map((eventGroup: EventGroup, index: number) => {\n const grouping = getEventGroupType(eventGroup.events[0], this.ticket);\n const groupIndex = this.eventGroups.length - index - 1;\n\n const classes = getClasses({\n grouping: true,\n [grouping]: true,\n expanded: eventGroup.open,\n });\n return html`<div class=\"${classes}\">\n ${grouping === 'verbose'\n ? html`<div\n class=\"event-count\"\n @click=${this.handleEventGroupShow}\n data-group-index=\"${groupIndex}\"\n >\n ${eventGroup.open\n ? html`<temba-icon\n @click=${this.handleEventGroupHide}\n data-group-index=\"${groupIndex}\"\n name=\"x\"\n clickable\n ></temba-icon>`\n : html`${eventGroup.events.length}\n ${eventGroup.events.length === 1\n ? html`event`\n : html`events`} `}\n </div>`\n : null}\n\n <div class=\"items\">\n ${eventGroup.events.map((event: ContactEvent) => {\n if (\n event.type === Events.TICKET_ASSIGNED &&\n (event as TicketEvent).note\n ) {\n const noteEvent = { ...event };\n noteEvent.type = Events.TICKET_NOTE_ADDED;\n\n return html`${this.renderEventContainer(\n noteEvent\n )}${this.renderEventContainer(event)}`;\n } else {\n return this.renderEventContainer(event);\n }\n })}\n </div>\n </div>`;\n })}\n </div>\n\n <div class=\"new-messages-container\">\n <div\n @click=${() => {\n this.scrollToBottom(true);\n }}\n class=\"new-messages ${getClasses({\n expanded: this.showMessageAlert,\n })}\"\n >\n New Messages\n </div>\n </div>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"ContactHistory.js","sourceRoot":"","sources":["../../../src/contacts/ContactHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import { css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { html, TemplateResult } from 'lit-html';\nimport { Contact, CustomEventType, Msg, Ticket } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\nimport { Asset, getAssets, getClasses, postJSON, throttle } from '../utils';\n\nimport {\n AirtimeTransferredEvent,\n CampaignFiredEvent,\n ChannelEvent,\n ContactEvent,\n ContactGroupsEvent,\n ContactHistoryPage,\n ContactLanguageChangedEvent,\n EmailSentEvent,\n ErrorMessageEvent,\n EventGroup,\n Events,\n FlowEvent,\n getEventGroupType,\n getEventStyles,\n LabelsAddedEvent,\n MsgEvent,\n NameChangedEvent,\n OptinRequestedEvent,\n renderAirtimeTransferredEvent,\n renderCallStartedEvent,\n renderCampaignFiredEvent,\n renderChannelEvent,\n renderContactGroupsEvent,\n renderContactLanguageChangedEvent,\n renderContactURNsChanged,\n renderEmailSent,\n renderErrorMessage,\n renderFlowEvent,\n renderLabelsAdded,\n renderMsgEvent,\n renderNameChanged,\n renderNoteCreated,\n renderOptinRequested,\n renderResultEvent,\n renderTicketAction,\n renderTicketAssigned,\n renderTicketOpened,\n renderUpdateEvent,\n renderWebhookEvent,\n TicketEvent,\n UpdateFieldEvent,\n UpdateResultEvent,\n URNsChangedEvent,\n WebhookEvent,\n} from './events';\nimport {\n fetchContactHistory,\n MAX_CHAT_REFRESH,\n MIN_CHAT_REFRESH,\n SCROLL_THRESHOLD,\n} from './helpers';\nimport { Lightbox } from '../lightbox/Lightbox';\nimport { Store } from '../store/Store';\n\n// when images load, make sure we are on the bottom of the scroll window if necessary\nexport const loadHandler = function (event) {\n const target = event.target as HTMLElement;\n const events = this.host.getEventsPane();\n if (target.tagName == 'IMG') {\n if (!this.host.showMessageAlert) {\n if (\n events.scrollTop > target.offsetTop - 1000 &&\n target.offsetTop > events.scrollHeight - 500\n ) {\n this.host.scrollToBottom();\n }\n }\n }\n};\n\nexport class ContactHistory extends RapidElement {\n public httpComplete: Promise<void | ContactHistoryPage>;\n private store: Store;\n\n public constructor() {\n super();\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.shadowRoot.addEventListener('load', loadHandler, true);\n this.store = document.querySelector('temba-store') as Store;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.shadowRoot.removeEventListener('load', loadHandler, true);\n }\n\n private getTicketForEvent(event: TicketEvent) {\n return this.getTicket((event as TicketEvent).ticket.uuid);\n }\n\n private getTicket(uuid: string) {\n return (this.tickets || []).find(ticket => ticket.uuid === uuid);\n }\n\n static get styles() {\n return css`\n ${getEventStyles()}\n\n .wrapper {\n border: 0px solid green;\n display: flex;\n flex-direction: column;\n align-items: items-stretch;\n flex-grow: 1;\n min-height: 0;\n }\n\n .events {\n overflow-y: scroll;\n overflow-x: hidden;\n background: #fff;\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n min-height: 0;\n padding-top: 3em;\n padding-bottom: 1em;\n }\n\n temba-loading {\n align-self: center;\n margin-top: 0.025em;\n position: absolute;\n z-index: 250;\n padding-top: 1em;\n }\n\n .new-messages-container {\n display: flex;\n z-index: 1;\n background: pink;\n margin-bottom: 0px;\n }\n\n .new-messages {\n pointer-events: none;\n margin: 0 auto;\n margin-top: 0em;\n margin-bottom: -2.5em;\n padding: 0.25em 1em;\n border-radius: var(--curvature);\n background: var(--color-primary-dark);\n color: var(--color-text-light);\n opacity: 0;\n cursor: pointer;\n transition: all var(--transition-speed) ease-in-out;\n box-shadow: rgb(0 0 0 / 15%) 0px 3px 3px 0px;\n }\n\n .new-messages.expanded {\n margin-top: -2.5em;\n margin-bottom: 0.5em;\n pointer-events: auto;\n opacity: 1;\n pointer: cursor;\n }\n\n .scroll-title {\n display: flex;\n flex-direction: column;\n z-index: 2;\n border-top-left-radius: var(--curvature);\n overflow: hidden;\n box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.15);\n background: rgb(240, 240, 240);\n padding: 1em 1.2em;\n font-size: 1.2em;\n font-weight: 400;\n }\n\n .attachment img {\n cursor: pointer;\n }\n `;\n }\n\n @property({ type: Object })\n contact: Contact;\n\n @property({ type: String })\n uuid: string;\n\n @property({ type: String })\n agent: string;\n\n @property({ type: Array })\n eventGroups: EventGroup[] = [];\n\n @property({ type: Boolean })\n refreshing = false;\n\n @property({ type: Boolean })\n fetching = false;\n\n @property({ type: Boolean })\n complete = false;\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Boolean })\n debug = false;\n\n @property({ type: Boolean })\n showMessageAlert = false;\n\n @property({ attribute: false, type: Object })\n mostRecentEvent: ContactEvent;\n\n @property({ type: String })\n ticket: string = null;\n\n @property({ type: String })\n endDate: string = null;\n\n @property({ type: Array })\n tickets: Ticket[] = null;\n\n ticketEvents: { [uuid: string]: TicketEvent } = {};\n\n nextBefore: number;\n nextAfter: number;\n lastHeight = 0;\n lastRefreshAdded: number;\n refreshTimeout: any = null;\n empty = false;\n\n public firstUpdated(changedProperties: Map<string, any>) {\n super.firstUpdated(changedProperties);\n this.handleClose = this.handleClose.bind(this);\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n // fire an event if we get a new event\n if (\n changedProperties.has('mostRecentEvent') &&\n changedProperties.get('mostRecentEvent') &&\n this.mostRecentEvent\n ) {\n this.fireCustomEvent(CustomEventType.Refreshed);\n }\n\n if (changedProperties.has('endDate')) {\n if (this.refreshTimeout && this.endDate) {\n window.clearTimeout(this.refreshTimeout);\n }\n }\n\n // if we don't have an endpoint infer one\n if (changedProperties.has('uuid')) {\n if (this.uuid == null) {\n this.reset();\n } else {\n const endpoint = `/contact/history/${this.uuid}/?_format=json`;\n\n if (this.endpoint !== endpoint) {\n this.reset();\n\n if (this.endDate) {\n const before = new Date(this.endDate);\n this.nextBefore = before.getTime() * 1000 + 1000;\n }\n\n this.endpoint = endpoint;\n this.refreshTickets();\n }\n }\n }\n\n if (changedProperties.has('ticket')) {\n this.endpoint = null;\n this.requestUpdate('uuid');\n }\n\n if (\n changedProperties.has('refreshing') &&\n this.refreshing &&\n this.endpoint &&\n !this.endDate\n ) {\n const after = (this.getLastEventTime() - 1) * 1000;\n let forceOpen = false;\n\n fetchContactHistory(false, this.endpoint, this.ticket, null, after)\n .then((results: ContactHistoryPage) => {\n if (results.events && results.events.length > 0) {\n this.updateMostRecent(results.events[0]);\n }\n\n // keep track of any ticket events\n results.events.forEach((event: ContactEvent) => {\n if (event.type === Events.TICKET_OPENED) {\n const ticketEvent = event as TicketEvent;\n this.ticketEvents[ticketEvent.ticket.uuid] = ticketEvent;\n }\n });\n\n const fetchedEvents = results.events.reverse();\n\n // dedupe any events we get from the server\n // TODO: perhaps make this a little less crazy\n let removed = 0;\n this.eventGroups.forEach(g => {\n const before = g.events.length;\n g.events = g.events.filter(\n prev =>\n !fetchedEvents.find(fetched => {\n return (\n prev.created_on == fetched.created_on &&\n prev.type === fetched.type\n );\n })\n );\n removed += before - g.events.length;\n });\n\n this.lastRefreshAdded = fetchedEvents.length - removed;\n\n // reflow our most recent event group in case it merges with our new groups\n const previousGroups = [...this.eventGroups];\n\n if (this.eventGroups.length > 0) {\n const sliced = previousGroups.splice(\n previousGroups.length - 1,\n 1\n )[0];\n\n forceOpen = sliced.open;\n fetchedEvents.splice(0, 0, ...sliced.events);\n }\n\n const grouped = this.getEventGroups(fetchedEvents);\n if (grouped.length) {\n if (forceOpen) {\n grouped[grouped.length - 1].open = forceOpen;\n }\n this.eventGroups = [...previousGroups, ...grouped];\n }\n this.refreshing = false;\n this.scheduleRefresh();\n })\n .catch(() => {\n this.refreshing = false;\n this.scheduleRefresh();\n });\n }\n\n if (changedProperties.has('fetching') && this.fetching) {\n if (!this.nextBefore) {\n this.nextBefore = new Date().getTime() * 1000 - 1000;\n }\n\n this.httpComplete = fetchContactHistory(\n this.empty,\n this.endpoint,\n this.ticket,\n this.nextBefore,\n this.nextAfter\n ).then((results: ContactHistoryPage) => {\n // see if we have a new event\n if (results.events && results.events.length > 0) {\n this.updateMostRecent(results.events[0]);\n\n // keep track of any ticket events\n results.events.forEach((event: ContactEvent) => {\n if (event.type === Events.TICKET_OPENED) {\n const ticketEvent = event as TicketEvent;\n this.ticketEvents[ticketEvent.ticket.uuid] = ticketEvent;\n }\n });\n }\n\n let forceOpen = false;\n const fetchedEvents = results.events ? results.events.reverse() : [];\n\n // reflow our last event group in case it merges with our new groups\n if (this.eventGroups.length > 0) {\n const sliced = this.eventGroups.splice(0, 1)[0];\n forceOpen = sliced.open;\n fetchedEvents.push(...sliced.events);\n }\n\n const grouped = this.getEventGroups(fetchedEvents);\n if (grouped.length) {\n if (forceOpen) {\n grouped[grouped.length - 1].open = forceOpen;\n }\n\n this.eventGroups = [...grouped, ...this.eventGroups];\n }\n\n if (results.next_before === this.nextBefore) {\n this.complete = true;\n }\n\n this.nextBefore = results.next_before;\n this.nextAfter = results.next_after;\n this.fetching = false;\n this.empty = false;\n });\n }\n\n if (changedProperties.has('refreshing') && !this.refreshing) {\n if (this.lastRefreshAdded > 0) {\n const events = this.getEventsPane();\n\n // if we are near the bottom, push us to the bottom to show new stuff\n if (this.lastHeight > 0) {\n const addedHeight = events.scrollHeight - this.lastHeight;\n\n const distanceFromBottom =\n events.scrollHeight -\n events.scrollTop -\n addedHeight -\n events.clientHeight;\n\n if (distanceFromBottom < 500) {\n this.scrollToBottom();\n } else {\n this.showMessageAlert = true;\n }\n }\n\n if (this.eventGroups.length > 0) {\n this.lastHeight = events.scrollHeight;\n }\n }\n }\n\n if (\n changedProperties.has('fetching') &&\n !this.fetching &&\n changedProperties.get('fetching') !== undefined\n ) {\n const events = this.getEventsPane();\n\n if (this.lastHeight && events.scrollHeight > this.lastHeight) {\n const scrollTop =\n events.scrollTop + events.scrollHeight - this.lastHeight;\n events.scrollTop = scrollTop;\n }\n\n // scroll to the bottom if it's our first fetch\n if (!this.lastHeight) {\n this.scrollToBottom();\n }\n\n // don't record our scroll height until we have history\n if (this.eventGroups.length > 0) {\n this.lastHeight = events.scrollHeight;\n }\n }\n\n if (changedProperties.has('endpoint') && this.endpoint) {\n this.fetching = true;\n this.empty = true;\n }\n }\n\n private refreshTickets() {\n if (this.ticket) {\n let url = `/api/v2/tickets.json?contact=${this.uuid}`;\n if (this.ticket) {\n url = `${url}&ticket=${this.ticket}`;\n }\n\n getAssets(url).then((tickets: Ticket[]) => {\n this.tickets = tickets.reverse();\n });\n }\n }\n\n public getEventsPane() {\n return this.getDiv('.events');\n }\n\n public scrollToBottom(smooth = false) {\n const events = this.getEventsPane();\n events.scrollTo({\n top: events.scrollHeight,\n behavior: smooth ? 'smooth' : 'auto',\n });\n this.showMessageAlert = false;\n\n window.setTimeout(() => {\n events.scrollTo({\n top: events.scrollHeight,\n behavior: smooth ? 'smooth' : 'auto',\n });\n }, 0);\n }\n\n public refresh(): void {\n this.scheduleRefresh(500);\n }\n\n private getEventGroups(events: ContactEvent[]): EventGroup[] {\n const grouped: EventGroup[] = [];\n let eventGroup: EventGroup = undefined;\n for (const event of events) {\n const currentEventGroupType = getEventGroupType(event, this.ticket);\n // see if we need a new event group\n if (!eventGroup || eventGroup.type !== currentEventGroupType) {\n // we have a new type, save our last group\n if (eventGroup) {\n grouped.push(eventGroup);\n }\n eventGroup = {\n open: false,\n events: [event],\n type: currentEventGroupType,\n };\n } else {\n // our event matches the current group, stuff it in there\n eventGroup.events.push(event);\n }\n }\n\n if (eventGroup && eventGroup.events.length > 0) {\n grouped.push(eventGroup);\n }\n return grouped;\n }\n\n private scheduleRefresh(wait = -1) {\n if (this.endDate) {\n return;\n }\n\n let refreshWait = wait;\n\n if (wait === -1) {\n const lastEventTime = this.getLastEventTime();\n refreshWait = Math.max(\n Math.min((new Date().getTime() - lastEventTime) / 2, MAX_CHAT_REFRESH),\n MIN_CHAT_REFRESH\n );\n }\n\n // cancel any outstanding timeout\n if (wait > -1 && this.refreshTimeout) {\n window.clearTimeout(this.refreshTimeout);\n }\n\n this.refreshTimeout = window.setTimeout(() => {\n if (this.refreshing) {\n this.scheduleRefresh();\n this.refreshing = false;\n } else {\n this.refreshing = true;\n }\n }, refreshWait);\n }\n\n private reset() {\n this.endpoint = null;\n this.tickets = null;\n this.ticketEvents = {};\n this.eventGroups = [];\n this.fetching = false;\n this.complete = false;\n this.nextBefore = null;\n this.nextAfter = null;\n this.lastHeight = 0;\n }\n\n private handleEventGroupShow(event: MouseEvent) {\n const grouping = event.currentTarget as HTMLDivElement;\n const groupIndex = parseInt(grouping.getAttribute('data-group-index'));\n const eventGroup =\n this.eventGroups[this.eventGroups.length - groupIndex - 1];\n eventGroup.open = true;\n this.requestUpdate('eventGroups');\n }\n\n private handleEventGroupHide(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n const grouping = event.currentTarget as HTMLDivElement;\n const groupIndex = parseInt(grouping.getAttribute('data-group-index'));\n const eventGroup =\n this.eventGroups[this.eventGroups.length - groupIndex - 1];\n\n eventGroup.open = false;\n\n this.requestUpdate('eventGroups');\n }\n\n private handleScroll() {\n const events = this.getEventsPane();\n if (events.scrollTop <= SCROLL_THRESHOLD) {\n if (this.eventGroups.length > 0 && !this.fetching && !this.complete) {\n this.fetching = true;\n }\n }\n }\n\n private updateMostRecent(newEvent: ContactEvent) {\n if (\n !this.mostRecentEvent ||\n this.mostRecentEvent.type !== newEvent.type ||\n this.mostRecentEvent.created_on !== newEvent.created_on\n ) {\n this.mostRecentEvent = newEvent;\n }\n }\n\n private getLastEventTime(): number {\n const mostRecentGroup = this.eventGroups[this.eventGroups.length - 1];\n if (mostRecentGroup) {\n const mostRecentEvent =\n mostRecentGroup.events[mostRecentGroup.events.length - 1];\n return new Date(mostRecentEvent.created_on).getTime();\n }\n return 0;\n }\n\n public renderEvent(event: ContactEvent): any {\n switch (event.type) {\n case Events.IVR_CREATED:\n case Events.MESSAGE_CREATED:\n case Events.MESSAGE_RECEIVED:\n case Events.BROADCAST_CREATED:\n if ((event as MsgEvent).created_by) {\n (event as MsgEvent).created_by = this.store.getUser(\n (event as MsgEvent).created_by.email\n );\n }\n\n return renderMsgEvent(event as MsgEvent);\n\n case Events.FLOW_ENTERED:\n case Events.FLOW_EXITED:\n return renderFlowEvent(event as FlowEvent);\n\n case Events.RUN_RESULT_CHANGED:\n return renderResultEvent(event as UpdateResultEvent);\n\n case Events.CONTACT_FIELD_CHANGED:\n return renderUpdateEvent(event as UpdateFieldEvent);\n\n case Events.CONTACT_NAME_CHANGED:\n return renderNameChanged(event as NameChangedEvent);\n\n case Events.CONTACT_URNS_CHANGED:\n return renderContactURNsChanged(event as URNsChangedEvent);\n\n case Events.EMAIL_SENT:\n return renderEmailSent(event as EmailSentEvent);\n\n case Events.INPUT_LABELS_ADDED:\n return renderLabelsAdded(event as LabelsAddedEvent);\n\n case Events.TICKET_OPENED: {\n return renderTicketAction(event as TicketEvent, 'opened', !this.ticket);\n }\n case Events.TICKET_NOTE_ADDED:\n return renderNoteCreated(event as TicketEvent);\n\n case Events.TICKET_ASSIGNED:\n return renderTicketAssigned(event as TicketEvent);\n case Events.TICKET_REOPENED: {\n return renderTicketAction(\n event as TicketEvent,\n 'reopened',\n !this.ticket\n );\n }\n case Events.TICKET_CLOSED:\n return renderTicketAction(event as TicketEvent, 'closed', !this.ticket);\n\n case Events.ERROR:\n case Events.FAILURE:\n return renderErrorMessage(event as ErrorMessageEvent);\n case Events.CONTACT_GROUPS_CHANGED:\n return renderContactGroupsEvent(event as ContactGroupsEvent);\n case Events.WEBHOOK_CALLED:\n return renderWebhookEvent(event as WebhookEvent);\n case Events.AIRTIME_TRANSFERRED:\n return renderAirtimeTransferredEvent(event as AirtimeTransferredEvent);\n case Events.CALL_STARTED:\n return renderCallStartedEvent();\n case Events.CAMPAIGN_FIRED:\n return renderCampaignFiredEvent(event as CampaignFiredEvent);\n case Events.CHANNEL_EVENT:\n return renderChannelEvent(event as ChannelEvent);\n case Events.CONTACT_LANGUAGE_CHANGED:\n return renderContactLanguageChangedEvent(\n event as ContactLanguageChangedEvent\n );\n case Events.OPTIN_REQUESTED:\n return renderOptinRequested(event as OptinRequestedEvent);\n }\n\n return html`<temba-icon\n name=\"alert-triangle\"\n style=\"fill:var(--color-error)\"\n ></temba-icon>\n <div class=\"description\">${event.type}</div>`;\n }\n\n private handleClose(uuid: string) {\n this.httpComplete = postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'close',\n })\n .then(() => {\n this.refreshTickets();\n this.refresh();\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: { uuid, status: 'closed' },\n });\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n public checkForAgentAssignmentEvent(agent: string) {\n this.httpComplete = getAssets(\n `/api/v2/tickets.json?uuid=${this.ticket}`\n ).then((assets: Asset[]) => {\n if (assets.length === 1) {\n const ticket = assets[0] as Ticket;\n if (ticket.assignee && ticket.assignee.email === agent) {\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: { uuid: this.ticket, assigned: 'self' },\n });\n } else {\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: {\n uuid: this.ticket,\n assigned: ticket.assignee ? ticket.assignee : null,\n },\n });\n }\n }\n });\n }\n\n public getEventHandlers() {\n return [\n {\n event: 'scroll',\n method: throttle(this.handleScroll, 50),\n },\n ];\n }\n\n /** Check if a ticket event is no longer represented in a session */\n private isPurged(ticket: Ticket): boolean {\n return !this.ticketEvents[ticket.uuid];\n }\n\n private handleEventClicked(event) {\n const ele = event.target as HTMLDivElement;\n if (ele.tagName == 'IMG') {\n // if we have one, show in our lightbox\n const lightbox = document.querySelector('temba-lightbox') as Lightbox;\n if (lightbox) {\n lightbox.showElement(ele);\n }\n }\n }\n\n private renderEventContainer(event: ContactEvent) {\n const renderedEvent = html`\n <div\n @click=${this.handleEventClicked}\n class=\"${this.ticket ? 'active-ticket' : ''} event ${event.type}\"\n >\n ${this.renderEvent(event)}\n </div>\n ${this.debug ? html`<pre>${JSON.stringify(event, null, 2)}</pre>` : null}\n `;\n return renderedEvent;\n }\n\n public render(): TemplateResult {\n return html`\n ${\n this.fetching\n ? html`<temba-loading units=\"5\" size=\"10\"></temba-loading>`\n : html`<div style=\"height:0em\"></div>`\n }\n <div class=\"events\" @scroll=${this.handleScroll}>\n ${this.eventGroups.map((eventGroup: EventGroup, index: number) => {\n const grouping = getEventGroupType(eventGroup.events[0], this.ticket);\n const groupIndex = this.eventGroups.length - index - 1;\n\n const classes = getClasses({\n grouping: true,\n [grouping]: true,\n expanded: eventGroup.open,\n });\n return html`<div class=\"${classes}\">\n ${grouping === 'verbose'\n ? html`<div\n class=\"event-count\"\n @click=${this.handleEventGroupShow}\n data-group-index=\"${groupIndex}\"\n >\n ${eventGroup.open\n ? html`<temba-icon\n @click=${this.handleEventGroupHide}\n data-group-index=\"${groupIndex}\"\n name=\"x\"\n clickable\n ></temba-icon>`\n : html`${eventGroup.events.length}\n ${eventGroup.events.length === 1\n ? html`event`\n : html`events`} `}\n </div>`\n : null}\n\n <div class=\"items\">\n ${eventGroup.events.map((event: ContactEvent) => {\n if (\n event.type === Events.TICKET_ASSIGNED &&\n (event as TicketEvent).note\n ) {\n const noteEvent = { ...event };\n noteEvent.type = Events.TICKET_NOTE_ADDED;\n\n return html`${this.renderEventContainer(\n noteEvent\n )}${this.renderEventContainer(event)}`;\n } else {\n return this.renderEventContainer(event);\n }\n })}\n </div>\n </div>`;\n })}\n </div>\n\n ${\n this.contact && this.contact.status === 'active'\n ? html`<div class=\"new-messages-container\">\n <div\n @click=${() => {\n this.scrollToBottom(true);\n }}\n class=\"new-messages ${getClasses({\n expanded: this.showMessageAlert,\n })}\"\n >\n New Messages\n </div>\n </div>`\n : null\n }\n \n </div>\n `;\n }\n}\n"]}
@@ -3,8 +3,10 @@ import { css, html } from 'lit';
3
3
  import { property } from 'lit/decorators.js';
4
4
  import { CustomEventType, TicketStatus } from '../interfaces';
5
5
  import { StoreElement } from '../store/StoreElement';
6
- import { getClasses, getFullName, postJSON, renderAvatar, stopEvent, } from '../utils';
6
+ import { getClasses, postJSON, stopEvent } from '../utils';
7
7
  import { Icon } from '../vectoricon';
8
+ const dropdownUserScale = 0.7;
9
+ const inlineUserScale = 0.8;
8
10
  export class ContactTickets extends StoreElement {
9
11
  constructor() {
10
12
  super(...arguments);
@@ -108,6 +110,10 @@ export class ContactTickets extends StoreElement {
108
110
  border-bottom: 1px solid #f3f3f3;
109
111
  }
110
112
 
113
+ .option-group temba-user {
114
+ flex-grow: 1;
115
+ }
116
+
111
117
  .assigned .user {
112
118
  flex-grow: 1;
113
119
  }
@@ -143,9 +149,6 @@ export class ContactTickets extends StoreElement {
143
149
  background: var(--color-selection);
144
150
  }
145
151
 
146
- .user .avatar {
147
- }
148
-
149
152
  .user .name {
150
153
  display: -webkit-box;
151
154
  -webkit-line-clamp: 1;
@@ -207,15 +210,6 @@ export class ContactTickets extends StoreElement {
207
210
  }
208
211
  }
209
212
  }
210
- renderUser(user) {
211
- if (!user) {
212
- return null;
213
- }
214
- return html `<div class="user">
215
- <div class="avatar">${renderAvatar({ user: user, scale: 0.6 })}</div>
216
- <div class="name">${getFullName(user)}</div>
217
- </div>`;
218
- }
219
213
  handleClose(uuid) {
220
214
  postJSON(`/api/v2/ticket_actions.json`, {
221
215
  tickets: [uuid],
@@ -246,6 +240,7 @@ export class ContactTickets extends StoreElement {
246
240
  if (ticket.assignee && ticket.assignee.email === email) {
247
241
  return;
248
242
  }
243
+ this.blur();
249
244
  postJSON(`/api/v2/ticket_actions.json`, {
250
245
  tickets: [uuid],
251
246
  action: 'assign',
@@ -312,13 +307,10 @@ export class ContactTickets extends StoreElement {
312
307
  <div slot="toggle" class="toggle">
313
308
  ${ticket.assignee
314
309
  ? html `
315
- <div>
316
- ${renderAvatar({
317
- name: ticket.assignee.name,
318
- user: ticket.assignee,
319
- scale: 0.7,
320
- })}
321
- </div>
310
+ <temba-user
311
+ email=${ticket.assignee.email}
312
+ scale="${inlineUserScale}"
313
+ ></temba-user>
322
314
  `
323
315
  : html `
324
316
  <temba-button
@@ -344,7 +336,11 @@ export class ContactTickets extends StoreElement {
344
336
  ? 'current-user'
345
337
  : ''}"
346
338
  >
347
- ${this.renderUser(users.find(user => user.email === ticket.assignee.email))}
339
+ <temba-user
340
+ email=${ticket.assignee.email}
341
+ name
342
+ scale="${dropdownUserScale}"
343
+ ></temba-user>
348
344
  <temba-button
349
345
  name="Unassign"
350
346
  primary
@@ -368,7 +364,11 @@ export class ContactTickets extends StoreElement {
368
364
  this.handleTicketAssignment(ticket.uuid, agent.email);
369
365
  }}
370
366
  >
371
- ${this.renderUser(agent)}
367
+ <temba-user
368
+ email=${agent.email}
369
+ name
370
+ scale="${dropdownUserScale}"
371
+ ></temba-user>
372
372
  </div>
373
373
  `
374
374
  : null}
@@ -388,7 +388,11 @@ export class ContactTickets extends StoreElement {
388
388
  this.handleTicketAssignment(ticket.uuid, user.email);
389
389
  }}
390
390
  >
391
- ${this.renderUser(user)}
391
+ <temba-user
392
+ email=${user.email}
393
+ scale="${dropdownUserScale}"
394
+ name
395
+ ></temba-user>
392
396
  </div>`;
393
397
  })}
394
398
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"ContactTickets.js","sourceRoot":"","sources":["../../../src/contacts/ContactTickets.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType, Ticket, TicketStatus, User } from '../interfaces';\nimport { StoreElement } from '../store/StoreElement';\nimport {\n getClasses,\n getFullName,\n postJSON,\n renderAvatar,\n stopEvent,\n} from '../utils';\nimport { Icon } from '../vectoricon';\n\nexport class ContactTickets extends StoreElement {\n @property({ type: String })\n agent: string;\n\n @property({ type: String })\n contact: string;\n\n @property({ type: String })\n ticket: string;\n\n @property({ type: Boolean })\n clickable = false;\n\n @property({ type: Boolean })\n expandable = false;\n\n @property({ type: Boolean })\n expanded = false;\n\n @property({ type: Object, attribute: false })\n data: Ticket[];\n\n static get styles() {\n return css`\n :host {\n }\n\n :hover {\n }\n\n .ticket.expandable:hover,\n .ticket.clickable:hover {\n cursor: pointer;\n box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.055),\n 0 0 0px 2px var(--color-link-primary);\n }\n\n .header {\n display: flex;\n flex-direction: row;\n flex-grow: 1;\n }\n\n .tickets {\n display: flex;\n flex-direction: column;\n padding: 0.3em 0.8em;\n }\n\n .count {\n margin-left: 0.5em;\n }\n\n .ticket {\n background: #fff;\n display: flex;\n flex-direction: column;\n margin-bottom: 0.5em;\n border-radius: var(--curvature);\n display: flex;\n flex-direction: column;\n align-items: stretch;\n box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.055),\n 0 0 0px 1px rgba(0, 0, 0, 0.02);\n transition: all 200ms ease-in-out;\n }\n\n .ticket .topic {\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0.5em 0.75em 0.5em 0.75em;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 1;\n flex-grow: 2;\n }\n\n .ticket .body {\n max-height: 0px;\n overflow-y: auto;\n -webkit-line-clamp: none;\n white-space: normal;\n width: initial;\n padding: 0.5em 0.75em 0em 0.75em;\n max-height: 40vh;\n display: none;\n margin-bottom: 0.5em;\n border-top: 1px solid #e6e6e6;\n }\n\n .ticket.expanded .body {\n display: block;\n }\n\n .status {\n --icon-color: #999;\n }\n\n .ticket.closed {\n background: #f9f9f9;\n color: #888;\n }\n\n .resolve {\n color: var(--color-primary-dark);\n }\n\n .dropdown {\n color: rgb(45, 45, 45);\n z-index: 50;\n width: 18em;\n }\n\n .option-group {\n padding: 0.4em;\n border-bottom: 1px solid #f3f3f3;\n }\n\n .assigned .user {\n flex-grow: 1;\n }\n\n .assigned {\n display: flex;\n align-items: center;\n }\n\n .assigned temba-button {\n margin-right: 0.75em;\n }\n\n .assigned .user:hover {\n cursor: default;\n background: none;\n }\n\n .options {\n max-height: 40vh;\n overflow-y: auto;\n border-bottom: none;\n }\n\n .user {\n display: flex;\n align-items: center;\n border-radius: var(--curvature);\n cursor: pointer;\n }\n\n .user:hover {\n background: var(--color-selection);\n }\n\n .user .avatar {\n }\n\n .user .name {\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n overflow: hidden;\n flex-grow: 1;\n }\n\n .user temba-button {\n margin-left: 0.5em;\n }\n\n .current-user {\n font-weight: 400;\n }\n\n .details {\n display: flex;\n align-items: center;\n flex-shrink: 1;\n margin-right: 0.5em;\n }\n\n .details .date {\n padding: 0em 0.5em;\n }\n\n .details .toggle {\n padding-right: 0.5em;\n }\n `;\n }\n\n prepareData(data: any): any {\n if (data && data.length) {\n data.sort((a: Ticket, b: Ticket) => {\n if (a.status == TicketStatus.Open && b.status == TicketStatus.Closed) {\n return -1;\n }\n\n if (b.status == TicketStatus.Open && a.status == TicketStatus.Closed) {\n return 1;\n }\n\n if (\n a.status == TicketStatus.Closed &&\n b.status == TicketStatus.Closed\n ) {\n return (\n new Date(b.closed_on).getTime() - new Date(a.closed_on).getTime()\n );\n }\n\n return (\n new Date(b.opened_on).getTime() - new Date(a.opened_on).getTime()\n );\n });\n }\n return data;\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('contact') || changes.has('ticket')) {\n if (this.contact) {\n this.url = `/api/v2/tickets.json?contact=${this.contact}${\n this.ticket ? '&ticket=' + this.ticket : ''\n }`;\n } else {\n this.url = null;\n }\n }\n }\n\n private renderUser(user: User) {\n if (!user) {\n return null;\n }\n return html`<div class=\"user\">\n <div class=\"avatar\">${renderAvatar({ user: user, scale: 0.6 })}</div>\n <div class=\"name\">${getFullName(user)}</div>\n </div>`;\n }\n\n private handleClose(uuid: string) {\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'close',\n })\n .then(() => {\n this.refresh();\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n private handleReopen(uuid: string) {\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'reopen',\n })\n .then(() => {\n this.refresh();\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n public handleTicketAssignment(uuid: string, email: string) {\n // if its already assigned to use, it's a noop\n const ticket = this.data.find(ticket => ticket.uuid === uuid);\n if (ticket.assignee && ticket.assignee.email === email) {\n return;\n }\n\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'assign',\n assignee: email,\n })\n .then(() => {\n this.refresh();\n })\n .catch((response: any) => {\n console.error(response);\n });\n return true;\n }\n\n public renderTicket(ticket: Ticket) {\n const date = ticket.opened_on;\n const users = this.store.getAssignableUsers();\n const agent = users.find(user => user.email === this.agent);\n return html`\n <div\n @click=${() => {\n if (this.clickable) {\n this.fireCustomEvent(CustomEventType.ButtonClicked, { ticket });\n } else if (this.expandable) {\n this.expanded = !this.expanded;\n }\n }}\n class=\"ticket ${ticket.status} ${getClasses({\n clickable: this.clickable,\n expandable: this.expandable,\n expanded: this.expanded,\n })}\"\n >\n <div class=\"header\">\n <div class=\"topic\">${ticket.topic.name}</div>\n\n <div class=\"details\">\n <div class=\"date\">\n <temba-date value=\"${date}\" display=\"duration\"></temba-date>\n </div>\n\n ${ticket.status === TicketStatus.Closed\n ? html`<div class=\"reopen\">\n <temba-button\n primary\n small\n name=\"Reopen\"\n @click=${(event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n this.handleReopen(ticket.uuid);\n }}\n ></temba-button>\n </div>`\n : html`\n <div>\n <temba-dropdown\n right\n arrowsize=\"8\"\n arrowoffset=\"-44\"\n offsety=\"8\"\n offsetx=${ticket.assignee ? -42 : -28}\n >\n <div slot=\"toggle\" class=\"toggle\">\n ${ticket.assignee\n ? html`\n <div>\n ${renderAvatar({\n name: ticket.assignee.name,\n user: ticket.assignee,\n scale: 0.7,\n })}\n </div>\n `\n : html`\n <temba-button\n name=\"Assign\"\n primary\n small\n ></temba-button>\n `}\n </div>\n\n <div\n slot=\"dropdown\"\n class=\"dropdown\"\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n }}\n >\n ${ticket.assignee\n ? html`\n <div\n class=\"assigned option-group ${agent &&\n ticket.assignee.email == agent.email\n ? 'current-user'\n : ''}\"\n >\n ${this.renderUser(\n users.find(\n user => user.email === ticket.assignee.email\n )\n )}\n <temba-button\n name=\"Unassign\"\n primary\n small\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n this.handleTicketAssignment(\n ticket.uuid,\n null\n );\n }}\n ></temba-button>\n </div>\n `\n : null}\n ${agent &&\n (!ticket.assignee ||\n agent.email !== ticket.assignee.email)\n ? html`\n <div\n class=\"current-user option-group\"\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n this.handleTicketAssignment(\n ticket.uuid,\n agent.email\n );\n }}\n >\n ${this.renderUser(agent)}\n </div>\n `\n : null}\n\n <div class=\"options option-group\">\n ${this.store.getAssignableUsers().map(user => {\n if (\n ticket.assignee &&\n user.email === ticket.assignee.email\n ) {\n return null;\n }\n\n if (user.email === this.agent) {\n return null;\n }\n return html`<div\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n this.handleTicketAssignment(\n ticket.uuid,\n user.email\n );\n }}\n >\n ${this.renderUser(user)}\n </div>`;\n })}\n </div>\n </div>\n </temba-dropdown>\n </div>\n <temba-tip\n text=\"Resolve\"\n position=\"left\"\n style=\"width:1.5em\"\n class=\"resolve\"\n >\n <temba-icon\n size=\"1.25\"\n name=\"${Icon.check}\"\n @click=${(event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n this.handleClose(ticket.uuid);\n }}\n ?clickable=${open}\n />\n </temba-tip>\n `}\n </div>\n </div>\n <div class=\"body\">${ticket.body}</div>\n </div>\n `;\n }\n\n public render(): TemplateResult {\n if (this.data && this.data.length > 0) {\n const tickets = this.data.map(ticket => {\n return this.renderTicket(ticket);\n });\n return html`${tickets}`;\n }\n\n return html`<slot name=\"empty\"></slot>`;\n }\n}\n"]}
1
+ {"version":3,"file":"ContactTickets.js","sourceRoot":"","sources":["../../../src/contacts/ContactTickets.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAU,YAAY,EAAQ,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,MAAM,OAAO,cAAe,SAAQ,YAAY;IAAhD;;QAWE,cAAS,GAAG,KAAK,CAAC;QAGlB,eAAU,GAAG,KAAK,CAAC;QAGnB,aAAQ,GAAG,KAAK,CAAC;IAucnB,CAAC;IAlcC,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoKT,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,IAAS;QACnB,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE;gBACjC,IAAI,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE;oBACpE,OAAO,CAAC,CAAC,CAAC;iBACX;gBAED,IAAI,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE;oBACpE,OAAO,CAAC,CAAC;iBACV;gBAED,IACE,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM;oBAC/B,CAAC,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,EAC/B;oBACA,OAAO,CACL,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAClE,CAAC;iBACH;gBAED,OAAO,CACL,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAClE,CAAC;YACJ,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAES,OAAO,CACf,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YACnD,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,IAAI,CAAC,GAAG,GAAG,gCAAgC,IAAI,CAAC,OAAO,GACrD,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAC3C,EAAE,CAAC;aACJ;iBAAM;gBACL,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;aACjB;SACF;IACH,CAAC;IAEO,WAAW,CAAC,IAAY;QAC9B,QAAQ,CAAC,6BAA6B,EAAE;YACtC,OAAO,EAAE,CAAC,IAAI,CAAC;YACf,MAAM,EAAE,OAAO;SAChB,CAAC;aACC,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,QAAa,EAAE,EAAE;YACvB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,YAAY,CAAC,IAAY;QAC/B,QAAQ,CAAC,6BAA6B,EAAE;YACtC,OAAO,EAAE,CAAC,IAAI,CAAC;YACf,MAAM,EAAE,QAAQ;SACjB,CAAC;aACC,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,QAAa,EAAE,EAAE;YACvB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,sBAAsB,CAAC,IAAY,EAAE,KAAa;QACvD,8CAA8C;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC9D,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,KAAK,EAAE;YACtD,OAAO;SACR;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QAEZ,QAAQ,CAAC,6BAA6B,EAAE;YACtC,OAAO,EAAE,CAAC,IAAI,CAAC;YACf,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,KAAK;SAChB,CAAC;aACC,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,QAAa,EAAE,EAAE;YACvB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACL,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,YAAY,CAAC,MAAc;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAA;;iBAEE,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;aACjE;iBAAM,IAAI,IAAI,CAAC,UAAU,EAAE;gBAC1B,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;aAChC;QACH,CAAC;wBACe,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC;YAC1C,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;;;+BAGqB,MAAM,CAAC,KAAK,CAAC,IAAI;;;;mCAIb,IAAI;;;cAGzB,MAAM,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM;YACrC,CAAC,CAAC,IAAI,CAAA;;;;;6BAKS,CAAC,KAAiB,EAAE,EAAE;gBAC7B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;;uBAEE;YACT,CAAC,CAAC,IAAI,CAAA;;;;;;;gCAOY,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;;;0BAGjC,MAAM,CAAC,QAAQ;gBACf,CAAC,CAAC,IAAI,CAAA;;wCAEQ,MAAM,CAAC,QAAQ,CAAC,KAAK;yCACpB,eAAe;;6BAE3B;gBACH,CAAC,CAAC,IAAI,CAAA;;;;;;6BAMH;;;;;;iCAMI,CAAC,KAAiB,EAAE,EAAE;gBAC7B,SAAS,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;;0BAEC,MAAM,CAAC,QAAQ;gBACf,CAAC,CAAC,IAAI,CAAA;;+DAE+B,KAAK;oBACpC,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;oBAClC,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,EAAE;;;0CAGI,MAAM,CAAC,QAAQ,CAAC,KAAK;;2CAEpB,iBAAiB;;;;;;2CAMjB,CAAC,KAAiB,EAAE,EAAE;oBAC7B,SAAS,CAAC,KAAK,CAAC,CAAC;oBACjB,IAAI,CAAC,sBAAsB,CACzB,MAAM,CAAC,IAAI,EACX,IAAI,CACL,CAAC;gBACJ,CAAC;;;6BAGN;gBACH,CAAC,CAAC,IAAI;0BACN,KAAK;gBACP,CAAC,CAAC,MAAM,CAAC,QAAQ;oBACf,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACtC,CAAC,CAAC,IAAI,CAAA;;;yCAGS,CAAC,KAAiB,EAAE,EAAE;oBAC7B,SAAS,CAAC,KAAK,CAAC,CAAC;oBACjB,IAAI,CAAC,sBAAsB,CACzB,MAAM,CAAC,IAAI,EACX,KAAK,CAAC,KAAK,CACZ,CAAC;gBACJ,CAAC;;;0CAGS,KAAK,CAAC,KAAK;;2CAEV,iBAAiB;;;6BAG/B;gBACH,CAAC,CAAC,IAAI;;;4BAGJ,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBAC3C,IACE,MAAM,CAAC,QAAQ;oBACf,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,QAAQ,CAAC,KAAK,EACpC;oBACA,OAAO,IAAI,CAAC;iBACb;gBAED,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE;oBAC7B,OAAO,IAAI,CAAC;iBACb;gBACD,OAAO,IAAI,CAAA;uCACA,CAAC,KAAiB,EAAE,EAAE;oBAC7B,SAAS,CAAC,KAAK,CAAC,CAAC;oBACjB,IAAI,CAAC,sBAAsB,CACzB,MAAM,CAAC,IAAI,EACX,IAAI,CAAC,KAAK,CACX,CAAC;gBACJ,CAAC;;;wCAGS,IAAI,CAAC,KAAK;yCACT,iBAAiB;;;mCAGvB,CAAC;YACV,CAAC,CAAC;;;;;;;;;;;;;8BAaE,IAAI,CAAC,KAAK;+BACT,CAAC,KAAiB,EAAE,EAAE;gBAC7B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;mCACY,IAAI;;;iBAGtB;;;4BAGW,MAAM,CAAC,IAAI;;KAElC,CAAC;IACJ,CAAC;IAEM,MAAM;QACX,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;gBACrC,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAA,GAAG,OAAO,EAAE,CAAC;SACzB;QAED,OAAO,IAAI,CAAA,4BAA4B,CAAC;IAC1C,CAAC;CACF;AAtdC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6CACb;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CACX;AAGhB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CACZ;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;iDACV;AAGlB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;kDACT;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gDACX;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4CAC9B","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType, Ticket, TicketStatus, User } from '../interfaces';\nimport { StoreElement } from '../store/StoreElement';\nimport { getClasses, postJSON, stopEvent } from '../utils';\nimport { Icon } from '../vectoricon';\n\nconst dropdownUserScale = 0.7;\nconst inlineUserScale = 0.8;\n\nexport class ContactTickets extends StoreElement {\n @property({ type: String })\n agent: string;\n\n @property({ type: String })\n contact: string;\n\n @property({ type: String })\n ticket: string;\n\n @property({ type: Boolean })\n clickable = false;\n\n @property({ type: Boolean })\n expandable = false;\n\n @property({ type: Boolean })\n expanded = false;\n\n @property({ type: Object, attribute: false })\n data: Ticket[];\n\n static get styles() {\n return css`\n :host {\n }\n\n :hover {\n }\n\n .ticket.expandable:hover,\n .ticket.clickable:hover {\n cursor: pointer;\n box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.055),\n 0 0 0px 2px var(--color-link-primary);\n }\n\n .header {\n display: flex;\n flex-direction: row;\n flex-grow: 1;\n }\n\n .tickets {\n display: flex;\n flex-direction: column;\n padding: 0.3em 0.8em;\n }\n\n .count {\n margin-left: 0.5em;\n }\n\n .ticket {\n background: #fff;\n display: flex;\n flex-direction: column;\n margin-bottom: 0.5em;\n border-radius: var(--curvature);\n display: flex;\n flex-direction: column;\n align-items: stretch;\n box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.055),\n 0 0 0px 1px rgba(0, 0, 0, 0.02);\n transition: all 200ms ease-in-out;\n }\n\n .ticket .topic {\n overflow: hidden;\n text-overflow: ellipsis;\n margin: 0.5em 0.75em 0.5em 0.75em;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 1;\n flex-grow: 2;\n }\n\n .ticket .body {\n max-height: 0px;\n overflow-y: auto;\n -webkit-line-clamp: none;\n white-space: normal;\n width: initial;\n padding: 0.5em 0.75em 0em 0.75em;\n max-height: 40vh;\n display: none;\n margin-bottom: 0.5em;\n border-top: 1px solid #e6e6e6;\n }\n\n .ticket.expanded .body {\n display: block;\n }\n\n .status {\n --icon-color: #999;\n }\n\n .ticket.closed {\n background: #f9f9f9;\n color: #888;\n }\n\n .resolve {\n color: var(--color-primary-dark);\n }\n\n .dropdown {\n color: rgb(45, 45, 45);\n z-index: 50;\n width: 18em;\n }\n\n .option-group {\n padding: 0.4em;\n border-bottom: 1px solid #f3f3f3;\n }\n\n .option-group temba-user {\n flex-grow: 1;\n }\n\n .assigned .user {\n flex-grow: 1;\n }\n\n .assigned {\n display: flex;\n align-items: center;\n }\n\n .assigned temba-button {\n margin-right: 0.75em;\n }\n\n .assigned .user:hover {\n cursor: default;\n background: none;\n }\n\n .options {\n max-height: 40vh;\n overflow-y: auto;\n border-bottom: none;\n }\n\n .user {\n display: flex;\n align-items: center;\n border-radius: var(--curvature);\n cursor: pointer;\n }\n\n .user:hover {\n background: var(--color-selection);\n }\n\n .user .name {\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n overflow: hidden;\n flex-grow: 1;\n }\n\n .user temba-button {\n margin-left: 0.5em;\n }\n\n .current-user {\n font-weight: 400;\n }\n\n .details {\n display: flex;\n align-items: center;\n flex-shrink: 1;\n margin-right: 0.5em;\n }\n\n .details .date {\n padding: 0em 0.5em;\n }\n\n .details .toggle {\n padding-right: 0.5em;\n }\n `;\n }\n\n prepareData(data: any): any {\n if (data && data.length) {\n data.sort((a: Ticket, b: Ticket) => {\n if (a.status == TicketStatus.Open && b.status == TicketStatus.Closed) {\n return -1;\n }\n\n if (b.status == TicketStatus.Open && a.status == TicketStatus.Closed) {\n return 1;\n }\n\n if (\n a.status == TicketStatus.Closed &&\n b.status == TicketStatus.Closed\n ) {\n return (\n new Date(b.closed_on).getTime() - new Date(a.closed_on).getTime()\n );\n }\n\n return (\n new Date(b.opened_on).getTime() - new Date(a.opened_on).getTime()\n );\n });\n }\n return data;\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('contact') || changes.has('ticket')) {\n if (this.contact) {\n this.url = `/api/v2/tickets.json?contact=${this.contact}${\n this.ticket ? '&ticket=' + this.ticket : ''\n }`;\n } else {\n this.url = null;\n }\n }\n }\n\n private handleClose(uuid: string) {\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'close',\n })\n .then(() => {\n this.refresh();\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n private handleReopen(uuid: string) {\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'reopen',\n })\n .then(() => {\n this.refresh();\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n public handleTicketAssignment(uuid: string, email: string) {\n // if its already assigned to use, it's a noop\n const ticket = this.data.find(ticket => ticket.uuid === uuid);\n if (ticket.assignee && ticket.assignee.email === email) {\n return;\n }\n this.blur();\n\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'assign',\n assignee: email,\n })\n .then(() => {\n this.refresh();\n })\n .catch((response: any) => {\n console.error(response);\n });\n return true;\n }\n\n public renderTicket(ticket: Ticket) {\n const date = ticket.opened_on;\n const users = this.store.getAssignableUsers();\n const agent = users.find(user => user.email === this.agent);\n return html`\n <div\n @click=${() => {\n if (this.clickable) {\n this.fireCustomEvent(CustomEventType.ButtonClicked, { ticket });\n } else if (this.expandable) {\n this.expanded = !this.expanded;\n }\n }}\n class=\"ticket ${ticket.status} ${getClasses({\n clickable: this.clickable,\n expandable: this.expandable,\n expanded: this.expanded,\n })}\"\n >\n <div class=\"header\">\n <div class=\"topic\">${ticket.topic.name}</div>\n\n <div class=\"details\">\n <div class=\"date\">\n <temba-date value=\"${date}\" display=\"duration\"></temba-date>\n </div>\n\n ${ticket.status === TicketStatus.Closed\n ? html`<div class=\"reopen\">\n <temba-button\n primary\n small\n name=\"Reopen\"\n @click=${(event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n this.handleReopen(ticket.uuid);\n }}\n ></temba-button>\n </div>`\n : html`\n <div>\n <temba-dropdown\n right\n arrowsize=\"8\"\n arrowoffset=\"-44\"\n offsety=\"8\"\n offsetx=${ticket.assignee ? -42 : -28}\n >\n <div slot=\"toggle\" class=\"toggle\">\n ${ticket.assignee\n ? html`\n <temba-user\n email=${ticket.assignee.email}\n scale=\"${inlineUserScale}\"\n ></temba-user>\n `\n : html`\n <temba-button\n name=\"Assign\"\n primary\n small\n ></temba-button>\n `}\n </div>\n\n <div\n slot=\"dropdown\"\n class=\"dropdown\"\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n }}\n >\n ${ticket.assignee\n ? html`\n <div\n class=\"assigned option-group ${agent &&\n ticket.assignee.email == agent.email\n ? 'current-user'\n : ''}\"\n >\n <temba-user\n email=${ticket.assignee.email}\n name\n scale=\"${dropdownUserScale}\"\n ></temba-user>\n <temba-button\n name=\"Unassign\"\n primary\n small\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n this.handleTicketAssignment(\n ticket.uuid,\n null\n );\n }}\n ></temba-button>\n </div>\n `\n : null}\n ${agent &&\n (!ticket.assignee ||\n agent.email !== ticket.assignee.email)\n ? html`\n <div\n class=\"current-user option-group\"\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n this.handleTicketAssignment(\n ticket.uuid,\n agent.email\n );\n }}\n >\n <temba-user\n email=${agent.email}\n name\n scale=\"${dropdownUserScale}\"\n ></temba-user>\n </div>\n `\n : null}\n\n <div class=\"options option-group\">\n ${this.store.getAssignableUsers().map(user => {\n if (\n ticket.assignee &&\n user.email === ticket.assignee.email\n ) {\n return null;\n }\n\n if (user.email === this.agent) {\n return null;\n }\n return html`<div\n @click=${(event: MouseEvent) => {\n stopEvent(event);\n this.handleTicketAssignment(\n ticket.uuid,\n user.email\n );\n }}\n >\n <temba-user\n email=${user.email}\n scale=\"${dropdownUserScale}\"\n name\n ></temba-user>\n </div>`;\n })}\n </div>\n </div>\n </temba-dropdown>\n </div>\n <temba-tip\n text=\"Resolve\"\n position=\"left\"\n style=\"width:1.5em\"\n class=\"resolve\"\n >\n <temba-icon\n size=\"1.25\"\n name=\"${Icon.check}\"\n @click=${(event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n this.handleClose(ticket.uuid);\n }}\n ?clickable=${open}\n />\n </temba-tip>\n `}\n </div>\n </div>\n <div class=\"body\">${ticket.body}</div>\n </div>\n `;\n }\n\n public render(): TemplateResult {\n if (this.data && this.data.length > 0) {\n const tickets = this.data.map(ticket => {\n return this.renderTicket(ticket);\n });\n return html`${tickets}`;\n }\n\n return html`<slot name=\"empty\"></slot>`;\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { css, html } from 'lit';
2
- import { getClasses, oxford, oxfordFn, oxfordNamed, renderAvatar, } from '../utils';
2
+ import { getClasses, oxford, oxfordFn, oxfordNamed } from '../utils';
3
3
  import { Icon } from '../vectoricon';
4
4
  import { getDisplayName } from './helpers';
5
5
  export const getEventStyles = () => {
@@ -600,7 +600,7 @@ export const renderAttachment = (attachment) => {
600
600
  }
601
601
  return html `<div style="">${inner}</div>`;
602
602
  };
603
- export const renderMsgEvent = (event, agent) => {
603
+ export const renderMsgEvent = (event) => {
604
604
  const isInbound = event.type === Events.MESSAGE_RECEIVED;
605
605
  const isError = event.status === 'E';
606
606
  const isFailure = event.status === 'F';
@@ -692,9 +692,10 @@ export const renderMsgEvent = (event, agent) => {
692
692
  </div>
693
693
 
694
694
  ${!isInbound && event.created_by
695
- ? html `<div style="margin-left:0.8em;margin-top:0.3em;font-size:0.9em">
696
- ${renderAvatar({ user: event.created_by })}
697
- </div>`
695
+ ? html `<temba-user
696
+ style="margin-left:0.5em"
697
+ email=${event.created_by.email}
698
+ ></temba-user>`
698
699
  : null}
699
700
  </div>`;
700
701
  };
@@ -813,9 +814,7 @@ export const renderNoteCreated = (event) => {
813
814
  ></temba-date>
814
815
  </div>
815
816
  </div>
816
- <div style="margin-left:0.8em;margin-top:0.3em;">
817
- ${renderAvatar({ user: event.created_by })}
818
- </div>
817
+ <temba-user email=${event.created_by.email}></temba-user>
819
818
  </div>`;
820
819
  };
821
820
  export const renderTicketAction = (event, action, grouped) => {