@nyaruka/temba-components 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/a525ddb7.js +1 -0
- package/dist/index.js +1 -1
- package/dist/sw.js +1 -1
- package/dist/sw.js.map +1 -1
- package/dist/templates/components-body.html +1 -1
- package/dist/templates/components-head.html +1 -1
- package/out-tsc/src/button/Button.js +1 -0
- package/out-tsc/src/button/Button.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +81 -33
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactDetails.js +22 -22
- package/out-tsc/src/contacts/ContactDetails.js.map +1 -1
- package/out-tsc/src/contacts/ContactHistory.js +131 -138
- package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
- package/out-tsc/src/contacts/events.js +55 -44
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/list/ContactList.js +1 -1
- package/out-tsc/src/list/ContactList.js.map +1 -1
- package/out-tsc/src/list/TembaList.js +10 -3
- package/out-tsc/src/list/TembaList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +7 -2
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/loading/Loading.js +9 -1
- package/out-tsc/src/loading/Loading.js.map +1 -1
- package/out-tsc/src/options/Options.js +14 -2
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/tip/Tip.js +6 -0
- package/out-tsc/src/tip/Tip.js.map +1 -1
- package/out-tsc/src/vectoricon/VectorIcon.js +17 -5
- package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
- package/out-tsc/test/temba-contact-history.test.js +2 -2
- package/out-tsc/test/temba-contact-history.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/contacts/history-expanded.png +0 -0
- package/screenshots/truth/contacts/history.png +0 -0
- package/screenshots/truth/list/items-selected.png +0 -0
- package/screenshots/truth/list/items-updated.png +0 -0
- package/screenshots/truth/list/items.png +0 -0
- package/screenshots/truth/modax/simple.png +0 -0
- package/screenshots/truth/options/block.png +0 -0
- package/screenshots/truth/select/disabled-multi-selection.png +0 -0
- package/screenshots/truth/select/disabled-selection.png +0 -0
- package/screenshots/truth/select/disabled.png +0 -0
- package/screenshots/truth/select/embedded.png +0 -0
- package/screenshots/truth/select/expression-selected.png +0 -0
- package/screenshots/truth/select/expressions.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/local-options.png +0 -0
- package/screenshots/truth/select/remote-options.png +0 -0
- package/screenshots/truth/select/search-enabled.png +0 -0
- package/screenshots/truth/select/search-multi-no-matches.png +0 -0
- package/screenshots/truth/select/search-selected-focus.png +0 -0
- package/screenshots/truth/select/search-selected.png +0 -0
- package/screenshots/truth/select/search-with-selected.png +0 -0
- package/screenshots/truth/select/searching.png +0 -0
- package/screenshots/truth/select/selected-multi.png +0 -0
- package/screenshots/truth/select/selected-single.png +0 -0
- package/screenshots/truth/select/with-placeholder.png +0 -0
- package/screenshots/truth/select/without-placeholder.png +0 -0
- package/screenshots/truth/textinput/date-form.png +0 -0
- package/screenshots/truth/textinput/input-disabled.png +0 -0
- package/screenshots/truth/textinput/input-form.png +0 -0
- package/screenshots/truth/textinput/input-placeholder.png +0 -0
- package/screenshots/truth/textinput/input-updated.png +0 -0
- package/screenshots/truth/textinput/input.png +0 -0
- package/screenshots/truth/textinput/textarea.png +0 -0
- package/screenshots/truth/tip/bottom.png +0 -0
- package/screenshots/truth/tip/left.png +0 -0
- package/screenshots/truth/tip/right.png +0 -0
- package/screenshots/truth/tip/top.png +0 -0
- package/src/button/Button.ts +1 -0
- package/src/contacts/ContactChat.ts +93 -33
- package/src/contacts/ContactDetails.ts +23 -23
- package/src/contacts/ContactHistory.ts +156 -159
- package/src/contacts/events.ts +59 -44
- package/src/interfaces.ts +1 -1
- package/src/list/ContactList.ts +1 -1
- package/src/list/TembaList.ts +13 -4
- package/src/list/TembaMenu.ts +7 -2
- package/src/loading/Loading.ts +8 -1
- package/src/options/Options.ts +14 -2
- package/src/tip/Tip.ts +6 -0
- package/src/vectoricon/VectorIcon.ts +17 -5
- package/test/temba-contact-history.test.ts +2 -2
- package/test-assets/style.css +4 -1
- package/dist/d59a9ae2.js +0 -1
package/dist/sw.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let r=Promise.resolve();return t[e]||(r=new Promise(async r=>{if("document"in self){const t=document.createElement("script");t.src=e,document.head.appendChild(t),t.onload=r}else importScripts(e),r()})),r.then(()=>{if(!t[e])throw new Error(`Module ${e} didn’t register its module`);return t[e]})},r=(r,t)=>{Promise.all(r.map(e)).then(e=>t(1===e.length?e[0]:e))},t={require:Promise.resolve(r)};self.define=(r,s,o)=>{t[r]||(t[r]=Promise.resolve().then(()=>{let t={};const n={uri:location.origin+r.slice(1)};return Promise.all(s.map(r=>{switch(r){case"exports":return t;case"module":return n;default:return e(r)}})).then(e=>{const r=o(...e);return t.default||(t.default=r),t})}))}}define("./sw.js",["./workbox-80efdfd1"],(function(e){"use strict";e.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"
|
|
1
|
+
if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let r=Promise.resolve();return t[e]||(r=new Promise(async r=>{if("document"in self){const t=document.createElement("script");t.src=e,document.head.appendChild(t),t.onload=r}else importScripts(e),r()})),r.then(()=>{if(!t[e])throw new Error(`Module ${e} didn’t register its module`);return t[e]})},r=(r,t)=>{Promise.all(r.map(e)).then(e=>t(1===e.length?e[0]:e))},t={require:Promise.resolve(r)};self.define=(r,s,o)=>{t[r]||(t[r]=Promise.resolve().then(()=>{let t={};const n={uri:location.origin+r.slice(1)};return Promise.all(s.map(r=>{switch(r){case"exports":return t;case"module":return n;default:return e(r)}})).then(e=>{const r=o(...e);return t.default||(t.default=r),t})}))}}define("./sw.js",["./workbox-80efdfd1"],(function(e){"use strict";e.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"a525ddb7.js",revision:"3b8203c9e64973380fb4c4676a37113f"},{url:"templates/components-body.html",revision:"6e09da41662e122c5618c54c20502e83"},{url:"templates/components-head.html",revision:"1c182c8f2d51ff9c48c75b07a7085236"}],{}),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/
|
|
1
|
+
{"version":3,"file":"sw.js","sources":["../../../../../tmp/e8c8c83d8e890e21aaa361f265767e3b/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {skipWaiting as workbox_core_skipWaiting} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/skipWaiting.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/temba-components/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\nworkbox_core_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\": \"a525ddb7.js\",\n \"revision\": \"3b8203c9e64973380fb4c4676a37113f\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"6e09da41662e122c5618c54c20502e83\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"1c182c8f2d51ff9c48c75b07a7085236\"\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":["workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"k1BAmCoC,CAClC,KACS,uBACK,oCAEd,KACS,0CACK,oCAEd,KACS,0CACK,qCAEb,oBAE2B,IAAIA,kBAAgCC,0BAA2C,iCAG/E,iBAAkB,IAAIC,aAAiC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/
|
|
1
|
+
<script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/a525ddb7.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.18.0"</script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/
|
|
1
|
+
<link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/a525ddb7.js" crossorigin="anonymous">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/button/Button.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAkB,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,OAAO,MAAO,SAAQ,UAAU;IAAtC;;
|
|
1
|
+
{"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/button/Button.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, TemplateResult, html, css, property } from 'lit-element';\nimport { getClasses } from '../utils';\n\nexport class Button extends LitElement {\n static get styles() {\n return css`\n :host {\n display: inline-block;\n font-family: var(--font-family);\n font-weight: 400;\n }\n\n .v-2.button-container {\n background: var(--button-bg);\n background-image: var(--button-bg-img);\n color: var(--button-text);\n box-shadow: var(--button-shadow);\n transition: all 100ms ease-in;\n }\n\n .button-container {\n color: #fff;\n cursor: pointer;\n display: block;\n border-radius: var(--curvature);\n outline: none;\n transition: background ease-in 200ms;\n user-select: none;\n -webkit-user-select: none;\n text-align: center;\n }\n\n .button-name {\n white-space: nowrap;\n }\n\n .secondary-button:hover .button-mask {\n border: 1px solid var(--color-button-secondary);\n }\n\n .button-mask:hover {\n background: rgba(0, 0, 0, 0.05);\n }\n\n .button-container:focus {\n outline: none;\n margin: 0;\n }\n\n .button-container:focus {\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .button-container.secondary-button:focus .button-mask {\n background: transparent;\n }\n\n .button-mask {\n padding: var(--button-y) var(--button-x);\n border-radius: var(--curvature);\n border: 1px solid transparent;\n transition: all ease-in 200ms;\n background: var(--button-mask);\n }\n\n .button-container.disabled-button {\n background: rgba(0, 0, 0, 0.05);\n color: rgba(255, 255, 255, 0.45);\n cursor: default;\n }\n\n .button-container.disabled-button .button-mask {\n box-shadow: 0 0 0px 1px var(--color-button-disabled);\n }\n\n .button-container.disabled-button:hover .button-mask {\n box-shadow: 0 0 0px 1px var(--color-button-disabled);\n background: rgba(0, 0, 0, 0.05);\n }\n\n .button-container.active-button .button-mask {\n }\n\n .secondary-button.active-button {\n background: transparent;\n color: var(--color-text);\n }\n\n .secondary-button.active-button .button-mask {\n border: none;\n }\n\n .button-container.secondary-button.active-button:focus .button-mask {\n background: transparent;\n box-shadow: none;\n }\n\n .primary-button {\n background: var(--color-button-primary);\n color: var(--color-button-primary-text);\n }\n\n .light-button {\n background: var(--color-button-light);\n color: var(--color-button-light-text);\n }\n\n .attention-button {\n background: var(--color-button-attention);\n color: var(--color-button-primary-text);\n }\n\n .secondary-button {\n background: transparent;\n color: var(--color-text);\n font-weight: 300;\n }\n\n .destructive-button {\n background: var(--color-button-destructive);\n color: var(--color-button-destructive-text);\n }\n\n .button-mask.disabled-button {\n background: rgba(0, 0, 0, 0.1);\n }\n\n .secondary-button .button-mask:hover {\n background: transparent;\n }\n\n .submit-animation {\n padding: 1px 4px;\n }\n\n .submit-animation temba-loading {\n margin-bottom: -3px;\n line-height: normal;\n }\n `;\n }\n\n @property({ type: Boolean })\n primary: boolean;\n\n @property({ type: Boolean })\n secondary: boolean;\n\n @property({ type: Boolean })\n attention: boolean;\n\n @property({ type: Number })\n v = 1;\n\n @property({ type: Boolean })\n destructive: boolean;\n\n @property()\n name: string;\n\n @property({ type: Boolean })\n disabled: boolean;\n\n @property({ type: Boolean })\n submitting: boolean;\n\n @property({ type: Boolean })\n active: boolean;\n\n @property({ type: String })\n href: string;\n\n private handleClick(evt: MouseEvent) {\n if (this.disabled) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n if (this.href && !this.disabled) {\n this.ownerDocument.location.href = this.href;\n evt.preventDefault();\n evt.stopPropagation();\n }\n }\n\n private handleKeyUp(event: KeyboardEvent): void {\n this.active = false;\n if (event.key === 'Enter') {\n this.click();\n }\n }\n\n private handleMouseDown(): void {\n if (!this.disabled && !this.submitting) {\n this.active = true;\n this.classList.add('active');\n }\n }\n\n private handleMouseUp(): void {\n this.active = false;\n this.classList.remove('active');\n }\n\n public render(): TemplateResult {\n const buttonName = this.submitting\n ? html`<div class=\"submit-animation\">\n <temba-loading units=\"3\" size=\"8\" color=\"#eee\"></temba-loading>\n </div>`\n : this.name;\n\n return html`\n <div\n class=\"button-container \n v-${this.v}\n ${getClasses({\n 'primary-button':\n this.primary ||\n (!this.primary &&\n !this.secondary &&\n !this.attention &&\n this.v == 1),\n 'secondary-button': this.secondary,\n 'disabled-button': this.disabled,\n 'active-button': this.active,\n 'attention-button': this.attention,\n 'destructive-button': this.destructive,\n })}\"\n tabindex=\"0\"\n @mousedown=${this.handleMouseDown}\n @mouseup=${this.handleMouseUp}\n @mouseleave=${this.handleMouseUp}\n @keyup=${this.handleKeyUp}\n @click=${this.handleClick}\n >\n <div class=\"button-mask\">\n <div class=\"button-name\">${buttonName}</div>\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
@@ -3,16 +3,20 @@ import { css, html, property } from 'lit-element';
|
|
|
3
3
|
import { RapidElement } from '../RapidElement';
|
|
4
4
|
import { CustomEventType } from '../interfaces';
|
|
5
5
|
import { COOKIE_KEYS, getCookieBoolean, postJSON, setCookie } from '../utils';
|
|
6
|
+
import { fetchContact } from './helpers';
|
|
7
|
+
const DEFAULT_REFRESH = 10000;
|
|
6
8
|
export class ContactChat extends RapidElement {
|
|
7
9
|
constructor() {
|
|
8
10
|
super();
|
|
9
|
-
this.contact = null;
|
|
10
11
|
this.contactsEndpoint = '/api/v2/contacts.json';
|
|
11
12
|
this.currentChat = '';
|
|
12
13
|
this.currentNote = '';
|
|
13
14
|
this.showDetails = true;
|
|
15
|
+
this.monitor = false;
|
|
14
16
|
this.currentTicket = null;
|
|
17
|
+
this.currentContact = null;
|
|
15
18
|
this.agent = -1;
|
|
19
|
+
this.refreshInterval = null;
|
|
16
20
|
this.showDetails = getCookieBoolean(COOKIE_KEYS.TICKET_SHOW_DETAILS);
|
|
17
21
|
}
|
|
18
22
|
static get styles() {
|
|
@@ -31,13 +35,16 @@ export class ContactChat extends RapidElement {
|
|
|
31
35
|
overflow: hidden;
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
.left-pane {
|
|
39
|
+
box-shadow: -13px 10px 7px 14px rgba(0, 0, 0, 0.15);
|
|
40
|
+
z-index: 100;
|
|
41
|
+
}
|
|
42
|
+
|
|
34
43
|
.chat-wrapper {
|
|
35
44
|
display: flex;
|
|
36
45
|
flex-direction: column;
|
|
37
46
|
height: 100%;
|
|
38
|
-
background: #fff;
|
|
39
47
|
overflow: hidden;
|
|
40
|
-
border-radius: var(--curvature);
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
.chatbox {
|
|
@@ -86,11 +93,10 @@ export class ContactChat extends RapidElement {
|
|
|
86
93
|
|
|
87
94
|
.toolbar {
|
|
88
95
|
position: relative;
|
|
89
|
-
width:
|
|
90
|
-
background: #
|
|
96
|
+
width: 2.5em;
|
|
97
|
+
background: #e6e6e6;
|
|
91
98
|
transition: all 600ms ease-in;
|
|
92
99
|
z-index: 10;
|
|
93
|
-
box-shadow: -1px 0px 6px 1px rgba(0, 0, 0, 0.1);
|
|
94
100
|
flex-shrink: 0;
|
|
95
101
|
border-top-right-radius: var(--curvature);
|
|
96
102
|
border-bottom-right-radius: var(--curvature);
|
|
@@ -107,7 +113,8 @@ export class ContactChat extends RapidElement {
|
|
|
107
113
|
}
|
|
108
114
|
|
|
109
115
|
.toolbar.closed {
|
|
110
|
-
box-shadow:
|
|
116
|
+
box-shadow: inset 10px 0px 10px -11px rgb(0 0 0 / 15%);
|
|
117
|
+
z-index: 1000;
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
temba-contact-details {
|
|
@@ -117,8 +124,6 @@ export class ContactChat extends RapidElement {
|
|
|
117
124
|
transition: margin 600ms cubic-bezier(0.68, -0.55, 0.265, 1.05),
|
|
118
125
|
opacity 600ms ease-in-out 200ms;
|
|
119
126
|
z-index: 5;
|
|
120
|
-
margin-right: -1.5em;
|
|
121
|
-
border-top-right-radius: 6px;
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
temba-contact-details.hidden {
|
|
@@ -155,6 +160,22 @@ export class ContactChat extends RapidElement {
|
|
|
155
160
|
}
|
|
156
161
|
`;
|
|
157
162
|
}
|
|
163
|
+
connectedCallback() {
|
|
164
|
+
super.connectedCallback();
|
|
165
|
+
if (this.monitor) {
|
|
166
|
+
this.refreshInterval = setInterval(() => {
|
|
167
|
+
if (this.currentTicket && this.currentTicket.closed_on) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.refresh();
|
|
171
|
+
}, DEFAULT_REFRESH);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
disconnectedCallback() {
|
|
175
|
+
if (this.refreshInterval) {
|
|
176
|
+
clearInterval(this.refreshInterval);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
158
179
|
getContactHistory() {
|
|
159
180
|
return this.shadowRoot.querySelector('temba-contact-history');
|
|
160
181
|
}
|
|
@@ -169,12 +190,31 @@ export class ContactChat extends RapidElement {
|
|
|
169
190
|
}
|
|
170
191
|
updated(changedProperties) {
|
|
171
192
|
super.updated(changedProperties);
|
|
193
|
+
/* if (changedProperties.has('currentTicket')) {
|
|
194
|
+
console.log('currentTicket', this.currentTicket);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (changedProperties.has('currentContact')) {
|
|
198
|
+
console.log('currentContact', this.currentContact);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (changedProperties.has('contactUUID')) {
|
|
202
|
+
console.log('contactUUID', this.contactUUID);
|
|
203
|
+
}*/
|
|
204
|
+
// we were provided a uuid, fetch our contact details
|
|
205
|
+
if (changedProperties.has('contactUUID')) {
|
|
206
|
+
fetchContact(this.contactsEndpoint + '?uuid=' + this.contactUUID).then(contact => {
|
|
207
|
+
this.currentContact = contact;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
172
210
|
// if we don't have an endpoint infer one
|
|
173
|
-
if (changedProperties.has('
|
|
211
|
+
if (changedProperties.has('currentContact')) {
|
|
174
212
|
// focus our completion on load
|
|
175
213
|
const prevContact = changedProperties.get('contact');
|
|
176
214
|
if (!prevContact ||
|
|
177
|
-
(this.
|
|
215
|
+
(this.currentContact &&
|
|
216
|
+
this.currentContact.ticket &&
|
|
217
|
+
this.currentContact.ticket.uuid !== prevContact.ticket.uuid)) {
|
|
178
218
|
const completion = this.shadowRoot.querySelector('temba-completion');
|
|
179
219
|
if (completion) {
|
|
180
220
|
window.setTimeout(() => {
|
|
@@ -191,7 +231,7 @@ export class ContactChat extends RapidElement {
|
|
|
191
231
|
this.currentChat = chat.value;
|
|
192
232
|
}
|
|
193
233
|
handleReopen() {
|
|
194
|
-
const uuid = this.
|
|
234
|
+
const uuid = this.currentTicket.uuid;
|
|
195
235
|
postJSON(`/api/v2/tickets.json?uuid=${uuid}`, {
|
|
196
236
|
status: 'open',
|
|
197
237
|
})
|
|
@@ -206,11 +246,14 @@ export class ContactChat extends RapidElement {
|
|
|
206
246
|
});
|
|
207
247
|
}
|
|
208
248
|
handleSend() {
|
|
209
|
-
|
|
210
|
-
contacts: [this.
|
|
249
|
+
const payload = {
|
|
250
|
+
contacts: [this.currentContact.uuid],
|
|
211
251
|
text: this.currentChat,
|
|
212
|
-
|
|
213
|
-
|
|
252
|
+
};
|
|
253
|
+
if (this.currentTicket) {
|
|
254
|
+
payload['ticket'] = this.currentTicket.uuid;
|
|
255
|
+
}
|
|
256
|
+
postJSON(`/api/v2/broadcasts.json`, payload)
|
|
214
257
|
.then(() => {
|
|
215
258
|
this.currentChat = '';
|
|
216
259
|
this.refresh(true);
|
|
@@ -228,24 +271,21 @@ export class ContactChat extends RapidElement {
|
|
|
228
271
|
this.showDetails = !this.showDetails;
|
|
229
272
|
setCookie(COOKIE_KEYS.TICKET_SHOW_DETAILS, this.showDetails);
|
|
230
273
|
}
|
|
231
|
-
handleCurrentTicketChanged(event) {
|
|
232
|
-
this.currentTicket = event.detail.context;
|
|
233
|
-
}
|
|
234
274
|
render() {
|
|
235
275
|
return html `
|
|
236
276
|
<div style="display: flex; height: 100%;">
|
|
237
|
-
<div style="flex-grow: 1; margin-right: 0em;">
|
|
277
|
+
<div style="flex-grow: 1; margin-right: 0em;" class="left-pane">
|
|
238
278
|
<div class="chat-wrapper">
|
|
239
|
-
${this.
|
|
279
|
+
${this.currentContact
|
|
240
280
|
? html ` <temba-contact-history
|
|
241
|
-
.uuid=${this.
|
|
242
|
-
.
|
|
243
|
-
.
|
|
281
|
+
.uuid=${this.currentContact.uuid}
|
|
282
|
+
.contact=${this.currentContact}
|
|
283
|
+
.ticket=${this.currentTicket ? this.currentTicket.uuid : null}
|
|
284
|
+
.endDate=${this.currentTicket ? this.currentTicket.closed_on : null}
|
|
244
285
|
.agent=${this.agent}
|
|
245
|
-
@temba-context-changed=${this.handleCurrentTicketChanged}
|
|
246
286
|
></temba-contact-history>
|
|
247
287
|
|
|
248
|
-
${this.
|
|
288
|
+
${this.currentTicket && this.currentTicket.closed_on
|
|
249
289
|
? html `<div class="closed-footer">
|
|
250
290
|
<temba-button
|
|
251
291
|
id="reopen-button"
|
|
@@ -281,20 +321,19 @@ export class ContactChat extends RapidElement {
|
|
|
281
321
|
: null}
|
|
282
322
|
</div>
|
|
283
323
|
</div>
|
|
284
|
-
${this.
|
|
324
|
+
${this.currentContact
|
|
285
325
|
? html `<temba-contact-details
|
|
286
326
|
style="z-index: 10"
|
|
287
327
|
class="${this.showDetails ? '' : 'hidden'}"
|
|
288
|
-
|
|
289
|
-
.name="${this.contact.name}"
|
|
328
|
+
showGroups="true"
|
|
290
329
|
.visible=${this.showDetails}
|
|
291
330
|
.ticket=${this.currentTicket}
|
|
292
|
-
|
|
331
|
+
.contact=${this.currentContact}
|
|
293
332
|
></temba-contact-details>`
|
|
294
333
|
: null}
|
|
295
334
|
|
|
296
335
|
<div class="toolbar ${this.showDetails ? '' : 'closed'}">
|
|
297
|
-
${this.
|
|
336
|
+
${this.currentContact
|
|
298
337
|
? html `
|
|
299
338
|
<temba-tip
|
|
300
339
|
style="margin-top:5px"
|
|
@@ -366,8 +405,11 @@ export class ContactChat extends RapidElement {
|
|
|
366
405
|
}
|
|
367
406
|
}
|
|
368
407
|
__decorate([
|
|
369
|
-
property({ type:
|
|
370
|
-
], ContactChat.prototype, "
|
|
408
|
+
property({ type: String, attribute: 'contact' })
|
|
409
|
+
], ContactChat.prototype, "contactUUID", void 0);
|
|
410
|
+
__decorate([
|
|
411
|
+
property({ type: String, attribute: 'ticket' })
|
|
412
|
+
], ContactChat.prototype, "ticketUUID", void 0);
|
|
371
413
|
__decorate([
|
|
372
414
|
property({ type: String })
|
|
373
415
|
], ContactChat.prototype, "contactsEndpoint", void 0);
|
|
@@ -380,9 +422,15 @@ __decorate([
|
|
|
380
422
|
__decorate([
|
|
381
423
|
property({ type: Boolean })
|
|
382
424
|
], ContactChat.prototype, "showDetails", void 0);
|
|
425
|
+
__decorate([
|
|
426
|
+
property({ type: Boolean })
|
|
427
|
+
], ContactChat.prototype, "monitor", void 0);
|
|
383
428
|
__decorate([
|
|
384
429
|
property({ type: Object })
|
|
385
430
|
], ContactChat.prototype, "currentTicket", void 0);
|
|
431
|
+
__decorate([
|
|
432
|
+
property({ type: Object })
|
|
433
|
+
], ContactChat.prototype, "currentContact", void 0);
|
|
386
434
|
__decorate([
|
|
387
435
|
property({ type: Number })
|
|
388
436
|
], ContactChat.prototype, "agent", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactChat.js","sourceRoot":"","sources":["../../../src/contacts/ContactChat.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, property, TemplateResult } from 'lit-element';\nimport { RapidElement } from '../RapidElement';\nimport { Contact, CustomEventType, Ticket } from '../interfaces';\nimport { COOKIE_KEYS, getCookieBoolean, postJSON, setCookie } from '../utils';\nimport { TextInput } from '../textinput/TextInput';\nimport { Completion } from '../completion/Completion';\nimport { ContactHistory } from './ContactHistory';\nimport { Modax } from '../dialog/Modax';\n\nexport class ContactChat extends RapidElement {\n public static get styles() {\n return css`\n :host {\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2),\n 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n\n height: 100%;\n border-radius: var(--curvature);\n\n flex-grow: 1;\n width: 100%;\n display: block;\n background: #f2f2f2;\n overflow: hidden;\n }\n\n .chat-wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #fff;\n overflow: hidden;\n border-radius: var(--curvature);\n }\n\n .chatbox {\n padding: 1em;\n background: #f2f2f2;\n border-top: 3px solid #e1e1e1;\n display: flex;\n flex-direction: column;\n z-index: 3;\n border-bottom-left-radius: var(--curvature);\n }\n\n .closed-footer {\n padding: 1em;\n background: #f2f2f2;\n border-top: 3px solid #e1e1e1;\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n\n temba-completion {\n --textarea-height: 2.5em;\n }\n\n a {\n color: var(--color-link-primary);\n }\n\n a:hover {\n text-decoration: underline;\n color: var(--color-link-primary-hover);\n }\n\n temba-button#send-button {\n --button-y: 1px;\n --button-x: 12px;\n margin-top: 0.8em;\n align-self: flex-end;\n }\n\n temba-button#reopen-button {\n --button-y: 1px;\n --button-x: 12px;\n }\n\n .toolbar {\n position: relative;\n width: 2em;\n background: #f2f2f2;\n transition: all 600ms ease-in;\n z-index: 10;\n box-shadow: -1px 0px 6px 1px rgba(0, 0, 0, 0.1);\n flex-shrink: 0;\n border-top-right-radius: var(--curvature);\n border-bottom-right-radius: var(--curvature);\n padding: 0.5em 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n overflow: hidden;\n }\n\n .toolbar temba-icon {\n fill: rgb(60, 60, 60);\n margin-bottom: 0.5em;\n }\n\n .toolbar.closed {\n box-shadow: -1px 0px 1px 1px rgba(0, 0, 0, 0);\n }\n\n temba-contact-details {\n flex-basis: 16em;\n flex-grow: 0;\n flex-shrink: 0;\n transition: margin 600ms cubic-bezier(0.68, -0.55, 0.265, 1.05),\n opacity 600ms ease-in-out 200ms;\n z-index: 5;\n margin-right: -1.5em;\n border-top-right-radius: 6px;\n }\n\n temba-contact-details.hidden {\n margin-right: -16em;\n opacity: 0;\n }\n\n @media only screen and (max-width: 768px) {\n temba-contact-details {\n flex-basis: 12em;\n flex-shrink: 0;\n }\n\n temba-contact-details.hidden {\n margin-right: -12em;\n }\n }\n\n #close-button,\n #open-button {\n margin-top: 1em;\n }\n\n #details-button {\n margin-top: 0.25em;\n transform: rotate(180deg);\n }\n\n #note-dialog,\n #assign-dialog {\n --header-bg: rgb(255, 249, 194);\n --header-text: #555;\n --textarea-height: 5em;\n }\n `;\n }\n\n @property({ type: Object })\n contact: Contact = null;\n\n @property({ type: String })\n contactsEndpoint = '/api/v2/contacts.json';\n\n @property({ type: String })\n currentChat = '';\n\n @property({ type: String })\n currentNote = '';\n\n @property({ type: Boolean })\n showDetails = true;\n\n @property({ type: Object })\n currentTicket: Ticket = null;\n\n @property({ type: Number })\n agent = -1;\n\n constructor() {\n super();\n this.showDetails = getCookieBoolean(COOKIE_KEYS.TICKET_SHOW_DETAILS);\n }\n\n public getContactHistory(): ContactHistory {\n return this.shadowRoot.querySelector(\n 'temba-contact-history'\n ) as ContactHistory;\n }\n\n public refresh(scrollToBottom = false): void {\n const contactHistory = this.getContactHistory();\n if (contactHistory) {\n if (scrollToBottom) {\n contactHistory.scrollToBottom();\n }\n contactHistory.refresh();\n }\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n // if we don't have an endpoint infer one\n if (changedProperties.has('contact')) {\n // focus our completion on load\n const prevContact = changedProperties.get('contact');\n if (\n !prevContact ||\n (this.contact && this.contact.ticket.uuid !== prevContact.ticket.uuid)\n ) {\n const completion = this.shadowRoot.querySelector(\n 'temba-completion'\n ) as Completion;\n if (completion) {\n window.setTimeout(() => {\n completion.click();\n }, 0);\n }\n }\n }\n }\n\n private handleChatChange(event: Event) {\n event.stopPropagation();\n event.preventDefault();\n\n const chat = event.currentTarget as TextInput;\n this.currentChat = chat.value;\n }\n\n private handleReopen() {\n const uuid = this.contact.ticket.uuid;\n postJSON(`/api/v2/tickets.json?uuid=${uuid}`, {\n status: 'open',\n })\n .then(() => {\n this.refresh();\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: { uuid, status: 'open' },\n });\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n private handleSend() {\n postJSON(`/api/v2/broadcasts.json`, {\n contacts: [this.contact.uuid],\n text: this.currentChat,\n ticket: this.currentTicket.uuid,\n })\n .then(() => {\n this.currentChat = '';\n this.refresh(true);\n })\n .catch(err => {\n // error message dialog?\n console.error(err);\n });\n }\n\n private handleTicketAssigned() {\n this.refresh();\n this.getContactHistory().checkForAgentAssignmentEvent(this.agent);\n }\n\n private handleDetailSlider(): void {\n this.showDetails = !this.showDetails;\n setCookie(COOKIE_KEYS.TICKET_SHOW_DETAILS, this.showDetails);\n }\n\n private handleCurrentTicketChanged(event: CustomEvent): void {\n this.currentTicket = event.detail.context;\n }\n\n public render(): TemplateResult {\n return html`\n <div style=\"display: flex; height: 100%;\">\n <div style=\"flex-grow: 1; margin-right: 0em;\">\n <div class=\"chat-wrapper\">\n ${this.contact\n ? html` <temba-contact-history\n .uuid=${this.contact.uuid}\n .ticket=${this.contact.ticket.uuid}\n .endDate=${this.contact.ticket.closed_on}\n .agent=${this.agent}\n @temba-context-changed=${this.handleCurrentTicketChanged}\n ></temba-contact-history>\n\n ${\n this.contact.ticket.closed_on\n ? html`<div class=\"closed-footer\">\n <temba-button\n id=\"reopen-button\"\n name=\"Reopen\"\n @click=${this.handleReopen}\n ></temba-button>\n </div>`\n : html` <div class=\"chatbox\">\n <temba-completion\n @change=${this.handleChatChange}\n .value=${this.currentChat}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n const chat = e.target as Completion;\n if (!chat.hasVisibleOptions()) {\n this.handleSend();\n e.preventDefault();\n e.stopPropagation();\n }\n }\n }}\n textarea\n >\n </temba-completion>\n <temba-button\n id=\"send-button\"\n name=\"Send\"\n @click=${this.handleSend}\n ?disabled=${this.currentChat.trim().length === 0}\n ></temba-button>\n </div>`\n }\n </div>`\n : null}\n </div>\n </div>\n ${this.contact\n ? html`<temba-contact-details\n style=\"z-index: 10\"\n class=\"${this.showDetails ? '' : 'hidden'}\"\n .uuid=\"${this.contact.uuid}\"\n .name=\"${this.contact.name}\"\n .visible=${this.showDetails}\n .ticket=${this.currentTicket}\n endpoint=\"${this.contactsEndpoint}?uuid=${this.contact.uuid}\"\n ></temba-contact-details>`\n : null}\n\n <div class=\"toolbar ${this.showDetails ? '' : 'closed'}\">\n ${this.contact\n ? html`\n <temba-tip\n style=\"margin-top:5px\"\n text=\"${this.showDetails ? 'Hide Details' : 'Show Details'}\"\n position=\"left\"\n hideOnChange\n >\n <temba-icon\n id=\"details-button\"\n name=\"${this.showDetails ? 'chevrons-left' : 'sidebar'}\"\n @click=\"${this.handleDetailSlider}\"\n clickable\n animatechange=\"spin\"\n ></temba-icon>\n </temba-tip>\n\n ${this.currentTicket\n ? html`<temba-tip\n style=\"margin-top:5px\"\n text=\"Assign\"\n position=\"left\"\n >\n <temba-icon\n id=\"assign-button\"\n name=\"user\"\n @click=\"${() => {\n const modax = this.shadowRoot.getElementById(\n 'assign-dialog'\n ) as Modax;\n modax.open = true;\n }}\"\n clickable\n ></temba-icon>\n </temba-tip>\n <temba-tip\n style=\"margin-top:5px\"\n text=\"Add Note\"\n position=\"left\"\n >\n <temba-icon\n id=\"add-note-button\"\n name=\"edit\"\n @click=\"${() => {\n const note = this.shadowRoot.getElementById(\n 'note-dialog'\n ) as Modax;\n note.open = true;\n }}\"\n clickable\n ></temba-icon>\n </temba-tip>`\n : null}\n `\n : null}\n </div>\n </div>\n\n ${this.currentTicket\n ? html`<temba-modax\n header=\"Add Note\"\n id=\"note-dialog\"\n @temba-submitted=${this.refresh}\n endpoint=\"/ticket/note/${this.currentTicket.uuid}/\"\n ></temba-modax>\n <temba-modax\n header=\"Assign Ticket\"\n id=\"assign-dialog\"\n @temba-submitted=${this.handleTicketAssigned}\n endpoint=\"/ticket/assign/${this.currentTicket.uuid}/\"\n /></temba-modax>`\n : null}\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ContactChat.js","sourceRoot":"","sources":["../../../src/contacts/ContactChat.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, property, TemplateResult } from 'lit-element';\nimport { RapidElement } from '../RapidElement';\nimport { Contact, CustomEventType, Ticket } from '../interfaces';\nimport { COOKIE_KEYS, getCookieBoolean, postJSON, setCookie } from '../utils';\nimport { TextInput } from '../textinput/TextInput';\nimport { Completion } from '../completion/Completion';\nimport { ContactHistory } from './ContactHistory';\nimport { Modax } from '../dialog/Modax';\nimport { fetchContact } from './helpers';\n\nconst DEFAULT_REFRESH = 10000;\n\nexport class ContactChat extends RapidElement {\n public static get styles() {\n return css`\n :host {\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2),\n 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n\n height: 100%;\n border-radius: var(--curvature);\n\n flex-grow: 1;\n width: 100%;\n display: block;\n background: #f2f2f2;\n overflow: hidden;\n }\n\n .left-pane {\n box-shadow: -13px 10px 7px 14px rgba(0, 0, 0, 0.15);\n z-index: 100;\n }\n\n .chat-wrapper {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n }\n\n .chatbox {\n padding: 1em;\n background: #f2f2f2;\n border-top: 3px solid #e1e1e1;\n display: flex;\n flex-direction: column;\n z-index: 3;\n border-bottom-left-radius: var(--curvature);\n }\n\n .closed-footer {\n padding: 1em;\n background: #f2f2f2;\n border-top: 3px solid #e1e1e1;\n display: flex;\n flex-direction: column;\n align-items: center;\n }\n\n temba-completion {\n --textarea-height: 2.5em;\n }\n\n a {\n color: var(--color-link-primary);\n }\n\n a:hover {\n text-decoration: underline;\n color: var(--color-link-primary-hover);\n }\n\n temba-button#send-button {\n --button-y: 1px;\n --button-x: 12px;\n margin-top: 0.8em;\n align-self: flex-end;\n }\n\n temba-button#reopen-button {\n --button-y: 1px;\n --button-x: 12px;\n }\n\n .toolbar {\n position: relative;\n width: 2.5em;\n background: #e6e6e6;\n transition: all 600ms ease-in;\n z-index: 10;\n flex-shrink: 0;\n border-top-right-radius: var(--curvature);\n border-bottom-right-radius: var(--curvature);\n padding: 0.5em 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n overflow: hidden;\n }\n\n .toolbar temba-icon {\n fill: rgb(60, 60, 60);\n margin-bottom: 0.5em;\n }\n\n .toolbar.closed {\n box-shadow: inset 10px 0px 10px -11px rgb(0 0 0 / 15%);\n z-index: 1000;\n }\n\n temba-contact-details {\n flex-basis: 16em;\n flex-grow: 0;\n flex-shrink: 0;\n transition: margin 600ms cubic-bezier(0.68, -0.55, 0.265, 1.05),\n opacity 600ms ease-in-out 200ms;\n z-index: 5;\n }\n\n temba-contact-details.hidden {\n margin-right: -16em;\n opacity: 0;\n }\n\n @media only screen and (max-width: 768px) {\n temba-contact-details {\n flex-basis: 12em;\n flex-shrink: 0;\n }\n\n temba-contact-details.hidden {\n margin-right: -12em;\n }\n }\n\n #close-button,\n #open-button {\n margin-top: 1em;\n }\n\n #details-button {\n margin-top: 0.25em;\n transform: rotate(180deg);\n }\n\n #note-dialog,\n #assign-dialog {\n --header-bg: rgb(255, 249, 194);\n --header-text: #555;\n --textarea-height: 5em;\n }\n `;\n }\n\n @property({ type: String, attribute: 'contact' })\n contactUUID: string;\n\n @property({ type: String, attribute: 'ticket' })\n ticketUUID: string;\n\n @property({ type: String })\n contactsEndpoint = '/api/v2/contacts.json';\n\n @property({ type: String })\n currentChat = '';\n\n @property({ type: String })\n currentNote = '';\n\n @property({ type: Boolean })\n showDetails = true;\n\n @property({ type: Boolean })\n monitor = false;\n\n @property({ type: Object })\n currentTicket: Ticket = null;\n\n @property({ type: Object })\n currentContact: Contact = null;\n\n @property({ type: Number })\n agent = -1;\n\n constructor() {\n super();\n this.showDetails = getCookieBoolean(COOKIE_KEYS.TICKET_SHOW_DETAILS);\n }\n\n refreshInterval = null;\n\n public connectedCallback() {\n super.connectedCallback();\n if (this.monitor) {\n this.refreshInterval = setInterval(() => {\n if (this.currentTicket && this.currentTicket.closed_on) {\n return;\n }\n this.refresh();\n }, DEFAULT_REFRESH);\n }\n }\n\n public disconnectedCallback() {\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval);\n }\n }\n\n public getContactHistory(): ContactHistory {\n return this.shadowRoot.querySelector(\n 'temba-contact-history'\n ) as ContactHistory;\n }\n\n public refresh(scrollToBottom = false): void {\n const contactHistory = this.getContactHistory();\n if (contactHistory) {\n if (scrollToBottom) {\n contactHistory.scrollToBottom();\n }\n contactHistory.refresh();\n }\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n\n /* if (changedProperties.has('currentTicket')) {\n console.log('currentTicket', this.currentTicket);\n }\n\n if (changedProperties.has('currentContact')) {\n console.log('currentContact', this.currentContact);\n }\n\n if (changedProperties.has('contactUUID')) {\n console.log('contactUUID', this.contactUUID);\n }*/\n\n // we were provided a uuid, fetch our contact details\n if (changedProperties.has('contactUUID')) {\n fetchContact(this.contactsEndpoint + '?uuid=' + this.contactUUID).then(\n contact => {\n this.currentContact = contact;\n }\n );\n }\n\n // if we don't have an endpoint infer one\n if (changedProperties.has('currentContact')) {\n // focus our completion on load\n const prevContact = changedProperties.get('contact');\n if (\n !prevContact ||\n (this.currentContact &&\n this.currentContact.ticket &&\n this.currentContact.ticket.uuid !== prevContact.ticket.uuid)\n ) {\n const completion = this.shadowRoot.querySelector(\n 'temba-completion'\n ) as Completion;\n if (completion) {\n window.setTimeout(() => {\n completion.click();\n }, 0);\n }\n }\n }\n }\n\n private handleChatChange(event: Event) {\n event.stopPropagation();\n event.preventDefault();\n\n const chat = event.currentTarget as TextInput;\n this.currentChat = chat.value;\n }\n\n private handleReopen() {\n const uuid = this.currentTicket.uuid;\n postJSON(`/api/v2/tickets.json?uuid=${uuid}`, {\n status: 'open',\n })\n .then(() => {\n this.refresh();\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n ticket: { uuid, status: 'open' },\n });\n })\n .catch((response: any) => {\n console.error(response);\n });\n }\n\n private handleSend() {\n const payload = {\n contacts: [this.currentContact.uuid],\n text: this.currentChat,\n };\n\n if (this.currentTicket) {\n payload['ticket'] = this.currentTicket.uuid;\n }\n\n postJSON(`/api/v2/broadcasts.json`, payload)\n .then(() => {\n this.currentChat = '';\n this.refresh(true);\n })\n .catch(err => {\n // error message dialog?\n console.error(err);\n });\n }\n\n private handleTicketAssigned() {\n this.refresh();\n this.getContactHistory().checkForAgentAssignmentEvent(this.agent);\n }\n\n private handleDetailSlider(): void {\n this.showDetails = !this.showDetails;\n setCookie(COOKIE_KEYS.TICKET_SHOW_DETAILS, this.showDetails);\n }\n\n public render(): TemplateResult {\n return html`\n <div style=\"display: flex; height: 100%;\">\n <div style=\"flex-grow: 1; margin-right: 0em;\" class=\"left-pane\">\n <div class=\"chat-wrapper\">\n ${this.currentContact\n ? html` <temba-contact-history\n .uuid=${this.currentContact.uuid}\n .contact=${this.currentContact}\n .ticket=${\n this.currentTicket ? this.currentTicket.uuid : null\n }\n .endDate=${\n this.currentTicket ? this.currentTicket.closed_on : null\n }\n .agent=${this.agent}\n ></temba-contact-history>\n\n ${\n this.currentTicket && this.currentTicket.closed_on\n ? html`<div class=\"closed-footer\">\n <temba-button\n id=\"reopen-button\"\n name=\"Reopen\"\n @click=${this.handleReopen}\n ></temba-button>\n </div>`\n : html` <div class=\"chatbox\">\n <temba-completion\n @change=${this.handleChatChange}\n .value=${this.currentChat}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n const chat = e.target as Completion;\n if (!chat.hasVisibleOptions()) {\n this.handleSend();\n e.preventDefault();\n e.stopPropagation();\n }\n }\n }}\n textarea\n >\n </temba-completion>\n <temba-button\n id=\"send-button\"\n name=\"Send\"\n @click=${this.handleSend}\n ?disabled=${this.currentChat.trim().length === 0}\n ></temba-button>\n </div>`\n }\n </div>`\n : null}\n </div>\n </div>\n ${this.currentContact\n ? html`<temba-contact-details\n style=\"z-index: 10\"\n class=\"${this.showDetails ? '' : 'hidden'}\"\n showGroups=\"true\"\n .visible=${this.showDetails}\n .ticket=${this.currentTicket}\n .contact=${this.currentContact}\n ></temba-contact-details>`\n : null}\n\n <div class=\"toolbar ${this.showDetails ? '' : 'closed'}\">\n ${this.currentContact\n ? html`\n <temba-tip\n style=\"margin-top:5px\"\n text=\"${this.showDetails ? 'Hide Details' : 'Show Details'}\"\n position=\"left\"\n hideOnChange\n >\n <temba-icon\n id=\"details-button\"\n name=\"${this.showDetails ? 'chevrons-left' : 'sidebar'}\"\n @click=\"${this.handleDetailSlider}\"\n clickable\n animatechange=\"spin\"\n ></temba-icon>\n </temba-tip>\n\n ${this.currentTicket\n ? html`<temba-tip\n style=\"margin-top:5px\"\n text=\"Assign\"\n position=\"left\"\n >\n <temba-icon\n id=\"assign-button\"\n name=\"user\"\n @click=\"${() => {\n const modax = this.shadowRoot.getElementById(\n 'assign-dialog'\n ) as Modax;\n modax.open = true;\n }}\"\n clickable\n ></temba-icon>\n </temba-tip>\n <temba-tip\n style=\"margin-top:5px\"\n text=\"Add Note\"\n position=\"left\"\n >\n <temba-icon\n id=\"add-note-button\"\n name=\"edit\"\n @click=\"${() => {\n const note = this.shadowRoot.getElementById(\n 'note-dialog'\n ) as Modax;\n note.open = true;\n }}\"\n clickable\n ></temba-icon>\n </temba-tip>`\n : null}\n `\n : null}\n </div>\n </div>\n\n ${this.currentTicket\n ? html`<temba-modax\n header=\"Add Note\"\n id=\"note-dialog\"\n @temba-submitted=${this.refresh}\n endpoint=\"/ticket/note/${this.currentTicket.uuid}/\"\n ></temba-modax>\n <temba-modax\n header=\"Assign Ticket\"\n id=\"assign-dialog\"\n @temba-submitted=${this.handleTicketAssigned}\n endpoint=\"/ticket/assign/${this.currentTicket.uuid}/\"\n /></temba-modax>`\n : null}\n `;\n }\n}\n"]}
|
|
@@ -19,18 +19,16 @@ export class ContactDetails extends RapidElement {
|
|
|
19
19
|
static get styles() {
|
|
20
20
|
return css `
|
|
21
21
|
:host {
|
|
22
|
-
box-shadow: inset 14px 0 7px -14px rgba(0, 0, 0, 0.15);
|
|
23
22
|
background: #f9f9f9;
|
|
24
23
|
display: block;
|
|
25
24
|
height: 100%;
|
|
26
25
|
position: relative;
|
|
27
|
-
border-bottom-right-radius: var(--curvature);
|
|
28
26
|
overflow: hidden;
|
|
27
|
+
-webkit-mask-image: -webkit-radial-gradient(white, black);
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
.wrapper {
|
|
32
|
-
padding
|
|
33
|
-
padding-left: 1em;
|
|
31
|
+
padding: 0em 1em;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
34
|
a {
|
|
@@ -42,9 +40,9 @@ export class ContactDetails extends RapidElement {
|
|
|
42
40
|
}
|
|
43
41
|
|
|
44
42
|
.contact > .name {
|
|
45
|
-
font-size:
|
|
43
|
+
font-size: 1.2em;
|
|
46
44
|
font-weight: 400;
|
|
47
|
-
padding: 0.75em;
|
|
45
|
+
padding: 0.5em 0.75em;
|
|
48
46
|
padding-right: 1em;
|
|
49
47
|
}
|
|
50
48
|
|
|
@@ -91,12 +89,9 @@ export class ContactDetails extends RapidElement {
|
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
.fields-wrapper {
|
|
94
|
-
margin-top: 1em;
|
|
95
92
|
background: #fff;
|
|
96
|
-
border-radius: var(--curvature);
|
|
97
93
|
overflow: hidden;
|
|
98
|
-
|
|
99
|
-
0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
|
94
|
+
margin: 0em -1em;
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
.body-wrapper {
|
|
@@ -111,9 +106,7 @@ export class ContactDetails extends RapidElement {
|
|
|
111
106
|
.fields {
|
|
112
107
|
padding: 1em;
|
|
113
108
|
max-height: 200px;
|
|
114
|
-
border-radius: var(--curvature);
|
|
115
109
|
overflow-y: auto;
|
|
116
|
-
-webkit-mask-image: -webkit-radial-gradient(white, black);
|
|
117
110
|
}
|
|
118
111
|
|
|
119
112
|
.field {
|
|
@@ -145,12 +138,9 @@ export class ContactDetails extends RapidElement {
|
|
|
145
138
|
}
|
|
146
139
|
updated(changes) {
|
|
147
140
|
super.updated(changes);
|
|
148
|
-
if (changes.has('
|
|
149
|
-
this.flow = null;
|
|
150
|
-
this.expandFields = false;
|
|
141
|
+
if (changes.has('contact')) {
|
|
151
142
|
const store = document.querySelector('temba-store');
|
|
152
|
-
|
|
153
|
-
this.contact = contact;
|
|
143
|
+
if (this.contact && this.contact.fields) {
|
|
154
144
|
this.fields = Object.keys(this.contact.fields).filter((key) => {
|
|
155
145
|
const hasField = !!this.contact.fields[key];
|
|
156
146
|
return hasField && store.getContactField(key).pinned;
|
|
@@ -167,6 +157,13 @@ export class ContactDetails extends RapidElement {
|
|
|
167
157
|
}
|
|
168
158
|
return a.name.localeCompare(b.name);
|
|
169
159
|
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (changes.has('endpoint')) {
|
|
163
|
+
this.flow = null;
|
|
164
|
+
this.expandFields = false;
|
|
165
|
+
fetchContact(this.endpoint).then((contact) => {
|
|
166
|
+
this.contact = contact;
|
|
170
167
|
});
|
|
171
168
|
}
|
|
172
169
|
}
|
|
@@ -196,9 +193,9 @@ export class ContactDetails extends RapidElement {
|
|
|
196
193
|
}
|
|
197
194
|
if (this.contact) {
|
|
198
195
|
return html `<div class="contact">
|
|
199
|
-
<div class="name"
|
|
200
|
-
|
|
201
|
-
${this.showGroups
|
|
196
|
+
<div class="name">
|
|
197
|
+
${this.name || this.contact.name}
|
|
198
|
+
${this.showGroups && !this.ticket
|
|
202
199
|
? html `<div>
|
|
203
200
|
${this.contact.groups.map((group) => {
|
|
204
201
|
return html `<a
|
|
@@ -213,6 +210,8 @@ export class ContactDetails extends RapidElement {
|
|
|
213
210
|
})}
|
|
214
211
|
</div>`
|
|
215
212
|
: html ``}
|
|
213
|
+
</div>
|
|
214
|
+
<div class="wrapper">
|
|
216
215
|
${body
|
|
217
216
|
? html `<div class="body-wrapper">
|
|
218
217
|
<div class="body">${body}</div>
|
|
@@ -265,13 +264,14 @@ export class ContactDetails extends RapidElement {
|
|
|
265
264
|
: null}
|
|
266
265
|
|
|
267
266
|
<div class="actions">
|
|
268
|
-
${this.showGroups
|
|
267
|
+
${this.showGroups && !this.ticket
|
|
269
268
|
? html `
|
|
270
269
|
<div class="start-flow">
|
|
271
270
|
<temba-select
|
|
272
271
|
endpoint="/api/v2/flows.json?archived=false"
|
|
273
272
|
placeholder="Start Flow"
|
|
274
273
|
flavor="small"
|
|
274
|
+
searchable="true"
|
|
275
275
|
.values=${this.flow ? [this.flow] : []}
|
|
276
276
|
@temba-selection=${this.handleFlowChanged}
|
|
277
277
|
></temba-select>
|
|
@@ -291,7 +291,7 @@ __decorate([
|
|
|
291
291
|
property({ type: String })
|
|
292
292
|
], ContactDetails.prototype, "uuid", void 0);
|
|
293
293
|
__decorate([
|
|
294
|
-
property({
|
|
294
|
+
property({ type: Object })
|
|
295
295
|
], ContactDetails.prototype, "contact", void 0);
|
|
296
296
|
__decorate([
|
|
297
297
|
property({ attribute: false })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactDetails.js","sourceRoot":"","sources":["../../../src/contacts/ContactDetails.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/camelcase */\nimport { css, html, property, TemplateResult } from 'lit-element';\nimport { Contact, Group, Ticket } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\nimport { isDate, timeSince, truncate } from '../utils';\nimport { Store } from '../store/Store';\nimport { BODY_SNIPPET_LENGTH, fetchContact } from './helpers';\n\nexport class ContactDetails extends RapidElement {\n static get styles() {\n return css`\n :host {\n box-shadow: inset 14px 0 7px -14px rgba(0, 0, 0, 0.15);\n background: #f9f9f9;\n display: block;\n height: 100%;\n position: relative;\n border-bottom-right-radius: var(--curvature);\n overflow: hidden;\n }\n\n .wrapper {\n padding-right: 3.5em;\n padding-left: 1em;\n }\n\n a {\n color: var(--color-link-primary);\n }\n\n .field-links {\n font-size: 0.8em;\n }\n\n .contact > .name {\n font-size: 18px;\n font-weight: 400;\n padding: 0.75em;\n padding-right: 1em;\n }\n\n .group-label temba-icon {\n display: inline-block;\n fill: var(--color-text-dark);\n margin-bottom: -2px;\n margin-right: 4px;\n }\n\n .group-label {\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),\n 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n line-height: 1.25;\n text-decoration: none;\n cursor: default;\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n display: inline-block;\n font-size: 0.75rem;\n font-weight: 400;\n border-radius: 9999px;\n background-color: #f1f1f1;\n color: rgba(0, 0, 0, 0.5);\n letter-spacing: 0.025em;\n white-space: nowrap;\n text-align: center;\n margin-right: 6px;\n margin-top: 6px;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .start-flow {\n }\n\n .actions {\n margin-top: 16px;\n border: 0px solid #ddd;\n border-radius: var(--curvature);\n padding: 0px;\n }\n\n .fields-wrapper {\n margin-top: 1em;\n background: #fff;\n border-radius: var(--curvature);\n overflow: hidden;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),\n 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n }\n\n .body-wrapper {\n overflow: hidden;\n }\n\n .body {\n max-height: 200px;\n overflow-y: auto;\n }\n\n .fields {\n padding: 1em;\n max-height: 200px;\n border-radius: var(--curvature);\n overflow-y: auto;\n -webkit-mask-image: -webkit-radial-gradient(white, black);\n }\n\n .field {\n border-radius: var(--curvature);\n\n display: flex;\n flex-direction: column;\n margin-bottom: 0.3em;\n }\n\n .field .name {\n margin-right: 8px;\n font-weight: 400;\n color: #666;\n font-size: 0.9em;\n word-break: break-word;\n }\n .field .value {\n font-size: 0.8em;\n word-break: break-word;\n }\n\n temba-button {\n margin-top: 5px;\n display: block;\n --button-y: 0;\n }\n `;\n }\n\n // optional display name\n @property({ type: String })\n name: string;\n\n @property({ type: String })\n uuid: string;\n\n @property({ attribute: false, type: Object })\n contact: Contact;\n\n @property({ attribute: false })\n flow: any = null;\n\n // the fields with values for this contact\n @property({ type: Array })\n fields: string[] = [];\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Boolean })\n expandFields = false;\n\n @property({ type: Boolean })\n expandBody = false;\n\n @property({ type: Boolean })\n showGroups = false;\n\n @property({ type: Boolean })\n showFlows = false;\n\n @property({ type: Object })\n ticket: Ticket = null;\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n if (changes.has('endpoint')) {\n this.flow = null;\n this.expandFields = false;\n\n const store: Store = document.querySelector('temba-store');\n\n fetchContact(this.endpoint).then((contact: Contact) => {\n this.contact = contact;\n this.fields = Object.keys(this.contact.fields).filter((key: string) => {\n const hasField = !!this.contact.fields[key];\n return hasField && store.getContactField(key).pinned;\n });\n\n this.contact.groups.forEach((group: Group) => {\n group.is_dynamic = store.isDynamicGroup(group.uuid);\n });\n\n this.contact.groups.sort((a: Group, b: Group) => {\n if (a.is_dynamic) {\n return -1;\n }\n if (b.is_dynamic) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n });\n }\n }\n\n private handleFlowChanged(evt: CustomEvent) {\n this.flow = evt.detail.selected as any;\n }\n\n private handleExpandFields(): void {\n this.expandFields = true;\n }\n\n private handleHideFields(): void {\n this.expandFields = false;\n }\n\n private handleExpandBody(): void {\n this.expandBody = true;\n }\n\n private handleHideBody(): void {\n this.expandBody = false;\n }\n\n public render(): TemplateResult {\n const store: Store = document.querySelector('temba-store');\n\n let body = this.ticket ? this.ticket.body : null;\n const showBodyToggle = body ? body.length > BODY_SNIPPET_LENGTH : false;\n if (\n !this.expandBody &&\n this.ticket &&\n this.ticket.body.length > BODY_SNIPPET_LENGTH\n ) {\n body = truncate(this.ticket.body, BODY_SNIPPET_LENGTH);\n }\n\n if (this.contact) {\n return html`<div class=\"contact\">\n <div class=\"name\">${this.name || this.contact.name}</div>\n <div class=\"wrapper\">\n ${this.showGroups\n ? html`<div>\n ${this.contact.groups.map((group: Group) => {\n return html`<a\n href=\"/contact/filter/${group.uuid}/\"\n target=\"_\"\n ><div class=\"group-label\" style=\"cursor:pointer\">\n ${group.is_dynamic\n ? html`<temba-icon name=\"atom\"></temba-icon>`\n : null}${group.name}\n </div></a\n >`;\n })}\n </div>`\n : html``}\n ${body\n ? html`<div class=\"body-wrapper\">\n <div class=\"body\">${body}</div>\n <div class=\"field-links\">\n ${showBodyToggle\n ? !this.expandBody\n ? html`<a href=\"#\" @click=\"${this.handleExpandBody}\"\n >more</a\n >`\n : html`<a href=\"#\" @click=\"${this.handleHideBody}\"\n >less</a\n >`\n : null}\n </div>\n </div>`\n : null}\n ${this.fields.length > 0\n ? html` <div class=\"fields-wrapper\">\n <div class=\"fields\">\n ${this.fields\n .slice(0, this.expandFields ? 255 : 3)\n .map((key: string) => {\n let value = this.contact.fields[key];\n if (value) {\n if (isDate(value)) {\n value = timeSince(new Date(value));\n }\n return html`<div class=\"field\">\n <div class=\"name\">\n ${store.getContactField(key).label}\n </div>\n <div class=\"value\">${value}</div>\n </div>`;\n }\n })}\n\n <div class=\"field-links\">\n ${this.fields.length > 3\n ? !this.expandFields\n ? html`<a href=\"#\" @click=\"${this.handleExpandFields}\"\n >more</a\n >`\n : html`<a href=\"#\" @click=\"${this.handleHideFields}\"\n >less</a\n >`\n : null}\n </div>\n </div>\n </div>`\n : null}\n\n <div class=\"actions\">\n ${this.showGroups\n ? html`\n <div class=\"start-flow\">\n <temba-select\n endpoint=\"/api/v2/flows.json?archived=false\"\n placeholder=\"Start Flow\"\n flavor=\"small\"\n .values=${this.flow ? [this.flow] : []}\n @temba-selection=${this.handleFlowChanged}\n ></temba-select>\n </div>\n `\n : null}\n </div>\n </div>\n </div>`;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ContactDetails.js","sourceRoot":"","sources":["../../../src/contacts/ContactDetails.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/camelcase */\nimport { css, html, property, TemplateResult } from 'lit-element';\nimport { Contact, Group, Ticket } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\nimport { isDate, timeSince, truncate } from '../utils';\nimport { Store } from '../store/Store';\nimport { BODY_SNIPPET_LENGTH, fetchContact } from './helpers';\n\nexport class ContactDetails extends RapidElement {\n static get styles() {\n return css`\n :host {\n background: #f9f9f9;\n display: block;\n height: 100%;\n position: relative;\n overflow: hidden;\n -webkit-mask-image: -webkit-radial-gradient(white, black);\n }\n\n .wrapper {\n padding: 0em 1em;\n }\n\n a {\n color: var(--color-link-primary);\n }\n\n .field-links {\n font-size: 0.8em;\n }\n\n .contact > .name {\n font-size: 1.2em;\n font-weight: 400;\n padding: 0.5em 0.75em;\n padding-right: 1em;\n }\n\n .group-label temba-icon {\n display: inline-block;\n fill: var(--color-text-dark);\n margin-bottom: -2px;\n margin-right: 4px;\n }\n\n .group-label {\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1),\n 0 1px 2px 0 rgba(0, 0, 0, 0.06);\n line-height: 1.25;\n text-decoration: none;\n cursor: default;\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n display: inline-block;\n font-size: 0.75rem;\n font-weight: 400;\n border-radius: 9999px;\n background-color: #f1f1f1;\n color: rgba(0, 0, 0, 0.5);\n letter-spacing: 0.025em;\n white-space: nowrap;\n text-align: center;\n margin-right: 6px;\n margin-top: 6px;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .start-flow {\n }\n\n .actions {\n margin-top: 16px;\n border: 0px solid #ddd;\n border-radius: var(--curvature);\n padding: 0px;\n }\n\n .fields-wrapper {\n background: #fff;\n overflow: hidden;\n margin: 0em -1em;\n }\n\n .body-wrapper {\n overflow: hidden;\n }\n\n .body {\n max-height: 200px;\n overflow-y: auto;\n }\n\n .fields {\n padding: 1em;\n max-height: 200px;\n overflow-y: auto;\n }\n\n .field {\n border-radius: var(--curvature);\n\n display: flex;\n flex-direction: column;\n margin-bottom: 0.3em;\n }\n\n .field .name {\n margin-right: 8px;\n font-weight: 400;\n color: #666;\n font-size: 0.9em;\n word-break: break-word;\n }\n .field .value {\n font-size: 0.8em;\n word-break: break-word;\n }\n\n temba-button {\n margin-top: 5px;\n display: block;\n --button-y: 0;\n }\n `;\n }\n\n // optional display name\n @property({ type: String })\n name: string;\n\n @property({ type: String })\n uuid: string;\n\n @property({ type: Object })\n contact: Contact;\n\n @property({ attribute: false })\n flow: any = null;\n\n // the fields with values for this contact\n @property({ type: Array })\n fields: string[] = [];\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Boolean })\n expandFields = false;\n\n @property({ type: Boolean })\n expandBody = false;\n\n @property({ type: Boolean })\n showGroups = false;\n\n @property({ type: Boolean })\n showFlows = false;\n\n @property({ type: Object })\n ticket: Ticket = null;\n\n public updated(changes: Map<string, any>) {\n super.updated(changes);\n\n if (changes.has('contact')) {\n const store: Store = document.querySelector('temba-store');\n if (this.contact && this.contact.fields) {\n this.fields = Object.keys(this.contact.fields).filter((key: string) => {\n const hasField = !!this.contact.fields[key];\n return hasField && store.getContactField(key).pinned;\n });\n\n this.contact.groups.forEach((group: Group) => {\n group.is_dynamic = store.isDynamicGroup(group.uuid);\n });\n\n this.contact.groups.sort((a: Group, b: Group) => {\n if (a.is_dynamic) {\n return -1;\n }\n if (b.is_dynamic) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n }\n }\n\n if (changes.has('endpoint')) {\n this.flow = null;\n this.expandFields = false;\n fetchContact(this.endpoint).then((contact: Contact) => {\n this.contact = contact;\n });\n }\n }\n\n private handleFlowChanged(evt: CustomEvent) {\n this.flow = evt.detail.selected as any;\n }\n\n private handleExpandFields(): void {\n this.expandFields = true;\n }\n\n private handleHideFields(): void {\n this.expandFields = false;\n }\n\n private handleExpandBody(): void {\n this.expandBody = true;\n }\n\n private handleHideBody(): void {\n this.expandBody = false;\n }\n\n public render(): TemplateResult {\n const store: Store = document.querySelector('temba-store');\n\n let body = this.ticket ? this.ticket.body : null;\n const showBodyToggle = body ? body.length > BODY_SNIPPET_LENGTH : false;\n if (\n !this.expandBody &&\n this.ticket &&\n this.ticket.body.length > BODY_SNIPPET_LENGTH\n ) {\n body = truncate(this.ticket.body, BODY_SNIPPET_LENGTH);\n }\n\n if (this.contact) {\n return html`<div class=\"contact\">\n <div class=\"name\">\n ${this.name || this.contact.name}\n ${this.showGroups && !this.ticket\n ? html`<div>\n ${this.contact.groups.map((group: Group) => {\n return html`<a\n href=\"/contact/filter/${group.uuid}/\"\n target=\"_\"\n ><div class=\"group-label\" style=\"cursor:pointer\">\n ${group.is_dynamic\n ? html`<temba-icon name=\"atom\"></temba-icon>`\n : null}${group.name}\n </div></a\n >`;\n })}\n </div>`\n : html``}\n </div>\n <div class=\"wrapper\">\n ${body\n ? html`<div class=\"body-wrapper\">\n <div class=\"body\">${body}</div>\n <div class=\"field-links\">\n ${showBodyToggle\n ? !this.expandBody\n ? html`<a href=\"#\" @click=\"${this.handleExpandBody}\"\n >more</a\n >`\n : html`<a href=\"#\" @click=\"${this.handleHideBody}\"\n >less</a\n >`\n : null}\n </div>\n </div>`\n : null}\n ${this.fields.length > 0\n ? html` <div class=\"fields-wrapper\">\n <div class=\"fields\">\n ${this.fields\n .slice(0, this.expandFields ? 255 : 3)\n .map((key: string) => {\n let value = this.contact.fields[key];\n if (value) {\n if (isDate(value)) {\n value = timeSince(new Date(value));\n }\n return html`<div class=\"field\">\n <div class=\"name\">\n ${store.getContactField(key).label}\n </div>\n <div class=\"value\">${value}</div>\n </div>`;\n }\n })}\n\n <div class=\"field-links\">\n ${this.fields.length > 3\n ? !this.expandFields\n ? html`<a href=\"#\" @click=\"${this.handleExpandFields}\"\n >more</a\n >`\n : html`<a href=\"#\" @click=\"${this.handleHideFields}\"\n >less</a\n >`\n : null}\n </div>\n </div>\n </div>`\n : null}\n\n <div class=\"actions\">\n ${this.showGroups && !this.ticket\n ? html`\n <div class=\"start-flow\">\n <temba-select\n endpoint=\"/api/v2/flows.json?archived=false\"\n placeholder=\"Start Flow\"\n flavor=\"small\"\n searchable=\"true\"\n .values=${this.flow ? [this.flow] : []}\n @temba-selection=${this.handleFlowChanged}\n ></temba-select>\n </div>\n `\n : null}\n </div>\n </div>\n </div>`;\n }\n }\n}\n"]}
|