@nyaruka/temba-components 0.26.1 → 0.26.2

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 (38) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/demo/index.html +32 -13
  3. package/dist/4f80c187.js +4277 -0
  4. package/dist/index.js +279 -202
  5. package/dist/sw.js +1 -1
  6. package/dist/sw.js.map +1 -1
  7. package/dist/templates/components-body.html +1 -1
  8. package/dist/templates/components-head.html +1 -1
  9. package/out-tsc/src/contacts/ContactChat.js +99 -85
  10. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  11. package/out-tsc/src/contacts/ContactHistory.js +30 -36
  12. package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
  13. package/out-tsc/src/contacts/events.js +61 -74
  14. package/out-tsc/src/contacts/events.js.map +1 -1
  15. package/out-tsc/src/list/TembaMenu.js +18 -13
  16. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  17. package/out-tsc/src/tabpane/Tab.js +46 -0
  18. package/out-tsc/src/tabpane/Tab.js.map +1 -0
  19. package/out-tsc/src/tabpane/TabPane.js +109 -0
  20. package/out-tsc/src/tabpane/TabPane.js.map +1 -0
  21. package/out-tsc/temba-modules.js +4 -0
  22. package/out-tsc/temba-modules.js.map +1 -1
  23. package/out-tsc/test/temba-contact-history.test.js +9 -7
  24. package/out-tsc/test/temba-contact-history.test.js.map +1 -1
  25. package/package.json +1 -1
  26. package/screenshots/truth/contacts/history-expanded.png +0 -0
  27. package/screenshots/truth/contacts/history.png +0 -0
  28. package/screenshots/truth/list/menu-submenu.png +0 -0
  29. package/src/contacts/ContactChat.ts +113 -94
  30. package/src/contacts/ContactHistory.ts +57 -59
  31. package/src/contacts/events.ts +61 -75
  32. package/src/list/TembaMenu.ts +19 -14
  33. package/src/tabpane/Tab.ts +42 -0
  34. package/src/tabpane/TabPane.ts +113 -0
  35. package/temba-modules.ts +4 -0
  36. package/test/temba-contact-history.test.ts +9 -7
  37. package/test-assets/style.css +6 -0
  38. package/dist/e477aebd.js +0 -4200
@@ -0,0 +1,109 @@
1
+ import { __decorate } from "tslib";
2
+ import { css, html } from 'lit';
3
+ import { property } from 'lit/decorators';
4
+ import { RapidElement } from '../RapidElement';
5
+ export class TabPane extends RapidElement {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.index = 0;
9
+ }
10
+ static get styles() {
11
+ return css `
12
+ :host {
13
+ display: flex;
14
+ flex-direction: column;
15
+ min-height: 0;
16
+ }
17
+
18
+ .tabs {
19
+ display: flex;
20
+ }
21
+
22
+ .tab {
23
+ padding: 0.5em 1em;
24
+ margin: 0em 0em;
25
+ cursor: pointer;
26
+ display: flex;
27
+ border-radius: var(--curvature);
28
+ border-bottom-right-radius: 0px;
29
+ border-bottom-left-radius: 0px;
30
+ border: 0px solid rgba(0, 0, 0, 0.45);
31
+ color: var(--color-text-dark);
32
+ --icon-color: var(--color-text-dark);
33
+ }
34
+
35
+ .tab temba-icon {
36
+ margin-right: 0.4em;
37
+ }
38
+
39
+ .tab.selected {
40
+ cursor: default;
41
+ box-shadow: 2px 1px 3px 2px rgba(0, 0, 0, 0.07);
42
+ background: #fff;
43
+ }
44
+
45
+ .pane {
46
+ display: flex;
47
+ flex-direction: column;
48
+ flex-grow: 1;
49
+ background: #fff;
50
+ border-radius: var(--curvature);
51
+ box-shadow: 2px 5px 12px 2px rgba(0, 0, 0, 0.09),
52
+ 3px 3px 2px 1px rgba(0, 0, 0, 0.05);
53
+ min-height: 0;
54
+ }
55
+
56
+ .pane.first {
57
+ border-top-left-radius: 0px;
58
+ }
59
+ `;
60
+ }
61
+ handleTabClick(event) {
62
+ this.index = parseInt(event.currentTarget.dataset.index);
63
+ this.requestUpdate('index');
64
+ }
65
+ updated(changedProperties) {
66
+ super.updated(changedProperties);
67
+ if (changedProperties.has('index')) {
68
+ if (this.children.length > this.index) {
69
+ for (let i = 0; i < this.children.length; i++) {
70
+ const tab = this.children[i];
71
+ tab.selected = i == this.index;
72
+ if (tab.selected) {
73
+ tab.style.display = 'flex';
74
+ }
75
+ else {
76
+ tab.style.display = 'none';
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ render() {
83
+ const tabs = [];
84
+ for (const tab of this.children) {
85
+ tabs.push(tab);
86
+ }
87
+ return html `
88
+ <div class="tabs">
89
+ ${tabs.map((tab, index) => html `
90
+ <div
91
+ @click=${this.handleTabClick}
92
+ data-index=${index}
93
+ class="tab ${index == this.index ? 'selected' : ''}"
94
+ >
95
+ ${tab.icon ? html `<temba-icon name=${tab.icon} />` : null}
96
+ ${tab.name}
97
+ </div>
98
+ `)}
99
+ </div>
100
+ <div class="pane ${this.index === 0 ? 'first' : null}">
101
+ <slot></slot>
102
+ </div>
103
+ `;
104
+ }
105
+ }
106
+ __decorate([
107
+ property({ type: Number })
108
+ ], TabPane.prototype, "index", void 0);
109
+ //# sourceMappingURL=TabPane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabPane.js","sourceRoot":"","sources":["../../../src/tabpane/TabPane.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,OAAO,OAAQ,SAAQ,YAAY;IAAzC;;QAsDE,UAAK,GAAG,CAAC,CAAC;IAqDZ,CAAC;IA1GC,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgDT,CAAC;IACJ,CAAC;IAKO,cAAc,CAAC,KAAiB;QACtC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAClB,KAAK,CAAC,aAAgC,CAAC,OAAO,CAAC,KAAK,CACtD,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAEM,OAAO,CAAC,iBAAmC;QAChD,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE;gBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAQ,CAAC;oBACpC,GAAG,CAAC,QAAQ,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;oBAE/B,IAAI,GAAG,CAAC,QAAQ,EAAE;wBAChB,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;qBAC5B;yBAAM;wBACL,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;qBAC5B;iBACF;aACF;SACF;IACH,CAAC;IAEM,MAAM;QACX,MAAM,IAAI,GAAU,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,GAAU,CAAC,CAAC;SACvB;QAED,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,GAAG,CACR,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAA;;uBAEP,IAAI,CAAC,cAAc;2BACf,KAAK;2BACL,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;;gBAEhD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA,oBAAoB,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI;gBACvD,GAAG,CAAC,IAAI;;WAEb,CACF;;yBAEgB,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;;;KAGrD,CAAC;IACJ,CAAC;CACF;AArDC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCACjB","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators';\nimport { RapidElement } from '../RapidElement';\nimport { Tab } from './Tab';\n\nexport class TabPane extends RapidElement {\n static get styles() {\n return css`\n :host {\n display: flex;\n flex-direction: column;\n min-height: 0;\n }\n\n .tabs {\n display: flex;\n }\n\n .tab {\n padding: 0.5em 1em;\n margin: 0em 0em;\n cursor: pointer;\n display: flex;\n border-radius: var(--curvature);\n border-bottom-right-radius: 0px;\n border-bottom-left-radius: 0px;\n border: 0px solid rgba(0, 0, 0, 0.45);\n color: var(--color-text-dark);\n --icon-color: var(--color-text-dark);\n }\n\n .tab temba-icon {\n margin-right: 0.4em;\n }\n\n .tab.selected {\n cursor: default;\n box-shadow: 2px 1px 3px 2px rgba(0, 0, 0, 0.07);\n background: #fff;\n }\n\n .pane {\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n background: #fff;\n border-radius: var(--curvature);\n box-shadow: 2px 5px 12px 2px rgba(0, 0, 0, 0.09),\n 3px 3px 2px 1px rgba(0, 0, 0, 0.05);\n min-height: 0;\n }\n\n .pane.first {\n border-top-left-radius: 0px;\n }\n `;\n }\n\n @property({ type: Number })\n index = 0;\n\n private handleTabClick(event: MouseEvent): void {\n this.index = parseInt(\n (event.currentTarget as HTMLDivElement).dataset.index\n );\n this.requestUpdate('index');\n }\n\n public updated(changedProperties: Map<string, any>) {\n super.updated(changedProperties);\n if (changedProperties.has('index')) {\n if (this.children.length > this.index) {\n for (let i = 0; i < this.children.length; i++) {\n const tab = this.children[i] as Tab;\n tab.selected = i == this.index;\n\n if (tab.selected) {\n tab.style.display = 'flex';\n } else {\n tab.style.display = 'none';\n }\n }\n }\n }\n }\n\n public render(): TemplateResult {\n const tabs: Tab[] = [];\n for (const tab of this.children) {\n tabs.push(tab as Tab);\n }\n\n return html`\n <div class=\"tabs\">\n ${tabs.map(\n (tab, index) => html`\n <div\n @click=${this.handleTabClick}\n data-index=${index}\n class=\"tab ${index == this.index ? 'selected' : ''}\"\n >\n ${tab.icon ? html`<temba-icon name=${tab.icon} />` : null}\n ${tab.name}\n </div>\n `\n )}\n </div>\n <div class=\"pane ${this.index === 0 ? 'first' : null}\">\n <slot></slot>\n </div>\n `;\n }\n}\n"]}
@@ -23,6 +23,8 @@ import { Tip } from './src/tip/Tip';
23
23
  import { TembaMenu } from './src/list/TembaMenu';
24
24
  import { Anchor } from './src/anchor/Anchor';
25
25
  import { Dropdown } from './src/dropdown/Dropdown';
26
+ import { TabPane } from './src/tabpane/TabPane';
27
+ import { Tab } from './src/tabpane/Tab';
26
28
  export function addCustomElement(name, comp) {
27
29
  if (!window.customElements.get(name)) {
28
30
  window.customElements.define(name, comp);
@@ -53,4 +55,6 @@ addCustomElement('temba-menu', TembaMenu);
53
55
  addCustomElement('temba-contact-search', ContactSearch);
54
56
  addCustomElement('temba-icon', VectorIcon);
55
57
  addCustomElement('temba-dropdown', Dropdown);
58
+ addCustomElement('temba-tabs', TabPane);
59
+ addCustomElement('temba-tab', Tab);
56
60
  //# sourceMappingURL=temba-modules.js.map
@@ -1 +1 @@
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';\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);\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';\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"]}
@@ -6,7 +6,7 @@ import { assertScreenshot, getClip, getHTML, mockGET, } from '../test/utils.test
6
6
  import './utils.test';
7
7
  export const createHistory = async (def) => {
8
8
  const parentNode = document.createElement('div');
9
- parentNode.setAttribute('style', 'width: 500px;height:750px;display:flex;flex-direction:column');
9
+ parentNode.setAttribute('style', 'width: 500px;height:750px;display:flex;flex-direction:column;flex-grow:1;min-height:0;');
10
10
  const history = (await fixture(def, { parentNode }));
11
11
  // let history fetch start and wait for it
12
12
  await waitFor(0);
@@ -16,7 +16,9 @@ export const createHistory = async (def) => {
16
16
  await history.httpComplete;
17
17
  return history;
18
18
  };
19
- const getHistoryHTML = (attrs = {}) => getHTML('temba-contact-history', attrs);
19
+ const getHistoryHTML = (attrs = {}) =>
20
+ // attrs = "min-height:0;display:flex;flex-grow:1;flex-direction:column";
21
+ getHTML('temba-contact-history', attrs);
20
22
  const getHistoryClip = (ele) => {
21
23
  const clip = getClip(ele);
22
24
  clip.height = Math.min(clip.height, 750);
@@ -44,9 +46,9 @@ describe('temba-contact-history', () => {
44
46
  // we should have scrolled to the bottom
45
47
  const events = history.shadowRoot.querySelector('.events');
46
48
  const top = events.scrollHeight - events.getBoundingClientRect().height;
47
- expect(top).to.equal(223);
49
+ expect(top).to.equal(539);
48
50
  // make sure we actually scrolled to there
49
- // expect(events.scrollTop).to.equal(top - 1);
51
+ expect(events.scrollTop).to.equal(top - 4);
50
52
  await assertScreenshot('contacts/history', getHistoryClip(history));
51
53
  });
52
54
  it('expands event groups', async () => {
@@ -54,12 +56,12 @@ describe('temba-contact-history', () => {
54
56
  uuid: '1234',
55
57
  }));
56
58
  // our groups with collapsed events
57
- const groups = [3, 11];
59
+ const groups = [3, 5, 7];
58
60
  for (const idx of groups) {
59
- const group = history.shadowRoot.querySelector(`[data-group-index='${idx}']`);
61
+ const group = history.shadowRoot.querySelector(`.event-count[data-group-index='${idx}']`);
60
62
  group.click();
61
63
  }
62
- await waitFor(1000);
64
+ await waitFor(500);
63
65
  await assertScreenshot('contacts/history-expanded', getHistoryClip(history));
64
66
  });
65
67
  });
@@ -1 +1 @@
1
- {"version":3,"file":"temba-contact-history.test.js","sourceRoot":"","sources":["../../test/temba-contact-history.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, assert, expect } from '@open-wc/testing';\nimport sinon from 'sinon';\nimport { ContactHistory } from '../src/contacts/ContactHistory';\nimport { stubbable } from '../src/utils';\nimport {\n assertScreenshot,\n getClip,\n getHTML,\n mockGET,\n} from '../test/utils.test';\nimport './utils.test';\n\nexport const createHistory = async (def: string) => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute(\n 'style',\n 'width: 500px;height:750px;display:flex;flex-direction:column'\n );\n const history = (await fixture(def, { parentNode })) as ContactHistory;\n\n // let history fetch start and wait for it\n await waitFor(0);\n await history.httpComplete;\n\n // wait for scroll update\n await waitFor(0);\n await history.httpComplete;\n\n return history;\n};\n\nconst getHistoryHTML = (attrs: any = {}) =>\n getHTML('temba-contact-history', attrs);\n\nconst getHistoryClip = (ele: ContactHistory) => {\n const clip = getClip(ele);\n clip.height = Math.min(clip.height, 750);\n clip.bottom = clip.top + clip.height;\n return clip;\n};\n\n// stub our current date for consistent screenshots\nsinon.stub(stubbable, 'getCurrentDate').callsFake(() => {\n return new Date('2021-03-31T00:00:00.000-00:00');\n});\n\ndescribe('temba-contact-history', () => {\n beforeEach(() => {\n mockGET(\n /\\/contact\\/history\\/1234\\/.*/,\n '/test-assets/contacts/history.json'\n );\n\n mockGET(\n /\\/api\\/v2\\/tickets\\.json\\?contact=1234/,\n '/test-assets/api/tickets.json'\n );\n });\n\n it('can be created', async () => {\n const history = await createHistory(getHistoryHTML());\n assert.instanceOf(history, ContactHistory);\n });\n\n it('renders history', async () => {\n const history = await createHistory(\n getHistoryHTML({\n uuid: '1234',\n })\n );\n\n await waitFor(500);\n\n // we should have scrolled to the bottom\n const events = history.shadowRoot.querySelector('.events');\n const top = events.scrollHeight - events.getBoundingClientRect().height;\n expect(top).to.equal(223);\n\n // make sure we actually scrolled to there\n // expect(events.scrollTop).to.equal(top - 1);\n\n await assertScreenshot('contacts/history', getHistoryClip(history));\n });\n\n it('expands event groups', async () => {\n const history = await createHistory(\n getHistoryHTML({\n uuid: '1234',\n })\n );\n\n // our groups with collapsed events\n const groups = [3, 11];\n for (const idx of groups) {\n const group = history.shadowRoot.querySelector(\n `[data-group-index='${idx}']`\n ) as HTMLDivElement;\n group.click();\n }\n\n await waitFor(1000);\n\n await assertScreenshot(\n 'contacts/history-expanded',\n getHistoryClip(history)\n );\n });\n});\n"]}
1
+ {"version":3,"file":"temba-contact-history.test.js","sourceRoot":"","sources":["../../test/temba-contact-history.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { fixture, assert, expect } from '@open-wc/testing';\nimport sinon from 'sinon';\nimport { ContactHistory } from '../src/contacts/ContactHistory';\nimport { stubbable } from '../src/utils';\nimport {\n assertScreenshot,\n getClip,\n getHTML,\n mockGET,\n} from '../test/utils.test';\nimport './utils.test';\n\nexport const createHistory = async (def: string) => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute(\n 'style',\n 'width: 500px;height:750px;display:flex;flex-direction:column;flex-grow:1;min-height:0;'\n );\n const history = (await fixture(def, { parentNode })) as ContactHistory;\n\n // let history fetch start and wait for it\n await waitFor(0);\n await history.httpComplete;\n\n // wait for scroll update\n await waitFor(0);\n await history.httpComplete;\n\n return history;\n};\n\nconst getHistoryHTML = (attrs: any = {} as any) =>\n // attrs = \"min-height:0;display:flex;flex-grow:1;flex-direction:column\";\n getHTML('temba-contact-history', attrs);\n\nconst getHistoryClip = (ele: ContactHistory) => {\n const clip = getClip(ele);\n clip.height = Math.min(clip.height, 750);\n clip.bottom = clip.top + clip.height;\n return clip;\n};\n\n// stub our current date for consistent screenshots\nsinon.stub(stubbable, 'getCurrentDate').callsFake(() => {\n return new Date('2021-03-31T00:00:00.000-00:00');\n});\n\ndescribe('temba-contact-history', () => {\n beforeEach(() => {\n mockGET(\n /\\/contact\\/history\\/1234\\/.*/,\n '/test-assets/contacts/history.json'\n );\n\n mockGET(\n /\\/api\\/v2\\/tickets\\.json\\?contact=1234/,\n '/test-assets/api/tickets.json'\n );\n });\n\n it('can be created', async () => {\n const history = await createHistory(getHistoryHTML());\n assert.instanceOf(history, ContactHistory);\n });\n\n it('renders history', async () => {\n const history = await createHistory(\n getHistoryHTML({\n uuid: '1234',\n })\n );\n\n await waitFor(500);\n\n // we should have scrolled to the bottom\n const events = history.shadowRoot.querySelector('.events');\n const top = events.scrollHeight - events.getBoundingClientRect().height;\n\n expect(top).to.equal(539);\n\n // make sure we actually scrolled to there\n expect(events.scrollTop).to.equal(top - 4);\n\n await assertScreenshot('contacts/history', getHistoryClip(history));\n });\n\n it('expands event groups', async () => {\n const history = await createHistory(\n getHistoryHTML({\n uuid: '1234',\n })\n );\n\n // our groups with collapsed events\n const groups = [3, 5, 7];\n for (const idx of groups) {\n const group = history.shadowRoot.querySelector(\n `.event-count[data-group-index='${idx}']`\n ) as HTMLDivElement;\n group.click();\n }\n\n await waitFor(500);\n\n await assertScreenshot(\n 'contacts/history-expanded',\n getHistoryClip(history)\n );\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.26.1",
3
+ "version": "0.26.2",
4
4
  "description": "Web components to support rapidpro and related projects",
5
5
  "author": "Nyaruka <code@nyaruka.coim>",
6
6
  "main": "dist/index.js",
@@ -14,35 +14,36 @@ const DEFAULT_REFRESH = 10000;
14
14
  export class ContactChat extends RapidElement {
15
15
  public static get styles() {
16
16
  return css`
17
- :host {
18
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2),
19
- 0 1px 2px 0 rgba(0, 0, 0, 0.06);
20
-
21
- height: 100%;
22
- border-radius: var(--curvature);
23
-
24
- flex-grow: 1;
25
- width: 100%;
26
- display: block;
27
- background: #f2f2f2;
28
- overflow: hidden;
29
- }
30
-
31
17
  .left-pane {
32
18
  box-shadow: -13px 10px 7px 14px rgba(0, 0, 0, 0);
33
19
  transition: box-shadow 600ms linear;
34
20
  }
35
21
 
36
22
  .left-pane.open {
37
- box-shadow: -13px 10px 7px 14px rgba(0, 0, 0, 0.15);
38
23
  z-index: 1000;
39
24
  }
40
25
 
26
+ :host {
27
+ flex-grow: 1;
28
+ display: flex;
29
+ flex-direction: row;
30
+ min-height: 0;
31
+ border-radius: var(--curvature);
32
+ }
33
+
41
34
  .chat-wrapper {
42
35
  display: flex;
36
+ flex-grow: 1;
43
37
  flex-direction: column;
44
- height: 100%;
45
38
  overflow: hidden;
39
+ min-height: 0;
40
+ }
41
+
42
+ temba-contact-history {
43
+ flex-grow: 1;
44
+ display: flex;
45
+ flex-direction: column;
46
+ min-height: 0;
46
47
  }
47
48
 
48
49
  .chatbox {
@@ -53,6 +54,11 @@ export class ContactChat extends RapidElement {
53
54
  flex-direction: column;
54
55
  z-index: 3;
55
56
  border-bottom-left-radius: var(--curvature);
57
+ border-bottom-right-radius: var(--curvature);
58
+ }
59
+
60
+ .chatbox.full {
61
+ border-bottom-right-radius: 0 !important;
56
62
  }
57
63
 
58
64
  .closed-footer {
@@ -176,6 +182,9 @@ export class ContactChat extends RapidElement {
176
182
  @property({ type: Boolean })
177
183
  showDetails = true;
178
184
 
185
+ @property({ type: Boolean })
186
+ toolbar = false;
187
+
179
188
  @property({ type: Boolean })
180
189
  monitor = false;
181
190
 
@@ -321,14 +330,13 @@ export class ContactChat extends RapidElement {
321
330
 
322
331
  public render(): TemplateResult {
323
332
  return html`
324
- <div style="display: flex; height: 100%;">
325
- <div
326
- style="flex-grow: 1; margin-right: 0em;"
327
- class="left-pane ${this.showDetails ? 'open' : ''}"
328
- >
329
- <div class="chat-wrapper">
330
- ${this.currentContact
331
- ? html` <temba-contact-history
333
+ <div
334
+ style="flex-grow: 1; margin-right: 0em; display:flex; flex-direction:row; min-height: 0;"
335
+ class="left-pane ${this.showDetails ? 'open' : ''}"
336
+ >
337
+ <div class="chat-wrapper">
338
+ ${this.currentContact
339
+ ? html`<temba-contact-history
332
340
  .uuid=${this.currentContact.uuid}
333
341
  .contact=${this.currentContact}
334
342
  .ticket=${
@@ -349,7 +357,9 @@ export class ContactChat extends RapidElement {
349
357
  @click=${this.handleReopen}
350
358
  ></temba-button>
351
359
  </div>`
352
- : html` <div class="chatbox">
360
+ : html` <div
361
+ class="chatbox ${this.toolbar ? 'full' : ''}"
362
+ >
353
363
  <temba-completion
354
364
  @change=${this.handleChatChange}
355
365
  .value=${this.currentChat}
@@ -375,81 +385,88 @@ export class ContactChat extends RapidElement {
375
385
  </div>`
376
386
  }
377
387
  </div>`
378
- : null}
379
- </div>
388
+ : null}
380
389
  </div>
381
- ${this.currentContact
382
- ? html`<temba-contact-details
383
- style="z-index: 10"
384
- class="${this.showDetails ? '' : 'hidden'}"
385
- showGroups="true"
386
- .visible=${this.showDetails}
387
- .ticket=${this.currentTicket}
388
- .contact=${this.currentContact}
389
- ></temba-contact-details>`
390
- : null}
390
+ </div>
391
+
392
+ ${this.toolbar
393
+ ? html`${
394
+ this.currentContact
395
+ ? html`<temba-contact-details
396
+ style="z-index: 10"
397
+ class="${this.showDetails ? '' : 'hidden'}"
398
+ showGroups="true"
399
+ .visible=${this.showDetails}
400
+ .ticket=${this.currentTicket}
401
+ .contact=${this.currentContact}
402
+ ></temba-contact-details>`
403
+ : null
404
+ }
391
405
 
392
406
  <div class="toolbar ${this.showDetails ? '' : 'closed'}">
393
- ${this.currentContact
394
- ? html`
395
- <temba-tip
396
- style="margin-top:5px"
397
- text="${this.showDetails ? 'Hide Details' : 'Show Details'}"
398
- position="left"
399
- hideOnChange
400
- >
401
- <temba-icon
402
- id="details-button"
403
- name="${this.showDetails ? 'chevrons-left' : 'sidebar'}"
404
- @click="${this.handleDetailSlider}"
405
- clickable
406
- animatechange="spin"
407
- ></temba-icon>
408
- </temba-tip>
409
-
410
- ${this.currentTicket
411
- ? html`<temba-tip
412
- style="margin-top:5px"
413
- text="Assign"
414
- position="left"
415
- >
416
- <temba-icon
417
- id="assign-button"
418
- name="user"
419
- @click="${() => {
420
- const modax = this.shadowRoot.getElementById(
421
- 'assign-dialog'
422
- ) as Modax;
423
- modax.open = true;
424
- }}"
425
- clickable
426
- ></temba-icon>
427
- </temba-tip>
428
- <temba-tip
429
- style="margin-top:5px"
430
- text="Add Note"
431
- position="left"
432
- >
433
- <temba-icon
434
- id="add-note-button"
435
- name="edit"
436
- @click="${() => {
437
- const note = this.shadowRoot.getElementById(
438
- 'note-dialog'
439
- ) as Modax;
440
- note.open = true;
441
- }}"
442
- clickable
443
- ></temba-icon>
444
- </temba-tip>`
445
- : null}
446
- `
447
- : null}
407
+ ${
408
+ this.currentContact
409
+ ? html`
410
+ <temba-tip
411
+ style="margin-top:5px"
412
+ text="${this.showDetails ? 'Hide Details' : 'Show Details'}"
413
+ position="left"
414
+ hideOnChange
415
+ >
416
+ <temba-icon
417
+ id="details-button"
418
+ name="${this.showDetails ? 'chevrons-left' : 'sidebar'}"
419
+ @click="${this.handleDetailSlider}"
420
+ clickable
421
+ animatechange="spin"
422
+ ></temba-icon>
423
+ </temba-tip>
424
+
425
+ ${this.currentTicket
426
+ ? html`<temba-tip
427
+ style="margin-top:5px"
428
+ text="Assign"
429
+ position="left"
430
+ >
431
+ <temba-icon
432
+ id="assign-button"
433
+ name="user"
434
+ @click="${() => {
435
+ const modax = this.shadowRoot.getElementById(
436
+ 'assign-dialog'
437
+ ) as Modax;
438
+ modax.open = true;
439
+ }}"
440
+ clickable
441
+ ></temba-icon>
442
+ </temba-tip>
443
+ <temba-tip
444
+ style="margin-top:5px"
445
+ text="Add Note"
446
+ position="left"
447
+ >
448
+ <temba-icon
449
+ id="add-note-button"
450
+ name="edit"
451
+ @click="${() => {
452
+ const note = this.shadowRoot.getElementById(
453
+ 'note-dialog'
454
+ ) as Modax;
455
+ note.open = true;
456
+ }}"
457
+ clickable
458
+ ></temba-icon>
459
+ </temba-tip>`
460
+ : null}
461
+ `
462
+ : null
463
+ }
448
464
  </div>
449
465
  </div>
450
466
 
451
- ${this.currentTicket
452
- ? html`<temba-modax
467
+ ${
468
+ this.currentTicket
469
+ ? html`<temba-modax
453
470
  header="Add Note"
454
471
  id="note-dialog"
455
472
  @temba-submitted=${this.refresh}
@@ -461,6 +478,8 @@ export class ContactChat extends RapidElement {
461
478
  @temba-submitted=${this.handleTicketAssigned}
462
479
  endpoint="/ticket/assign/${this.currentTicket.uuid}/"
463
480
  /></temba-modax>`
481
+ : null
482
+ }`
464
483
  : null}
465
484
  `;
466
485
  }