@nyaruka/temba-components 0.55.0 → 0.56.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{31b8df84.js → e3f2a5a4.js} +169 -102
  3. package/dist/index.js +169 -102
  4. package/dist/locales/es.js +6 -0
  5. package/dist/locales/es.js.map +1 -1
  6. package/dist/locales/fr.js +6 -0
  7. package/dist/locales/fr.js.map +1 -1
  8. package/dist/locales/pt.js +6 -0
  9. package/dist/locales/pt.js.map +1 -1
  10. package/dist/static/svg/index.svg +1 -1
  11. package/dist/sw.js +1 -1
  12. package/dist/sw.js.map +1 -1
  13. package/dist/templates/components-body.html +1 -1
  14. package/dist/templates/components-head.html +1 -1
  15. package/out-tsc/src/FormElement.js +6 -0
  16. package/out-tsc/src/FormElement.js.map +1 -1
  17. package/out-tsc/src/button/Button.js +1 -1
  18. package/out-tsc/src/button/Button.js.map +1 -1
  19. package/out-tsc/src/contactsearch/ContactSearch.js +244 -95
  20. package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
  21. package/out-tsc/src/label/Label.js +2 -3
  22. package/out-tsc/src/label/Label.js.map +1 -1
  23. package/out-tsc/src/locales/es.js +6 -0
  24. package/out-tsc/src/locales/es.js.map +1 -1
  25. package/out-tsc/src/locales/fr.js +6 -0
  26. package/out-tsc/src/locales/fr.js.map +1 -1
  27. package/out-tsc/src/locales/pt.js +6 -0
  28. package/out-tsc/src/locales/pt.js.map +1 -1
  29. package/out-tsc/src/omnibox/Omnibox.js +10 -3
  30. package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
  31. package/out-tsc/src/select/Select.js +21 -11
  32. package/out-tsc/src/select/Select.js.map +1 -1
  33. package/out-tsc/src/vectoricon/index.js +3 -1
  34. package/out-tsc/src/vectoricon/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/FormElement.ts +8 -0
  37. package/src/button/Button.ts +1 -1
  38. package/src/contactsearch/ContactSearch.ts +270 -113
  39. package/src/label/Label.ts +2 -3
  40. package/src/locales/es.ts +6 -0
  41. package/src/locales/fr.ts +6 -0
  42. package/src/locales/pt.ts +6 -0
  43. package/src/omnibox/Omnibox.ts +10 -4
  44. package/src/select/Select.ts +21 -11
  45. package/src/vectoricon/index.ts +4 -1
  46. package/static/svg/index.svg +1 -1
  47. package/static/svg/work/traced/edit-03.svg +1 -0
  48. package/static/svg/work/traced/flip-backward.svg +1 -0
  49. package/static/svg/work/used/edit-03.svg +3 -0
  50. package/static/svg/work/used/flip-backward.svg +3 -0
  51. package/xliff/es.xlf +18 -0
  52. package/xliff/fr.xlf +18 -0
  53. package/xliff/pt.xlf +18 -0
package/dist/sw.js CHANGED
@@ -1,2 +1,2 @@
1
- if(!self.define){let e,t={};const o=(o,n)=>(o=new URL(o+".js",n).href,t[o]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=o,e.onload=t,document.head.appendChild(e)}else e=o,importScripts(o),t()})).then((()=>{let e=t[o];if(!e)throw new Error(`Module ${o} didn’t register its module`);return e})));self.define=(n,s)=>{const c=e||("document"in self?document.currentScript.src:"")||location.href;if(t[c])return;let i={};const r=e=>o(e,c),l={module:{uri:c},exports:i,require:r};t[c]=Promise.all(n.map((e=>l[e]||r(e)))).then((e=>(s(...e),i)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"31b8df84.js",revision:"4a175183f75a1efb60f05c0f14bb008a"},{url:"templates/components-body.html",revision:"b142c93d8c1ab1b5d7f288dcb34cc364"},{url:"templates/components-head.html",revision:"5cfc1b1be0a72fd5b88b4c04cc2dc825"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
1
+ if(!self.define){let e,t={};const o=(o,n)=>(o=new URL(o+".js",n).href,t[o]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=o,e.onload=t,document.head.appendChild(e)}else e=o,importScripts(o),t()})).then((()=>{let e=t[o];if(!e)throw new Error(`Module ${o} didn’t register its module`);return e})));self.define=(n,s)=>{const i=e||("document"in self?document.currentScript.src:"")||location.href;if(t[i])return;let r={};const l=e=>o(e,i),c={module:{uri:i},exports:r,require:l};t[i]=Promise.all(n.map((e=>c[e]||l(e)))).then((e=>(s(...e),r)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"e3f2a5a4.js",revision:"15e59c2469f4a9b42b823aecd25117b3"},{url:"templates/components-body.html",revision:"f6938bc95a128bb1d6ddad6d356bfebd"},{url:"templates/components-head.html",revision:"005b42c4c1fae80548ae41c2c9ed7b98"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
2
2
  //# sourceMappingURL=sw.js.map
package/dist/sw.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sw.js","sources":["../../../../../tmp/52ba5436a31a365b780f436ea2a7e311/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"31b8df84.js\",\n \"revision\": \"4a175183f75a1efb60f05c0f14bb008a\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"b142c93d8c1ab1b5d7f288dcb34cc364\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"5cfc1b1be0a72fd5b88b4c04cc2dc825\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,CAAE,GAEwBC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}
1
+ {"version":3,"file":"sw.js","sources":["../../../../../tmp/a89324a944b3bf34f9f40037f0ea929c/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"e3f2a5a4.js\",\n \"revision\": \"15e59c2469f4a9b42b823aecd25117b3\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"f6938bc95a128bb1d6ddad6d356bfebd\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"005b42c4c1fae80548ae41c2c9ed7b98\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,CAAE,GAEwBC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}
@@ -1 +1 @@
1
- <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/31b8df84.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.55.0"</script>
1
+ <script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/e3f2a5a4.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.56.0"</script>
@@ -1 +1 @@
1
- <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/31b8df84.js" crossorigin="anonymous">
1
+ <link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/e3f2a5a4.js" crossorigin="anonymous">
@@ -26,6 +26,12 @@ export class FormElement extends RapidElement {
26
26
  get type() {
27
27
  return this.localName;
28
28
  }
29
+ setValue(value) {
30
+ this.value = this.serializeValue(value);
31
+ }
32
+ getDeserializedValue() {
33
+ return JSON.parse(this.value);
34
+ }
29
35
  serializeValue(value) {
30
36
  return JSON.stringify(value);
31
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FormElement.js","sourceRoot":"","sources":["../../src/FormElement.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAmC3C;QACE,KAAK,EAAE,CAAC;QAlCV,SAAI,GAAG,EAAE,CAAC;QAqBV,UAAK,GAAG,IAAI,CAAC;QAGb,cAAS,GAAgB,IAAI,CAAC;QAG9B,aAAQ,GAAG,KAAK,CAAC;QAQf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IAC1C,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAClC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACzC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,cAAc,CAAC,KAAU;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;;AA1BM,0BAAc,GAAG,IAAI,CAAC;AA7B7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yCACjB;AAGV;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;6CAClC;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;+CAClC;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;+CAClC;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;8CAClC;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACb;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2CACT;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACd;AAGb;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;8CACD;AAG9B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;6CACX","sourcesContent":["import { RapidElement } from './RapidElement';\nimport { property } from 'lit/decorators.js';\n\n/**\n * FormElement is a component that appends a hidden input (outside of\n * its own shadow) with its value to be included in forms.\n */\nexport class FormElement extends RapidElement {\n @property({ type: String })\n name = '';\n\n @property({ type: String, attribute: 'help_text' })\n helpText: string;\n\n @property({ type: Boolean, attribute: 'help_always' })\n helpAlways: boolean;\n\n @property({ type: Boolean, attribute: 'widget_only' })\n widgetOnly: boolean;\n\n @property({ type: Boolean, attribute: 'hide_label' })\n hideLabel: boolean;\n\n @property({ type: String })\n label: string;\n\n @property({ type: Array })\n errors: string[];\n\n @property({ type: String })\n value = null;\n\n @property({ attribute: false })\n inputRoot: HTMLElement = this;\n\n @property({ type: Boolean })\n disabled = false;\n\n static formAssociated = true;\n\n private internals: ElementInternals;\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this.value);\n }\n }\n\n get form() {\n return this.internals.form;\n }\n\n get type() {\n return this.localName;\n }\n\n public serializeValue(value: any): string {\n return JSON.stringify(value);\n }\n}\n"]}
1
+ {"version":3,"file":"FormElement.js","sourceRoot":"","sources":["../../src/FormElement.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAmC3C;QACE,KAAK,EAAE,CAAC;QAlCV,SAAI,GAAG,EAAE,CAAC;QAqBV,UAAK,GAAG,IAAI,CAAC;QAGb,cAAS,GAAgB,IAAI,CAAC;QAG9B,aAAQ,GAAG,KAAK,CAAC;QAQf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IAC1C,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAClC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACzC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,QAAQ,CAAC,KAAU;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAEM,oBAAoB;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAEM,cAAc,CAAC,KAAU;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;;AAlCM,0BAAc,GAAG,IAAI,CAAC;AA7B7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yCACjB;AAGV;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;6CAClC;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;+CAClC;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;+CAClC;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;8CAClC;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACb;AAGd;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;2CACT;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;0CACd;AAGb;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;8CACD;AAG9B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;6CACX","sourcesContent":["import { RapidElement } from './RapidElement';\nimport { property } from 'lit/decorators.js';\n\n/**\n * FormElement is a component that appends a hidden input (outside of\n * its own shadow) with its value to be included in forms.\n */\nexport class FormElement extends RapidElement {\n @property({ type: String })\n name = '';\n\n @property({ type: String, attribute: 'help_text' })\n helpText: string;\n\n @property({ type: Boolean, attribute: 'help_always' })\n helpAlways: boolean;\n\n @property({ type: Boolean, attribute: 'widget_only' })\n widgetOnly: boolean;\n\n @property({ type: Boolean, attribute: 'hide_label' })\n hideLabel: boolean;\n\n @property({ type: String })\n label: string;\n\n @property({ type: Array })\n errors: string[];\n\n @property({ type: String })\n value = null;\n\n @property({ attribute: false })\n inputRoot: HTMLElement = this;\n\n @property({ type: Boolean })\n disabled = false;\n\n static formAssociated = true;\n\n private internals: ElementInternals;\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this.value);\n }\n }\n\n get form() {\n return this.internals.form;\n }\n\n get type() {\n return this.localName;\n }\n\n public setValue(value: any) {\n this.value = this.serializeValue(value);\n }\n\n public getDeserializedValue(): any {\n return JSON.parse(this.value);\n }\n\n public serializeValue(value: any): string {\n return JSON.stringify(value);\n }\n}\n"]}
@@ -209,7 +209,7 @@ export class Button extends LitElement {
209
209
  @click=${this.handleClick}
210
210
  >
211
211
  <div class="button-mask">
212
- <div class="button-name">${buttonName}</div>
212
+ <div class="button-name"><slot name="name">${buttonName}</slot></div>
213
213
  </div>
214
214
  </div>
215
215
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/button/Button.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAkB,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,OAAO,MAAO,SAAQ,UAAU;IAAtC;;QA2JE,MAAC,GAAG,CAAC,CAAC;IAoGR,CAAC;IA9PC,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4IT,CAAC;IACJ,CAAC;IAyCO,WAAW,CAAC,GAAe;QACjC,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,GAAG,CAAC,cAAc,EAAE,CAAC;YACrB,GAAG,CAAC,eAAe,EAAE,CAAC;SACvB;QAED,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC/B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YAC7C,GAAG,CAAC,cAAc,EAAE,CAAC;YACrB,GAAG,CAAC,eAAe,EAAE,CAAC;SACvB;IACH,CAAC;IAEO,WAAW,CAAC,KAAoB;QACtC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE;YACzB,IAAI,CAAC,KAAK,EAAE,CAAC;SACd;IACH,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SAC9B;IACH,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAEM,MAAM;QACX,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;YAChC,CAAC,CAAC,IAAI,CAAA;;eAEG;YACT,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAEd,OAAO,IAAI,CAAA;;;cAGD,IAAI,CAAC,CAAC;YACR,UAAU,CAAC;YACb,gBAAgB,EACd,IAAI,CAAC,OAAO;gBACZ,CAAC,CAAC,IAAI,CAAC,OAAO;oBACZ,CAAC,IAAI,CAAC,SAAS;oBACf,CAAC,IAAI,CAAC,SAAS;oBACf,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;YAChB,kBAAkB,EAAE,IAAI,CAAC,SAAS;YAClC,iBAAiB,EAAE,IAAI,CAAC,QAAQ;YAChC,eAAe,EAAE,IAAI,CAAC,MAAM;YAC5B,kBAAkB,EAAE,IAAI,CAAC,SAAS;YAClC,oBAAoB,EAAE,IAAI,CAAC,WAAW;YACtC,cAAc,EAAE,IAAI,CAAC,KAAK;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;;qBAEW,IAAI,CAAC,eAAe;mBACtB,IAAI,CAAC,aAAa;sBACf,IAAI,CAAC,aAAa;iBACvB,IAAI,CAAC,WAAW;iBAChB,IAAI,CAAC,WAAW;;;qCAGI,UAAU;;;KAG1C,CAAC;IACJ,CAAC;CACF;AA7GC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;uCACX;AAGjB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;yCACT;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;yCACT;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iCACrB;AAGN;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;2CACP;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;qCACb;AAGf;IADC,QAAQ,EAAE;oCACE;AAGb;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;wCACV;AAGlB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;0CACR;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;sCACZ;AAGhB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;qCACb;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCACd;AAGb;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;qCACZ","sourcesContent":["import { LitElement, TemplateResult, html, css } from 'lit';\nimport { getClasses } from '../utils';\n\nimport { property } from 'lit/decorators.js';\n\nexport class Button extends LitElement {\n static get styles() {\n return css`\n :host {\n display: inline-block;\n font-family: var(--font-family);\n font-weight: 400;\n }\n\n .small {\n font-size: 0.8em;\n --button-y: 0px;\n --button-x: 0.5em;\n }\n\n .v-2.button-container {\n background: var(--button-bg);\n background-image: var(--button-bg-img);\n color: var(--button-text);\n box-shadow: var(--button-shadow);\n transition: all calc(var(--transition-speed) / 2) ease-in;\n }\n\n .button-container {\n color: #fff;\n cursor: pointer;\n display: block;\n border-radius: var(--curvature);\n outline: none;\n transition: background ease-in var(--transition-speed);\n user-select: none;\n -webkit-user-select: none;\n text-align: center;\n }\n\n .button-name {\n white-space: nowrap;\n }\n\n .secondary-button:hover .button-mask {\n border: 1px solid var(--color-button-secondary);\n }\n\n .button-mask:hover {\n background: rgba(0, 0, 0, 0.05);\n }\n\n .button-container:focus {\n outline: none;\n margin: 0;\n }\n\n .button-container:focus {\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .button-container.secondary-button:focus .button-mask {\n background: transparent;\n }\n\n .button-mask {\n padding: var(--button-y) var(--button-x);\n border-radius: var(--curvature);\n border: 1px solid transparent;\n transition: var(--transition-speed);\n background: var(--button-mask);\n }\n\n .button-container.disabled-button {\n background: rgba(0, 0, 0, 0.05);\n color: rgba(255, 255, 255, 0.45);\n cursor: default;\n }\n\n .button-container.disabled-button .button-mask {\n box-shadow: 0 0 0px 1px var(--color-button-disabled);\n }\n\n .button-container.disabled-button:hover .button-mask {\n box-shadow: 0 0 0px 1px var(--color-button-disabled);\n background: rgba(0, 0, 0, 0.05);\n }\n\n .button-container.active-button .button-mask {\n }\n\n .secondary-button.active-button {\n background: transparent;\n color: var(--color-text);\n }\n\n .secondary-button.active-button .button-mask {\n border: none;\n }\n\n .button-container.secondary-button.active-button:focus .button-mask {\n background: transparent;\n box-shadow: none;\n }\n\n .primary-button {\n background: var(--color-button-primary);\n color: var(--color-button-primary-text);\n }\n\n .light-button {\n background: var(--color-button-light);\n color: var(--color-button-light-text);\n }\n\n .attention-button {\n background: var(--color-button-attention);\n color: var(--color-button-primary-text);\n }\n\n .secondary-button {\n background: transparent;\n color: var(--color-text);\n font-weight: 300;\n }\n\n .destructive-button {\n background: var(--color-button-destructive);\n color: var(--color-button-destructive-text);\n }\n\n .button-mask.disabled-button {\n background: rgba(0, 0, 0, 0.1);\n }\n\n .secondary-button .button-mask:hover {\n background: transparent;\n }\n\n .submit-animation {\n padding: 1px 4px;\n }\n\n .submit-animation temba-loading {\n margin-bottom: -3px;\n line-height: normal;\n }\n `;\n }\n\n @property({ type: Boolean })\n primary: boolean;\n\n @property({ type: Boolean })\n secondary: boolean;\n\n @property({ type: Boolean })\n attention: boolean;\n\n @property({ type: Number })\n v = 1;\n\n @property({ type: Boolean })\n destructive: boolean;\n\n @property({ type: Boolean })\n light: boolean;\n\n @property()\n name: string;\n\n @property({ type: Boolean })\n disabled: boolean;\n\n @property({ type: Boolean })\n submitting: boolean;\n\n @property({ type: Boolean })\n active: boolean;\n\n @property({ type: Boolean })\n small: boolean;\n\n @property({ type: String })\n href: string;\n\n @property({ type: Number })\n index?: number;\n\n private handleClick(evt: MouseEvent) {\n if (this.disabled) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n if (this.href && !this.disabled) {\n this.ownerDocument.location.href = this.href;\n evt.preventDefault();\n evt.stopPropagation();\n }\n }\n\n private handleKeyUp(event: KeyboardEvent): void {\n this.active = false;\n if (event.key === 'Enter') {\n this.click();\n }\n }\n\n private handleMouseDown(): void {\n if (!this.disabled && !this.submitting) {\n this.active = true;\n this.classList.add('active');\n }\n }\n\n private handleMouseUp(): void {\n this.active = false;\n this.classList.remove('active');\n }\n\n public render(): TemplateResult {\n const buttonName = this.submitting\n ? html`<div class=\"submit-animation\">\n <temba-loading units=\"3\" size=\"8\" color=\"#eee\"></temba-loading>\n </div>`\n : this.name;\n\n return html`\n <div\n class=\"button-container \n v-${this.v}\n ${getClasses({\n 'primary-button':\n this.primary ||\n (!this.primary &&\n !this.secondary &&\n !this.attention &&\n this.v == 1),\n 'secondary-button': this.secondary,\n 'disabled-button': this.disabled,\n 'active-button': this.active,\n 'attention-button': this.attention,\n 'destructive-button': this.destructive,\n 'light-button': this.light,\n small: this.small,\n })}\"\n tabindex=\"0\"\n @mousedown=${this.handleMouseDown}\n @mouseup=${this.handleMouseUp}\n @mouseleave=${this.handleMouseUp}\n @keyup=${this.handleKeyUp}\n @click=${this.handleClick}\n >\n <div class=\"button-mask\">\n <div class=\"button-name\">${buttonName}</div>\n </div>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/button/Button.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, TemplateResult, html, css } from 'lit';\nimport { getClasses } from '../utils';\n\nimport { property } from 'lit/decorators.js';\n\nexport class Button extends LitElement {\n static get styles() {\n return css`\n :host {\n display: inline-block;\n font-family: var(--font-family);\n font-weight: 400;\n }\n\n .small {\n font-size: 0.8em;\n --button-y: 0px;\n --button-x: 0.5em;\n }\n\n .v-2.button-container {\n background: var(--button-bg);\n background-image: var(--button-bg-img);\n color: var(--button-text);\n box-shadow: var(--button-shadow);\n transition: all calc(var(--transition-speed) / 2) ease-in;\n }\n\n .button-container {\n color: #fff;\n cursor: pointer;\n display: block;\n border-radius: var(--curvature);\n outline: none;\n transition: background ease-in var(--transition-speed);\n user-select: none;\n -webkit-user-select: none;\n text-align: center;\n }\n\n .button-name {\n white-space: nowrap;\n }\n\n .secondary-button:hover .button-mask {\n border: 1px solid var(--color-button-secondary);\n }\n\n .button-mask:hover {\n background: rgba(0, 0, 0, 0.05);\n }\n\n .button-container:focus {\n outline: none;\n margin: 0;\n }\n\n .button-container:focus {\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .button-container.secondary-button:focus .button-mask {\n background: transparent;\n }\n\n .button-mask {\n padding: var(--button-y) var(--button-x);\n border-radius: var(--curvature);\n border: 1px solid transparent;\n transition: var(--transition-speed);\n background: var(--button-mask);\n }\n\n .button-container.disabled-button {\n background: rgba(0, 0, 0, 0.05);\n color: rgba(255, 255, 255, 0.45);\n cursor: default;\n }\n\n .button-container.disabled-button .button-mask {\n box-shadow: 0 0 0px 1px var(--color-button-disabled);\n }\n\n .button-container.disabled-button:hover .button-mask {\n box-shadow: 0 0 0px 1px var(--color-button-disabled);\n background: rgba(0, 0, 0, 0.05);\n }\n\n .button-container.active-button .button-mask {\n }\n\n .secondary-button.active-button {\n background: transparent;\n color: var(--color-text);\n }\n\n .secondary-button.active-button .button-mask {\n border: none;\n }\n\n .button-container.secondary-button.active-button:focus .button-mask {\n background: transparent;\n box-shadow: none;\n }\n\n .primary-button {\n background: var(--color-button-primary);\n color: var(--color-button-primary-text);\n }\n\n .light-button {\n background: var(--color-button-light);\n color: var(--color-button-light-text);\n }\n\n .attention-button {\n background: var(--color-button-attention);\n color: var(--color-button-primary-text);\n }\n\n .secondary-button {\n background: transparent;\n color: var(--color-text);\n font-weight: 300;\n }\n\n .destructive-button {\n background: var(--color-button-destructive);\n color: var(--color-button-destructive-text);\n }\n\n .button-mask.disabled-button {\n background: rgba(0, 0, 0, 0.1);\n }\n\n .secondary-button .button-mask:hover {\n background: transparent;\n }\n\n .submit-animation {\n padding: 1px 4px;\n }\n\n .submit-animation temba-loading {\n margin-bottom: -3px;\n line-height: normal;\n }\n `;\n }\n\n @property({ type: Boolean })\n primary: boolean;\n\n @property({ type: Boolean })\n secondary: boolean;\n\n @property({ type: Boolean })\n attention: boolean;\n\n @property({ type: Number })\n v = 1;\n\n @property({ type: Boolean })\n destructive: boolean;\n\n @property({ type: Boolean })\n light: boolean;\n\n @property()\n name: string;\n\n @property({ type: Boolean })\n disabled: boolean;\n\n @property({ type: Boolean })\n submitting: boolean;\n\n @property({ type: Boolean })\n active: boolean;\n\n @property({ type: Boolean })\n small: boolean;\n\n @property({ type: String })\n href: string;\n\n @property({ type: Number })\n index?: number;\n\n private handleClick(evt: MouseEvent) {\n if (this.disabled) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n if (this.href && !this.disabled) {\n this.ownerDocument.location.href = this.href;\n evt.preventDefault();\n evt.stopPropagation();\n }\n }\n\n private handleKeyUp(event: KeyboardEvent): void {\n this.active = false;\n if (event.key === 'Enter') {\n this.click();\n }\n }\n\n private handleMouseDown(): void {\n if (!this.disabled && !this.submitting) {\n this.active = true;\n this.classList.add('active');\n }\n }\n\n private handleMouseUp(): void {\n this.active = false;\n this.classList.remove('active');\n }\n\n public render(): TemplateResult {\n const buttonName = this.submitting\n ? html`<div class=\"submit-animation\">\n <temba-loading units=\"3\" size=\"8\" color=\"#eee\"></temba-loading>\n </div>`\n : this.name;\n\n return html`\n <div\n class=\"button-container \n v-${this.v}\n ${getClasses({\n 'primary-button':\n this.primary ||\n (!this.primary &&\n !this.secondary &&\n !this.attention &&\n this.v == 1),\n 'secondary-button': this.secondary,\n 'disabled-button': this.disabled,\n 'active-button': this.active,\n 'attention-button': this.attention,\n 'destructive-button': this.destructive,\n 'light-button': this.light,\n small: this.small,\n })}\"\n tabindex=\"0\"\n @mousedown=${this.handleMouseDown}\n @mouseup=${this.handleMouseUp}\n @mouseleave=${this.handleMouseUp}\n @keyup=${this.handleKeyUp}\n @click=${this.handleClick}\n >\n <div class=\"button-mask\">\n <div class=\"button-name\"><slot name=\"name\">${buttonName}</slot></div>\n </div>\n </div>\n `;\n }\n}\n"]}
@@ -1,11 +1,13 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, css } from 'lit';
3
+ import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
3
4
  import { property } from 'lit/decorators.js';
4
- import { getClasses, postJSON } from '../utils';
5
+ import { getClasses, postJSON, stopEvent } from '../utils';
5
6
  import '../alert/Alert';
6
7
  import { CustomEventType } from '../interfaces';
7
8
  import { FormElement } from '../FormElement';
8
- const QUEIT_MILLIS = 1000;
9
+ import { msg } from '@lit/localize';
10
+ const QUEIT_MILLIS = 2000;
9
11
  export class ContactSearch extends FormElement {
10
12
  constructor() {
11
13
  super(...arguments);
@@ -14,8 +16,11 @@ export class ContactSearch extends FormElement {
14
16
  this.query = '';
15
17
  this.inactiveThreshold = 1000;
16
18
  this.inactiveDays = 90;
17
- this.initialized = false;
19
+ this.recipients = [];
20
+ this.advanced = false;
21
+ this.refreshKey = '0';
18
22
  this.exclusions = {};
23
+ this.initialized = false;
19
24
  }
20
25
  static get styles() {
21
26
  return css `
@@ -141,6 +146,17 @@ export class ContactSearch extends FormElement {
141
146
 
142
147
  .summary {
143
148
  min-height: 2.2em;
149
+ display: flex;
150
+ flex-grow: 1;
151
+ align-items: center;
152
+ }
153
+
154
+ .summary .result-count {
155
+ flex-grow: 1;
156
+ }
157
+
158
+ .results.empty {
159
+ display: none !important;
144
160
  }
145
161
 
146
162
  .results.initialized {
@@ -149,37 +165,91 @@ export class ContactSearch extends FormElement {
149
165
  margin-top: 0.5em;
150
166
  margin-left: 0.6em;
151
167
  }
168
+
169
+ .advanced-icon {
170
+ cursor: pointer;
171
+ margin-right: 0.5em;
172
+ }
173
+
174
+ .query .advanced-icon {
175
+ margin-top: 1em;
176
+ margin-right: 1em;
177
+ }
178
+
179
+ .advanced-icon:hover {
180
+ --icon-color: var(--color-link-primary-hover) !important;
181
+ }
182
+
183
+ .query {
184
+ --textarea-height: 5em;
185
+ }
186
+
187
+ #recipients {
188
+ margin-bottom: 1em;
189
+ display: block;
190
+ }
191
+
192
+ temba-alert {
193
+ margin: 1em 0;
194
+ }
152
195
  `;
153
196
  }
197
+ refresh() {
198
+ this.refreshKey = 'requested_' + new Date().getTime();
199
+ }
154
200
  updated(changedProperties) {
155
201
  super.updated(changedProperties);
156
- if (changedProperties.has('query') || changedProperties.has('endpoint')) {
157
- this.fetching = !!this.query && !!this.endpoint;
158
- if (this.fetching) {
159
- this.initialized = true;
160
- // clear our summary on any change
161
- this.summary = null;
162
- if (this.lastQuery) {
163
- window.clearTimeout(this.lastQuery);
164
- }
165
- if (this.query.trim().length > 0) {
166
- this.lastQuery = window.setTimeout(() => {
167
- this.fetchSummary(this.query);
168
- }, QUEIT_MILLIS);
169
- }
202
+ if (changedProperties.has('advanced') && this.advanced) {
203
+ return;
204
+ }
205
+ // if we remove the in_a_flow option, make sure it's not part of our exclusions
206
+ if (changedProperties.has('in_a_flow') && !this.in_a_flow) {
207
+ delete this.exclusions['in_a_flow'];
208
+ this.requestUpdate('exclusions');
209
+ }
210
+ if ((changedProperties.has('query') && this.advanced) ||
211
+ (changedProperties.has('refreshKey') && this.refreshKey !== '0')) {
212
+ this.summary = null;
213
+ // this.errors = [];
214
+ this.fireCustomEvent(CustomEventType.ContentChanged, { reset: true });
215
+ if (this.lastQuery) {
216
+ window.clearTimeout(this.lastQuery);
217
+ this.fetching = false;
218
+ }
219
+ if (this.query.trim().length > 0 || this.recipients.length > 0) {
220
+ this.fetching = true;
221
+ this.lastQuery = window.setTimeout(() => {
222
+ this.fetchSummary();
223
+ }, QUEIT_MILLIS);
170
224
  }
171
225
  }
172
226
  }
173
- fetchSummary(query) {
227
+ fetchSummary() {
174
228
  if (this.endpoint) {
229
+ const group_uuids = this.recipients
230
+ .filter((value) => value.type === 'group')
231
+ .map((value) => value.id);
232
+ const contact_uuids = this.recipients
233
+ .filter((value) => value.type === 'contact')
234
+ .map((value) => value.id);
175
235
  postJSON(this.endpoint, {
176
- include: { query },
236
+ include: this.advanced
237
+ ? { query: this.query }
238
+ : { contact_uuids, group_uuids },
177
239
  exclude: this.exclusions,
178
240
  }).then((response) => {
179
241
  this.fetching = false;
180
242
  if (response.status === 200) {
181
243
  this.summary = response.json;
182
- this.value = this.summary.query;
244
+ if (!this.advanced) {
245
+ this.query = this.summary.query;
246
+ }
247
+ this.setValue({
248
+ advanced: this.advanced,
249
+ query: this.query,
250
+ exclusions: this.exclusions,
251
+ recipients: this.recipients,
252
+ });
183
253
  if (this.summary.error) {
184
254
  this.errors = [this.summary.error];
185
255
  }
@@ -200,12 +270,37 @@ export class ContactSearch extends FormElement {
200
270
  });
201
271
  }
202
272
  }
273
+ handleAdvancedToggle(evt) {
274
+ stopEvent(evt);
275
+ this.recipients = [];
276
+ this.exclusions = {};
277
+ if (this.advanced) {
278
+ this.query = '';
279
+ this.value = null;
280
+ }
281
+ this.advanced = !this.advanced;
282
+ this.setValue({
283
+ advanced: this.advanced,
284
+ query: this.query,
285
+ exclusions: this.exclusions,
286
+ recipients: this.recipients,
287
+ });
288
+ }
203
289
  handleQueryChange(evt) {
204
290
  const input = evt.target;
205
291
  this.query = input.inputElement.value;
206
292
  }
207
- handleSlotChanged(evt) {
293
+ handleRecipientsChanged(evt) {
294
+ if (this.refreshKey !== '0' || this.initialized) {
295
+ this.refresh();
296
+ }
297
+ else {
298
+ this.initialized = true;
299
+ }
300
+ }
301
+ handleExclusionChanged(evt) {
208
302
  if (evt.target.tagName === 'TEMBA-CHECKBOX') {
303
+ const ex = JSON.stringify(this.exclusions);
209
304
  const checkbox = evt.target;
210
305
  let value = checkbox.checked;
211
306
  if (!value) {
@@ -217,106 +312,148 @@ export class ContactSearch extends FormElement {
217
312
  }
218
313
  this.exclusions[checkbox.name] = value;
219
314
  }
315
+ if (ex !== JSON.stringify(this.exclusions)) {
316
+ this.refresh();
317
+ }
220
318
  }
221
- this.requestUpdate('query');
222
319
  }
223
320
  render() {
224
321
  let summary;
225
322
  if (this.summary) {
226
- const fields = Object.keys(this.summary.fields || []).map((uuid) => {
227
- return { uuid, ...this.summary.fields[uuid] };
228
- });
229
323
  if (!this.summary.error) {
230
324
  const count = this.summary.total;
231
- const lastSeenOn = this.summary.query.indexOf('last_seen_on') > -1;
232
325
  summary = html `
233
- <table cellspacing="0" cellpadding="0">
234
- <tr class="header">
235
- <td colspan="2">
236
- Found
237
- <a
238
- class="linked"
239
- target="_"
240
- href="/contact/?search=${encodeURIComponent(this.summary.query)}"
241
- >
242
- ${count.toLocaleString()}
243
- </a>
244
- contact${count !== 1 ? 's' : ''}
245
- </td>
246
- ${fields.map(field => html ` <td class="field-header">${field.label}</td> `)}
247
- <td></td>
248
- <td class="field-header date">
249
- ${lastSeenOn ? 'Last Seen' : 'Created'}
250
- </td>
251
- </tr>
252
-
253
- ${this.summary.sample.map((contact) => html `
254
- <tr class="contact">
255
- <td class="urn">${contact.primary_urn_formatted}</td>
256
- <td class="name">${contact.name}</td>
257
- ${fields.map(field => html `
258
- <td class="field">
259
- ${(contact.fields[field.uuid] || { text: '' })
260
- .text}
261
- </td>
262
- `)}
263
- <td></td>
264
- <td class="date">
265
- ${lastSeenOn
266
- ? contact.last_seen_on || '--'
267
- : contact.created_on}
268
- </td>
269
- </tr>
270
- `)}
271
- ${this.summary.total > this.summary.sample.length
272
- ? html `<tr class="table-footer">
273
- <td class="query-details" colspan=${fields.length + 3}></td>
274
- <td class="more">
275
- <a
276
- class="linked"
277
- target="_"
278
- href="/contact/?search=${encodeURIComponent(this.summary.query)}"
279
- >more</a
280
- >
281
- </td>
282
- </tr>`
283
- : null}
284
- </table>
326
+ <div class="result-count">
327
+ Found
328
+ <a
329
+ class="linked"
330
+ target="_"
331
+ href="/contact/?search=${encodeURIComponent(this.summary.query)}"
332
+ >
333
+ ${count.toLocaleString()}
334
+ </a>
335
+ contact${count !== 1 ? 's' : ''}
336
+ </div>
337
+ <temba-button
338
+ class="edit"
339
+ name="edit"
340
+ secondary
341
+ small
342
+ @click=${this.handleAdvancedToggle}
343
+ >
344
+ <div slot="name">
345
+ <div style="display: flex; align-items: center;">
346
+ ${this.advanced
347
+ ? html ` <temba-icon
348
+ name="reset"
349
+ style="margin-right:0.5em"
350
+ ></temba-icon>
351
+ Start Over`
352
+ : html ` <temba-icon
353
+ name="edit"
354
+ style="margin-right:0.5em"
355
+ ></temba-icon>
356
+ Edit Query`}
357
+ </div>
358
+ </div>
359
+ </temba-button>
285
360
  `;
286
361
  }
287
362
  }
363
+ if (this.summary && this.summary.blockers.length > 0) {
364
+ return html `${this.summary.blockers.map(error => html `<temba-alert level="error">${unsafeHTML(error)}</temba-alert>`)}`;
365
+ }
288
366
  return html `
289
- <div class="query">
290
- <temba-textinput
291
- .label=${this.label}
292
- .helpText=${this.helpText}
293
- .widgetOnly=${this.widgetOnly}
294
- .errors=${this.errors}
295
- name=${this.name}
296
- .inputRoot=${this}
297
- @input=${this.handleQueryChange}
298
- placeholder=${this.placeholder}
299
- .value=${this.query}
300
- textarea
301
- autogrow
302
- >
303
- </temba-textinput>
304
- </div>
367
+ ${this.advanced
368
+ ? html `<div class="query">
369
+ <temba-textinput
370
+ .label=${this.label}
371
+ .helpText=${this.helpText}
372
+ .widgetOnly=${this.widgetOnly}
373
+ .errors=${this.errors}
374
+ name=${this.name}
375
+ .inputRoot=${this}
376
+ @input=${this.handleQueryChange}
377
+ placeholder=${this.placeholder}
378
+ .value=${this.query}
379
+ textarea
380
+ autogrow
381
+ >
382
+ </temba-textinput>
383
+ </div>`
384
+ : html `<temba-omnibox
385
+ placeholder="Search for contacts or groups"
386
+ widget_only=""
387
+ groups=""
388
+ contacts=""
389
+ label="Recipients"
390
+ help_text="The contacts to send the message to."
391
+ .errors=${this.errors}
392
+ id="recipients"
393
+ name="recipients"
394
+ .value=${this.recipients}
395
+ endpoint="/contact/omnibox/?"
396
+ @change=${this.handleRecipientsChanged}
397
+ >
398
+ </temba-omnibox>
305
399
 
306
- <slot @change=${this.handleSlotChanged}></slot>
400
+ ${this.not_seen_since_days
401
+ ? html `<temba-checkbox
402
+ name="not_seen_since_days"
403
+ label="${msg('Skip inactive contacts')}"
404
+ help_text="${msg('Only include contacts who have sent a message in the last 90 days.')}"
405
+ ?checked=${this.exclusions['not_seen_since_days'] === 90}
406
+ @change=${this.handleExclusionChanged}
407
+ ></temba-checkbox>`
408
+ : null}
409
+ ${this.in_a_flow
410
+ ? html `<temba-checkbox
411
+ name="in_a_flow"
412
+ label="${msg('Skip contacts currently in a flow')}"
413
+ help_text="${msg('Avoid interrupting a contact who is already in a flow.')}"
414
+ ?checked=${this.exclusions['in_a_flow']}
415
+ @change=${this.handleExclusionChanged}
416
+ ></temba-checkbox>`
417
+ : null}
418
+ ${this.started_previously
419
+ ? html `<temba-checkbox
420
+ name="started_previously"
421
+ label="${msg('Skip repeat contacts')}"
422
+ help_text="${msg('Avoid restarting a contact who has been in this flow in the last 90 days.')}"
423
+ ?checked=${this.exclusions['started_previously']}
424
+ @change=${this.handleExclusionChanged}
425
+ ></temba-checkbox>`
426
+ : null}`}
307
427
 
308
428
  <div
309
429
  class="results ${getClasses({
310
430
  fetching: this.fetching,
311
431
  initialized: this.initialized || this.fetching,
432
+ empty: ((this.summary && this.summary.error) || !this.summary) &&
433
+ !this.fetching,
312
434
  })}"
313
435
  >
314
436
  <temba-loading units="6" size="8"></temba-loading>
315
437
  <div class="summary ${this.expanded ? 'expanded' : ''}">${summary}</div>
316
438
  </div>
439
+
440
+ ${this.summary && this.summary.warnings
441
+ ? this.summary.warnings.map(warning => html `<temba-alert level="warning"
442
+ >${unsafeHTML(warning)}</temba-alert
443
+ >`)
444
+ : ``}
317
445
  `;
318
446
  }
319
447
  }
448
+ __decorate([
449
+ property({ type: Boolean })
450
+ ], ContactSearch.prototype, "in_a_flow", void 0);
451
+ __decorate([
452
+ property({ type: Boolean })
453
+ ], ContactSearch.prototype, "started_previously", void 0);
454
+ __decorate([
455
+ property({ type: Boolean })
456
+ ], ContactSearch.prototype, "not_seen_since_days", void 0);
320
457
  __decorate([
321
458
  property({ type: Boolean })
322
459
  ], ContactSearch.prototype, "fetching", void 0);
@@ -347,4 +484,16 @@ __decorate([
347
484
  __decorate([
348
485
  property({ type: Object, attribute: false })
349
486
  ], ContactSearch.prototype, "flow", void 0);
487
+ __decorate([
488
+ property({ type: Array })
489
+ ], ContactSearch.prototype, "recipients", void 0);
490
+ __decorate([
491
+ property({ type: Boolean })
492
+ ], ContactSearch.prototype, "advanced", void 0);
493
+ __decorate([
494
+ property({ type: String })
495
+ ], ContactSearch.prototype, "refreshKey", void 0);
496
+ __decorate([
497
+ property({ type: Object })
498
+ ], ContactSearch.prototype, "exclusions", void 0);
350
499
  //# sourceMappingURL=ContactSearch.js.map