@nyaruka/temba-components 0.136.0 → 0.137.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 (137) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/demo/components/webchat/example.html +2 -2
  3. package/dist/temba-components.js +537 -578
  4. package/dist/temba-components.js.map +1 -1
  5. package/out-tsc/src/display/Chat.js +123 -44
  6. package/out-tsc/src/display/Chat.js.map +1 -1
  7. package/out-tsc/src/display/FloatingTab.js +2 -6
  8. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  9. package/out-tsc/src/events/eventRenderers.js +442 -0
  10. package/out-tsc/src/events/eventRenderers.js.map +1 -0
  11. package/out-tsc/src/flow/CanvasNode.js +18 -1
  12. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  13. package/out-tsc/src/flow/Editor.js +10 -7
  14. package/out-tsc/src/flow/Editor.js.map +1 -1
  15. package/out-tsc/src/flow/NodeEditor.js +0 -1
  16. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  17. package/out-tsc/src/layout/FloatingWindow.js.map +1 -1
  18. package/out-tsc/src/list/ShortcutList.js +1 -1
  19. package/out-tsc/src/list/ShortcutList.js.map +1 -1
  20. package/out-tsc/src/live/ContactChat.js +12 -321
  21. package/out-tsc/src/live/ContactChat.js.map +1 -1
  22. package/out-tsc/src/simulator/Simulator.js +432 -541
  23. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  24. package/out-tsc/src/store/AppState.js +33 -0
  25. package/out-tsc/src/store/AppState.js.map +1 -1
  26. package/out-tsc/test/temba-appstate-node-sorting.test.js +430 -0
  27. package/out-tsc/test/temba-appstate-node-sorting.test.js.map +1 -0
  28. package/out-tsc/test/temba-floating-tab.test.js +0 -9
  29. package/out-tsc/test/temba-floating-tab.test.js.map +1 -1
  30. package/out-tsc/test/temba-flow-editor.test.js +261 -0
  31. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  32. package/out-tsc/test/temba-simulator.test.js +51 -32
  33. package/out-tsc/test/temba-simulator.test.js.map +1 -1
  34. package/package.json +1 -1
  35. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  36. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  37. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  38. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  39. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  40. package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
  41. package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
  42. package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
  43. package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
  44. package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
  45. package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
  46. package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
  47. package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
  48. package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
  49. package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
  50. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  51. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  52. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  53. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  54. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  55. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  56. package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
  57. package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
  58. package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
  59. package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
  60. package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
  61. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  62. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  63. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  64. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  65. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  66. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  67. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  68. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  69. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  70. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  71. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  72. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  73. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  74. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  75. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  76. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  77. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  78. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  79. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  80. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  81. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  82. package/screenshots/truth/contacts/chat-failure.png +0 -0
  83. package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
  84. package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
  85. package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
  86. package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
  87. package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
  88. package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
  89. package/screenshots/truth/floating-tab/gray.png +0 -0
  90. package/screenshots/truth/floating-tab/green.png +0 -0
  91. package/screenshots/truth/floating-tab/purple.png +0 -0
  92. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  93. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  94. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  95. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  96. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  97. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  98. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  99. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  100. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  101. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  102. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  103. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  104. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  105. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  106. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  107. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  108. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  109. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
  110. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  111. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  112. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  113. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  114. package/screenshots/truth/simulator/after-message-sent.png +0 -0
  115. package/screenshots/truth/simulator/after-reset.png +0 -0
  116. package/screenshots/truth/simulator/attachment-menu.png +0 -0
  117. package/screenshots/truth/simulator/context-expanded.png +0 -0
  118. package/screenshots/truth/simulator/context-explorer-open.png +0 -0
  119. package/screenshots/truth/simulator/event-info.png +0 -0
  120. package/screenshots/truth/simulator/image-attachment.png +0 -0
  121. package/screenshots/truth/simulator/open-initial.png +0 -0
  122. package/screenshots/truth/simulator/quick-replies.png +0 -0
  123. package/src/display/Chat.ts +123 -44
  124. package/src/display/FloatingTab.ts +2 -7
  125. package/src/events/eventRenderers.ts +527 -0
  126. package/src/flow/CanvasNode.ts +18 -1
  127. package/src/flow/Editor.ts +11 -7
  128. package/src/flow/NodeEditor.ts +0 -1
  129. package/src/layout/FloatingWindow.ts +1 -1
  130. package/src/list/ShortcutList.ts +1 -1
  131. package/src/live/ContactChat.ts +17 -376
  132. package/src/simulator/Simulator.ts +492 -564
  133. package/src/store/AppState.ts +56 -0
  134. package/test/temba-appstate-node-sorting.test.ts +506 -0
  135. package/test/temba-floating-tab.test.ts +0 -11
  136. package/test/temba-flow-editor.test.ts +297 -0
  137. package/test/temba-simulator.test.ts +64 -34
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingWindow.js","sourceRoot":"","sources":["../../../src/layout/FloatingWindow.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { CustomEventType } from '../interfaces';\nimport { getClasses } from '../utils';\nimport { FloatingTab } from '../display/FloatingTab';\n\nexport class FloatingWindow extends RapidElement {\n static get styles() {\n return css`\n .window.hidden {\n transform: translateX(100%);\n opacity: 0;\n pointer-events: none;\n }\n\n .window {\n transition: transform var(--transition-duration, 300ms) ease-in-out,\n opacity var(--transition-duration, 300ms) ease-in-out;\n position: fixed;\n z-index: 5000;\n top: 100px;\n background: white;\n border-radius: 8px;\n box-shadow: -4px 4px 20px rgba(0, 0, 0, 0.3);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .window.chromeless {\n background: transparent;\n border-radius: 0;\n box-shadow: none;\n pointer-events: none;\n }\n\n .window.chromeless .body {\n pointer-events: none;\n }\n\n .window.dragging {\n user-select: none;\n cursor: move;\n }\n\n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 6px;\n background: var(--header-color, var(--color-primary-light, #f3f4f6));\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n cursor: move;\n user-select: none;\n }\n\n .title {\n font-weight: 600;\n font-size: 16px;\n color: white;\n padding-left: 8px;\n }\n\n .close-button {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background-color calc(var(--transition-duration, 150ms) / 2)\n ease-in-out;\n }\n\n .close-button:hover {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n .close-button temba-icon {\n --icon-color: white;\n }\n\n .body {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n }\n\n .window.chromeless .body {\n padding: 0;\n }\n\n ::slotted(.drag-handle) {\n cursor: move;\n user-select: none;\n border: 1px solid red;\n }\n `;\n }\n\n @property({ type: String })\n header = '';\n\n @property({ type: Number })\n width = 500;\n\n @property({ type: Number })\n minHeight = 200;\n\n @property({ type: Number })\n maxHeight = 800;\n\n @property({ type: Number })\n top = 100;\n\n @property({ type: Number })\n left = -1; // -1 means calculate from right side\n\n @property({ type: Boolean })\n hidden = true;\n\n @property({ type: Boolean })\n dragging = false;\n\n @property({ type: Boolean })\n chromeless = false;\n\n @property({ type: String })\n color = '#6B7280';\n\n @property({ type: Number })\n leftBoundaryMargin = 0;\n\n @property({ type: Number })\n rightBoundaryMargin = 0;\n\n @property({ type: Number })\n topBoundaryMargin = 0;\n\n @property({ type: Number })\n bottomBoundaryMargin = 0;\n\n private dragStartX = 0;\n private dragStartY = 0;\n private dragOffsetX = 0;\n private dragOffsetY = 0;\n private positionFromRight = false;\n private defaultTop = 100;\n private defaultLeft = -1;\n\n public firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n\n // store the default position from properties\n this.defaultTop = this.top;\n this.defaultLeft = this.left;\n\n // determine if we should position from right side\n if (this.left === -1) {\n this.positionFromRight = true;\n }\n\n // set up drag handle listeners for chromeless windows\n if (this.chromeless) {\n this.setupDragHandles();\n }\n\n // listen for window resize to keep window in bounds\n window.addEventListener('resize', this.handleResize);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('resize', this.handleResize);\n }\n\n private setupDragHandles() {\n // listen for mousedown on slotted content\n this.addEventListener('mousedown', this.handleSlotMouseDown);\n }\n\n private handleSlotMouseDown = (event: MouseEvent) => {\n // check if the target or any parent has the drag-handle class\n const target = event.target as HTMLElement;\n const dragHandle = target.closest('.drag-handle');\n\n if (!dragHandle) {\n return;\n }\n\n this.dragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragOffsetX = this.left;\n this.dragOffsetY = this.top;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n\n event.preventDefault();\n };\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('hidden')) {\n // when hiding, reset positioning behavior to original\n if (this.hidden && !changes.get('hidden')) {\n if (this.defaultLeft === -1) {\n this.positionFromRight = true;\n }\n }\n\n // reset to default position when showing\n if (!this.hidden && changes.get('hidden')) {\n // reset top to default\n this.top = this.defaultTop;\n\n // if positioned from right, recalculate based on current viewport\n if (this.positionFromRight) {\n this.left = window.innerWidth - this.width - 20;\n } else {\n // reset left to default\n this.left = this.defaultLeft;\n }\n }\n }\n\n // setup drag handles if chromeless changed to true\n if (changes.has('chromeless') && this.chromeless) {\n this.setupDragHandles();\n }\n }\n\n private handleClose() {\n this.hidden = true;\n // show all tabs when window is closed\n FloatingTab.showAllTabs();\n this.fireCustomEvent(CustomEventType.DialogHidden);\n }\n\n private handleHeaderMouseDown(event: MouseEvent) {\n // don't start drag if clicking on close button\n if ((event.target as HTMLElement).closest('.close-button')) {\n return;\n }\n\n this.dragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragOffsetX = this.left;\n this.dragOffsetY = this.top;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n\n event.preventDefault();\n }\n\n private handleMouseMove = (event: MouseEvent) => {\n if (!this.dragging) return;\n\n const deltaX = event.clientX - this.dragStartX;\n const deltaY = event.clientY - this.dragStartY;\n\n this.left = this.dragOffsetX + deltaX;\n this.top = this.dragOffsetY + deltaY;\n\n // keep window within viewport bounds with 20px padding\n const padding = 20;\n this.left = Math.max(\n padding - this.leftBoundaryMargin,\n Math.min(\n this.left,\n window.innerWidth - this.width - padding + this.rightBoundaryMargin\n )\n );\n\n // get the actual rendered height of the window element\n const windowElement = this.shadowRoot?.querySelector(\n '.window'\n ) as HTMLElement;\n const currentHeight =\n windowElement?.offsetHeight || this.maxHeight || window.innerHeight;\n const maxTop = Math.max(\n padding - this.topBoundaryMargin,\n window.innerHeight - currentHeight - padding + this.bottomBoundaryMargin\n );\n this.top = Math.max(\n padding - this.topBoundaryMargin,\n Math.min(this.top, maxTop)\n );\n };\n\n private handleMouseUp = () => {\n this.dragging = false;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n\n // once user drags the window, stop auto-positioning from right\n this.positionFromRight = false;\n };\n\n private handleResize = () => {\n // only constrain position if window is visible\n if (this.hidden) return;\n\n const padding = 20;\n const windowElement = this.shadowRoot?.querySelector(\n '.window'\n ) as HTMLElement;\n const currentHeight =\n windowElement?.offsetHeight || this.maxHeight || window.innerHeight;\n\n // if positioned from right, always recalculate from right edge\n if (this.positionFromRight) {\n this.left =\n window.innerWidth - this.width - padding + this.rightBoundaryMargin;\n } else {\n // only adjust left if out of bounds\n const minLeft = padding - this.leftBoundaryMargin;\n const maxLeft =\n window.innerWidth - this.width - padding + this.rightBoundaryMargin;\n\n if (this.left < minLeft) {\n this.left = minLeft;\n } else if (this.left > maxLeft) {\n this.left = maxLeft;\n }\n }\n\n // only adjust top if out of bounds\n const minTop = padding - this.topBoundaryMargin;\n const maxTop = Math.max(\n padding - this.topBoundaryMargin,\n window.innerHeight - currentHeight - padding + this.bottomBoundaryMargin\n );\n\n if (this.top < minTop) {\n this.top = minTop;\n } else if (this.top > maxTop) {\n this.top = maxTop;\n }\n };\n\n public show() {\n this.hidden = false;\n }\n\n public hide() {\n this.hidden = true;\n }\n\n public close() {\n this.hidden = true;\n // show all tabs when window is closed\n FloatingTab.showAllTabs();\n this.fireCustomEvent(CustomEventType.DialogHidden);\n }\n\n public render(): TemplateResult {\n const minHeightStyle = this.minHeight\n ? `min-height: ${this.minHeight}px;`\n : '';\n const maxHeightStyle = this.maxHeight\n ? `max-height: ${this.maxHeight}px;`\n : '';\n\n const windowStyle = `\n width: ${this.width}px;\n ${minHeightStyle}\n ${maxHeightStyle}\n top: ${this.top}px;\n left: ${this.left}px;\n --header-color: ${this.color};\n `;\n\n const windowClasses = getClasses({\n window: true,\n dragging: this.dragging,\n hidden: this.hidden,\n chromeless: this.chromeless\n });\n\n return html`\n <div class=\"${windowClasses}\" style=\"${windowStyle}\">\n ${!this.chromeless\n ? html`\n <div class=\"header\" @mousedown=${this.handleHeaderMouseDown}>\n <div class=\"title\">${this.header}</div>\n <button class=\"close-button\" @click=${this.handleClose}>\n <temba-icon name=\"close\" size=\"1.5\"></temba-icon>\n </button>\n </div>\n `\n : ''}\n <div class=\"body\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"FloatingWindow.js","sourceRoot":"","sources":["../../../src/layout/FloatingWindow.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { CustomEventType } from '../interfaces';\nimport { getClasses } from '../utils';\nimport { FloatingTab } from '../display/FloatingTab';\n\nexport class FloatingWindow extends RapidElement {\n static get styles() {\n return css`\n .window.hidden {\n transform: translateX(100%);\n opacity: 0;\n pointer-events: none;\n }\n\n .window {\n transition: transform var(--transition-duration, 300ms) ease-in-out,\n opacity var(--transition-duration, 300ms) ease-in-out;\n position: fixed;\n z-index: 5000;\n top: 100px;\n background: white;\n border-radius: 8px;\n box-shadow: -4px 4px 20px rgba(0, 0, 0, 0.3);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .window.chromeless {\n background: transparent;\n border-radius: 0;\n box-shadow: none;\n pointer-events: none;\n }\n\n .window.chromeless .body {\n pointer-events: none;\n }\n\n .window.dragging {\n user-select: none;\n cursor: move;\n }\n\n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 6px;\n background: var(--header-color, var(--color-primary-light, #f3f4f6));\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n cursor: move;\n user-select: none;\n }\n\n .title {\n font-weight: 600;\n font-size: 16px;\n color: white;\n padding-left: 8px;\n }\n\n .close-button {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background-color calc(var(--transition-duration, 150ms) / 2)\n ease-in-out;\n }\n\n .close-button:hover {\n background-color: rgba(255, 255, 255, 0.2);\n }\n\n .close-button temba-icon {\n --icon-color: white;\n }\n\n .body {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n }\n\n .window.chromeless .body {\n padding: 0;\n }\n\n ::slotted(.drag-handle) {\n cursor: move;\n user-select: none;\n border: 1px solid red;\n }\n `;\n }\n\n @property({ type: String })\n header = '';\n\n @property({ type: Number })\n width = 500;\n\n @property({ type: Number })\n minHeight = 200;\n\n @property({ type: Number })\n maxHeight = 800;\n\n @property({ type: Number })\n top = 100;\n\n @property({ type: Number })\n left = -1; // -1 means calculate from right side\n\n @property({ type: Boolean })\n hidden = true;\n\n @property({ type: Boolean })\n dragging = false;\n\n @property({ type: Boolean })\n chromeless = false;\n\n @property({ type: String })\n color = '#6B7280';\n\n @property({ type: Number })\n leftBoundaryMargin = 0;\n\n @property({ type: Number })\n rightBoundaryMargin = 0;\n\n @property({ type: Number })\n topBoundaryMargin = 0;\n\n @property({ type: Number })\n bottomBoundaryMargin = 0;\n\n private dragStartX = 0;\n private dragStartY = 0;\n private dragOffsetX = 0;\n private dragOffsetY = 0;\n private positionFromRight = false;\n private defaultTop = 100;\n private defaultLeft = -1;\n\n public firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n\n // store the default position from properties\n this.defaultTop = this.top;\n this.defaultLeft = this.left;\n\n // determine if we should position from right side\n if (this.left === -1) {\n this.positionFromRight = true;\n }\n\n // set up drag handle listeners for chromeless windows\n if (this.chromeless) {\n this.setupDragHandles();\n }\n\n // listen for window resize to keep window in bounds\n window.addEventListener('resize', this.handleResize);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('resize', this.handleResize);\n }\n\n private setupDragHandles() {\n // listen for mousedown on slotted content\n this.addEventListener('mousedown', this.handleSlotMouseDown);\n }\n\n private handleSlotMouseDown = (event: MouseEvent) => {\n // check if the target or any parent has the drag-handle class\n const target = event.target as HTMLElement;\n const dragHandle = target.closest('.drag-handle');\n\n if (!dragHandle) {\n return;\n }\n\n this.dragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragOffsetX = this.left;\n this.dragOffsetY = this.top;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n\n event.preventDefault();\n };\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('hidden')) {\n // when hiding, reset positioning behavior to original\n if (this.hidden && !changes.get('hidden')) {\n if (this.defaultLeft === -1) {\n this.positionFromRight = true;\n }\n }\n\n // reset to default position when showing\n if (!this.hidden && changes.get('hidden')) {\n // reset top to default\n this.top = this.defaultTop;\n\n // if positioned from right, recalculate based on current viewport\n if (this.positionFromRight) {\n this.left = window.innerWidth - this.width - 20;\n } else {\n // reset left to default\n this.left = this.defaultLeft;\n }\n }\n }\n\n // setup drag handles if chromeless changed to true\n if (changes.has('chromeless') && this.chromeless) {\n this.setupDragHandles();\n }\n }\n\n public handleClose() {\n this.hidden = true;\n // show all tabs when window is closed\n FloatingTab.showAllTabs();\n this.fireCustomEvent(CustomEventType.DialogHidden);\n }\n\n private handleHeaderMouseDown(event: MouseEvent) {\n // don't start drag if clicking on close button\n if ((event.target as HTMLElement).closest('.close-button')) {\n return;\n }\n\n this.dragging = true;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n this.dragOffsetX = this.left;\n this.dragOffsetY = this.top;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n\n event.preventDefault();\n }\n\n private handleMouseMove = (event: MouseEvent) => {\n if (!this.dragging) return;\n\n const deltaX = event.clientX - this.dragStartX;\n const deltaY = event.clientY - this.dragStartY;\n\n this.left = this.dragOffsetX + deltaX;\n this.top = this.dragOffsetY + deltaY;\n\n // keep window within viewport bounds with 20px padding\n const padding = 20;\n this.left = Math.max(\n padding - this.leftBoundaryMargin,\n Math.min(\n this.left,\n window.innerWidth - this.width - padding + this.rightBoundaryMargin\n )\n );\n\n // get the actual rendered height of the window element\n const windowElement = this.shadowRoot?.querySelector(\n '.window'\n ) as HTMLElement;\n const currentHeight =\n windowElement?.offsetHeight || this.maxHeight || window.innerHeight;\n const maxTop = Math.max(\n padding - this.topBoundaryMargin,\n window.innerHeight - currentHeight - padding + this.bottomBoundaryMargin\n );\n this.top = Math.max(\n padding - this.topBoundaryMargin,\n Math.min(this.top, maxTop)\n );\n };\n\n private handleMouseUp = () => {\n this.dragging = false;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n\n // once user drags the window, stop auto-positioning from right\n this.positionFromRight = false;\n };\n\n private handleResize = () => {\n // only constrain position if window is visible\n if (this.hidden) return;\n\n const padding = 20;\n const windowElement = this.shadowRoot?.querySelector(\n '.window'\n ) as HTMLElement;\n const currentHeight =\n windowElement?.offsetHeight || this.maxHeight || window.innerHeight;\n\n // if positioned from right, always recalculate from right edge\n if (this.positionFromRight) {\n this.left =\n window.innerWidth - this.width - padding + this.rightBoundaryMargin;\n } else {\n // only adjust left if out of bounds\n const minLeft = padding - this.leftBoundaryMargin;\n const maxLeft =\n window.innerWidth - this.width - padding + this.rightBoundaryMargin;\n\n if (this.left < minLeft) {\n this.left = minLeft;\n } else if (this.left > maxLeft) {\n this.left = maxLeft;\n }\n }\n\n // only adjust top if out of bounds\n const minTop = padding - this.topBoundaryMargin;\n const maxTop = Math.max(\n padding - this.topBoundaryMargin,\n window.innerHeight - currentHeight - padding + this.bottomBoundaryMargin\n );\n\n if (this.top < minTop) {\n this.top = minTop;\n } else if (this.top > maxTop) {\n this.top = maxTop;\n }\n };\n\n public show() {\n this.hidden = false;\n }\n\n public hide() {\n this.hidden = true;\n }\n\n public close() {\n this.hidden = true;\n // show all tabs when window is closed\n FloatingTab.showAllTabs();\n this.fireCustomEvent(CustomEventType.DialogHidden);\n }\n\n public render(): TemplateResult {\n const minHeightStyle = this.minHeight\n ? `min-height: ${this.minHeight}px;`\n : '';\n const maxHeightStyle = this.maxHeight\n ? `max-height: ${this.maxHeight}px;`\n : '';\n\n const windowStyle = `\n width: ${this.width}px;\n ${minHeightStyle}\n ${maxHeightStyle}\n top: ${this.top}px;\n left: ${this.left}px;\n --header-color: ${this.color};\n `;\n\n const windowClasses = getClasses({\n window: true,\n dragging: this.dragging,\n hidden: this.hidden,\n chromeless: this.chromeless\n });\n\n return html`\n <div class=\"${windowClasses}\" style=\"${windowStyle}\">\n ${!this.chromeless\n ? html`\n <div class=\"header\" @mousedown=${this.handleHeaderMouseDown}>\n <div class=\"title\">${this.header}</div>\n <button class=\"close-button\" @click=${this.handleClose}>\n <temba-icon name=\"close\" size=\"1.5\"></temba-icon>\n </button>\n </div>\n `\n : ''}\n <div class=\"body\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n"]}
@@ -59,7 +59,7 @@ export class ShortcutList extends StoreMonitorElement {
59
59
  style="
60
60
  overflow: hidden;
61
61
  text-overflow: ellipsis;
62
- width:100px;
62
+ width:175px;
63
63
  padding-right: 10px;
64
64
  white-space: nowrap;"
65
65
  >
@@ -1 +1 @@
1
- {"version":3,"file":"ShortcutList.js","sourceRoot":"","sources":["../../../src/list/ShortcutList.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE,MAAM,OAAO,YAAa,SAAQ,mBAAmB;IACnD,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;KAsBT,CAAC;IACJ,CAAC;IAWD;QACE,KAAK,EAAE,CAAC;QANV,sBAAiB,GAAG,EAAE,CAAC;QAGvB,gBAAW,GAAG,CAAC,CAAC;IAIhB,CAAC;IAES,YAAY,CACpB,OAA0D;QAE1D,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;IACrD,CAAC;IAEM,OAAO,CACZ,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK;qBAChC,YAAY,EAAE;qBACd,MAAM,CAAC,CAAC,QAAkB,EAAE,EAAE,CAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAChE,CAAC;YACN,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,QAAkB;QACtC,OAAO,IAAI,CAAA;;;;;;;;;UASL,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;UAiBb,QAAQ,CAAC,IAAI;;WAEZ,CAAC;IACV,CAAC;IAEM,WAAW;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;IAChC,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YACnC,CAAC,CAAC,IAAI,CAAA;cACA,IAAI,CAAC,MAAM;gBACX,CAAC,CAAC,IAAI,CAAA,uCAAuC,IAAI,CAAC,MAAM,UAAU;gBAClE,CAAC,CAAC,IAAI,CAAA;+BACW;iBACd;YACT,CAAC,CAAC,IAAI;;;yBAGW,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAClD,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM;;;;wBAIM,IAAI,CAAC,cAAc;uBACpB,IAAI,CAAC,WAAW;mBACpB,IAAI,CAAC,iBAAiB;;KAEpC,CAAC;IACJ,CAAC;CACF;AAtGC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACZ;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;uDACH;AAGvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDACX","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Shortcut } from '../interfaces';\nimport { StoreMonitorElement } from '../store/StoreMonitorElement';\nimport { Options } from '../display/Options';\n\nexport class ShortcutList extends StoreMonitorElement {\n static get styles() {\n return css`\n temba-options {\n display: block;\n width: 100%;\n flex-grow: 1;\n }\n\n .options-empty {\n height: 0;\n overflow: hidden;\n }\n\n .no-match {\n margin: 5px 10px;\n padding: 10px;\n }\n\n .filter {\n background: #f3f3f3;\n padding: 0.1em 0.3em;\n border-radius: var(--curvature);\n }\n `;\n }\n\n @property({ type: String })\n filter: string;\n\n @property({ type: Array })\n filteredShortcuts = [];\n\n @property({ type: Number })\n cursorIndex = 0;\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n }\n\n public storeUpdated(): void {\n this.filteredShortcuts = this.store.getShortcuts();\n }\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n\n if (changes.has('filter')) {\n if (!this.filter) {\n this.filteredShortcuts = this.store.getShortcuts();\n } else {\n this.filteredShortcuts = this.store\n .getShortcuts()\n .filter((shortcut: Shortcut) =>\n shortcut.name.toLowerCase().includes(this.filter.toLowerCase())\n );\n }\n this.cursorIndex = 0;\n }\n }\n\n public renderShortcut(shortcut: Shortcut): TemplateResult {\n return html`<div style=\"display:flex;align-items: center;min-width:0\">\n <div\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n width:100px; \n padding-right: 10px;\n white-space: nowrap;\"\n >\n ${shortcut.name}\n </div>\n <div\n style=\" \n font-size: 0.9em;\n color: rgba(0, 0, 0, 0.4);\n flex:1;\n overflow: hidden;\n text-overflow: ellipsis;\n\n display: -webkit-box;\n line-height: 16px;\n max-height: 16px;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n \"\n >\n ${shortcut.text}\n </div>\n </div>`;\n }\n\n public getShortcut() {\n const options = this.shadowRoot.querySelector('temba-options') as Options;\n return options.getSelection();\n }\n\n public render(): TemplateResult {\n return html`\n ${this.filteredShortcuts.length === 0\n ? html`<div class=\"no-match\">\n ${this.filter\n ? html`No matches for <span class=\"filter\">${this.filter}</span>.`\n : html`No shortcuts yet, create some to quickly include them in\n your messages.`}\n </div>`\n : null}\n\n <temba-options\n class=\"options-${this.filteredShortcuts.length === 0\n ? 'empty'\n : 'full'}\"\n block\n cursorHover\n visible\n .renderOption=${this.renderShortcut}\n .cursorIndex=${this.cursorIndex}\n .options=${this.filteredShortcuts}\n ></temba-options>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"ShortcutList.js","sourceRoot":"","sources":["../../../src/list/ShortcutList.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE,MAAM,OAAO,YAAa,SAAQ,mBAAmB;IACnD,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;KAsBT,CAAC;IACJ,CAAC;IAWD;QACE,KAAK,EAAE,CAAC;QANV,sBAAiB,GAAG,EAAE,CAAC;QAGvB,gBAAW,GAAG,CAAC,CAAC;IAIhB,CAAC;IAES,YAAY,CACpB,OAA0D;QAE1D,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;IACrD,CAAC;IAEM,OAAO,CACZ,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK;qBAChC,YAAY,EAAE;qBACd,MAAM,CAAC,CAAC,QAAkB,EAAE,EAAE,CAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAChE,CAAC;YACN,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,QAAkB;QACtC,OAAO,IAAI,CAAA;;;;;;;;;UASL,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;UAiBb,QAAQ,CAAC,IAAI;;WAEZ,CAAC;IACV,CAAC;IAEM,WAAW;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;IAChC,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YACnC,CAAC,CAAC,IAAI,CAAA;cACA,IAAI,CAAC,MAAM;gBACX,CAAC,CAAC,IAAI,CAAA,uCAAuC,IAAI,CAAC,MAAM,UAAU;gBAClE,CAAC,CAAC,IAAI,CAAA;+BACW;iBACd;YACT,CAAC,CAAC,IAAI;;;yBAGW,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAClD,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM;;;;wBAIM,IAAI,CAAC,cAAc;uBACpB,IAAI,CAAC,WAAW;mBACpB,IAAI,CAAC,iBAAiB;;KAEpC,CAAC;IACJ,CAAC;CACF;AAtGC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACZ;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;uDACH;AAGvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDACX","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Shortcut } from '../interfaces';\nimport { StoreMonitorElement } from '../store/StoreMonitorElement';\nimport { Options } from '../display/Options';\n\nexport class ShortcutList extends StoreMonitorElement {\n static get styles() {\n return css`\n temba-options {\n display: block;\n width: 100%;\n flex-grow: 1;\n }\n\n .options-empty {\n height: 0;\n overflow: hidden;\n }\n\n .no-match {\n margin: 5px 10px;\n padding: 10px;\n }\n\n .filter {\n background: #f3f3f3;\n padding: 0.1em 0.3em;\n border-radius: var(--curvature);\n }\n `;\n }\n\n @property({ type: String })\n filter: string;\n\n @property({ type: Array })\n filteredShortcuts = [];\n\n @property({ type: Number })\n cursorIndex = 0;\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n }\n\n public storeUpdated(): void {\n this.filteredShortcuts = this.store.getShortcuts();\n }\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n\n if (changes.has('filter')) {\n if (!this.filter) {\n this.filteredShortcuts = this.store.getShortcuts();\n } else {\n this.filteredShortcuts = this.store\n .getShortcuts()\n .filter((shortcut: Shortcut) =>\n shortcut.name.toLowerCase().includes(this.filter.toLowerCase())\n );\n }\n this.cursorIndex = 0;\n }\n }\n\n public renderShortcut(shortcut: Shortcut): TemplateResult {\n return html`<div style=\"display:flex;align-items: center;min-width:0\">\n <div\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n width:175px; \n padding-right: 10px;\n white-space: nowrap;\"\n >\n ${shortcut.name}\n </div>\n <div\n style=\" \n font-size: 0.9em;\n color: rgba(0, 0, 0, 0.4);\n flex:1;\n overflow: hidden;\n text-overflow: ellipsis;\n\n display: -webkit-box;\n line-height: 16px;\n max-height: 16px;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n \"\n >\n ${shortcut.text}\n </div>\n </div>`;\n }\n\n public getShortcut() {\n const options = this.shadowRoot.querySelector('temba-options') as Options;\n return options.getSelection();\n }\n\n public render(): TemplateResult {\n return html`\n ${this.filteredShortcuts.length === 0\n ? html`<div class=\"no-match\">\n ${this.filter\n ? html`No matches for <span class=\"filter\">${this.filter}</span>.`\n : html`No shortcuts yet, create some to quickly include them in\n your messages.`}\n </div>`\n : null}\n\n <temba-options\n class=\"options-${this.filteredShortcuts.length === 0\n ? 'empty'\n : 'full'}\"\n block\n cursorHover\n visible\n .renderOption=${this.renderShortcut}\n .cursorIndex=${this.cursorIndex}\n .options=${this.filteredShortcuts}\n ></temba-options>\n `;\n }\n}\n"]}
@@ -3,10 +3,11 @@ import { __decorate } from "tslib";
3
3
  import { css, html } from 'lit';
4
4
  import { property } from 'lit/decorators.js';
5
5
  import { CustomEventType } from '../interfaces';
6
- import { fetchResults, generateUUIDv7, getUrl, oxfordFn, postJSON, postUrl } from '../utils';
6
+ import { fetchResults, generateUUIDv7, getUrl, postJSON, postUrl } from '../utils';
7
7
  import { ContactStoreElement } from './ContactStoreElement';
8
8
  import { MessageType } from '../display/Chat';
9
9
  import { DEFAULT_AVATAR } from '../webchat/assets';
10
+ import { renderEvent, renderTicketAction, renderTicketAssigneeChanged } from '../events/eventRenderers';
10
11
  /*
11
12
  export const SCROLL_THRESHOLD = 100;
12
13
  export const SIMULATED_WEB_SLOWNESS = 0;
@@ -14,213 +15,8 @@ export const MAX_CHAT_REFRESH = 10000;
14
15
  export const MIN_CHAT_REFRESH = 500;
15
16
  export const BODY_SNIPPET_LENGTH = 250;
16
17
  */
17
- export var Events;
18
- (function (Events) {
19
- Events["AIRTIME_TRANSFERRED"] = "airtime_transferred";
20
- Events["BROADCAST_CREATED"] = "broadcast_created";
21
- Events["CALL_CREATED"] = "call_created";
22
- Events["CALL_MISSED"] = "call_missed";
23
- Events["CALL_RECEIVED"] = "call_received";
24
- Events["CHAT_STARTED"] = "chat_started";
25
- Events["CONTACT_FIELD_CHANGED"] = "contact_field_changed";
26
- Events["CONTACT_GROUPS_CHANGED"] = "contact_groups_changed";
27
- Events["CONTACT_LANGUAGE_CHANGED"] = "contact_language_changed";
28
- Events["CONTACT_NAME_CHANGED"] = "contact_name_changed";
29
- Events["CONTACT_STATUS_CHANGED"] = "contact_status_changed";
30
- Events["CONTACT_URNS_CHANGED"] = "contact_urns_changed";
31
- Events["IVR_CREATED"] = "ivr_created";
32
- Events["MSG_CREATED"] = "msg_created";
33
- Events["MSG_RECEIVED"] = "msg_received";
34
- Events["OPTIN_REQUESTED"] = "optin_requested";
35
- Events["OPTIN_STARTED"] = "optin_started";
36
- Events["OPTIN_STOPPED"] = "optin_stopped";
37
- Events["RUN_ENDED"] = "run_ended";
38
- Events["RUN_STARTED"] = "run_started";
39
- Events["TICKET_ASSIGNEE_CHANGED"] = "ticket_assignee_changed";
40
- Events["TICKET_CLOSED"] = "ticket_closed";
41
- Events["TICKET_NOTE_ADDED"] = "ticket_note_added";
42
- Events["TICKET_OPENED"] = "ticket_opened";
43
- Events["TICKET_REOPENED"] = "ticket_reopened";
44
- Events["TICKET_TOPIC_CHANGED"] = "ticket_topic_changed";
45
- })(Events || (Events = {}));
46
- const renderInfoList = (singular, plural, items) => {
47
- if (items.length === 1) {
48
- return html `<div>${singular} <strong>${items[0].name}</strong></div>`;
49
- }
50
- else {
51
- const list = items.map((item) => item.name);
52
- if (list.length === 2) {
53
- return html `<div>
54
- ${plural} <strong>${list[0]}</strong> and <strong>${list[1]}</strong>
55
- </div>`;
56
- }
57
- else {
58
- const last = list.pop();
59
- const middle = list.map((name, index) => html `<strong>${name}</strong>${index < list.length - 1 ? ', ' : ''}`);
60
- return html `<div>${plural} ${middle}, and <strong>${last}</strong></div>`;
61
- }
62
- }
63
- };
64
- const renderRunEvent = (event) => {
65
- let verb = 'Started';
66
- if (event.type === Events.RUN_ENDED) {
67
- if (event.status === 'completed') {
68
- verb = 'Completed';
69
- }
70
- else if (event.status === 'expired') {
71
- verb = 'Expired from';
72
- }
73
- else {
74
- verb = 'Interrupted';
75
- }
76
- }
77
- return html `<div>
78
- ${verb}
79
- <a href="/flow/editor/${event.flow.uuid}/"
80
- ><strong>${event.flow.name}</strong></a
81
- >
82
- </div>`;
83
- };
84
- const renderChatStartedEvent = (event) => {
85
- if (event.params) {
86
- return html `<div>Chat referral</div>`;
87
- }
88
- else {
89
- return html `<div>Chat started</div>`;
90
- }
91
- };
92
- const renderUpdateEvent = (event) => {
93
- return event.value
94
- ? html `<div>
95
- Updated <strong>${event.field.name}</strong> to
96
- <strong>${event.value.text}</strong>
97
- </div>`
98
- : html `<div>Cleared <strong>${event.field.name}</strong></div>`;
99
- };
100
- const renderNameChanged = (event) => {
101
- return html `<div>
102
- Updated <strong>name</strong> to <strong>${event.name}</strong>
103
- </div>`;
104
- };
105
- const renderContactURNsChanged = (event) => {
106
- return html `<div>
107
- Updated <strong>URNs</strong> to
108
- ${oxfordFn(event.urns, (urn) => html `<strong>${urn.split(':')[1].split('?')[0]}</strong>`)}
109
- </div>`;
110
- };
111
- export const renderTicketAction = (event, action) => {
112
- var _a;
113
- const ticketUUID = ((_a = event.ticket) === null || _a === void 0 ? void 0 : _a.uuid) || event.ticket_uuid;
114
- const actionNote = event.note
115
- ? html `<div
116
- style="width:85%; background: #fffac3; padding: 1em;margin-bottom: 1em;margin-top:1em; border: 1px solid #ffe97f;border-radius: var(--curvature);line-height: 1.2em; word-break: break-word;"
117
- >
118
- <div style="color: #8e830fff; font-size: 1em;margin-bottom:0.25em; ">
119
- <strong>${event._user ? event._user.name : 'Someone'}</strong> added a
120
- note
121
- <temba-date
122
- value=${event.created_on.toISOString()}
123
- display="relative"
124
- ></temba-date>
125
- </div>
126
- <div style="white-space: pre-wrap;">${event.note}</div>
127
- </div>`
128
- : null;
129
- if (action === 'noted') {
130
- return html `${actionNote}`;
131
- }
132
- const description = event._user
133
- ? html `<div>
134
- <strong>${event._user.name}</strong> ${action} a
135
- <strong><a href="/ticket/all/closed/${ticketUUID}/">ticket</a></strong>
136
- </div>`
137
- : html `<div>
138
- A
139
- <strong><a href="/ticket/all/closed/${ticketUUID}/">ticket</a></strong>
140
- was <strong>${action}</strong>
141
- </div>`;
142
- return html `<div style="${actionNote ? 'margin-bottom: 1em;' : ''}">
143
- ${description}
144
- </div>
145
- ${actionNote}`;
146
- };
147
- export const renderTicketAssigneeChanged = (event) => {
148
- if (event._user) {
149
- if (event.assignee) {
150
- return html `<div>
151
- <strong>${event._user.name}</strong> assigned this ticket to
152
- <strong>${event.assignee.name}</strong>
153
- </div>`;
154
- }
155
- else {
156
- return html `<div>
157
- <strong>${event._user.name}</strong> unassigned this ticket
158
- </div>`;
159
- }
160
- }
161
- else {
162
- if (event.assignee) {
163
- return html `<div>
164
- This ticket was assigned to <strong>${event.assignee.name}</strong>
165
- </div>`;
166
- }
167
- else {
168
- return html `<div>This ticket was unassigned</div>`;
169
- }
170
- }
171
- };
172
- export const renderTicketOpened = (event) => {
173
- return html `<div>${event.ticket.topic.name} ticket was opened</div>`;
174
- };
175
- export const renderContactGroupsEvent = (event) => {
176
- const groupsEvent = event;
177
- if (groupsEvent.groups_added) {
178
- return renderInfoList('Added to group', 'Added to groups', groupsEvent.groups_added);
179
- }
180
- else if (groupsEvent.groups_removed) {
181
- return renderInfoList('Removed from group', 'Removed from groups', groupsEvent.groups_removed);
182
- }
183
- };
184
- export const renderAirtimeTransferredEvent = (event) => {
185
- if (parseFloat(event.amount) === 0) {
186
- return html `<div>Airtime transfer failed</div>`;
187
- }
188
- return html `<div>
189
- Transferred <strong>${event.amount}</strong> ${event.currency} of airtime
190
- </div>`;
191
- };
192
- export const renderContactLanguageChangedEvent = (event) => {
193
- return html `<div>
194
- Language updated to <strong>${event.language}</strong>
195
- </div>`;
196
- };
197
- export const renderContactStatusChangedEvent = (event) => {
198
- return html `<div>Status updated to <strong>${event.status}</strong></div>`;
199
- };
200
- export const renderCallEvent = (event) => {
201
- if (event.type === Events.CALL_CREATED) {
202
- return html `<div>Call started</div>`;
203
- }
204
- else if (event.type === Events.CALL_MISSED) {
205
- return html `<div>Call missed</div>`;
206
- }
207
- else if (event.type === Events.CALL_RECEIVED) {
208
- return html `<div>Call answered</div>`;
209
- }
210
- };
211
- export const renderOptInEvent = (event) => {
212
- if (event.type === Events.OPTIN_REQUESTED) {
213
- return html `<div>
214
- Requested opt-in for <strong>${event.optin.name}</strong>
215
- </div>`;
216
- }
217
- else if (event.type === Events.OPTIN_STARTED) {
218
- return html `<div>Opted in to <strong>${event.optin.name}</strong></div>`;
219
- }
220
- else if (event.type === Events.OPTIN_STOPPED) {
221
- return html `<div>Opted out of <strong>${event.optin.name}</strong></div>`;
222
- }
223
- };
18
+ // re-export for backwards compatibility
19
+ export { renderTicketAction, renderTicketAssigneeChanged };
224
20
  export class ContactChat extends ContactStoreElement {
225
21
  static get styles() {
226
22
  return css `
@@ -584,119 +380,13 @@ export class ContactChat extends ContactStoreElement {
584
380
  }, this.pollingInterval);
585
381
  }
586
382
  prerender(event) {
587
- switch (event.type) {
588
- case Events.AIRTIME_TRANSFERRED:
589
- event._rendered = {
590
- html: renderAirtimeTransferredEvent(event),
591
- type: MessageType.Inline
592
- };
593
- break;
594
- case Events.CALL_CREATED:
595
- case Events.CALL_MISSED:
596
- case Events.CALL_RECEIVED:
597
- event._rendered = {
598
- html: renderCallEvent(event),
599
- type: MessageType.Inline
600
- };
601
- break;
602
- case Events.CHAT_STARTED:
603
- event._rendered = {
604
- html: renderChatStartedEvent(event),
605
- type: MessageType.Inline
606
- };
607
- break;
608
- case Events.CONTACT_FIELD_CHANGED:
609
- event._rendered = {
610
- html: renderUpdateEvent(event),
611
- type: MessageType.Inline
612
- };
613
- break;
614
- case Events.CONTACT_GROUPS_CHANGED:
615
- event._rendered = {
616
- html: renderContactGroupsEvent(event),
617
- type: MessageType.Inline
618
- };
619
- break;
620
- case Events.CONTACT_LANGUAGE_CHANGED:
621
- event._rendered = {
622
- html: renderContactLanguageChangedEvent(event),
623
- type: MessageType.Inline
624
- };
625
- break;
626
- case Events.CONTACT_NAME_CHANGED:
627
- event._rendered = {
628
- html: renderNameChanged(event),
629
- type: MessageType.Inline
630
- };
631
- break;
632
- case Events.CONTACT_STATUS_CHANGED:
633
- event._rendered = {
634
- html: renderContactStatusChangedEvent(event),
635
- type: MessageType.Inline
636
- };
637
- break;
638
- case Events.CONTACT_URNS_CHANGED:
639
- event._rendered = {
640
- html: renderContactURNsChanged(event),
641
- type: MessageType.Inline
642
- };
643
- break;
644
- case Events.OPTIN_REQUESTED:
645
- case Events.OPTIN_STARTED:
646
- case Events.OPTIN_STOPPED:
647
- event._rendered = {
648
- html: renderOptInEvent(event),
649
- type: MessageType.Inline
650
- };
651
- break;
652
- case Events.RUN_STARTED:
653
- case Events.RUN_ENDED:
654
- event._rendered = {
655
- html: renderRunEvent(event),
656
- type: MessageType.Inline
657
- };
658
- break;
659
- case Events.TICKET_ASSIGNEE_CHANGED:
660
- event._rendered = {
661
- html: renderTicketAssigneeChanged(event),
662
- type: MessageType.Inline
663
- };
664
- break;
665
- case Events.TICKET_CLOSED:
666
- event._rendered = {
667
- html: renderTicketAction(event, 'closed'),
668
- type: MessageType.Inline
669
- };
670
- break;
671
- case Events.TICKET_OPENED:
672
- event._rendered = {
673
- html: renderTicketAction(event, 'opened'),
674
- type: MessageType.Inline
675
- };
676
- break;
677
- case Events.TICKET_NOTE_ADDED:
678
- event._rendered = {
679
- html: renderTicketAction(event, 'noted'),
680
- type: MessageType.Inline
681
- };
682
- break;
683
- case Events.TICKET_REOPENED:
684
- event._rendered = {
685
- html: renderTicketAction(event, 'reopened'),
686
- type: MessageType.Inline
687
- };
688
- break;
689
- case Events.TICKET_TOPIC_CHANGED:
690
- event._rendered = {
691
- html: html `<div>
692
- Topic changed to
693
- <strong>${event.topic.name}</strong>
694
- </div>`,
695
- type: MessageType.Inline
696
- };
697
- break;
698
- default:
699
- // console.error('Unknown event type', event);
383
+ // use the unified renderEvent function with isSimulation = false
384
+ const rendered = renderEvent(event, false);
385
+ if (rendered) {
386
+ event._rendered = {
387
+ html: rendered,
388
+ type: MessageType.Inline
389
+ };
700
390
  }
701
391
  }
702
392
  createMessages(page) {
@@ -946,6 +636,7 @@ export class ContactChat extends ContactStoreElement {
946
636
  @temba-fetch-complete=${this.fetchComplete}
947
637
  avatar=${this.avatar}
948
638
  agent
639
+ avatars
949
640
  ?hasFooter=${inFlow}
950
641
  .showMessageLogsAfter=${this.showMessageLogsAfter}
951
642
  >