@nyaruka/temba-components 0.35.2 → 0.36.1

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.
Files changed (231) hide show
  1. package/.eslintrc.js +0 -2
  2. package/.github/workflows/build.yml +1 -0
  3. package/.github/workflows/publish.yml +2 -3
  4. package/CHANGELOG.md +26 -0
  5. package/demo/index.html +1 -3
  6. package/dist/4d30c7b8.js +1 -0
  7. package/dist/index.js +0 -5737
  8. package/dist/sw.js +1 -1
  9. package/dist/sw.js.map +1 -1
  10. package/dist/workbox-919adfb7.js +2 -0
  11. package/dist/workbox-919adfb7.js.map +1 -0
  12. package/out-tsc/src/FormElement.js +1 -1
  13. package/out-tsc/src/FormElement.js.map +1 -1
  14. package/out-tsc/src/RefreshElement.js +1 -1
  15. package/out-tsc/src/RefreshElement.js.map +1 -1
  16. package/out-tsc/src/alert/Alert.js +1 -1
  17. package/out-tsc/src/alert/Alert.js.map +1 -1
  18. package/out-tsc/src/aliaseditor/AliasEditor.js +6 -6
  19. package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
  20. package/out-tsc/src/anchor/Anchor.js +1 -1
  21. package/out-tsc/src/anchor/Anchor.js.map +1 -1
  22. package/out-tsc/src/button/Button.js +1 -1
  23. package/out-tsc/src/button/Button.js.map +1 -1
  24. package/out-tsc/src/charcount/CharCount.js +1 -1
  25. package/out-tsc/src/charcount/CharCount.js.map +1 -1
  26. package/out-tsc/src/checkbox/Checkbox.js +1 -1
  27. package/out-tsc/src/checkbox/Checkbox.js.map +1 -1
  28. package/out-tsc/src/completion/Completion.js +3 -3
  29. package/out-tsc/src/completion/Completion.js.map +1 -1
  30. package/out-tsc/src/completion/helpers.js +2 -2
  31. package/out-tsc/src/completion/helpers.js.map +1 -1
  32. package/out-tsc/src/contacts/ContactChat.js +184 -156
  33. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  34. package/out-tsc/src/contacts/ContactDetails.js +1 -1
  35. package/out-tsc/src/contacts/ContactDetails.js.map +1 -1
  36. package/out-tsc/src/contacts/ContactFieldEditor.js +1 -1
  37. package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
  38. package/out-tsc/src/contacts/ContactFields.js +1 -1
  39. package/out-tsc/src/contacts/ContactFields.js.map +1 -1
  40. package/out-tsc/src/contacts/ContactHistory.js +1 -1
  41. package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
  42. package/out-tsc/src/contacts/ContactName.js +1 -1
  43. package/out-tsc/src/contacts/ContactName.js.map +1 -1
  44. package/out-tsc/src/contacts/ContactNameFetch.js +1 -1
  45. package/out-tsc/src/contacts/ContactNameFetch.js.map +1 -1
  46. package/out-tsc/src/contacts/ContactPending.js +13 -13
  47. package/out-tsc/src/contacts/ContactPending.js.map +1 -1
  48. package/out-tsc/src/contacts/ContactStoreElement.js +1 -1
  49. package/out-tsc/src/contacts/ContactStoreElement.js.map +1 -1
  50. package/out-tsc/src/contacts/ContactTickets.js +1 -1
  51. package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
  52. package/out-tsc/src/contacts/ContactUrn.js +1 -1
  53. package/out-tsc/src/contacts/ContactUrn.js.map +1 -1
  54. package/out-tsc/src/contactsearch/ContactSearch.js +1 -1
  55. package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
  56. package/out-tsc/src/date/TembaDate.js +1 -1
  57. package/out-tsc/src/date/TembaDate.js.map +1 -1
  58. package/out-tsc/src/datepicker/DatePicker.js +8 -8
  59. package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
  60. package/out-tsc/src/dialog/Dialog.js +11 -11
  61. package/out-tsc/src/dialog/Dialog.js.map +1 -1
  62. package/out-tsc/src/dialog/Modax.js +16 -17
  63. package/out-tsc/src/dialog/Modax.js.map +1 -1
  64. package/out-tsc/src/dropdown/Dropdown.js +14 -11
  65. package/out-tsc/src/dropdown/Dropdown.js.map +1 -1
  66. package/out-tsc/src/fields/FieldManager.js +1 -1
  67. package/out-tsc/src/fields/FieldManager.js.map +1 -1
  68. package/out-tsc/src/flow/FlowStoreElement.js +1 -1
  69. package/out-tsc/src/flow/FlowStoreElement.js.map +1 -1
  70. package/out-tsc/src/formfield/FormField.js +1 -1
  71. package/out-tsc/src/formfield/FormField.js.map +1 -1
  72. package/out-tsc/src/label/Label.js +2 -2
  73. package/out-tsc/src/label/Label.js.map +1 -1
  74. package/out-tsc/src/leafletmap/LeafletMap.js +12 -12
  75. package/out-tsc/src/leafletmap/LeafletMap.js.map +1 -1
  76. package/out-tsc/src/list/ContentMenu.js +163 -0
  77. package/out-tsc/src/list/ContentMenu.js.map +1 -0
  78. package/out-tsc/src/list/RunList.js +13 -12
  79. package/out-tsc/src/list/RunList.js.map +1 -1
  80. package/out-tsc/src/list/SortableList.js +14 -14
  81. package/out-tsc/src/list/SortableList.js.map +1 -1
  82. package/out-tsc/src/list/TembaList.js +14 -16
  83. package/out-tsc/src/list/TembaList.js.map +1 -1
  84. package/out-tsc/src/list/TembaMenu.js +108 -108
  85. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  86. package/out-tsc/src/list/TicketList.js +8 -8
  87. package/out-tsc/src/list/TicketList.js.map +1 -1
  88. package/out-tsc/src/loading/Loading.js +2 -2
  89. package/out-tsc/src/loading/Loading.js.map +1 -1
  90. package/out-tsc/src/omnibox/Omnibox.js +2 -2
  91. package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
  92. package/out-tsc/src/options/Options.js +2 -2
  93. package/out-tsc/src/options/Options.js.map +1 -1
  94. package/out-tsc/src/remote/Remote.js +1 -1
  95. package/out-tsc/src/remote/Remote.js.map +1 -1
  96. package/out-tsc/src/select/Select.js +2 -2
  97. package/out-tsc/src/select/Select.js.map +1 -1
  98. package/out-tsc/src/shadowless/Shadowless.js +1 -1
  99. package/out-tsc/src/shadowless/Shadowless.js.map +1 -1
  100. package/out-tsc/src/slider/TembaSlider.js +2 -2
  101. package/out-tsc/src/slider/TembaSlider.js.map +1 -1
  102. package/out-tsc/src/store/Store.js +8 -5
  103. package/out-tsc/src/store/Store.js.map +1 -1
  104. package/out-tsc/src/store/StoreElement.js +1 -1
  105. package/out-tsc/src/store/StoreElement.js.map +1 -1
  106. package/out-tsc/src/tabpane/Tab.js +1 -1
  107. package/out-tsc/src/tabpane/Tab.js.map +1 -1
  108. package/out-tsc/src/tabpane/TabPane.js +1 -1
  109. package/out-tsc/src/tabpane/TabPane.js.map +1 -1
  110. package/out-tsc/src/textinput/TextInput.js +15 -15
  111. package/out-tsc/src/textinput/TextInput.js.map +1 -1
  112. package/out-tsc/src/tip/Tip.js +2 -2
  113. package/out-tsc/src/tip/Tip.js.map +1 -1
  114. package/out-tsc/src/utils/index.js +1 -6
  115. package/out-tsc/src/utils/index.js.map +1 -1
  116. package/out-tsc/src/vectoricon/VectorIcon.js +9 -9
  117. package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
  118. package/out-tsc/temba-modules.js +3 -0
  119. package/out-tsc/temba-modules.js.map +1 -1
  120. package/out-tsc/test/MouseHelper.js +1 -1
  121. package/out-tsc/test/MouseHelper.js.map +1 -1
  122. package/out-tsc/test/temba-contact-chat.test.js +93 -50
  123. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  124. package/out-tsc/test/temba-contact-history.test.js +1 -1
  125. package/out-tsc/test/temba-contact-history.test.js.map +1 -1
  126. package/out-tsc/test/temba-content-menu.test.js +57 -0
  127. package/out-tsc/test/temba-content-menu.test.js.map +1 -0
  128. package/out-tsc/test/temba-modax.test.js +18 -19
  129. package/out-tsc/test/temba-modax.test.js.map +1 -1
  130. package/out-tsc/test/temba-select.test.js +1 -0
  131. package/out-tsc/test/temba-select.test.js.map +1 -1
  132. package/out-tsc/test/temba-tip.test.js +4 -6
  133. package/out-tsc/test/temba-tip.test.js.map +1 -1
  134. package/out-tsc/test/utils.test.js +5 -17
  135. package/out-tsc/test/utils.test.js.map +1 -1
  136. package/package.json +16 -28
  137. package/rollup.config.js +1 -0
  138. package/screenshots/truth/contacts/{contact-active-show-chat-history.png → contact-active-show-chatbox.png} +0 -0
  139. package/screenshots/truth/contacts/contact-active-ticket-closed-show-reopen-button.png +0 -0
  140. package/screenshots/truth/contacts/contact-active-ticket-open-show-chatbox.png +0 -0
  141. package/screenshots/truth/contacts/{contact-archived-hide-chat-msg.png → contact-archived-hide-chatbox.png} +0 -0
  142. package/screenshots/truth/contacts/contact-archived-ticket-closed-hide-chatbox.png +0 -0
  143. package/screenshots/truth/contacts/{contact-archived-show-chat-history.png → contact-blocked-hide-chatbox.png} +0 -0
  144. package/screenshots/truth/contacts/{contact-blocked-hide-chat-msg.png → contact-stopped-hide-chatbox.png} +0 -0
  145. package/screenshots/truth/content-menu/button-no-items.png +0 -0
  146. package/screenshots/truth/content-menu/item-no-buttons.png +0 -0
  147. package/screenshots/truth/content-menu/items-and-buttons.png +0 -0
  148. package/src/FormElement.ts +1 -1
  149. package/src/RefreshElement.ts +1 -1
  150. package/src/alert/Alert.ts +1 -1
  151. package/src/aliaseditor/AliasEditor.ts +2 -2
  152. package/src/anchor/Anchor.ts +1 -1
  153. package/src/button/Button.ts +1 -1
  154. package/src/charcount/CharCount.ts +1 -1
  155. package/src/checkbox/Checkbox.ts +1 -1
  156. package/src/completion/Completion.ts +3 -3
  157. package/src/completion/helpers.ts +8 -2
  158. package/src/contacts/ContactChat.ts +185 -157
  159. package/src/contacts/ContactDetails.ts +1 -1
  160. package/src/contacts/ContactFieldEditor.ts +1 -1
  161. package/src/contacts/ContactFields.ts +1 -1
  162. package/src/contacts/ContactHistory.ts +1 -1
  163. package/src/contacts/ContactName.ts +1 -1
  164. package/src/contacts/ContactNameFetch.ts +1 -1
  165. package/src/contacts/ContactPending.ts +1 -1
  166. package/src/contacts/ContactStoreElement.ts +1 -1
  167. package/src/contacts/ContactTickets.ts +1 -1
  168. package/src/contacts/ContactUrn.ts +1 -1
  169. package/src/contactsearch/ContactSearch.ts +1 -1
  170. package/src/date/TembaDate.ts +1 -1
  171. package/src/datepicker/DatePicker.ts +1 -1
  172. package/src/dialog/Dialog.ts +2 -2
  173. package/src/dialog/Modax.ts +17 -24
  174. package/src/dropdown/Dropdown.ts +20 -14
  175. package/src/fields/FieldManager.ts +1 -1
  176. package/src/flow/FlowStoreElement.ts +1 -1
  177. package/src/formfield/FormField.ts +1 -1
  178. package/src/label/Label.ts +2 -2
  179. package/src/leafletmap/LeafletMap.ts +1 -1
  180. package/src/list/ContentMenu.ts +177 -0
  181. package/src/list/RunList.ts +4 -3
  182. package/src/list/SortableList.ts +1 -1
  183. package/src/list/TembaList.ts +2 -4
  184. package/src/list/TembaMenu.ts +1 -1
  185. package/src/list/TicketList.ts +1 -1
  186. package/src/loading/Loading.ts +2 -2
  187. package/src/omnibox/Omnibox.ts +2 -2
  188. package/src/options/Options.ts +2 -2
  189. package/src/remote/Remote.ts +1 -1
  190. package/src/select/Select.ts +2 -2
  191. package/src/shadowless/Shadowless.ts +1 -1
  192. package/src/slider/TembaSlider.ts +2 -2
  193. package/src/store/Store.ts +11 -7
  194. package/src/store/StoreElement.ts +1 -1
  195. package/src/tabpane/Tab.ts +1 -1
  196. package/src/tabpane/TabPane.ts +1 -1
  197. package/src/textinput/TextInput.ts +3 -3
  198. package/src/tip/Tip.ts +6 -6
  199. package/src/untyped.d.ts +0 -2
  200. package/src/utils/index.ts +1 -5
  201. package/src/vectoricon/VectorIcon.ts +1 -1
  202. package/temba-modules.ts +3 -0
  203. package/test/MouseHelper.ts +1 -1
  204. package/test/temba-contact-chat.test.ts +148 -62
  205. package/test/temba-contact-history.test.ts +1 -1
  206. package/test/temba-content-menu.test.ts +84 -0
  207. package/test/temba-modax.test.ts +25 -21
  208. package/test/temba-select.test.ts +2 -0
  209. package/test/temba-tip.test.ts +10 -5
  210. package/test/utils.test.ts +6 -19
  211. package/test-assets/contacts/{contact-barak-archived → contact-barack-archived} +1 -1
  212. package/test-assets/contacts/contact-carter-active +52 -0
  213. package/test-assets/contacts/contact-michelle-blocked +1 -1
  214. package/test-assets/contacts/contact-tim-stopped +1 -1
  215. package/test-assets/list/content-menu-archived-contacts.json +12 -0
  216. package/test-assets/list/content-menu-contact-read.json +49 -0
  217. package/test-assets/list/content-menu-new-campaign.json +15 -0
  218. package/test-assets/tickets/empty.json +6 -0
  219. package/test-assets/tickets/ticket-barack-closed.json +22 -0
  220. package/test-assets/tickets/ticket-carter-closed.json +22 -0
  221. package/test-assets/tickets/ticket-carter-open.json +22 -0
  222. package/web-test-runner.config.mjs +21 -18
  223. package/dist/41042aab.js +0 -5738
  224. package/dist/templates/components-body.html +0 -1
  225. package/dist/templates/components-head.html +0 -1
  226. package/dist/workbox-80efdfd1.js +0 -2
  227. package/dist/workbox-80efdfd1.js.map +0 -1
  228. package/screenshots/truth/contacts/contact-active-show-chat-msg.png +0 -0
  229. package/screenshots/truth/contacts/contact-blocked-show-chat-history.png +0 -0
  230. package/screenshots/truth/contacts/contact-stopped-hide-chat-msg.png +0 -0
  231. package/screenshots/truth/contacts/contact-stopped-show-chat-history.png +0 -0
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { RapidElement } from '../RapidElement';
4
4
 
5
5
  export class Dropdown extends RapidElement {
@@ -71,7 +71,7 @@ export class Dropdown extends RapidElement {
71
71
  arrowOffset = this.arrowSize * 2;
72
72
 
73
73
  @property({ type: Number })
74
- offsetX = -10;
74
+ offsetX = 0;
75
75
 
76
76
  @property({ type: Number })
77
77
  offsetY = 0;
@@ -79,11 +79,7 @@ export class Dropdown extends RapidElement {
79
79
  public firstUpdated(props: any) {
80
80
  super.firstUpdated(props);
81
81
 
82
- const dropdown = this.shadowRoot.querySelector(
83
- '.dropdown'
84
- ) as HTMLDivElement;
85
82
  const arrow = this.shadowRoot.querySelector('.arrow') as HTMLDivElement;
86
-
87
83
  arrow.style.borderWidth = this.arrowSize + 'px';
88
84
  arrow.style.top = '-' + this.arrowSize + 'px';
89
85
 
@@ -93,14 +89,9 @@ export class Dropdown extends RapidElement {
93
89
  arrow.style.left = this.arrowOffset + 'px';
94
90
  }
95
91
 
96
- dropdown.style.marginTop = this.offsetY + 'px';
97
-
98
- if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
99
- dropdown.style.marginLeft =
100
- '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
101
- } else {
102
- dropdown.style.marginLeft = this.offsetX + 'px';
103
- }
92
+ const dropdown = this.shadowRoot.querySelector(
93
+ '.dropdown'
94
+ ) as HTMLDivElement;
104
95
 
105
96
  dropdown.addEventListener('blur', () => {
106
97
  // we nest this to deal with clicking the toggle to close
@@ -116,6 +107,21 @@ export class Dropdown extends RapidElement {
116
107
 
117
108
  public updated(changedProperties: Map<string, any>) {
118
109
  super.updated(changedProperties);
110
+
111
+ if (changedProperties.has('offsetY') || changedProperties.has('offsetX')) {
112
+ const dropdown = this.shadowRoot.querySelector(
113
+ '.dropdown'
114
+ ) as HTMLDivElement;
115
+
116
+ dropdown.style.marginTop = this.offsetY + 'px';
117
+ if (dropdown.offsetLeft + dropdown.clientWidth > window.outerWidth) {
118
+ dropdown.style.marginLeft =
119
+ '-' + (dropdown.clientWidth - this.clientWidth - this.offsetX) + 'px';
120
+ } else {
121
+ dropdown.style.marginLeft = this.offsetX + 'px';
122
+ }
123
+ }
124
+
119
125
  if (changedProperties.has('open')) {
120
126
  if (this.open) {
121
127
  this.classList.add('open');
@@ -1,5 +1,5 @@
1
1
  import { css, html, PropertyValueMap, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { ContactField, CustomEventType } from '../interfaces';
4
4
 
5
5
  import { SortableList } from '../list/SortableList';
@@ -1,5 +1,5 @@
1
1
  import { html, PropertyValueMap, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { FlowDetails } from '../interfaces';
4
4
  import { StoreElement } from '../store/StoreElement';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { TemplateResult, html, css, LitElement } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
 
4
4
  /**
5
5
  * A small wrapper to display labels and help text in a smartmin style.
@@ -1,7 +1,7 @@
1
1
  import { LitElement, TemplateResult, html, css } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { getClasses } from '../utils';
4
- import { styleMap } from 'lit-html/directives/style-map';
4
+ import { styleMap } from 'lit-html/directives/style-map.js';
5
5
 
6
6
  export default class Label extends LitElement {
7
7
  static get styles() {
@@ -9,7 +9,7 @@ import {
9
9
  Path,
10
10
  } from 'leaflet';
11
11
  import { css, html, LitElement } from 'lit';
12
- import { property } from 'lit/decorators';
12
+ import { property } from 'lit/decorators.js';
13
13
 
14
14
  import { FeatureProperties } from '../interfaces';
15
15
  import { getUrl, WebResponse } from '../utils';
@@ -0,0 +1,177 @@
1
+ import { TemplateResult, html, css, PropertyValueMap } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { CustomEventType } from '../interfaces';
4
+
5
+ import { RapidElement } from '../RapidElement';
6
+ import { getUrl, WebResponse } from '../utils';
7
+
8
+ const HEADERS = {
9
+ 'Temba-Content-Menu': '1',
10
+ 'Temba-Spa': '1',
11
+ };
12
+
13
+ export interface ContentMenuItem {
14
+ type: string;
15
+ as_button: boolean;
16
+ label: string;
17
+ url: string;
18
+ disabled: boolean;
19
+ modal_id: string;
20
+ on_submit: string;
21
+ primary: boolean;
22
+ title: string;
23
+ on_click: null;
24
+ link_class: string;
25
+ }
26
+
27
+ export enum ContentMenuItemType {
28
+ LINK = 'link',
29
+ JS = 'js',
30
+ URL_POST = 'url_post',
31
+ MODAX = 'modax',
32
+ DIVIDER = 'divider',
33
+ }
34
+
35
+ export class ContentMenu extends RapidElement {
36
+ static get styles() {
37
+ return css`
38
+ .container {
39
+ --button-y: 0.4em;
40
+ --button-x: 1em;
41
+ display: flex;
42
+ }
43
+
44
+ .button_item,
45
+ .primary_button_item {
46
+ margin-left: 1rem;
47
+ }
48
+
49
+ .toggle {
50
+ --icon-color: rgb(102, 102, 102);
51
+ padding: 0.5rem;
52
+ margin-left: 0.5rem;
53
+ }
54
+
55
+ .toggle:hover {
56
+ background: rgba(0, 0, 0, 0.05);
57
+ border-radius: var(--curvature);
58
+ --icon-color: rgb(136, 136, 136);
59
+ }
60
+
61
+ .dropdown {
62
+ padding: 1rem 1.5rem;
63
+ color: rgb(45, 45, 45);
64
+ z-index: 50;
65
+ min-width: 200px;
66
+ }
67
+
68
+ .divider {
69
+ border-bottom: 1px solid rgb(237, 237, 237);
70
+ margin: 1rem -1.5em;
71
+ }
72
+
73
+ .item {
74
+ white-space: nowrap;
75
+ margin: 0.2em 0em;
76
+ font-size: 1.1rem;
77
+ cursor: pointer;
78
+ font-weight: 400;
79
+ }
80
+
81
+ .item:hover {
82
+ color: rgb(var(--primary-rgb));
83
+ }
84
+ `;
85
+ }
86
+
87
+ @property({ type: String })
88
+ endpoint: string;
89
+
90
+ @property({ type: Array })
91
+ buttons: ContentMenuItem[] = [];
92
+
93
+ @property({ type: Array })
94
+ items: ContentMenuItem[] = [];
95
+
96
+ private fetchContentMenu() {
97
+ if (this.endpoint) {
98
+ getUrl(this.endpoint, null, HEADERS)
99
+ .then((response: WebResponse) => {
100
+ const json = response.json;
101
+ const contentMenu = json.items as ContentMenuItem[];
102
+ if (contentMenu) {
103
+ this.buttons = contentMenu.filter(item => item.as_button);
104
+ this.items = contentMenu.filter(item => !item.as_button);
105
+ } else {
106
+ this.buttons = [];
107
+ this.items = [];
108
+ }
109
+
110
+ this.fireCustomEvent(CustomEventType.Loaded, {
111
+ buttons: this.buttons,
112
+ items: this.items,
113
+ });
114
+ })
115
+ .catch((error: any) => {
116
+ console.error(error);
117
+ });
118
+ }
119
+ }
120
+
121
+ public refresh() {
122
+ this.fetchContentMenu();
123
+ }
124
+
125
+ protected updated(changes: Map<string, any>) {
126
+ if (changes.has('endpoint')) {
127
+ this.fetchContentMenu();
128
+ }
129
+ }
130
+
131
+ private handleItemClicked(item: ContentMenuItem) {
132
+ this.fireCustomEvent(CustomEventType.Selection, item);
133
+ }
134
+
135
+ public render(): TemplateResult {
136
+ return html`
137
+ <div class="container">
138
+ ${this.buttons.map(button => {
139
+ return html`<temba-button
140
+ class="${button.primary ? 'primary_button_item' : 'button_item'}"
141
+ name=${button.label}
142
+ @click=${() => this.handleItemClicked(button)}
143
+ >
144
+ ${button.label}
145
+ </temba-button>`;
146
+ })}
147
+ ${this.items && this.items.length > 0
148
+ ? html` <temba-dropdown
149
+ arrowsize="8"
150
+ arrowoffset="-12"
151
+ offsetx="-200"
152
+ offsety="6"
153
+ >
154
+ <div slot="toggle" class="toggle">
155
+ <temba-icon name="menu" size="1.5"></temba-icon>
156
+ </div>
157
+ <div slot="dropdown" class="dropdown">
158
+ ${this.items.map(item => {
159
+ if (item.type === ContentMenuItemType.DIVIDER) {
160
+ return html` <div class="divider"></div>`;
161
+ } else {
162
+ return html` <div
163
+ class="item"
164
+ name=${item.label}
165
+ @click=${() => this.handleItemClicked(item)}
166
+ >
167
+ ${item.label}
168
+ </div>`;
169
+ }
170
+ })}
171
+ </div>
172
+ </temba-dropdown>`
173
+ : null}
174
+ </div>
175
+ `;
176
+ }
177
+ }
@@ -1,8 +1,9 @@
1
1
  import { html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { Checkbox } from '../checkbox/Checkbox';
4
4
  import { Select } from '../select/Select';
5
5
  import { capitalize } from '../utils';
6
+ import { Icon } from '../vectoricon';
6
7
  import { TembaList } from './TembaList';
7
8
 
8
9
  const FLOW_COLOR = 'rgb(223, 65, 159)';
@@ -268,7 +269,7 @@ export class RunList extends TembaList {
268
269
  <temba-date
269
270
  value="${this.selectedRun.created_on}"
270
271
  display="duration"
271
- />
272
+ ></temba-date>
272
273
  </div>`}
273
274
  </div>
274
275
  </div>
@@ -286,7 +287,7 @@ export class RunList extends TembaList {
286
287
  <temba-icon
287
288
  clickable
288
289
  style="margin-left:0.75em;"
289
- name="trash"
290
+ name=${Icon.delete}
290
291
  onclick="deleteRun(${this.selectedRun.id});"
291
292
  ></temba-icon>
292
293
  </div>
@@ -1,5 +1,5 @@
1
1
  import { css, html, PropertyValueMap, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement } from '../RapidElement';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { Store } from '../store/Store';
@@ -143,9 +143,7 @@ export class TembaList extends RapidElement {
143
143
  }
144
144
 
145
145
  if (changedProperties.has('mostRecentItem')) {
146
- if (this.mostRecentItem) {
147
- this.fireCustomEvent(CustomEventType.Refreshed);
148
- }
146
+ this.fireCustomEvent(CustomEventType.Refreshed);
149
147
  }
150
148
 
151
149
  if (changedProperties.has('cursorIndex')) {
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { fetchResults, getClasses } from '../utils';
@@ -1,5 +1,5 @@
1
1
  import { html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { TembaList } from './TembaList';
4
4
  import { timeSince } from '../utils';
5
5
  import { Contact } from '../interfaces';
@@ -1,6 +1,6 @@
1
1
  import { html, TemplateResult, css, LitElement } from 'lit';
2
- import { property } from 'lit/decorators';
3
- import { styleMap } from 'lit-html/directives/style-map';
2
+ import { property } from 'lit/decorators.js';
3
+ import { styleMap } from 'lit-html/directives/style-map.js';
4
4
  import { range } from '../utils';
5
5
 
6
6
  export class Loading extends LitElement {
@@ -1,6 +1,6 @@
1
1
  import { TemplateResult, html, css } from 'lit';
2
- import { property } from 'lit/decorators';
3
- import { styleMap } from 'lit-html/directives/style-map';
2
+ import { property } from 'lit/decorators.js';
3
+ import { styleMap } from 'lit-html/directives/style-map.js';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { Select } from '../select/Select';
6
6
  import { Icon } from '../vectoricon';
@@ -1,8 +1,8 @@
1
1
  import { TemplateResult, html, css } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement, EventHandler } from '../RapidElement';
5
- import { styleMap } from 'lit-html/directives/style-map';
5
+ import { styleMap } from 'lit-html/directives/style-map.js';
6
6
  import {
7
7
  getClasses,
8
8
  getScrollParent,
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property, customElement } from 'lit/decorators';
2
+ import { property, customElement } from 'lit/decorators.js';
3
3
  import { RapidElement } from '../RapidElement';
4
4
 
5
5
  @customElement('temba-remote')
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-empty-function */
2
2
  import { TemplateResult, html, css } from 'lit';
3
- import { property } from 'lit/decorators';
3
+ import { property } from 'lit/decorators.js';
4
4
  import {
5
5
  getUrl,
6
6
  getClasses,
@@ -20,7 +20,7 @@ import {
20
20
  executeCompletionQuery,
21
21
  } from '../completion/helpers';
22
22
  import { Store } from '../store/Store';
23
- import { styleMap } from 'lit-html/directives/style-map';
23
+ import { styleMap } from 'lit-html/directives/style-map.js';
24
24
  import { Icon } from '../vectoricon';
25
25
 
26
26
  const LOOK_AHEAD = 20;
@@ -1,4 +1,4 @@
1
- import { customElement, property } from 'lit/decorators';
1
+ import { customElement, property } from 'lit/decorators.js';
2
2
  import { TemplateResult, LitElement } from 'lit';
3
3
 
4
4
  @customElement('temba-shadowless')
@@ -1,6 +1,6 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { styleMap } from 'lit-html/directives/style-map';
3
- import { property } from 'lit/decorators';
2
+ import { styleMap } from 'lit-html/directives/style-map.js';
3
+ import { property } from 'lit/decorators.js';
4
4
  import { FormElement } from '../FormElement';
5
5
  import { getClasses } from '../utils';
6
6
 
@@ -1,4 +1,4 @@
1
- import { property } from 'lit/decorators';
1
+ import { property } from 'lit/decorators.js';
2
2
  import {
3
3
  fetchResults,
4
4
  getUrl,
@@ -6,6 +6,8 @@ import {
6
6
  Asset,
7
7
  WebResponse,
8
8
  postUrl,
9
+ postJSON,
10
+ postForm,
9
11
  } from '../utils';
10
12
  import {
11
13
  ContactField,
@@ -18,10 +20,6 @@ import {
18
20
  } from '../interfaces';
19
21
  import { RapidElement } from '../RapidElement';
20
22
  import Lru from 'tiny-lru';
21
- import {
22
- HumanizeDurationLanguage,
23
- HumanizeDuration,
24
- } from 'humanize-duration-ts';
25
23
  import { DateTime } from 'luxon';
26
24
 
27
25
  export class Store extends RapidElement {
@@ -66,8 +64,6 @@ export class Store extends RapidElement {
66
64
  private workspace: Workspace;
67
65
  private featuredFields: ContactField[] = [];
68
66
 
69
- private langService = new HumanizeDurationLanguage();
70
- private humanizer = new HumanizeDuration(this.langService);
71
67
 
72
68
  // http promise to monitor for completeness
73
69
  public httpComplete: Promise<void | WebResponse[]>;
@@ -263,6 +259,14 @@ export class Store extends RapidElement {
263
259
  .toLocaleString(DateTime.DATETIME_SHORT);
264
260
  }
265
261
 
262
+ public postJSON(url: string, payload: any = '') {
263
+ return postJSON(url, payload);
264
+ }
265
+
266
+ public postForm(url: string, payload: any | FormData) {
267
+ return postForm(url, payload);
268
+ }
269
+
266
270
  public postUrl(
267
271
  url: string,
268
272
  payload: any = '',
@@ -1,5 +1,5 @@
1
1
  import { PropertyValueMap } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { Store } from './Store';
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { RapidElement } from '../RapidElement';
4
4
  import { getClasses } from '../utils';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { CustomEventType } from '../interfaces';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { getClasses } from '../utils';
@@ -1,7 +1,7 @@
1
1
  import { TemplateResult, html, css } from 'lit';
2
- import { property } from 'lit/decorators';
3
- import { ifDefined } from 'lit-html/directives/if-defined';
4
- import { styleMap } from 'lit-html/directives/style-map';
2
+ import { property } from 'lit/decorators.js';
3
+ import { ifDefined } from 'lit-html/directives/if-defined.js';
4
+ import { styleMap } from 'lit-html/directives/style-map.js';
5
5
  import { FormElement } from '../FormElement';
6
6
  import { Modax } from '../dialog/Modax';
7
7
  import { sanitize } from './helpers';
package/src/tip/Tip.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { property } from 'lit/decorators';
3
- import { styleMap } from 'lit-html/directives/style-map';
2
+ import { property } from 'lit/decorators.js';
3
+ import { styleMap } from 'lit-html/directives/style-map.js';
4
4
  import { RapidElement } from '../RapidElement';
5
5
  import { getClasses } from '../utils';
6
6
  import { getCenter, getMiddle } from './helpers';
@@ -61,6 +61,7 @@ export class Tip extends RapidElement {
61
61
  }
62
62
  `;
63
63
  }
64
+
64
65
  @property({ type: String })
65
66
  text: string;
66
67
 
@@ -86,11 +87,13 @@ export class Tip extends RapidElement {
86
87
  poppedTop: boolean;
87
88
 
88
89
  arrow: string;
89
-
90
90
  arrowTop: number;
91
91
  arrowLeft: number;
92
92
  arrowDirection: string;
93
93
 
94
+ lastEnter = 0;
95
+ failSafe = 0;
96
+
94
97
  public updated(changed: Map<string, any>) {
95
98
  if ((changed.has('visible') || changed.has('text')) && this.visible) {
96
99
  this.calculatePosition();
@@ -148,9 +151,6 @@ export class Tip extends RapidElement {
148
151
  }
149
152
  }
150
153
 
151
- lastEnter = 0;
152
- failSafe = 0;
153
-
154
154
  private handleMouseEnter() {
155
155
  this.lastEnter = window.setTimeout(() => {
156
156
  this.visible = true;
package/src/untyped.d.ts CHANGED
@@ -16,5 +16,3 @@ declare function moveMouse(x: number, y: number);
16
16
  declare function mouseDown();
17
17
  declare function mouseUp();
18
18
  declare function setViewport({}: any);
19
-
20
- declare function readStaticFile(filename: string);
@@ -234,11 +234,7 @@ export const postFormData = (
234
234
  postUrl(url, formData, true)
235
235
  .then(response => {
236
236
  if (response.status >= 200 && response.status < 300) {
237
- if (response.json.status === 'success' || response.status === 201) {
238
- resolve(response);
239
- } else {
240
- reject({ errors: response.json.errors });
241
- }
237
+ resolve(response);
242
238
  }
243
239
  reject('Server failure');
244
240
  })
@@ -1,5 +1,5 @@
1
1
  import { LitElement, TemplateResult, html, css } from 'lit';
2
- import { property } from 'lit/decorators';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { Icon } from '.';
4
4
 
5
5
  import { getClasses } from '../utils';
package/temba-modules.ts CHANGED
@@ -41,6 +41,7 @@ import { ContactNameFetch } from './src/contacts/ContactNameFetch';
41
41
  import DatePicker from './src/datepicker/DatePicker';
42
42
  import { FieldManager } from './src/fields/FieldManager';
43
43
  import { SortableList } from './src/list/SortableList';
44
+ import { ContentMenu } from './src/list/ContentMenu';
44
45
  import { TembaDate } from './src/date/TembaDate';
45
46
 
46
47
  export function addCustomElement(name: string, comp: any) {
@@ -69,6 +70,7 @@ addCustomElement('temba-contact-field', ContactFieldEditor);
69
70
  addCustomElement('temba-contact-fields', ContactFields);
70
71
  addCustomElement('temba-field-manager', FieldManager);
71
72
  addCustomElement('temba-urn', ContactUrn);
73
+ addCustomElement('temba-content-menu', ContentMenu);
72
74
 
73
75
  addCustomElement('temba-field', FormField);
74
76
  addCustomElement('temba-dialog', Dialog);
@@ -93,3 +95,4 @@ addCustomElement('temba-contact-badges', ContactBadges);
93
95
  addCustomElement('temba-contact-pending', ContactPending);
94
96
  addCustomElement('temba-contact-tickets', ContactTickets);
95
97
  addCustomElement('temba-slider', TembaSlider);
98
+ addCustomElement('temba-content-menu', ContentMenu);
@@ -1,5 +1,5 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
- import { customElement } from 'lit/decorators';
2
+ import { customElement } from 'lit/decorators.js';
3
3
  import { RapidElement } from '../src/RapidElement';
4
4
 
5
5
  @customElement('mouse-helper')