@nyaruka/temba-components 0.58.5 → 0.58.8

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 (56) hide show
  1. package/.devcontainer/devcontainer.json +4 -0
  2. package/.github/workflows/build.yml +2 -1
  3. package/.github/workflows/publish.yml +1 -0
  4. package/CHANGELOG.md +20 -0
  5. package/dist/{98acdbde.js → 82b805ce.js} +30 -2
  6. package/dist/index.js +30 -2
  7. package/dist/sw.js +1 -1
  8. package/dist/sw.js.map +1 -1
  9. package/dist/templates/components-body.html +1 -1
  10. package/dist/templates/components-head.html +1 -1
  11. package/out-tsc/src/contacts/events.js +39 -1
  12. package/out-tsc/src/contacts/events.js.map +1 -1
  13. package/package.json +1 -1
  14. package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
  15. package/screenshots/truth/checkbox/checkbox-no-label-no-background-hover.png +0 -0
  16. package/screenshots/truth/checkbox/checkbox-whitespace-label-no-background-hover.png +0 -0
  17. package/screenshots/truth/checkbox/checked.png +0 -0
  18. package/screenshots/truth/checkbox/default.png +0 -0
  19. package/screenshots/truth/contacts/badges.png +0 -0
  20. package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
  21. package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
  22. package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
  23. package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
  24. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
  25. package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
  26. package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
  27. package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
  28. package/screenshots/truth/contacts/contact-active-default.png +0 -0
  29. package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
  30. package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
  31. package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
  32. package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
  33. package/screenshots/truth/contacts/details.png +0 -0
  34. package/screenshots/truth/contacts/history.png +0 -0
  35. package/screenshots/truth/contacts/tickets-assignment.png +0 -0
  36. package/screenshots/truth/contacts/tickets.png +0 -0
  37. package/screenshots/truth/label/custom.png +0 -0
  38. package/screenshots/truth/label/danger.png +0 -0
  39. package/screenshots/truth/label/dark.png +0 -0
  40. package/screenshots/truth/label/default-icon.png +0 -0
  41. package/screenshots/truth/label/primary.png +0 -0
  42. package/screenshots/truth/label/secondary.png +0 -0
  43. package/screenshots/truth/label/shadow.png +0 -0
  44. package/screenshots/truth/label/tertiary.png +0 -0
  45. package/screenshots/truth/list/fields-dragging.png +0 -0
  46. package/screenshots/truth/list/fields-filtered.png +0 -0
  47. package/screenshots/truth/list/fields-hovered.png +0 -0
  48. package/screenshots/truth/list/fields.png +0 -0
  49. package/screenshots/truth/menu/menu-focused-with items.png +0 -0
  50. package/screenshots/truth/menu/menu-refresh-1.png +0 -0
  51. package/screenshots/truth/menu/menu-refresh-2.png +0 -0
  52. package/screenshots/truth/menu/menu-submenu.png +0 -0
  53. package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
  54. package/screenshots/truth/menu/menu-tasks.png +0 -0
  55. package/screenshots/truth/select/selection-clearable.png +0 -0
  56. package/src/contacts/events.ts +38 -1
@@ -6,6 +6,10 @@
6
6
  "forwardPorts": [
7
7
  3010
8
8
  ],
9
+ "runArgs": [
10
+ "--network=textit_default",
11
+ "--hostname=temba-components"
12
+ ],
9
13
  "remoteUser": "node",
10
14
  "postCreateCommand": "sudo chown -R node /workspaces/temba-components/static/svg && sudo chown node /workspaces/temba-components && sudo chown node /workspaces/temba-components/screenshots && yarn install"
11
15
  // "features": {},
@@ -8,6 +8,7 @@ jobs:
8
8
  steps:
9
9
  - name: Checkout (GitHub)
10
10
  uses: actions/checkout@v3
11
+ - run: docker network create --driver bridge textit_default
11
12
  - name: Build and run dev container task
12
13
  uses: devcontainers/ci@v0.3
13
14
  with:
@@ -27,4 +28,4 @@ jobs:
27
28
  uses: codecov/codecov-action@v3
28
29
  with:
29
30
  token: ${{secrets.CODECOV_TOKEN}}
30
- files: coverage/lcov.info
31
+ files: coverage/lcov.info
@@ -12,6 +12,7 @@ jobs:
12
12
  steps:
13
13
  - name: Checkout (GitHub)
14
14
  uses: actions/checkout@v3
15
+ - run: docker network create --driver bridge textit_default
15
16
  - name: Build and run dev container task
16
17
  uses: devcontainers/ci@v0.3
17
18
  with:
package/CHANGELOG.md CHANGED
@@ -4,8 +4,28 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v0.58.8](https://github.com/nyaruka/temba-components/compare/v0.58.7...v0.58.8)
8
+
9
+ - Update publish.yml [`7dc7d69`](https://github.com/nyaruka/temba-components/commit/7dc7d69822942b39c3b35e06846cfd4c65108b2d)
10
+
11
+ #### [v0.58.7](https://github.com/nyaruka/temba-components/compare/v0.58.6...v0.58.7)
12
+
13
+ > 28 September 2023
14
+
15
+ #### [v0.58.6](https://github.com/nyaruka/temba-components/compare/v0.58.5...v0.58.6)
16
+
17
+ > 28 September 2023
18
+
19
+ - Support rendering optin request [`#359`](https://github.com/nyaruka/temba-components/pull/359)
20
+ - Update screenshots [`#361`](https://github.com/nyaruka/temba-components/pull/361)
21
+ - Adjust styles [`cf34f3f`](https://github.com/nyaruka/temba-components/commit/cf34f3f69439c63554ebec5fdff2fb7ecaf22158)
22
+ - Update build.yml [`94587ec`](https://github.com/nyaruka/temba-components/commit/94587ec8e55c022665cedb1b32348015d9e5d4e6)
23
+ - Fix build [`67e8cd6`](https://github.com/nyaruka/temba-components/commit/67e8cd69ba8a1ac70176e333d0088d855185720d)
24
+
7
25
  #### [v0.58.5](https://github.com/nyaruka/temba-components/compare/v0.58.4...v0.58.5)
8
26
 
27
+ > 6 September 2023
28
+
9
29
  - Update more permissions [`d4ed2b7`](https://github.com/nyaruka/temba-components/commit/d4ed2b7e405f3b5e93bafffb051b12ab79e134ad)
10
30
 
11
31
  #### [v0.58.4](https://github.com/nyaruka/temba-components/compare/v0.58.3...v0.58.4)
@@ -1867,7 +1867,18 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
1867
1867
  </div>`))}
1868
1868
  </div> `:null}
1869
1869
  </div>
1870
- ${t.msg.text||t.msg.attachments?null:D`<div class="unsupported">Unsupported Message</div>`}
1870
+ ${t.optin?D`<div class="optin">
1871
+ <temba-icon
1872
+ size="1"
1873
+ class="broadcast inline"
1874
+ name="${pt.restore}"
1875
+ ></temba-icon>
1876
+ <div class="text">
1877
+ Requested Opt In for
1878
+ <span class="italic">${t.optin.name}</span>
1879
+ </div>
1880
+ </div>`:null}
1881
+ ${t.msg.text||t.msg.attachments||t.optin?null:D`<div class="unsupported">Unsupported Message</div>`}
1871
1882
 
1872
1883
  <div
1873
1884
  class="msg-summary"
@@ -2271,6 +2282,23 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
2271
2282
  border-radius: var(--curvature);
2272
2283
  }
2273
2284
 
2285
+ .optin {
2286
+ border: 1px solid #f2f2f2;
2287
+ color: #999;
2288
+ padding: 0.5em 1em;
2289
+ border-radius: var(--curvature);
2290
+ display: inline-flex;
2291
+ }
2292
+
2293
+ .optin .text {
2294
+ margin-left: 0.5em;
2295
+ display: inline;
2296
+ }
2297
+
2298
+ .optin span.italic {
2299
+ font-style: italic;
2300
+ }
2301
+
2274
2302
  .time {
2275
2303
  padding: 0.3em 1px;
2276
2304
  }
@@ -2598,7 +2626,7 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
2598
2626
  ${t.campaign_event.offset_display}
2599
2627
  ${t.campaign_event.relative_to.name}</span
2600
2628
  >
2601
- </div>`)(t);case al.CHANNEL_EVENT:return(t=>{let e="",i=pt.call;return"mt_miss"===t.channel_event_type?(e="Missed outgoing call",i=pt.call_missed):"mo_miss"===t.channel_event_type?(e="Missed incoming call",i=pt.call_missed):"new_conversation"===t.channel_event_type?(e="Started Conversation",i=pt.event):"welcome_message"===t.channel_event_type?(e="Welcome Message Sent",i=pt.event):"referral"===t.channel_event_type?(e="Referred",i=pt.event):"follow"===t.channel_event_type?(e="Followed",i=pt.event):"stop_contact"===t.channel_event_type?(e="Stopped",i=pt.contact_stopped):"mt_call"===t.channel_event_type?e="Outgoing Phone Call":"mo_call"==t.channel_event_type&&(e="Incoming Phone call"),D`<temba-icon name="${i}"></temba-icon>
2629
+ </div>`)(t);case al.CHANNEL_EVENT:return(t=>{let e="",i=pt.call;return"mt_miss"===t.channel_event_type?(e="Missed outgoing call",i=pt.call_missed):"mo_miss"===t.channel_event_type?(e="Missed incoming call",i=pt.call_missed):"new_conversation"===t.channel_event_type?(e="Started Conversation",i=pt.event):"welcome_message"===t.channel_event_type?(e="Welcome Message Sent",i=pt.event):"referral"===t.channel_event_type?(e="Referred",i=pt.event):"follow"===t.channel_event_type?(e="Followed",i=pt.event):"stop_contact"===t.channel_event_type?(e="Stopped",i=pt.contact_stopped):"mt_call"===t.channel_event_type?e="Outgoing Phone Call":"mo_call"==t.channel_event_type?e="Incoming Phone call":"optin"==t.channel_event_type?(e="Opted in",i=pt.restore):"optout"==t.channel_event_type&&(e="Opted out",i=pt.error),D`<temba-icon name="${i}"></temba-icon>
2602
2630
  <div class="description">${e}</div>`})(t);case al.CONTACT_LANGUAGE_CHANGED:return(t=>D`<temba-icon name="${pt.contact_updated}"></temba-icon>
2603
2631
  <div class="description">
2604
2632
  Language updated to <span class="attn">${t.language}</span>
package/dist/index.js CHANGED
@@ -1867,7 +1867,18 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
1867
1867
  </div>`))}
1868
1868
  </div> `:null}
1869
1869
  </div>
1870
- ${t.msg.text||t.msg.attachments?null:D`<div class="unsupported">Unsupported Message</div>`}
1870
+ ${t.optin?D`<div class="optin">
1871
+ <temba-icon
1872
+ size="1"
1873
+ class="broadcast inline"
1874
+ name="${pt.restore}"
1875
+ ></temba-icon>
1876
+ <div class="text">
1877
+ Requested Opt In for
1878
+ <span class="italic">${t.optin.name}</span>
1879
+ </div>
1880
+ </div>`:null}
1881
+ ${t.msg.text||t.msg.attachments||t.optin?null:D`<div class="unsupported">Unsupported Message</div>`}
1871
1882
 
1872
1883
  <div
1873
1884
  class="msg-summary"
@@ -2271,6 +2282,23 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
2271
2282
  border-radius: var(--curvature);
2272
2283
  }
2273
2284
 
2285
+ .optin {
2286
+ border: 1px solid #f2f2f2;
2287
+ color: #999;
2288
+ padding: 0.5em 1em;
2289
+ border-radius: var(--curvature);
2290
+ display: inline-flex;
2291
+ }
2292
+
2293
+ .optin .text {
2294
+ margin-left: 0.5em;
2295
+ display: inline;
2296
+ }
2297
+
2298
+ .optin span.italic {
2299
+ font-style: italic;
2300
+ }
2301
+
2274
2302
  .time {
2275
2303
  padding: 0.3em 1px;
2276
2304
  }
@@ -2598,7 +2626,7 @@ function t(t,e,i,n){var o,s=arguments.length,r=s<3?e:null===n?n=Object.getOwnPro
2598
2626
  ${t.campaign_event.offset_display}
2599
2627
  ${t.campaign_event.relative_to.name}</span
2600
2628
  >
2601
- </div>`)(t);case al.CHANNEL_EVENT:return(t=>{let e="",i=pt.call;return"mt_miss"===t.channel_event_type?(e="Missed outgoing call",i=pt.call_missed):"mo_miss"===t.channel_event_type?(e="Missed incoming call",i=pt.call_missed):"new_conversation"===t.channel_event_type?(e="Started Conversation",i=pt.event):"welcome_message"===t.channel_event_type?(e="Welcome Message Sent",i=pt.event):"referral"===t.channel_event_type?(e="Referred",i=pt.event):"follow"===t.channel_event_type?(e="Followed",i=pt.event):"stop_contact"===t.channel_event_type?(e="Stopped",i=pt.contact_stopped):"mt_call"===t.channel_event_type?e="Outgoing Phone Call":"mo_call"==t.channel_event_type&&(e="Incoming Phone call"),D`<temba-icon name="${i}"></temba-icon>
2629
+ </div>`)(t);case al.CHANNEL_EVENT:return(t=>{let e="",i=pt.call;return"mt_miss"===t.channel_event_type?(e="Missed outgoing call",i=pt.call_missed):"mo_miss"===t.channel_event_type?(e="Missed incoming call",i=pt.call_missed):"new_conversation"===t.channel_event_type?(e="Started Conversation",i=pt.event):"welcome_message"===t.channel_event_type?(e="Welcome Message Sent",i=pt.event):"referral"===t.channel_event_type?(e="Referred",i=pt.event):"follow"===t.channel_event_type?(e="Followed",i=pt.event):"stop_contact"===t.channel_event_type?(e="Stopped",i=pt.contact_stopped):"mt_call"===t.channel_event_type?e="Outgoing Phone Call":"mo_call"==t.channel_event_type?e="Incoming Phone call":"optin"==t.channel_event_type?(e="Opted in",i=pt.restore):"optout"==t.channel_event_type&&(e="Opted out",i=pt.error),D`<temba-icon name="${i}"></temba-icon>
2602
2630
  <div class="description">${e}</div>`})(t);case al.CONTACT_LANGUAGE_CHANGED:return(t=>D`<temba-icon name="${pt.contact_updated}"></temba-icon>
2603
2631
  <div class="description">
2604
2632
  Language updated to <span class="attn">${t.language}</span>
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:"98acdbde.js",revision:"cf66430e3d2bd0a928053ddfd92de68f"},{url:"templates/components-body.html",revision:"c8a106bc6b871ba5eea31626bfb16a08"},{url:"templates/components-head.html",revision:"b7a29a505e05a152c5417db5fe8f5bb5"}],{}),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 r={};const l=e=>o(e,i),c={module:{uri:i},exports:r,require:l};t[i]=Promise.all(n.map((e=>c[e]||l(e)))).then((e=>(s(...e),r)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"82b805ce.js",revision:"f157074d9195333688bb75224b844e1e"},{url:"templates/components-body.html",revision:"7512b1888d19dfa0c7f7a12a97708dea"},{url:"templates/components-head.html",revision:"dccf17c4ac4bf85d472a7722889366fb"}],{}),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/c4842a59a53ff203c81535e3fc02ea15/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\": \"98acdbde.js\",\n \"revision\": \"cf66430e3d2bd0a928053ddfd92de68f\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"c8a106bc6b871ba5eea31626bfb16a08\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"b7a29a505e05a152c5417db5fe8f5bb5\"\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/5e788e0e63c9cadbcf7cc62696303f11/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\": \"82b805ce.js\",\n \"revision\": \"f157074d9195333688bb75224b844e1e\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"7512b1888d19dfa0c7f7a12a97708dea\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"dccf17c4ac4bf85d472a7722889366fb\"\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/98acdbde.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.58.5"</script>
1
+ <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/82b805ce.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.58.8"</script>
@@ -1 +1 @@
1
- <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/98acdbde.js" crossorigin="anonymous">
1
+ <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/82b805ce.js" crossorigin="anonymous">
@@ -361,6 +361,23 @@ export const getEventStyles = () => {
361
361
  border-radius: var(--curvature);
362
362
  }
363
363
 
364
+ .optin {
365
+ border: 1px solid #f2f2f2;
366
+ color: #999;
367
+ padding: 0.5em 1em;
368
+ border-radius: var(--curvature);
369
+ display: inline-flex;
370
+ }
371
+
372
+ .optin .text {
373
+ margin-left: 0.5em;
374
+ display: inline;
375
+ }
376
+
377
+ .optin span.italic {
378
+ font-style: italic;
379
+ }
380
+
364
381
  .time {
365
382
  padding: 0.3em 1px;
366
383
  }
@@ -655,7 +672,20 @@ export const renderMsgEvent = (event, agent) => {
655
672
  </div> `
656
673
  : null}
657
674
  </div>
658
- ${!event.msg.text && !event.msg.attachments
675
+ ${event.optin
676
+ ? html `<div class="optin">
677
+ <temba-icon
678
+ size="1"
679
+ class="broadcast inline"
680
+ name="${Icon.restore}"
681
+ ></temba-icon>
682
+ <div class="text">
683
+ Requested Opt In for
684
+ <span class="italic">${event.optin.name}</span>
685
+ </div>
686
+ </div>`
687
+ : null}
688
+ ${!event.msg.text && !event.msg.attachments && !event.optin
659
689
  ? html `<div class="unsupported">Unsupported Message</div>`
660
690
  : null}
661
691
 
@@ -986,6 +1016,14 @@ export const renderChannelEvent = (event) => {
986
1016
  else if (event.channel_event_type == 'mo_call') {
987
1017
  eventMessage = 'Incoming Phone call';
988
1018
  }
1019
+ else if (event.channel_event_type == 'optin') {
1020
+ eventMessage = 'Opted in';
1021
+ icon = Icon.restore;
1022
+ }
1023
+ else if (event.channel_event_type == 'optout') {
1024
+ eventMessage = 'Opted out';
1025
+ icon = Icon.error;
1026
+ }
989
1027
  return html `<temba-icon name="${icon}"></temba-icon>
990
1028
  <div class="description">${eventMessage}</div>`;
991
1029
  };
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/contacts/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAEhD,OAAO,EACL,UAAU,EACV,MAAM,EACN,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6cT,CAAC;AACJ,CAAC,CAAC;AAQF,MAAM,CAAN,IAAY,MA4BX;AA5BD,WAAY,MAAM;IAChB,yCAA+B,CAAA;IAC/B,2CAAiC,CAAA;IACjC,iDAAuC,CAAA;IACvC,qCAA2B,CAAA;IAC3B,uCAA6B,CAAA;IAC7B,qCAA2B,CAAA;IAC3B,mDAAyC,CAAA;IACzC,yDAA+C,CAAA;IAC/C,2DAAiD,CAAA;IACjD,uDAA6C,CAAA;IAC7C,uDAA6C,CAAA;IAC7C,2CAAiC,CAAA;IACjC,yCAA+B,CAAA;IAC/B,+DAAqD,CAAA;IACrD,2CAAiC,CAAA;IACjC,qDAA2C,CAAA;IAC3C,uCAA6B,CAAA;IAC7B,mCAAyB,CAAA;IACzB,mDAAyC,CAAA;IACzC,uCAA6B,CAAA;IAC7B,6CAAmC,CAAA;IACnC,iDAAuC,CAAA;IACvC,yCAA+B,CAAA;IAC/B,yCAA+B,CAAA;IAC/B,6CAAmC,CAAA;IACnC,yBAAe,CAAA;IACf,6BAAmB,CAAA;AACrB,CAAC,EA5BW,MAAM,KAAN,MAAM,QA4BjB;AA6HD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAmB,EAAE,MAAc,EAAE,EAAE;IACvE,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,UAAU,CAAC;KACnB;IAED,QAAQ,KAAK,CAAC,IAAI,EAAE;QAClB,KAAK,MAAM,CAAC,eAAe,CAAC;QAC5B,KAAK,MAAM,CAAC,aAAa,CAAC;QAC1B,KAAK,MAAM,CAAC,aAAa,CAAC;QAC1B,KAAK,MAAM,CAAC,eAAe;YACzB,IAAI,CAAC,MAAM,EAAE;gBACX,OAAO,SAAS,CAAC;aAClB;YAED,IAAK,KAAqB,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;gBACjD,OAAO,SAAS,CAAC;aAClB;YAED,MAAM;QACR,KAAK,MAAM,CAAC,YAAY,CAAC;QACzB,KAAK,MAAM,CAAC,WAAW;YACrB,OAAO,OAAO,CAAC;QACjB,KAAK,MAAM,CAAC,iBAAiB,CAAC;QAC9B,KAAK,MAAM,CAAC,eAAe,CAAC;QAC5B,KAAK,MAAM,CAAC,gBAAgB,CAAC;QAC7B,KAAK,MAAM,CAAC,WAAW,CAAC;QACxB,KAAK,MAAM,CAAC,iBAAiB,CAAC;QAC9B,KAAK,MAAM,CAAC,YAAY;YACtB,OAAO,UAAU,CAAC;KACrB;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAE,EAAE;IAC7C,OAAO,IAAI,CAAA;MACP,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;SACrC,CAAC;AACV,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAkB,EAAkB,EAAE;IACrE,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAE/C,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,IAAI,SAAS,KAAK,OAAO,EAAE;QACzB,KAAK,GAAG,IAAI,CAAA;kBACE,GAAG;KAChB,CAAC;KACH;SAAM,IAAI,GAAG,KAAK,KAAK,EAAE;QACxB,OAAO,IAAI,CAAA;;mBAEI,GAAG,8GAA8G,CAAC;KAClI;SAAM,IAAI,SAAS,KAAK,OAAO,EAAE;QAChC,OAAO,IAAI,CAAA;;;;;qBAKM,GAAG;cACV,CAAC;KACZ;SAAM,IAAI,SAAS,KAAK,OAAO,EAAE;QAChC,OAAO,IAAI,CAAA;;aAEF,GAAG;cACF,OAAO;;;4BAGO,GAAG,KAAK,GAAG;aAC1B,CAAC;KACX;SAAM,IAAI,OAAO,KAAK,KAAK,EAAE;QAC5B,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,GAAG,GAAG,YAAY,IAAI,QAAQ,CAAC;QAE3C,OAAO,IAAI,CAAA;;;;;;;;kEAQmD,SAAS;YACrE,KAAK,YAAY,QAAQ,GAAG,KAAK,MAAM,SAAS;YAChD,KAAK,YAAY,QAAQ;YACzB,KAAK,sCAAsC,GAAG;eACrC,CAAC;KACb;SAAM;QACL,OAAO,IAAI,CAAA;0BACW,IAAI,CAAC,QAAQ;wBACf,GAAG;WAChB,CAAC;KACT;IAED,OAAO,IAAI,CAAA,iBAAiB,KAAK,QAAQ,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,KAAe,EACf,KAAa,EACG,EAAE;IAClB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,gBAAgB,CAAC;IACzD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;IAEvC,sDAAsD;IACtD,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,IAAI,KAAK,CAAC,QAAQ,EAAE;QAClB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;;;gBAGL,KAAK,CAAC,QAAQ;gBACd,IAAI,CAAC,GAAG;qBACH,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;;WAE7C,CAAC,CAAC;KACV;SAAM,IAAI,OAAO,EAAE;QAClB,OAAO,CAAC,IAAI,CACV,IAAI,CAAA;;gBAEM,IAAI,CAAC,KAAK;;qBAEL,CAChB,CAAC;KACH;SAAM,IAAI,SAAS,EAAE;QACpB,OAAO,CAAC,IAAI,CACV,IAAI,CAAA;2CACiC,KAAK,CAAC,qBAAqB;gBACtD,IAAI,CAAC,KAAK;;qBAEL,CAChB,CAAC;KACH;IACD,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC,EAAE;QAC7B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA;;;gBAGL,IAAI,CAAC,SAAS;;gCAEE,KAAK,CAAC,eAAe;qCAChB,CAAC,CAAC;KACpC;IACD,OAAO,CAAC,IAAI,CACV,IAAI,CAAA;;eAEO,KAAK,CAAC,UAAU;;mBAEZ,CAChB,CAAC;IAEF,OAAO,IAAI,CAAA;;;iBAGI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,gBAAgB,CACzD,KAAK,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAC5B,CAAC,MAAM,IAAI,UAAU,CAAC;QACrB,GAAG,EAAE,IAAI;QACT,SAAS,EAAE,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU;KAC/C,CAAC;;UAEA,KAAK,CAAC,GAAG,CAAC,IAAI;QACd,CAAC,CAAC,IAAI,CAAA,sBAAsB,KAAK,CAAC,GAAG,CAAC,IAAI,SAAS;QACnD,CAAC,CAAC,IAAI;UACN,KAAK,CAAC,GAAG,CAAC,WAAW;QACrB,CAAC,CAAC,IAAI,CAAA;gBACA,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CACzB,UAAU,CAAC,EAAE,CACX,IAAI,CAAA;sBACA,gBAAgB,CAAC,UAAU,CAAC;yBACzB,CACV;oBACK;QACV,CAAC,CAAC,IAAI;;QAER,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW;QACzC,CAAC,CAAC,IAAI,CAAA,oDAAoD;QAC1D,CAAC,CAAC,IAAI;;;;mCAIqB,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;;;UAGpD,OAAO;;;;MAIX,CAAC,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU;QAClC,CAAC,CAAC,IAAI,CAAA;YACA,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;eACnC;QACT,CAAC,CAAC,IAAI;SACH,CAAC;AACV,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAgB,EAAkB,EAAE;IAClE,IAAI,IAAI,GAAG,aAAa,CAAC;IACzB,IAAI,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC;IAEjC,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,YAAY,EAAE;YACtC,IAAI,GAAG,SAAS,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;SAClB;aAAM;YACL,IAAI,GAAG,WAAW,CAAC;YACnB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;SAClB;KACF;IAED,OAAO,IAAI,CAAA;wBACW,IAAI;;QAEpB,IAAI;;;6BAGiB,KAAK,CAAC,IAAI,CAAC,IAAI;;;UAGlC,KAAK,CAAC,IAAI,CAAC,IAAI;;;GAGtB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAwB,EAAkB,EAAE;IAC5E,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QAC9B,OAAO,IAAI,CAAC;KACb;IACD,OAAO,IAAI,CAAA;wBACW,IAAI,CAAC,OAAO;;;0BAGV,KAAK,CAAC,IAAI;;0BAEV,KAAK,CAAC,KAAK;QAC7B,KAAK,CAAC,QAAQ;QACd,CAAC,CAAC,IAAI,CAAA;gCACkB,KAAK,CAAC,QAAQ,QAAQ;QAC9C,CAAC,CAAC,IAAI;;GAEX,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAuB,EAAkB,EAAE;IAC3E,OAAO,IAAI,CAAA;wBACW,IAAI,CAAC,eAAe;;QAEpC,KAAK,CAAC,KAAK;QACX,CAAC,CAAC,IAAI,CAAA;gCACkB,KAAK,CAAC,KAAK,CAAC,IAAI;;gCAEhB,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ;QAChD,CAAC,CAAC,IAAI,CAAA;gCACkB,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ;;GAErD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAuB,EAAkB,EAAE;IAC3E,OAAO,IAAI,CAAA;wBACW,IAAI,CAAC,eAAe;;;;;0BAKlB,KAAK,CAAC,IAAI;;GAEjC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,KAAuB,EACP,EAAE;IAClB,OAAO,IAAI,CAAA;wBACW,IAAI,CAAC,eAAe;;;;;UAKlC,QAAQ,CACR,KAAK,CAAC,IAAI,EACV,CAAC,GAAW,EAAE,EAAE,CACd,IAAI,CAAA,qBAAqB,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CACnE;;;GAGN,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAqB,EAAkB,EAAE;IACvE,OAAO,IAAI,CAAA;wBACW,IAAI,CAAC,KAAK;;;0BAGR,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC;;0BAEvB,KAAK,CAAC,OAAO;;GAEpC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAuB,EAAkB,EAAE;IAC3E,OAAO,IAAI,CAAA;wBACW,IAAI,CAAC,KAAK;;;0BAGR,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;;GAEvD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAkB,EAAkB,EAAE;IACtE,OAAO,IAAI,CAAA;;iCAEoB,KAAK,CAAC,IAAI;;;;;mBAKxB,KAAK,CAAC,UAAU;;;;;;QAM3B,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC;;SAEjC,CAAC;AACV,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,KAAkB,EAAE,EAAE;IAC3C,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;IACtB,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE;QACpD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;KACnB;SAAM,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE;QAC7D,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;KACrB;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAkB,EAClB,MAAc,EACd,OAAgB,EACA,EAAE;IAClB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,OAAO,EAAE;QACX,OAAO,IAAI,CAAA;0BACW,IAAI;;UAEpB,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM;;;;mCAIjB,KAAK,CAAC,MAAM,CAAC,IAAI;;;;;WAKzC,CAAC;KACT;IAED,OAAO,IAAI,CAAA;;;UAGH,KAAK,CAAC,UAAU;QAChB,CAAC,CAAC,IAAI,CAAA,IAAI,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,eAAe;QACnE,CAAC,CAAC,IAAI,CAAA,oBAAoB,MAAM,GAAG;;;;;mBAK1B,KAAK,CAAC,UAAU;;;;;GAKhC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAkB,EAAkB,EAAE;IACzE,OAAO,IAAI,CAAA;;;UAGH,KAAK,CAAC,QAAQ;QACd,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,UAAU,CAAC,EAAE;YACzC,CAAC,CAAC,IAAI,CAAA,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,mBAAmB;YAC5D,CAAC,CAAC,IAAI,CAAA,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC;oCACjB,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ;QAChE,CAAC,CAAC,IAAI,CAAA,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,yBAAyB;;;;;mBAKzD,KAAK,CAAC,UAAU;;;;;GAKhC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAkB,EAClB,WAAmC,EACnC,OAAgB,EACA,EAAE;IAClB,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,OAAO,EAAE;QACX,OAAO,IAAI,CAAA;0BACW,IAAI;;UAEpB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI;;;;mCAIE,KAAK,CAAC,MAAM,CAAC,IAAI;;;;;WAKzC,CAAC;KACT;SAAM;QACL,OAAO,IAAI,CAAA;;;YAGH,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC;;;;;qBAKvB,KAAK,CAAC,UAAU;;;;;KAKhC,CAAC;KACH;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAwB,EACR,EAAE;IAClB,OAAO,IAAI,CAAA;;cAEC,IAAI,CAAC,KAAK;;;;QAIhB,KAAK,CAAC,IAAI;QACV,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO;QAC7B,CAAC,CAAC,IAAI,CAAA,0DAA0D;QAChE,CAAC,CAAC,IAAI;;GAEX,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAmB,EAAkB,EAAE;IACxE,OAAO,IAAI,CAAA;;eAEE,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;;;0BAG/B,IAAI,CAAC,OAAO;;UAE5B,KAAK,CAAC,MAAM,KAAK,SAAS;QAC1B,CAAC,CAAC,IAAI,CAAA,uBAAuB,KAAK,CAAC,GAAG,EAAE;QACxC,CAAC,CAAC,IAAI,CAAA,kBAAkB,KAAK,CAAC,GAAG,EAAE;;;GAG1C,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,KAA8B,EACd,EAAE;IAClB,IAAI,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;QACzC,OAAO,IAAI,CAAA;gBACC,IAAI,CAAC,KAAK;;;mEAGyC,CAAC;KACjE;IAED,OAAO,IAAI,CAAA,qBAAqB,IAAI,CAAC,OAAO;;;0BAGpB,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ;;WAEpD,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAmB,EAAE;IACzD,OAAO,IAAI,CAAA,qBAAqB,IAAI,CAAC,IAAI;gDACK,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAC/C,KAAkC,EAClB,EAAE;IAClB,OAAO,IAAI,CAAA,qBAAqB,IAAI,CAAC,eAAe;;+CAEP,KAAK,CAAC,QAAQ;WAClD,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAmB,EAAkB,EAAE;IACxE,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAErB,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE;QAC1C,YAAY,GAAG,sBAAsB,CAAC;QACtC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;KACzB;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE;QACjD,YAAY,GAAG,sBAAsB,CAAC;QACtC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;KACzB;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,kBAAkB,EAAE;QAC1D,YAAY,GAAG,sBAAsB,CAAC;QACtC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;KACnB;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,EAAE;QACzD,YAAY,GAAG,sBAAsB,CAAC;QACtC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;KACnB;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,UAAU,EAAE;QAClD,YAAY,GAAG,UAAU,CAAC;QAC1B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;KACnB;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,QAAQ,EAAE;QAChD,YAAY,GAAG,UAAU,CAAC;QAC1B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;KACnB;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,cAAc,EAAE;QACtD,YAAY,GAAG,SAAS,CAAC;QACzB,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC;KAC7B;SAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE;QACjD,YAAY,GAAG,qBAAqB,CAAC;KACtC;SAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,SAAS,EAAE;QAChD,YAAY,GAAG,qBAAqB,CAAC;KACtC;IAED,OAAO,IAAI,CAAA,qBAAqB,IAAI;+BACP,YAAY,QAAQ,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,KAAyB,EACT,EAAE;IAClB,OAAO,IAAI,CAAA,qBAAqB,IAAI,CAAC,QAAQ;;;;;;+BAMhB,KAAK,CAAC,QAAQ,CAAC,IAAI;WACvC,KAAK,CAAC,QAAQ,CAAC,IAAI;;QAEtB,KAAK,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;;;;oCAIxB,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,cAAc;SACpE,EAAE;;UAEH,KAAK,CAAC,cAAc,CAAC,cAAc;UACnC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI;;WAEpC,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,KAAyB,EACT,EAAE;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,cAAc,CAAC;IAC1D,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IACnC,OAAO,IAAI,CAAA;;cAEC,IAAI,CAAC,KAAK;eACT,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC;;;QAGpD,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc;QACnC,QAAQ,CACR,MAAM,EACN,CAAC,KAAsB,EAAE,EAAE,CACzB,IAAI,CAAA;;;oCAGsB,KAAK,CAAC,IAAI;eAC/B,KAAK,CAAC,IAAI;YACb,CACL;QACC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO;QAC7B,CAAC,CAAC,IAAI,CAAA,0DAA0D;QAChE,CAAC,CAAC,IAAI;;GAEX,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { Msg, ObjectReference, User } from '../interfaces';\nimport {\n getClasses,\n oxford,\n oxfordFn,\n oxfordNamed,\n renderAvatar,\n} 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 .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(230, 230, 230);\n }\n\n .airtime_transferred,\n .flow_exited,\n .flow_entered,\n .ticket_opened,\n .ticket_reopened,\n .ticket_closed,\n .call_started,\n .campaign_fired {\n --icon-color: rgba(223, 65, 159, 1);\n }\n\n .active-ticket.ticket_opened {\n padding: 0em 1em;\n }\n\n .ticket_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 .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 ERROR = 'error',\n FAILURE = 'failure',\n}\n\nexport interface ContactEvent {\n type: string;\n created_on: string;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n msg_type: string;\n recipient_count?: number;\n created_by?: User;\n}\n\nexport interface FlowEvent extends ContactEvent {\n flow: ObjectReference;\n status: string;\n}\n\nexport interface EmailSentEvent extends ContactEvent {\n to: string[];\n subject: string;\n body: string;\n}\n\nexport interface URNsChangedEvent extends ContactEvent {\n urns: string[];\n}\n\nexport interface TicketEvent extends ContactEvent {\n note?: string;\n assignee?: User;\n ticket: {\n uuid: string;\n ticketer: ObjectReference;\n body: string;\n topic?: ObjectReference;\n external_id?: string;\n closed_on?: string;\n opened_on?: string;\n };\n created_by?: User;\n}\n\nexport interface LabelsAddedEvent extends ContactEvent {\n labels: ObjectReference[];\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ErrorMessageEvent extends ContactEvent {\n text: string;\n}\n\nexport interface UpdateResultEvent extends ContactEvent {\n name: string;\n value: string;\n category: string;\n input: string;\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface WebhookEvent extends ContactEvent {\n status: string;\n status_code: number;\n elapsed_ms: number;\n logs_url: string;\n url: string;\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n desired_amount: string;\n actual_amount: string;\n logs_url: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\nexport interface CampaignFiredEvent extends ContactEvent {\n campaign: { uuid: string; id: number; name: string };\n campaign_event: {\n id: number;\n offset_display: string;\n relative_to: { key: string; name: string };\n };\n fired_result: string;\n}\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n\nexport const getEventGroupType = (event: ContactEvent, ticket: string) => {\n if (!event) {\n return 'messages';\n }\n\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&amp;layer=mapnik&amp;marker=${geo}\"\n ></iframe>`;\n } else {\n return html`<div style=\"display:flex\">\n <temba-icon name=\"${Icon.download}\"></temba-icon>\n <div>Attachment ${ext}</div>\n </div>`;\n }\n\n return html`<div style=\"\">${inner}</div>`;\n};\n\nexport const renderMsgEvent = (\n event: MsgEvent,\n agent: string\n): TemplateResult => {\n const isInbound = event.type === Events.MESSAGE_RECEIVED;\n const isError = event.status === 'E';\n const isFailure = event.status === 'F';\n\n // summary items which appear under the message bubble\n const summary: TemplateResult[] = [];\n\n if (event.logs_url) {\n summary.push(html` <div class=\"icon-link\">\n <temba-icon\n onclick=\"goto(event)\"\n href=\"${event.logs_url}\"\n name=\"${Icon.log}\"\n class=\"log ${isError || isFailure ? 'error' : ''}\"\n ></temba-icon>\n </div>`);\n } else if (isError) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery error\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n } else if (isFailure) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery failure: ${event.failed_reason_display}\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n }\n if (event.recipient_count > 1) {\n summary.push(html`<temba-icon\n size=\"1\"\n class=\"broadcast\"\n name=\"${Icon.broadcast}\"\n ></temba-icon>\n <div class=\"recipients\">${event.recipient_count} contacts</div>\n <div class=\"separator\">•</div>`);\n }\n summary.push(\n html`<temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>`\n );\n\n return html`<div style=\"display:flex;align-items:flex-start\">\n <div style=\"display:flex;flex-direction:column\">\n <div\n class=\"${event.msg.text ? '' : 'no-message'} attachments-${(\n event.msg.attachments || []\n ).length} ${getClasses({\n msg: true,\n automated: !isInbound && !event.msg.created_by,\n })}\"\n >\n ${event.msg.text\n ? html` <div class=\"text\">${event.msg.text}</div> `\n : null}\n ${event.msg.attachments\n ? html`<div class=\"attachments\">\n ${event.msg.attachments.map(\n attachment =>\n html` <div class=\"attachment\">\n ${renderAttachment(attachment)}\n </div>`\n )}\n </div> `\n : null}\n </div>\n ${!event.msg.text && !event.msg.attachments\n ? html`<div class=\"unsupported\">Unsupported Message</div>`\n : null}\n\n <div\n class=\"msg-summary\"\n style=\"flex-direction:row${isInbound ? '-reverse' : ''}\"\n >\n <div style=\"flex-grow:1\"></div>\n ${summary}\n </div>\n </div>\n\n ${!isInbound && event.msg.created_by\n ? html`<div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.9em\">\n ${renderUserAvatar(event.msg.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\nconst getTicketIcon = (event: TicketEvent) => {\n let icon = Icon.inbox;\n if (event.ticket.ticketer.name.indexOf('Email') > -1) {\n icon = Icon.email;\n } else if (event.ticket.ticketer.name.indexOf('Zendesk') > -1) {\n icon = Icon.zendesk;\n }\n return icon;\n};\n\nexport const renderTicketAction = (\n event: TicketEvent,\n action: string,\n grouped: boolean\n): TemplateResult => {\n const reopened = new Date(event.created_on);\n const icon = getTicketIcon(event);\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${getDisplayName(event.created_by)} ${action} a\n <span\n onclick=\"goto(event)\"\n class=\"linked\"\n href=\"/ticket/all/open/${event.ticket.uuid}/\"\n >\n ticket\n </span>\n </div>\n </div>`;\n }\n\n return html`\n <div class=\"assigned active\">\n <div style=\"text-align:center\">\n ${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 const icon = getTicketIcon(event);\n\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${event.ticket.topic.name}\n <span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/ticket/all/open/${event.ticket.uuid}\"\n >ticket</span\n >\n was opened\n </div>\n </div>`;\n } else {\n return html`\n <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 renderChannelEvent = (event: ChannelEvent): TemplateResult => {\n let eventMessage = '';\n let icon = Icon.call;\n\n if (event.channel_event_type === 'mt_miss') {\n eventMessage = 'Missed outgoing call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'mo_miss') {\n eventMessage = 'Missed incoming call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'new_conversation') {\n eventMessage = 'Started Conversation';\n icon = Icon.event;\n } else if (event.channel_event_type === 'welcome_message') {\n eventMessage = 'Welcome Message Sent';\n icon = Icon.event;\n } else if (event.channel_event_type === 'referral') {\n eventMessage = 'Referred';\n icon = Icon.event;\n } else if (event.channel_event_type === 'follow') {\n eventMessage = 'Followed';\n icon = Icon.event;\n } else if (event.channel_event_type === 'stop_contact') {\n eventMessage = 'Stopped';\n icon = Icon.contact_stopped;\n } else if (event.channel_event_type === 'mt_call') {\n eventMessage = 'Outgoing Phone Call';\n } else if (event.channel_event_type == 'mo_call') {\n eventMessage = 'Incoming Phone call';\n }\n\n return html`<temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">${eventMessage}</div>`;\n};\n\nexport const renderCampaignFiredEvent = (\n event: CampaignFiredEvent\n): TemplateResult => {\n return html`<temba-icon name=\"${Icon.campaign}\"></temba-icon>\n <div class=\"description\">\n Campaign\n <span\n class=\"linked\"\n onclick=\"goto(event, this)\"\n href=\"/campaign/read/${event.campaign.uuid}/\"\n >${event.campaign.name}</span\n >\n ${event.fired_result === 'S' ? 'skipped' : 'triggered'}\n <span\n class=\"linked\"\n onclick=\"goto(event, this)\"\n href=\"/campaignevent/read/${event.campaign.uuid}/${event.campaign_event\n .id}/\"\n >\n ${event.campaign_event.offset_display}\n ${event.campaign_event.relative_to.name}</span\n >\n </div>`;\n};\n\nexport const renderContactGroupsEvent = (\n event: ContactGroupsEvent\n): TemplateResult => {\n const groups = event.groups_added || event.groups_removed;\n const added = !!event.groups_added;\n return html`\n <temba-icon\n name=\"${Icon.users}\"\n class=\"${getClasses({ added: added, removed: !added })}\"\n ></temba-icon>\n <div class=\"description\">\n ${added ? 'Added to' : 'Removed from'}\n ${oxfordFn(\n groups,\n (group: ObjectReference) =>\n html`<span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/contact/filter/${group.uuid}\"\n >${group.name}</span\n >`\n )}\n ${event.type === Events.FAILURE\n ? html`<div>Run ended prematurely, check the flow design.</div>`\n : null}\n </div>\n `;\n};\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/contacts/events.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { Msg, ObjectReference, User } from '../interfaces';\nimport {\n getClasses,\n oxford,\n oxfordFn,\n oxfordNamed,\n renderAvatar,\n} 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 .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(230, 230, 230);\n }\n\n .airtime_transferred,\n .flow_exited,\n .flow_entered,\n .ticket_opened,\n .ticket_reopened,\n .ticket_closed,\n .call_started,\n .campaign_fired {\n --icon-color: rgba(223, 65, 159, 1);\n }\n\n .active-ticket.ticket_opened {\n padding: 0em 1em;\n }\n\n .ticket_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 border: 1px solid #f2f2f2;\n color: #999;\n padding: 0.5em 1em;\n border-radius: var(--curvature);\n display: inline-flex;\n }\n\n .optin .text {\n margin-left: 0.5em;\n display: inline;\n }\n\n .optin span.italic {\n font-style: italic;\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 ERROR = 'error',\n FAILURE = 'failure',\n}\n\nexport interface ContactEvent {\n type: string;\n created_on: string;\n}\n\nexport interface ChannelEvent extends ContactEvent {\n channel_event_type: string;\n duration: number;\n}\n\nexport interface ContactLanguageChangedEvent extends ContactEvent {\n language: string;\n step_uuid: string;\n session_uuid: string;\n}\n\nexport interface MsgEvent extends ContactEvent {\n msg: Msg;\n status: string;\n failed_reason?: string;\n failed_reason_display?: string;\n logs_url: string;\n msg_type: string;\n recipient_count?: number;\n created_by?: User;\n 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 ticketer: ObjectReference;\n body: string;\n topic?: ObjectReference;\n external_id?: string;\n closed_on?: string;\n opened_on?: string;\n };\n created_by?: User;\n}\n\nexport interface LabelsAddedEvent extends ContactEvent {\n labels: ObjectReference[];\n}\n\nexport interface NameChangedEvent extends ContactEvent {\n name: string;\n}\n\nexport interface UpdateFieldEvent extends ContactEvent {\n field: { key: string; name: string };\n value: { text: string };\n}\n\nexport interface ErrorMessageEvent extends ContactEvent {\n text: string;\n}\n\nexport interface UpdateResultEvent extends ContactEvent {\n name: string;\n value: string;\n category: string;\n input: string;\n}\n\nexport interface ContactGroupsEvent extends ContactEvent {\n groups_added: ObjectReference[];\n groups_removed: ObjectReference[];\n}\n\nexport interface WebhookEvent extends ContactEvent {\n status: string;\n status_code: number;\n elapsed_ms: number;\n logs_url: string;\n url: string;\n}\n\nexport interface AirtimeTransferredEvent extends ContactEvent {\n sender: string;\n recipient: string;\n currency: string;\n desired_amount: string;\n actual_amount: string;\n logs_url: string;\n}\n\nexport type CallStartedEvent = ContactEvent;\nexport interface CampaignFiredEvent extends ContactEvent {\n campaign: { uuid: string; id: number; name: string };\n campaign_event: {\n id: number;\n offset_display: string;\n relative_to: { key: string; name: string };\n };\n fired_result: string;\n}\n\nexport interface ContactHistoryPage {\n has_older: boolean;\n recent_only: boolean;\n next_before: number;\n next_after: number;\n start_date: Date;\n events: ContactEvent[];\n}\n\nexport const getEventGroupType = (event: ContactEvent, ticket: string) => {\n if (!event) {\n return 'messages';\n }\n\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&amp;layer=mapnik&amp;marker=${geo}\"\n ></iframe>`;\n } else {\n return html`<div style=\"display:flex\">\n <temba-icon name=\"${Icon.download}\"></temba-icon>\n <div>Attachment ${ext}</div>\n </div>`;\n }\n\n return html`<div style=\"\">${inner}</div>`;\n};\n\nexport const renderMsgEvent = (\n event: MsgEvent,\n agent: string\n): TemplateResult => {\n const isInbound = event.type === Events.MESSAGE_RECEIVED;\n const isError = event.status === 'E';\n const isFailure = event.status === 'F';\n\n // summary items which appear under the message bubble\n const summary: TemplateResult[] = [];\n\n if (event.logs_url) {\n summary.push(html` <div class=\"icon-link\">\n <temba-icon\n onclick=\"goto(event)\"\n href=\"${event.logs_url}\"\n name=\"${Icon.log}\"\n class=\"log ${isError || isFailure ? 'error' : ''}\"\n ></temba-icon>\n </div>`);\n } else if (isError) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery error\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n } else if (isFailure) {\n summary.push(\n html`<temba-icon\n title=\"Message delivery failure: ${event.failed_reason_display}\"\n name=\"${Icon.error}\"\n class=\"delivery-error\"\n ></temba-icon>`\n );\n }\n if (event.recipient_count > 1) {\n summary.push(html`<temba-icon\n size=\"1\"\n class=\"broadcast\"\n name=\"${Icon.broadcast}\"\n ></temba-icon>\n <div class=\"recipients\">${event.recipient_count} contacts</div>\n <div class=\"separator\">•</div>`);\n }\n summary.push(\n html`<temba-date\n class=\"time\"\n value=\"${event.created_on}\"\n display=\"duration\"\n ></temba-date>`\n );\n\n return html`<div style=\"display:flex;align-items:flex-start\">\n <div style=\"display:flex;flex-direction:column\">\n <div\n class=\"${event.msg.text ? '' : 'no-message'} attachments-${(\n event.msg.attachments || []\n ).length} ${getClasses({\n msg: true,\n automated: !isInbound && !event.msg.created_by,\n })}\"\n >\n ${event.msg.text\n ? html` <div class=\"text\">${event.msg.text}</div> `\n : null}\n ${event.msg.attachments\n ? html`<div class=\"attachments\">\n ${event.msg.attachments.map(\n attachment =>\n html` <div class=\"attachment\">\n ${renderAttachment(attachment)}\n </div>`\n )}\n </div> `\n : null}\n </div>\n ${event.optin\n ? html`<div class=\"optin\">\n <temba-icon\n size=\"1\"\n class=\"broadcast inline\"\n name=\"${Icon.restore}\"\n ></temba-icon>\n <div class=\"text\">\n Requested Opt In for\n <span class=\"italic\">${event.optin.name}</span>\n </div>\n </div>`\n : null}\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=\"flex-direction:row${isInbound ? '-reverse' : ''}\"\n >\n <div style=\"flex-grow:1\"></div>\n ${summary}\n </div>\n </div>\n\n ${!isInbound && event.msg.created_by\n ? html`<div style=\"margin-left:0.8em;margin-top:0.3em;font-size:0.9em\">\n ${renderUserAvatar(event.msg.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\nconst getTicketIcon = (event: TicketEvent) => {\n let icon = Icon.inbox;\n if (event.ticket.ticketer.name.indexOf('Email') > -1) {\n icon = Icon.email;\n } else if (event.ticket.ticketer.name.indexOf('Zendesk') > -1) {\n icon = Icon.zendesk;\n }\n return icon;\n};\n\nexport const renderTicketAction = (\n event: TicketEvent,\n action: string,\n grouped: boolean\n): TemplateResult => {\n const reopened = new Date(event.created_on);\n const icon = getTicketIcon(event);\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${getDisplayName(event.created_by)} ${action} a\n <span\n onclick=\"goto(event)\"\n class=\"linked\"\n href=\"/ticket/all/open/${event.ticket.uuid}/\"\n >\n ticket\n </span>\n </div>\n </div>`;\n }\n\n return html`\n <div class=\"assigned active\">\n <div style=\"text-align:center\">\n ${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 const icon = getTicketIcon(event);\n\n if (grouped) {\n return html`<div class=\"\" style=\"display: flex\">\n <temba-icon name=\"${icon}\"></temba-icon>\n <div class=\"description\">\n ${event.ticket.topic.name}\n <span\n class=\"linked\"\n onclick=\"goto(event)\"\n href=\"/ticket/all/open/${event.ticket.uuid}\"\n >ticket</span\n >\n was opened\n </div>\n </div>`;\n } else {\n return html`\n <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 renderChannelEvent = (event: ChannelEvent): TemplateResult => {\n let eventMessage = '';\n let icon = Icon.call;\n\n if (event.channel_event_type === 'mt_miss') {\n eventMessage = 'Missed outgoing call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'mo_miss') {\n eventMessage = 'Missed incoming call';\n icon = Icon.call_missed;\n } else if (event.channel_event_type === 'new_conversation') {\n eventMessage = 'Started Conversation';\n icon = Icon.event;\n } else if (event.channel_event_type === 'welcome_message') {\n eventMessage = 'Welcome Message Sent';\n icon = Icon.event;\n } else if (event.channel_event_type === 'referral') {\n eventMessage = 'Referred';\n icon = Icon.event;\n } else if (event.channel_event_type === 'follow') {\n eventMessage = 'Followed';\n icon = Icon.event;\n } else if (event.channel_event_type === 'stop_contact') {\n eventMessage = 'Stopped';\n icon = Icon.contact_stopped;\n } else if (event.channel_event_type === 'mt_call') {\n eventMessage = 'Outgoing Phone Call';\n } else if (event.channel_event_type == 'mo_call') {\n eventMessage = 'Incoming Phone call';\n } else if (event.channel_event_type == 'optin') {\n eventMessage = 'Opted in';\n icon = Icon.restore;\n } else if (event.channel_event_type == 'optout') {\n eventMessage = 'Opted out';\n icon = Icon.error;\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.58.5",
3
+ "version": "0.58.8",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -369,6 +369,23 @@ export const getEventStyles = () => {
369
369
  border-radius: var(--curvature);
370
370
  }
371
371
 
372
+ .optin {
373
+ border: 1px solid #f2f2f2;
374
+ color: #999;
375
+ padding: 0.5em 1em;
376
+ border-radius: var(--curvature);
377
+ display: inline-flex;
378
+ }
379
+
380
+ .optin .text {
381
+ margin-left: 0.5em;
382
+ display: inline;
383
+ }
384
+
385
+ .optin span.italic {
386
+ font-style: italic;
387
+ }
388
+
372
389
  .time {
373
390
  padding: 0.3em 1px;
374
391
  }
@@ -536,6 +553,7 @@ export interface MsgEvent extends ContactEvent {
536
553
  msg_type: string;
537
554
  recipient_count?: number;
538
555
  created_by?: User;
556
+ optin?: ObjectReference;
539
557
  }
540
558
 
541
559
  export interface FlowEvent extends ContactEvent {
@@ -812,7 +830,20 @@ export const renderMsgEvent = (
812
830
  </div> `
813
831
  : null}
814
832
  </div>
815
- ${!event.msg.text && !event.msg.attachments
833
+ ${event.optin
834
+ ? html`<div class="optin">
835
+ <temba-icon
836
+ size="1"
837
+ class="broadcast inline"
838
+ name="${Icon.restore}"
839
+ ></temba-icon>
840
+ <div class="text">
841
+ Requested Opt In for
842
+ <span class="italic">${event.optin.name}</span>
843
+ </div>
844
+ </div>`
845
+ : null}
846
+ ${!event.msg.text && !event.msg.attachments && !event.optin
816
847
  ? html`<div class="unsupported">Unsupported Message</div>`
817
848
  : null}
818
849
 
@@ -1175,6 +1206,12 @@ export const renderChannelEvent = (event: ChannelEvent): TemplateResult => {
1175
1206
  eventMessage = 'Outgoing Phone Call';
1176
1207
  } else if (event.channel_event_type == 'mo_call') {
1177
1208
  eventMessage = 'Incoming Phone call';
1209
+ } else if (event.channel_event_type == 'optin') {
1210
+ eventMessage = 'Opted in';
1211
+ icon = Icon.restore;
1212
+ } else if (event.channel_event_type == 'optout') {
1213
+ eventMessage = 'Opted out';
1214
+ icon = Icon.error;
1178
1215
  }
1179
1216
 
1180
1217
  return html`<temba-icon name="${icon}"></temba-icon>