@nyaruka/temba-components 0.42.0 → 0.43.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 +16 -0
- package/dist/{f3b7c2f1.js → 96498fd6.js} +227 -203
- package/dist/index.js +227 -203
- 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/aliaseditor/AliasEditor.js +2 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
- package/out-tsc/src/compose/Compose.js +1 -0
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +1 -2
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactHistory.js +17 -1
- package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
- package/out-tsc/src/contacts/events.js +64 -58
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/lightbox/Lightbox.js +146 -0
- package/out-tsc/src/lightbox/Lightbox.js.map +1 -0
- package/out-tsc/src/list/TembaMenu.js +2 -42
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/list/TicketList.js +2 -2
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/utils/index.js +54 -1
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +1 -1
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/out-tsc/temba-modules.js +2 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +16 -2
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-contact-history.test.js +1 -1
- package/out-tsc/test/temba-contact-history.test.js.map +1 -1
- package/out-tsc/test/temba-lightbox.test.js +28 -0
- package/out-tsc/test/temba-lightbox.test.js.map +1 -0
- package/out-tsc/test/utils.test.js +1 -2
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
- package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
- package/screenshots/truth/contacts/contact-active-default.png +0 -0
- package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-active-ticket-closed-show-reopen-button.png +0 -0
- package/screenshots/truth/contacts/contact-active-ticket-open-show-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-archived-ticket-closed-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/history.png +0 -0
- package/screenshots/truth/lightbox/img-zoomed.png +0 -0
- package/screenshots/truth/lightbox/img.png +0 -0
- package/screenshots/truth/menu/menu-focused-with items.png +0 -0
- package/screenshots/truth/menu/menu-refresh-1.png +0 -0
- package/screenshots/truth/menu/menu-refresh-2.png +0 -0
- package/screenshots/truth/menu/menu-root.png +0 -0
- package/screenshots/truth/menu/menu-submenu.png +0 -0
- package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
- package/screenshots/truth/menu/menu-tasks.png +0 -0
- package/src/aliaseditor/AliasEditor.ts +2 -1
- package/src/compose/Compose.ts +1 -0
- package/src/contacts/ContactChat.ts +1 -2
- package/src/contacts/ContactHistory.ts +19 -1
- package/src/contacts/events.ts +79 -64
- package/src/lightbox/Lightbox.ts +161 -0
- package/src/list/TembaMenu.ts +2 -45
- package/src/list/TicketList.ts +2 -2
- package/src/untyped.d.ts +1 -0
- package/src/utils/index.ts +68 -2
- package/src/vectoricon/index.ts +1 -1
- package/static/css/temba-components.css +4 -1
- package/temba-modules.ts +2 -0
- package/test/temba-contact-chat.test.ts +16 -3
- package/test/temba-contact-history.test.ts +1 -1
- package/test/temba-lightbox.test.ts +35 -0
- package/test/utils.test.ts +1 -2
- package/test-assets/img/meow.jpg +0 -0
- package/test-assets/style.css +1 -0
- package/web-test-runner.config.mjs +4 -0
- package/screenshots/truth/menu/menu-focus.png +0 -0
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
|
|
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 c=e=>o(e,i),l={module:{uri:i},exports:r,require:c};t[i]=Promise.all(n.map((e=>l[e]||c(e)))).then((e=>(s(...e),r)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"96498fd6.js",revision:"6ac3aa6ee1670e83e9be10c55728f1f6"},{url:"templates/components-body.html",revision:"cd9f77c6113b76c983925c17670c8fa0"},{url:"templates/components-head.html",revision:"a7cf8743843d01afb834337d07c13eef"}],{}),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/b1ef8bce74c44f9167fde1beb5876505/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 {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\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\": \"96498fd6.js\",\n \"revision\": \"6ac3aa6ee1670e83e9be10c55728f1f6\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"cd9f77c6113b76c983925c17670c8fa0\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"a7cf8743843d01afb834337d07c13eef\"\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/
|
|
1
|
+
<script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/96498fd6.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.43.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/96498fd6.js" crossorigin="anonymous">
|
|
@@ -2,6 +2,7 @@ import { __decorate } from "tslib";
|
|
|
2
2
|
import { css, html, LitElement } from 'lit';
|
|
3
3
|
import { getUrl, postJSON } from '../utils';
|
|
4
4
|
import { styleMap } from 'lit-html/directives/style-map.js';
|
|
5
|
+
import { Icon } from '../vectoricon';
|
|
5
6
|
import { property } from 'lit/decorators.js';
|
|
6
7
|
export class AliasEditor extends LitElement {
|
|
7
8
|
static get styles() {
|
|
@@ -221,7 +222,7 @@ export class AliasEditor extends LitElement {
|
|
|
221
222
|
evt.stopPropagation();
|
|
222
223
|
}}
|
|
223
224
|
>
|
|
224
|
-
<temba-icon name="
|
|
225
|
+
<temba-icon name="${Icon.updated}" />
|
|
225
226
|
</div>
|
|
226
227
|
`
|
|
227
228
|
: ''}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AliasEditor.js","sourceRoot":"","sources":["../../../src/aliaseditor/AliasEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, TemplateResult } from 'lit';\nimport { FeatureProperties } from '../interfaces';\nimport { getUrl, postJSON, WebResponse } from '../utils';\nimport { TextInput } from '../textinput/TextInput';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { FormElement } from '../FormElement';\n\nimport { property } from 'lit/decorators.js';\n\nexport class AliasEditor extends LitElement {\n static get styles() {\n return css`\n :host {\n line-height: normal;\n }\n\n temba-textinput {\n height: 150px;\n }\n\n #left-column {\n display: inline-block;\n margin-left: 10px;\n width: 300px;\n z-index: 100;\n }\n\n .search {\n margin-bottom: 10px;\n }\n\n .feature {\n padding: 4px 14px;\n font-size: 16px;\n }\n\n .level-0 {\n margin-left: 0px;\n }\n\n .level-1 {\n margin-left: 5px;\n font-size: 95%;\n }\n\n .level-2 {\n margin-left: 10px;\n font-size: 90%;\n }\n\n .level-3 {\n margin-left: 15px;\n font-size: 85%;\n }\n\n .feature-name {\n display: inline-block;\n }\n\n .clickable {\n text-decoration: none;\n cursor: pointer;\n color: var(--color-link-primary);\n }\n\n .clickable.secondary {\n color: var(--color-link-secondary);\n }\n\n .clickable:hover {\n text-decoration: underline;\n color: var(--color-link-primary-hover);\n }\n\n .feature:hover .showonhover {\n visibility: visible;\n }\n\n .showonhover {\n visibility: hidden;\n }\n\n .aliases {\n color: #bbb;\n font-size: 80%;\n display: inline;\n margin-left: 5px;\n }\n\n temba-label {\n margin-right: 3px;\n margin-bottom: 3px;\n vertical-align: top;\n }\n\n .selected {\n display: flex;\n flex-direction: column;\n padding: 15px;\n padding-bottom: 40px;\n }\n\n .selected .name {\n font-size: 18px;\n padding: 5px;\n }\n\n .selected .help {\n padding: 5px 2px;\n font-size: 11px;\n color: var(--color-secondary-light);\n }\n\n #right-column {\n vertical-align: top;\n margin-left: 20px;\n display: inline-block;\n }\n\n leaflet-map {\n height: 250px;\n width: 450px;\n border: 0px solid #999;\n border-radius: var(--curvature);\n }\n\n .edit {\n display: inline-block;\n margin-right: 0px;\n }\n `;\n }\n\n @property({ type: Array, attribute: false })\n path: FeatureProperties[] = [];\n\n @property()\n endpoint: string;\n\n @property()\n osmId: string;\n\n @property({ type: Object })\n hovered: FeatureProperties;\n\n @property({ type: Object })\n editFeature: FeatureProperties;\n\n @property({ type: String, attribute: false })\n editFeatureAliases: string;\n\n public constructor() {\n super();\n }\n\n public updated(changedProperties: Map<string, any>) {\n if (changedProperties.has('osmId')) {\n // going up the tree doesn't require a fetch\n const newPath = [];\n for (const feature of this.path) {\n newPath.push(feature);\n if (feature.osm_id === this.osmId) {\n this.path = [...newPath];\n this.hideAliasDialog();\n return;\n }\n }\n\n this.fetchFeature();\n }\n }\n\n private fetchFeature() {\n getUrl(this.getEndpoint() + 'boundaries/' + this.osmId + '/').then(\n (response: WebResponse) => {\n this.path = response.json as FeatureProperties[];\n this.hideAliasDialog();\n }\n );\n }\n\n private handleMapClicked(feature: FeatureProperties): void {\n this.hovered = null;\n if (!feature || feature.osm_id !== this.osmId) {\n this.osmId = feature.osm_id;\n }\n }\n\n private handlePlaceClicked(feature: FeatureProperties) {\n this.osmId = feature.osm_id;\n }\n\n private handleSearchSelection(evt: CustomEvent) {\n const selection = evt.detail.selected as FeatureProperties;\n this.showAliasDialog(selection);\n const select = this.shadowRoot.querySelector('temba-select') as FormElement;\n select.clear();\n }\n\n private isMatch(option: any, query: string) {\n return `${option.name} ${option.aliases}`.toLowerCase().indexOf(query) > -1;\n }\n\n private renderFeature(\n feature: FeatureProperties,\n remainingPath: FeatureProperties[]\n ): TemplateResult {\n const selectedFeature = this.path[this.path.length - 1];\n const clickable =\n (feature.has_children || feature.level === 0) &&\n feature !== selectedFeature;\n const renderedFeature = html`\n <div class=\"feature\">\n <div\n @mouseover=${() => {\n if (feature.level > 0) {\n this.hovered = feature;\n }\n }}\n @mouseout=${() => {\n this.hovered = null;\n }}\n class=\"level-${feature.level}\"\n >\n <div\n class=\"feature-name ${clickable ? 'clickable' : ''}\"\n @click=${() => {\n if (clickable) {\n this.handlePlaceClicked(feature);\n }\n }}\n >\n ${feature.name}\n </div>\n\n <div class=\"aliases\">\n ${feature.aliases.split('\\n').map((alias: string) =>\n alias.trim().length > 0\n ? html`\n <temba-label\n class=\"alias\"\n @click=${() => {\n this.showAliasDialog(feature);\n }}\n light\n clickable\n >${alias}</temba-label\n >\n `\n : null\n )}\n ${feature.level > 0\n ? html`\n <div\n class=\"edit clickable showonhover\"\n @click=${(evt: MouseEvent) => {\n this.showAliasDialog(feature);\n evt.preventDefault();\n evt.stopPropagation();\n }}\n >\n <temba-icon name=\"edit\" />\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `;\n\n const renderedChildren = (feature.children || []).map(\n (child: FeatureProperties) => {\n if (\n remainingPath.length > 0 &&\n remainingPath[0].osm_id === child.osm_id\n ) {\n return this.renderFeature(remainingPath[0], remainingPath.slice(1));\n }\n\n if (\n remainingPath.length === 0 ||\n remainingPath[0].children.length === 0\n ) {\n return this.renderFeature(child, remainingPath);\n }\n\n return null;\n }\n );\n\n return html` ${renderedFeature} ${renderedChildren} `;\n }\n\n public showAliasDialog(feature: FeatureProperties) {\n this.editFeatureAliases = feature.aliases;\n this.editFeature = feature;\n const aliasDialog = this.shadowRoot.getElementById('alias-dialog');\n if (aliasDialog) {\n aliasDialog.setAttribute('open', '');\n }\n }\n\n public hideAliasDialog() {\n const aliasDialog = this.shadowRoot.getElementById('alias-dialog');\n this.editFeature = null;\n this.editFeatureAliases = null;\n if (aliasDialog) {\n aliasDialog.removeAttribute('open');\n }\n\n this.requestUpdate();\n }\n\n private getEndpoint(): string {\n return this.endpoint + (!this.endpoint.endsWith('/') ? '/' : '');\n }\n\n private handleDialogClick(evt: CustomEvent) {\n const button = evt.detail.button;\n if (button.name === 'Save') {\n const textarea = this.shadowRoot.getElementById(\n this.editFeature.osm_id\n ) as TextInput;\n const aliases = textarea.inputElement.value;\n const payload = { osm_id: this.editFeature.osm_id, aliases };\n postJSON(\n this.getEndpoint() + 'boundaries/' + this.editFeature.osm_id + '/',\n payload\n ).then(() => {\n this.fetchFeature();\n });\n }\n\n if (button.name === 'Cancel') {\n this.hideAliasDialog();\n }\n }\n\n private getOptions(response: WebResponse) {\n return response.json.filter((option: any) => option.level > 0);\n }\n\n private getOptionsComplete(newestOptions: FeatureProperties[]) {\n return newestOptions.length === 0;\n }\n\n private renderOptionDetail(option: FeatureProperties): TemplateResult {\n const labelStyles = {\n marginTop: '3px',\n marginRight: '3px',\n };\n\n const aliasList = option.aliases.split('\\n');\n const aliases = aliasList.map((alias: string) =>\n alias.trim().length > 0\n ? html`\n <temba-label style=${styleMap(labelStyles)} class=\"alias\" dark\n >${alias}</temba-label\n >\n `\n : null\n );\n return html`\n <div class=\"path\">${option.path.replace(/>/gi, '‣')}</div>\n <div class=\"aliases\">${aliases}</div>\n `;\n }\n\n public render(): TemplateResult {\n if (this.path.length === 0) {\n return html``;\n }\n\n // if we are a leaf, have our map show the level above\n const selectedFeature = this.path[this.path.length - 1];\n const mapFeature =\n selectedFeature.children.length === 0\n ? this.path[this.path.length - 2]\n : selectedFeature;\n\n const editFeatureId = this.editFeature ? this.editFeature.osm_id : null;\n const editFeatureName = this.editFeature ? this.editFeature.name : null;\n\n return html`\n <div id=\"left-column\">\n <div class=\"search\">\n <temba-select\n placeholder=\"Search\"\n endpoint=\"${this.getEndpoint()}boundaries/${this.path[0].osm_id}/?\"\n .renderOptionDetail=${this.renderOptionDetail}\n .getOptions=${this.getOptions}\n .isComplete=${this.getOptionsComplete}\n .isMatch=${this.isMatch}\n @temba-selection=${this.handleSearchSelection.bind(this)}\n queryParam=\"q\"\n searchable\n ></temba-select>\n </div>\n <div class=\"feature-tree\">\n ${this.renderFeature(this.path[0], this.path.slice(1))}\n </div>\n </div>\n\n <div id=\"right-column\">\n <leaflet-map\n endpoint=${this.getEndpoint()}\n .feature=${mapFeature}\n .osmId=${mapFeature.osm_id}\n .hovered=${this.hovered}\n .onFeatureClicked=${this.handleMapClicked.bind(this)}\n >\n </leaflet-map>\n </div>\n\n <temba-dialog\n id=\"alias-dialog\"\n header=\"Aliases for ${editFeatureName}\"\n primaryButtonName=\"Save\"\n @temba-button-clicked=${this.handleDialogClick.bind(this)}\n >\n <div class=\"selected\">\n <temba-textinput\n .helpText=\"Enter other aliases for ${editFeatureName}, one per line\"\n name=\"aliases\"\n id=${editFeatureId}\n .value=${this.editFeatureAliases}\n textarea\n ></temba-textinput>\n </div>\n </temba-dialog>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AliasEditor.js","sourceRoot":"","sources":["../../../src/aliaseditor/AliasEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, TemplateResult } from 'lit';\nimport { FeatureProperties } from '../interfaces';\nimport { getUrl, postJSON, WebResponse } from '../utils';\nimport { TextInput } from '../textinput/TextInput';\nimport { styleMap } from 'lit-html/directives/style-map.js';\nimport { FormElement } from '../FormElement';\nimport { Icon } from '../vectoricon';\n\nimport { property } from 'lit/decorators.js';\n\nexport class AliasEditor extends LitElement {\n static get styles() {\n return css`\n :host {\n line-height: normal;\n }\n\n temba-textinput {\n height: 150px;\n }\n\n #left-column {\n display: inline-block;\n margin-left: 10px;\n width: 300px;\n z-index: 100;\n }\n\n .search {\n margin-bottom: 10px;\n }\n\n .feature {\n padding: 4px 14px;\n font-size: 16px;\n }\n\n .level-0 {\n margin-left: 0px;\n }\n\n .level-1 {\n margin-left: 5px;\n font-size: 95%;\n }\n\n .level-2 {\n margin-left: 10px;\n font-size: 90%;\n }\n\n .level-3 {\n margin-left: 15px;\n font-size: 85%;\n }\n\n .feature-name {\n display: inline-block;\n }\n\n .clickable {\n text-decoration: none;\n cursor: pointer;\n color: var(--color-link-primary);\n }\n\n .clickable.secondary {\n color: var(--color-link-secondary);\n }\n\n .clickable:hover {\n text-decoration: underline;\n color: var(--color-link-primary-hover);\n }\n\n .feature:hover .showonhover {\n visibility: visible;\n }\n\n .showonhover {\n visibility: hidden;\n }\n\n .aliases {\n color: #bbb;\n font-size: 80%;\n display: inline;\n margin-left: 5px;\n }\n\n temba-label {\n margin-right: 3px;\n margin-bottom: 3px;\n vertical-align: top;\n }\n\n .selected {\n display: flex;\n flex-direction: column;\n padding: 15px;\n padding-bottom: 40px;\n }\n\n .selected .name {\n font-size: 18px;\n padding: 5px;\n }\n\n .selected .help {\n padding: 5px 2px;\n font-size: 11px;\n color: var(--color-secondary-light);\n }\n\n #right-column {\n vertical-align: top;\n margin-left: 20px;\n display: inline-block;\n }\n\n leaflet-map {\n height: 250px;\n width: 450px;\n border: 0px solid #999;\n border-radius: var(--curvature);\n }\n\n .edit {\n display: inline-block;\n margin-right: 0px;\n }\n `;\n }\n\n @property({ type: Array, attribute: false })\n path: FeatureProperties[] = [];\n\n @property()\n endpoint: string;\n\n @property()\n osmId: string;\n\n @property({ type: Object })\n hovered: FeatureProperties;\n\n @property({ type: Object })\n editFeature: FeatureProperties;\n\n @property({ type: String, attribute: false })\n editFeatureAliases: string;\n\n public constructor() {\n super();\n }\n\n public updated(changedProperties: Map<string, any>) {\n if (changedProperties.has('osmId')) {\n // going up the tree doesn't require a fetch\n const newPath = [];\n for (const feature of this.path) {\n newPath.push(feature);\n if (feature.osm_id === this.osmId) {\n this.path = [...newPath];\n this.hideAliasDialog();\n return;\n }\n }\n\n this.fetchFeature();\n }\n }\n\n private fetchFeature() {\n getUrl(this.getEndpoint() + 'boundaries/' + this.osmId + '/').then(\n (response: WebResponse) => {\n this.path = response.json as FeatureProperties[];\n this.hideAliasDialog();\n }\n );\n }\n\n private handleMapClicked(feature: FeatureProperties): void {\n this.hovered = null;\n if (!feature || feature.osm_id !== this.osmId) {\n this.osmId = feature.osm_id;\n }\n }\n\n private handlePlaceClicked(feature: FeatureProperties) {\n this.osmId = feature.osm_id;\n }\n\n private handleSearchSelection(evt: CustomEvent) {\n const selection = evt.detail.selected as FeatureProperties;\n this.showAliasDialog(selection);\n const select = this.shadowRoot.querySelector('temba-select') as FormElement;\n select.clear();\n }\n\n private isMatch(option: any, query: string) {\n return `${option.name} ${option.aliases}`.toLowerCase().indexOf(query) > -1;\n }\n\n private renderFeature(\n feature: FeatureProperties,\n remainingPath: FeatureProperties[]\n ): TemplateResult {\n const selectedFeature = this.path[this.path.length - 1];\n const clickable =\n (feature.has_children || feature.level === 0) &&\n feature !== selectedFeature;\n const renderedFeature = html`\n <div class=\"feature\">\n <div\n @mouseover=${() => {\n if (feature.level > 0) {\n this.hovered = feature;\n }\n }}\n @mouseout=${() => {\n this.hovered = null;\n }}\n class=\"level-${feature.level}\"\n >\n <div\n class=\"feature-name ${clickable ? 'clickable' : ''}\"\n @click=${() => {\n if (clickable) {\n this.handlePlaceClicked(feature);\n }\n }}\n >\n ${feature.name}\n </div>\n\n <div class=\"aliases\">\n ${feature.aliases.split('\\n').map((alias: string) =>\n alias.trim().length > 0\n ? html`\n <temba-label\n class=\"alias\"\n @click=${() => {\n this.showAliasDialog(feature);\n }}\n light\n clickable\n >${alias}</temba-label\n >\n `\n : null\n )}\n ${feature.level > 0\n ? html`\n <div\n class=\"edit clickable showonhover\"\n @click=${(evt: MouseEvent) => {\n this.showAliasDialog(feature);\n evt.preventDefault();\n evt.stopPropagation();\n }}\n >\n <temba-icon name=\"${Icon.updated}\" />\n </div>\n `\n : ''}\n </div>\n </div>\n </div>\n `;\n\n const renderedChildren = (feature.children || []).map(\n (child: FeatureProperties) => {\n if (\n remainingPath.length > 0 &&\n remainingPath[0].osm_id === child.osm_id\n ) {\n return this.renderFeature(remainingPath[0], remainingPath.slice(1));\n }\n\n if (\n remainingPath.length === 0 ||\n remainingPath[0].children.length === 0\n ) {\n return this.renderFeature(child, remainingPath);\n }\n\n return null;\n }\n );\n\n return html` ${renderedFeature} ${renderedChildren} `;\n }\n\n public showAliasDialog(feature: FeatureProperties) {\n this.editFeatureAliases = feature.aliases;\n this.editFeature = feature;\n const aliasDialog = this.shadowRoot.getElementById('alias-dialog');\n if (aliasDialog) {\n aliasDialog.setAttribute('open', '');\n }\n }\n\n public hideAliasDialog() {\n const aliasDialog = this.shadowRoot.getElementById('alias-dialog');\n this.editFeature = null;\n this.editFeatureAliases = null;\n if (aliasDialog) {\n aliasDialog.removeAttribute('open');\n }\n\n this.requestUpdate();\n }\n\n private getEndpoint(): string {\n return this.endpoint + (!this.endpoint.endsWith('/') ? '/' : '');\n }\n\n private handleDialogClick(evt: CustomEvent) {\n const button = evt.detail.button;\n if (button.name === 'Save') {\n const textarea = this.shadowRoot.getElementById(\n this.editFeature.osm_id\n ) as TextInput;\n const aliases = textarea.inputElement.value;\n const payload = { osm_id: this.editFeature.osm_id, aliases };\n postJSON(\n this.getEndpoint() + 'boundaries/' + this.editFeature.osm_id + '/',\n payload\n ).then(() => {\n this.fetchFeature();\n });\n }\n\n if (button.name === 'Cancel') {\n this.hideAliasDialog();\n }\n }\n\n private getOptions(response: WebResponse) {\n return response.json.filter((option: any) => option.level > 0);\n }\n\n private getOptionsComplete(newestOptions: FeatureProperties[]) {\n return newestOptions.length === 0;\n }\n\n private renderOptionDetail(option: FeatureProperties): TemplateResult {\n const labelStyles = {\n marginTop: '3px',\n marginRight: '3px',\n };\n\n const aliasList = option.aliases.split('\\n');\n const aliases = aliasList.map((alias: string) =>\n alias.trim().length > 0\n ? html`\n <temba-label style=${styleMap(labelStyles)} class=\"alias\" dark\n >${alias}</temba-label\n >\n `\n : null\n );\n return html`\n <div class=\"path\">${option.path.replace(/>/gi, '‣')}</div>\n <div class=\"aliases\">${aliases}</div>\n `;\n }\n\n public render(): TemplateResult {\n if (this.path.length === 0) {\n return html``;\n }\n\n // if we are a leaf, have our map show the level above\n const selectedFeature = this.path[this.path.length - 1];\n const mapFeature =\n selectedFeature.children.length === 0\n ? this.path[this.path.length - 2]\n : selectedFeature;\n\n const editFeatureId = this.editFeature ? this.editFeature.osm_id : null;\n const editFeatureName = this.editFeature ? this.editFeature.name : null;\n\n return html`\n <div id=\"left-column\">\n <div class=\"search\">\n <temba-select\n placeholder=\"Search\"\n endpoint=\"${this.getEndpoint()}boundaries/${this.path[0].osm_id}/?\"\n .renderOptionDetail=${this.renderOptionDetail}\n .getOptions=${this.getOptions}\n .isComplete=${this.getOptionsComplete}\n .isMatch=${this.isMatch}\n @temba-selection=${this.handleSearchSelection.bind(this)}\n queryParam=\"q\"\n searchable\n ></temba-select>\n </div>\n <div class=\"feature-tree\">\n ${this.renderFeature(this.path[0], this.path.slice(1))}\n </div>\n </div>\n\n <div id=\"right-column\">\n <leaflet-map\n endpoint=${this.getEndpoint()}\n .feature=${mapFeature}\n .osmId=${mapFeature.osm_id}\n .hovered=${this.hovered}\n .onFeatureClicked=${this.handleMapClicked.bind(this)}\n >\n </leaflet-map>\n </div>\n\n <temba-dialog\n id=\"alias-dialog\"\n header=\"Aliases for ${editFeatureName}\"\n primaryButtonName=\"Save\"\n @temba-button-clicked=${this.handleDialogClick.bind(this)}\n >\n <div class=\"selected\">\n <temba-textinput\n .helpText=\"Enter other aliases for ${editFeatureName}, one per line\"\n name=\"aliases\"\n id=${editFeatureId}\n .value=${this.editFeatureAliases}\n textarea\n ></temba-textinput>\n </div>\n </temba-dialog>\n `;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Compose.js","sourceRoot":"","sources":["../../../src/compose/Compose.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { FormElement } from '../FormElement';\nimport { property } from 'lit/decorators.js';\nimport { Icon } from '../vectoricon';\nimport { CustomEventType } from '../interfaces';\nimport {\n formatFileSize,\n formatFileType,\n getClasses,\n postFormData,\n truncate,\n WebResponse,\n} from '../utils';\nimport { Completion } from '../completion/Completion';\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n type: string; //deprecated\n url: string;\n name: string;\n size: number;\n error: string;\n}\n\nexport class Compose extends FormElement {\n static get styles() {\n return css`\n .container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n position: relative;\n\n border-radius: var(--curvature-widget);\n background: var(--color-widget-bg);\n border: 1px solid var(--color-widget-border);\n transition: all ease-in-out var(--transition-speed);\n box-shadow: var(--widget-box-shadow);\n caret-color: var(--input-caret);\n padding: var(--temba-textinput-padding);\n }\n .container:focus-within {\n border-color: var(--color-focus);\n background: var(--color-widget-bg-focused);\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .drop-mask {\n opacity: 0;\n pointer-events: none;\n position: absolute;\n z-index: 1;\n height: 100%;\n width: 100%;\n bottom: 0;\n right: 0;\n background: rgba(210, 243, 184, 0.8);\n border-radius: var(--curvature-widget);\n margin: -0.5em;\n padding: 0.5em;\n transition: opacity ease-in-out var(--transition-speed);\n display: flex;\n align-items: center;\n text-align: center;\n }\n\n .highlight .drop-mask {\n opacity: 1;\n }\n\n .drop-mask > div {\n margin: auto;\n border-radius: var(--curvature-widget);\n font-weight: 400;\n color: rgba(0, 0, 0, 0.5);\n }\n\n .items {\n }\n\n temba-completion {\n margin-left: 0.3em;\n margin-top: 0.3em;\n --color-widget-border: none;\n --curvature-widget: none;\n --widget-box-shadow: none;\n --widget-box-shadow-focused: none;\n --temba-textinput-padding: 0;\n }\n\n .attachments {\n display: flex;\n flex-direction: column;\n }\n .attachments-list {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n }\n .attachment-item {\n background: rgba(100, 100, 100, 0.1);\n border-radius: 2px;\n margin: 0.3em;\n display: flex;\n color: var(--color-widget-text);\n }\n .attachment-item.error {\n background: rgba(250, 0, 0, 0.1);\n color: rgba(250, 0, 0, 0.75);\n }\n .remove-item {\n cursor: pointer !important;\n padding: 3px 6px;\n border-right: 1px solid rgba(100, 100, 100, 0.2);\n margin-top: 1px;\n background: rgba(100, 100, 100, 0.05);\n }\n\n .remove-item:hover {\n background: rgba(100, 100, 100, 0.1);\n }\n\n .remove-item.error:hover {\n background: rgba(250, 0, 0, 0.1);\n }\n\n .remove-item.error {\n background: rgba(250, 0, 0, 0.05);\n color: rgba(250, 0, 0, 0.75);\n }\n .attachment-name {\n align-self: center;\n font-size: 12px;\n padding: 2px 8px;\n }\n\n .actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-left: 0.25em;\n padding: 0.2em;\n }\n\n #upload-files {\n display: none;\n }\n .upload-label {\n display: flex;\n align-items: center;\n }\n .upload-icon {\n color: rgb(102, 102, 102);\n }\n .actions-right {\n display: flex;\n align-items: center;\n }\n temba-charcount {\n margin-right: 5px;\n overflow: hidden;\n --temba-charcount-counts-margin-top: 0px;\n --temba-charcount-summary-margin-top: 0px;\n --temba-charcount-summary-position: fixed;\n --temba-charcount-summary-right: 105px;\n --temba-charcount-summary-bottom: 105px;\n }\n temba-button {\n --button-y: 1px;\n --button-x: 12px;\n }\n .send-error {\n color: rgba(250, 0, 0, 0.75);\n font-size: var(--help-text-size);\n }\n `;\n }\n\n @property({ type: Boolean })\n chatbox: boolean;\n\n @property({ type: Boolean })\n attachments: boolean;\n\n @property({ type: Boolean })\n counter: boolean;\n\n @property({ type: Boolean })\n pendingDrop: boolean;\n\n @property({ type: Boolean })\n button: boolean;\n\n @property({ type: String, attribute: false })\n currentChat = '';\n\n @property({ type: String })\n accept = ''; //e.g. \".xls,.xlsx\"\n\n @property({ type: String, attribute: false })\n endpoint = '/msgmedia/upload/';\n\n @property({ type: Boolean, attribute: false })\n uploading: boolean;\n\n // values = valid and uploaded attachments\n // errorValues = invalid and not-uploaded attachments\n @property({ type: Array, attribute: false })\n errorValues: Attachment[] = [];\n\n @property({ type: String })\n buttonName = 'Send';\n\n @property({ type: Boolean, attribute: false })\n buttonDisabled = true;\n\n @property({ type: String, attribute: false })\n buttonError = '';\n\n public constructor() {\n super();\n }\n\n public updated(changes: Map<string, any>): void {\n super.updated(changes);\n\n if (\n changes.has('currentChat') ||\n changes.has('values') ||\n changes.has('buttonError')\n ) {\n this.toggleButton();\n }\n }\n\n firstUpdated(): void {\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 public reset(): void {\n this.currentChat = '';\n this.values = [];\n this.errorValues = [];\n this.buttonError = '';\n }\n\n private handleChatboxChange(evt: Event) {\n const completion = evt.target as Completion;\n const textInput = completion.textInputElement;\n this.currentChat = textInput.value;\n this.preventDefaults(evt);\n }\n\n private handleDragEnter(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragOver(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragLeave(evt: DragEvent): void {\n this.unhighlight(evt);\n }\n\n private handleDrop(evt: DragEvent): void {\n this.unhighlight(evt);\n\n const dt = evt.dataTransfer;\n if (dt) {\n const files = dt.files;\n this.uploadFiles(files);\n }\n }\n\n private preventDefaults(evt: Event): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n private highlight(evt: DragEvent): void {\n this.pendingDrop = true;\n this.preventDefaults(evt);\n }\n\n private unhighlight(evt: DragEvent): void {\n this.pendingDrop = false;\n this.preventDefaults(evt);\n }\n\n private handleAddAttachments(): void {\n this.dispatchEvent(new Event('change'));\n }\n\n private handleUploadFileChanged(evt: Event): void {\n const target = evt.target as HTMLInputElement;\n const files = target.files;\n this.uploadFiles(files);\n }\n\n public uploadFiles(files: FileList): void {\n let filesToUpload = [];\n if (this.values && this.values.length > 0) {\n //remove duplicate files that have already been uploaded\n filesToUpload = [...files].filter(file => {\n const index = this.values.findIndex(\n value => value.name === file.name && value.size === file.size\n );\n if (index === -1) {\n return file;\n }\n });\n } else {\n filesToUpload = [...files];\n }\n filesToUpload.map(fileToUpload => {\n this.uploadFile(fileToUpload);\n });\n }\n\n private uploadFile(file: File): void {\n this.uploading = true;\n\n const url = this.endpoint;\n const payload = new FormData();\n payload.append('file', file);\n postFormData(url, payload)\n .then((response: WebResponse) => {\n if (response.json.error) {\n this.addErrorValue(file, response.json.error);\n } else {\n const attachment = response.json as Attachment;\n if (attachment) {\n this.addValue(attachment);\n this.fireCustomEvent(CustomEventType.AttachmentAdded, attachment);\n }\n }\n })\n .catch((error: string) => {\n console.log(error);\n this.addErrorValue(file, error);\n })\n .finally(() => {\n this.uploading = false;\n });\n }\n\n private addErrorValue(file: File, error: string) {\n const errorValue = {\n uuid: Math.random().toString(36).slice(2, 6),\n content_type: file.type,\n type: file.type,\n name: file.name,\n url: file.name,\n size: file.size,\n error: error,\n };\n this.errorValues.push(errorValue);\n this.requestUpdate('errorValues');\n }\n public removeErrorValue(valueToRemove: any) {\n this.errorValues = this.errorValues.filter(\n (value: any) => value !== valueToRemove\n );\n this.requestUpdate('errorValues');\n }\n\n private handleRemoveAttachment(evt: Event): void {\n const target = evt.target as HTMLDivElement;\n\n const attachment = this.values.find(({ uuid }) => uuid === target.id);\n if (attachment) {\n this.removeValue(attachment);\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);\n }\n const errorAttachment = this.errorValues.find(\n ({ uuid }) => uuid === target.id\n );\n if (errorAttachment) {\n this.removeErrorValue(errorAttachment);\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);\n }\n }\n\n public toggleButton() {\n if (this.button) {\n if (this.buttonError && this.buttonError.length > 0) {\n this.buttonDisabled = true;\n } else {\n const chatboxEmpty = this.currentChat.trim().length === 0;\n const attachmentsEmpty = this.values.length === 0;\n if (this.chatbox && this.attachments) {\n this.buttonDisabled = chatboxEmpty && attachmentsEmpty;\n } else if (this.chatbox) {\n this.buttonDisabled = chatboxEmpty;\n } else if (this.attachments) {\n this.buttonDisabled = attachmentsEmpty;\n } else {\n this.buttonDisabled = true;\n }\n }\n }\n }\n\n private handleSendClick() {\n this.handleSend();\n }\n\n private handleSendEnter(evt: KeyboardEvent) {\n if (evt.key === 'Enter' && !evt.shiftKey) {\n const chat = evt.target as Completion;\n if (!chat.hasVisibleOptions()) {\n this.handleSend();\n }\n }\n }\n\n private handleSend() {\n if (!this.buttonDisabled) {\n this.buttonDisabled = true;\n const name = this.buttonName;\n this.fireCustomEvent(CustomEventType.ButtonClicked, { name });\n }\n }\n\n private handleSendBlur() {\n if (this.buttonError.length > 0) {\n this.buttonError = '';\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=${getClasses({ container: true, highlight: this.pendingDrop })}\n @dragenter=\"${this.handleDragEnter}\"\n @dragover=\"${this.handleDragOver}\"\n @dragleave=\"${this.handleDragLeave}\"\n @drop=\"${this.handleDrop}\"\n >\n <div class=\"drop-mask\"><div>Upload Attachment</div></div>\n\n ${this.chatbox\n ? html`<div class=\"items chatbox\">${this.getChatbox()}</div>`\n : null}\n ${this.attachments\n ? html`<div class=\"items attachments\">${this.getAttachments()}</div>`\n : null}\n <div class=\"items actions\">${this.getActions()}</div>\n </div>\n `;\n }\n\n private getChatbox(): TemplateResult {\n return html` <temba-completion\n value=${this.currentChat}\n gsm\n textarea\n autogrow\n @change=${this.handleChatboxChange}\n @keydown=${this.handleSendEnter}\n placeholder=\"Write something here\"\n @blur=${this.handleSendBlur}\n >\n </temba-completion>`;\n }\n\n private getAttachments(): TemplateResult {\n return html`\n ${(this.values && this.values.length > 0) ||\n (this.errorValues && this.errorValues.length > 0)\n ? html` <div class=\"attachments-list\">\n ${this.values.map(attachment => {\n return html` <div class=\"attachment-item\">\n <div\n class=\"remove-item\"\n @click=\"${this.handleRemoveAttachment}\"\n >\n <temba-icon\n id=\"${attachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${attachment.name} (${formatFileSize(\n attachment.size,\n 2\n )}) ${attachment.type}\"\n >${truncate(attachment.name, 25)}\n (${formatFileSize(attachment.size, 0)})\n ${formatFileType(attachment.type)}</span\n >\n </div>\n </div>`;\n })}\n ${this.errorValues.map(errorAttachment => {\n return html` <div class=\"attachment-item error\">\n <div\n class=\"remove-item error\"\n @click=\"${this.handleRemoveAttachment}\"\n >\n <temba-icon\n id=\"${errorAttachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${errorAttachment.name} (${formatFileSize(\n 0,\n 0\n )}) - Attachment failed - ${errorAttachment.error}\"\n >${truncate(errorAttachment.name, 25)}\n (${formatFileSize(0, 0)}) - Attachment failed</span\n >\n </div>\n </div>`;\n })}\n </div>`\n : null}\n `;\n }\n\n private getActions(): TemplateResult {\n return html`\n <div class=\"actions-left\">\n ${this.attachments ? this.getUploader() : null}\n </div>\n <div class=\"actions-center\"></div>\n <div class=\"actions-right\">\n ${this.buttonError\n ? html`<div class=\"send-error\">${this.buttonError}</div>`\n : null}\n ${this.counter ? this.getCounter() : null}\n ${this.button ? this.getButton() : null}\n </div>\n `;\n }\n\n private getUploader(): TemplateResult {\n if (this.uploading) {\n return html`<temba-loading units=\"3\" size=\"12\"></temba-loading>`;\n } else {\n return html` <input\n type=\"file\"\n id=\"upload-files\"\n multiple\n accept=\"${this.accept}\"\n @change=\"${this.handleUploadFileChanged}\"\n />\n <label class=\"actions-left upload-label\" for=\"upload-files\">\n <temba-icon\n class=\"upload-icon\"\n name=\"${Icon.attachment}\"\n @click=\"${this.handleAddAttachments}\"\n clickable\n ></temba-icon>\n </label>`;\n }\n }\n\n private getCounter(): TemplateResult {\n return html`<temba-charcount text=\"${this.currentChat}\"></temba-charcount>`;\n }\n\n private getButton(): TemplateResult {\n return html` <temba-button\n id=\"send-button\"\n name=${this.buttonName}\n @click=${this.handleSendClick}\n ?disabled=${this.buttonDisabled}\n @blur=${this.handleSendBlur}\n ></temba-button>`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Compose.js","sourceRoot":"","sources":["../../../src/compose/Compose.ts"],"names":[],"mappings":";AAAA,OAAO,EAAkB,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,cAAc,EACd,cAAc,EACd,UAAU,EACV,YAAY,EACZ,QAAQ,GAET,MAAM,UAAU,CAAC;AAalB,MAAM,OAAO,OAAQ,SAAQ,WAAW;IACtC,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqJT,CAAC;IACJ,CAAC;IA2CD;QACE,KAAK,EAAE,CAAC;QA1BV,gBAAW,GAAG,EAAE,CAAC;QAGjB,WAAM,GAAG,EAAE,CAAC,CAAC,mBAAmB;QAGhC,aAAQ,GAAG,mBAAmB,CAAC;QAK/B,0CAA0C;QAC1C,qDAAqD;QAErD,gBAAW,GAAiB,EAAE,CAAC;QAG/B,eAAU,GAAG,MAAM,CAAC;QAGpB,mBAAc,GAAG,IAAI,CAAC;QAGtB,gBAAW,GAAG,EAAE,CAAC;IAIjB,CAAC;IAEM,OAAO,CAAC,OAAyB;QACtC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvB,IACE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAC1B;YACA,IAAI,CAAC,YAAY,EAAE,CAAC;SACrB;IACH,CAAC;IAED,YAAY;QACV,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAC9C,kBAAkB,CACL,CAAC;QAChB,IAAI,UAAU,EAAE;YACd,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBACrB,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC,EAAE,CAAC,CAAC,CAAC;SACP;IACH,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,CAAC;IAEO,mBAAmB,CAAC,GAAU;QACpC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAoB,CAAC;QAC5C,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEO,eAAe,CAAC,GAAc;QACpC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAEO,cAAc,CAAC,GAAc;QACnC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAEO,eAAe,CAAC,GAAc;QACpC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAEO,UAAU,CAAC,GAAc;QAC/B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAEtB,MAAM,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC;QAC5B,IAAI,EAAE,EAAE;YACN,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;YACvB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;SACzB;IACH,CAAC;IAEO,eAAe,CAAC,GAAU;QAChC,GAAG,CAAC,cAAc,EAAE,CAAC;QACrB,GAAG,CAAC,eAAe,EAAE,CAAC;IACxB,CAAC;IAEO,SAAS,CAAC,GAAc;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEO,WAAW,CAAC,GAAc;QAChC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1C,CAAC;IAEO,uBAAuB,CAAC,GAAU;QACxC,MAAM,MAAM,GAAG,GAAG,CAAC,MAA0B,CAAC;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEM,WAAW,CAAC,KAAe;QAChC,IAAI,aAAa,GAAG,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACzC,wDAAwD;YACxD,aAAa,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CACjC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAC9D,CAAC;gBACF,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;oBAChB,OAAO,IAAI,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;SACJ;aAAM;YACL,aAAa,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;SAC5B;QACD,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;YAC/B,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,IAAU;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7B,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC;aACvB,IAAI,CAAC,CAAC,QAAqB,EAAE,EAAE;YAC9B,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE;gBACvB,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;aAC/C;iBAAM;gBACL,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAkB,CAAC;gBAC/C,IAAI,UAAU,EAAE;oBACd,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;oBAC1B,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;iBACnE;aACF;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAa,EAAE,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,aAAa,CAAC,IAAU,EAAE,KAAa;QAC7C,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5C,YAAY,EAAE,IAAI,CAAC,IAAI;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,EAAE,IAAI,CAAC,IAAI;YACd,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,KAAK;SACb,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC;IACM,gBAAgB,CAAC,aAAkB;QACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CACxC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,KAAK,aAAa,CACxC,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC;IAEO,sBAAsB,CAAC,GAAU;QACvC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAwB,CAAC;QAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC;SACrE;QACD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAC3C,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CACjC,CAAC;QACF,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;YACvC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC;SACrE;IACH,CAAC;IAEM,YAAY;QACjB,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;gBACnD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;aAC5B;iBAAM;gBACL,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;gBAC1D,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;gBAClD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE;oBACpC,IAAI,CAAC,cAAc,GAAG,YAAY,IAAI,gBAAgB,CAAC;iBACxD;qBAAM,IAAI,IAAI,CAAC,OAAO,EAAE;oBACvB,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;iBACpC;qBAAM,IAAI,IAAI,CAAC,WAAW,EAAE;oBAC3B,IAAI,CAAC,cAAc,GAAG,gBAAgB,CAAC;iBACxC;qBAAM;oBACL,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;iBAC5B;aACF;SACF;IACH,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAEO,eAAe,CAAC,GAAkB;QACxC,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE;YACxC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAoB,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE;gBAC7B,IAAI,CAAC,UAAU,EAAE,CAAC;aACnB;YACD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;SAC3B;IACH,CAAC;IAEO,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;SAC/D;IACH,CAAC;IAEO,cAAc;QACpB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YAC/B,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;SACvB;IACH,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;;gBAEC,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;sBACtD,IAAI,CAAC,eAAe;qBACrB,IAAI,CAAC,cAAc;sBAClB,IAAI,CAAC,eAAe;iBACzB,IAAI,CAAC,UAAU;;;;UAItB,IAAI,CAAC,OAAO;YACZ,CAAC,CAAC,IAAI,CAAA,8BAA8B,IAAI,CAAC,UAAU,EAAE,QAAQ;YAC7D,CAAC,CAAC,IAAI;UACN,IAAI,CAAC,WAAW;YAChB,CAAC,CAAC,IAAI,CAAA,kCAAkC,IAAI,CAAC,cAAc,EAAE,QAAQ;YACrE,CAAC,CAAC,IAAI;qCACqB,IAAI,CAAC,UAAU,EAAE;;KAEjD,CAAC;IACJ,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAA;cACD,IAAI,CAAC,WAAW;;;;gBAId,IAAI,CAAC,mBAAmB;iBACvB,IAAI,CAAC,eAAe;;cAEvB,IAAI,CAAC,cAAc;;wBAET,CAAC;IACvB,CAAC;IAEO,cAAc;QACpB,OAAO,IAAI,CAAA;QACP,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YACzC,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;YAC/C,CAAC,CAAC,IAAI,CAAA;cACA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;gBAC7B,OAAO,IAAI,CAAA;;;4BAGG,IAAI,CAAC,sBAAsB;;;0BAG7B,UAAU,CAAC,IAAI;4BACb,IAAI,CAAC,YAAY;;;;;6BAKhB,UAAU,CAAC,IAAI,KAAK,cAAc,CACzC,UAAU,CAAC,IAAI,EACf,CAAC,CACF,KAAK,UAAU,CAAC,IAAI;uBAClB,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;uBAC7B,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;sBACnC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC;;;qBAGhC,CAAC;YACV,CAAC,CAAC;cACA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE;gBACvC,OAAO,IAAI,CAAA;;;4BAGG,IAAI,CAAC,sBAAsB;;;0BAG7B,eAAe,CAAC,IAAI;4BAClB,IAAI,CAAC,YAAY;;;;;6BAKhB,eAAe,CAAC,IAAI,KAAK,cAAc,CAC9C,CAAC,EACD,CAAC,CACF,2BAA2B,eAAe,CAAC,KAAK;uBAC9C,QAAQ,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC;uBAClC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;;;qBAGtB,CAAC;YACV,CAAC,CAAC;iBACG;YACT,CAAC,CAAC,IAAI;KACT,CAAC;IACJ,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;;;;UAI5C,IAAI,CAAC,WAAW;YAChB,CAAC,CAAC,IAAI,CAAA,2BAA2B,IAAI,CAAC,WAAW,QAAQ;YACzD,CAAC,CAAC,IAAI;UACN,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI;UACvC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI;;KAE1C,CAAC;IACJ,CAAC;IAEO,WAAW;QACjB,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,OAAO,IAAI,CAAA,qDAAqD,CAAC;SAClE;aAAM;YACL,OAAO,IAAI,CAAA;;;;oBAIG,IAAI,CAAC,MAAM;qBACV,IAAI,CAAC,uBAAuB;;;;;oBAK7B,IAAI,CAAC,UAAU;sBACb,IAAI,CAAC,oBAAoB;;;iBAG9B,CAAC;SACb;IACH,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAA,0BAA0B,IAAI,CAAC,WAAW,sBAAsB,CAAC;IAC9E,CAAC;IAEO,SAAS;QACf,OAAO,IAAI,CAAA;;aAEF,IAAI,CAAC,UAAU;eACb,IAAI,CAAC,eAAe;kBACjB,IAAI,CAAC,cAAc;cACvB,IAAI,CAAC,cAAc;qBACZ,CAAC;IACpB,CAAC;CACF;AApZC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;wCACX;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CACP;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;wCACX;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CACP;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;uCACZ;AAGhB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4CAC5B;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCACf;AAGZ;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;yCACd;AAG/B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0CAC3B;AAKnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4CACb;AAG/B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACP;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;+CACxB;AAGtB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4CAC5B","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { FormElement } from '../FormElement';\nimport { property } from 'lit/decorators.js';\nimport { Icon } from '../vectoricon';\nimport { CustomEventType } from '../interfaces';\nimport {\n formatFileSize,\n formatFileType,\n getClasses,\n postFormData,\n truncate,\n WebResponse,\n} from '../utils';\nimport { Completion } from '../completion/Completion';\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n type: string; //deprecated\n url: string;\n name: string;\n size: number;\n error: string;\n}\n\nexport class Compose extends FormElement {\n static get styles() {\n return css`\n .container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n position: relative;\n\n border-radius: var(--curvature-widget);\n background: var(--color-widget-bg);\n border: 1px solid var(--color-widget-border);\n transition: all ease-in-out var(--transition-speed);\n box-shadow: var(--widget-box-shadow);\n caret-color: var(--input-caret);\n padding: var(--temba-textinput-padding);\n }\n .container:focus-within {\n border-color: var(--color-focus);\n background: var(--color-widget-bg-focused);\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .drop-mask {\n opacity: 0;\n pointer-events: none;\n position: absolute;\n z-index: 1;\n height: 100%;\n width: 100%;\n bottom: 0;\n right: 0;\n background: rgba(210, 243, 184, 0.8);\n border-radius: var(--curvature-widget);\n margin: -0.5em;\n padding: 0.5em;\n transition: opacity ease-in-out var(--transition-speed);\n display: flex;\n align-items: center;\n text-align: center;\n }\n\n .highlight .drop-mask {\n opacity: 1;\n }\n\n .drop-mask > div {\n margin: auto;\n border-radius: var(--curvature-widget);\n font-weight: 400;\n color: rgba(0, 0, 0, 0.5);\n }\n\n .items {\n }\n\n temba-completion {\n margin-left: 0.3em;\n margin-top: 0.3em;\n --color-widget-border: none;\n --curvature-widget: none;\n --widget-box-shadow: none;\n --widget-box-shadow-focused: none;\n --temba-textinput-padding: 0;\n }\n\n .attachments {\n display: flex;\n flex-direction: column;\n }\n .attachments-list {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n }\n .attachment-item {\n background: rgba(100, 100, 100, 0.1);\n border-radius: 2px;\n margin: 0.3em;\n display: flex;\n color: var(--color-widget-text);\n }\n .attachment-item.error {\n background: rgba(250, 0, 0, 0.1);\n color: rgba(250, 0, 0, 0.75);\n }\n .remove-item {\n cursor: pointer !important;\n padding: 3px 6px;\n border-right: 1px solid rgba(100, 100, 100, 0.2);\n margin-top: 1px;\n background: rgba(100, 100, 100, 0.05);\n }\n\n .remove-item:hover {\n background: rgba(100, 100, 100, 0.1);\n }\n\n .remove-item.error:hover {\n background: rgba(250, 0, 0, 0.1);\n }\n\n .remove-item.error {\n background: rgba(250, 0, 0, 0.05);\n color: rgba(250, 0, 0, 0.75);\n }\n .attachment-name {\n align-self: center;\n font-size: 12px;\n padding: 2px 8px;\n }\n\n .actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-left: 0.25em;\n padding: 0.2em;\n }\n\n #upload-files {\n display: none;\n }\n .upload-label {\n display: flex;\n align-items: center;\n }\n .upload-icon {\n color: rgb(102, 102, 102);\n }\n .actions-right {\n display: flex;\n align-items: center;\n }\n temba-charcount {\n margin-right: 5px;\n overflow: hidden;\n --temba-charcount-counts-margin-top: 0px;\n --temba-charcount-summary-margin-top: 0px;\n --temba-charcount-summary-position: fixed;\n --temba-charcount-summary-right: 105px;\n --temba-charcount-summary-bottom: 105px;\n }\n temba-button {\n --button-y: 1px;\n --button-x: 12px;\n }\n .send-error {\n color: rgba(250, 0, 0, 0.75);\n font-size: var(--help-text-size);\n }\n `;\n }\n\n @property({ type: Boolean })\n chatbox: boolean;\n\n @property({ type: Boolean })\n attachments: boolean;\n\n @property({ type: Boolean })\n counter: boolean;\n\n @property({ type: Boolean })\n pendingDrop: boolean;\n\n @property({ type: Boolean })\n button: boolean;\n\n @property({ type: String, attribute: false })\n currentChat = '';\n\n @property({ type: String })\n accept = ''; //e.g. \".xls,.xlsx\"\n\n @property({ type: String, attribute: false })\n endpoint = '/msgmedia/upload/';\n\n @property({ type: Boolean, attribute: false })\n uploading: boolean;\n\n // values = valid and uploaded attachments\n // errorValues = invalid and not-uploaded attachments\n @property({ type: Array, attribute: false })\n errorValues: Attachment[] = [];\n\n @property({ type: String })\n buttonName = 'Send';\n\n @property({ type: Boolean, attribute: false })\n buttonDisabled = true;\n\n @property({ type: String, attribute: false })\n buttonError = '';\n\n public constructor() {\n super();\n }\n\n public updated(changes: Map<string, any>): void {\n super.updated(changes);\n\n if (\n changes.has('currentChat') ||\n changes.has('values') ||\n changes.has('buttonError')\n ) {\n this.toggleButton();\n }\n }\n\n firstUpdated(): void {\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 public reset(): void {\n this.currentChat = '';\n this.values = [];\n this.errorValues = [];\n this.buttonError = '';\n }\n\n private handleChatboxChange(evt: Event) {\n const completion = evt.target as Completion;\n const textInput = completion.textInputElement;\n this.currentChat = textInput.value;\n this.preventDefaults(evt);\n }\n\n private handleDragEnter(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragOver(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragLeave(evt: DragEvent): void {\n this.unhighlight(evt);\n }\n\n private handleDrop(evt: DragEvent): void {\n this.unhighlight(evt);\n\n const dt = evt.dataTransfer;\n if (dt) {\n const files = dt.files;\n this.uploadFiles(files);\n }\n }\n\n private preventDefaults(evt: Event): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n private highlight(evt: DragEvent): void {\n this.pendingDrop = true;\n this.preventDefaults(evt);\n }\n\n private unhighlight(evt: DragEvent): void {\n this.pendingDrop = false;\n this.preventDefaults(evt);\n }\n\n private handleAddAttachments(): void {\n this.dispatchEvent(new Event('change'));\n }\n\n private handleUploadFileChanged(evt: Event): void {\n const target = evt.target as HTMLInputElement;\n const files = target.files;\n this.uploadFiles(files);\n }\n\n public uploadFiles(files: FileList): void {\n let filesToUpload = [];\n if (this.values && this.values.length > 0) {\n //remove duplicate files that have already been uploaded\n filesToUpload = [...files].filter(file => {\n const index = this.values.findIndex(\n value => value.name === file.name && value.size === file.size\n );\n if (index === -1) {\n return file;\n }\n });\n } else {\n filesToUpload = [...files];\n }\n filesToUpload.map(fileToUpload => {\n this.uploadFile(fileToUpload);\n });\n }\n\n private uploadFile(file: File): void {\n this.uploading = true;\n\n const url = this.endpoint;\n const payload = new FormData();\n payload.append('file', file);\n postFormData(url, payload)\n .then((response: WebResponse) => {\n if (response.json.error) {\n this.addErrorValue(file, response.json.error);\n } else {\n const attachment = response.json as Attachment;\n if (attachment) {\n this.addValue(attachment);\n this.fireCustomEvent(CustomEventType.AttachmentAdded, attachment);\n }\n }\n })\n .catch((error: string) => {\n console.log(error);\n this.addErrorValue(file, error);\n })\n .finally(() => {\n this.uploading = false;\n });\n }\n\n private addErrorValue(file: File, error: string) {\n const errorValue = {\n uuid: Math.random().toString(36).slice(2, 6),\n content_type: file.type,\n type: file.type,\n name: file.name,\n url: file.name,\n size: file.size,\n error: error,\n };\n this.errorValues.push(errorValue);\n this.requestUpdate('errorValues');\n }\n public removeErrorValue(valueToRemove: any) {\n this.errorValues = this.errorValues.filter(\n (value: any) => value !== valueToRemove\n );\n this.requestUpdate('errorValues');\n }\n\n private handleRemoveAttachment(evt: Event): void {\n const target = evt.target as HTMLDivElement;\n\n const attachment = this.values.find(({ uuid }) => uuid === target.id);\n if (attachment) {\n this.removeValue(attachment);\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);\n }\n const errorAttachment = this.errorValues.find(\n ({ uuid }) => uuid === target.id\n );\n if (errorAttachment) {\n this.removeErrorValue(errorAttachment);\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);\n }\n }\n\n public toggleButton() {\n if (this.button) {\n if (this.buttonError && this.buttonError.length > 0) {\n this.buttonDisabled = true;\n } else {\n const chatboxEmpty = this.currentChat.trim().length === 0;\n const attachmentsEmpty = this.values.length === 0;\n if (this.chatbox && this.attachments) {\n this.buttonDisabled = chatboxEmpty && attachmentsEmpty;\n } else if (this.chatbox) {\n this.buttonDisabled = chatboxEmpty;\n } else if (this.attachments) {\n this.buttonDisabled = attachmentsEmpty;\n } else {\n this.buttonDisabled = true;\n }\n }\n }\n }\n\n private handleSendClick() {\n this.handleSend();\n }\n\n private handleSendEnter(evt: KeyboardEvent) {\n if (evt.key === 'Enter' && !evt.shiftKey) {\n const chat = evt.target as Completion;\n if (!chat.hasVisibleOptions()) {\n this.handleSend();\n }\n this.preventDefaults(evt);\n }\n }\n\n private handleSend() {\n if (!this.buttonDisabled) {\n this.buttonDisabled = true;\n const name = this.buttonName;\n this.fireCustomEvent(CustomEventType.ButtonClicked, { name });\n }\n }\n\n private handleSendBlur() {\n if (this.buttonError.length > 0) {\n this.buttonError = '';\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=${getClasses({ container: true, highlight: this.pendingDrop })}\n @dragenter=\"${this.handleDragEnter}\"\n @dragover=\"${this.handleDragOver}\"\n @dragleave=\"${this.handleDragLeave}\"\n @drop=\"${this.handleDrop}\"\n >\n <div class=\"drop-mask\"><div>Upload Attachment</div></div>\n\n ${this.chatbox\n ? html`<div class=\"items chatbox\">${this.getChatbox()}</div>`\n : null}\n ${this.attachments\n ? html`<div class=\"items attachments\">${this.getAttachments()}</div>`\n : null}\n <div class=\"items actions\">${this.getActions()}</div>\n </div>\n `;\n }\n\n private getChatbox(): TemplateResult {\n return html` <temba-completion\n value=${this.currentChat}\n gsm\n textarea\n autogrow\n @change=${this.handleChatboxChange}\n @keydown=${this.handleSendEnter}\n placeholder=\"Write something here\"\n @blur=${this.handleSendBlur}\n >\n </temba-completion>`;\n }\n\n private getAttachments(): TemplateResult {\n return html`\n ${(this.values && this.values.length > 0) ||\n (this.errorValues && this.errorValues.length > 0)\n ? html` <div class=\"attachments-list\">\n ${this.values.map(attachment => {\n return html` <div class=\"attachment-item\">\n <div\n class=\"remove-item\"\n @click=\"${this.handleRemoveAttachment}\"\n >\n <temba-icon\n id=\"${attachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${attachment.name} (${formatFileSize(\n attachment.size,\n 2\n )}) ${attachment.type}\"\n >${truncate(attachment.name, 25)}\n (${formatFileSize(attachment.size, 0)})\n ${formatFileType(attachment.type)}</span\n >\n </div>\n </div>`;\n })}\n ${this.errorValues.map(errorAttachment => {\n return html` <div class=\"attachment-item error\">\n <div\n class=\"remove-item error\"\n @click=\"${this.handleRemoveAttachment}\"\n >\n <temba-icon\n id=\"${errorAttachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${errorAttachment.name} (${formatFileSize(\n 0,\n 0\n )}) - Attachment failed - ${errorAttachment.error}\"\n >${truncate(errorAttachment.name, 25)}\n (${formatFileSize(0, 0)}) - Attachment failed</span\n >\n </div>\n </div>`;\n })}\n </div>`\n : null}\n `;\n }\n\n private getActions(): TemplateResult {\n return html`\n <div class=\"actions-left\">\n ${this.attachments ? this.getUploader() : null}\n </div>\n <div class=\"actions-center\"></div>\n <div class=\"actions-right\">\n ${this.buttonError\n ? html`<div class=\"send-error\">${this.buttonError}</div>`\n : null}\n ${this.counter ? this.getCounter() : null}\n ${this.button ? this.getButton() : null}\n </div>\n `;\n }\n\n private getUploader(): TemplateResult {\n if (this.uploading) {\n return html`<temba-loading units=\"3\" size=\"12\"></temba-loading>`;\n } else {\n return html` <input\n type=\"file\"\n id=\"upload-files\"\n multiple\n accept=\"${this.accept}\"\n @change=\"${this.handleUploadFileChanged}\"\n />\n <label class=\"actions-left upload-label\" for=\"upload-files\">\n <temba-icon\n class=\"upload-icon\"\n name=\"${Icon.attachment}\"\n @click=\"${this.handleAddAttachments}\"\n clickable\n ></temba-icon>\n </label>`;\n }\n }\n\n private getCounter(): TemplateResult {\n return html`<temba-charcount text=\"${this.currentChat}\"></temba-charcount>`;\n }\n\n private getButton(): TemplateResult {\n return html` <temba-button\n id=\"send-button\"\n name=${this.buttonName}\n @click=${this.handleSendClick}\n ?disabled=${this.buttonDisabled}\n @blur=${this.handleSendBlur}\n ></temba-button>`;\n }\n}\n"]}
|
|
@@ -235,8 +235,7 @@ export class ContactChat extends ContactStoreElement {
|
|
|
235
235
|
}
|
|
236
236
|
const attachments = compose.values.map(attachment => {
|
|
237
237
|
const content_type = attachment.content_type;
|
|
238
|
-
|
|
239
|
-
return content_type + ':' + url;
|
|
238
|
+
return content_type + ':' + attachment.url;
|
|
240
239
|
});
|
|
241
240
|
if (attachments.length > 0) {
|
|
242
241
|
payload['attachments'] = attachments;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactChat.js","sourceRoot":"","sources":["../../../src/contacts/ContactChat.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAW,eAAe,EAAU,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,MAAM,OAAO,WAAY,SAAQ,mBAAmB;IAC3C,MAAM,KAAK,MAAM;QACtB,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiJT,CAAC;IACJ,CAAC;IAmCD;QACE,KAAK,EAAE,CAAC;QA9BV,qBAAgB,GAAG,uBAAuB,CAAC;QAG3C,gBAAW,GAAG,EAAE,CAAC;QAGjB,gBAAW,GAAG,EAAE,CAAC;QAGjB,gBAAW,GAAG,IAAI,CAAC;QAGnB,YAAO,GAAG,KAAK,CAAC;QAGhB,YAAO,GAAG,KAAK,CAAC;QAGhB,kBAAa,GAAW,IAAI,CAAC;QAG7B,mBAAc,GAAY,IAAI,CAAC;QAG/B,UAAK,GAAG,EAAE,CAAC;QAUX,oBAAe,GAAG,IAAI,CAAC;QAHrB,IAAI,CAAC,WAAW,GAAG,gBAAgB,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;IACvE,CAAC;IAIM,iBAAiB;QACtB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;gBACtC,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;oBACtD,OAAO;iBACR;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC,EAAE,eAAe,CAAC,CAAC;SACrB;IACH,CAAC;IAEM,oBAAoB;QACzB,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;SACrC;IACH,CAAC;IAEM,iBAAiB;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAClC,uBAAuB,CACN,CAAC;IACtB,CAAC;IAEM,OAAO,CAAC,cAAc,GAAG,KAAK;QACnC,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,IAAI,cAAc,EAAE;YAClB,IAAI,cAAc,EAAE;gBAClB,cAAc,CAAC,cAAc,EAAE,CAAC;aACjC;YACD,cAAc,CAAC,OAAO,EAAE,CAAC;SAC1B;IACH,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAEjC,yCAAyC;QACzC,IACE,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC;YAC7B,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EACvC;YACA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC;SACjC;IACH,CAAC;IAEO,kBAAkB;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QACrC,QAAQ,CAAC,6BAA6B,EAAE;YACtC,OAAO,EAAE,CAAC,IAAI,CAAC;YACf,MAAM,EAAE,QAAQ;SACjB,CAAC;aACC,IAAI,CAAC,GAAG,EAAE;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,cAAc,EAAE;gBACnD,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE;aACjC,CAAC,CAAC;QACL,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,QAAa,EAAE,EAAE;YACvB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,UAAU,CAAC,GAAgB;QACjC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QACnC,IAAI,UAAU,KAAK,MAAM,EAAE;YACzB,MAAM,OAAO,GAAG;gBACd,QAAQ,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;aACrC,CAAC;YACF,MAAM,OAAO,GAAG,GAAG,CAAC,aAAwB,CAAC;YAC7C,IAAI,OAAO,EAAE;gBACX,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC;gBACjC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;oBACnB,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;iBACxB;gBACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;oBAClD,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;oBAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;oBAC3D,OAAO,YAAY,GAAG,GAAG,GAAG,GAAG,CAAC;gBAClC,CAAC,CAAC,CAAC;gBACH,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC1B,OAAO,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC;iBACtC;aACF;YACD,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;aAC7C;YAED,MAAM,YAAY,GAAG,UAAU,GAAG,4BAA4B,CAAC;YAE/D,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAC;iBACzC,IAAI,CAAC,QAAQ,CAAC,EAAE;gBACf,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE;oBACzB,OAAO,CAAC,KAAK,EAAE,CAAC;oBAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iBACpB;qBAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE;oBAChC,IACE,QAAQ,CAAC,IAAI,CAAC,IAAI;wBAClB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;wBACtB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EACjC;wBACA,OAAO,CAAC,WAAW;4BACjB,6CAA6C,CAAC;qBACjD;yBAAM,IACL,QAAQ,CAAC,IAAI,CAAC,WAAW;wBACzB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG;wBAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EACxC;wBACA,OAAO,CAAC,WAAW;4BACjB,8CAA8C,CAAC;qBAClD;yBAAM;wBACL,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC;qBACpC;iBACF;qBAAM;oBACL,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC;iBACpC;YACH,CAAC,CAAC;iBACD,KAAK,CAAC,KAAK,CAAC,EAAE;gBACb,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACrB,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC;YACrC,CAAC,CAAC,CAAC;SACN;IACH,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,iBAAiB,EAAE,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;QACrC,SAAS,CAAC,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/D,CAAC;IAEM,MAAM;QACX,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc;YACxC,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE;YAC/B,CAAC,CAAC,IAAI,CAAC;QACT,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAEpE,MAAM,wBAAwB,GAAG,IAAI,CAAA;;0BAEf,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;;kCAEtB,cAAc,IAAI,OAAO;WAChD,CAAC;QAER,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc;gBACxC,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE;gBAC/B,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc;gBAC9C,CAAC,CAAC,IAAI,CAAC,wBAAwB,EAAE;gBACjC,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,+BAA+B,GACnC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,aAAa;gBACvC,CAAC,CAAC,IAAI,CAAC,kCAAkC,EAAE;gBAC3C,CAAC,CAAC,IAAI,CAAC;YACX,MAAM,kCAAkC,GAAG,IAAI,CAAC,aAAa;gBAC3D,CAAC,CAAC,IAAI,CAAC,qCAAqC,EAAE;gBAC9C,CAAC,CAAC,IAAI,CAAC;YAET,MAAM,wBAAwB,GAAG,IAAI,CAAA,GAAG,cAAc;8BAC9B,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;YAClD,oBAAoB,IAAI,+BAA+B;;UAEzD,kCAAkC,EAAE,CAAC;YAEzC,OAAO,IAAI,CAAA,GAAG,wBAAwB,IAAI,wBAAwB,EAAE,CAAC;SACtE;QAED,OAAO,IAAI,CAAA,GAAG,wBAAwB,EAAE,CAAC;IAC3C,CAAC;IAEO,sBAAsB;QAC5B,OAAO,IAAI,CAAA;cACD,IAAI,CAAC,cAAc,CAAC,IAAI;iBACrB,IAAI,CAAC,cAAc;gBACpB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;iBAClD,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;eAC1D,IAAI,CAAC,KAAK;;6BAEI,CAAC;IAC5B,CAAC;IAEO,eAAe;QACrB,IAAI,IAAI,CAAC,aAAa,EAAE;YACtB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,QAAQ,EAAE;gBAClE,uDAAuD;gBACvD,OAAO,IAAI,CAAC;aACb;iBAAM;gBACL,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;oBAChC,wDAAwD;oBACxD,OAAO,IAAI,CAAA;;;;uBAIE,IAAI,CAAC,kBAAkB;;iBAE7B,CAAC;iBACT;qBAAM;oBACL,iDAAiD;oBACjD,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;iBAC1B;aACF;SACF;QAED,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,QAAQ,EAAE;YAClE,uDAAuD;YACvD,OAAO,IAAI,CAAC;SACb;aAAM;YACL,6BAA6B;YAC7B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;SAC1B;IACH,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAA,wBAAwB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;gCAMjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;;WAG/C,CAAC;IACV,CAAC;IAEO,sBAAsB;QAC5B,OAAO,IAAI,CAAA;;eAEA,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;;iBAE9B,IAAI,CAAC,WAAW;gBACjB,IAAI,CAAC,aAAa;iBACjB,IAAI,CAAC,cAAc;;6BAEP,CAAC;IAC5B,CAAC;IAEO,wBAAwB;QAC9B,OAAO,IAAI,CAAA;;cAED,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc;;;;;;gBAMhD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa;kBACnD,IAAI,CAAC,kBAAkB;;;;iBAIxB,CAAC;IAChB,CAAC;IAEO,kCAAkC;QACxC,OAAO,IAAI,CAAA;;;;;;;kBAOG,IAAI,CAAC,KAAK;oBACR,GAAG,EAAE;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,CAC1C,eAAe,CACP,CAAC;YACX,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QACpB,CAAC;;;;;;;kBAOO,IAAI,CAAC,QAAQ;oBACX,GAAG,EAAE;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,aAAa,CAAU,CAAC;YACpE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;;;mBAGQ,CAAC;IAClB,CAAC;IAEO,qCAAqC;QAC3C,OAAO,IAAI,CAAA;;;2BAGY,IAAI,CAAC,OAAO;iCACN,IAAI,CAAC,aAAa,CAAC,IAAI;;;;;;2BAM7B,IAAI,CAAC,oBAAoB;mCACjB,IAAI,CAAC,aAAa,CAAC,IAAI;;qBAErC,CAAC;IACpB,CAAC;CACF;AAxVC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;+CAC7B;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qDACgB;AAG3C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDACV;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDACV;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gDACT;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CACZ;AAGhB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CACZ;AAGhB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDACE;AAG7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;mDACI;AAG/B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CAChB","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Contact, CustomEventType, Ticket } from '../interfaces';\nimport { COOKIE_KEYS, getCookieBoolean, postJSON, setCookie } from '../utils';\nimport { ContactHistory } from './ContactHistory';\nimport { Modax } from '../dialog/Modax';\nimport { ContactStoreElement } from './ContactStoreElement';\nimport { Icon } from '../vectoricon';\nimport { Compose } from '../compose/Compose';\n\nconst DEFAULT_REFRESH = 10000;\n\nexport class ContactChat extends ContactStoreElement {\n public static get styles() {\n return css`\n .left-pane {\n box-shadow: -13px 10px 7px 14px rgba(0, 0, 0, 0);\n transition: box-shadow 600ms linear;\n }\n\n .left-pane.open {\n z-index: 1000;\n }\n\n :host {\n flex-grow: 1;\n display: flex;\n flex-direction: row;\n min-height: 0;\n border-radius: var(--curvature);\n }\n\n .chat-wrapper {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n }\n\n temba-contact-history {\n border-bottom: 3px solid #e1e1e1;\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n }\n\n .chatbox {\n background: rgb(242, 242, 242);\n padding: 1em;\n display: flex;\n flex-direction: column;\n z-index: 3;\n border-bottom-left-radius: var(--curvature);\n border-bottom-right-radius: var(--curvature);\n }\n\n .chatbox.full {\n border-bottom-right-radius: 0 !important;\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 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#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 }\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 temba-completion {\n --widget-box-shadow: none;\n --color-widget-border: transparent;\n --widget-box-shadow-focused: none;\n --color-focus: transparent;\n --color-widget-bg-focused: transparent;\n }\n `;\n }\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 toolbar = false;\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: String })\n agent = '';\n\n // http promise to monitor for completeness\n public httpComplete: Promise<void>;\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 we don't have an endpoint infer one\n if (\n changedProperties.has('data') ||\n changedProperties.has('currentContact')\n ) {\n this.currentContact = this.data;\n }\n }\n\n private handleTicketReopen() {\n const uuid = this.currentTicket.uuid;\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'reopen',\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(evt: CustomEvent) {\n const buttonName = evt.detail.name;\n if (buttonName === 'Send') {\n const payload = {\n contacts: [this.currentContact.uuid],\n };\n const compose = evt.currentTarget as Compose;\n if (compose) {\n const text = compose.currentChat;\n if (text.length > 0) {\n payload['text'] = text;\n }\n const attachments = compose.values.map(attachment => {\n const content_type = attachment.content_type;\n const url = new URL(attachment.url, document.baseURI).href;\n return content_type + ':' + url;\n });\n if (attachments.length > 0) {\n payload['attachments'] = attachments;\n }\n }\n if (this.currentTicket) {\n payload['ticket'] = this.currentTicket.uuid;\n }\n\n const genericError = buttonName + ' failed, please try again.';\n\n postJSON(`/api/v2/broadcasts.json`, payload)\n .then(response => {\n if (response.status < 400) {\n compose.reset();\n this.refresh(true);\n } else if (response.status < 500) {\n if (\n response.json.text &&\n response.json.text.eng &&\n response.json.text.eng.length > 0\n ) {\n compose.buttonError =\n 'Text must have no more than 640 characters.';\n } else if (\n response.json.attachments &&\n response.json.attachments.eng &&\n response.json.attachments.eng.length > 0\n ) {\n compose.buttonError =\n 'Attachments must have no more than 10 files.';\n } else {\n compose.buttonError = genericError;\n }\n } else {\n compose.buttonError = genericError;\n }\n })\n .catch(error => {\n console.error(error);\n compose.buttonError = genericError;\n });\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 const contactHistory = this.currentContact\n ? this.getTembaContactHistory()\n : null;\n const chatbox = this.currentContact ? this.getTembaChatbox() : null;\n\n const contactHistoryAndChatbox = html`<div\n style=\"flex-grow: 1; margin-right: 0em; display:flex; flex-direction:row; min-height: 0;\"\n class=\"left-pane ${this.showDetails ? 'open' : ''}\"\n >\n <div class=\"chat-wrapper\">${contactHistory} ${chatbox}</div>\n </div>`;\n\n if (this.toolbar) {\n const contactDetails = this.currentContact\n ? this.getTembaContactDetails()\n : null;\n const toggleContactDetails = this.currentContact\n ? this.getToggleDetailsTembaTip()\n : null;\n const addNoteAndAssignTicketTembaTips =\n this.currentContact && this.currentTicket\n ? this.getAddNoteAndAssignTicketTembaTips()\n : null;\n const addNoteAndAssignTicketTembaModaxes = this.currentTicket\n ? this.getAddNoteAndAssignTicketTembaModaxes()\n : null;\n\n const contactDetailsAndActions = html`${contactDetails}\n <div class=\"toolbar ${this.showDetails ? '' : 'closed'}\">\n ${toggleContactDetails} ${addNoteAndAssignTicketTembaTips}\n </div>\n ${addNoteAndAssignTicketTembaModaxes}`;\n\n return html`${contactHistoryAndChatbox} ${contactDetailsAndActions}`;\n }\n\n return html`${contactHistoryAndChatbox}`;\n }\n\n private getTembaContactHistory(): TemplateResult {\n return html` <temba-contact-history\n .uuid=${this.currentContact.uuid}\n .contact=${this.currentContact}\n .ticket=${this.currentTicket ? this.currentTicket.uuid : null}\n .endDate=${this.currentTicket ? this.currentTicket.closed_on : null}\n .agent=${this.agent}\n >\n </temba-contact-history>`;\n }\n\n private getTembaChatbox(): TemplateResult {\n if (this.currentTicket) {\n if (this.currentContact && this.currentContact.status !== 'active') {\n //no chatbox for archived, blocked, or stopped contacts\n return null;\n } else {\n if (this.currentTicket.closed_on) {\n //reopen button for active contacts with a closed ticket\n return html` <div class=\"closed-footer\">\n <temba-button\n id=\"reopen-button\"\n name=\"Reopen\"\n @click=${this.handleTicketReopen}\n ></temba-button>\n </div>`;\n } else {\n //chatbox for active contacts with an open ticket\n return this.getChatbox();\n }\n }\n }\n\n if (this.currentContact && this.currentContact.status !== 'active') {\n //no chatbox for archived, blocked, or stopped contacts\n return null;\n } else {\n //chatbox for active contacts\n return this.getChatbox();\n }\n }\n\n private getChatbox(): TemplateResult {\n return html` <div class=\"chatbox ${this.toolbar ? 'full' : ''}\">\n <temba-compose\n chatbox\n attachments\n counter\n button\n @temba-button-clicked=${this.handleSend.bind(this)}\n >\n </temba-compose>\n </div>`;\n }\n\n private getTembaContactDetails(): TemplateResult {\n return 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 >\n </temba-contact-details>`;\n }\n\n private getToggleDetailsTembaTip(): TemplateResult {\n return html` <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 ? Icon.menu_collapse : 'layout-left'}\"\n @click=\"${this.handleDetailSlider}\"\n clickable\n animatechange=\"spin\"\n ></temba-icon>\n </temba-tip>`;\n }\n\n private getAddNoteAndAssignTicketTembaTips(): TemplateResult {\n return html` <temba-tip\n style=\"margin-top:5px\"\n text=\"Assign\"\n position=\"left\"\n >\n <temba-icon\n id=\"assign-button\"\n name=\"${Icon.users}\"\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 style=\"margin-top:5px\" text=\"Add Note\" position=\"left\">\n <temba-icon\n id=\"add-note-button\"\n name=\"${Icon.add_note}\"\n @click=\"${() => {\n const note = this.shadowRoot.getElementById('note-dialog') as Modax;\n note.open = true;\n }}\"\n clickable\n ></temba-icon>\n </temba-tip>`;\n }\n\n private getAddNoteAndAssignTicketTembaModaxes(): TemplateResult {\n return html` <temba-modax\n header=\"Add Note\"\n id=\"note-dialog\"\n @temba-submitted=${this.refresh}\n endpoint=\"/ticket/note/${this.currentTicket.uuid}/\"\n >\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 >\n </temba-modax>`;\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, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Contact, CustomEventType, Ticket } from '../interfaces';\nimport { COOKIE_KEYS, getCookieBoolean, postJSON, setCookie } from '../utils';\nimport { ContactHistory } from './ContactHistory';\nimport { Modax } from '../dialog/Modax';\nimport { ContactStoreElement } from './ContactStoreElement';\nimport { Icon } from '../vectoricon';\nimport { Compose } from '../compose/Compose';\n\nconst DEFAULT_REFRESH = 10000;\n\nexport class ContactChat extends ContactStoreElement {\n public static get styles() {\n return css`\n .left-pane {\n box-shadow: -13px 10px 7px 14px rgba(0, 0, 0, 0);\n transition: box-shadow 600ms linear;\n }\n\n .left-pane.open {\n z-index: 1000;\n }\n\n :host {\n flex-grow: 1;\n display: flex;\n flex-direction: row;\n min-height: 0;\n border-radius: var(--curvature);\n }\n\n .chat-wrapper {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n }\n\n temba-contact-history {\n border-bottom: 3px solid #e1e1e1;\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n }\n\n .chatbox {\n background: rgb(242, 242, 242);\n padding: 1em;\n display: flex;\n flex-direction: column;\n z-index: 3;\n border-bottom-left-radius: var(--curvature);\n border-bottom-right-radius: var(--curvature);\n }\n\n .chatbox.full {\n border-bottom-right-radius: 0 !important;\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 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#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 }\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 temba-completion {\n --widget-box-shadow: none;\n --color-widget-border: transparent;\n --widget-box-shadow-focused: none;\n --color-focus: transparent;\n --color-widget-bg-focused: transparent;\n }\n `;\n }\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 toolbar = false;\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: String })\n agent = '';\n\n // http promise to monitor for completeness\n public httpComplete: Promise<void>;\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 we don't have an endpoint infer one\n if (\n changedProperties.has('data') ||\n changedProperties.has('currentContact')\n ) {\n this.currentContact = this.data;\n }\n }\n\n private handleTicketReopen() {\n const uuid = this.currentTicket.uuid;\n postJSON(`/api/v2/ticket_actions.json`, {\n tickets: [uuid],\n action: 'reopen',\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(evt: CustomEvent) {\n const buttonName = evt.detail.name;\n if (buttonName === 'Send') {\n const payload = {\n contacts: [this.currentContact.uuid],\n };\n const compose = evt.currentTarget as Compose;\n if (compose) {\n const text = compose.currentChat;\n if (text.length > 0) {\n payload['text'] = text;\n }\n const attachments = compose.values.map(attachment => {\n const content_type = attachment.content_type;\n return content_type + ':' + attachment.url;\n });\n if (attachments.length > 0) {\n payload['attachments'] = attachments;\n }\n }\n if (this.currentTicket) {\n payload['ticket'] = this.currentTicket.uuid;\n }\n\n const genericError = buttonName + ' failed, please try again.';\n\n postJSON(`/api/v2/broadcasts.json`, payload)\n .then(response => {\n if (response.status < 400) {\n compose.reset();\n this.refresh(true);\n } else if (response.status < 500) {\n if (\n response.json.text &&\n response.json.text.eng &&\n response.json.text.eng.length > 0\n ) {\n compose.buttonError =\n 'Text must have no more than 640 characters.';\n } else if (\n response.json.attachments &&\n response.json.attachments.eng &&\n response.json.attachments.eng.length > 0\n ) {\n compose.buttonError =\n 'Attachments must have no more than 10 files.';\n } else {\n compose.buttonError = genericError;\n }\n } else {\n compose.buttonError = genericError;\n }\n })\n .catch(error => {\n console.error(error);\n compose.buttonError = genericError;\n });\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 const contactHistory = this.currentContact\n ? this.getTembaContactHistory()\n : null;\n const chatbox = this.currentContact ? this.getTembaChatbox() : null;\n\n const contactHistoryAndChatbox = html`<div\n style=\"flex-grow: 1; margin-right: 0em; display:flex; flex-direction:row; min-height: 0;\"\n class=\"left-pane ${this.showDetails ? 'open' : ''}\"\n >\n <div class=\"chat-wrapper\">${contactHistory} ${chatbox}</div>\n </div>`;\n\n if (this.toolbar) {\n const contactDetails = this.currentContact\n ? this.getTembaContactDetails()\n : null;\n const toggleContactDetails = this.currentContact\n ? this.getToggleDetailsTembaTip()\n : null;\n const addNoteAndAssignTicketTembaTips =\n this.currentContact && this.currentTicket\n ? this.getAddNoteAndAssignTicketTembaTips()\n : null;\n const addNoteAndAssignTicketTembaModaxes = this.currentTicket\n ? this.getAddNoteAndAssignTicketTembaModaxes()\n : null;\n\n const contactDetailsAndActions = html`${contactDetails}\n <div class=\"toolbar ${this.showDetails ? '' : 'closed'}\">\n ${toggleContactDetails} ${addNoteAndAssignTicketTembaTips}\n </div>\n ${addNoteAndAssignTicketTembaModaxes}`;\n\n return html`${contactHistoryAndChatbox} ${contactDetailsAndActions}`;\n }\n\n return html`${contactHistoryAndChatbox}`;\n }\n\n private getTembaContactHistory(): TemplateResult {\n return html` <temba-contact-history\n .uuid=${this.currentContact.uuid}\n .contact=${this.currentContact}\n .ticket=${this.currentTicket ? this.currentTicket.uuid : null}\n .endDate=${this.currentTicket ? this.currentTicket.closed_on : null}\n .agent=${this.agent}\n >\n </temba-contact-history>`;\n }\n\n private getTembaChatbox(): TemplateResult {\n if (this.currentTicket) {\n if (this.currentContact && this.currentContact.status !== 'active') {\n //no chatbox for archived, blocked, or stopped contacts\n return null;\n } else {\n if (this.currentTicket.closed_on) {\n //reopen button for active contacts with a closed ticket\n return html` <div class=\"closed-footer\">\n <temba-button\n id=\"reopen-button\"\n name=\"Reopen\"\n @click=${this.handleTicketReopen}\n ></temba-button>\n </div>`;\n } else {\n //chatbox for active contacts with an open ticket\n return this.getChatbox();\n }\n }\n }\n\n if (this.currentContact && this.currentContact.status !== 'active') {\n //no chatbox for archived, blocked, or stopped contacts\n return null;\n } else {\n //chatbox for active contacts\n return this.getChatbox();\n }\n }\n\n private getChatbox(): TemplateResult {\n return html` <div class=\"chatbox ${this.toolbar ? 'full' : ''}\">\n <temba-compose\n chatbox\n attachments\n counter\n button\n @temba-button-clicked=${this.handleSend.bind(this)}\n >\n </temba-compose>\n </div>`;\n }\n\n private getTembaContactDetails(): TemplateResult {\n return 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 >\n </temba-contact-details>`;\n }\n\n private getToggleDetailsTembaTip(): TemplateResult {\n return html` <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 ? Icon.menu_collapse : 'layout-left'}\"\n @click=\"${this.handleDetailSlider}\"\n clickable\n animatechange=\"spin\"\n ></temba-icon>\n </temba-tip>`;\n }\n\n private getAddNoteAndAssignTicketTembaTips(): TemplateResult {\n return html` <temba-tip\n style=\"margin-top:5px\"\n text=\"Assign\"\n position=\"left\"\n >\n <temba-icon\n id=\"assign-button\"\n name=\"${Icon.users}\"\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 style=\"margin-top:5px\" text=\"Add Note\" position=\"left\">\n <temba-icon\n id=\"add-note-button\"\n name=\"${Icon.add_note}\"\n @click=\"${() => {\n const note = this.shadowRoot.getElementById('note-dialog') as Modax;\n note.open = true;\n }}\"\n clickable\n ></temba-icon>\n </temba-tip>`;\n }\n\n private getAddNoteAndAssignTicketTembaModaxes(): TemplateResult {\n return html` <temba-modax\n header=\"Add Note\"\n id=\"note-dialog\"\n @temba-submitted=${this.refresh}\n endpoint=\"/ticket/note/${this.currentTicket.uuid}/\"\n >\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 >\n </temba-modax>`;\n }\n}\n"]}
|
|
@@ -81,6 +81,7 @@ export class ContactHistory extends RapidElement {
|
|
|
81
81
|
flex-grow: 1;
|
|
82
82
|
min-height: 0;
|
|
83
83
|
padding-top: 3em;
|
|
84
|
+
padding-bottom: 1em;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
temba-loading {
|
|
@@ -175,6 +176,10 @@ export class ContactHistory extends RapidElement {
|
|
|
175
176
|
.sticky-bin .attn {
|
|
176
177
|
color: var(--color-text);
|
|
177
178
|
}
|
|
179
|
+
|
|
180
|
+
.attachment img {
|
|
181
|
+
cursor: pointer;
|
|
182
|
+
}
|
|
178
183
|
`;
|
|
179
184
|
}
|
|
180
185
|
firstUpdated(changedProperties) {
|
|
@@ -551,7 +556,7 @@ export class ContactHistory extends RapidElement {
|
|
|
551
556
|
return renderTicketOpened(ticketEvent, closeHandler, !this.ticket);
|
|
552
557
|
}
|
|
553
558
|
case Events.TICKET_NOTE_ADDED:
|
|
554
|
-
return renderNoteCreated(event
|
|
559
|
+
return renderNoteCreated(event);
|
|
555
560
|
case Events.TICKET_ASSIGNED:
|
|
556
561
|
return renderTicketAssigned(event);
|
|
557
562
|
case Events.TICKET_REOPENED: {
|
|
@@ -631,11 +636,22 @@ export class ContactHistory extends RapidElement {
|
|
|
631
636
|
isPurged(ticket) {
|
|
632
637
|
return !this.ticketEvents[ticket.uuid];
|
|
633
638
|
}
|
|
639
|
+
handleEventClicked(event) {
|
|
640
|
+
const ele = event.target;
|
|
641
|
+
if (ele.tagName == 'IMG') {
|
|
642
|
+
// if we have one, show in our lightbox
|
|
643
|
+
const lightbox = document.querySelector('temba-lightbox');
|
|
644
|
+
if (lightbox) {
|
|
645
|
+
lightbox.showElement(ele);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
634
649
|
renderEventContainer(event) {
|
|
635
650
|
const stickyId = this.getStickyId(event);
|
|
636
651
|
const isSticky = !!stickyId;
|
|
637
652
|
const renderedEvent = html `
|
|
638
653
|
<div
|
|
654
|
+
@click=${this.handleEventClicked}
|
|
639
655
|
class="${this.ticket
|
|
640
656
|
? 'active-ticket'
|
|
641
657
|
: ''} event ${event.type} ${isSticky ? 'has-sticky' : ''}"
|