@nyaruka/temba-components 0.72.1 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/{730431a7.js → 92eb6aec.js} +334 -180
- package/dist/index.js +334 -180
- package/dist/static/svg/index.svg +1 -1
- package/dist/sw.js +1 -1
- package/dist/sw.js.map +1 -1
- package/dist/templates/components-body.html +1 -1
- package/dist/templates/components-head.html +1 -1
- package/out-tsc/src/FormElement.js +0 -3
- package/out-tsc/src/FormElement.js.map +1 -1
- package/out-tsc/src/contacts/ContactFieldEditor.js +232 -39
- package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/contacts/ContactFields.js +33 -1
- package/out-tsc/src/contacts/ContactFields.js.map +1 -1
- package/out-tsc/src/datepicker/DatePicker.js +6 -5
- package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +31 -1
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +3 -1
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/datepicker/initial-timezone.png +0 -0
- package/src/FormElement.ts +0 -4
- package/src/contacts/ContactFieldEditor.ts +228 -35
- package/src/contacts/ContactFields.ts +48 -1
- package/src/datepicker/DatePicker.ts +6 -6
- package/src/interfaces.ts +1 -0
- package/src/textinput/TextInput.ts +30 -1
- package/src/vectoricon/index.ts +4 -1
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/hash-01.svg +1 -0
- package/static/svg/work/used/hash-01.svg +3 -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 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:"
|
|
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:"92eb6aec.js",revision:"0b97821043f6f8cd939615de0b9ca744"},{url:"templates/components-body.html",revision:"51c5a0a58d995e1b77263ccf3892bbc3"},{url:"templates/components-head.html",revision:"a2498c42d5a64d363ec6d9ca0efb309a"}],{}),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/1e0834bdbdeb4bb411d5b885c9c3256b/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/workspaces/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/workspaces/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/workspaces/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/workspaces/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/workspaces/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/workspaces/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"92eb6aec.js\",\n \"revision\": \"0b97821043f6f8cd939615de0b9ca744\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"51c5a0a58d995e1b77263ccf3892bbc3\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"a2498c42d5a64d363ec6d9ca0efb309a\"\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/92eb6aec.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.73.0"</script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<script src="{{STATIC_URL}}croppie/croppie.js"></script><link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/
|
|
1
|
+
<script src="{{STATIC_URL}}croppie/croppie.js"></script><link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/92eb6aec.js" crossorigin="anonymous">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormElement.js","sourceRoot":"","sources":["../../src/FormElement.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAkC3C;QACE,KAAK,EAAE,CAAC;QAjCV,SAAI,GAAG,EAAE,CAAC;QAqBV,UAAK,GAAG,IAAI,CAAC;QAGb,cAAS,GAAgB,IAAI,CAAC;QAG9B,aAAQ,GAAG,KAAK,CAAC;QAOf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IAC1C,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAClC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACzC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"FormElement.js","sourceRoot":"","sources":["../../src/FormElement.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAkC3C;QACE,KAAK,EAAE,CAAC;QAjCV,SAAI,GAAG,EAAE,CAAC;QAqBV,UAAK,GAAG,IAAI,CAAC;QAGb,cAAS,GAAgB,IAAI,CAAC;QAG9B,aAAQ,GAAG,KAAK,CAAC;QAOf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IAC1C,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAClC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACzC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAEM,QAAQ,CAAC,KAAU;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAEM,oBAAoB;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAEM,cAAc,CAAC,KAAU;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;;AA9BM,0BAAc,GAAG,IAAI,CAAC;AA5B7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yCACjB;AAGV;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;6CAClC;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;+CAClC;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;+CAClC;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;8CAClC;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACb;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2CACT;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACd;AAGb;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;8CACD;AAG9B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;6CACX","sourcesContent":["import { RapidElement } from './RapidElement';\nimport { property } from 'lit/decorators.js';\n\n/**\n * FormElement is a component that appends a hidden input (outside of\n * its own shadow) with its value to be included in forms.\n */\nexport class FormElement extends RapidElement {\n @property({ type: String })\n name = '';\n\n @property({ type: String, attribute: 'help_text' })\n helpText: string;\n\n @property({ type: Boolean, attribute: 'help_always' })\n helpAlways: boolean;\n\n @property({ type: Boolean, attribute: 'widget_only' })\n widgetOnly: boolean;\n\n @property({ type: Boolean, attribute: 'hide_label' })\n hideLabel: boolean;\n\n @property({ type: String })\n label: string;\n\n @property({ type: Array })\n errors: string[];\n\n @property({ type: String })\n value = null;\n\n @property({ attribute: false })\n inputRoot: HTMLElement = this;\n\n @property({ type: Boolean })\n disabled = false;\n static formAssociated = true;\n\n protected internals: ElementInternals;\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this.value);\n }\n }\n\n get form() {\n return this.internals.form;\n }\n\n public setValue(value: any) {\n this.value = this.serializeValue(value);\n }\n\n public getDeserializedValue(): any {\n return JSON.parse(this.value);\n }\n\n public serializeValue(value: any): string {\n return JSON.stringify(value);\n }\n}\n"]}
|
|
@@ -3,14 +3,24 @@ import { css, html } from 'lit';
|
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
4
|
import { CustomEventType } from '../interfaces';
|
|
5
5
|
import { RapidElement } from '../RapidElement';
|
|
6
|
+
import { InputType } from '../textinput/TextInput';
|
|
6
7
|
import { Icon } from '../vectoricon';
|
|
7
8
|
import { getClasses } from '../utils';
|
|
9
|
+
var Status;
|
|
10
|
+
(function (Status) {
|
|
11
|
+
Status["Success"] = "success";
|
|
12
|
+
Status["Failure"] = "failure";
|
|
13
|
+
Status["Saving"] = "saving";
|
|
14
|
+
Status["Ready"] = "ready";
|
|
15
|
+
})(Status || (Status = {}));
|
|
8
16
|
export class ContactFieldEditor extends RapidElement {
|
|
9
17
|
constructor() {
|
|
10
18
|
super(...arguments);
|
|
11
19
|
this.icon = navigator.clipboard ? Icon.copy : '';
|
|
12
20
|
this.iconClass = '';
|
|
21
|
+
this.status = Status.Ready;
|
|
13
22
|
this.disabled = false;
|
|
23
|
+
this.dirty = false;
|
|
14
24
|
}
|
|
15
25
|
static get styles() {
|
|
16
26
|
return css `
|
|
@@ -34,15 +44,28 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
.wrapper.mutable:hover {
|
|
37
|
-
--color-widget-border: rgb(225, 225, 225);
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
.wrapper.mutable {
|
|
41
|
-
--color-widget-border:
|
|
50
|
+
--color-widget-border: rgb(235, 235, 235);
|
|
42
51
|
--color-widget-bg: transparent;
|
|
43
52
|
--input-cursor: pointer;
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
|
|
54
|
+
border-bottom: none;
|
|
55
|
+
margin-bottom: 0.5em;
|
|
56
|
+
padding-bottom: 0em;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.mutable.success {
|
|
60
|
+
--color-widget-border: rgba(var(--success-rgb), 0.6);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.mutable.failure {
|
|
64
|
+
--color-widget-border: rgba(var(--error-rgb), 0.3) !important;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.mutable .dirty {
|
|
68
|
+
--color-widget-border: rgb(235, 235, 235);
|
|
46
69
|
}
|
|
47
70
|
|
|
48
71
|
.prefix {
|
|
@@ -75,20 +98,20 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
75
98
|
.postfix {
|
|
76
99
|
display: flex;
|
|
77
100
|
align-items: stretch;
|
|
101
|
+
margin-left: 1em;
|
|
78
102
|
}
|
|
79
103
|
|
|
80
104
|
.popper {
|
|
81
|
-
padding: 0.5em 0.75em;
|
|
82
105
|
background: rgba(0, 0, 0, 0.03);
|
|
83
106
|
border-top-right-radius: var(--curvature-widget);
|
|
84
107
|
border-bottom-right-radius: var(--curvature-widget);
|
|
85
108
|
--icon-color: #888;
|
|
86
|
-
|
|
109
|
+
display: flex;
|
|
87
110
|
cursor: default;
|
|
88
111
|
transition: all var(--transition-speed) ease-in-out;
|
|
89
|
-
display: flex;
|
|
90
112
|
align-items: stretch;
|
|
91
113
|
z-index: 1000;
|
|
114
|
+
margin: -1px;
|
|
92
115
|
}
|
|
93
116
|
|
|
94
117
|
temba-icon[name='calendar'] {
|
|
@@ -106,16 +129,39 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
106
129
|
|
|
107
130
|
temba-textinput:focus .popper,
|
|
108
131
|
temba-textinput:hover .popper {
|
|
109
|
-
|
|
132
|
+
display: flex;
|
|
110
133
|
}
|
|
111
134
|
|
|
112
135
|
.disabled temba-textinput .postfix {
|
|
113
136
|
display: none;
|
|
137
|
+
padding: none;
|
|
114
138
|
}
|
|
115
139
|
|
|
116
|
-
.unset temba-textinput
|
|
117
|
-
.unset temba-textinput
|
|
118
|
-
|
|
140
|
+
.unset temba-textinput .popper .copy,
|
|
141
|
+
.unset temba-textinput .popper .search {
|
|
142
|
+
display: none;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.unset temba-textinput:focus .popper .copy,
|
|
146
|
+
.unset temba-textinput:hover .popper .copy,
|
|
147
|
+
.unset temba-textinput:focus .popper .save,
|
|
148
|
+
.unset temba-textinput:hover .popper .save {
|
|
149
|
+
display: none;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.popper temba-icon {
|
|
153
|
+
padding: 0.5em 0em;
|
|
154
|
+
padding-right: 1em;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.popper:first-child {
|
|
158
|
+
padding: 0.5em 0em;
|
|
159
|
+
padding-right: 0.5em;
|
|
160
|
+
padding-left: 1em;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.popper:last-child {
|
|
164
|
+
padding-right: 0em;
|
|
119
165
|
}
|
|
120
166
|
|
|
121
167
|
.copy.clicked temba-icon {
|
|
@@ -126,13 +172,90 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
126
172
|
transition: all 200ms ease-in-out;
|
|
127
173
|
}
|
|
128
174
|
|
|
129
|
-
temba-icon.search {
|
|
130
|
-
margin-right: 1em;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
175
|
temba-datepicker {
|
|
134
176
|
position: relative;
|
|
135
177
|
}
|
|
178
|
+
|
|
179
|
+
.save-state {
|
|
180
|
+
display: flex;
|
|
181
|
+
align-items: center;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.save-button {
|
|
185
|
+
padding-right: 1em;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.dirty .copy,
|
|
189
|
+
.dirty .search {
|
|
190
|
+
display: none;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.saving .copy,
|
|
194
|
+
.saving .search {
|
|
195
|
+
display: none;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.success .copy,
|
|
199
|
+
.success .search {
|
|
200
|
+
display: none;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.failure .copy,
|
|
204
|
+
.failure .search {
|
|
205
|
+
display: none;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.popper.success {
|
|
209
|
+
background: rgb(var(--success-rgb));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.popper.failure {
|
|
213
|
+
background: rgb(var(--error-rgb));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.popper.success temba-icon,
|
|
217
|
+
.popper.failure temba-icon {
|
|
218
|
+
--icon-color: #fff !important;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.popper.dirty {
|
|
222
|
+
background: rgba(0, 0, 0, 0.03);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
temba-datepicker .popper {
|
|
226
|
+
border-radius: 0px;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
temba-datepicker .popper:first-child {
|
|
230
|
+
padding: 0;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.dirty temba-datepicker .popper:first-child {
|
|
234
|
+
padding-left: 1em;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.success temba-datepicker .popper:first-child {
|
|
238
|
+
padding-left: 1em;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.failure temba-datepicker .popper:first-child {
|
|
242
|
+
padding-left: 1em;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.saving temba-datepicker .popper:first-child {
|
|
246
|
+
padding-left: 1em;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
temba-datepicker .postfix {
|
|
250
|
+
margin-left: 0;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.saving temba-datepicker,
|
|
254
|
+
.saving temba-textinput {
|
|
255
|
+
pointer-events: none !important;
|
|
256
|
+
cursor: default !important;
|
|
257
|
+
opacity: 0.7;
|
|
258
|
+
}
|
|
136
259
|
`;
|
|
137
260
|
}
|
|
138
261
|
connectedCallback() {
|
|
@@ -163,55 +286,119 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
163
286
|
evt.preventDefault();
|
|
164
287
|
evt.stopPropagation();
|
|
165
288
|
}
|
|
289
|
+
handleResponse(response) {
|
|
290
|
+
if (response.status === 200) {
|
|
291
|
+
this.value = response.json.fields[this.key];
|
|
292
|
+
// this.status = Status.Success;
|
|
293
|
+
// on success lets go back to ready state for now
|
|
294
|
+
this.status = Status.Ready;
|
|
295
|
+
this.dirty = false;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
this.status = Status.Failure;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
166
301
|
handleSubmit() {
|
|
167
302
|
const input = this.shadowRoot.querySelector('temba-textinput, temba-datepicker');
|
|
168
303
|
if (input.value !== this.value) {
|
|
304
|
+
this.dirty = true;
|
|
305
|
+
this.status = Status.Saving;
|
|
169
306
|
this.value = input.value;
|
|
170
307
|
this.fireEvent('change');
|
|
171
308
|
}
|
|
172
|
-
this.icon = navigator.clipboard ? 'copy' : '';
|
|
173
309
|
}
|
|
174
310
|
handleChange(evt) {
|
|
175
311
|
evt.preventDefault();
|
|
176
312
|
evt.stopPropagation();
|
|
177
313
|
}
|
|
314
|
+
handleDateChange(evt) {
|
|
315
|
+
evt.preventDefault();
|
|
316
|
+
evt.stopPropagation();
|
|
317
|
+
this.dirty = true;
|
|
318
|
+
}
|
|
178
319
|
handleInput(evt) {
|
|
320
|
+
const input = evt.currentTarget;
|
|
179
321
|
if (evt.key === 'Enter') {
|
|
180
|
-
const input = evt.currentTarget;
|
|
181
322
|
input.blur();
|
|
323
|
+
this.handleSubmit();
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
if (input.value !== this.value) {
|
|
327
|
+
this.dirty = true;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
getInputType(type) {
|
|
332
|
+
if (type === 'numeric') {
|
|
333
|
+
return InputType.Number;
|
|
182
334
|
}
|
|
335
|
+
return InputType.Text;
|
|
183
336
|
}
|
|
184
337
|
render() {
|
|
338
|
+
const state = html `<div class="save-state">
|
|
339
|
+
${this.dirty
|
|
340
|
+
? html `<temba-button
|
|
341
|
+
class="save-button"
|
|
342
|
+
name="Save"
|
|
343
|
+
small
|
|
344
|
+
@click=${this.handleSubmit}
|
|
345
|
+
></temba-button>`
|
|
346
|
+
: html ` ${this.status === Status.Saving
|
|
347
|
+
? html `<temba-icon
|
|
348
|
+
spin
|
|
349
|
+
name="${Icon.progress_spinner}"
|
|
350
|
+
></temba-icon>`
|
|
351
|
+
: null}
|
|
352
|
+
${this.status === Status.Success && !this.dirty
|
|
353
|
+
? html `<temba-icon name="${Icon.success}"></temba-icon>`
|
|
354
|
+
: null}
|
|
355
|
+
${this.status === Status.Failure
|
|
356
|
+
? html `<temba-tip text="Failed to save changes, try again later."
|
|
357
|
+
><temba-icon name="${Icon.alert_warning}"></temba-icon
|
|
358
|
+
></temba-tip>`
|
|
359
|
+
: null}`}
|
|
360
|
+
</div>`;
|
|
185
361
|
return html `
|
|
186
362
|
<div
|
|
187
|
-
class=${
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
363
|
+
class=${this.status +
|
|
364
|
+
' ' +
|
|
365
|
+
getClasses({
|
|
366
|
+
wrapper: true,
|
|
367
|
+
set: !!this.value,
|
|
368
|
+
unset: !this.value,
|
|
369
|
+
disabled: this.disabled,
|
|
370
|
+
mutable: !this.disabled,
|
|
371
|
+
dirty: this.dirty,
|
|
372
|
+
})}
|
|
194
373
|
>
|
|
195
374
|
${this.type === 'datetime'
|
|
196
375
|
? html `
|
|
197
376
|
<temba-datepicker
|
|
198
377
|
timezone=${this.timezone}
|
|
199
378
|
value="${this.value ? this.value : ''}"
|
|
200
|
-
@change=${this.
|
|
379
|
+
@change=${this.handleDateChange}
|
|
201
380
|
?disabled=${this.disabled}
|
|
202
381
|
time
|
|
203
382
|
>
|
|
204
383
|
<div class="prefix" slot="prefix">
|
|
205
384
|
<div class="name">${this.name}</div>
|
|
206
385
|
</div>
|
|
386
|
+
<div class="postfix" slot="postfix">
|
|
387
|
+
<div
|
|
388
|
+
class="popper ${this.status} ${this.dirty ? 'dirty' : ''}"
|
|
389
|
+
>
|
|
390
|
+
${state}
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
207
393
|
</temba-datepicker>
|
|
208
394
|
`
|
|
209
395
|
: html `
|
|
210
396
|
<temba-textinput
|
|
397
|
+
class="${this.status} ${this.dirty ? 'dirty' : ''}"
|
|
211
398
|
value="${this.value ? this.value : ''}"
|
|
212
|
-
@
|
|
213
|
-
@keydown=${this.handleInput}
|
|
399
|
+
@keyup=${this.handleInput}
|
|
214
400
|
@change=${this.handleChange}
|
|
401
|
+
type=${this.getInputType(this.type)}
|
|
215
402
|
?disabled=${this.disabled}
|
|
216
403
|
>
|
|
217
404
|
<div class="prefix" slot="prefix">
|
|
@@ -220,21 +407,21 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
220
407
|
|
|
221
408
|
<div class="postfix">
|
|
222
409
|
<div
|
|
223
|
-
class="popper ${this.iconClass}
|
|
410
|
+
class="popper ${this.iconClass} ${this.status} ${this.dirty
|
|
411
|
+
? 'dirty'
|
|
412
|
+
: ''}"
|
|
224
413
|
@click=${this.handleIconClick}
|
|
225
414
|
>
|
|
226
|
-
${
|
|
227
|
-
|
|
228
|
-
<temba-icon
|
|
229
|
-
class="search"
|
|
230
|
-
icon-action="search"
|
|
231
|
-
name="${Icon.search}"
|
|
232
|
-
animateclick="pulse"
|
|
233
|
-
></temba-icon>
|
|
234
|
-
</div>
|
|
235
|
-
`
|
|
236
|
-
: null}
|
|
415
|
+
${state}
|
|
416
|
+
|
|
237
417
|
<temba-icon
|
|
418
|
+
class="search"
|
|
419
|
+
icon-action="search"
|
|
420
|
+
name="${Icon.search}"
|
|
421
|
+
animateclick="pulse"
|
|
422
|
+
></temba-icon>
|
|
423
|
+
<temba-icon
|
|
424
|
+
class="copy"
|
|
238
425
|
icon-action="copy"
|
|
239
426
|
name="${this.icon}"
|
|
240
427
|
animatechange="spin"
|
|
@@ -269,7 +456,13 @@ __decorate([
|
|
|
269
456
|
__decorate([
|
|
270
457
|
property({ type: String })
|
|
271
458
|
], ContactFieldEditor.prototype, "iconClass", void 0);
|
|
459
|
+
__decorate([
|
|
460
|
+
property({ type: String })
|
|
461
|
+
], ContactFieldEditor.prototype, "status", void 0);
|
|
272
462
|
__decorate([
|
|
273
463
|
property({ type: Boolean })
|
|
274
464
|
], ContactFieldEditor.prototype, "disabled", void 0);
|
|
465
|
+
__decorate([
|
|
466
|
+
property({ type: Boolean })
|
|
467
|
+
], ContactFieldEditor.prototype, "dirty", void 0);
|
|
275
468
|
//# sourceMappingURL=ContactFieldEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactFieldEditor.js","sourceRoot":"","sources":["../../../src/contacts/ContactFieldEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { FormElement } from '../FormElement';\nimport { CustomEventType } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\nimport { TextInput } from '../textinput/TextInput';\nimport { Icon } from '../vectoricon';\nimport { getClasses } from '../utils';\n\nexport class ContactFieldEditor extends RapidElement {\n @property({ type: String })\n key: string;\n\n @property({ type: String })\n value: string;\n\n @property({ type: String })\n name: string;\n\n @property({ type: String })\n type: string;\n\n @property({ type: String })\n timezone: string;\n\n @property({ type: String })\n icon = navigator.clipboard ? Icon.copy : '';\n\n @property({ type: String })\n iconClass = '';\n\n @property({ type: Boolean })\n disabled = false;\n\n static get styles() {\n return css`\n :host {\n --transition-speed: 0ms;\n }\n\n .wrapper {\n --temba-textinput-padding: 1.4em 0.8em 0.4em 0.8em;\n --disabled-opacity: 1;\n position: relative;\n --color-widget-bg: transparent;\n --color-widget-bg-focused: #fff;\n --widget-box-shadow: none;\n padding-bottom: 0.6em;\n border-bottom: 1px solid #ececec;\n }\n\n .wrapper.disabled {\n --color-widget-border: transparent;\n }\n\n .wrapper.mutable:hover {\n --color-widget-border: rgb(225, 225, 225);\n }\n\n .wrapper.mutable {\n --color-widget-border: transparent;\n --color-widget-bg: transparent;\n --input-cursor: pointer;\n --color-widget-text-focused: #666;\n --color-widget-text: var(--color-link-primary) !important;\n }\n\n .prefix {\n border-top-left-radius: var(--curvature-widget);\n border-bottom-left-radius: var(--curvature-widget);\n cursor: pointer !important;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n padding: 0em 0.5em;\n position: absolute;\n margin-top: 0.2em;\n pointer-events: none;\n }\n\n .wrapper {\n margin-bottom: 0.5em;\n }\n\n .prefix .name {\n padding: 0em 0.4em;\n color: rgba(100, 100, 100, 0.7);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 0.8em;\n }\n\n .postfix {\n display: flex;\n align-items: stretch;\n }\n\n .popper {\n padding: 0.5em 0.75em;\n background: rgba(0, 0, 0, 0.03);\n border-top-right-radius: var(--curvature-widget);\n border-bottom-right-radius: var(--curvature-widget);\n --icon-color: #888;\n opacity: 0;\n cursor: default;\n transition: all var(--transition-speed) ease-in-out;\n display: flex;\n align-items: stretch;\n z-index: 1000;\n }\n\n temba-icon[name='calendar'] {\n --icon-color: rgba(0, 0, 0, 0.2);\n }\n\n temba-icon:hover {\n --icon-color: rgba(0, 0, 0, 0.5);\n }\n\n temba-icon {\n cursor: pointer;\n --icon-color: rgba(0, 0, 0, 0.3);\n }\n\n temba-textinput:focus .popper,\n temba-textinput:hover .popper {\n opacity: 1;\n }\n\n .disabled temba-textinput .postfix {\n display: none;\n }\n\n .unset temba-textinput:focus .popper,\n .unset temba-textinput:hover .popper {\n opacity: 0;\n }\n\n .copy.clicked temba-icon {\n transform: scale(1.2);\n }\n\n temba-icon {\n transition: all 200ms ease-in-out;\n }\n\n temba-icon.search {\n margin-right: 1em;\n }\n\n temba-datepicker {\n position: relative;\n }\n `;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.handleInput = this.handleInput.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n }\n\n public handleIconClick(evt: MouseEvent) {\n const ele = evt.target as HTMLDivElement;\n const icon = ele.getAttribute('icon-action');\n const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;\n\n if (icon === 'copy') {\n if (navigator.clipboard) {\n this.iconClass = 'clicked';\n navigator.clipboard.writeText(input.getDisplayValue()).then(() => {\n window.setTimeout(() => {\n this.iconClass = '';\n }, 300);\n });\n }\n }\n\n if (icon === 'search') {\n this.fireCustomEvent(CustomEventType.ButtonClicked, {\n key: this.key,\n value: this.value,\n });\n }\n\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n public handleSubmit() {\n const input = this.shadowRoot.querySelector(\n 'temba-textinput, temba-datepicker'\n ) as FormElement;\n if (input.value !== this.value) {\n this.value = input.value;\n this.fireEvent('change');\n }\n this.icon = navigator.clipboard ? 'copy' : '';\n }\n\n public handleChange(evt: Event) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n public handleInput(evt: KeyboardEvent) {\n if (evt.key === 'Enter') {\n const input = evt.currentTarget as TextInput;\n input.blur();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=${getClasses({\n wrapper: true,\n set: !!this.value,\n unset: !this.value,\n disabled: this.disabled,\n mutable: !this.disabled,\n })}\n >\n ${this.type === 'datetime'\n ? html`\n <temba-datepicker\n timezone=${this.timezone}\n value=\"${this.value ? this.value : ''}\"\n @change=${this.handleSubmit}\n ?disabled=${this.disabled}\n time\n >\n <div class=\"prefix\" slot=\"prefix\">\n <div class=\"name\">${this.name}</div>\n </div>\n </temba-datepicker>\n `\n : html`\n <temba-textinput\n value=\"${this.value ? this.value : ''}\"\n @blur=${this.handleSubmit}\n @keydown=${this.handleInput}\n @change=${this.handleChange}\n ?disabled=${this.disabled}\n >\n <div class=\"prefix\" slot=\"prefix\">\n <div class=\"name\">${this.name}</div>\n </div>\n\n <div class=\"postfix\">\n <div\n class=\"popper ${this.iconClass}\"\n @click=${this.handleIconClick}\n >\n ${this.value\n ? html`\n <temba-icon\n class=\"search\"\n icon-action=\"search\"\n name=\"${Icon.search}\"\n animateclick=\"pulse\"\n ></temba-icon>\n </div>\n `\n : null}\n <temba-icon\n icon-action=\"copy\"\n name=\"${this.icon}\"\n animatechange=\"spin\"\n animateclick=\"pulse\"\n ></temba-icon>\n </div>\n </div>\n </temba-textinput>\n `}\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ContactFieldEditor.js","sourceRoot":"","sources":["../../../src/contacts/ContactFieldEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { FormElement } from '../FormElement';\nimport { CustomEventType } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\nimport { InputType, TextInput } from '../textinput/TextInput';\nimport { Icon } from '../vectoricon';\nimport { getClasses, WebResponse } from '../utils';\n\nenum Status {\n Success = 'success',\n Failure = 'failure',\n Saving = 'saving',\n Ready = 'ready',\n}\n\nexport class ContactFieldEditor extends RapidElement {\n @property({ type: String })\n key: string;\n\n @property({ type: String })\n value: string;\n\n @property({ type: String })\n name: string;\n\n @property({ type: String })\n type: string;\n\n @property({ type: String })\n timezone: string;\n\n @property({ type: String })\n icon = navigator.clipboard ? Icon.copy : '';\n\n @property({ type: String })\n iconClass = '';\n\n @property({ type: String })\n status: Status = Status.Ready;\n\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: Boolean })\n dirty = false;\n\n static get styles() {\n return css`\n :host {\n --transition-speed: 0ms;\n }\n\n .wrapper {\n --temba-textinput-padding: 1.4em 0.8em 0.4em 0.8em;\n --disabled-opacity: 1;\n position: relative;\n --color-widget-bg: transparent;\n --color-widget-bg-focused: #fff;\n --widget-box-shadow: none;\n padding-bottom: 0.6em;\n border-bottom: 1px solid #ececec;\n }\n\n .wrapper.disabled {\n --color-widget-border: transparent;\n }\n\n .wrapper.mutable:hover {\n }\n\n .wrapper.mutable {\n --color-widget-border: rgb(235, 235, 235);\n --color-widget-bg: transparent;\n --input-cursor: pointer;\n\n border-bottom: none;\n margin-bottom: 0.5em;\n padding-bottom: 0em;\n }\n\n .mutable.success {\n --color-widget-border: rgba(var(--success-rgb), 0.6);\n }\n\n .mutable.failure {\n --color-widget-border: rgba(var(--error-rgb), 0.3) !important;\n }\n\n .mutable .dirty {\n --color-widget-border: rgb(235, 235, 235);\n }\n\n .prefix {\n border-top-left-radius: var(--curvature-widget);\n border-bottom-left-radius: var(--curvature-widget);\n cursor: pointer !important;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: flex;\n padding: 0em 0.5em;\n position: absolute;\n margin-top: 0.2em;\n pointer-events: none;\n }\n\n .wrapper {\n margin-bottom: 0.5em;\n }\n\n .prefix .name {\n padding: 0em 0.4em;\n color: rgba(100, 100, 100, 0.7);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 0.8em;\n }\n\n .postfix {\n display: flex;\n align-items: stretch;\n margin-left: 1em;\n }\n\n .popper {\n background: rgba(0, 0, 0, 0.03);\n border-top-right-radius: var(--curvature-widget);\n border-bottom-right-radius: var(--curvature-widget);\n --icon-color: #888;\n display: flex;\n cursor: default;\n transition: all var(--transition-speed) ease-in-out;\n align-items: stretch;\n z-index: 1000;\n margin: -1px;\n }\n\n temba-icon[name='calendar'] {\n --icon-color: rgba(0, 0, 0, 0.2);\n }\n\n temba-icon:hover {\n --icon-color: rgba(0, 0, 0, 0.5);\n }\n\n temba-icon {\n cursor: pointer;\n --icon-color: rgba(0, 0, 0, 0.3);\n }\n\n temba-textinput:focus .popper,\n temba-textinput:hover .popper {\n display: flex;\n }\n\n .disabled temba-textinput .postfix {\n display: none;\n padding: none;\n }\n\n .unset temba-textinput .popper .copy,\n .unset temba-textinput .popper .search {\n display: none;\n }\n\n .unset temba-textinput:focus .popper .copy,\n .unset temba-textinput:hover .popper .copy,\n .unset temba-textinput:focus .popper .save,\n .unset temba-textinput:hover .popper .save {\n display: none;\n }\n\n .popper temba-icon {\n padding: 0.5em 0em;\n padding-right: 1em;\n }\n\n .popper:first-child {\n padding: 0.5em 0em;\n padding-right: 0.5em;\n padding-left: 1em;\n }\n\n .popper:last-child {\n padding-right: 0em;\n }\n\n .copy.clicked temba-icon {\n transform: scale(1.2);\n }\n\n temba-icon {\n transition: all 200ms ease-in-out;\n }\n\n temba-datepicker {\n position: relative;\n }\n\n .save-state {\n display: flex;\n align-items: center;\n }\n\n .save-button {\n padding-right: 1em;\n }\n\n .dirty .copy,\n .dirty .search {\n display: none;\n }\n\n .saving .copy,\n .saving .search {\n display: none;\n }\n\n .success .copy,\n .success .search {\n display: none;\n }\n\n .failure .copy,\n .failure .search {\n display: none;\n }\n\n .popper.success {\n background: rgb(var(--success-rgb));\n }\n\n .popper.failure {\n background: rgb(var(--error-rgb));\n }\n\n .popper.success temba-icon,\n .popper.failure temba-icon {\n --icon-color: #fff !important;\n }\n\n .popper.dirty {\n background: rgba(0, 0, 0, 0.03);\n }\n\n temba-datepicker .popper {\n border-radius: 0px;\n }\n\n temba-datepicker .popper:first-child {\n padding: 0;\n }\n\n .dirty temba-datepicker .popper:first-child {\n padding-left: 1em;\n }\n\n .success temba-datepicker .popper:first-child {\n padding-left: 1em;\n }\n\n .failure temba-datepicker .popper:first-child {\n padding-left: 1em;\n }\n\n .saving temba-datepicker .popper:first-child {\n padding-left: 1em;\n }\n\n temba-datepicker .postfix {\n margin-left: 0;\n }\n\n .saving temba-datepicker,\n .saving temba-textinput {\n pointer-events: none !important;\n cursor: default !important;\n opacity: 0.7;\n }\n `;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.handleInput = this.handleInput.bind(this);\n this.handleSubmit = this.handleSubmit.bind(this);\n }\n\n public handleIconClick(evt: MouseEvent) {\n const ele = evt.target as HTMLDivElement;\n const icon = ele.getAttribute('icon-action');\n const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;\n\n if (icon === 'copy') {\n if (navigator.clipboard) {\n this.iconClass = 'clicked';\n navigator.clipboard.writeText(input.getDisplayValue()).then(() => {\n window.setTimeout(() => {\n this.iconClass = '';\n }, 300);\n });\n }\n }\n\n if (icon === 'search') {\n this.fireCustomEvent(CustomEventType.ButtonClicked, {\n key: this.key,\n value: this.value,\n });\n }\n\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n public handleResponse(response: WebResponse) {\n if (response.status === 200) {\n this.value = response.json.fields[this.key];\n // this.status = Status.Success;\n // on success lets go back to ready state for now\n this.status = Status.Ready;\n this.dirty = false;\n } else {\n this.status = Status.Failure;\n }\n }\n\n public handleSubmit() {\n const input = this.shadowRoot.querySelector(\n 'temba-textinput, temba-datepicker'\n ) as FormElement;\n\n if (input.value !== this.value) {\n this.dirty = true;\n this.status = Status.Saving;\n this.value = input.value;\n this.fireEvent('change');\n }\n }\n\n public handleChange(evt: Event) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n public handleDateChange(evt: Event) {\n evt.preventDefault();\n evt.stopPropagation();\n this.dirty = true;\n }\n\n public handleInput(evt: KeyboardEvent) {\n const input = evt.currentTarget as TextInput;\n if (evt.key === 'Enter') {\n input.blur();\n this.handleSubmit();\n } else {\n if (input.value !== this.value) {\n this.dirty = true;\n }\n }\n }\n\n private getInputType(type: string): string {\n if (type === 'numeric') {\n return InputType.Number;\n }\n return InputType.Text;\n }\n\n public render(): TemplateResult {\n const state = html`<div class=\"save-state\">\n ${this.dirty\n ? html`<temba-button\n class=\"save-button\"\n name=\"Save\"\n small\n @click=${this.handleSubmit}\n ></temba-button>`\n : html` ${this.status === Status.Saving\n ? html`<temba-icon\n spin\n name=\"${Icon.progress_spinner}\"\n ></temba-icon>`\n : null}\n ${this.status === Status.Success && !this.dirty\n ? html`<temba-icon name=\"${Icon.success}\"></temba-icon>`\n : null}\n ${this.status === Status.Failure\n ? html`<temba-tip text=\"Failed to save changes, try again later.\"\n ><temba-icon name=\"${Icon.alert_warning}\"></temba-icon\n ></temba-tip>`\n : null}`}\n </div>`;\n\n return html`\n <div\n class=${this.status +\n ' ' +\n getClasses({\n wrapper: true,\n set: !!this.value,\n unset: !this.value,\n disabled: this.disabled,\n mutable: !this.disabled,\n dirty: this.dirty,\n })}\n >\n ${this.type === 'datetime'\n ? html`\n <temba-datepicker\n timezone=${this.timezone}\n value=\"${this.value ? this.value : ''}\"\n @change=${this.handleDateChange}\n ?disabled=${this.disabled}\n time\n >\n <div class=\"prefix\" slot=\"prefix\">\n <div class=\"name\">${this.name}</div>\n </div>\n <div class=\"postfix\" slot=\"postfix\">\n <div\n class=\"popper ${this.status} ${this.dirty ? 'dirty' : ''}\"\n >\n ${state}\n </div>\n </div>\n </temba-datepicker>\n `\n : html`\n <temba-textinput\n class=\"${this.status} ${this.dirty ? 'dirty' : ''}\"\n value=\"${this.value ? this.value : ''}\"\n @keyup=${this.handleInput}\n @change=${this.handleChange}\n type=${this.getInputType(this.type)}\n ?disabled=${this.disabled}\n >\n <div class=\"prefix\" slot=\"prefix\">\n <div class=\"name\">${this.name}</div>\n </div>\n\n <div class=\"postfix\">\n <div\n class=\"popper ${this.iconClass} ${this.status} ${this.dirty\n ? 'dirty'\n : ''}\"\n @click=${this.handleIconClick}\n >\n ${state}\n\n <temba-icon\n class=\"search\"\n icon-action=\"search\"\n name=\"${Icon.search}\"\n animateclick=\"pulse\"\n ></temba-icon>\n <temba-icon\n class=\"copy\"\n icon-action=\"copy\"\n name=\"${this.icon}\"\n animatechange=\"spin\"\n animateclick=\"pulse\"\n ></temba-icon>\n </div>\n </div>\n </temba-textinput>\n `}\n </div>\n `;\n }\n}\n"]}
|
|
@@ -90,6 +90,7 @@ export class ContactFields extends ContactStoreElement {
|
|
|
90
90
|
postJSON('/api/v2/contacts.json?uuid=' + this.data.uuid, {
|
|
91
91
|
fields: { [field.key]: value },
|
|
92
92
|
}).then((response) => {
|
|
93
|
+
field.handleResponse(response);
|
|
93
94
|
// returns a single contact with latest updates
|
|
94
95
|
this.setContact(response.json);
|
|
95
96
|
});
|
|
@@ -105,6 +106,34 @@ export class ContactFields extends ContactStoreElement {
|
|
|
105
106
|
const [bk] = b;
|
|
106
107
|
const fieldA = this.store.getContactField(ak);
|
|
107
108
|
const fieldB = this.store.getContactField(bk);
|
|
109
|
+
if (fieldA.type === 'ward') {
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
if (fieldB.type === 'ward') {
|
|
113
|
+
return -1;
|
|
114
|
+
}
|
|
115
|
+
if (fieldA.type === 'district' &&
|
|
116
|
+
fieldB.type !== 'ward' &&
|
|
117
|
+
fieldB.type !== 'district') {
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
if (fieldB.type === 'district' &&
|
|
121
|
+
fieldA.type !== 'ward' &&
|
|
122
|
+
fieldA.type !== 'district') {
|
|
123
|
+
return -1;
|
|
124
|
+
}
|
|
125
|
+
if (fieldA.type === 'state' &&
|
|
126
|
+
fieldB.type !== 'ward' &&
|
|
127
|
+
fieldB.type !== 'district' &&
|
|
128
|
+
fieldB.type !== 'state') {
|
|
129
|
+
return 1;
|
|
130
|
+
}
|
|
131
|
+
if (fieldB.type === 'state' &&
|
|
132
|
+
fieldA.type !== 'ward' &&
|
|
133
|
+
fieldA.type !== 'district' &&
|
|
134
|
+
fieldA.type !== 'state') {
|
|
135
|
+
return -1;
|
|
136
|
+
}
|
|
108
137
|
if (fieldA.featured && !fieldB.featured) {
|
|
109
138
|
return -1;
|
|
110
139
|
}
|
|
@@ -132,7 +161,10 @@ export class ContactFields extends ContactStoreElement {
|
|
|
132
161
|
@change=${this.handleFieldChanged}
|
|
133
162
|
timezone=${this.timezone}
|
|
134
163
|
?disabled=${(this.isAgent() && field.agent_access === 'view') ||
|
|
135
|
-
this.disabled
|
|
164
|
+
this.disabled ||
|
|
165
|
+
field.value_type === 'ward' ||
|
|
166
|
+
field.value_type === 'district' ||
|
|
167
|
+
field.value_type === 'state'
|
|
136
168
|
? true
|
|
137
169
|
: false}
|
|
138
170
|
></temba-contact-field>`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactFields.js","sourceRoot":"","sources":["../../../src/contacts/ContactFields.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { getClasses, postJSON } from '../utils';\nimport { ContactFieldEditor } from './ContactFieldEditor';\nimport { ContactStoreElement } from './ContactStoreElement';\nimport { Checkbox } from '../checkbox/Checkbox';\n\nconst MIN_FOR_FILTER = 10;\n\nexport class ContactFields extends ContactStoreElement {\n static get styles() {\n return css`\n .field {\n display: flex;\n margin: 0.3em 0.3em;\n box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.15);\n border-radius: 0px;\n align-items: center;\n overflow: hidden;\n }\n\n .show-all .unset,\n .featured {\n display: block !important;\n }\n\n .unset {\n display: none;\n }\n\n .field:hover {\n box-shadow: 1px 1px 6px 2px rgba(0, 0, 0, 0.05),\n 0px 0px 0px 2px var(--color-link-primary);\n cursor: pointer;\n }\n\n .label {\n padding: 0.25em 1em;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n color: #777;\n font-size: 0.9em;\n font-weight: 400;\n box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.1) inset;\n }\n\n .value {\n --icon-color: #ddd;\n max-width: 150px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0.25em 1em;\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n font-size: 0.9em;\n }\n\n .toggle {\n display: flex;\n background: #fff;\n align-items: center;\n margin-bottom: 0.5em;\n }\n\n .disabled .toggle {\n display: none;\n }\n `;\n }\n\n @property({ type: Boolean })\n system: boolean;\n\n @property({ type: Boolean })\n dirty: boolean;\n\n @property({ type: Boolean })\n showAll: boolean;\n\n @property({ type: String })\n timezone: string;\n\n @property({ type: String })\n role: string;\n\n @property({ type: Boolean })\n disabled = false;\n\n connectedCallback(): void {\n super.connectedCallback();\n this.handleFieldChanged = this.handleFieldChanged.bind(this);\n }\n\n private isAgent(): boolean {\n return this.role === 'T';\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('data')) {\n if (Object.keys(this.data.fields).length <= MIN_FOR_FILTER) {\n this.showAll = true;\n }\n }\n }\n\n public handleFieldChanged(evt: InputEvent) {\n const field = evt.currentTarget as ContactFieldEditor;\n const value = field.value;\n postJSON('/api/v2/contacts.json?uuid=' + this.data.uuid, {\n fields: { [field.key]: value },\n }).then((response: any) => {\n // returns a single contact with latest updates\n this.setContact(response.json);\n });\n }\n\n public handleToggle(evt: Event) {\n const checkbox = evt.currentTarget as Checkbox;\n this.showAll = checkbox.checked;\n }\n\n public render(): TemplateResult {\n if (this.data) {\n const fieldsToShow = Object.entries(this.data.fields).sort(\n (a: [string, string], b: [string, string]) => {\n const [ak] = a;\n const [bk] = b;\n const fieldA = this.store.getContactField(ak);\n const fieldB = this.store.getContactField(bk);\n\n if (fieldA.featured && !fieldB.featured) {\n return -1;\n }\n\n if (fieldB.featured && !fieldA.featured) {\n return 1;\n }\n\n const priority = fieldB.priority - fieldA.priority;\n if (priority !== 0) {\n return priority;\n }\n\n return ak.localeCompare(bk);\n }\n );\n\n if (fieldsToShow.length == 0) {\n return html`<slot name=\"empty\"></slot>`;\n }\n\n const fields = fieldsToShow.map((entry: [string, string]) => {\n const [k, v] = entry;\n const field = this.store.getContactField(k);\n return html`<temba-contact-field\n class=${getClasses({ set: !!v, unset: !v, featured: field.featured })}\n key=${field.key}\n name=${field.label}\n value=${v}\n type=${field.value_type}\n @change=${this.handleFieldChanged}\n timezone=${this.timezone}\n ?disabled=${(this.isAgent() && field.agent_access === 'view') ||\n this.disabled\n ? true\n : false}\n ></temba-contact-field>`;\n });\n\n return html`\n <div class=${getClasses({ disabled: this.disabled })}>\n <div class=\"fields ${this.showAll ? 'show-all' : ''}\">${fields}</div>\n ${Object.keys(this.data.fields).length >= MIN_FOR_FILTER\n ? html`<div class=\"toggle\">\n <div style=\"flex-grow: 1\"></div>\n <div>\n <temba-checkbox\n ?checked=${this.showAll}\n @change=${this.handleToggle}\n label=\"Show All\"\n ></temba-checkbox>\n </div>\n </div>`\n : null}\n </div>\n `;\n }\n\n return super.render();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ContactFields.js","sourceRoot":"","sources":["../../../src/contacts/ContactFields.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { getClasses, postJSON } from '../utils';\nimport { ContactFieldEditor } from './ContactFieldEditor';\nimport { ContactStoreElement } from './ContactStoreElement';\nimport { Checkbox } from '../checkbox/Checkbox';\n\nconst MIN_FOR_FILTER = 10;\n\nexport class ContactFields extends ContactStoreElement {\n static get styles() {\n return css`\n .field {\n display: flex;\n margin: 0.3em 0.3em;\n box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.15);\n border-radius: 0px;\n align-items: center;\n overflow: hidden;\n }\n\n .show-all .unset,\n .featured {\n display: block !important;\n }\n\n .unset {\n display: none;\n }\n\n .field:hover {\n box-shadow: 1px 1px 6px 2px rgba(0, 0, 0, 0.05),\n 0px 0px 0px 2px var(--color-link-primary);\n cursor: pointer;\n }\n\n .label {\n padding: 0.25em 1em;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n color: #777;\n font-size: 0.9em;\n font-weight: 400;\n box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.1) inset;\n }\n\n .value {\n --icon-color: #ddd;\n max-width: 150px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0.25em 1em;\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n font-size: 0.9em;\n }\n\n .toggle {\n display: flex;\n background: #fff;\n align-items: center;\n margin-bottom: 0.5em;\n }\n\n .disabled .toggle {\n display: none;\n }\n `;\n }\n\n @property({ type: Boolean })\n system: boolean;\n\n @property({ type: Boolean })\n dirty: boolean;\n\n @property({ type: Boolean })\n showAll: boolean;\n\n @property({ type: String })\n timezone: string;\n\n @property({ type: String })\n role: string;\n\n @property({ type: Boolean })\n disabled = false;\n\n connectedCallback(): void {\n super.connectedCallback();\n this.handleFieldChanged = this.handleFieldChanged.bind(this);\n }\n\n private isAgent(): boolean {\n return this.role === 'T';\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('data')) {\n if (Object.keys(this.data.fields).length <= MIN_FOR_FILTER) {\n this.showAll = true;\n }\n }\n }\n\n public handleFieldChanged(evt: InputEvent) {\n const field = evt.currentTarget as ContactFieldEditor;\n const value = field.value;\n postJSON('/api/v2/contacts.json?uuid=' + this.data.uuid, {\n fields: { [field.key]: value },\n }).then((response: any) => {\n field.handleResponse(response);\n\n // returns a single contact with latest updates\n this.setContact(response.json);\n });\n }\n\n public handleToggle(evt: Event) {\n const checkbox = evt.currentTarget as Checkbox;\n this.showAll = checkbox.checked;\n }\n\n public render(): TemplateResult {\n if (this.data) {\n const fieldsToShow = Object.entries(this.data.fields).sort(\n (a: [string, string], b: [string, string]) => {\n const [ak] = a;\n const [bk] = b;\n const fieldA = this.store.getContactField(ak);\n const fieldB = this.store.getContactField(bk);\n\n if (fieldA.type === 'ward') {\n return 1;\n }\n\n if (fieldB.type === 'ward') {\n return -1;\n }\n\n if (\n fieldA.type === 'district' &&\n fieldB.type !== 'ward' &&\n fieldB.type !== 'district'\n ) {\n return 1;\n }\n\n if (\n fieldB.type === 'district' &&\n fieldA.type !== 'ward' &&\n fieldA.type !== 'district'\n ) {\n return -1;\n }\n\n if (\n fieldA.type === 'state' &&\n fieldB.type !== 'ward' &&\n fieldB.type !== 'district' &&\n fieldB.type !== 'state'\n ) {\n return 1;\n }\n\n if (\n fieldB.type === 'state' &&\n fieldA.type !== 'ward' &&\n fieldA.type !== 'district' &&\n fieldA.type !== 'state'\n ) {\n return -1;\n }\n\n if (fieldA.featured && !fieldB.featured) {\n return -1;\n }\n\n if (fieldB.featured && !fieldA.featured) {\n return 1;\n }\n\n const priority = fieldB.priority - fieldA.priority;\n if (priority !== 0) {\n return priority;\n }\n\n return ak.localeCompare(bk);\n }\n );\n\n if (fieldsToShow.length == 0) {\n return html`<slot name=\"empty\"></slot>`;\n }\n\n const fields = fieldsToShow.map((entry: [string, string]) => {\n const [k, v] = entry;\n const field = this.store.getContactField(k);\n return html`<temba-contact-field\n class=${getClasses({ set: !!v, unset: !v, featured: field.featured })}\n key=${field.key}\n name=${field.label}\n value=${v}\n type=${field.value_type}\n @change=${this.handleFieldChanged}\n timezone=${this.timezone}\n ?disabled=${(this.isAgent() && field.agent_access === 'view') ||\n this.disabled ||\n field.value_type === 'ward' ||\n field.value_type === 'district' ||\n field.value_type === 'state'\n ? true\n : false}\n ></temba-contact-field>`;\n });\n\n return html`\n <div class=${getClasses({ disabled: this.disabled })}>\n <div class=\"fields ${this.showAll ? 'show-all' : ''}\">${fields}</div>\n ${Object.keys(this.data.fields).length >= MIN_FOR_FILTER\n ? html`<div class=\"toggle\">\n <div style=\"flex-grow: 1\"></div>\n <div>\n <temba-checkbox\n ?checked=${this.showAll}\n @change=${this.handleToggle}\n label=\"Show All\"\n ></temba-checkbox>\n </div>\n </div>`\n : null}\n </div>\n `;\n }\n\n return super.render();\n }\n}\n"]}
|