@nyaruka/temba-components 0.122.0 → 0.124.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/.github/copilot-instructions.md +181 -0
- package/.github/workflows/build.yml +3 -3
- package/.github/workflows/cla.yml +6 -6
- package/.github/workflows/copilot-setup-steps.yml +86 -0
- package/CHANGELOG.md +44 -0
- package/demo/drag-drop-demo.html +141 -0
- package/demo/index.html +57 -0
- package/demo/test-drag-drop.html +94 -0
- package/dist/locales/es.js +1 -0
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +1 -0
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/pt.js +1 -0
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +366 -247
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/chart/TembaChart.js +81 -14
- package/out-tsc/src/chart/TembaChart.js.map +1 -1
- package/out-tsc/src/fields/FieldManager.js +27 -34
- package/out-tsc/src/fields/FieldManager.js.map +1 -1
- package/out-tsc/src/list/RunList.js +13 -8
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +257 -60
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/locales/es.js +1 -0
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +1 -0
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/pt.js +1 -0
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/omnibox/Omnibox.js +1 -1
- package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
- package/out-tsc/src/options/Options.js +36 -13
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/select/Select.js +226 -43
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/store/AppState.js +3 -3
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/utils/index.js +6 -1
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/vectoricon/VectorIcon.js +2 -1
- package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +5 -2
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/temba-modules.js +0 -2
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/temba-appstate-language.test.js +176 -0
- package/out-tsc/test/temba-appstate-language.test.js.map +1 -0
- package/out-tsc/test/temba-chart.test.js +125 -0
- package/out-tsc/test/temba-chart.test.js.map +1 -1
- package/out-tsc/test/temba-dropdown.test.js +317 -0
- package/out-tsc/test/temba-dropdown.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +273 -0
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor.test.js +244 -0
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -0
- package/out-tsc/test/temba-flow-plumber.test.js +145 -0
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -0
- package/out-tsc/test/temba-flow-render.test.js +171 -0
- package/out-tsc/test/temba-flow-render.test.js.map +1 -0
- package/out-tsc/test/temba-omnibox.test.js +2 -3
- package/out-tsc/test/temba-omnibox.test.js.map +1 -1
- package/out-tsc/test/temba-run-list.test.js +588 -0
- package/out-tsc/test/temba-run-list.test.js.map +1 -0
- package/out-tsc/test/temba-select.test.js +149 -52
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-sortable-list.test.js +91 -15
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/out-tsc/test/temba-toast.test.js +299 -0
- package/out-tsc/test/temba-toast.test.js.map +1 -0
- package/out-tsc/test/temba-utils-index.test.js +1178 -0
- package/out-tsc/test/temba-utils-index.test.js.map +1 -0
- package/out-tsc/test/temba-webchat-lightbox-fix.test.js +42 -0
- package/out-tsc/test/temba-webchat-lightbox-fix.test.js.map +1 -0
- package/out-tsc/test/temba-webchat.test.js +816 -0
- package/out-tsc/test/temba-webchat.test.js.map +1 -0
- package/out-tsc/test/utils.test.js +33 -1
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +6 -8
- package/screenshots/truth/alert/error.png +0 -0
- package/screenshots/truth/alert/info.png +0 -0
- package/screenshots/truth/alert/warning.png +0 -0
- package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
- package/screenshots/truth/checkbox/checked.png +0 -0
- package/screenshots/truth/checkbox/default.png +0 -0
- package/screenshots/truth/colorpicker/default.png +0 -0
- package/screenshots/truth/colorpicker/focused.png +0 -0
- package/screenshots/truth/colorpicker/initialized.png +0 -0
- package/screenshots/truth/colorpicker/selected.png +0 -0
- package/screenshots/truth/compose/attachments-tab.png +0 -0
- package/screenshots/truth/compose/attachments-with-files-focused.png +0 -0
- package/screenshots/truth/compose/attachments-with-files.png +0 -0
- package/screenshots/truth/compose/intial-text.png +0 -0
- package/screenshots/truth/compose/no-counter.png +0 -0
- package/screenshots/truth/compose/wraps-text-and-spaces.png +0 -0
- package/screenshots/truth/compose/wraps-text-and-url.png +0 -0
- package/screenshots/truth/compose/wraps-text-no-spaces.png +0 -0
- package/screenshots/truth/contacts/badges.png +0 -0
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-active-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
- package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
- package/screenshots/truth/content-menu/button-no-items.png +0 -0
- package/screenshots/truth/content-menu/items-and-buttons.png +0 -0
- package/screenshots/truth/counter/summary.png +0 -0
- package/screenshots/truth/counter/text.png +0 -0
- package/screenshots/truth/counter/unicode-variables.png +0 -0
- package/screenshots/truth/counter/unicode.png +0 -0
- package/screenshots/truth/counter/variable.png +0 -0
- package/screenshots/truth/date/date-inline.png +0 -0
- package/screenshots/truth/date/date.png +0 -0
- package/screenshots/truth/date/datetime.png +0 -0
- package/screenshots/truth/date/duration.png +0 -0
- package/screenshots/truth/date/timedate.png +0 -0
- package/screenshots/truth/datepicker/date-truncated-time.png +0 -0
- package/screenshots/truth/datepicker/date.png +0 -0
- package/screenshots/truth/datepicker/initial-timezone.png +0 -0
- package/screenshots/truth/datepicker/updated-keyboard-date.png +0 -0
- package/screenshots/truth/dialog/focused.png +0 -0
- package/screenshots/truth/dropdown/after-blur.png +0 -0
- package/screenshots/truth/dropdown/bottom-edge-collision.png +0 -0
- package/screenshots/truth/dropdown/custom-arrow-size.png +0 -0
- package/screenshots/truth/dropdown/default.png +0 -0
- package/screenshots/truth/dropdown/narrow-toggle.png +0 -0
- package/screenshots/truth/dropdown/no-mask.png +0 -0
- package/screenshots/truth/dropdown/opened.png +0 -0
- package/screenshots/truth/dropdown/positioned.png +0 -0
- package/screenshots/truth/dropdown/right-edge-collision.png +0 -0
- package/screenshots/truth/dropdown/with-mask.png +0 -0
- package/screenshots/truth/flow/editor-basic.png +0 -0
- package/screenshots/truth/label/custom.png +0 -0
- package/screenshots/truth/label/danger.png +0 -0
- package/screenshots/truth/label/dark.png +0 -0
- package/screenshots/truth/label/default-icon.png +0 -0
- package/screenshots/truth/label/no-icon.png +0 -0
- package/screenshots/truth/label/primary.png +0 -0
- package/screenshots/truth/label/secondary.png +0 -0
- package/screenshots/truth/label/shadow.png +0 -0
- package/screenshots/truth/label/tertiary.png +0 -0
- package/screenshots/truth/lightbox/img-zoomed.png +0 -0
- package/screenshots/truth/list/fields-dragging.png +0 -0
- package/screenshots/truth/list/fields-filtered.png +0 -0
- package/screenshots/truth/list/fields-hovered.png +0 -0
- package/screenshots/truth/list/fields.png +0 -0
- package/screenshots/truth/list/items-selected.png +0 -0
- package/screenshots/truth/list/items-updated.png +0 -0
- package/screenshots/truth/list/items.png +0 -0
- package/screenshots/truth/list/sortable-dragging.png +0 -0
- package/screenshots/truth/list/sortable-dropped.png +0 -0
- package/screenshots/truth/list/sortable.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/screenshots/truth/modax/form.png +0 -0
- package/screenshots/truth/modax/simple.png +0 -0
- package/screenshots/truth/omnibox/selected.png +0 -0
- package/screenshots/truth/options/block.png +0 -0
- package/screenshots/truth/run-list/basic.png +0 -0
- package/screenshots/truth/select/disabled-multi-selection.png +0 -0
- package/screenshots/truth/select/disabled-selection.png +0 -0
- package/screenshots/truth/select/disabled.png +0 -0
- package/screenshots/truth/select/embedded.png +0 -0
- package/screenshots/truth/select/empty-options.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/multi-reorder-final.png +0 -0
- package/screenshots/truth/select/multi-reorder-initial.png +0 -0
- package/screenshots/truth/select/multi-with-endpoint.png +0 -0
- package/screenshots/truth/select/multiple-initial-values.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-maxitems-reached.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/static-initial-value.png +0 -0
- package/screenshots/truth/select/static-initial-via-selected.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/slider/custom-min-custom-max-valid-value.png +0 -0
- package/screenshots/truth/slider/custom-min-default-max-no-value.png +0 -0
- package/screenshots/truth/slider/default-min-custom-max-no-value.png +0 -0
- package/screenshots/truth/slider/default-min-default-max-invalid-value.png +0 -0
- package/screenshots/truth/slider/default-min-default-max-valid-value.png +0 -0
- package/screenshots/truth/slider/update-slider-on-value-change.png +0 -0
- package/screenshots/truth/templates/default.png +0 -0
- package/screenshots/truth/templates/unapproved.png +0 -0
- package/screenshots/truth/textinput/input-disabled.png +0 -0
- package/screenshots/truth/textinput/input-focused.png +0 -0
- package/screenshots/truth/textinput/input-form.png +0 -0
- package/screenshots/truth/textinput/input-inserted.png +0 -0
- package/screenshots/truth/textinput/input-placeholder.png +0 -0
- package/screenshots/truth/textinput/input-updated.png +0 -0
- package/screenshots/truth/textinput/input.png +0 -0
- package/screenshots/truth/textinput/textarea-focused.png +0 -0
- package/screenshots/truth/textinput/textarea.png +0 -0
- package/screenshots/truth/tip/bottom.png +0 -0
- package/screenshots/truth/tip/left.png +0 -0
- package/screenshots/truth/tip/right.png +0 -0
- package/screenshots/truth/tip/top.png +0 -0
- package/screenshots/truth/webchat/closed-widget.png +0 -0
- package/screenshots/truth/webchat/connected-state.png +0 -0
- package/screenshots/truth/webchat/connecting-state.png +0 -0
- package/screenshots/truth/webchat/disconnected-state.png +0 -0
- package/screenshots/truth/webchat/opened-widget.png +0 -0
- package/src/chart/TembaChart.ts +86 -15
- package/src/fields/FieldManager.ts +30 -38
- package/src/list/RunList.ts +11 -8
- package/src/list/SortableList.ts +291 -67
- package/src/locales/es.ts +1 -0
- package/src/locales/fr.ts +1 -0
- package/src/locales/pt.ts +1 -0
- package/src/omnibox/Omnibox.ts +1 -1
- package/src/options/Options.ts +38 -13
- package/src/select/Select.ts +245 -47
- package/src/store/AppState.ts +3 -3
- package/src/utils/index.ts +17 -5
- package/src/vectoricon/VectorIcon.ts +2 -1
- package/src/webchat/WebChat.ts +5 -2
- package/temba-modules.ts +0 -2
- package/test/temba-appstate-language.test.ts +218 -0
- package/test/temba-chart.test.ts +161 -1
- package/test/temba-dropdown.test.ts +444 -0
- package/test/temba-flow-editor-node.test.ts +344 -0
- package/test/temba-flow-editor.test.ts +301 -0
- package/test/temba-flow-plumber.test.ts +189 -0
- package/test/temba-flow-render.test.ts +220 -0
- package/test/temba-omnibox.test.ts +2 -3
- package/test/temba-run-list.test.ts +774 -0
- package/test/temba-select.test.ts +206 -78
- package/test/temba-sortable-list.test.ts +108 -15
- package/test/temba-toast.test.ts +386 -0
- package/test/temba-utils-index.test.ts +1547 -0
- package/test/temba-webchat-lightbox-fix.test.ts +57 -0
- package/test/temba-webchat.test.ts +1095 -0
- package/test/utils.test.ts +56 -2
- package/test-assets/list/flow-results.json +17 -0
- package/test-assets/list/runs.json +126 -0
- package/test-assets/style.css +23 -0
- package/web-test-runner.config.mjs +33 -7
- package/xliff/es.xlf +3 -0
- package/xliff/fr.xlf +3 -0
- package/xliff/pt.xlf +3 -0
- package/out-tsc/src/outboxmonitor/OutboxMonitor.js +0 -136
- package/out-tsc/src/outboxmonitor/OutboxMonitor.js.map +0 -1
- package/src/outboxmonitor/OutboxMonitor.ts +0 -148
|
@@ -4,30 +4,57 @@ import { property, state } from 'lit/decorators.js';
|
|
|
4
4
|
import { css, html } from 'lit';
|
|
5
5
|
import { getClasses } from '../utils';
|
|
6
6
|
import { getStore } from '../store/Store';
|
|
7
|
+
// eslint-disable-next-line import/no-named-as-default
|
|
7
8
|
import Chart from 'chart.js/auto';
|
|
8
9
|
import 'chartjs-adapter-luxon';
|
|
9
10
|
const colors = [
|
|
11
|
+
'rgba(54, 162, 235, 0.2)',
|
|
10
12
|
'rgba(255, 159, 64, 0.2)',
|
|
11
13
|
'rgba(75, 192, 192, 0.2)',
|
|
12
|
-
'rgba(54, 162, 235, 0.2)',
|
|
13
14
|
'rgba(153, 102, 255, 0.2)',
|
|
14
15
|
'rgba(255, 205, 86, 0.2)',
|
|
15
|
-
'rgba(255, 99, 132, 0.2)'
|
|
16
|
-
'rgba(201, 203, 207, 0.2)'
|
|
16
|
+
'rgba(255, 99, 132, 0.2)'
|
|
17
17
|
];
|
|
18
18
|
const colorsBorder = [
|
|
19
|
+
'rgb(54, 162, 235)',
|
|
19
20
|
'rgb(255, 159, 64)',
|
|
20
21
|
'rgb(75, 192, 192)',
|
|
21
|
-
'rgb(54, 162, 235)',
|
|
22
22
|
'rgb(153, 102, 255)',
|
|
23
23
|
'rgb(255, 205, 86)',
|
|
24
|
-
'rgb(255, 99, 132)'
|
|
25
|
-
'rgb(201, 203, 207)'
|
|
24
|
+
'rgb(255, 99, 132)'
|
|
26
25
|
];
|
|
27
|
-
const allBorderColor = 'rgb(54, 162, 235)';
|
|
28
|
-
const allBackgroundColor = 'rgba(54, 162, 235, 0.2)';
|
|
29
26
|
const otherBackgroundColor = 'rgba(201, 203, 207, 0.2)';
|
|
30
27
|
const otherBorderColor = 'rgb(201, 203, 207)';
|
|
28
|
+
/**
|
|
29
|
+
* Formats a duration in seconds to a human-readable string showing the two largest units.
|
|
30
|
+
* Examples: 68787 -> "19h 6m", 958000 -> "11d 2h", 3661 -> "1h 1m"
|
|
31
|
+
*/
|
|
32
|
+
export function formatDurationFromSeconds(seconds) {
|
|
33
|
+
if (seconds === 0) {
|
|
34
|
+
return '0s';
|
|
35
|
+
}
|
|
36
|
+
const totalDays = Math.floor(seconds / 86400);
|
|
37
|
+
const remainingAfterDays = seconds % 86400;
|
|
38
|
+
const remainingHours = Math.floor(remainingAfterDays / 3600);
|
|
39
|
+
const remainingAfterHours = remainingAfterDays % 3600;
|
|
40
|
+
const remainingMinutes = Math.floor(remainingAfterHours / 60);
|
|
41
|
+
const remainingSeconds = remainingAfterHours % 60;
|
|
42
|
+
const units = [];
|
|
43
|
+
if (totalDays > 0) {
|
|
44
|
+
units.push(`${totalDays}d`);
|
|
45
|
+
}
|
|
46
|
+
if (remainingHours > 0) {
|
|
47
|
+
units.push(`${remainingHours}h`);
|
|
48
|
+
}
|
|
49
|
+
if (remainingMinutes > 0 && units.length < 2) {
|
|
50
|
+
units.push(`${remainingMinutes}m`);
|
|
51
|
+
}
|
|
52
|
+
if (remainingSeconds > 0 && units.length < 2) {
|
|
53
|
+
units.push(`${remainingSeconds}s`);
|
|
54
|
+
}
|
|
55
|
+
// Return the first two most significant units
|
|
56
|
+
return units.slice(0, 2).join(' ');
|
|
57
|
+
}
|
|
31
58
|
export class TembaChart extends RapidElement {
|
|
32
59
|
static get styles() {
|
|
33
60
|
return css `
|
|
@@ -85,7 +112,11 @@ export class TembaChart extends RapidElement {
|
|
|
85
112
|
this.maxSplits = 2;
|
|
86
113
|
this.splits = [];
|
|
87
114
|
this.dataname = 'Counts';
|
|
115
|
+
this.single = false;
|
|
116
|
+
this.legend = false;
|
|
88
117
|
this.config = false;
|
|
118
|
+
this.formatDuration = false;
|
|
119
|
+
this.colorIndex = 0;
|
|
89
120
|
this.showConfig = false;
|
|
90
121
|
}
|
|
91
122
|
firstUpdated(changes) {
|
|
@@ -131,18 +162,18 @@ export class TembaChart extends RapidElement {
|
|
|
131
162
|
else {
|
|
132
163
|
datasets.push({
|
|
133
164
|
...dataset,
|
|
134
|
-
backgroundColor: colors[datasets.length % colors.length],
|
|
135
|
-
borderColor: colorsBorder[datasets.length % colorsBorder.length],
|
|
165
|
+
backgroundColor: colors[(datasets.length + this.colorIndex) % colors.length],
|
|
166
|
+
borderColor: colorsBorder[(datasets.length + this.colorIndex) % colorsBorder.length],
|
|
136
167
|
borderWidth: 1
|
|
137
168
|
});
|
|
138
169
|
}
|
|
139
170
|
}
|
|
140
171
|
if (datasets.length === 0) {
|
|
141
172
|
datasets.push({
|
|
142
|
-
label: `All ${this.dataname}`,
|
|
173
|
+
label: this.single ? this.dataname : `All ${this.dataname}`,
|
|
143
174
|
data: sums,
|
|
144
|
-
backgroundColor:
|
|
145
|
-
borderColor:
|
|
175
|
+
backgroundColor: colors[this.colorIndex % colors.length],
|
|
176
|
+
borderColor: colorsBorder[this.colorIndex % colorsBorder.length],
|
|
146
177
|
borderWidth: 1
|
|
147
178
|
});
|
|
148
179
|
}
|
|
@@ -174,6 +205,23 @@ export class TembaChart extends RapidElement {
|
|
|
174
205
|
datasets: this.datasets
|
|
175
206
|
},
|
|
176
207
|
options: {
|
|
208
|
+
plugins: {
|
|
209
|
+
legend: {
|
|
210
|
+
display: this.legend
|
|
211
|
+
},
|
|
212
|
+
...(this.formatDuration && {
|
|
213
|
+
tooltip: {
|
|
214
|
+
callbacks: {
|
|
215
|
+
label: (context) => {
|
|
216
|
+
const label = context.dataset.label || '';
|
|
217
|
+
const value = context.parsed.y;
|
|
218
|
+
const formattedValue = formatDurationFromSeconds(value);
|
|
219
|
+
return `${label}: ${formattedValue}`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
},
|
|
177
225
|
responsive: true,
|
|
178
226
|
maintainAspectRatio: false,
|
|
179
227
|
animation: {
|
|
@@ -192,7 +240,14 @@ export class TembaChart extends RapidElement {
|
|
|
192
240
|
scales: {
|
|
193
241
|
y: {
|
|
194
242
|
min: 0,
|
|
195
|
-
stacked: true
|
|
243
|
+
stacked: true,
|
|
244
|
+
...(this.formatDuration && {
|
|
245
|
+
ticks: {
|
|
246
|
+
callback: (value) => {
|
|
247
|
+
return formatDurationFromSeconds(value);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
})
|
|
196
251
|
},
|
|
197
252
|
x: {
|
|
198
253
|
type: 'time',
|
|
@@ -301,9 +356,21 @@ __decorate([
|
|
|
301
356
|
__decorate([
|
|
302
357
|
property({ type: String })
|
|
303
358
|
], TembaChart.prototype, "dataname", void 0);
|
|
359
|
+
__decorate([
|
|
360
|
+
property({ type: Boolean })
|
|
361
|
+
], TembaChart.prototype, "single", void 0);
|
|
362
|
+
__decorate([
|
|
363
|
+
property({ type: Boolean })
|
|
364
|
+
], TembaChart.prototype, "legend", void 0);
|
|
304
365
|
__decorate([
|
|
305
366
|
property({ type: Boolean })
|
|
306
367
|
], TembaChart.prototype, "config", void 0);
|
|
368
|
+
__decorate([
|
|
369
|
+
property({ type: Boolean })
|
|
370
|
+
], TembaChart.prototype, "formatDuration", void 0);
|
|
371
|
+
__decorate([
|
|
372
|
+
property({ type: Number })
|
|
373
|
+
], TembaChart.prototype, "colorIndex", void 0);
|
|
307
374
|
__decorate([
|
|
308
375
|
state()
|
|
309
376
|
], TembaChart.prototype, "showConfig", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TembaChart.js","sourceRoot":"","sources":["../../../src/chart/TembaChart.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAGlE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,KAAoB,MAAM,eAAe,CAAC;AACjD,OAAO,uBAAuB,CAAC;AAE/B,MAAM,MAAM,GAAG;IACb,yBAAyB;IACzB,yBAAyB;IACzB,yBAAyB;IACzB,0BAA0B;IAC1B,yBAAyB;IACzB,yBAAyB;IACzB,0BAA0B;CAC3B,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,mBAAmB;IACnB,mBAAmB;IACnB,mBAAmB;IACnB,oBAAoB;IACpB,mBAAmB;IACnB,mBAAmB;IACnB,oBAAoB;CACrB,CAAC;AAEF,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAC3C,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAErD,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AACxD,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAO9C,MAAM,OAAO,UAAW,SAAQ,YAAY;IAuC1C,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4CT,CAAC;IACJ,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QAtFV,cAAS,GAAc,KAAK,CAAC;QAM7B,WAAM,GAAW,EAAE,CAAC;QAGpB,UAAK,GAAY,KAAK,CAAC;QAMvB,aAAQ,GAAwC,EAAE,CAAC;QAGnD,cAAS,GAAW,CAAC,CAAC;QAGtB,WAAM,GAAa,EAAE,CAAC;QAGtB,aAAQ,GAAG,QAAQ,CAAC;QAGpB,WAAM,GAAY,KAAK,CAAC;QAGxB,eAAU,GAAY,KAAK,CAAC;IAyD5B,CAAC;IAES,YAAY,CACpB,OAA0D;QAE1D,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAES,OAAO,CACf,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YACzB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACvC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YACjC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,eAAe;QACrB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,EAAE,CAAC;YACpB,8DAA8D;YAC9D,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACzC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;oBAC/D,kBAAkB;oBAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC7C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;4BAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAC5B,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAC7B,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,QAAQ,CAAC,IAAI,CAAC;wBACZ,GAAG,OAAO;wBACV,eAAe,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;wBACxD,WAAW,EAAE,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;wBAChE,WAAW,EAAE,CAAC;qBACf,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,QAAQ,CAAC,IAAI,CAAC;oBACZ,KAAK,EAAE,OAAO,IAAI,CAAC,QAAQ,EAAE;oBAC7B,IAAI,EAAE,IAAI;oBACV,eAAe,EAAE,kBAAkB;oBACnC,WAAW,EAAE,cAAc;oBAC3B,WAAW,EAAE,CAAC;iBACf,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC;oBACZ,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,IAAI;oBACV,eAAe,EAAE,oBAAoB;oBACrC,WAAW,EAAE,gBAAgB;oBAC7B,WAAW,EAAE,CAAC;iBACf,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,CAAC;IACH,CAAC;IAEM,WAAW;;QAChB,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,MAAM,IAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;gBACzC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG;oBAChB,IAAI,EAAE,IAAI,CAAC,SAAS;oBACpB,IAAI,EAAE;wBACJ,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;wBACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;qBACxB;oBACD,OAAO,EAAE;wBACP,UAAU,EAAE,IAAI;wBAChB,mBAAmB,EAAE,KAAK;wBAC1B,SAAS,EAAE;4BACT,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE;4BAChB,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE;yBACjB;wBACD,UAAU,EAAE;4BACV,OAAO,EAAE;gCACP,QAAQ,EAAE,IAAI;gCACd,MAAM,EAAE,QAAQ;gCAChB,IAAI,EAAE,CAAC;gCACP,EAAE,EAAE,CAAC;gCACL,IAAI,EAAE,IAAI;6BACX;yBACF;wBACD,MAAM,EAAE;4BACN,CAAC,EAAE;gCACD,GAAG,EAAE,CAAC;gCACN,OAAO,EAAE,IAAI;6BACd;4BACD,CAAC,EAAE;gCACD,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE;oCACJ,IAAI,EAAE,KAAK;oCACX,aAAa,EAAE,KAAK,EAAE,2BAA2B;oCACjD,cAAc,EAAE;wCACd,GAAG,EAAE,QAAQ;qCACd;iCACF;gCACD,IAAI,EAAE;oCACJ,OAAO,EAAE,KAAK;iCACf;gCACD,OAAO,EAAE,IAAI;6BACd;yBACF;qBACF;iBACF,CAAC;gBACF,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAgB,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,CAAQ;QAClC,MAAM,MAAM,GAAG,CAAC,CAAC,MAA8B,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACzC,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAES,MAAM;;QACd,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,MAAM;YACX,CAAC,CAAC,IAAI,CAAA,4BAA4B,IAAI,CAAC,MAAM,QAAQ;YACrD,CAAC,CAAC,IAAI;;QAEN,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI;YACxB,CAAC,CAAC,IAAI,CAAA;;uBAES,UAAU,CAAC;gBAClB,eAAe,EAAE,IAAI;gBACrB,IAAI,EAAE,IAAI,CAAC,UAAU,IAAI,CAAA,MAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,QAAQ,0CAAE,MAAM,IAAG,CAAC;aACzD,CAAC;;;;;;;0BAOU,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;;;2BAGrC,IAAI,CAAC,kBAAkB;;;;WAIvC;YACH,CAAC,CAAC,IAAI;;mBAEK,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;;;gCAGtC,IAAI,CAAC,QAAQ;oBACzB,IAAI,CAAC,SAAS,CACtB,MAAA,IAAI,CAAC,IAAI,0CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,EAAE,OAAO,CAAC,KAAK;YACnB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC,CACJ;oBACS,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBAC/C,IAAI,CAAC,mBAAmB;;;;;WAKjC,CAAC;IACV,CAAC;CACF;AA3RC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6CACE;AAG7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCACf;AAGZ;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACP;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;yCACL;AAGvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wCACN;AAGrB;IADC,KAAK,EAAE;4CAC2C;AAGnD;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6CACL;AAGtB;IADC,KAAK,EAAE;0CACc;AAGtB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACP;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;0CACJ;AAGxB;IADC,KAAK,EAAE;8CACoB","sourcesContent":["import { RapidElement } from '../RapidElement';\nimport { property, state } from 'lit/decorators.js';\nimport { css, html, PropertyValueMap, TemplateResult } from 'lit';\n\nimport { Select, SelectOption } from '../select/Select';\nimport { getClasses } from '../utils';\nimport { getStore } from '../store/Store';\n\nimport Chart, { ChartType } from 'chart.js/auto';\nimport 'chartjs-adapter-luxon';\n\nconst colors = [\n 'rgba(255, 159, 64, 0.2)',\n 'rgba(75, 192, 192, 0.2)',\n 'rgba(54, 162, 235, 0.2)',\n 'rgba(153, 102, 255, 0.2)',\n 'rgba(255, 205, 86, 0.2)',\n 'rgba(255, 99, 132, 0.2)',\n 'rgba(201, 203, 207, 0.2)'\n];\n\nconst colorsBorder = [\n 'rgb(255, 159, 64)',\n 'rgb(75, 192, 192)',\n 'rgb(54, 162, 235)',\n 'rgb(153, 102, 255)',\n 'rgb(255, 205, 86)',\n 'rgb(255, 99, 132)',\n 'rgb(201, 203, 207)'\n];\n\nconst allBorderColor = 'rgb(54, 162, 235)';\nconst allBackgroundColor = 'rgba(54, 162, 235, 0.2)';\n\nconst otherBackgroundColor = 'rgba(201, 203, 207, 0.2)';\nconst otherBorderColor = 'rgb(201, 203, 207)';\n\nexport interface RapidChartData {\n labels: string[];\n datasets: { label: string; data: number[] }[];\n}\n\nexport class TembaChart extends RapidElement {\n @property({ type: String })\n chartType: ChartType = 'bar';\n\n @property({ type: String })\n url: string;\n\n @property({ type: String })\n header: string = '';\n\n @property({ type: Boolean })\n other: boolean = false;\n\n @property({ type: Object })\n data: RapidChartData;\n\n @state()\n datasets: { label: string; data: number[] }[] = [];\n\n @property({ type: Number })\n maxSplits: number = 2;\n\n @state()\n splits: string[] = [];\n\n @property({ type: String })\n dataname = 'Counts';\n\n @property({ type: Boolean })\n config: boolean = false;\n\n @state()\n showConfig: boolean = false;\n\n chart: Chart;\n shadowRootDiv: HTMLDivElement;\n canvas: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D;\n\n static get styles() {\n return css`\n .chart-title {\n font-size: 1.2em;\n font-weight: 600;\n text-align: center;\n }\n\n temba-select {\n display: block;\n }\n\n .config-toggle {\n margin-top: -2.5em;\n margin-right: -0.5em;\n color: #bbb;\n display: none;\n }\n\n .config-toggle:hover {\n color: #666;\n }\n\n .config-toggle.show {\n color: #666;\n display: block;\n }\n\n .config {\n max-height: 0px;\n margin: 2em 0.5em;\n padding: 0em 1em;\n border-radius: var(--curvature);\n border: 1px solid transparent;\n background: transparent;\n overflow: hidden;\n transition: all 0.2s ease-in-out;\n }\n\n .config.show {\n padding: 1em;\n max-height: 50px;\n background: rgba(0, 0, 0, 0.02);\n border: 1px solid rgba(0, 0, 0, 0.09);\n }\n `;\n }\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n const wrapper = this.shadowRoot.querySelector('#canvas-wrapper');\n this.canvas = document.createElement('canvas');\n this.canvas.setAttribute('height', '300px');\n wrapper.appendChild(this.canvas);\n this.ctx = this.canvas.getContext('2d');\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('data') || changes.has('splits')) {\n this.calculateSplits();\n }\n\n if (changes.has('datasets')) {\n this.updateChart();\n }\n\n if (changes.has('url')) {\n const store = getStore();\n store.getUrl(this.url).then((response) => {\n this.data = response.json.data;\n });\n }\n }\n\n private calculateSplits() {\n if (this.data) {\n const datasets = [];\n // keep a running list of values that is the sum at each index\n const sums = [];\n for (const dataset of this.data.datasets) {\n if (this.splits.find((s) => s === dataset.label) === undefined) {\n // update our sums\n for (let i = 0; i < dataset.data.length; i++) {\n if (sums[i] === undefined) {\n sums[i] = dataset.data[i];\n } else {\n sums[i] += dataset.data[i];\n }\n }\n } else {\n datasets.push({\n ...dataset,\n backgroundColor: colors[datasets.length % colors.length],\n borderColor: colorsBorder[datasets.length % colorsBorder.length],\n borderWidth: 1\n });\n }\n }\n\n if (datasets.length === 0) {\n datasets.push({\n label: `All ${this.dataname}`,\n data: sums,\n backgroundColor: allBackgroundColor,\n borderColor: allBorderColor,\n borderWidth: 1\n });\n } else {\n datasets.push({\n label: 'Other',\n data: sums,\n backgroundColor: otherBackgroundColor,\n borderColor: otherBorderColor,\n borderWidth: 1\n });\n }\n this.datasets = datasets;\n }\n }\n\n public updateChart(): void {\n if (this.datasets?.length > 0) {\n if (this.chart) {\n this.chart.data.labels = this.data.labels;\n this.chart.data.datasets = this.datasets;\n this.chart.update();\n } else {\n const chartData = {\n type: this.chartType,\n data: {\n labels: this.data.labels,\n datasets: this.datasets\n },\n options: {\n responsive: true,\n maintainAspectRatio: false,\n animation: {\n x: { from: 500 },\n y: { from: 500 }\n },\n animations: {\n tension: {\n duration: 1000,\n easing: 'linear',\n from: 1,\n to: 0,\n loop: true\n }\n },\n scales: {\n y: {\n min: 0,\n stacked: true\n },\n x: {\n type: 'time',\n time: {\n unit: 'day',\n tooltipFormat: 'DDD', // Luxon for 'Feb 16, 2025'\n displayFormats: {\n day: 'MMM dd'\n }\n },\n grid: {\n display: false\n },\n stacked: true\n }\n }\n }\n };\n this.chart = new Chart(this.ctx, chartData as any);\n }\n }\n }\n\n private handleSplitsChanged(e: Event) {\n const select = e.target as Select<SelectOption>;\n this.splits = select.values.map((option) => {\n return option.value;\n });\n }\n\n private handleToggleConfig() {\n this.showConfig = !this.showConfig;\n if (!this.showConfig) {\n this.splits = [];\n }\n }\n\n protected render(): TemplateResult {\n return html`<div>\n ${this.header\n ? html`<div class=\"chart-title\">${this.header}</div>`\n : null}\n <div id=\"canvas-wrapper\"></div>\n ${this.config && this.data\n ? html`\n <div\n class=\"${getClasses({\n 'config-toggle': true,\n show: this.showConfig && this.data?.datasets?.length > 1\n })}\"\n style=\"display: flex; flex-direction: row; align-items: center; justify-content: space-between;\"\n >\n <div></div>\n <div>\n <temba-icon\n animateChange=\"spin\"\n name=\"${this.showConfig ? 'close' : 'settings'}\"\n clickable\n size=\"1.5\"\n @click=${this.handleToggleConfig}\n ></temba-icon>\n </div>\n </div>\n `\n : null}\n\n <div class=${getClasses({ config: true, show: this.showConfig })}>\n <temba-select\n multi\n placeholder=\"Select ${this.dataname}\"\n options=${JSON.stringify(\n this.data?.datasets.map((dataset) => ({\n name: dataset.label,\n value: dataset.label\n }))\n )}\n .values=${this.splits.map((s) => ({ name: s, value: s }))}\n @change=${this.handleSplitsChanged}\n >\n </temba-select>\n <div></div>\n </div>\n </div>`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TembaChart.js","sourceRoot":"","sources":["../../../src/chart/TembaChart.ts"],"names":[],"mappings":"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","sourcesContent":["import { RapidElement } from '../RapidElement';\nimport { property, state } from 'lit/decorators.js';\nimport { css, html, PropertyValueMap, TemplateResult } from 'lit';\n\nimport { Select, SelectOption } from '../select/Select';\nimport { getClasses } from '../utils';\nimport { getStore } from '../store/Store';\n\n// eslint-disable-next-line import/no-named-as-default\nimport Chart, { ChartType } from 'chart.js/auto';\nimport 'chartjs-adapter-luxon';\n\nconst colors = [\n 'rgba(54, 162, 235, 0.2)',\n 'rgba(255, 159, 64, 0.2)',\n 'rgba(75, 192, 192, 0.2)',\n 'rgba(153, 102, 255, 0.2)',\n 'rgba(255, 205, 86, 0.2)',\n 'rgba(255, 99, 132, 0.2)'\n];\n\nconst colorsBorder = [\n 'rgb(54, 162, 235)',\n 'rgb(255, 159, 64)',\n 'rgb(75, 192, 192)',\n 'rgb(153, 102, 255)',\n 'rgb(255, 205, 86)',\n 'rgb(255, 99, 132)'\n];\n\nconst otherBackgroundColor = 'rgba(201, 203, 207, 0.2)';\nconst otherBorderColor = 'rgb(201, 203, 207)';\n\n/**\n * Formats a duration in seconds to a human-readable string showing the two largest units.\n * Examples: 68787 -> \"19h 6m\", 958000 -> \"11d 2h\", 3661 -> \"1h 1m\"\n */\nexport function formatDurationFromSeconds(seconds: number): string {\n if (seconds === 0) {\n return '0s';\n }\n\n const totalDays = Math.floor(seconds / 86400);\n const remainingAfterDays = seconds % 86400;\n const remainingHours = Math.floor(remainingAfterDays / 3600);\n const remainingAfterHours = remainingAfterDays % 3600;\n const remainingMinutes = Math.floor(remainingAfterHours / 60);\n const remainingSeconds = remainingAfterHours % 60;\n\n const units = [];\n\n if (totalDays > 0) {\n units.push(`${totalDays}d`);\n }\n if (remainingHours > 0) {\n units.push(`${remainingHours}h`);\n }\n if (remainingMinutes > 0 && units.length < 2) {\n units.push(`${remainingMinutes}m`);\n }\n if (remainingSeconds > 0 && units.length < 2) {\n units.push(`${remainingSeconds}s`);\n }\n\n // Return the first two most significant units\n return units.slice(0, 2).join(' ');\n}\n\nexport interface RapidChartData {\n labels: string[];\n datasets: { label: string; data: number[] }[];\n}\n\nexport class TembaChart extends RapidElement {\n @property({ type: String })\n chartType: ChartType = 'bar';\n\n @property({ type: String })\n url: string;\n\n @property({ type: String })\n header: string = '';\n\n @property({ type: Boolean })\n other: boolean = false;\n\n @property({ type: Object })\n data: RapidChartData;\n\n @state()\n datasets: { label: string; data: number[] }[] = [];\n\n @property({ type: Number })\n maxSplits: number = 2;\n\n @state()\n splits: string[] = [];\n\n @property({ type: String })\n dataname = 'Counts';\n\n @property({ type: Boolean })\n single: boolean = false;\n\n @property({ type: Boolean })\n legend: boolean = false;\n\n @property({ type: Boolean })\n config: boolean = false;\n\n @property({ type: Boolean })\n formatDuration: boolean = false;\n\n @property({ type: Number })\n colorIndex: number = 0;\n\n @state()\n showConfig: boolean = false;\n\n chart: Chart;\n shadowRootDiv: HTMLDivElement;\n canvas: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D;\n\n static get styles() {\n return css`\n .chart-title {\n font-size: 1.2em;\n font-weight: 600;\n text-align: center;\n }\n\n temba-select {\n display: block;\n }\n\n .config-toggle {\n margin-top: -2.5em;\n margin-right: -0.5em;\n color: #bbb;\n display: none;\n }\n\n .config-toggle:hover {\n color: #666;\n }\n\n .config-toggle.show {\n color: #666;\n display: block;\n }\n\n .config {\n max-height: 0px;\n margin: 2em 0.5em;\n padding: 0em 1em;\n border-radius: var(--curvature);\n border: 1px solid transparent;\n background: transparent;\n overflow: hidden;\n transition: all 0.2s ease-in-out;\n }\n\n .config.show {\n padding: 1em;\n max-height: 50px;\n background: rgba(0, 0, 0, 0.02);\n border: 1px solid rgba(0, 0, 0, 0.09);\n }\n `;\n }\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n const wrapper = this.shadowRoot.querySelector('#canvas-wrapper');\n this.canvas = document.createElement('canvas');\n this.canvas.setAttribute('height', '300px');\n wrapper.appendChild(this.canvas);\n this.ctx = this.canvas.getContext('2d');\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('data') || changes.has('splits')) {\n this.calculateSplits();\n }\n\n if (changes.has('datasets')) {\n this.updateChart();\n }\n\n if (changes.has('url')) {\n const store = getStore();\n store.getUrl(this.url).then((response) => {\n this.data = response.json.data;\n });\n }\n }\n\n private calculateSplits() {\n if (this.data) {\n const datasets = [];\n // keep a running list of values that is the sum at each index\n const sums = [];\n for (const dataset of this.data.datasets) {\n if (this.splits.find((s) => s === dataset.label) === undefined) {\n // update our sums\n for (let i = 0; i < dataset.data.length; i++) {\n if (sums[i] === undefined) {\n sums[i] = dataset.data[i];\n } else {\n sums[i] += dataset.data[i];\n }\n }\n } else {\n datasets.push({\n ...dataset,\n backgroundColor:\n colors[(datasets.length + this.colorIndex) % colors.length],\n borderColor:\n colorsBorder[\n (datasets.length + this.colorIndex) % colorsBorder.length\n ],\n borderWidth: 1\n });\n }\n }\n\n if (datasets.length === 0) {\n datasets.push({\n label: this.single ? this.dataname : `All ${this.dataname}`,\n data: sums,\n backgroundColor: colors[this.colorIndex % colors.length],\n borderColor: colorsBorder[this.colorIndex % colorsBorder.length],\n borderWidth: 1\n });\n } else {\n datasets.push({\n label: 'Other',\n data: sums,\n backgroundColor: otherBackgroundColor,\n borderColor: otherBorderColor,\n borderWidth: 1\n });\n }\n this.datasets = datasets;\n }\n }\n\n public updateChart(): void {\n if (this.datasets?.length > 0) {\n if (this.chart) {\n this.chart.data.labels = this.data.labels;\n this.chart.data.datasets = this.datasets;\n this.chart.update();\n } else {\n const chartData = {\n type: this.chartType,\n data: {\n labels: this.data.labels,\n datasets: this.datasets\n },\n options: {\n plugins: {\n legend: {\n display: this.legend\n },\n ...(this.formatDuration && {\n tooltip: {\n callbacks: {\n label: (context: any) => {\n const label = context.dataset.label || '';\n const value = context.parsed.y;\n const formattedValue = formatDurationFromSeconds(value);\n return `${label}: ${formattedValue}`;\n }\n }\n }\n })\n },\n responsive: true,\n maintainAspectRatio: false,\n animation: {\n x: { from: 500 },\n y: { from: 500 }\n },\n animations: {\n tension: {\n duration: 1000,\n easing: 'linear',\n from: 1,\n to: 0,\n loop: true\n }\n },\n scales: {\n y: {\n min: 0,\n stacked: true,\n ...(this.formatDuration && {\n ticks: {\n callback: (value: any) => {\n return formatDurationFromSeconds(value);\n }\n }\n })\n },\n x: {\n type: 'time',\n time: {\n unit: 'day',\n tooltipFormat: 'DDD', // Luxon for 'Feb 16, 2025'\n displayFormats: {\n day: 'MMM dd'\n }\n },\n grid: {\n display: false\n },\n stacked: true\n }\n }\n }\n };\n this.chart = new Chart(this.ctx, chartData as any);\n }\n }\n }\n\n private handleSplitsChanged(e: Event) {\n const select = e.target as Select<SelectOption>;\n this.splits = select.values.map((option) => {\n return option.value;\n });\n }\n\n private handleToggleConfig() {\n this.showConfig = !this.showConfig;\n if (!this.showConfig) {\n this.splits = [];\n }\n }\n\n protected render(): TemplateResult {\n return html`<div>\n ${this.header\n ? html`<div class=\"chart-title\">${this.header}</div>`\n : null}\n <div id=\"canvas-wrapper\"></div>\n ${this.config && this.data\n ? html`\n <div\n class=\"${getClasses({\n 'config-toggle': true,\n show: this.showConfig && this.data?.datasets?.length > 1\n })}\"\n style=\"display: flex; flex-direction: row; align-items: center; justify-content: space-between;\"\n >\n <div></div>\n <div>\n <temba-icon\n animateChange=\"spin\"\n name=\"${this.showConfig ? 'close' : 'settings'}\"\n clickable\n size=\"1.5\"\n @click=${this.handleToggleConfig}\n ></temba-icon>\n </div>\n </div>\n `\n : null}\n\n <div class=${getClasses({ config: true, show: this.showConfig })}>\n <temba-select\n multi\n placeholder=\"Select ${this.dataname}\"\n options=${JSON.stringify(\n this.data?.datasets.map((dataset) => ({\n name: dataset.label,\n value: dataset.label\n }))\n )}\n .values=${this.splits.map((s) => ({ name: s, value: s }))}\n @change=${this.handleSplitsChanged}\n >\n </temba-select>\n <div></div>\n </div>\n </div>`;\n }\n}\n"]}
|
|
@@ -120,7 +120,7 @@ export class FieldManager extends EndpointMonitorElement {
|
|
|
120
120
|
border-radius: var(--curvature);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
.featured temba-sortable-list .field:hover {
|
|
123
|
+
.featured:not(.dragging) temba-sortable-list .field:hover {
|
|
124
124
|
cursor: move;
|
|
125
125
|
border-color: #e6e6e6;
|
|
126
126
|
background: #fcfcfc;
|
|
@@ -163,30 +163,26 @@ export class FieldManager extends EndpointMonitorElement {
|
|
|
163
163
|
this.filterFields();
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
handleSaveOrder(event) {
|
|
167
|
-
const list = event.currentTarget;
|
|
168
|
-
postJSON(this.priorityEndpoint, list
|
|
169
|
-
.getIds()
|
|
170
|
-
.reverse()
|
|
171
|
-
.reduce((map, key, idx) => {
|
|
172
|
-
map[key] = idx;
|
|
173
|
-
return map;
|
|
174
|
-
}, {})).then(() => {
|
|
175
|
-
this.store.refreshFields();
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
166
|
handleOrderChanged(event) {
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
this.featuredFields
|
|
183
|
-
this.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
167
|
+
// Apply the reordering immediately - the SortableList now provides accurate indexes
|
|
168
|
+
const [fromIdx, toIdx] = event.detail.swap;
|
|
169
|
+
const temp = this.featuredFields[fromIdx];
|
|
170
|
+
this.featuredFields.splice(fromIdx, 1);
|
|
171
|
+
this.featuredFields.splice(toIdx, 0, temp);
|
|
172
|
+
this.requestUpdate();
|
|
173
|
+
// Save the new order to the server
|
|
174
|
+
const list = event.currentTarget;
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
postJSON(this.priorityEndpoint, list
|
|
177
|
+
.getIds()
|
|
178
|
+
.reverse()
|
|
179
|
+
.reduce((map, key, idx) => {
|
|
180
|
+
map[key] = idx;
|
|
181
|
+
return map;
|
|
182
|
+
}, {})).then(() => {
|
|
183
|
+
this.store.refreshFields();
|
|
184
|
+
});
|
|
185
|
+
}, 0);
|
|
190
186
|
}
|
|
191
187
|
handleFieldAction(event) {
|
|
192
188
|
const ele = event.target;
|
|
@@ -210,10 +206,13 @@ export class FieldManager extends EndpointMonitorElement {
|
|
|
210
206
|
display: flex;
|
|
211
207
|
flex-direction: row;
|
|
212
208
|
align-items: center;
|
|
213
|
-
padding: 0.25em 1em;
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
209
|
+
padding: 0.25em 1em;"
|
|
210
|
+
@click=${(e) => {
|
|
211
|
+
const ele = e.currentTarget;
|
|
212
|
+
const key = ele.dataset.key;
|
|
213
|
+
const action = ele.dataset.action;
|
|
214
|
+
this.fireCustomEvent(CustomEventType.Selection, { key, action });
|
|
215
|
+
}}
|
|
217
216
|
>
|
|
218
217
|
<div
|
|
219
218
|
style="display: flex; min-width: 200px; width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 2em"
|
|
@@ -285,10 +284,7 @@ export class FieldManager extends EndpointMonitorElement {
|
|
|
285
284
|
`
|
|
286
285
|
: html `
|
|
287
286
|
<temba-sortable-list
|
|
288
|
-
@change=${this.handleSaveOrder}
|
|
289
287
|
@temba-order-changed=${this.handleOrderChanged}
|
|
290
|
-
@temba-drag-start=${this.handleDragStart}
|
|
291
|
-
@temba-drag-stop=${this.handleDragStop}
|
|
292
288
|
>
|
|
293
289
|
${this.featuredFields.map((field) => this.renderField(field))}
|
|
294
290
|
</temba-sortable-list>
|
|
@@ -318,9 +314,6 @@ __decorate([
|
|
|
318
314
|
__decorate([
|
|
319
315
|
property({ type: Object, attribute: false })
|
|
320
316
|
], FieldManager.prototype, "otherFieldKeys", void 0);
|
|
321
|
-
__decorate([
|
|
322
|
-
property({ type: String })
|
|
323
|
-
], FieldManager.prototype, "draggingId", void 0);
|
|
324
317
|
__decorate([
|
|
325
318
|
property({ type: String })
|
|
326
319
|
], FieldManager.prototype, "query", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FieldManager.js","sourceRoot":"","sources":["../../../src/fields/FieldManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ContactField, CustomEventType } from '../interfaces';\n\nimport { SortableList } from '../list/SortableList';\nimport { EndpointMonitorElement } from '../store/EndpointMonitorElement';\nimport { postJSON } from '../utils';\n\nconst TYPE_NAMES = {\n text: 'Text',\n numeric: 'Number',\n number: 'Number',\n datetime: 'Date & Time',\n state: 'State',\n ward: 'Ward',\n district: 'District'\n};\n\nconst matches = (field: ContactField, query: string): boolean => {\n if (!query) {\n return true;\n }\n const search = (\n field.label +\n field.key +\n TYPE_NAMES[field.value_type]\n ).toLowerCase();\n if (search.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n return false;\n};\n\nexport class FieldManager extends EndpointMonitorElement {\n static get styles() {\n return css`\n :host {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n min-height: 0px;\n }\n\n .featured,\n .other-fields {\n background: #fff;\n border-radius: var(--curvature);\n box-shadow: var(--shadow);\n margin-bottom: 1em;\n display: flex;\n flex-direction: column;\n }\n\n .featured {\n max-height: 40%;\n }\n\n .other-fields {\n flex-grow: 2;\n min-height: 0px;\n margin-bottom: 0px;\n }\n\n temba-textinput {\n margin-bottom: 1em;\n }\n\n .scroll-box {\n overflow-y: auto;\n flex-grow: 1;\n flex-direction: column;\n display: flex;\n }\n\n .header temba-icon {\n margin-right: 0.5em;\n }\n\n .label {\n flex-grow: 1;\n }\n\n .header {\n padding: 0.5em 1em;\n display: flex;\n align-items: flex-start;\n border-bottom: 1px solid var(--color-widget-border);\n }\n\n .featured-field {\n user-select: none;\n }\n\n temba-sortable-list {\n padding: 0.5em 0em;\n width: 100%;\n overflow-y: auto;\n }\n\n .scroll-box {\n padding: 0.5em 0em;\n }\n\n temba-icon[name='usages']:hover {\n --icon-color: var(--color-link-primary);\n }\n\n .field:hover temba-icon[name='delete_small'] {\n opacity: 1 !important;\n cursor: pointer !important;\n pointer-events: all !important;\n }\n\n temba-icon[name='delete_small']:hover {\n --icon-color: var(--color-link-primary);\n }\n\n .field {\n border: 1px solid transparent;\n margin: 0 0.5em;\n border-radius: var(--curvature);\n }\n\n .featured temba-sortable-list .field:hover {\n cursor: move;\n border-color: #e6e6e6;\n background: #fcfcfc;\n }\n `;\n }\n\n @property({ type: String, attribute: 'priority-endpoint' })\n priorityEndpoint: string;\n\n @property({ type: Object, attribute: false })\n featuredFields: ContactField[];\n\n @property({ type: Object, attribute: false })\n otherFieldKeys: string[] = [];\n\n @property({ type: String })\n draggingId: string;\n\n @property({ type: String })\n query = '';\n\n protected firstUpdated(\n _changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(_changedProperties);\n this.url = this.store.fieldsEndpoint;\n }\n\n private filterFields() {\n const filteredKeys = this.store.getFieldKeys().filter((key) => {\n const field = this.store.getContactField(key);\n if (field.featured) {\n return false;\n }\n return matches(field, this.query);\n });\n\n // sort by the label instead of the key\n filteredKeys.sort((a, b) => {\n return this.store\n .getContactField(a)\n .label.localeCompare(this.store.getContactField(b).label);\n });\n\n const featured: ContactField[] = [];\n this.store.getFeaturedFields().forEach((field) => {\n if (matches(field, this.query)) {\n featured.push(field);\n }\n });\n\n this.otherFieldKeys = filteredKeys;\n this.featuredFields = featured;\n }\n\n protected updated(\n properties: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.update(properties);\n if (properties.has('data')) {\n this.filterFields();\n } else if (properties.has('query')) {\n this.filterFields();\n }\n }\n\n private handleSaveOrder(event) {\n const list = event.currentTarget as SortableList;\n postJSON(\n this.priorityEndpoint,\n list\n .getIds()\n .reverse()\n .reduce((map, key, idx) => {\n map[key] = idx;\n return map;\n }, {})\n ).then(() => {\n this.store.refreshFields();\n });\n }\n\n private handleOrderChanged(event) {\n const swapsies = event.detail;\n const temp = this.featuredFields[swapsies.fromIdx];\n this.featuredFields[swapsies.fromIdx] = this.featuredFields[swapsies.toIdx];\n this.featuredFields[swapsies.toIdx] = temp;\n this.requestUpdate('featuredFields');\n }\n\n private handleDragStart(event) {\n this.draggingId = event.detail.id;\n }\n\n private handleDragStop() {\n this.draggingId = null;\n }\n\n private handleFieldAction(event: MouseEvent) {\n const ele = event.target as HTMLDivElement;\n const key = ele.dataset.key;\n const action = ele.dataset.action;\n this.fireCustomEvent(CustomEventType.Selection, { key, action });\n }\n\n private handleSearch(event) {\n this.query = (event.target.value || '').trim();\n }\n\n private hasUsages(field: ContactField): boolean {\n return (\n field.usages.campaign_events + field.usages.flows + field.usages.groups >\n 0\n );\n }\n\n private renderField(field: ContactField) {\n return html`\n <div\n class=\"field sortable\"\n id=\"${field.key}\"\n style=\"\n display: flex; \n flex-direction: row; \n align-items: center;\n padding: 0.25em 1em; \n ${field.key === this.draggingId\n ? 'background: var(--color-selection)'\n : ''}\"\n >\n <div\n style=\"display: flex; min-width: 200px; width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 2em\"\n >\n <span\n @click=${this.handleFieldAction}\n data-key=${field.key}\n data-action=\"update\"\n style=\"color: var(--color-link-primary); cursor:pointer;\"\n >\n ${field.label}\n </span>\n ${this.hasUsages(field)\n ? html`\n <temba-icon\n size=\"0.8\"\n style=\"color: #ccc; margin-left: 0.7em;\"\n name=\"usages\"\n data-key=${field.key}\n data-action=\"usages\"\n @click=${this.handleFieldAction}\n clickable\n ></temba-icon>\n `\n : null}\n <div class=\"flex-grow:1\"></div>\n </div>\n <div\n style=\"flex-grow:1; font-family: Roboto Mono, monospace; font-size:0.8em;\"\n >\n @fields.${field.key}\n </div>\n <div>${TYPE_NAMES[field.value_type]}</div>\n <temba-icon\n style=\"pointer-events:none;color:#ccc;margin-left:0.3em;margin-right:-0.5em;opacity:0\"\n name=\"delete_small\"\n data-key=${field.key}\n data-action=\"delete\"\n @click=${this.handleFieldAction}\n ></temba-icon>\n </div>\n `;\n }\n\n public render(): TemplateResult {\n if (!this.featuredFields) {\n return null;\n }\n\n return html`\n <temba-textinput\n id=\"search\"\n placeholder=\"Search\"\n @change=${this.handleSearch}\n clearable\n value=${this.query}\n ></temba-textinput>\n\n ${this.featuredFields.length > 0\n ? html`\n <div class=\"featured\">\n <div class=\"header\">\n <temba-icon name=\"featured\"></temba-icon>\n <div class=\"label\">Featured</div>\n </div>\n ${this.query\n ? html`\n <div class=\"scroll-box\">\n ${this.featuredFields.map((field) =>\n this.renderField(field)\n )}\n </div>\n `\n : html`\n <temba-sortable-list\n @change=${this.handleSaveOrder}\n @temba-order-changed=${this.handleOrderChanged}\n @temba-drag-start=${this.handleDragStart}\n @temba-drag-stop=${this.handleDragStop}\n >\n ${this.featuredFields.map((field) =>\n this.renderField(field)\n )}\n </temba-sortable-list>\n `}\n </div>\n `\n : null}\n\n <div class=\"other-fields\">\n <div class=\"header\">\n <temba-icon name=\"fields\"></temba-icon>\n <div class=\"label\">Everything Else</div>\n </div>\n <div class=\"scroll-box\">\n ${this.otherFieldKeys.map((field) =>\n this.renderField(this.store.getContactField(field))\n )}\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FieldManager.js","sourceRoot":"","sources":["../../../src/fields/FieldManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ContactField, CustomEventType } from '../interfaces';\n\nimport { SortableList } from '../list/SortableList';\nimport { EndpointMonitorElement } from '../store/EndpointMonitorElement';\nimport { postJSON } from '../utils';\n\nconst TYPE_NAMES = {\n text: 'Text',\n numeric: 'Number',\n number: 'Number',\n datetime: 'Date & Time',\n state: 'State',\n ward: 'Ward',\n district: 'District'\n};\n\nconst matches = (field: ContactField, query: string): boolean => {\n if (!query) {\n return true;\n }\n const search = (\n field.label +\n field.key +\n TYPE_NAMES[field.value_type]\n ).toLowerCase();\n if (search.toLowerCase().indexOf(query) > -1) {\n return true;\n }\n return false;\n};\n\nexport class FieldManager extends EndpointMonitorElement {\n static get styles() {\n return css`\n :host {\n display: flex;\n flex-grow: 1;\n flex-direction: column;\n min-height: 0px;\n }\n\n .featured,\n .other-fields {\n background: #fff;\n border-radius: var(--curvature);\n box-shadow: var(--shadow);\n margin-bottom: 1em;\n display: flex;\n flex-direction: column;\n }\n\n .featured {\n max-height: 40%;\n }\n\n .other-fields {\n flex-grow: 2;\n min-height: 0px;\n margin-bottom: 0px;\n }\n\n temba-textinput {\n margin-bottom: 1em;\n }\n\n .scroll-box {\n overflow-y: auto;\n flex-grow: 1;\n flex-direction: column;\n display: flex;\n }\n\n .header temba-icon {\n margin-right: 0.5em;\n }\n\n .label {\n flex-grow: 1;\n }\n\n .header {\n padding: 0.5em 1em;\n display: flex;\n align-items: flex-start;\n border-bottom: 1px solid var(--color-widget-border);\n }\n\n .featured-field {\n user-select: none;\n }\n\n temba-sortable-list {\n padding: 0.5em 0em;\n width: 100%;\n overflow-y: auto;\n }\n\n .scroll-box {\n padding: 0.5em 0em;\n }\n\n temba-icon[name='usages']:hover {\n --icon-color: var(--color-link-primary);\n }\n\n .field:hover temba-icon[name='delete_small'] {\n opacity: 1 !important;\n cursor: pointer !important;\n pointer-events: all !important;\n }\n\n temba-icon[name='delete_small']:hover {\n --icon-color: var(--color-link-primary);\n }\n\n .field {\n border: 1px solid transparent;\n margin: 0 0.5em;\n border-radius: var(--curvature);\n }\n\n .featured:not(.dragging) temba-sortable-list .field:hover {\n cursor: move;\n border-color: #e6e6e6;\n background: #fcfcfc;\n }\n `;\n }\n\n @property({ type: String, attribute: 'priority-endpoint' })\n priorityEndpoint: string;\n\n @property({ type: Object, attribute: false })\n featuredFields: ContactField[];\n\n @property({ type: Object, attribute: false })\n otherFieldKeys: string[] = [];\n\n @property({ type: String })\n query = '';\n\n protected firstUpdated(\n _changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(_changedProperties);\n this.url = this.store.fieldsEndpoint;\n }\n\n private filterFields() {\n const filteredKeys = this.store.getFieldKeys().filter((key) => {\n const field = this.store.getContactField(key);\n if (field.featured) {\n return false;\n }\n return matches(field, this.query);\n });\n\n // sort by the label instead of the key\n filteredKeys.sort((a, b) => {\n return this.store\n .getContactField(a)\n .label.localeCompare(this.store.getContactField(b).label);\n });\n\n const featured: ContactField[] = [];\n this.store.getFeaturedFields().forEach((field) => {\n if (matches(field, this.query)) {\n featured.push(field);\n }\n });\n\n this.otherFieldKeys = filteredKeys;\n this.featuredFields = featured;\n }\n\n protected updated(\n properties: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.update(properties);\n if (properties.has('data')) {\n this.filterFields();\n } else if (properties.has('query')) {\n this.filterFields();\n }\n }\n\n private handleOrderChanged(event) {\n // Apply the reordering immediately - the SortableList now provides accurate indexes\n const [fromIdx, toIdx] = event.detail.swap;\n\n const temp = this.featuredFields[fromIdx];\n this.featuredFields.splice(fromIdx, 1);\n this.featuredFields.splice(toIdx, 0, temp);\n this.requestUpdate();\n\n // Save the new order to the server\n const list = event.currentTarget as SortableList;\n setTimeout(() => {\n postJSON(\n this.priorityEndpoint,\n list\n .getIds()\n .reverse()\n .reduce((map, key, idx) => {\n map[key] = idx;\n return map;\n }, {})\n ).then(() => {\n this.store.refreshFields();\n });\n }, 0);\n }\n\n private handleFieldAction(event: MouseEvent) {\n const ele = event.target as HTMLDivElement;\n const key = ele.dataset.key;\n const action = ele.dataset.action;\n this.fireCustomEvent(CustomEventType.Selection, { key, action });\n }\n\n private handleSearch(event) {\n this.query = (event.target.value || '').trim();\n }\n\n private hasUsages(field: ContactField): boolean {\n return (\n field.usages.campaign_events + field.usages.flows + field.usages.groups >\n 0\n );\n }\n\n private renderField(field: ContactField) {\n return html`\n <div\n class=\"field sortable\"\n id=\"${field.key}\"\n style=\"\n display: flex; \n flex-direction: row; \n align-items: center;\n padding: 0.25em 1em;\"\n @click=${(e: MouseEvent) => {\n const ele = e.currentTarget as HTMLDivElement;\n const key = ele.dataset.key;\n const action = ele.dataset.action;\n this.fireCustomEvent(CustomEventType.Selection, { key, action });\n }}\n >\n <div\n style=\"display: flex; min-width: 200px; width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 2em\"\n >\n <span\n @click=${this.handleFieldAction}\n data-key=${field.key}\n data-action=\"update\"\n style=\"color: var(--color-link-primary); cursor:pointer;\"\n >\n ${field.label}\n </span>\n ${this.hasUsages(field)\n ? html`\n <temba-icon\n size=\"0.8\"\n style=\"color: #ccc; margin-left: 0.7em;\"\n name=\"usages\"\n data-key=${field.key}\n data-action=\"usages\"\n @click=${this.handleFieldAction}\n clickable\n ></temba-icon>\n `\n : null}\n <div class=\"flex-grow:1\"></div>\n </div>\n <div\n style=\"flex-grow:1; font-family: Roboto Mono, monospace; font-size:0.8em;\"\n >\n @fields.${field.key}\n </div>\n <div>${TYPE_NAMES[field.value_type]}</div>\n <temba-icon\n style=\"pointer-events:none;color:#ccc;margin-left:0.3em;margin-right:-0.5em;opacity:0\"\n name=\"delete_small\"\n data-key=${field.key}\n data-action=\"delete\"\n @click=${this.handleFieldAction}\n ></temba-icon>\n </div>\n `;\n }\n\n public render(): TemplateResult {\n if (!this.featuredFields) {\n return null;\n }\n\n return html`\n <temba-textinput\n id=\"search\"\n placeholder=\"Search\"\n @change=${this.handleSearch}\n clearable\n value=${this.query}\n ></temba-textinput>\n\n ${this.featuredFields.length > 0\n ? html`\n <div class=\"featured\">\n <div class=\"header\">\n <temba-icon name=\"featured\"></temba-icon>\n <div class=\"label\">Featured</div>\n </div>\n ${this.query\n ? html`\n <div class=\"scroll-box\">\n ${this.featuredFields.map((field) =>\n this.renderField(field)\n )}\n </div>\n `\n : html`\n <temba-sortable-list\n @temba-order-changed=${this.handleOrderChanged}\n >\n ${this.featuredFields.map((field) =>\n this.renderField(field)\n )}\n </temba-sortable-list>\n `}\n </div>\n `\n : null}\n\n <div class=\"other-fields\">\n <div class=\"header\">\n <temba-icon name=\"fields\"></temba-icon>\n <div class=\"label\">Everything Else</div>\n </div>\n <div class=\"scroll-box\">\n ${this.otherFieldKeys.map((field) =>\n this.renderField(this.store.getContactField(field))\n )}\n </div>\n </div>\n `;\n }\n}\n"]}
|
|
@@ -106,6 +106,7 @@ export class RunList extends TembaList {
|
|
|
106
106
|
}
|
|
107
107
|
createRenderOption() {
|
|
108
108
|
this.renderOption = (run) => {
|
|
109
|
+
var _a, _b, _c;
|
|
109
110
|
let statusStyle = '';
|
|
110
111
|
if (!run.exited_on) {
|
|
111
112
|
statusStyle = 'font-weight:400;';
|
|
@@ -119,8 +120,8 @@ export class RunList extends TembaList {
|
|
|
119
120
|
style="width:16em;white-space:nowrap;overflow: hidden; text-overflow: ellipsis;"
|
|
120
121
|
>
|
|
121
122
|
<temba-contact-name
|
|
122
|
-
name=${run.contact.name || run.contact.anon_display}
|
|
123
|
-
urn=${run.contact.urn}
|
|
123
|
+
name=${((_a = run.contact) === null || _a === void 0 ? void 0 : _a.name) || ((_b = run.contact) === null || _b === void 0 ? void 0 : _b.anon_display) || ''}
|
|
124
|
+
urn=${((_c = run.contact) === null || _c === void 0 ? void 0 : _c.urn) || ''}
|
|
124
125
|
icon-size="15"
|
|
125
126
|
/>
|
|
126
127
|
</div>
|
|
@@ -207,10 +208,11 @@ export class RunList extends TembaList {
|
|
|
207
208
|
`;
|
|
208
209
|
}
|
|
209
210
|
renderFooter() {
|
|
211
|
+
var _a, _b, _c, _d;
|
|
210
212
|
if (!this.selectedRun || !this.resultKeys) {
|
|
211
213
|
return null;
|
|
212
214
|
}
|
|
213
|
-
const resultKeys = Object.keys(this.selectedRun.values);
|
|
215
|
+
const resultKeys = Object.keys(this.selectedRun.values || {});
|
|
214
216
|
return html ` <div
|
|
215
217
|
style="margin-top: 1.5em; margin-bottom:0.5em;flex-grow:1;border-radius:var(--curvature); border: 1px solid var(--color-widget-border);"
|
|
216
218
|
>
|
|
@@ -221,11 +223,12 @@ export class RunList extends TembaList {
|
|
|
221
223
|
<div>
|
|
222
224
|
<temba-contact-name
|
|
223
225
|
style="cursor:pointer"
|
|
224
|
-
name=${this.selectedRun.contact.name ||
|
|
225
|
-
this.selectedRun.contact.anon_display
|
|
226
|
-
|
|
226
|
+
name=${((_a = this.selectedRun.contact) === null || _a === void 0 ? void 0 : _a.name) ||
|
|
227
|
+
((_b = this.selectedRun.contact) === null || _b === void 0 ? void 0 : _b.anon_display) ||
|
|
228
|
+
''}
|
|
229
|
+
urn=${((_c = this.selectedRun.contact) === null || _c === void 0 ? void 0 : _c.urn) || ''}
|
|
227
230
|
onclick="goto(event, this)"
|
|
228
|
-
href="/contact/read/${this.selectedRun.contact.uuid}/"
|
|
231
|
+
href="/contact/read/${((_d = this.selectedRun.contact) === null || _d === void 0 ? void 0 : _d.uuid) || ''}/"
|
|
229
232
|
></temba-contact-name>
|
|
230
233
|
<div
|
|
231
234
|
style="display:flex;margin-left:-0.2em;margin-top:0.25em;font-size: 0.65em"
|
|
@@ -257,7 +260,9 @@ export class RunList extends TembaList {
|
|
|
257
260
|
<div style="flex-grow:1"></div>
|
|
258
261
|
<div style="display:flex;flex-direction: column">
|
|
259
262
|
<div style="font-size:0.75em">
|
|
260
|
-
${
|
|
263
|
+
${this.selectedRun.created_on
|
|
264
|
+
? new Date(this.selectedRun.created_on).toLocaleString()
|
|
265
|
+
: ''}
|
|
261
266
|
</div>
|
|
262
267
|
<div
|
|
263
268
|
style="font-size:0.6em;align-self:flex-end;color:#888;line-height:0.75em"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunList.js","sourceRoot":"","sources":["../../../src/list/RunList.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Checkbox } from '../checkbox/Checkbox';\nimport { Select } from '../select/Select';\nimport { capitalize } from '../utils';\nimport { Icon } from '../vectoricon';\nimport { TembaList } from './TembaList';\n\nconst FLOW_COLOR = 'rgb(223, 65, 159)';\n\nexport class RunList extends TembaList {\n @property({ type: String })\n flow: string;\n\n @property({ type: Object, attribute: false })\n results: any[];\n\n @property({ type: Boolean })\n responses = true;\n\n @property({ type: Object })\n resultPreview: any;\n\n @property({ type: Object })\n selectedRun: any;\n\n @property({ type: Boolean })\n allowDelete = false;\n\n private resultKeys = {};\n\n static get styles() {\n return css`\n :host {\n overflow-y: auto !important;\n --contact-name-font-size: 1em;\n }\n\n @media only screen and (max-height: 768px) {\n temba-options {\n max-height: 20vh;\n }\n }\n\n temba-options {\n display: block;\n width: 100%;\n flex-grow: 1;\n }\n `;\n }\n\n public firstUpdated(changedProperties: Map<string, any>) {\n super.firstUpdated(changedProperties);\n }\n\n public updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n if (changedProperties.has('responses') || changedProperties.has('flow')) {\n if (this.flow) {\n this.endpoint = `/api/v2/runs.json?flow=${this.flow}${\n this.responses ? '&responded=1' : ''\n }`;\n }\n }\n\n if (changedProperties.has('resultPreview')) {\n this.createRenderOption();\n }\n\n if (changedProperties.has('results')) {\n if (this.results) {\n const select = this.shadowRoot.querySelector(\n 'temba-select'\n ) as Select<any>;\n select.setOptions(this.results);\n this.resultKeys = this.results.reduce(\n (current, result) => ({ ...current, [result.key]: result }),\n {}\n );\n }\n }\n }\n\n public renderResultPreview(run: any) {\n if (this.resultPreview) {\n const runResult = run.values[this.resultPreview.key];\n if (runResult) {\n if (this.resultPreview.categories.length > 1) {\n if (runResult.category) {\n return runResult.category;\n }\n } else {\n return runResult.value;\n }\n }\n }\n return null;\n }\n\n public removeRun(id: number) {\n this.items = this.items.filter((run) => run.id !== id);\n this.cursorIndex = Math.min(this.cursorIndex, this.items.length);\n this.requestUpdate('cursorIndex');\n }\n\n public getIcon(run: any): TemplateResult {\n let icon = null;\n if (run.exit_type == 'completed') {\n icon = html`<temba-icon\n name=\"check\"\n style=\"--icon-color:#666;margin-left:0.5em\"\n />`;\n } else if (run.exit_type == 'interrupted') {\n icon = html`<temba-icon\n name=\"x-octagon\"\n style=\"--icon-color:${FLOW_COLOR};margin-left:0.5em\"\n />`;\n } else if (run.exit_type == 'expired') {\n icon = html`<temba-icon\n name=\"clock\"\n style=\"--icon-color:${FLOW_COLOR};margin-left:0.5em\"\n />`;\n } else if (!run.exit_type) {\n if (run.responded) {\n icon = html`<temba-icon\n name=\"activity\"\n style=\"--icon-color:var(--color-primary-dark);margin-left:0.5em\"\n />`;\n } else {\n icon = html`<temba-icon\n name=\"hourglass\"\n style=\"--icon-color:var(--color-primary-dark);margin-left:0.5em\"\n />`;\n }\n }\n return icon;\n }\n\n public createRenderOption() {\n this.renderOption = (run: any): TemplateResult => {\n let statusStyle = '';\n\n if (!run.exited_on) {\n statusStyle = 'font-weight:400;';\n }\n\n if (!run.responded) {\n statusStyle += '';\n }\n\n return html`\n <div class=\"row\" style=\"${statusStyle}display:flex;align-items:center\">\n <div\n style=\"width:16em;white-space:nowrap;overflow: hidden; text-overflow: ellipsis;\"\n >\n <temba-contact-name\n name=${run.contact.name || run.contact.anon_display}\n urn=${run.contact.urn}\n icon-size=\"15\"\n />\n </div>\n\n <div\n style=\"margin: 0em 1em;flex:1;white-space:nowrap; overflow:hidden; text-overflow: ellipsis;\"\n >\n ${this.renderResultPreview(run)}\n </div>\n\n <div style=\"flex-shrink:1\">\n <temba-date value=\"${run.modified_on}\" display=\"duration\" />\n </div>\n ${this.getIcon(run)}\n </div>\n `;\n };\n }\n\n public getRefreshEndpoint() {\n if (this.items.length > 0) {\n const modifiedOn = this.items[0].modified_on;\n return this.endpoint + '&after=' + modifiedOn;\n }\n return this.endpoint;\n }\n\n public toggleResponded() {\n this.responses = (\n this.shadowRoot.querySelector('#responded') as Checkbox\n ).checked;\n }\n\n public handleColumnChanged(event: any) {\n if (event.target.values.length > 0) {\n this.resultPreview = event.target.values[0];\n } else {\n this.resultPreview = null;\n }\n }\n\n public handleSelected(selected: any) {\n this.selectedRun = selected;\n }\n\n public getListStyle(): string {\n return '';\n }\n\n public renderHeader(): TemplateResult {\n return html`\n <div style=\"display:flex;width:100%;margin-bottom: 1em;\">\n <div style=\"flex-grow:1\">\n ${this.results\n ? html`\n <temba-select\n clearable\n placeholder=\"Result Preview\"\n valueKey=\"key\"\n @change=${this.handleColumnChanged}\n />\n `\n : null}\n </div>\n <div style=\"margin-left:1em;\">\n <temba-checkbox\n id=\"responded\"\n label=\"Responses Only\"\n checked=\"true\"\n @click=${this.toggleResponded}\n />\n </div>\n </div>\n <div\n style=\"\n font-size:0.8em;\n color:rgba(0,0,0,.4);\n text-align:right;\n background:#f9f9f9;\n border: 1px solid var(--color-widget-border);\n margin-bottom:-0.5em; \n padding-bottom: 0.6em;\n padding-top: 0.3em;\n padding-right: 4.5em;\n border-top-right-radius: var(--curvature);\n border-top-left-radius: var(--curvature)\n \"\n >\n Last Updated\n </div>\n `;\n }\n\n public renderFooter(): TemplateResult {\n if (!this.selectedRun || !this.resultKeys) {\n return null;\n }\n\n const resultKeys = Object.keys(this.selectedRun.values);\n\n return html` <div\n style=\"margin-top: 1.5em; margin-bottom:0.5em;flex-grow:1;border-radius:var(--curvature); border: 1px solid var(--color-widget-border);\"\n >\n <div style=\"display:flex;flex-direction:column;\">\n <div\n style=\"font-size:1.5em;background:#f9f9f9;padding:.75em;padding-top:.35em;display:flex;align-items:center;border-top-right-radius:var(--curvature);border-top-left-radius:var(--curvature)\"\n >\n <div>\n <temba-contact-name\n style=\"cursor:pointer\"\n name=${this.selectedRun.contact.name ||\n this.selectedRun.contact.anon_display}\n urn=${this.selectedRun.contact.urn}\n onclick=\"goto(event, this)\"\n href=\"/contact/read/${this.selectedRun.contact.uuid}/\"\n ></temba-contact-name>\n <div\n style=\"display:flex;margin-left:-0.2em;margin-top:0.25em;font-size: 0.65em\"\n >\n ${this.selectedRun.exit_type\n ? html`\n <div style=\"margin-left:2em;flex-grow:1;display:flex\">\n ${this.getIcon(this.selectedRun)}\n <div style=\"margin-left:0.5em\">\n ${capitalize(this.selectedRun.exit_type)} \n </div>\n <temba-date\n value=\"${this.selectedRun.exited_on}\"\n compare=\"${this.selectedRun.created_on}\"\n display=\"duration\"\n />\n </div>\n `\n : html`${this.getIcon(this.selectedRun)}\n <div style=\"margin-left:1.5em;flex-grow:1;display:flex\">\n <div>Started </div>\n <temba-date\n value=\"${this.selectedRun.created_on}\"\n display=\"duration\"\n ></temba-date>\n </div>`}\n </div>\n </div>\n <div style=\"flex-grow:1\"></div>\n <div style=\"display:flex;flex-direction: column\">\n <div style=\"font-size:0.75em\">\n ${new Date(this.selectedRun.created_on).toLocaleString()}\n </div>\n <div\n style=\"font-size:0.6em;align-self:flex-end;color:#888;line-height:0.75em\"\n >\n Started\n </div>\n </div>\n ${this.allowDelete\n ? html` <temba-icon\n clickable\n style=\"margin-left:0.75em;\"\n name=${Icon.delete}\n onclick=\"deleteRun(${this.selectedRun.id});\"\n ></temba-icon>`\n : null}\n </div>\n\n ${resultKeys.length > 0\n ? html`\n <div style=\"padding:1em;\">\n <div\n style=\"display:flex;font-size:1.2em;position:relative;right:0px\"\n >\n <div style=\"flex-grow:1\"></div>\n </div>\n\n <table width=\"100%\">\n <tr>\n <th style=\"text-align:left\" width=\"25%\">Result</th>\n <th style=\"text-align:left\" width=\"25%\">Category</th>\n <th style=\"text-align:left\">Value</th>\n </tr>\n\n ${Object.keys(this.selectedRun.values).map((key: string) => {\n const result = this.selectedRun.values[key];\n const meta = this.resultKeys[key];\n\n // if our result is no longer represented in the flow, skip it\n if (meta) {\n return html`<tr>\n <td>${result.name}</td>\n <td>\n ${meta.categories.length > 1 ? result.category : '--'}\n </td>\n <td>${result.value}</td>\n </tr>`;\n }\n return null;\n })}\n </table>\n </div>\n `\n : null}\n </div>\n </div>`;\n }\n\n constructor() {\n super();\n this.reverseRefresh = false;\n this.valueKey = 'uuid';\n this.hideShadow = true;\n this.createRenderOption();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RunList.js","sourceRoot":"","sources":["../../../src/list/RunList.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Checkbox } from '../checkbox/Checkbox';\nimport { Select } from '../select/Select';\nimport { capitalize } from '../utils';\nimport { Icon } from '../vectoricon';\nimport { TembaList } from './TembaList';\n\nconst FLOW_COLOR = 'rgb(223, 65, 159)';\n\nexport class RunList extends TembaList {\n @property({ type: String })\n flow: string;\n\n @property({ type: Object, attribute: false })\n results: any[];\n\n @property({ type: Boolean })\n responses = true;\n\n @property({ type: Object })\n resultPreview: any;\n\n @property({ type: Object })\n selectedRun: any;\n\n @property({ type: Boolean })\n allowDelete = false;\n\n private resultKeys = {};\n\n static get styles() {\n return css`\n :host {\n overflow-y: auto !important;\n --contact-name-font-size: 1em;\n }\n\n @media only screen and (max-height: 768px) {\n temba-options {\n max-height: 20vh;\n }\n }\n\n temba-options {\n display: block;\n width: 100%;\n flex-grow: 1;\n }\n `;\n }\n\n public firstUpdated(changedProperties: Map<string, any>) {\n super.firstUpdated(changedProperties);\n }\n\n public updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n if (changedProperties.has('responses') || changedProperties.has('flow')) {\n if (this.flow) {\n this.endpoint = `/api/v2/runs.json?flow=${this.flow}${\n this.responses ? '&responded=1' : ''\n }`;\n }\n }\n\n if (changedProperties.has('resultPreview')) {\n this.createRenderOption();\n }\n\n if (changedProperties.has('results')) {\n if (this.results) {\n const select = this.shadowRoot.querySelector(\n 'temba-select'\n ) as Select<any>;\n select.setOptions(this.results);\n this.resultKeys = this.results.reduce(\n (current, result) => ({ ...current, [result.key]: result }),\n {}\n );\n }\n }\n }\n\n public renderResultPreview(run: any) {\n if (this.resultPreview) {\n const runResult = run.values[this.resultPreview.key];\n if (runResult) {\n if (this.resultPreview.categories.length > 1) {\n if (runResult.category) {\n return runResult.category;\n }\n } else {\n return runResult.value;\n }\n }\n }\n return null;\n }\n\n public removeRun(id: number) {\n this.items = this.items.filter((run) => run.id !== id);\n this.cursorIndex = Math.min(this.cursorIndex, this.items.length);\n this.requestUpdate('cursorIndex');\n }\n\n public getIcon(run: any): TemplateResult {\n let icon = null;\n if (run.exit_type == 'completed') {\n icon = html`<temba-icon\n name=\"check\"\n style=\"--icon-color:#666;margin-left:0.5em\"\n />`;\n } else if (run.exit_type == 'interrupted') {\n icon = html`<temba-icon\n name=\"x-octagon\"\n style=\"--icon-color:${FLOW_COLOR};margin-left:0.5em\"\n />`;\n } else if (run.exit_type == 'expired') {\n icon = html`<temba-icon\n name=\"clock\"\n style=\"--icon-color:${FLOW_COLOR};margin-left:0.5em\"\n />`;\n } else if (!run.exit_type) {\n if (run.responded) {\n icon = html`<temba-icon\n name=\"activity\"\n style=\"--icon-color:var(--color-primary-dark);margin-left:0.5em\"\n />`;\n } else {\n icon = html`<temba-icon\n name=\"hourglass\"\n style=\"--icon-color:var(--color-primary-dark);margin-left:0.5em\"\n />`;\n }\n }\n return icon;\n }\n\n public createRenderOption() {\n this.renderOption = (run: any): TemplateResult => {\n let statusStyle = '';\n\n if (!run.exited_on) {\n statusStyle = 'font-weight:400;';\n }\n\n if (!run.responded) {\n statusStyle += '';\n }\n\n return html`\n <div class=\"row\" style=\"${statusStyle}display:flex;align-items:center\">\n <div\n style=\"width:16em;white-space:nowrap;overflow: hidden; text-overflow: ellipsis;\"\n >\n <temba-contact-name\n name=${run.contact?.name || run.contact?.anon_display || ''}\n urn=${run.contact?.urn || ''}\n icon-size=\"15\"\n />\n </div>\n\n <div\n style=\"margin: 0em 1em;flex:1;white-space:nowrap; overflow:hidden; text-overflow: ellipsis;\"\n >\n ${this.renderResultPreview(run)}\n </div>\n\n <div style=\"flex-shrink:1\">\n <temba-date value=\"${run.modified_on}\" display=\"duration\" />\n </div>\n ${this.getIcon(run)}\n </div>\n `;\n };\n }\n\n public getRefreshEndpoint() {\n if (this.items.length > 0) {\n const modifiedOn = this.items[0].modified_on;\n return this.endpoint + '&after=' + modifiedOn;\n }\n return this.endpoint;\n }\n\n public toggleResponded() {\n this.responses = (\n this.shadowRoot.querySelector('#responded') as Checkbox\n ).checked;\n }\n\n public handleColumnChanged(event: any) {\n if (event.target.values.length > 0) {\n this.resultPreview = event.target.values[0];\n } else {\n this.resultPreview = null;\n }\n }\n\n public handleSelected(selected: any) {\n this.selectedRun = selected;\n }\n\n public getListStyle(): string {\n return '';\n }\n\n public renderHeader(): TemplateResult {\n return html`\n <div style=\"display:flex;width:100%;margin-bottom: 1em;\">\n <div style=\"flex-grow:1\">\n ${this.results\n ? html`\n <temba-select\n clearable\n placeholder=\"Result Preview\"\n valueKey=\"key\"\n @change=${this.handleColumnChanged}\n />\n `\n : null}\n </div>\n <div style=\"margin-left:1em;\">\n <temba-checkbox\n id=\"responded\"\n label=\"Responses Only\"\n checked=\"true\"\n @click=${this.toggleResponded}\n />\n </div>\n </div>\n <div\n style=\"\n font-size:0.8em;\n color:rgba(0,0,0,.4);\n text-align:right;\n background:#f9f9f9;\n border: 1px solid var(--color-widget-border);\n margin-bottom:-0.5em; \n padding-bottom: 0.6em;\n padding-top: 0.3em;\n padding-right: 4.5em;\n border-top-right-radius: var(--curvature);\n border-top-left-radius: var(--curvature)\n \"\n >\n Last Updated\n </div>\n `;\n }\n\n public renderFooter(): TemplateResult {\n if (!this.selectedRun || !this.resultKeys) {\n return null;\n }\n\n const resultKeys = Object.keys(this.selectedRun.values || {});\n\n return html` <div\n style=\"margin-top: 1.5em; margin-bottom:0.5em;flex-grow:1;border-radius:var(--curvature); border: 1px solid var(--color-widget-border);\"\n >\n <div style=\"display:flex;flex-direction:column;\">\n <div\n style=\"font-size:1.5em;background:#f9f9f9;padding:.75em;padding-top:.35em;display:flex;align-items:center;border-top-right-radius:var(--curvature);border-top-left-radius:var(--curvature)\"\n >\n <div>\n <temba-contact-name\n style=\"cursor:pointer\"\n name=${this.selectedRun.contact?.name ||\n this.selectedRun.contact?.anon_display ||\n ''}\n urn=${this.selectedRun.contact?.urn || ''}\n onclick=\"goto(event, this)\"\n href=\"/contact/read/${this.selectedRun.contact?.uuid || ''}/\"\n ></temba-contact-name>\n <div\n style=\"display:flex;margin-left:-0.2em;margin-top:0.25em;font-size: 0.65em\"\n >\n ${this.selectedRun.exit_type\n ? html`\n <div style=\"margin-left:2em;flex-grow:1;display:flex\">\n ${this.getIcon(this.selectedRun)}\n <div style=\"margin-left:0.5em\">\n ${capitalize(this.selectedRun.exit_type)} \n </div>\n <temba-date\n value=\"${this.selectedRun.exited_on}\"\n compare=\"${this.selectedRun.created_on}\"\n display=\"duration\"\n />\n </div>\n `\n : html`${this.getIcon(this.selectedRun)}\n <div style=\"margin-left:1.5em;flex-grow:1;display:flex\">\n <div>Started </div>\n <temba-date\n value=\"${this.selectedRun.created_on}\"\n display=\"duration\"\n ></temba-date>\n </div>`}\n </div>\n </div>\n <div style=\"flex-grow:1\"></div>\n <div style=\"display:flex;flex-direction: column\">\n <div style=\"font-size:0.75em\">\n ${this.selectedRun.created_on\n ? new Date(this.selectedRun.created_on).toLocaleString()\n : ''}\n </div>\n <div\n style=\"font-size:0.6em;align-self:flex-end;color:#888;line-height:0.75em\"\n >\n Started\n </div>\n </div>\n ${this.allowDelete\n ? html` <temba-icon\n clickable\n style=\"margin-left:0.75em;\"\n name=${Icon.delete}\n onclick=\"deleteRun(${this.selectedRun.id});\"\n ></temba-icon>`\n : null}\n </div>\n\n ${resultKeys.length > 0\n ? html`\n <div style=\"padding:1em;\">\n <div\n style=\"display:flex;font-size:1.2em;position:relative;right:0px\"\n >\n <div style=\"flex-grow:1\"></div>\n </div>\n\n <table width=\"100%\">\n <tr>\n <th style=\"text-align:left\" width=\"25%\">Result</th>\n <th style=\"text-align:left\" width=\"25%\">Category</th>\n <th style=\"text-align:left\">Value</th>\n </tr>\n\n ${Object.keys(this.selectedRun.values).map((key: string) => {\n const result = this.selectedRun.values[key];\n const meta = this.resultKeys[key];\n\n // if our result is no longer represented in the flow, skip it\n if (meta) {\n return html`<tr>\n <td>${result.name}</td>\n <td>\n ${meta.categories.length > 1 ? result.category : '--'}\n </td>\n <td>${result.value}</td>\n </tr>`;\n }\n return null;\n })}\n </table>\n </div>\n `\n : null}\n </div>\n </div>`;\n }\n\n constructor() {\n super();\n this.reverseRefresh = false;\n this.valueKey = 'uuid';\n this.hideShadow = true;\n this.createRenderOption();\n }\n}\n"]}
|