@nyaruka/temba-components 0.96.0 → 0.98.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 +13 -0
- package/dist/temba-components.js +169 -147
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/contacts/ContactFieldEditor.js +139 -62
- package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/contacts/ContactFields.js +2 -5
- package/out-tsc/src/contacts/ContactFields.js.map +1 -1
- package/out-tsc/src/options/Options.js +1 -0
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/select/Select.js +69 -68
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/templates/TemplateEditor.js +2 -10
- package/out-tsc/src/templates/TemplateEditor.js.map +1 -1
- package/out-tsc/test/temba-template-editor.test.js +2 -18
- package/out-tsc/test/temba-template-editor.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/select/disabled-multi-selection.png +0 -0
- package/screenshots/truth/select/disabled-selection.png +0 -0
- package/screenshots/truth/select/disabled.png +0 -0
- package/screenshots/truth/select/embedded.png +0 -0
- package/screenshots/truth/select/expression-selected.png +0 -0
- package/screenshots/truth/select/expressions.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/local-options.png +0 -0
- package/screenshots/truth/select/remote-options.png +0 -0
- package/screenshots/truth/select/search-enabled.png +0 -0
- package/screenshots/truth/select/search-multi-no-matches.png +0 -0
- package/screenshots/truth/select/search-selected-focus.png +0 -0
- package/screenshots/truth/select/search-selected.png +0 -0
- package/screenshots/truth/select/search-with-selected.png +0 -0
- package/screenshots/truth/select/searching.png +0 -0
- package/screenshots/truth/select/selected-multi.png +0 -0
- package/screenshots/truth/select/selected-single.png +0 -0
- package/screenshots/truth/select/selection-clearable.png +0 -0
- package/screenshots/truth/select/truncated-selection.png +0 -0
- package/screenshots/truth/select/with-placeholder.png +0 -0
- package/screenshots/truth/select/without-placeholder.png +0 -0
- package/screenshots/truth/templates/default.png +0 -0
- package/screenshots/truth/templates/unapproved.png +0 -0
- package/src/contacts/ContactFieldEditor.ts +150 -62
- package/src/contacts/ContactFields.ts +2 -5
- package/src/options/Options.ts +1 -0
- package/src/select/Select.ts +65 -72
- package/src/templates/TemplateEditor.ts +3 -16
- package/static/api/templates.json +116 -201
- package/test/temba-template-editor.test.ts +2 -22
- package/screenshots/truth/templates/french.png +0 -0
package/src/select/Select.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
executeCompletionQuery
|
|
21
21
|
} from '../completion/helpers';
|
|
22
22
|
import { Store } from '../store/Store';
|
|
23
|
-
import { styleMap } from 'lit-html/directives/style-map.js';
|
|
23
|
+
import { StyleInfo, styleMap } from 'lit-html/directives/style-map.js';
|
|
24
24
|
import { Icon } from '../vectoricon';
|
|
25
25
|
import { msg } from '@lit/localize';
|
|
26
26
|
|
|
@@ -99,6 +99,7 @@ export class Select extends FormElement {
|
|
|
99
99
|
padding-top: 1px;
|
|
100
100
|
box-shadow: var(--widget-box-shadow);
|
|
101
101
|
position: relative;
|
|
102
|
+
min-height: 2.5em;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
temba-icon.select-open:hover,
|
|
@@ -204,57 +205,41 @@ export class Select extends FormElement {
|
|
|
204
205
|
box-shadow: none !important;
|
|
205
206
|
font-family: var(--font-family);
|
|
206
207
|
caret-color: var(--input-caret);
|
|
208
|
+
border: 0px solid purple !important;
|
|
207
209
|
}
|
|
208
210
|
|
|
209
|
-
input
|
|
210
|
-
box-shadow: none !important;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.searchable.no-search-input .input-wrapper {
|
|
214
|
-
flex-grow: inherit;
|
|
211
|
+
.input-wrapper {
|
|
215
212
|
min-width: 1px;
|
|
216
213
|
}
|
|
217
214
|
|
|
218
|
-
.
|
|
219
|
-
flex-grow: 1;
|
|
215
|
+
.input-wrapper:focus-within {
|
|
220
216
|
min-width: 1px;
|
|
221
217
|
}
|
|
222
218
|
|
|
223
|
-
.
|
|
224
|
-
|
|
225
|
-
min-width: 1px;
|
|
219
|
+
.input-wrapper {
|
|
220
|
+
margin-left: 6px;
|
|
226
221
|
}
|
|
227
222
|
|
|
228
|
-
.
|
|
229
|
-
|
|
230
|
-
min-width: 80%;
|
|
231
|
-
height: 100%;
|
|
223
|
+
.multi .input-wrapper {
|
|
224
|
+
margin-left: 2px !important;
|
|
232
225
|
}
|
|
233
226
|
|
|
234
|
-
.
|
|
227
|
+
.input-wrapper:focus-within .placeholder {
|
|
235
228
|
display: none;
|
|
236
229
|
}
|
|
237
230
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
input.searchbox {
|
|
242
|
-
padding: 6px 2px !important;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.searchable.single.no-search-input.empty
|
|
246
|
-
.selected
|
|
247
|
-
.input-wrapper
|
|
248
|
-
input.searchbox {
|
|
249
|
-
padding: 6px 6px !important;
|
|
231
|
+
input:focus {
|
|
232
|
+
box-shadow: none !important;
|
|
233
|
+
flex-grow: 1;
|
|
250
234
|
}
|
|
251
235
|
|
|
252
|
-
.
|
|
253
|
-
|
|
236
|
+
.searchable.search-input .input-wrapper {
|
|
237
|
+
flex-grow: 1;
|
|
238
|
+
min-width: 1px !important;
|
|
254
239
|
}
|
|
255
240
|
|
|
256
|
-
.searchable
|
|
257
|
-
|
|
241
|
+
.searchable.single.search-input .selected .selected-item {
|
|
242
|
+
display: none;
|
|
258
243
|
}
|
|
259
244
|
|
|
260
245
|
.searchable input {
|
|
@@ -264,7 +249,6 @@ export class Select extends FormElement {
|
|
|
264
249
|
color: var(--color-text);
|
|
265
250
|
resize: none;
|
|
266
251
|
box-shadow: none !important;
|
|
267
|
-
flex-grow: 1;
|
|
268
252
|
border: none;
|
|
269
253
|
caret-color: var(--input-caret);
|
|
270
254
|
}
|
|
@@ -274,7 +258,8 @@ export class Select extends FormElement {
|
|
|
274
258
|
}
|
|
275
259
|
|
|
276
260
|
.input-wrapper {
|
|
277
|
-
|
|
261
|
+
display: flex;
|
|
262
|
+
margin-right: 0em;
|
|
278
263
|
}
|
|
279
264
|
|
|
280
265
|
.input-wrapper .searchbox {
|
|
@@ -284,13 +269,6 @@ export class Select extends FormElement {
|
|
|
284
269
|
border: 0px;
|
|
285
270
|
}
|
|
286
271
|
|
|
287
|
-
.searchbox::placeholder {
|
|
288
|
-
color: var(--color-placeholder);
|
|
289
|
-
font-size: 1em;
|
|
290
|
-
line-height: var(--temba-select-selected-line-height);
|
|
291
|
-
padding-left: 1px;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
272
|
.placeholder {
|
|
295
273
|
font-size: var(--temba-select-selected-font-size);
|
|
296
274
|
color: var(--color-placeholder);
|
|
@@ -340,6 +318,9 @@ export class Select extends FormElement {
|
|
|
340
318
|
`;
|
|
341
319
|
}
|
|
342
320
|
|
|
321
|
+
@property({ type: Object })
|
|
322
|
+
inputStyle: StyleInfo = {};
|
|
323
|
+
|
|
343
324
|
@property({ type: Boolean })
|
|
344
325
|
multi = false;
|
|
345
326
|
|
|
@@ -643,7 +624,11 @@ export class Select extends FormElement {
|
|
|
643
624
|
!this.fetching
|
|
644
625
|
) {
|
|
645
626
|
if (this.isPastFetchThreshold()) {
|
|
646
|
-
|
|
627
|
+
if (this.next) {
|
|
628
|
+
this.fetchOptions(null, null, this.next);
|
|
629
|
+
} else {
|
|
630
|
+
this.fetchOptions(this.query, this.page + 1);
|
|
631
|
+
}
|
|
647
632
|
}
|
|
648
633
|
}
|
|
649
634
|
|
|
@@ -909,9 +894,9 @@ export class Select extends FormElement {
|
|
|
909
894
|
}
|
|
910
895
|
}
|
|
911
896
|
|
|
912
|
-
|
|
897
|
+
// TODO: do we still need to support page numbers?
|
|
898
|
+
public fetchOptions(query: string, page = 0, next = null) {
|
|
913
899
|
this.completionOptions = [];
|
|
914
|
-
|
|
915
900
|
if (!this.fetching) {
|
|
916
901
|
this.fetching = true;
|
|
917
902
|
|
|
@@ -936,28 +921,27 @@ export class Select extends FormElement {
|
|
|
936
921
|
|
|
937
922
|
if (this.endpoint) {
|
|
938
923
|
let url = this.endpoint;
|
|
924
|
+
if (next) {
|
|
925
|
+
url = next;
|
|
926
|
+
} else {
|
|
927
|
+
if (query && this.queryParam) {
|
|
928
|
+
if (url.indexOf('?') > -1) {
|
|
929
|
+
url += '&';
|
|
930
|
+
} else {
|
|
931
|
+
url += '?';
|
|
932
|
+
}
|
|
939
933
|
|
|
940
|
-
|
|
941
|
-
if (url.indexOf('?') > -1) {
|
|
942
|
-
url += '&';
|
|
943
|
-
} else {
|
|
944
|
-
url += '?';
|
|
934
|
+
url += this.queryParam + '=' + encodeURIComponent(query);
|
|
945
935
|
}
|
|
946
936
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
url += '?';
|
|
937
|
+
if (page) {
|
|
938
|
+
if (url.indexOf('?') > -1) {
|
|
939
|
+
url += '&';
|
|
940
|
+
} else {
|
|
941
|
+
url += '?';
|
|
942
|
+
}
|
|
943
|
+
url += 'page=' + page;
|
|
955
944
|
}
|
|
956
|
-
url += 'page=' + page;
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
if (this.next) {
|
|
960
|
-
url = this.next;
|
|
961
945
|
}
|
|
962
946
|
|
|
963
947
|
const cache = this.lruCache.get(url);
|
|
@@ -1000,6 +984,7 @@ export class Select extends FormElement {
|
|
|
1000
984
|
}
|
|
1001
985
|
);
|
|
1002
986
|
|
|
987
|
+
this.next = null;
|
|
1003
988
|
const json = response.json;
|
|
1004
989
|
if (json['next']) {
|
|
1005
990
|
this.next = json['next'];
|
|
@@ -1025,9 +1010,7 @@ export class Select extends FormElement {
|
|
|
1025
1010
|
});
|
|
1026
1011
|
}
|
|
1027
1012
|
|
|
1028
|
-
// if (!this.next) {
|
|
1029
1013
|
this.fetching = false;
|
|
1030
|
-
//}
|
|
1031
1014
|
this.page = page;
|
|
1032
1015
|
})
|
|
1033
1016
|
.catch((reason: any) => {
|
|
@@ -1163,8 +1146,9 @@ export class Select extends FormElement {
|
|
|
1163
1146
|
}
|
|
1164
1147
|
|
|
1165
1148
|
private handleContainerClick(event: MouseEvent) {
|
|
1149
|
+
event.stopPropagation();
|
|
1150
|
+
event.preventDefault();
|
|
1166
1151
|
this.focused = true;
|
|
1167
|
-
|
|
1168
1152
|
if ((event.target as any).tagName !== 'INPUT') {
|
|
1169
1153
|
const input = this.shadowRoot.querySelector('input');
|
|
1170
1154
|
if (input) {
|
|
@@ -1175,8 +1159,6 @@ export class Select extends FormElement {
|
|
|
1175
1159
|
|
|
1176
1160
|
if (this.visibleOptions.length > 0) {
|
|
1177
1161
|
this.visibleOptions = [];
|
|
1178
|
-
event.preventDefault();
|
|
1179
|
-
event.stopPropagation();
|
|
1180
1162
|
} else {
|
|
1181
1163
|
this.requestUpdate('input');
|
|
1182
1164
|
}
|
|
@@ -1196,10 +1178,12 @@ export class Select extends FormElement {
|
|
|
1196
1178
|
}
|
|
1197
1179
|
|
|
1198
1180
|
private handleArrowClick(event: MouseEvent): void {
|
|
1181
|
+
event.preventDefault();
|
|
1182
|
+
event.stopPropagation();
|
|
1199
1183
|
if (this.visibleOptions.length > 0) {
|
|
1200
1184
|
this.visibleOptions = [];
|
|
1201
|
-
|
|
1202
|
-
|
|
1185
|
+
} else {
|
|
1186
|
+
this.handleContainerClick(event);
|
|
1203
1187
|
}
|
|
1204
1188
|
}
|
|
1205
1189
|
|
|
@@ -1244,6 +1228,10 @@ export class Select extends FormElement {
|
|
|
1244
1228
|
evt.preventDefault();
|
|
1245
1229
|
evt.stopPropagation();
|
|
1246
1230
|
this.setValues([]);
|
|
1231
|
+
if (this.visibleOptions.length > 0) {
|
|
1232
|
+
this.visibleOptions = [];
|
|
1233
|
+
this.requestUpdate();
|
|
1234
|
+
}
|
|
1247
1235
|
}
|
|
1248
1236
|
|
|
1249
1237
|
public setValues(values: any[]) {
|
|
@@ -1315,19 +1303,21 @@ export class Select extends FormElement {
|
|
|
1315
1303
|
<div class="input-wrapper">
|
|
1316
1304
|
<input
|
|
1317
1305
|
class="searchbox"
|
|
1306
|
+
style=${this.inputStyle ? styleMap(this.inputStyle) : ''}
|
|
1318
1307
|
@input=${this.handleInput}
|
|
1319
1308
|
@keydown=${this.handleKeyDown}
|
|
1320
1309
|
@click=${this.handleClick}
|
|
1321
1310
|
type="text"
|
|
1322
|
-
placeholder=${placeholder}
|
|
1323
1311
|
.value=${this.input}
|
|
1324
1312
|
/>
|
|
1325
1313
|
<div id="anchor" style=${styleMap(anchorStyles)}></div>
|
|
1314
|
+
${placeholderDiv}
|
|
1326
1315
|
</div>
|
|
1327
1316
|
`
|
|
1328
1317
|
: placeholderDiv;
|
|
1329
1318
|
|
|
1330
1319
|
return html`
|
|
1320
|
+
|
|
1331
1321
|
<temba-field
|
|
1332
1322
|
name=${this.name}
|
|
1333
1323
|
.label=${this.label}
|
|
@@ -1339,12 +1329,15 @@ export class Select extends FormElement {
|
|
|
1339
1329
|
>
|
|
1340
1330
|
<slot></slot>
|
|
1341
1331
|
<div class="wrapper-bg">
|
|
1332
|
+
|
|
1342
1333
|
<div
|
|
1343
1334
|
tabindex="0"
|
|
1344
1335
|
class="select-container ${classes}"
|
|
1345
1336
|
@click=${this.handleContainerClick}
|
|
1346
|
-
>
|
|
1337
|
+
>
|
|
1338
|
+
|
|
1347
1339
|
<div class="left-side">
|
|
1340
|
+
<slot name="prefix"></slot>
|
|
1348
1341
|
<div class="selected">
|
|
1349
1342
|
${!this.multi ? input : null}
|
|
1350
1343
|
${this.values.map(
|
|
@@ -24,8 +24,8 @@ interface Template {
|
|
|
24
24
|
created_on: string;
|
|
25
25
|
modified_on: string;
|
|
26
26
|
name: string;
|
|
27
|
-
translations: Translation[];
|
|
28
27
|
uuid: string;
|
|
28
|
+
base_translation: Translation;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export class TemplateEditor extends FormElement {
|
|
@@ -154,9 +154,6 @@ export class TemplateEditor extends FormElement {
|
|
|
154
154
|
@property({ type: Object })
|
|
155
155
|
selectedTemplate: Template;
|
|
156
156
|
|
|
157
|
-
@property({ type: String })
|
|
158
|
-
lang = 'eng-US';
|
|
159
|
-
|
|
160
157
|
// initial variables, not reflected back
|
|
161
158
|
@property({ type: Array })
|
|
162
159
|
variables: string[];
|
|
@@ -192,22 +189,12 @@ export class TemplateEditor extends FormElement {
|
|
|
192
189
|
private handleTemplateChanged(event: CustomEvent) {
|
|
193
190
|
const prev = this.selectedTemplate;
|
|
194
191
|
this.selectedTemplate = (event.target as any).values[0] as Template;
|
|
195
|
-
|
|
196
192
|
if (prev) {
|
|
197
193
|
this.currentVariables = [];
|
|
198
194
|
}
|
|
199
195
|
|
|
200
|
-
const [lang, loc] = this.lang.split('-');
|
|
201
196
|
if (this.selectedTemplate) {
|
|
202
|
-
this.translation = this.selectedTemplate.
|
|
203
|
-
(translation) => {
|
|
204
|
-
return (
|
|
205
|
-
translation.locale === this.lang ||
|
|
206
|
-
(!loc && translation.locale.split('-')[0] === lang)
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
);
|
|
210
|
-
|
|
197
|
+
this.translation = this.selectedTemplate.base_translation;
|
|
211
198
|
if (this.translation) {
|
|
212
199
|
this.variables = new Array(
|
|
213
200
|
(this.translation.variables || []).length
|
|
@@ -405,7 +392,7 @@ export class TemplateEditor extends FormElement {
|
|
|
405
392
|
content = this.renderComponents(this.translation.components);
|
|
406
393
|
} else if (this.selectedTemplate) {
|
|
407
394
|
content = html`<div class="error-message">
|
|
408
|
-
|
|
395
|
+
This template currently has no approved translations.
|
|
409
396
|
</div>`;
|
|
410
397
|
}
|
|
411
398
|
|