@nyaruka/temba-components 0.86.1 → 0.88.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/.eslintrc.js +3 -3
- package/.prettierrc +6 -0
- package/.storybook/main.js +3 -3
- package/.storybook/preview.js +2 -2
- package/CHANGELOG.md +24 -24
- package/CreateIncludesPlugin.js +2 -2
- package/demo/index.html +1 -0
- package/dist/locales/es.js +1 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +1 -1
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/pt.js +1 -1
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +647 -535
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/RapidElement.js +3 -3
- package/out-tsc/src/RapidElement.js.map +1 -1
- package/out-tsc/src/ResizeElement.js +2 -2
- package/out-tsc/src/ResizeElement.js.map +1 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js +1 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
- package/out-tsc/src/button/Button.js +1 -1
- package/out-tsc/src/button/Button.js.map +1 -1
- package/out-tsc/src/charcount/helpers.js +1 -1
- package/out-tsc/src/charcount/helpers.js.map +1 -1
- package/out-tsc/src/colorpicker/ColorPicker.js +4 -4
- package/out-tsc/src/colorpicker/ColorPicker.js.map +1 -1
- package/out-tsc/src/completion/Completion.js +2 -2
- package/out-tsc/src/completion/Completion.js.map +1 -1
- package/out-tsc/src/completion/ExcellentParser.js +1 -1
- package/out-tsc/src/completion/ExcellentParser.js.map +1 -1
- package/out-tsc/src/completion/helpers.js +8 -8
- package/out-tsc/src/completion/helpers.js.map +1 -1
- package/out-tsc/src/compose/Compose.js +14 -14
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactBadges.js +2 -2
- package/out-tsc/src/contacts/ContactBadges.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +4 -4
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactDetails.js +4 -4
- package/out-tsc/src/contacts/ContactDetails.js.map +1 -1
- package/out-tsc/src/contacts/ContactFieldEditor.js +3 -3
- package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/contacts/ContactFields.js +2 -2
- package/out-tsc/src/contacts/ContactFields.js.map +1 -1
- package/out-tsc/src/contacts/ContactHistory.js +21 -19
- package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
- package/out-tsc/src/contacts/ContactPending.js +4 -4
- package/out-tsc/src/contacts/ContactPending.js.map +1 -1
- package/out-tsc/src/contacts/ContactTickets.js +8 -8
- package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
- package/out-tsc/src/contacts/events.js +2 -2
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/contacts/helpers.js +2 -2
- package/out-tsc/src/contacts/helpers.js.map +1 -1
- package/out-tsc/src/contactsearch/ContactSearch.js +7 -7
- package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
- package/out-tsc/src/date/TembaDate.js +1 -1
- package/out-tsc/src/date/TembaDate.js.map +1 -1
- package/out-tsc/src/datepicker/DatePicker.js +1 -1
- package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
- package/out-tsc/src/dialog/Dialog.js +5 -5
- package/out-tsc/src/dialog/Dialog.js.map +1 -1
- package/out-tsc/src/dialog/Modax.js +8 -8
- package/out-tsc/src/dialog/Modax.js.map +1 -1
- package/out-tsc/src/dropdown/Dropdown.js +1 -1
- package/out-tsc/src/dropdown/Dropdown.js.map +1 -1
- package/out-tsc/src/fields/FieldManager.js +6 -6
- package/out-tsc/src/fields/FieldManager.js.map +1 -1
- package/out-tsc/src/imagepicker/ImagePicker.js +4 -4
- package/out-tsc/src/imagepicker/ImagePicker.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/label/Label.js +1 -1
- package/out-tsc/src/label/Label.js.map +1 -1
- package/out-tsc/src/leafletmap/LeafletMap.js +6 -6
- package/out-tsc/src/leafletmap/LeafletMap.js.map +1 -1
- package/out-tsc/src/leafletmap/helpers.js +2 -2
- package/out-tsc/src/leafletmap/helpers.js.map +1 -1
- package/out-tsc/src/lightbox/Lightbox.js +2 -2
- package/out-tsc/src/lightbox/Lightbox.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +8 -8
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/RunList.js +1 -1
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +6 -6
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/list/TembaList.js +9 -7
- package/out-tsc/src/list/TembaList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +22 -22
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/loading/Loading.js +1 -1
- package/out-tsc/src/loading/Loading.js.map +1 -1
- package/out-tsc/src/locales/es.js +1 -1
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +1 -1
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/pt.js +1 -1
- 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 +9 -9
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/remote/Remote.js +1 -1
- package/out-tsc/src/remote/Remote.js.map +1 -1
- package/out-tsc/src/select/Select.js +18 -18
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/sms/gsmsplitter.js +8 -8
- package/out-tsc/src/sms/gsmsplitter.js.map +1 -1
- package/out-tsc/src/sms/gsmvalidator.js +1 -1
- package/out-tsc/src/sms/gsmvalidator.js.map +1 -1
- package/out-tsc/src/sms/index.js +2 -2
- package/out-tsc/src/sms/index.js.map +1 -1
- package/out-tsc/src/sms/unicodesplitter.js +8 -8
- package/out-tsc/src/sms/unicodesplitter.js.map +1 -1
- package/out-tsc/src/store/Store.js +10 -10
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/store/StoreElement.js +2 -2
- package/out-tsc/src/store/StoreElement.js.map +1 -1
- package/out-tsc/src/tabpane/TabPane.js +4 -4
- package/out-tsc/src/tabpane/TabPane.js.map +1 -1
- package/out-tsc/src/templates/TemplateEditor.js +9 -9
- package/out-tsc/src/templates/TemplateEditor.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +1 -1
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/thumbnail/Thumbnail.js +5 -5
- package/out-tsc/src/thumbnail/Thumbnail.js.map +1 -1
- package/out-tsc/src/tip/Tip.js +3 -3
- package/out-tsc/src/tip/Tip.js.map +1 -1
- package/out-tsc/src/toast/Toast.js +199 -0
- package/out-tsc/src/toast/Toast.js.map +1 -0
- package/out-tsc/src/utils/index.js +28 -21
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/vectoricon/VectorIcon.js +2 -2
- package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +1 -0
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +234 -81
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/src/webchat/assets.js +2 -0
- package/out-tsc/src/webchat/assets.js.map +1 -0
- package/out-tsc/src/webchat/index.js.map +1 -1
- package/out-tsc/temba-modules.js +2 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/temba-alert.test.js +1 -1
- package/out-tsc/test/temba-alert.test.js.map +1 -1
- package/out-tsc/test/temba-checkbox.test.js.map +1 -1
- package/out-tsc/test/temba-color-picker.test.js +4 -4
- package/out-tsc/test/temba-color-picker.test.js.map +1 -1
- package/out-tsc/test/temba-compose.test.js +50 -54
- package/out-tsc/test/temba-compose.test.js.map +1 -1
- package/out-tsc/test/temba-contact-badges.test.js +2 -2
- package/out-tsc/test/temba-contact-badges.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +25 -38
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-contact-details.test.js +2 -2
- package/out-tsc/test/temba-contact-details.test.js.map +1 -1
- package/out-tsc/test/temba-contact-fields.test.js +4 -4
- package/out-tsc/test/temba-contact-fields.test.js.map +1 -1
- package/out-tsc/test/temba-contact-history.test.js +3 -3
- package/out-tsc/test/temba-contact-history.test.js.map +1 -1
- package/out-tsc/test/temba-contact-search.test.js +7 -7
- package/out-tsc/test/temba-contact-search.test.js.map +1 -1
- package/out-tsc/test/temba-contact-tickets.test.js +3 -3
- package/out-tsc/test/temba-contact-tickets.test.js.map +1 -1
- package/out-tsc/test/temba-content-menu.test.js +7 -7
- package/out-tsc/test/temba-content-menu.test.js.map +1 -1
- package/out-tsc/test/temba-date.test.js +3 -3
- package/out-tsc/test/temba-date.test.js.map +1 -1
- package/out-tsc/test/temba-datepicker.test.js +1 -1
- package/out-tsc/test/temba-datepicker.test.js.map +1 -1
- package/out-tsc/test/temba-field-manager.test.js +1 -3
- package/out-tsc/test/temba-field-manager.test.js.map +1 -1
- package/out-tsc/test/temba-label.test.js +6 -6
- package/out-tsc/test/temba-label.test.js.map +1 -1
- package/out-tsc/test/temba-lightbox.test.js +2 -2
- package/out-tsc/test/temba-lightbox.test.js.map +1 -1
- package/out-tsc/test/temba-list.test.js +6 -6
- package/out-tsc/test/temba-list.test.js.map +1 -1
- package/out-tsc/test/temba-menu.test.js +4 -5
- package/out-tsc/test/temba-menu.test.js.map +1 -1
- package/out-tsc/test/temba-modax.test.js +3 -3
- package/out-tsc/test/temba-modax.test.js.map +1 -1
- package/out-tsc/test/temba-options.test.js +1 -1
- package/out-tsc/test/temba-options.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +17 -17
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-sortable-list.test.js +1 -1
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/out-tsc/test/temba-textinput.test.js +2 -2
- package/out-tsc/test/temba-textinput.test.js.map +1 -1
- package/out-tsc/test/temba-tip.test.js +4 -4
- package/out-tsc/test/temba-tip.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +8 -8
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +6 -15
- package/src/RapidElement.ts +3 -3
- package/src/ResizeElement.ts +2 -2
- package/src/aliaseditor/AliasEditor.ts +1 -2
- package/src/button/Button.ts +1 -1
- package/src/charcount/helpers.ts +1 -1
- package/src/colorpicker/ColorPicker.ts +4 -4
- package/src/completion/Completion.ts +2 -2
- package/src/completion/ExcellentParser.ts +1 -1
- package/src/completion/helpers.ts +9 -9
- package/src/compose/Compose.ts +18 -16
- package/src/contacts/ContactBadges.ts +2 -2
- package/src/contacts/ContactChat.ts +4 -4
- package/src/contacts/ContactDetails.ts +4 -4
- package/src/contacts/ContactFieldEditor.ts +4 -4
- package/src/contacts/ContactFields.ts +2 -2
- package/src/contacts/ContactHistory.ts +25 -22
- package/src/contacts/ContactPending.ts +4 -4
- package/src/contacts/ContactTickets.ts +9 -9
- package/src/contacts/events.ts +3 -3
- package/src/contacts/helpers.ts +2 -2
- package/src/contactsearch/ContactSearch.ts +9 -9
- package/src/date/TembaDate.ts +1 -1
- package/src/datepicker/DatePicker.ts +1 -1
- package/src/dialog/Dialog.ts +6 -6
- package/src/dialog/Modax.ts +8 -8
- package/src/dropdown/Dropdown.ts +1 -2
- package/src/emojis.json +1882 -1
- package/src/fields/FieldManager.ts +6 -7
- package/src/imagepicker/ImagePicker.ts +4 -4
- package/src/interfaces.ts +4 -4
- package/src/label/Label.ts +1 -1
- package/src/leafletmap/LeafletMap.ts +6 -6
- package/src/leafletmap/helpers.ts +2 -2
- package/src/lightbox/Lightbox.ts +2 -2
- package/src/list/ContentMenu.ts +9 -9
- package/src/list/RunList.ts +1 -1
- package/src/list/SortableList.ts +6 -6
- package/src/list/TembaList.ts +9 -7
- package/src/list/TembaMenu.ts +23 -23
- package/src/loading/Loading.ts +1 -1
- package/src/locales/es.ts +1 -1
- package/src/locales/fr.ts +1 -1
- package/src/locales/pt.ts +1 -1
- package/src/omnibox/Omnibox.ts +2 -2
- package/src/options/Options.ts +9 -9
- package/src/remote/Remote.ts +1 -1
- package/src/select/Select.ts +19 -19
- package/src/sms/gsmsplitter.ts +8 -8
- package/src/sms/gsmvalidator.ts +1 -1
- package/src/sms/index.ts +2 -2
- package/src/sms/unicodesplitter.ts +8 -8
- package/src/store/Store.ts +10 -10
- package/src/store/StoreElement.ts +2 -2
- package/src/tabpane/TabPane.ts +4 -4
- package/src/templates/TemplateEditor.ts +9 -9
- package/src/textinput/TextInput.ts +2 -2
- package/src/thumbnail/Thumbnail.ts +5 -5
- package/src/tip/Tip.ts +3 -3
- package/src/toast/Toast.ts +224 -0
- package/src/utils/index.ts +33 -24
- package/src/vectoricon/VectorIcon.ts +2 -2
- package/src/vectoricon/index.ts +2 -1
- package/src/webchat/WebChat.ts +272 -87
- package/src/webchat/assets.ts +2 -0
- package/src/webchat/index.ts +1 -1
- package/svg.js +28 -29
- package/temba-modules.ts +2 -0
- package/test/temba-alert.test.ts +1 -1
- package/test/temba-checkbox.test.ts +1 -1
- package/test/temba-color-picker.test.ts +4 -4
- package/test/temba-compose.test.ts +50 -55
- package/test/temba-contact-badges.test.ts +2 -2
- package/test/temba-contact-chat.test.ts +26 -46
- package/test/temba-contact-details.test.ts +2 -8
- package/test/temba-contact-fields.test.ts +4 -11
- package/test/temba-contact-history.test.ts +3 -3
- package/test/temba-contact-search.test.ts +7 -13
- package/test/temba-contact-tickets.test.ts +3 -3
- package/test/temba-content-menu.test.ts +7 -7
- package/test/temba-date.test.ts +3 -3
- package/test/temba-datepicker.test.ts +1 -1
- package/test/temba-field-manager.test.ts +1 -4
- package/test/temba-label.test.ts +6 -6
- package/test/temba-lightbox.test.ts +2 -2
- package/test/temba-list.test.ts +6 -6
- package/test/temba-menu.test.ts +4 -5
- package/test/temba-modax.test.ts +3 -3
- package/test/temba-options.test.ts +1 -1
- package/test/temba-select.test.ts +17 -17
- package/test/temba-sortable-list.test.ts +1 -1
- package/test/temba-textinput.test.ts +2 -2
- package/test/temba-tip.test.ts +5 -5
- package/test/utils.test.ts +8 -9
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { TemplateResult, css, html } from 'lit';
|
|
2
|
+
import { RapidElement } from '../RapidElement';
|
|
3
|
+
import { property } from 'lit/decorators.js';
|
|
4
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
5
|
+
|
|
6
|
+
interface ToastMessage {
|
|
7
|
+
id: number;
|
|
8
|
+
text: string;
|
|
9
|
+
level: 'info' | 'warning' | 'error';
|
|
10
|
+
visible?: boolean;
|
|
11
|
+
time: Date;
|
|
12
|
+
removeTime?: Date;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class Toast extends RapidElement {
|
|
16
|
+
@property({ type: Array })
|
|
17
|
+
messages: ToastMessage[] = [];
|
|
18
|
+
|
|
19
|
+
@property({ type: Number, attribute: 'duration' })
|
|
20
|
+
staleDuration = 5000;
|
|
21
|
+
|
|
22
|
+
@property({ type: Number, attribute: 'animation' })
|
|
23
|
+
animationDuration = 200;
|
|
24
|
+
|
|
25
|
+
@property({ type: Boolean, attribute: 'error-sticky' })
|
|
26
|
+
errorSticky = false;
|
|
27
|
+
|
|
28
|
+
@property({ type: Boolean, attribute: 'warning-sticky' })
|
|
29
|
+
warningSticky = false;
|
|
30
|
+
|
|
31
|
+
@property({ type: Boolean, attribute: 'info-sticky' })
|
|
32
|
+
infoSticky = false;
|
|
33
|
+
|
|
34
|
+
static styles = css`
|
|
35
|
+
:host {
|
|
36
|
+
position: fixed;
|
|
37
|
+
width: 400px;
|
|
38
|
+
z-index: 10000;
|
|
39
|
+
right: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.message {
|
|
43
|
+
background-color: rgba(50, 50, 50, 0.85);
|
|
44
|
+
background-color: rgba(255, 255, 255, 0.97);
|
|
45
|
+
color: rgba(0, 0, 0, 0.85);
|
|
46
|
+
padding: 0.5em 1em;
|
|
47
|
+
margin: 0.75em;
|
|
48
|
+
border-radius: 0.5em;
|
|
49
|
+
display: flex;
|
|
50
|
+
transition-property: transform, opacity;
|
|
51
|
+
transition-timing-function: ease-in-out;
|
|
52
|
+
transform: translateY(-100%);
|
|
53
|
+
opacity: 0;
|
|
54
|
+
box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 3em 2px;
|
|
55
|
+
border: 2px solid rgba(0, 0, 0, 0.3);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.message.visible {
|
|
59
|
+
transform: translateY(0);
|
|
60
|
+
opacity: 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.message.info {
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.message.warning {
|
|
67
|
+
color: rgba(255, 167, 0, 0.9);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.message.error {
|
|
71
|
+
border-color: var(--color-error);
|
|
72
|
+
color: var(--color-error);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.message.removing {
|
|
76
|
+
opacity: 0;
|
|
77
|
+
transform: translateY(-100%);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
temba-icon {
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
padding-left: 1em;
|
|
83
|
+
opacity: 0;
|
|
84
|
+
transition: all 200ms ease-in-out;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.message:hover temba-icon {
|
|
88
|
+
opacity: 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
temba-icon:hover {
|
|
92
|
+
transform: scale(1.3) translateX(-0.1em);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.message .text {
|
|
96
|
+
flex-grow: 1;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.info {
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
public checkForStaleMessages() {
|
|
104
|
+
const now = new Date();
|
|
105
|
+
|
|
106
|
+
// ignore sticky messages
|
|
107
|
+
const staleMessages = this.messages.filter((message) => {
|
|
108
|
+
if (message.level === 'error' && this.errorSticky) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (message.level === 'warning' && this.warningSticky) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (message.level === 'info' && this.infoSticky) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
staleMessages.forEach((message) => {
|
|
121
|
+
// error messages do not remove themselves
|
|
122
|
+
if (now.getTime() - message.time.getTime() > this.staleDuration) {
|
|
123
|
+
this.removeMessage(message);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if (this.messages.length === 0 && this.checker) {
|
|
128
|
+
window.clearInterval(this.checker);
|
|
129
|
+
this.checker = 0;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private checker: number;
|
|
134
|
+
private messageId: number = 0;
|
|
135
|
+
|
|
136
|
+
public addMessages(messages: ToastMessage[]) {
|
|
137
|
+
messages.forEach((message) => {
|
|
138
|
+
this.addMessage(message.text, message.level);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public addMessage(text: string, level: 'info' | 'warning' | 'error') {
|
|
143
|
+
const message: ToastMessage = {
|
|
144
|
+
id: ++this.messageId,
|
|
145
|
+
text,
|
|
146
|
+
level,
|
|
147
|
+
time: new Date()
|
|
148
|
+
};
|
|
149
|
+
this.messages.push(message);
|
|
150
|
+
|
|
151
|
+
window.setTimeout(() => {
|
|
152
|
+
message.visible = true;
|
|
153
|
+
this.requestUpdate('messages');
|
|
154
|
+
}, 100);
|
|
155
|
+
|
|
156
|
+
this.requestUpdate('messages');
|
|
157
|
+
|
|
158
|
+
if (this.checker) {
|
|
159
|
+
window.clearInterval(this.checker);
|
|
160
|
+
this.checker = 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.checker = window.setInterval(
|
|
164
|
+
this.checkForStaleMessages.bind(this),
|
|
165
|
+
1000
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public info(message: string) {
|
|
170
|
+
this.addMessage(message, 'info');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public warning(message: string) {
|
|
174
|
+
this.addMessage(message, 'warning');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public error(message: string) {
|
|
178
|
+
this.addMessage(message, 'error');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public removeMessage(message: ToastMessage) {
|
|
182
|
+
message.removeTime = new Date();
|
|
183
|
+
window.setTimeout(() => {
|
|
184
|
+
this.messages = this.messages.filter((m) => m !== message);
|
|
185
|
+
this.requestUpdate('messages');
|
|
186
|
+
}, this.animationDuration);
|
|
187
|
+
|
|
188
|
+
this.requestUpdate('messages');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private handleMessageClicked(e: MouseEvent) {
|
|
192
|
+
const ele = e.target as HTMLElement;
|
|
193
|
+
const id = parseInt(ele.getAttribute('message_id'));
|
|
194
|
+
const message = this.messages.find((m) => m.id === id);
|
|
195
|
+
if (message) {
|
|
196
|
+
this.removeMessage(message);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public render(): TemplateResult {
|
|
201
|
+
return html`
|
|
202
|
+
${repeat(
|
|
203
|
+
this.messages,
|
|
204
|
+
(message) => message.id,
|
|
205
|
+
(message) => html`
|
|
206
|
+
<div
|
|
207
|
+
style="transition-duration: ${this.animationDuration}ms"
|
|
208
|
+
class="message ${message.level} ${message.visible
|
|
209
|
+
? 'visible'
|
|
210
|
+
: ''} ${message.removeTime ? 'removing' : ''}"
|
|
211
|
+
>
|
|
212
|
+
<div class="text">${message.text}</div>
|
|
213
|
+
<temba-icon
|
|
214
|
+
name="close"
|
|
215
|
+
size="1.3"
|
|
216
|
+
message_id="${message.id}"
|
|
217
|
+
@click=${this.handleMessageClicked}
|
|
218
|
+
></temba-icon>
|
|
219
|
+
</div>
|
|
220
|
+
`
|
|
221
|
+
)}
|
|
222
|
+
`;
|
|
223
|
+
}
|
|
224
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Button } from '../button/Button';
|
|
|
4
4
|
import { Dialog } from '../dialog/Dialog';
|
|
5
5
|
import { Attachment, ContactField, Ticket, User } from '../interfaces';
|
|
6
6
|
import ColorHash from 'color-hash';
|
|
7
|
+
import { Toast } from '../toast/Toast';
|
|
7
8
|
|
|
8
9
|
export const DEFAULT_MEDIA_ENDPOINT = '/api/v2/media.json';
|
|
9
10
|
|
|
@@ -32,7 +33,7 @@ export enum Color {
|
|
|
32
33
|
BLUE = 'color:#5078b5;',
|
|
33
34
|
GREEN = 'color:#62bd6a;',
|
|
34
35
|
RED = 'color:#e36049;',
|
|
35
|
-
PURPLE = 'color:#a626a4;'
|
|
36
|
+
PURPLE = 'color:#a626a4;'
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export const log = (message: string | object, styling = '', details = []) => {
|
|
@@ -73,7 +74,7 @@ export const getHeaders = (headers: any = {}) => {
|
|
|
73
74
|
// mark us as ajax
|
|
74
75
|
fetchHeaders['X-Requested-With'] = 'XMLHttpRequest';
|
|
75
76
|
|
|
76
|
-
Object.keys(headers).forEach(key => {
|
|
77
|
+
Object.keys(headers).forEach((key) => {
|
|
77
78
|
fetchHeaders[key] = headers[key];
|
|
78
79
|
});
|
|
79
80
|
return fetchHeaders;
|
|
@@ -87,7 +88,7 @@ export const getUrl = (
|
|
|
87
88
|
return new Promise<WebResponse>((resolve, reject) => {
|
|
88
89
|
const options = {
|
|
89
90
|
method: 'GET',
|
|
90
|
-
headers: getHeaders(headers)
|
|
91
|
+
headers: getHeaders(headers)
|
|
91
92
|
};
|
|
92
93
|
|
|
93
94
|
if (controller) {
|
|
@@ -95,7 +96,7 @@ export const getUrl = (
|
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
fetch(url, options)
|
|
98
|
-
.then(response => {
|
|
99
|
+
.then((response) => {
|
|
99
100
|
response.text().then((body: string) => {
|
|
100
101
|
let json = {};
|
|
101
102
|
try {
|
|
@@ -108,11 +109,11 @@ export const getUrl = (
|
|
|
108
109
|
json,
|
|
109
110
|
url: response.url,
|
|
110
111
|
headers: response.headers,
|
|
111
|
-
status: response.status
|
|
112
|
+
status: response.status
|
|
112
113
|
});
|
|
113
114
|
});
|
|
114
115
|
})
|
|
115
|
-
.catch(error => {
|
|
116
|
+
.catch((error) => {
|
|
116
117
|
reject(error);
|
|
117
118
|
});
|
|
118
119
|
});
|
|
@@ -146,16 +147,16 @@ export const fetchResultsPage = (
|
|
|
146
147
|
.then((response: WebResponse) => {
|
|
147
148
|
resolve({
|
|
148
149
|
results: response.json.results,
|
|
149
|
-
next: response.json.next
|
|
150
|
+
next: response.json.next
|
|
150
151
|
});
|
|
151
152
|
})
|
|
152
|
-
.catch(error => reject(error));
|
|
153
|
+
.catch((error) => reject(error));
|
|
153
154
|
});
|
|
154
155
|
};
|
|
155
156
|
|
|
156
157
|
export const fetchResults = async (url: string): Promise<any[]> => {
|
|
157
158
|
if (!url) {
|
|
158
|
-
return new Promise<any[]>(resolve => resolve([]));
|
|
159
|
+
return new Promise<any[]>((resolve) => resolve([]));
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
let results: any[] = [];
|
|
@@ -177,19 +178,19 @@ export const getAssetPage = (url: string): Promise<AssetPage> => {
|
|
|
177
178
|
if (response.status >= 200 && response.status < 300) {
|
|
178
179
|
resolve({
|
|
179
180
|
assets: response.json.results,
|
|
180
|
-
next: response.json.next
|
|
181
|
+
next: response.json.next
|
|
181
182
|
});
|
|
182
183
|
} else {
|
|
183
184
|
reject(response);
|
|
184
185
|
}
|
|
185
186
|
})
|
|
186
|
-
.catch(error => reject(error));
|
|
187
|
+
.catch((error) => reject(error));
|
|
187
188
|
});
|
|
188
189
|
};
|
|
189
190
|
|
|
190
191
|
export const getAssets = async (url: string): Promise<Asset[]> => {
|
|
191
192
|
if (!url) {
|
|
192
|
-
return new Promise<Asset[]>(resolve => resolve([]));
|
|
193
|
+
return new Promise<Asset[]>((resolve) => resolve([]));
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
let assets: Asset[] = [];
|
|
@@ -231,17 +232,25 @@ export const postUrl = (
|
|
|
231
232
|
const options = {
|
|
232
233
|
method: 'POST',
|
|
233
234
|
headers: fetchHeaders,
|
|
234
|
-
body: payload
|
|
235
|
+
body: payload
|
|
235
236
|
};
|
|
236
237
|
|
|
237
238
|
return new Promise<WebResponse>((resolve, reject) => {
|
|
238
239
|
fetch(url, options)
|
|
239
|
-
.then(async response => {
|
|
240
|
+
.then(async (response) => {
|
|
240
241
|
if (response.status >= 500) {
|
|
241
242
|
reject(response);
|
|
242
243
|
return;
|
|
243
244
|
}
|
|
244
245
|
|
|
246
|
+
const toasts = response.headers.get('x-temba-toasts');
|
|
247
|
+
if (toasts) {
|
|
248
|
+
const toastEle = document.querySelector('temba-toast') as Toast;
|
|
249
|
+
if (toastEle) {
|
|
250
|
+
toastEle.addMessages(JSON.parse(toasts));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
245
254
|
response.text().then((body: string) => {
|
|
246
255
|
let json = {};
|
|
247
256
|
try {
|
|
@@ -254,11 +263,11 @@ export const postUrl = (
|
|
|
254
263
|
headers: response.headers,
|
|
255
264
|
status: response.status,
|
|
256
265
|
redirected: response.redirected,
|
|
257
|
-
url: response.url
|
|
266
|
+
url: response.url
|
|
258
267
|
});
|
|
259
268
|
});
|
|
260
269
|
})
|
|
261
|
-
.catch(error => {
|
|
270
|
+
.catch((error) => {
|
|
262
271
|
reject(error);
|
|
263
272
|
});
|
|
264
273
|
});
|
|
@@ -275,7 +284,7 @@ export const postFormData = (
|
|
|
275
284
|
): Promise<WebResponse> => {
|
|
276
285
|
return new Promise<WebResponse>((resolve, reject) => {
|
|
277
286
|
postUrl(url, formData, headers)
|
|
278
|
-
.then(response => {
|
|
287
|
+
.then((response) => {
|
|
279
288
|
if (response.status >= 200 && response.status < 400) {
|
|
280
289
|
resolve(response);
|
|
281
290
|
} else {
|
|
@@ -286,7 +295,7 @@ export const postFormData = (
|
|
|
286
295
|
}
|
|
287
296
|
}
|
|
288
297
|
})
|
|
289
|
-
.catch(err => {
|
|
298
|
+
.catch((err) => {
|
|
290
299
|
console.error(err);
|
|
291
300
|
reject(err);
|
|
292
301
|
});
|
|
@@ -319,7 +328,7 @@ export const hexToRgb = (hex: string): { r: number; g: number; b: number } => {
|
|
|
319
328
|
? {
|
|
320
329
|
r: parseInt(result[1], 16),
|
|
321
330
|
g: parseInt(result[2], 16),
|
|
322
|
-
b: parseInt(result[3], 16)
|
|
331
|
+
b: parseInt(result[3], 16)
|
|
323
332
|
}
|
|
324
333
|
: null;
|
|
325
334
|
};
|
|
@@ -343,7 +352,7 @@ export const getElementOffset = (
|
|
|
343
352
|
bottom: rect.top + rect.height,
|
|
344
353
|
right: rect.left + rect.width,
|
|
345
354
|
width: rect.width,
|
|
346
|
-
height: rect.height
|
|
355
|
+
height: rect.height
|
|
347
356
|
};
|
|
348
357
|
};
|
|
349
358
|
|
|
@@ -474,7 +483,7 @@ export const stubbable = new Stubbable();
|
|
|
474
483
|
export const timeSince = (
|
|
475
484
|
date: Date,
|
|
476
485
|
options: { compareDate?: Date; hideRecentText?: boolean; suffix?: string } = {
|
|
477
|
-
suffix: ''
|
|
486
|
+
suffix: ''
|
|
478
487
|
}
|
|
479
488
|
) => {
|
|
480
489
|
const { compareDate, hideRecentText, suffix } = options;
|
|
@@ -653,7 +662,7 @@ export const getCookieBoolean = (name: string) => {
|
|
|
653
662
|
export enum COOKIE_KEYS {
|
|
654
663
|
SETTINGS = 'settings',
|
|
655
664
|
MENU_COLLAPSED = 'menu-collapsed',
|
|
656
|
-
TICKET_SHOW_DETAILS = 'tickets.show-details'
|
|
665
|
+
TICKET_SHOW_DETAILS = 'tickets.show-details'
|
|
657
666
|
}
|
|
658
667
|
|
|
659
668
|
export const capitalize = ([first, ...rest], locale = navigator.language) =>
|
|
@@ -717,7 +726,7 @@ export const extractInitials = (text: string) => {
|
|
|
717
726
|
}
|
|
718
727
|
|
|
719
728
|
// use initial letters of words with preference to first word and capital letters
|
|
720
|
-
const firstLetters = words.map(w => w.substring(0, 1));
|
|
729
|
+
const firstLetters = words.map((w) => w.substring(0, 1));
|
|
721
730
|
const firstCapitals = firstLetters.filter(
|
|
722
731
|
(l, index) => l == l.toUpperCase() || index == 0
|
|
723
732
|
);
|
|
@@ -731,7 +740,7 @@ export const extractInitials = (text: string) => {
|
|
|
731
740
|
export const hslToHex = (h, s, l) => {
|
|
732
741
|
l /= 100;
|
|
733
742
|
const a = (s * Math.min(l, 1 - l)) / 100;
|
|
734
|
-
const f = n => {
|
|
743
|
+
const f = (n) => {
|
|
735
744
|
const k = (n + h / 30) % 12;
|
|
736
745
|
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
737
746
|
return Math.round(255 * color)
|
|
@@ -228,7 +228,7 @@ export class VectorIcon extends LitElement {
|
|
|
228
228
|
clickable: this.clickable,
|
|
229
229
|
circled: this.circled,
|
|
230
230
|
animate: !!this.animateChange || !!this.animateClick,
|
|
231
|
-
'spin-forever': this.spin
|
|
231
|
+
'spin-forever': this.spin
|
|
232
232
|
})}"
|
|
233
233
|
>
|
|
234
234
|
<svg
|
|
@@ -243,7 +243,7 @@ export class VectorIcon extends LitElement {
|
|
|
243
243
|
this.animationStep > 0,
|
|
244
244
|
[this.animateClick]: !!this.animateClick,
|
|
245
245
|
[this.animateClick + '-' + this.animationStep]:
|
|
246
|
-
this.animationStep > 0
|
|
246
|
+
this.animationStep > 0
|
|
247
247
|
})}"
|
|
248
248
|
>
|
|
249
249
|
<use
|
package/src/vectoricon/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-duplicate-enum-values */
|
|
1
2
|
// for cache busting we dynamically generate a fingerprint, use yarn svg to update
|
|
2
3
|
export const SVG_FINGERPRINT = 'e5bcaf1a10896e9b870da4b40474d67b';
|
|
3
4
|
|
|
@@ -249,5 +250,5 @@ export enum Icon {
|
|
|
249
250
|
datepicker = 'calendar',
|
|
250
251
|
slider = 'sliders-02',
|
|
251
252
|
select = 'browser',
|
|
252
|
-
input = 'edit-05'
|
|
253
|
+
input = 'edit-05'
|
|
253
254
|
}
|