@nyaruka/temba-components 0.26.8 → 0.26.9

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 (98) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/demo/index.html +9 -1
  3. package/dist/{d08b61e5.js → d0cc86be.js} +386 -38
  4. package/dist/index.js +386 -38
  5. package/dist/static/icons/symbol-defs.svg +13 -1
  6. package/dist/static/img/schemes/email.svg +1 -0
  7. package/dist/static/img/schemes/facebook.svg +1 -0
  8. package/dist/static/img/schemes/instagram.svg +1 -0
  9. package/dist/static/img/schemes/line.svg +1 -0
  10. package/dist/static/img/schemes/messenger.svg +1 -0
  11. package/dist/static/img/schemes/tel.svg +34 -0
  12. package/dist/static/img/schemes/telegram.svg +1 -0
  13. package/dist/static/img/schemes/twitter.svg +1 -0
  14. package/dist/static/img/schemes/viber.svg +1 -0
  15. package/dist/static/img/schemes/vk.svg +1 -0
  16. package/dist/static/img/schemes/whatsapp.svg +1 -0
  17. package/dist/sw.js +1 -1
  18. package/dist/sw.js.map +1 -1
  19. package/dist/templates/components-body.html +1 -1
  20. package/dist/templates/components-head.html +1 -1
  21. package/out-tsc/src/RapidElement.js.map +1 -1
  22. package/out-tsc/src/RefreshElement.js +28 -0
  23. package/out-tsc/src/RefreshElement.js.map +1 -0
  24. package/out-tsc/src/button/Button.js +4 -0
  25. package/out-tsc/src/button/Button.js.map +1 -1
  26. package/out-tsc/src/contacts/ContactChat.js +5 -13
  27. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  28. package/out-tsc/src/contacts/ContactFieldEditor.js +199 -0
  29. package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -0
  30. package/out-tsc/src/contacts/ContactFields.js +106 -0
  31. package/out-tsc/src/contacts/ContactFields.js.map +1 -0
  32. package/out-tsc/src/contacts/ContactGroups.js +39 -0
  33. package/out-tsc/src/contacts/ContactGroups.js.map +1 -0
  34. package/out-tsc/src/contacts/ContactName.js +40 -0
  35. package/out-tsc/src/contacts/ContactName.js.map +1 -0
  36. package/out-tsc/src/contacts/ContactStoreElement.js +44 -0
  37. package/out-tsc/src/contacts/ContactStoreElement.js.map +1 -0
  38. package/out-tsc/src/contacts/ContactUrn.js +38 -0
  39. package/out-tsc/src/contacts/ContactUrn.js.map +1 -0
  40. package/out-tsc/src/contacts/events.js +42 -4
  41. package/out-tsc/src/contacts/events.js.map +1 -1
  42. package/out-tsc/src/interfaces.js +1 -0
  43. package/out-tsc/src/interfaces.js.map +1 -1
  44. package/out-tsc/src/label/Label.js +32 -12
  45. package/out-tsc/src/label/Label.js.map +1 -1
  46. package/out-tsc/src/select/Select.js +4 -4
  47. package/out-tsc/src/select/Select.js.map +1 -1
  48. package/out-tsc/src/store/Store.js +97 -3
  49. package/out-tsc/src/store/Store.js.map +1 -1
  50. package/out-tsc/src/store/StoreElement.js +55 -0
  51. package/out-tsc/src/store/StoreElement.js.map +1 -0
  52. package/out-tsc/src/textinput/TextInput.js +35 -17
  53. package/out-tsc/src/textinput/TextInput.js.map +1 -1
  54. package/out-tsc/src/vectoricon/VectorIcon.js +16 -14
  55. package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
  56. package/out-tsc/temba-modules.js +12 -0
  57. package/out-tsc/temba-modules.js.map +1 -1
  58. package/package.json +3 -3
  59. package/rollup.config.js +1 -0
  60. package/src/RapidElement.ts +0 -1
  61. package/src/RefreshElement.ts +33 -0
  62. package/src/button/Button.ts +4 -0
  63. package/src/contacts/ContactChat.ts +7 -16
  64. package/src/contacts/ContactFieldEditor.ts +201 -0
  65. package/src/contacts/ContactFields.ts +112 -0
  66. package/src/contacts/ContactGroups.ts +41 -0
  67. package/src/contacts/ContactName.ts +37 -0
  68. package/src/contacts/ContactStoreElement.ts +51 -0
  69. package/src/contacts/ContactUrn.ts +38 -0
  70. package/src/contacts/events.ts +41 -4
  71. package/src/interfaces.ts +2 -0
  72. package/src/label/Label.ts +30 -7
  73. package/src/select/Select.ts +4 -4
  74. package/src/store/Store.ts +124 -3
  75. package/src/store/StoreElement.ts +71 -0
  76. package/src/textinput/TextInput.ts +48 -27
  77. package/src/vectoricon/VectorIcon.ts +19 -14
  78. package/static/icons/Read Me.txt +1 -1
  79. package/static/icons/SVG/calendar1.svg +5 -0
  80. package/static/icons/SVG/corner-down-left.svg +5 -0
  81. package/static/icons/SVG/more-horizontal.svg +5 -0
  82. package/static/icons/SVG/refresh-cw.svg +5 -0
  83. package/static/icons/demo-external-svg.html +21 -1
  84. package/static/icons/demo.html +34 -2
  85. package/static/icons/selection.json +412 -316
  86. package/static/icons/symbol-defs.svg +13 -1
  87. package/static/img/schemes/email.svg +1 -0
  88. package/static/img/schemes/facebook.svg +1 -0
  89. package/static/img/schemes/instagram.svg +1 -0
  90. package/static/img/schemes/line.svg +1 -0
  91. package/static/img/schemes/messenger.svg +1 -0
  92. package/static/img/schemes/tel.svg +34 -0
  93. package/static/img/schemes/telegram.svg +1 -0
  94. package/static/img/schemes/twitter.svg +1 -0
  95. package/static/img/schemes/viber.svg +1 -0
  96. package/static/img/schemes/vk.svg +1 -0
  97. package/static/img/schemes/whatsapp.svg +1 -0
  98. package/temba-modules.ts +12 -0
@@ -1 +1 @@
1
- {"version":3,"file":"temba-modules.js","sourceRoot":"","sources":["../temba-modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,IAAS;IACtD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACpC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KAC1C;AACH,CAAC;AAED,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACzC,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AACvC,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AACvC,gBAAgB,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;AAC/C,gBAAgB,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;AACjD,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAC7C,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACzC,gBAAgB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC3C,gBAAgB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC3C,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACzC,gBAAgB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC3C,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAEnC,gBAAgB,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAC3C,gBAAgB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACzC,gBAAgB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AACvC,gBAAgB,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;AAC/C,gBAAgB,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;AAC1D,gBAAgB,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;AACpD,gBAAgB,CAAC,uBAAuB,EAAE,cAAc,CAAC,CAAC;AAC1D,gBAAgB,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;AAClD,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;AAC1C,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;AAC1C,gBAAgB,CAAC,sBAAsB,EAAE,aAAa,CAAC,CAAC;AACxD,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAC3C,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAC7C,gBAAgB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AACxC,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC","sourcesContent":["import { Checkbox } from './src/checkbox/Checkbox';\nimport { TextInput } from './src/textinput/TextInput';\nimport { Store } from './src/store/Store';\nimport { Select } from './src/select/Select';\nimport { Completion } from './src/completion/Completion';\nimport { Modax } from './src/dialog/Modax';\nimport { Dialog } from './src/dialog/Dialog';\nimport { Button } from './src/button/Button';\nimport { FormField } from './src/formfield/FormField';\nimport { Loading } from './src/loading/Loading';\nimport { CharCount } from './src/charcount/CharCount';\nimport { Options } from './src/options/Options';\nimport { ContactChat } from './src/contacts/ContactChat';\nimport { ContactHistory } from './src/contacts/ContactHistory';\nimport { TicketList } from './src/list/TicketList';\nimport { ContactDetails } from './src/contacts/ContactDetails';\nimport { TembaList } from './src/list/TembaList';\nimport { ContactSearch } from './src/contactsearch/ContactSearch';\nimport { VectorIcon } from './src/vectoricon/VectorIcon';\nimport { Alert } from './src/alert/Alert';\nimport { Omnibox } from './src/omnibox/Omnibox';\nimport { Tip } from './src/tip/Tip';\nimport { TembaMenu } from './src/list/TembaMenu';\nimport { Anchor } from './src/anchor/Anchor';\nimport { Dropdown } from './src/dropdown/Dropdown';\nimport { TabPane } from './src/tabpane/TabPane';\nimport { Tab } from './src/tabpane/Tab';\n\nexport function addCustomElement(name: string, comp: any) {\n if (!window.customElements.get(name)) {\n window.customElements.define(name, comp);\n }\n}\n\naddCustomElement('temba-anchor', Anchor);\naddCustomElement('temba-alert', Alert);\naddCustomElement('temba-store', Store);\naddCustomElement('temba-textinput', TextInput);\naddCustomElement('temba-completion', Completion);\naddCustomElement('temba-checkbox', Checkbox);\naddCustomElement('temba-select', Select);\naddCustomElement('temba-options', Options);\naddCustomElement('temba-loading', Loading);\naddCustomElement('temba-button', Button);\naddCustomElement('temba-omnibox', Omnibox);\naddCustomElement('temba-tip', Tip);\n\naddCustomElement('temba-field', FormField);\naddCustomElement('temba-dialog', Dialog);\naddCustomElement('temba-modax', Modax);\naddCustomElement('temba-charcount', CharCount);\naddCustomElement('temba-contact-history', ContactHistory);\naddCustomElement('temba-contact-chat', ContactChat);\naddCustomElement('temba-contact-details', ContactDetails);\naddCustomElement('temba-ticket-list', TicketList);\naddCustomElement('temba-list', TembaList);\naddCustomElement('temba-menu', TembaMenu);\naddCustomElement('temba-contact-search', ContactSearch);\naddCustomElement('temba-icon', VectorIcon);\naddCustomElement('temba-dropdown', Dropdown);\naddCustomElement('temba-tabs', TabPane);\naddCustomElement('temba-tab', Tab);\n"]}
1
+ {"version":3,"file":"temba-modules.js","sourceRoot":"","sources":["../temba-modules.ts"],"names":[],"mappings":"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","sourcesContent":["import { Checkbox } from './src/checkbox/Checkbox';\nimport { TextInput } from './src/textinput/TextInput';\nimport { Store } from './src/store/Store';\nimport { Select } from './src/select/Select';\nimport { Completion } from './src/completion/Completion';\nimport { Modax } from './src/dialog/Modax';\nimport { Dialog } from './src/dialog/Dialog';\nimport { Button } from './src/button/Button';\nimport { FormField } from './src/formfield/FormField';\nimport { Loading } from './src/loading/Loading';\nimport { CharCount } from './src/charcount/CharCount';\nimport { Options } from './src/options/Options';\nimport { ContactChat } from './src/contacts/ContactChat';\nimport { ContactHistory } from './src/contacts/ContactHistory';\nimport { TicketList } from './src/list/TicketList';\nimport { ContactDetails } from './src/contacts/ContactDetails';\nimport { TembaList } from './src/list/TembaList';\nimport { ContactSearch } from './src/contactsearch/ContactSearch';\nimport { VectorIcon } from './src/vectoricon/VectorIcon';\nimport { Alert } from './src/alert/Alert';\nimport { Omnibox } from './src/omnibox/Omnibox';\nimport { Tip } from './src/tip/Tip';\nimport { TembaMenu } from './src/list/TembaMenu';\nimport { Anchor } from './src/anchor/Anchor';\nimport { Dropdown } from './src/dropdown/Dropdown';\nimport { TabPane } from './src/tabpane/TabPane';\nimport { Tab } from './src/tabpane/Tab';\nimport Label from './src/label/Label';\nimport { ContactGroups } from './src/contacts/ContactGroups';\nimport { ContactName } from './src/contacts/ContactName';\nimport { ContactUrn } from './src/contacts/ContactUrn';\nimport { ContactFields } from './src/contacts/ContactFields';\nimport { ContactFieldEditor } from './src/contacts/ContactFieldEditor';\n\nexport function addCustomElement(name: string, comp: any) {\n if (!window.customElements.get(name)) {\n window.customElements.define(name, comp);\n }\n}\n\naddCustomElement('temba-anchor', Anchor);\naddCustomElement('temba-alert', Alert);\naddCustomElement('temba-store', Store);\naddCustomElement('temba-textinput', TextInput);\naddCustomElement('temba-completion', Completion);\naddCustomElement('temba-checkbox', Checkbox);\naddCustomElement('temba-select', Select);\naddCustomElement('temba-options', Options);\naddCustomElement('temba-loading', Loading);\naddCustomElement('temba-button', Button);\naddCustomElement('temba-omnibox', Omnibox);\naddCustomElement('temba-tip', Tip);\n\naddCustomElement('temba-field', FormField);\naddCustomElement('temba-dialog', Dialog);\naddCustomElement('temba-modax', Modax);\naddCustomElement('temba-charcount', CharCount);\naddCustomElement('temba-contact-history', ContactHistory);\naddCustomElement('temba-contact-chat', ContactChat);\naddCustomElement('temba-contact-details', ContactDetails);\naddCustomElement('temba-ticket-list', TicketList);\naddCustomElement('temba-list', TembaList);\naddCustomElement('temba-label', Label);\naddCustomElement('temba-menu', TembaMenu);\naddCustomElement('temba-contact-search', ContactSearch);\naddCustomElement('temba-icon', VectorIcon);\naddCustomElement('temba-dropdown', Dropdown);\naddCustomElement('temba-tabs', TabPane);\naddCustomElement('temba-tab', Tab);\naddCustomElement('temba-contact-name', ContactName);\naddCustomElement('temba-contact-field', ContactFieldEditor);\naddCustomElement('temba-contact-fields', ContactFields);\naddCustomElement('temba-urn', ContactUrn);\naddCustomElement('temba-contact-groups', ContactGroups);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.26.8",
3
+ "version": "0.26.9",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",
@@ -29,7 +29,6 @@
29
29
  "version": "yarn run build && auto-changelog -p && git add CHANGELOG.md"
30
30
  },
31
31
  "dependencies": {
32
- "flru": "^1.0.2",
33
32
  "geojson": "^0.5.0",
34
33
  "highlight.js": "^10.7.1",
35
34
  "image-size": "^0.9.7",
@@ -38,7 +37,8 @@
38
37
  "lit-flatpickr": "^0.3",
39
38
  "marked": "4.0.10",
40
39
  "remarkable": "^2.0.1",
41
- "serialize-javascript": "^3.0.0"
40
+ "serialize-javascript": "^3.0.0",
41
+ "tiny-lru": "^8.0.2"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@babel/core": "7.11.0",
package/rollup.config.js CHANGED
@@ -58,6 +58,7 @@ const rollupConfig = merge(baseConfig, {
58
58
  copy({
59
59
  targets: [
60
60
  { src: 'static/icons/symbol-defs.svg', dest: 'dist/static/icons/' },
61
+ { src: 'static/img', dest: 'dist/static/' },
61
62
  {
62
63
  src: 'dist/*.js',
63
64
  dest: 'dist/',
@@ -9,7 +9,6 @@ export interface EventHandler {
9
9
 
10
10
  export class RapidElement extends LitElement {
11
11
  private eles: { [selector: string]: HTMLDivElement } = {};
12
-
13
12
  public getEventHandlers(): EventHandler[] {
14
13
  return [];
15
14
  }
@@ -0,0 +1,33 @@
1
+ import { PropertyValueMap } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { CustomEventType } from './interfaces';
4
+ import { RapidElement } from './RapidElement';
5
+ import { Store } from './store/Store';
6
+
7
+ export class RefreshElement extends RapidElement {
8
+ @property({ type: String })
9
+ endpoint: string;
10
+
11
+ protected updated(
12
+ properties: PropertyValueMap<any> | Map<PropertyKey, unknown>
13
+ ): void {
14
+ if (properties.has('endpoint')) {
15
+ this.refresh();
16
+ }
17
+ }
18
+
19
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
+ protected refreshComplete(results: any) {
21
+ // noop
22
+ }
23
+
24
+ public refresh(force = false) {
25
+ const store = document.querySelector('temba-store') as Store;
26
+ if (store) {
27
+ store.getResults(this.endpoint, { force }).then((results: any[]) => {
28
+ this.fireCustomEvent(CustomEventType.Refreshed, results);
29
+ this.refreshComplete(results);
30
+ });
31
+ }
32
+ }
33
+ }
@@ -157,6 +157,9 @@ export class Button extends LitElement {
157
157
  @property({ type: Boolean })
158
158
  destructive: boolean;
159
159
 
160
+ @property({ type: Boolean })
161
+ light: boolean;
162
+
160
163
  @property()
161
164
  name: string;
162
165
 
@@ -227,6 +230,7 @@ export class Button extends LitElement {
227
230
  'active-button': this.active,
228
231
  'attention-button': this.attention,
229
232
  'destructive-button': this.destructive,
233
+ 'light-button': this.light,
230
234
  })}"
231
235
  tabindex="0"
232
236
  @mousedown=${this.handleMouseDown}
@@ -1,17 +1,16 @@
1
1
  import { css, html, TemplateResult } from 'lit';
2
2
  import { property } from 'lit/decorators';
3
- import { RapidElement } from '../RapidElement';
4
3
  import { Contact, CustomEventType, Ticket } from '../interfaces';
5
4
  import { COOKIE_KEYS, getCookieBoolean, postJSON, setCookie } from '../utils';
6
5
  import { TextInput } from '../textinput/TextInput';
7
6
  import { Completion } from '../completion/Completion';
8
7
  import { ContactHistory } from './ContactHistory';
9
8
  import { Modax } from '../dialog/Modax';
10
- import { fetchContact } from './helpers';
9
+ import { ContactStoreElement } from './ContactStoreElement';
11
10
 
12
11
  const DEFAULT_REFRESH = 10000;
13
12
 
14
- export class ContactChat extends RapidElement {
13
+ export class ContactChat extends ContactStoreElement {
15
14
  public static get styles() {
16
15
  return css`
17
16
  .left-pane {
@@ -164,9 +163,6 @@ export class ContactChat extends RapidElement {
164
163
  `;
165
164
  }
166
165
 
167
- @property({ type: String, attribute: 'contact' })
168
- contactUUID: string;
169
-
170
166
  @property({ type: String, attribute: 'ticket' })
171
167
  ticketUUID: string;
172
168
 
@@ -241,17 +237,12 @@ export class ContactChat extends RapidElement {
241
237
  public updated(changedProperties: Map<string, any>) {
242
238
  super.updated(changedProperties);
243
239
 
244
- // we were provided a uuid, fetch our contact details
245
- if (changedProperties.has('contactUUID') && this.contactUUID) {
246
- fetchContact(this.contactsEndpoint + '?uuid=' + this.contactUUID).then(
247
- contact => {
248
- this.currentContact = contact;
249
- }
250
- );
251
- }
252
-
253
240
  // if we don't have an endpoint infer one
254
- if (changedProperties.has('currentContact')) {
241
+ if (
242
+ changedProperties.has('data') ||
243
+ changedProperties.has('currentContact')
244
+ ) {
245
+ this.currentContact = this.data;
255
246
  // focus our completion on load
256
247
  const prevContact = changedProperties.get('contact');
257
248
  if (
@@ -0,0 +1,201 @@
1
+ import { css, html, TemplateResult } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { RapidElement } from '../RapidElement';
4
+ import { TextInput } from '../textinput/TextInput';
5
+
6
+ export class ContactFieldEditor extends RapidElement {
7
+ @property({ type: String })
8
+ key: string;
9
+
10
+ @property({ type: String })
11
+ value: string;
12
+
13
+ @property({ type: String })
14
+ name: string;
15
+
16
+ @property({ type: String })
17
+ type: string;
18
+
19
+ @property({ type: String })
20
+ icon = navigator.clipboard ? 'copy' : '';
21
+
22
+ @property({ type: String })
23
+ iconClass = '';
24
+
25
+ static get styles() {
26
+ return css`
27
+ .prefix {
28
+ background: rgba(0, 0, 0, 0.05);
29
+ border-top-left-radius: 4px;
30
+ border-bottom-left-radius: 4px;
31
+ color: #888;
32
+ cursor: pointer;
33
+ width: 100px;
34
+ white-space: nowrap;
35
+ overflow: hidden;
36
+ text-overflow: ellipsis;
37
+ display: flex;
38
+ padding: 0em 0.5em;
39
+ }
40
+
41
+ .prefix .name {
42
+ padding: 0.5em 0em;
43
+ color: #888;
44
+ width: 80px;
45
+ white-space: nowrap;
46
+ overflow: hidden;
47
+ text-overflow: ellipsis;
48
+ }
49
+
50
+ .postfix {
51
+ display: flex;
52
+ align-items: stretch;
53
+ }
54
+
55
+ .popper {
56
+ padding: 0.5em 0.75em;
57
+ background: rgba(240, 240, 240, 1);
58
+ border-top-right-radius: 4px;
59
+ border-bottom-right-radius: 4px;
60
+ --icon-color: #888;
61
+ opacity: 0;
62
+ cursor: default;
63
+ transform: scale(0.5);
64
+ transition: all 300ms ease-in-out;
65
+ display: flex;
66
+ align-items: stretch;
67
+ z-index: 1000;
68
+ }
69
+
70
+ .postfix temba-icon[name='calendar'] {
71
+ --icon-color: #e3e3e3;
72
+ }
73
+
74
+ .popper.check {
75
+ background: rgba(90, 145, 86, 0.15);
76
+ }
77
+
78
+ .popper.none {
79
+ opacity: 0;
80
+ }
81
+
82
+ .popper.copy temba-icon:hover {
83
+ --icon-color: #555;
84
+ }
85
+
86
+ .popper.corner-down-left {
87
+ // background: var(--color-primary-dark);
88
+ // --icon-color: var(--color-text-light);
89
+ opacity: 1;
90
+ transform: scale(1);
91
+ }
92
+
93
+ temba-icon {
94
+ cursor: pointer;
95
+ }
96
+
97
+ temba-icon[name='check'] {
98
+ --icon-color: rgb(90, 145, 86);
99
+ }
100
+
101
+ temba-textinput:hover .popper.copy {
102
+ opacity: 1;
103
+ transform: scale(1);
104
+ }
105
+
106
+ temba-textinput:focus .popper.copy {
107
+ opacity: 1;
108
+ transform: scale(1);
109
+ }
110
+
111
+ .copy.clicked temba-icon {
112
+ transform: scale(1.2);
113
+ }
114
+
115
+ temba-icon {
116
+ transition: all 200ms ease-in-out;
117
+ }
118
+ `;
119
+ }
120
+
121
+ connectedCallback(): void {
122
+ super.connectedCallback();
123
+ this.handleInput = this.handleInput.bind(this);
124
+ this.handleSubmit = this.handleSubmit.bind(this);
125
+ }
126
+
127
+ public handleIconClick(evt: MouseEvent) {
128
+ const ele = evt.target as HTMLDivElement;
129
+ const icon = ele.getAttribute('name');
130
+ const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;
131
+
132
+ if (icon === 'copy') {
133
+ if (navigator.clipboard) {
134
+ this.iconClass = 'clicked';
135
+ navigator.clipboard.writeText(input.getDisplayValue()).then(() => {
136
+ window.setTimeout(() => {
137
+ this.iconClass = '';
138
+ }, 300);
139
+ });
140
+ }
141
+ }
142
+ evt.preventDefault();
143
+ evt.stopPropagation();
144
+ }
145
+
146
+ public handleSubmit() {
147
+ const input = this.shadowRoot.querySelector('temba-textinput') as TextInput;
148
+ if (input.value !== this.value) {
149
+ this.value = input.value;
150
+ this.fireEvent('change');
151
+ }
152
+ this.icon = navigator.clipboard ? 'copy' : '';
153
+ }
154
+
155
+ public handleChange(evt: Event) {
156
+ evt.preventDefault();
157
+ evt.stopPropagation();
158
+ }
159
+
160
+ public handleInput(evt: KeyboardEvent) {
161
+ if (evt.key === 'Enter') {
162
+ const input = evt.currentTarget as TextInput;
163
+ input.blur();
164
+ }
165
+ }
166
+
167
+ public render(): TemplateResult {
168
+ return html`
169
+ <div>
170
+ <temba-textinput
171
+ value="${this.value ? this.value : ''}"
172
+ ?datetimepicker=${this.type === 'datetime'}
173
+ @blur=${this.handleSubmit}
174
+ @keydown=${this.handleInput}
175
+ @change=${this.handleChange}
176
+ >
177
+ <div class="prefix" slot="prefix">
178
+ <div class="name">${this.name}</div>
179
+ </div>
180
+
181
+ <div class="postfix">
182
+ ${this.type === 'datetime'
183
+ ? html`<div
184
+ style="position: absolute; padding-top: .75em; padding-left: .75em;"
185
+ >
186
+ <temba-icon name="calendar" />
187
+ </div>`
188
+ : null}
189
+
190
+ <div
191
+ class="popper ${this.iconClass} ${this.icon ? this.icon : 'none'}"
192
+ @click=${this.handleIconClick}
193
+ >
194
+ <temba-icon name="${this.icon}" animatechange="spin"></temba-icon>
195
+ </div>
196
+ </div>
197
+ </temba-textinput>
198
+ </div>
199
+ `;
200
+ }
201
+ }
@@ -0,0 +1,112 @@
1
+ import { css, html, TemplateResult } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { ContactField } from '../interfaces';
4
+ import { postJSON } from '../utils';
5
+ import { ContactFieldEditor } from './ContactFieldEditor';
6
+ import { ContactStoreElement } from './ContactStoreElement';
7
+
8
+ export class ContactFields extends ContactStoreElement {
9
+ static get styles() {
10
+ return css`
11
+ :host {
12
+ display: flex;
13
+ flex-wrap: wrap;
14
+ flex-shrink: 1;
15
+ }
16
+
17
+ .field {
18
+ display: flex;
19
+ margin: 0.3em 0.3em;
20
+ box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.15);
21
+ border-radius: var(--curvature);
22
+ align-items: center;
23
+ overflow: hidden;
24
+ }
25
+
26
+ .field.set {
27
+ background: #fff;
28
+ }
29
+
30
+ .field.unset {
31
+ opacity: 0.4;
32
+ }
33
+
34
+ .field.unset .label {
35
+ }
36
+
37
+ .field:hover {
38
+ }
39
+
40
+ .field:hover {
41
+ box-shadow: 1px 1px 6px 2px rgba(0, 0, 0, 0.05),
42
+ 0px 0px 0px 2px var(--color-link-primary);
43
+ cursor: pointer;
44
+ }
45
+
46
+ .label {
47
+ padding: 0.25em 1em;
48
+ border-top-left-radius: var(--curvature);
49
+ border-bottom-left-radius: var(--curvature);
50
+ color: #777;
51
+ font-size: 0.9em;
52
+ font-weight: 400;
53
+ box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.1) inset;
54
+ }
55
+
56
+ .value {
57
+ --icon-color: #ddd;
58
+ max-width: 150px;
59
+ white-space: nowrap;
60
+ overflow: hidden;
61
+ text-overflow: ellipsis;
62
+ padding: 0.25em 1em;
63
+ border-top-right-radius: var(--curvature);
64
+ border-bottom-right-radius: var(--curvature);
65
+ font-size: 0.9em;
66
+ }
67
+
68
+ temba-contact-field {
69
+ margin: 0.3em;
70
+ min-width: 320px;
71
+ flex-grow: 1;
72
+ }
73
+ `;
74
+ }
75
+
76
+ @property({ type: Boolean })
77
+ dirty: boolean;
78
+
79
+ connectedCallback(): void {
80
+ super.connectedCallback();
81
+ this.handleFieldChanged = this.handleFieldChanged.bind(this);
82
+ }
83
+
84
+ public handleFieldChanged(evt: InputEvent) {
85
+ const field = evt.currentTarget as ContactFieldEditor;
86
+ this.data.fields[field.key] = field.value;
87
+ postJSON('/api/v2/contacts.json?uuid=' + this.data.uuid, {
88
+ fields: { [field.key]: field.value },
89
+ }).then(() => {
90
+ this.refresh();
91
+ });
92
+ }
93
+
94
+ public render(): TemplateResult {
95
+ const pinned = this.store.getPinnedFields();
96
+
97
+ const fields = pinned.map((field: ContactField) => {
98
+ if (this.data) {
99
+ const value = this.data.fields[field.key];
100
+ return html`<temba-contact-field
101
+ key=${field.key}
102
+ name=${field.label}
103
+ value=${value}
104
+ type=${field.value_type}
105
+ @change=${this.handleFieldChanged}
106
+ ></temba-contact-field>`;
107
+ }
108
+ });
109
+
110
+ return html`${this.data ? html` ${fields} ` : null}`;
111
+ }
112
+ }
@@ -0,0 +1,41 @@
1
+ import { css, html, TemplateResult } from 'lit';
2
+ import { Group } from '../interfaces';
3
+ import { ContactStoreElement } from './ContactStoreElement';
4
+
5
+ export class ContactGroups extends ContactStoreElement {
6
+ static get styles() {
7
+ return css`
8
+ .groups {
9
+ display: flex;
10
+ flex-wrap: wrap;
11
+ }
12
+
13
+ temba-label {
14
+ margin: 0.3em;
15
+ }
16
+ `;
17
+ }
18
+
19
+ public render(): TemplateResult {
20
+ return html`${this.data
21
+ ? html`
22
+ <div class="groups">
23
+ ${this.data.groups.map((group: Group) => {
24
+ return html`
25
+ <temba-label
26
+ onclick="goto(event)"
27
+ href="/contact/filter/${group.uuid}/"
28
+ icon=${group.is_dynamic ? 'atom' : 'users'}
29
+ clickable
30
+ light
31
+ shadow
32
+ >
33
+ ${group.name}
34
+ </temba-label>
35
+ `;
36
+ })}
37
+ </div>
38
+ `
39
+ : null}`;
40
+ }
41
+ }
@@ -0,0 +1,37 @@
1
+ import { css, html, TemplateResult } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { ContactStoreElement } from './ContactStoreElement';
4
+
5
+ export class ContactName extends ContactStoreElement {
6
+ @property({ type: Number, attribute: 'icon-size' })
7
+ size = 20;
8
+
9
+ static get styles() {
10
+ return css`
11
+ :host {
12
+ display: flex;
13
+ }
14
+
15
+ temba-urn {
16
+ margin-right: 0.2em;
17
+ margin-top: 2px;
18
+ }
19
+ `;
20
+ }
21
+
22
+ public render(): TemplateResult {
23
+ if (this.data) {
24
+ const urn =
25
+ this.data.urns.length > 0
26
+ ? html`<temba-urn
27
+ size=${this.size}
28
+ urn="${this.data.urns[0]}"
29
+ ></temba-urn>`
30
+ : null;
31
+ return html`
32
+ ${urn}
33
+ <div class="name">${this.data.name}</div>
34
+ `;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,51 @@
1
+ import { PropertyValueMap } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { Contact, Group } from '../interfaces';
4
+ import { StoreElement } from '../store/StoreElement';
5
+
6
+ export class ContactStoreElement extends StoreElement {
7
+ @property({ type: String })
8
+ contact: string;
9
+
10
+ @property({ type: Object, attribute: false })
11
+ data: Contact;
12
+
13
+ prepareData(data: any) {
14
+ if (data && data.length > 0) {
15
+ data = data[0];
16
+ data.groups.forEach((group: Group) => {
17
+ group.is_dynamic = this.store.isDynamicGroup(group.uuid);
18
+ });
19
+
20
+ data.groups.sort((a: Group, b: Group) => {
21
+ if (!a.is_dynamic || !b.is_dynamic) {
22
+ if (a.is_dynamic) {
23
+ return -1;
24
+ }
25
+
26
+ if (b.is_dynamic) {
27
+ return 1;
28
+ }
29
+ }
30
+
31
+ return a.name.localeCompare(b.name);
32
+ });
33
+
34
+ return data;
35
+ }
36
+ return null;
37
+ }
38
+
39
+ protected updated(
40
+ changes: PropertyValueMap<any> | Map<PropertyKey, unknown>
41
+ ): void {
42
+ super.updated(changes);
43
+ if (changes.has('contact')) {
44
+ if (this.contact) {
45
+ this.url = `/api/v2/contacts.json?uuid=${this.contact}`;
46
+ } else {
47
+ this.url = null;
48
+ }
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,38 @@
1
+ import { css, html, TemplateResult } from 'lit';
2
+ import { property } from 'lit/decorators';
3
+ import { RapidElement } from '../RapidElement';
4
+
5
+ export class ContactUrn extends RapidElement {
6
+ @property({ type: String })
7
+ urn: string;
8
+
9
+ @property({ type: Number })
10
+ size: number;
11
+
12
+ static get styles() {
13
+ return css`
14
+ .urn {
15
+ box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.04) inset;
16
+ padding: 3px;
17
+ border: 1px solid #ddd;
18
+ border-radius: 18rem;
19
+ background: #eee;
20
+ margin-right: 0.2em;
21
+ }
22
+ `;
23
+ }
24
+
25
+ public render(): TemplateResult {
26
+ const scheme = this.urn.split(':')[0];
27
+ return html`
28
+ <img
29
+ class="urn"
30
+ width="${this.size}em"
31
+ height="${this.size}em"
32
+ src="${this.prefix ||
33
+ (window as any).static_url ||
34
+ '/static/'}img/schemes/${scheme}.svg"
35
+ />
36
+ `;
37
+ }
38
+ }