@nyaruka/temba-components 0.132.0 → 0.133.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.
- package/CHANGELOG.md +20 -1
- package/demo/components/flow/example.html +1 -0
- package/demo/static/css/tailwind.css +30019 -0
- package/dist/temba-components.js +434 -402
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +26 -6
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js +4 -4
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +124 -58
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +66 -30
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/layout/FloatingWindow.js +1 -2
- package/out-tsc/src/layout/FloatingWindow.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +1 -0
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +3 -2
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +63 -35
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/store/AppState.js +31 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/utils.js +3 -3
- package/out-tsc/src/utils.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +6 -5
- package/out-tsc/test/ActionHelper.js.map +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +1 -1
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-floating-window.test.js +0 -2
- package/out-tsc/test/temba-floating-window.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-node.test.js +109 -0
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-utils-uuid.test.js +45 -1
- package/out-tsc/test/temba-utils-uuid.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +2 -2
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/with-attachments.png +0 -0
- package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
- package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
- package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
- package/screenshots/truth/floating-tab/default.png +0 -0
- package/screenshots/truth/floating-tab/gray.png +0 -0
- package/screenshots/truth/floating-tab/green.png +0 -0
- package/screenshots/truth/floating-tab/hover.png +0 -0
- package/screenshots/truth/floating-tab/purple.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
- package/src/display/Chat.ts +29 -7
- package/src/display/FloatingTab.ts +4 -4
- package/src/events.ts +1 -4
- package/src/flow/CanvasNode.ts +130 -57
- package/src/flow/Editor.ts +84 -30
- package/src/layout/FloatingWindow.ts +1 -3
- package/src/list/ContentMenu.ts +1 -0
- package/src/list/SortableList.ts +3 -2
- package/src/live/ContactChat.ts +68 -42
- package/src/store/AppState.ts +41 -0
- package/src/utils.ts +3 -3
- package/test/ActionHelper.ts +13 -5
- package/test/actions/send_broadcast.test.ts +2 -1
- package/test/temba-contact-chat.test.ts +1 -1
- package/test/temba-floating-window.test.ts +0 -2
- package/test/temba-flow-editor-node.test.ts +129 -0
- package/test/temba-utils-uuid.test.ts +61 -1
- package/test/utils.test.ts +7 -2
- package/test-assets/contacts/history.json +22 -9
- package/web-test-runner.config.mjs +3 -3
|
@@ -111,7 +111,7 @@ export class FloatingWindow extends RapidElement {
|
|
|
111
111
|
transition: transform var(--transition-duration, 300ms) ease-in-out,
|
|
112
112
|
opacity var(--transition-duration, 300ms) ease-in-out;
|
|
113
113
|
position: fixed;
|
|
114
|
-
z-index:
|
|
114
|
+
z-index: 5000;
|
|
115
115
|
top: 100px;
|
|
116
116
|
background: white;
|
|
117
117
|
border-radius: 8px;
|
|
@@ -215,7 +215,6 @@ export class FloatingWindow extends RapidElement {
|
|
|
215
215
|
updated(changes) {
|
|
216
216
|
super.updated(changes);
|
|
217
217
|
if (changes.has('hidden')) {
|
|
218
|
-
this.classList.toggle('hidden', this.hidden);
|
|
219
218
|
// when hiding, reset positioning behavior to original
|
|
220
219
|
if (this.hidden && !changes.get('hidden')) {
|
|
221
220
|
if (this.defaultLeft === -1) {
|
|
@@ -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: 9999;\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 }\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 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 this.classList.toggle('hidden', this.hidden);\n\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,\n Math.min(this.left, window.innerWidth - this.width - padding)\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,\n window.innerHeight - currentHeight - padding\n );\n this.top = Math.max(padding, Math.min(this.top, maxTop));\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 = window.innerWidth - this.width - padding;\n } else {\n // only adjust left if out of bounds\n const minLeft = padding;\n const maxLeft = window.innerWidth - this.width - padding;\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;\n const maxTop = Math.max(\n padding,\n window.innerHeight - currentHeight - padding\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 }\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 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,\n Math.min(this.left, window.innerWidth - this.width - padding)\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,\n window.innerHeight - currentHeight - padding\n );\n this.top = Math.max(padding, Math.min(this.top, maxTop));\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 = window.innerWidth - this.width - padding;\n } else {\n // only adjust left if out of bounds\n const minLeft = padding;\n const maxLeft = window.innerWidth - this.width - padding;\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;\n const maxTop = Math.max(\n padding,\n window.innerHeight - currentHeight - padding\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentMenu.js","sourceRoot":"","sources":["../../../src/list/ContentMenu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAkB,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAe,MAAM,UAAU,CAAC;AAE/C,MAAM,OAAO,GAAG;IACd,sBAAsB,EAAE,GAAG;IAC3B,aAAa,EAAE,GAAG;CACnB,CAAC;AAeF,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,oCAAa,CAAA;IACb,gCAAS,CAAA;IACT,4CAAqB,CAAA;IACrB,sCAAe,CAAA;IACf,0CAAmB,CAAA;AACrB,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B;AAED,MAAM,OAAO,WAAY,SAAQ,YAAY;IAA7C;;
|
|
1
|
+
{"version":3,"file":"ContentMenu.js","sourceRoot":"","sources":["../../../src/list/ContentMenu.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\n\nimport { RapidElement } from '../RapidElement';\nimport { getUrl, WebResponse } from '../utils';\n\nconst HEADERS = {\n 'X-Temba-Content-Menu': '1',\n 'X-Temba-Spa': '1'\n};\nexport interface ContentMenuItem {\n type: string;\n as_button: boolean;\n label: string;\n url: string;\n disabled: boolean;\n modal_id: string;\n on_submit: string;\n primary: boolean;\n title: string;\n on_click: null;\n link_class: string;\n}\n\nexport enum ContentMenuItemType {\n LINK = 'link',\n JS = 'js',\n URL_POST = 'url_post',\n MODAX = 'modax',\n DIVIDER = 'divider'\n}\n\nexport class ContentMenu extends RapidElement {\n static get styles() {\n return css`\n :host {\n tabindex: 0;\n z-index: 5000;\n }\n .container {\n --button-y: 0.4em;\n --button-x: 1em;\n display: flex;\n align-items: center;\n }\n\n .button_item,\n .primary_button_item {\n margin-left: 1rem;\n }\n\n temba-button {\n margin-right: 0.5rem;\n }\n .toggle {\n --icon-color: rgb(102, 102, 102);\n padding: 0.4em;\n }\n\n .toggle:hover {\n background: rgba(0, 0, 0, 0.05);\n border-radius: var(--curvature);\n --icon-color: rgb(136, 136, 136);\n }\n\n .dropdown {\n padding: 1rem 1.5rem;\n color: rgb(45, 45, 45);\n z-index: 50;\n min-width: 200px;\n tabindex: 0;\n }\n\n .divider {\n border-bottom: 1px solid rgb(237, 237, 237);\n margin: 1rem -1.5em;\n }\n\n .item {\n white-space: nowrap;\n margin: 0.2em 0em;\n font-size: 1.1rem;\n cursor: pointer;\n font-weight: 400;\n tabindex: 0;\n }\n\n .item:hover {\n color: var(--color-link-primary);\n }\n `;\n }\n\n @property({ type: String })\n endpoint: string;\n\n @property({ type: Number })\n legacy: number;\n\n @property({ type: Array, attribute: false })\n buttons: ContentMenuItem[] = [];\n\n @property({ type: Array, attribute: false })\n items: ContentMenuItem[] = [];\n\n @property({ type: Boolean })\n arrowTopLeft: boolean;\n\n private fetchContentMenu() {\n const url = this.endpoint;\n if (url) {\n const legacy = this.legacy;\n const headers = HEADERS;\n if (legacy) {\n delete headers['Temba-Spa'];\n }\n\n //ok, fetch the content menu\n getUrl(url, null, headers)\n .then((response: WebResponse) => {\n const json = response.json;\n const contentMenu = json.items as ContentMenuItem[];\n\n //populate (or initialize) the buttons and items\n if (contentMenu) {\n this.buttons = contentMenu.filter((item) => item.as_button);\n this.items = contentMenu.filter((item) => !item.as_button);\n } else {\n this.buttons = [];\n this.items = [];\n }\n\n //fire custom loaded event type when we're finished\n this.fireCustomEvent(CustomEventType.Loaded, {\n buttons: this.buttons,\n items: this.items\n });\n })\n .catch((error: any) => {\n this.fireCustomEvent(CustomEventType.Loaded, {\n buttons: this.buttons,\n items: this.items\n });\n\n console.error(error);\n });\n }\n }\n\n public refresh() {\n this.fetchContentMenu();\n }\n\n protected updated(changes: Map<string, any>) {\n super.updated(changes);\n if (changes.has('endpoint') || changes.has('legacy')) {\n this.fetchContentMenu();\n }\n }\n\n private handleItemClicked(item: ContentMenuItem, event: MouseEvent) {\n this.fireCustomEvent(CustomEventType.Selection, { item, event });\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"container\">\n ${this.buttons.map((button) => {\n return html`<temba-button\n class=\"${button.primary ? 'primary_button_item' : 'button_item'}\"\n name=${button.label}\n @click=${(event) => this.handleItemClicked(button, event)}\n >\n ${button.label}\n </temba-button>`;\n })}\n ${this.items && this.items.length > 0\n ? html`<temba-dropdown>\n <div slot=\"toggle\" class=\"toggle\">\n <temba-icon name=\"menu\" size=\"1.5\"></temba-icon>\n </div>\n <div slot=\"dropdown\" class=\"dropdown\">\n ${this.items.map((item) => {\n if (item.type === ContentMenuItemType.DIVIDER) {\n return html` <div class=\"divider\"></div>`;\n } else {\n return html` <div\n class=\"item\"\n name=${item.label}\n @click=${(event) => this.handleItemClicked(item, event)}\n >\n ${item.label}\n </div>`;\n }\n })}\n </div>\n </temba-dropdown>`\n : null}\n </div>\n `;\n }\n}\n"]}
|
|
@@ -464,8 +464,9 @@ export class SortableList extends RapidElement {
|
|
|
464
464
|
// use swap-based logic - report which indexes need to be swapped
|
|
465
465
|
const fromIdx = originalDragIdx;
|
|
466
466
|
const toIdx = this.pendingDropIndex;
|
|
467
|
-
// only fire if the position actually changed
|
|
468
|
-
|
|
467
|
+
// only fire if the position actually changed AND this is not an external drag
|
|
468
|
+
// External drags are handled by external drop handlers
|
|
469
|
+
if (fromIdx !== toIdx && !this.isExternalDrag) {
|
|
469
470
|
this.fireCustomEvent(CustomEventType.OrderChanged, {
|
|
470
471
|
swap: [fromIdx, toIdx]
|
|
471
472
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SortableList.js","sourceRoot":"","sources":["../../../src/list/SortableList.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;GAEG;AAEH,2CAA2C;AAC3C,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,uDAAuD;AACvD,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC,MAAM,OAAO,YAAa,SAAQ,YAAY;IAE5C,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmCT,CAAC;IACJ,CAAC;IA6CD;QACE,KAAK,EAAE,CAAC;QAxCV,eAAU,GAAY,KAAK,CAAC;QAS5B,QAAG,GAAW,KAAK,CAAC;QAGpB,iBAAY,GAAY,KAAK,CAAC;QAS9B,iBAAY,GAAmB,IAAI,CAAC;QACpC,YAAO,GAAmB,IAAI,CAAC;QAC/B,wBAAmB,GAAY,IAAI,CAAC,CAAC,4BAA4B;QACjE,sBAAiB,GAAW,CAAC,CAAC,CAAC,CAAC,6CAA6C;QAC7E,YAAO,GAAG,CAAC,CAAC;QACZ,YAAO,GAAG,CAAC,CAAC;QACZ,UAAK,GAAG,CAAC,CAAC;QACV,UAAK,GAAG,CAAC,CAAC;QAEV,gBAAW,GAAG,CAAC,CAAC,CAAC;QACjB,gBAAW,GAAG,IAAI,CAAC;QACnB,oBAAe,GAAmB,IAAI,CAAC;QACvC,qBAAgB,GAAG,CAAC,CAAC,CAAC;QACtB,yBAAoB,GAAgB,IAAI,CAAC;QACzC,mBAAc,GAAG,KAAK,CAAC;QAEf,iBAAY,GAAqC,IAAI,CAAC;QAI5D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IAEO,mBAAmB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU;aACzB,aAAa,CAAC,MAAM,CAAC;aACrB,gBAAgB,EAAE;aAClB,MAAM,CACL,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAC9C,CAAC;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,oBAAoB,CAAC,MAAc,EAAE,MAAc;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAC9D,IAAI,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;QAE7B,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,EAAE,CAAC;QAC/C,kEAAkE;QAClE,OAAO,CACL,MAAM,IAAI,IAAI,CAAC,IAAI,GAAG,qBAAqB;YAC3C,MAAM,IAAI,IAAI,CAAC,KAAK,GAAG,qBAAqB;YAC5C,MAAM,IAAI,IAAI,CAAC,GAAG,GAAG,qBAAqB;YAC1C,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAC9C,CAAC;IACJ,CAAC;IAEO,qBAAqB,CAAC,OAAoB;QAChD,6BAA6B;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAgB,CAAC;QAErD,0DAA0D;QAC1D,MAAM,cAAc,GAAG,CAAC,QAAqB,EAAE,MAAmB,EAAE,EAAE;YACpE,IAAI,CAAC;gBACH,oBAAoB;gBACpB,MAAM,cAAc,GAAG,QAAQ,CAAC,gBAAgB,CAC9C,yBAAyB,CAC1B,CAAC;gBACF,MAAM,YAAY,GAAG,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,CAAC;gBAExE,cAAc,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE;oBAC9C,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAGjB,CAAC;oBACtB,IAAI,WAAW,EAAE,CAAC;wBAChB,IAAI,aAAa,YAAY,gBAAgB,EAAE,CAAC;4BAC9C,MAAM,iBAAiB,GAAG,aAAiC,CAAC;4BAC5D,MAAM,eAAe,GAAG,WAA+B,CAAC;4BAExD,IACE,iBAAiB,CAAC,IAAI,KAAK,UAAU;gCACrC,iBAAiB,CAAC,IAAI,KAAK,OAAO,EAClC,CAAC;gCACD,eAAe,CAAC,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC;4BACtD,CAAC;iCAAM,CAAC;gCACN,eAAe,CAAC,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC;4BAClD,CAAC;wBACH,CAAC;6BAAM,IAAI,aAAa,YAAY,mBAAmB,EAAE,CAAC;4BACvD,WAAmC,CAAC,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC;wBACnE,CAAC;6BAAM,IAAI,aAAa,YAAY,iBAAiB,EAAE,CAAC;4BACrD,WAAiC,CAAC,aAAa;gCAC9C,aAAa,CAAC,aAAa,CAAC;wBAChC,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,4EAA4E;gBAC5E,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;gBACvE,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;gBAEnE,mBAAmB,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;oBAChD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;oBAC1C,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;wBAC3B,wCAAwC;wBACxC,IACE,UAAU,CAAC,OAAO;4BAClB,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EACrD,CAAC;4BACD,IAAI,CAAC;gCACH,yCAAyC;gCACzC,MAAM,UAAU,GAAG;oCACjB,OAAO;oCACP,QAAQ;oCACR,eAAe;oCACf,SAAS;oCACT,UAAU;oCACV,aAAa;iCACd,CAAC;gCACF,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;oCAC1B,IACE,IAAI,IAAI,UAAU;wCACjB,UAAkB,CAAC,IAAI,CAAC,KAAK,SAAS,EACvC,CAAC;wCACA,QAAgB,CAAC,IAAI,CAAC,GAAI,UAAkB,CAAC,IAAI,CAAC,CAAC;oCACtD,CAAC;gCACH,CAAC,CAAC,CAAC;gCAEH,6DAA6D;gCAC7D,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;oCACjD,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gCAC/C,CAAC,CAAC,CAAC;4BACL,CAAC;4BAAC,OAAO,CAAC,EAAE,CAAC;gCACX,8CAA8C;4BAChD,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,gDAAgD;4BAChD,IAAI,CAAC;gCACH,IACE,OAAO,IAAI,UAAU;oCACpB,UAAkB,CAAC,KAAK,KAAK,SAAS,EACvC,CAAC;oCACA,QAAgB,CAAC,KAAK,GAAI,UAAkB,CAAC,KAAK,CAAC;gCACtD,CAAC;4BACH,CAAC;4BAAC,OAAO,CAAC,EAAE,CAAC;gCACX,wCAAwC;4BAC1C,CAAC;4BAED,gDAAgD;4BAChD,IAAI,CAAC;gCACH,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;oCACjD,IACE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;wCAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAC7B,CAAC;wCACD,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;oCAC/C,CAAC;gCACH,CAAC,CAAC,CAAC;4BACL,CAAC;4BAAC,OAAO,CAAC,EAAE,CAAC;gCACX,wCAAwC;4BAC1C,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,iDAAiD;gBACjD,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,CAAC,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC,CAAC;QAEF,4DAA4D;QAC5D,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAE/B,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IAEO,WAAW,CAAC,EAAU;QAC5B,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;IAEO,iBAAiB,CACvB,MAAc,EACd,MAAc;QAEd,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAChD,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,GAAG,CAAC,EAAE,MAAK,MAAA,IAAI,CAAC,WAAW,0CAAE,EAAE,CAAA,CAAA,EAAA,CACzC,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,4EAA4E;YAC5E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;gBAE3C,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;oBACrB,6BAA6B;oBAC7B,OAAO,EAAE,OAAO,EAAE,GAAqB,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,wDAAwD;YACxD,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAmB;gBACxD,WAAW,EAAE,IAAI;aAClB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,0EAA0E;YAC1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxB,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;gBAE3C,IAAI,MAAM,GAAG,OAAO,EAAE,CAAC;oBACrB,6BAA6B;oBAC7B,OAAO,EAAE,OAAO,EAAE,GAAqB,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,wDAAwD;YACxD,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAmB;gBACxD,WAAW,EAAE,IAAI;aAClB,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,mBAAmB,CACzB,aAA0B,EAC1B,WAAoB;QAEpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO;QAEhD,wEAAwE;QACxE,IAAI,aAAa,KAAK,IAAI,CAAC,WAAW;YAAE,OAAO;QAE/C,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAErD,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,2BAA2B,CAAC;QAE7D,mEAAmE;QACnE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC;YACtC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YACrD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACvD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YAC1D,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,YAAY,GAAG,kBAAkB,CAAC;YAC7D,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;YAC5C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;YAClD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,oBAAoB,CAAC;QAC3D,CAAC;QAED,4DAA4D;QAC5D,IAAI,WAAW,EAAE,CAAC;YAChB,aAAa,CAAC,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,qBAAqB,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAEO,mBAAmB;QACzB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,sBAAsB;QAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB;YAAE,OAAO;QAEvD,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,2BAA2B,CAAC;QAE7D,4CAA4C;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACtC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACrD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACvD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAC1D,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,YAAY,GAAG,kBAAkB,CAAC;QAC7D,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;QAC5C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;QAClD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,oBAAoB,CAAC;QAEzD,iEAAiE;QACjE,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IACvE,CAAC;IAEO,eAAe,CAAC,KAAiB;QACvC,IAAI,GAAG,GAAG,KAAK,CAAC,MAAwB,CAAC;QAEzC,kEAAkE;QAClE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;QACH,CAAC;QAED,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC/B,IAAI,GAAG,EAAE,CAAC;YACR,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC;YACnB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;YAEvB,+EAA+E;YAC/E,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAC;YACzC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC,wCAAwC;YACzE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;YACzC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;YACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;YAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;YAE3B,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAC7D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,KAAiB;QACvC,IACE,CAAC,IAAI,CAAC,YAAY;YAClB,IAAI,CAAC,OAAO;YACZ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc;gBACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,EACxD,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,SAAS,EAAE;gBAC9C,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;aACpB,CAAC,CAAC;YAEH,uDAAuD;YACvD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE3D,oDAAoD;YACpD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAC5C,IAAI,CAAC,OAAO,CACK,CAAC;YAEpB,gEAAgE;YAChE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YACtD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAEpC,6BAA6B;YAC7B,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEzC,qDAAqD;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAEtC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;YAC3C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAClE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACpD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC;YACzC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;YACxC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC;YAElD,8CAA8C;YAC9C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvC,CAAC;YAED,8CAA8C;YAC9C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAE7C,uEAAuE;YACvE,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAE9B,4CAA4C;YAC5C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAa,EAAE,EAAE;oBACpC,CAAC,CAAC,eAAe,EAAE,CAAC;oBACpB,CAAC,CAAC,cAAc,EAAE,CAAC;gBACrB,CAAC,CAAC;gBACF,uEAAuE;gBACvE,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAElE,iFAAiF;YACjF,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY;gBACvC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;gBACzD,CAAC,CAAC,IAAI,CAAC,CAAC,gEAAgE;YAE1E,yEAAyE;YACzE,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBAClE,iCAAiC;gBACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAE3B,kDAAkD;gBAClD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;gBAC3C,CAAC;gBAED,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,YAAY,EAAE;oBACjD,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;oBACnB,MAAM,EAAE,KAAK,CAAC,OAAO;oBACrB,MAAM,EAAE,KAAK,CAAC,OAAO;iBACtB,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,YAAY,IAAI,eAAe,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACvE,sCAAsC;gBACtC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;gBAE5B,wDAAwD;gBACxD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC5C,CAAC;gBAED,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,YAAY,EAAE;oBACjD,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;iBACpB,CAAC,CAAC;YACL,CAAC;YAED,0EAA0E;YAC1E,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACzB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBACxE,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC;oBAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;oBAErD,oEAAoE;oBACpE,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC;oBAE/C,qEAAqE;oBACrE,uFAAuF;oBAEvF,IAAI,OAAO,CAAC;oBACZ,IAAI,SAAS,GAAG,eAAe,EAAE,CAAC;wBAChC,gEAAgE;wBAChE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBACpD,CAAC;yBAAM,CAAC;wBACN,iEAAiE;wBACjE,gHAAgH;wBAChH,8HAA8H;wBAC9H,qIAAqI;wBACrI,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;oBACpD,CAAC;oBAED,mDAAmD;oBACnD,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC;oBACrC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;oBAChC,IAAI,CAAC,oBAAoB,GAAG,aAAa,CAAC;oBAE1C,wBAAwB;oBACxB,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;gBACvD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC3B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBACzB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;oBAC3B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;gBACnC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,6EAA6E;gBAC7E,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,YAAY,EAAE;oBACjD,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;oBACnB,MAAM,EAAE,KAAK,CAAC,OAAO;oBACrB,MAAM,EAAE,KAAK,CAAC,OAAO;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,GAAe;QACnC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACzC,GAAG,CAAC,cAAc,EAAE,CAAC;YACrB,GAAG,CAAC,eAAe,EAAE,CAAC;YAEtB,4CAA4C;YAC5C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YAC7B,CAAC;YAED,uEAAuE;YACvE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC;YACxD,CAAC;YAED,4CAA4C;YAC5C,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE3B,kFAAkF;YAClF,IACE,CAAC,IAAI,CAAC,cAAc;gBACpB,IAAI,CAAC,gBAAgB,IAAI,CAAC;gBAC1B,IAAI,CAAC,oBAAoB,EACzB,CAAC;gBACD,oEAAoE;gBACpE,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC;gBAE/C,iEAAiE;gBACjE,MAAM,OAAO,GAAG,eAAe,CAAC;gBAChC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC;gBAEpC,6CAA6C;gBAC7C,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;oBACtB,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,YAAY,EAAE;wBACjD,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,QAAQ,EAAE;gBAC7C,EAAE,EAAE,IAAI,CAAC,UAAU;gBACnB,UAAU,EAAE,IAAI,CAAC,cAAc;gBAC/B,MAAM,EAAE,GAAG,CAAC,OAAO;gBACnB,MAAM,EAAE,GAAG,CAAC,OAAO;aACpB,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;YAC3B,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAE5B,gDAAgD;YAChD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YAEzB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE3B,4DAA4D;YAC5D,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,oCAAoC;gBACpC,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;wBAC/D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBAC3B,CAAC;gBACH,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAChE,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1C,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;;2BAEY,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;sBACxC,IAAI,CAAC,GAAG;;2BAEH,IAAI,CAAC,eAAe;;KAE1C,CAAC;IACJ,CAAC;CACF;AAjkBC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDACR;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gDACA;AAG5B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDACN;AAGrB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDACR;AAGnB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;yCACP;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;kDACE;AAO9B;IADC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;kDACa","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\n\n/**\n * A simple list that can be sorted by dragging\n */\n\n// how far we have to drag before it starts\nconst DRAG_THRESHOLD = 2;\n\n// padding around container for external drag detection\nconst EXTERNAL_DRAG_PADDING = 50;\n\nexport class SortableList extends RapidElement {\n originalDownDisplay: string;\n static get styles() {\n return css`\n :host {\n margin: auto;\n }\n\n .container {\n user-select: none;\n position: relative;\n display: grid;\n grid-template-columns: 1fr;\n }\n\n .container.horizontal {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n }\n\n .dragging {\n background: var(--color-selection);\n }\n\n .slot {\n flex-grow: 1;\n }\n\n slot > * {\n user-select: none;\n }\n\n temba-icon {\n opacity: 0.1;\n padding: 0.2em 0.5em;\n transition: all 300ms ease-in-out;\n }\n `;\n }\n\n @property({ type: String })\n draggingId: string;\n\n @property({ type: Boolean })\n horizontal: boolean = false;\n\n @property({ type: String })\n dropTargetId: string;\n\n @property({ type: String })\n dragHandle: string;\n\n @property({ type: String })\n gap: string = '0em';\n\n @property({ type: Boolean })\n externalDrag: boolean = false;\n\n /**\n * Optional callback to allow parent components to customize the ghost node.\n * Called after the ghost node is cloned but before it is appended to the DOM.\n */\n @property({ attribute: false })\n prepareGhost?: (ghost: HTMLElement) => void;\n\n ghostElement: HTMLDivElement = null;\n downEle: HTMLDivElement = null;\n originalElementRect: DOMRect = null; // Store original dimensions\n originalDragIndex: number = -1; // Store original index before moving element\n xOffset = 0;\n yOffset = 0;\n yDown = 0;\n xDown = 0;\n\n draggingIdx = -1;\n draggingEle = null;\n dropPlaceholder: HTMLDivElement = null;\n pendingDropIndex = -1;\n pendingTargetElement: HTMLElement = null;\n isExternalDrag = false;\n\n private clickBlocker: ((e: MouseEvent) => void) | null = null;\n\n public constructor() {\n super();\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n this.handleMouseDown = this.handleMouseDown.bind(this);\n }\n\n private getSortableElements(): Element[] {\n const eles = this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .filter(\n (ele) =>\n ele.classList.contains('sortable') &&\n !ele.classList.contains('drop-placeholder')\n );\n return eles;\n }\n\n private isMouseOverContainer(mouseX: number, mouseY: number): boolean {\n const container = this.shadowRoot.querySelector('.container');\n if (!container) return false;\n\n const rect = container.getBoundingClientRect();\n // add some padding to make it easier to stay within the container\n return (\n mouseX >= rect.left - EXTERNAL_DRAG_PADDING &&\n mouseX <= rect.right + EXTERNAL_DRAG_PADDING &&\n mouseY >= rect.top - EXTERNAL_DRAG_PADDING &&\n mouseY <= rect.bottom + EXTERNAL_DRAG_PADDING\n );\n }\n\n private cloneElementWithState(element: HTMLElement): HTMLElement {\n // First create a basic clone\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Helper function to copy form element values recursively\n const copyFormValues = (original: HTMLElement, cloned: HTMLElement) => {\n try {\n // Copy input values\n const originalInputs = original.querySelectorAll(\n 'input, textarea, select'\n );\n const clonedInputs = cloned.querySelectorAll('input, textarea, select');\n\n originalInputs.forEach((originalInput, index) => {\n const clonedInput = clonedInputs[index] as\n | HTMLInputElement\n | HTMLTextAreaElement\n | HTMLSelectElement;\n if (clonedInput) {\n if (originalInput instanceof HTMLInputElement) {\n const originalHtmlInput = originalInput as HTMLInputElement;\n const clonedHtmlInput = clonedInput as HTMLInputElement;\n\n if (\n originalHtmlInput.type === 'checkbox' ||\n originalHtmlInput.type === 'radio'\n ) {\n clonedHtmlInput.checked = originalHtmlInput.checked;\n } else {\n clonedHtmlInput.value = originalHtmlInput.value;\n }\n } else if (originalInput instanceof HTMLTextAreaElement) {\n (clonedInput as HTMLTextAreaElement).value = originalInput.value;\n } else if (originalInput instanceof HTMLSelectElement) {\n (clonedInput as HTMLSelectElement).selectedIndex =\n originalInput.selectedIndex;\n }\n }\n });\n\n // Copy properties from all custom elements that might have a value property\n const allOriginalElements = Array.from(original.querySelectorAll('*'));\n const allClonedElements = Array.from(cloned.querySelectorAll('*'));\n\n allOriginalElements.forEach((originalEl, index) => {\n const clonedEl = allClonedElements[index];\n if (clonedEl && originalEl) {\n // Special handling for temba components\n if (\n originalEl.tagName &&\n originalEl.tagName.toLowerCase().startsWith('temba-')\n ) {\n try {\n // Copy common temba component properties\n const tembaProps = [\n 'value',\n 'values',\n 'selectedValue',\n 'checked',\n 'selected',\n 'textContent'\n ];\n tembaProps.forEach((prop) => {\n if (\n prop in originalEl &&\n (originalEl as any)[prop] !== undefined\n ) {\n (clonedEl as any)[prop] = (originalEl as any)[prop];\n }\n });\n\n // Copy all attributes for temba components to preserve state\n Array.from(originalEl.attributes).forEach((attr) => {\n clonedEl.setAttribute(attr.name, attr.value);\n });\n } catch (e) {\n // Ignore errors when copying temba properties\n }\n } else {\n // Try to copy value property for other elements\n try {\n if (\n 'value' in originalEl &&\n (originalEl as any).value !== undefined\n ) {\n (clonedEl as any).value = (originalEl as any).value;\n }\n } catch (e) {\n // Ignore errors when copying properties\n }\n\n // Copy data attributes that might contain state\n try {\n Array.from(originalEl.attributes).forEach((attr) => {\n if (\n attr.name.startsWith('data-') ||\n attr.name.startsWith('aria-')\n ) {\n clonedEl.setAttribute(attr.name, attr.value);\n }\n });\n } catch (e) {\n // Ignore errors when copying attributes\n }\n }\n }\n });\n } catch (e) {\n // If anything fails, just return the basic clone\n console.warn('Failed to copy form values in cloneElementWithState:', e);\n }\n };\n\n // Copy form values for the root element and all descendants\n copyFormValues(element, clone);\n\n return clone;\n }\n\n public getIds() {\n return this.getSortableElements().map((ele) => ele.id);\n }\n\n private getRowIndex(id: string): number {\n return this.getSortableElements().findIndex((ele) => ele.id === id);\n }\n\n private getDropTargetInfo(\n mouseX: number,\n mouseY: number\n ): { element: HTMLDivElement; insertAfter: boolean } | null {\n const elements = this.getSortableElements().filter(\n (ele) => ele.id !== this.draggingEle?.id\n );\n\n if (elements.length === 0) return null;\n\n if (this.horizontal) {\n // For horizontal layout, find the insertion point based on mouse X position\n for (let i = 0; i < elements.length; i++) {\n const ele = elements[i];\n const rect = ele.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n\n if (mouseX < centerX) {\n // Insert before this element\n return { element: ele as HTMLDivElement, insertAfter: false };\n }\n }\n // If we're past all elements, insert after the last one\n return {\n element: elements[elements.length - 1] as HTMLDivElement,\n insertAfter: true\n };\n } else {\n // For vertical layout, find the insertion point based on mouse Y position\n for (let i = 0; i < elements.length; i++) {\n const ele = elements[i];\n const rect = ele.getBoundingClientRect();\n const centerY = rect.top + rect.height / 2;\n\n if (mouseY < centerY) {\n // Insert before this element\n return { element: ele as HTMLDivElement, insertAfter: false };\n }\n }\n // If we're past all elements, insert after the last one\n return {\n element: elements[elements.length - 1] as HTMLDivElement,\n insertAfter: true\n };\n }\n }\n\n private showDropPlaceholder(\n targetElement: HTMLElement,\n insertAfter: boolean\n ) {\n this.hideDropPlaceholder();\n\n if (!targetElement || !this.draggingEle) return;\n\n // Don't show placeholder if we're targeting the dragging element itself\n if (targetElement === this.draggingEle) return;\n\n this.dropPlaceholder = document.createElement('div');\n\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Copy dimensions from the original element (before it was hidden)\n if (this.originalElementRect) {\n const rect = this.originalElementRect;\n this.dropPlaceholder.style.width = rect.width + 'px';\n this.dropPlaceholder.style.height = rect.height + 'px';\n this.dropPlaceholder.style.minHeight = rect.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.border = '2px dashed #d1d5db';\n }\n\n // Insert the placeholder in the correct position in the DOM\n if (insertAfter) {\n targetElement.insertAdjacentElement('afterend', this.dropPlaceholder);\n } else {\n targetElement.insertAdjacentElement('beforebegin', this.dropPlaceholder);\n }\n }\n\n private hideDropPlaceholder() {\n if (this.dropPlaceholder) {\n this.dropPlaceholder.remove();\n this.dropPlaceholder = null;\n }\n }\n\n private showInitialPlaceholder() {\n if (!this.downEle || !this.originalElementRect) return;\n\n this.dropPlaceholder = document.createElement('div');\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Copy dimensions from the original element\n const rect = this.originalElementRect;\n this.dropPlaceholder.style.width = rect.width + 'px';\n this.dropPlaceholder.style.height = rect.height + 'px';\n this.dropPlaceholder.style.minHeight = rect.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.border = '2px dashed #d1d5db';\n\n // Insert the placeholder right after the hidden original element\n this.downEle.insertAdjacentElement('afterend', this.dropPlaceholder);\n }\n\n private handleMouseDown(event: MouseEvent) {\n let ele = event.target as HTMLDivElement;\n\n // if we have a drag handle, only allow dragging from that element\n if (this.dragHandle) {\n if (!ele.classList.contains(this.dragHandle)) {\n return;\n }\n }\n\n ele = ele.closest('.sortable');\n if (ele) {\n event.preventDefault();\n event.stopPropagation();\n this.downEle = ele;\n this.draggingId = ele.id;\n this.draggingIdx = this.getRowIndex(ele.id);\n this.draggingEle = ele;\n\n // Use getBoundingClientRect for accurate offsets and store original dimensions\n const rect = ele.getBoundingClientRect();\n this.originalElementRect = rect; // Store the original rect before hiding\n this.xOffset = event.clientX - rect.left;\n this.yOffset = event.clientY - rect.top;\n this.yDown = event.clientY;\n this.xDown = event.clientX;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n }\n\n private handleMouseMove(event: MouseEvent) {\n if (\n !this.ghostElement &&\n this.downEle &&\n (Math.abs(event.clientY - this.yDown) > DRAG_THRESHOLD ||\n Math.abs(event.clientX - this.xDown) > DRAG_THRESHOLD)\n ) {\n this.fireCustomEvent(CustomEventType.DragStart, {\n id: this.downEle.id\n });\n\n // Capture the original index BEFORE hiding the element\n this.originalDragIndex = this.getRowIndex(this.downEle.id);\n\n // Create a clone of the element to use as the ghost\n this.ghostElement = this.cloneElementWithState(\n this.downEle\n ) as HTMLDivElement;\n\n // Hide the original element during dragging using inline styles\n this.originalDownDisplay = this.downEle.style.display;\n this.downEle.style.display = 'none';\n\n // Style the clone as a ghost\n this.ghostElement.classList.add('ghost');\n\n // Use the stored original dimensions for positioning\n const rect = this.originalElementRect;\n\n this.ghostElement.style.position = 'fixed';\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top = event.clientY - this.yOffset + 'px';\n this.ghostElement.style.width = rect.width + 'px';\n this.ghostElement.style.height = rect.height + 'px';\n this.ghostElement.style.zIndex = '99999';\n this.ghostElement.style.opacity = '0.8';\n this.ghostElement.style.transform = 'scale(1.03)';\n\n // allow component to customize the ghost node\n if (this.prepareGhost) {\n this.prepareGhost(this.ghostElement);\n }\n\n // Add the clone to document.body for dragging\n document.body.appendChild(this.ghostElement);\n\n // Show initial placeholder in the original position to maintain layout\n this.showInitialPlaceholder();\n\n // Add global click blocker when drag starts\n if (!this.clickBlocker) {\n this.clickBlocker = (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n };\n // Use capture phase to intercept clicks before they reach any elements\n document.addEventListener('click', this.clickBlocker, true);\n }\n }\n\n if (this.ghostElement) {\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top = event.clientY - this.yOffset + 'px';\n\n // check if the drag is over the container (only if external dragging is allowed)\n const isOverContainer = this.externalDrag\n ? this.isMouseOverContainer(event.clientX, event.clientY)\n : true; // always consider \"over container\" if external drag is disabled\n\n // detect transition between internal and external drag (only if allowed)\n if (this.externalDrag && !isOverContainer && !this.isExternalDrag) {\n // transitioning to external drag\n this.isExternalDrag = true;\n this.hideDropPlaceholder();\n\n // hide the ghost element when dragging externally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'none';\n }\n\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n } else if (this.externalDrag && isOverContainer && this.isExternalDrag) {\n // transitioning back to internal drag\n this.isExternalDrag = false;\n\n // show the ghost element again when dragging internally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'block';\n }\n\n this.fireCustomEvent(CustomEventType.DragInternal, {\n id: this.downEle.id\n });\n }\n\n // only show drop placeholder and calculate drop position if internal drag\n if (!this.isExternalDrag) {\n const targetInfo = this.getDropTargetInfo(event.clientX, event.clientY);\n if (targetInfo) {\n const { element: targetElement, insertAfter } = targetInfo;\n const targetIdx = this.getRowIndex(targetElement.id);\n\n // Use the original drag index we captured before moving the element\n const originalDragIdx = this.originalDragIndex;\n\n // Calculate where the dragged element will end up in the final array\n // targetIdx is the position of target element in current DOM (missing dragged element)\n\n let dropIdx;\n if (targetIdx < originalDragIdx) {\n // Target is before the original drag position - moving backward\n dropIdx = insertAfter ? targetIdx + 1 : targetIdx;\n } else {\n // Target was originally after the drag position - moving forward\n // When moving the dragged element forward (i.e., to a higher index), the targetIdx is based on the current DOM,\n // which no longer includes the dragged element. This means all elements after the original position have shifted left by one,\n // so we need to subtract 1 from targetIdx to get the correct insertion index. If inserting after the target, we use targetIdx as is.\n dropIdx = insertAfter ? targetIdx : targetIdx - 1;\n }\n\n // Store pending drop info but don't fire event yet\n this.dropTargetId = targetElement.id;\n this.pendingDropIndex = dropIdx;\n this.pendingTargetElement = targetElement;\n\n // Show drop placeholder\n this.showDropPlaceholder(targetElement, insertAfter);\n } else {\n this.hideDropPlaceholder();\n this.dropTargetId = null;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n }\n } else {\n // external drag - continue firing external drag events with updated position\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n }\n }\n }\n\n private handleMouseUp(evt: MouseEvent) {\n if (this.draggingId && this.ghostElement) {\n evt.preventDefault();\n evt.stopPropagation();\n\n // Remove the ghost clone from document.body\n if (this.ghostElement) {\n this.ghostElement.remove();\n }\n\n // Restore visibility of the original element by clearing inline styles\n if (this.downEle) {\n this.downEle.style.display = this.originalDownDisplay;\n }\n\n // Clear visual effects before firing events\n this.hideDropPlaceholder();\n\n // fire the order changed event only when dropped if we have a valid drop position\n if (\n !this.isExternalDrag &&\n this.pendingDropIndex >= 0 &&\n this.pendingTargetElement\n ) {\n // Use the original drag index we captured before hiding the element\n const originalDragIdx = this.originalDragIndex;\n\n // use swap-based logic - report which indexes need to be swapped\n const fromIdx = originalDragIdx;\n const toIdx = this.pendingDropIndex;\n\n // only fire if the position actually changed\n if (fromIdx !== toIdx) {\n this.fireCustomEvent(CustomEventType.OrderChanged, {\n swap: [fromIdx, toIdx]\n });\n }\n }\n\n this.fireCustomEvent(CustomEventType.DragStop, {\n id: this.draggingId,\n isExternal: this.isExternalDrag,\n mouseX: evt.clientX,\n mouseY: evt.clientY\n });\n\n this.draggingId = null;\n this.dropTargetId = null;\n this.downEle = null;\n this.originalElementRect = null;\n this.originalDragIndex = -1;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n this.isExternalDrag = false;\n\n // Clear the ghost reference since we removed it\n this.ghostElement = null;\n\n this.hideDropPlaceholder();\n\n // Keep the click blocker active for a short time after drop\n if (this.clickBlocker) {\n // We'll clean it up after a timeout\n setTimeout(() => {\n if (this.clickBlocker) {\n document.removeEventListener('click', this.clickBlocker, true);\n this.clickBlocker = null;\n }\n }, 100);\n }\n }\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.dispatchEvent(new Event('change'));\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=\"container ${this.horizontal ? 'horizontal' : ''}\"\n style=\"gap: ${this.gap}\"\n >\n <slot @mousedown=${this.handleMouseDown}></slot>\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SortableList.js","sourceRoot":"","sources":["../../../src/list/SortableList.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { CustomEventType } from '../interfaces';\nimport { RapidElement } from '../RapidElement';\n\n/**\n * A simple list that can be sorted by dragging\n */\n\n// how far we have to drag before it starts\nconst DRAG_THRESHOLD = 2;\n\n// padding around container for external drag detection\nconst EXTERNAL_DRAG_PADDING = 50;\n\nexport class SortableList extends RapidElement {\n originalDownDisplay: string;\n static get styles() {\n return css`\n :host {\n margin: auto;\n }\n\n .container {\n user-select: none;\n position: relative;\n display: grid;\n grid-template-columns: 1fr;\n }\n\n .container.horizontal {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n }\n\n .dragging {\n background: var(--color-selection);\n }\n\n .slot {\n flex-grow: 1;\n }\n\n slot > * {\n user-select: none;\n }\n\n temba-icon {\n opacity: 0.1;\n padding: 0.2em 0.5em;\n transition: all 300ms ease-in-out;\n }\n `;\n }\n\n @property({ type: String })\n draggingId: string;\n\n @property({ type: Boolean })\n horizontal: boolean = false;\n\n @property({ type: String })\n dropTargetId: string;\n\n @property({ type: String })\n dragHandle: string;\n\n @property({ type: String })\n gap: string = '0em';\n\n @property({ type: Boolean })\n externalDrag: boolean = false;\n\n /**\n * Optional callback to allow parent components to customize the ghost node.\n * Called after the ghost node is cloned but before it is appended to the DOM.\n */\n @property({ attribute: false })\n prepareGhost?: (ghost: HTMLElement) => void;\n\n ghostElement: HTMLDivElement = null;\n downEle: HTMLDivElement = null;\n originalElementRect: DOMRect = null; // Store original dimensions\n originalDragIndex: number = -1; // Store original index before moving element\n xOffset = 0;\n yOffset = 0;\n yDown = 0;\n xDown = 0;\n\n draggingIdx = -1;\n draggingEle = null;\n dropPlaceholder: HTMLDivElement = null;\n pendingDropIndex = -1;\n pendingTargetElement: HTMLElement = null;\n isExternalDrag = false;\n\n private clickBlocker: ((e: MouseEvent) => void) | null = null;\n\n public constructor() {\n super();\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleMouseUp = this.handleMouseUp.bind(this);\n this.handleMouseDown = this.handleMouseDown.bind(this);\n }\n\n private getSortableElements(): Element[] {\n const eles = this.shadowRoot\n .querySelector('slot')\n .assignedElements()\n .filter(\n (ele) =>\n ele.classList.contains('sortable') &&\n !ele.classList.contains('drop-placeholder')\n );\n return eles;\n }\n\n private isMouseOverContainer(mouseX: number, mouseY: number): boolean {\n const container = this.shadowRoot.querySelector('.container');\n if (!container) return false;\n\n const rect = container.getBoundingClientRect();\n // add some padding to make it easier to stay within the container\n return (\n mouseX >= rect.left - EXTERNAL_DRAG_PADDING &&\n mouseX <= rect.right + EXTERNAL_DRAG_PADDING &&\n mouseY >= rect.top - EXTERNAL_DRAG_PADDING &&\n mouseY <= rect.bottom + EXTERNAL_DRAG_PADDING\n );\n }\n\n private cloneElementWithState(element: HTMLElement): HTMLElement {\n // First create a basic clone\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Helper function to copy form element values recursively\n const copyFormValues = (original: HTMLElement, cloned: HTMLElement) => {\n try {\n // Copy input values\n const originalInputs = original.querySelectorAll(\n 'input, textarea, select'\n );\n const clonedInputs = cloned.querySelectorAll('input, textarea, select');\n\n originalInputs.forEach((originalInput, index) => {\n const clonedInput = clonedInputs[index] as\n | HTMLInputElement\n | HTMLTextAreaElement\n | HTMLSelectElement;\n if (clonedInput) {\n if (originalInput instanceof HTMLInputElement) {\n const originalHtmlInput = originalInput as HTMLInputElement;\n const clonedHtmlInput = clonedInput as HTMLInputElement;\n\n if (\n originalHtmlInput.type === 'checkbox' ||\n originalHtmlInput.type === 'radio'\n ) {\n clonedHtmlInput.checked = originalHtmlInput.checked;\n } else {\n clonedHtmlInput.value = originalHtmlInput.value;\n }\n } else if (originalInput instanceof HTMLTextAreaElement) {\n (clonedInput as HTMLTextAreaElement).value = originalInput.value;\n } else if (originalInput instanceof HTMLSelectElement) {\n (clonedInput as HTMLSelectElement).selectedIndex =\n originalInput.selectedIndex;\n }\n }\n });\n\n // Copy properties from all custom elements that might have a value property\n const allOriginalElements = Array.from(original.querySelectorAll('*'));\n const allClonedElements = Array.from(cloned.querySelectorAll('*'));\n\n allOriginalElements.forEach((originalEl, index) => {\n const clonedEl = allClonedElements[index];\n if (clonedEl && originalEl) {\n // Special handling for temba components\n if (\n originalEl.tagName &&\n originalEl.tagName.toLowerCase().startsWith('temba-')\n ) {\n try {\n // Copy common temba component properties\n const tembaProps = [\n 'value',\n 'values',\n 'selectedValue',\n 'checked',\n 'selected',\n 'textContent'\n ];\n tembaProps.forEach((prop) => {\n if (\n prop in originalEl &&\n (originalEl as any)[prop] !== undefined\n ) {\n (clonedEl as any)[prop] = (originalEl as any)[prop];\n }\n });\n\n // Copy all attributes for temba components to preserve state\n Array.from(originalEl.attributes).forEach((attr) => {\n clonedEl.setAttribute(attr.name, attr.value);\n });\n } catch (e) {\n // Ignore errors when copying temba properties\n }\n } else {\n // Try to copy value property for other elements\n try {\n if (\n 'value' in originalEl &&\n (originalEl as any).value !== undefined\n ) {\n (clonedEl as any).value = (originalEl as any).value;\n }\n } catch (e) {\n // Ignore errors when copying properties\n }\n\n // Copy data attributes that might contain state\n try {\n Array.from(originalEl.attributes).forEach((attr) => {\n if (\n attr.name.startsWith('data-') ||\n attr.name.startsWith('aria-')\n ) {\n clonedEl.setAttribute(attr.name, attr.value);\n }\n });\n } catch (e) {\n // Ignore errors when copying attributes\n }\n }\n }\n });\n } catch (e) {\n // If anything fails, just return the basic clone\n console.warn('Failed to copy form values in cloneElementWithState:', e);\n }\n };\n\n // Copy form values for the root element and all descendants\n copyFormValues(element, clone);\n\n return clone;\n }\n\n public getIds() {\n return this.getSortableElements().map((ele) => ele.id);\n }\n\n private getRowIndex(id: string): number {\n return this.getSortableElements().findIndex((ele) => ele.id === id);\n }\n\n private getDropTargetInfo(\n mouseX: number,\n mouseY: number\n ): { element: HTMLDivElement; insertAfter: boolean } | null {\n const elements = this.getSortableElements().filter(\n (ele) => ele.id !== this.draggingEle?.id\n );\n\n if (elements.length === 0) return null;\n\n if (this.horizontal) {\n // For horizontal layout, find the insertion point based on mouse X position\n for (let i = 0; i < elements.length; i++) {\n const ele = elements[i];\n const rect = ele.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n\n if (mouseX < centerX) {\n // Insert before this element\n return { element: ele as HTMLDivElement, insertAfter: false };\n }\n }\n // If we're past all elements, insert after the last one\n return {\n element: elements[elements.length - 1] as HTMLDivElement,\n insertAfter: true\n };\n } else {\n // For vertical layout, find the insertion point based on mouse Y position\n for (let i = 0; i < elements.length; i++) {\n const ele = elements[i];\n const rect = ele.getBoundingClientRect();\n const centerY = rect.top + rect.height / 2;\n\n if (mouseY < centerY) {\n // Insert before this element\n return { element: ele as HTMLDivElement, insertAfter: false };\n }\n }\n // If we're past all elements, insert after the last one\n return {\n element: elements[elements.length - 1] as HTMLDivElement,\n insertAfter: true\n };\n }\n }\n\n private showDropPlaceholder(\n targetElement: HTMLElement,\n insertAfter: boolean\n ) {\n this.hideDropPlaceholder();\n\n if (!targetElement || !this.draggingEle) return;\n\n // Don't show placeholder if we're targeting the dragging element itself\n if (targetElement === this.draggingEle) return;\n\n this.dropPlaceholder = document.createElement('div');\n\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Copy dimensions from the original element (before it was hidden)\n if (this.originalElementRect) {\n const rect = this.originalElementRect;\n this.dropPlaceholder.style.width = rect.width + 'px';\n this.dropPlaceholder.style.height = rect.height + 'px';\n this.dropPlaceholder.style.minHeight = rect.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.border = '2px dashed #d1d5db';\n }\n\n // Insert the placeholder in the correct position in the DOM\n if (insertAfter) {\n targetElement.insertAdjacentElement('afterend', this.dropPlaceholder);\n } else {\n targetElement.insertAdjacentElement('beforebegin', this.dropPlaceholder);\n }\n }\n\n private hideDropPlaceholder() {\n if (this.dropPlaceholder) {\n this.dropPlaceholder.remove();\n this.dropPlaceholder = null;\n }\n }\n\n private showInitialPlaceholder() {\n if (!this.downEle || !this.originalElementRect) return;\n\n this.dropPlaceholder = document.createElement('div');\n this.dropPlaceholder.className = 'drop-placeholder sortable';\n\n // Copy dimensions from the original element\n const rect = this.originalElementRect;\n this.dropPlaceholder.style.width = rect.width + 'px';\n this.dropPlaceholder.style.height = rect.height + 'px';\n this.dropPlaceholder.style.minHeight = rect.height + 'px';\n this.dropPlaceholder.style.borderRadius = 'var(--curvature)';\n this.dropPlaceholder.style.flexShrink = '0';\n this.dropPlaceholder.style.background = '#f3f4f6';\n this.dropPlaceholder.style.border = '2px dashed #d1d5db';\n\n // Insert the placeholder right after the hidden original element\n this.downEle.insertAdjacentElement('afterend', this.dropPlaceholder);\n }\n\n private handleMouseDown(event: MouseEvent) {\n let ele = event.target as HTMLDivElement;\n\n // if we have a drag handle, only allow dragging from that element\n if (this.dragHandle) {\n if (!ele.classList.contains(this.dragHandle)) {\n return;\n }\n }\n\n ele = ele.closest('.sortable');\n if (ele) {\n event.preventDefault();\n event.stopPropagation();\n this.downEle = ele;\n this.draggingId = ele.id;\n this.draggingIdx = this.getRowIndex(ele.id);\n this.draggingEle = ele;\n\n // Use getBoundingClientRect for accurate offsets and store original dimensions\n const rect = ele.getBoundingClientRect();\n this.originalElementRect = rect; // Store the original rect before hiding\n this.xOffset = event.clientX - rect.left;\n this.yOffset = event.clientY - rect.top;\n this.yDown = event.clientY;\n this.xDown = event.clientX;\n\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n }\n\n private handleMouseMove(event: MouseEvent) {\n if (\n !this.ghostElement &&\n this.downEle &&\n (Math.abs(event.clientY - this.yDown) > DRAG_THRESHOLD ||\n Math.abs(event.clientX - this.xDown) > DRAG_THRESHOLD)\n ) {\n this.fireCustomEvent(CustomEventType.DragStart, {\n id: this.downEle.id\n });\n\n // Capture the original index BEFORE hiding the element\n this.originalDragIndex = this.getRowIndex(this.downEle.id);\n\n // Create a clone of the element to use as the ghost\n this.ghostElement = this.cloneElementWithState(\n this.downEle\n ) as HTMLDivElement;\n\n // Hide the original element during dragging using inline styles\n this.originalDownDisplay = this.downEle.style.display;\n this.downEle.style.display = 'none';\n\n // Style the clone as a ghost\n this.ghostElement.classList.add('ghost');\n\n // Use the stored original dimensions for positioning\n const rect = this.originalElementRect;\n\n this.ghostElement.style.position = 'fixed';\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top = event.clientY - this.yOffset + 'px';\n this.ghostElement.style.width = rect.width + 'px';\n this.ghostElement.style.height = rect.height + 'px';\n this.ghostElement.style.zIndex = '99999';\n this.ghostElement.style.opacity = '0.8';\n this.ghostElement.style.transform = 'scale(1.03)';\n\n // allow component to customize the ghost node\n if (this.prepareGhost) {\n this.prepareGhost(this.ghostElement);\n }\n\n // Add the clone to document.body for dragging\n document.body.appendChild(this.ghostElement);\n\n // Show initial placeholder in the original position to maintain layout\n this.showInitialPlaceholder();\n\n // Add global click blocker when drag starts\n if (!this.clickBlocker) {\n this.clickBlocker = (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n };\n // Use capture phase to intercept clicks before they reach any elements\n document.addEventListener('click', this.clickBlocker, true);\n }\n }\n\n if (this.ghostElement) {\n this.ghostElement.style.left = event.clientX - this.xOffset + 'px';\n this.ghostElement.style.top = event.clientY - this.yOffset + 'px';\n\n // check if the drag is over the container (only if external dragging is allowed)\n const isOverContainer = this.externalDrag\n ? this.isMouseOverContainer(event.clientX, event.clientY)\n : true; // always consider \"over container\" if external drag is disabled\n\n // detect transition between internal and external drag (only if allowed)\n if (this.externalDrag && !isOverContainer && !this.isExternalDrag) {\n // transitioning to external drag\n this.isExternalDrag = true;\n this.hideDropPlaceholder();\n\n // hide the ghost element when dragging externally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'none';\n }\n\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n } else if (this.externalDrag && isOverContainer && this.isExternalDrag) {\n // transitioning back to internal drag\n this.isExternalDrag = false;\n\n // show the ghost element again when dragging internally\n if (this.ghostElement) {\n this.ghostElement.style.display = 'block';\n }\n\n this.fireCustomEvent(CustomEventType.DragInternal, {\n id: this.downEle.id\n });\n }\n\n // only show drop placeholder and calculate drop position if internal drag\n if (!this.isExternalDrag) {\n const targetInfo = this.getDropTargetInfo(event.clientX, event.clientY);\n if (targetInfo) {\n const { element: targetElement, insertAfter } = targetInfo;\n const targetIdx = this.getRowIndex(targetElement.id);\n\n // Use the original drag index we captured before moving the element\n const originalDragIdx = this.originalDragIndex;\n\n // Calculate where the dragged element will end up in the final array\n // targetIdx is the position of target element in current DOM (missing dragged element)\n\n let dropIdx;\n if (targetIdx < originalDragIdx) {\n // Target is before the original drag position - moving backward\n dropIdx = insertAfter ? targetIdx + 1 : targetIdx;\n } else {\n // Target was originally after the drag position - moving forward\n // When moving the dragged element forward (i.e., to a higher index), the targetIdx is based on the current DOM,\n // which no longer includes the dragged element. This means all elements after the original position have shifted left by one,\n // so we need to subtract 1 from targetIdx to get the correct insertion index. If inserting after the target, we use targetIdx as is.\n dropIdx = insertAfter ? targetIdx : targetIdx - 1;\n }\n\n // Store pending drop info but don't fire event yet\n this.dropTargetId = targetElement.id;\n this.pendingDropIndex = dropIdx;\n this.pendingTargetElement = targetElement;\n\n // Show drop placeholder\n this.showDropPlaceholder(targetElement, insertAfter);\n } else {\n this.hideDropPlaceholder();\n this.dropTargetId = null;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n }\n } else {\n // external drag - continue firing external drag events with updated position\n this.fireCustomEvent(CustomEventType.DragExternal, {\n id: this.downEle.id,\n mouseX: event.clientX,\n mouseY: event.clientY\n });\n }\n }\n }\n\n private handleMouseUp(evt: MouseEvent) {\n if (this.draggingId && this.ghostElement) {\n evt.preventDefault();\n evt.stopPropagation();\n\n // Remove the ghost clone from document.body\n if (this.ghostElement) {\n this.ghostElement.remove();\n }\n\n // Restore visibility of the original element by clearing inline styles\n if (this.downEle) {\n this.downEle.style.display = this.originalDownDisplay;\n }\n\n // Clear visual effects before firing events\n this.hideDropPlaceholder();\n\n // fire the order changed event only when dropped if we have a valid drop position\n if (\n !this.isExternalDrag &&\n this.pendingDropIndex >= 0 &&\n this.pendingTargetElement\n ) {\n // Use the original drag index we captured before hiding the element\n const originalDragIdx = this.originalDragIndex;\n\n // use swap-based logic - report which indexes need to be swapped\n const fromIdx = originalDragIdx;\n const toIdx = this.pendingDropIndex;\n\n // only fire if the position actually changed AND this is not an external drag\n // External drags are handled by external drop handlers\n if (fromIdx !== toIdx && !this.isExternalDrag) {\n this.fireCustomEvent(CustomEventType.OrderChanged, {\n swap: [fromIdx, toIdx]\n });\n }\n }\n\n this.fireCustomEvent(CustomEventType.DragStop, {\n id: this.draggingId,\n isExternal: this.isExternalDrag,\n mouseX: evt.clientX,\n mouseY: evt.clientY\n });\n\n this.draggingId = null;\n this.dropTargetId = null;\n this.downEle = null;\n this.originalElementRect = null;\n this.originalDragIndex = -1;\n this.pendingDropIndex = -1;\n this.pendingTargetElement = null;\n this.isExternalDrag = false;\n\n // Clear the ghost reference since we removed it\n this.ghostElement = null;\n\n this.hideDropPlaceholder();\n\n // Keep the click blocker active for a short time after drop\n if (this.clickBlocker) {\n // We'll clean it up after a timeout\n setTimeout(() => {\n if (this.clickBlocker) {\n document.removeEventListener('click', this.clickBlocker, true);\n this.clickBlocker = null;\n }\n }, 100);\n }\n }\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.dispatchEvent(new Event('change'));\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=\"container ${this.horizontal ? 'horizontal' : ''}\"\n style=\"gap: ${this.gap}\"\n >\n <slot @mousedown=${this.handleMouseDown}></slot>\n </div>\n `;\n }\n}\n"]}
|
|
@@ -3,7 +3,7 @@ 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, getUrl, oxfordFn, postJSON, postUrl } from '../utils';
|
|
6
|
+
import { fetchResults, generateUUIDv7, getUrl, oxfordFn, 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';
|
|
@@ -427,10 +427,12 @@ export class ContactChat extends ContactStoreElement {
|
|
|
427
427
|
this.showInterrupt = false;
|
|
428
428
|
this.avatar = DEFAULT_AVATAR;
|
|
429
429
|
this.ticket = null;
|
|
430
|
-
this.
|
|
431
|
-
this.
|
|
430
|
+
this.beforeUUID = null; // for scrolling back through history
|
|
431
|
+
this.afterUUID = null; // for polling new messages
|
|
432
432
|
this.refreshId = null;
|
|
433
433
|
this.polling = false;
|
|
434
|
+
this.pollingInterval = 2000; // start at 2 seconds
|
|
435
|
+
this.lastFetchTime = null;
|
|
434
436
|
}
|
|
435
437
|
firstUpdated(changed) {
|
|
436
438
|
super.firstUpdated(changed);
|
|
@@ -469,10 +471,12 @@ export class ContactChat extends ContactStoreElement {
|
|
|
469
471
|
}
|
|
470
472
|
this.blockFetching = false;
|
|
471
473
|
this.ticket = null;
|
|
472
|
-
this.
|
|
473
|
-
this.
|
|
474
|
+
this.beforeUUID = null;
|
|
475
|
+
this.afterUUID = null;
|
|
474
476
|
this.refreshId = null;
|
|
475
477
|
this.polling = false;
|
|
478
|
+
this.pollingInterval = 2000;
|
|
479
|
+
this.lastFetchTime = null;
|
|
476
480
|
this.errorMessage = null;
|
|
477
481
|
const compose = this.shadowRoot.querySelector('temba-compose');
|
|
478
482
|
if (compose) {
|
|
@@ -513,6 +517,8 @@ export class ContactChat extends ContactStoreElement {
|
|
|
513
517
|
if (response.status < 400) {
|
|
514
518
|
const msg = this.createChatForMessageEvent(response.json.event);
|
|
515
519
|
this.chat.addMessages([msg], null, true);
|
|
520
|
+
// reset polling interval to 2 seconds after sending a message
|
|
521
|
+
this.pollingInterval = 2000;
|
|
516
522
|
this.checkForNewMessages();
|
|
517
523
|
composeEle.reset();
|
|
518
524
|
this.fireCustomEvent(CustomEventType.MessageSent, {
|
|
@@ -530,25 +536,26 @@ export class ContactChat extends ContactStoreElement {
|
|
|
530
536
|
}
|
|
531
537
|
getEndpoint() {
|
|
532
538
|
if (this.contact) {
|
|
533
|
-
return `/contact/
|
|
539
|
+
return `/contact/chat/${this.contact}/`;
|
|
534
540
|
}
|
|
535
541
|
return null;
|
|
536
542
|
}
|
|
537
|
-
scheduleRefresh() {
|
|
538
|
-
// knock five seconds off the newest event time so we are
|
|
539
|
-
// a little more aggressive about refreshing short term
|
|
540
|
-
let window = new Date().getTime() - this.newestEventTime / 1000 - 5000;
|
|
543
|
+
scheduleRefresh(hasNewEvents = false) {
|
|
541
544
|
if (this.refreshId) {
|
|
542
545
|
clearTimeout(this.refreshId);
|
|
543
546
|
this.refreshId = null;
|
|
544
547
|
}
|
|
545
|
-
//
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
548
|
+
// reset to 2 seconds if we received new events
|
|
549
|
+
if (hasNewEvents) {
|
|
550
|
+
this.pollingInterval = 2000;
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
// increase interval by 1 second up to max of 15 seconds
|
|
554
|
+
this.pollingInterval = Math.min(this.pollingInterval + 1000, 15000);
|
|
555
|
+
}
|
|
549
556
|
this.refreshId = setTimeout(() => {
|
|
550
557
|
this.checkForNewMessages();
|
|
551
|
-
},
|
|
558
|
+
}, this.pollingInterval);
|
|
552
559
|
}
|
|
553
560
|
getEventMessage(event) {
|
|
554
561
|
let message = null;
|
|
@@ -721,9 +728,10 @@ export class ContactChat extends ContactStoreElement {
|
|
|
721
728
|
if (page.events) {
|
|
722
729
|
let messages = [];
|
|
723
730
|
page.events.forEach((event) => {
|
|
724
|
-
|
|
725
|
-
if (
|
|
726
|
-
this.
|
|
731
|
+
// track the UUID of the newest event for polling
|
|
732
|
+
if (!this.afterUUID ||
|
|
733
|
+
event.uuid.toLowerCase() > this.afterUUID.toLowerCase()) {
|
|
734
|
+
this.afterUUID = event.uuid;
|
|
727
735
|
}
|
|
728
736
|
if (event.type === 'ticket_note_added') {
|
|
729
737
|
const ticketEvent = event;
|
|
@@ -775,25 +783,29 @@ export class ContactChat extends ContactStoreElement {
|
|
|
775
783
|
}
|
|
776
784
|
const chat = this.chat;
|
|
777
785
|
const contactChat = this;
|
|
778
|
-
if (this.currentContact && this.
|
|
786
|
+
if (this.currentContact && this.afterUUID) {
|
|
779
787
|
this.polling = true;
|
|
788
|
+
this.lastFetchTime = Date.now();
|
|
780
789
|
const endpoint = this.getEndpoint();
|
|
781
790
|
if (!endpoint) {
|
|
782
791
|
return;
|
|
783
792
|
}
|
|
784
793
|
const fetchContact = this.currentContact.uuid;
|
|
785
|
-
fetchContactHistory(
|
|
794
|
+
fetchContactHistory(endpoint, (_a = this.currentTicket) === null || _a === void 0 ? void 0 : _a.uuid, null, this.afterUUID).then((page) => {
|
|
786
795
|
if (fetchContact === this.currentContact.uuid) {
|
|
787
|
-
this.lastEventTime = page.next_before;
|
|
788
796
|
const messages = this.createMessages(page);
|
|
797
|
+
const hasNewEvents = messages.length > 0;
|
|
789
798
|
if (messages.length === 0) {
|
|
790
799
|
contactChat.blockFetching = true;
|
|
791
800
|
}
|
|
792
801
|
messages.reverse();
|
|
793
802
|
chat.addMessages(messages, null, true);
|
|
803
|
+
this.polling = false;
|
|
804
|
+
this.scheduleRefresh(hasNewEvents);
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
this.polling = false;
|
|
794
808
|
}
|
|
795
|
-
this.polling = false;
|
|
796
|
-
this.scheduleRefresh();
|
|
797
809
|
});
|
|
798
810
|
}
|
|
799
811
|
}
|
|
@@ -810,13 +822,31 @@ export class ContactChat extends ContactStoreElement {
|
|
|
810
822
|
if (!endpoint) {
|
|
811
823
|
return;
|
|
812
824
|
}
|
|
813
|
-
|
|
814
|
-
|
|
825
|
+
// initialize anchor UUID if not set (first fetch)
|
|
826
|
+
if (!this.beforeUUID && !this.afterUUID) {
|
|
827
|
+
// generate a UUID v7 for current time as the anchor
|
|
828
|
+
const anchorUUID = generateUUIDv7();
|
|
829
|
+
this.beforeUUID = anchorUUID;
|
|
830
|
+
this.afterUUID = anchorUUID;
|
|
831
|
+
}
|
|
832
|
+
fetchContactHistory(endpoint, (_a = this.currentTicket) === null || _a === void 0 ? void 0 : _a.uuid, this.beforeUUID, null).then((page) => {
|
|
815
833
|
const messages = this.createMessages(page);
|
|
816
834
|
messages.reverse();
|
|
817
835
|
if (messages.length === 0) {
|
|
818
836
|
contactChat.blockFetching = true;
|
|
819
837
|
}
|
|
838
|
+
else if (page.next) {
|
|
839
|
+
// update beforeUUID for next fetch of older messages
|
|
840
|
+
this.beforeUUID = page.next;
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
// no more history, mark end and show oldest event date
|
|
844
|
+
contactChat.blockFetching = true;
|
|
845
|
+
if (page.events && page.events.length > 0) {
|
|
846
|
+
const oldestEvent = page.events[page.events.length - 1];
|
|
847
|
+
chat.setEndOfHistory(new Date(oldestEvent.created_on));
|
|
848
|
+
}
|
|
849
|
+
}
|
|
820
850
|
chat.addMessages(messages);
|
|
821
851
|
this.scheduleRefresh();
|
|
822
852
|
});
|
|
@@ -1099,25 +1129,23 @@ export const fetchContact = (endpoint) => {
|
|
|
1099
1129
|
});
|
|
1100
1130
|
});
|
|
1101
1131
|
};
|
|
1102
|
-
export const fetchContactHistory = (
|
|
1103
|
-
if (reset) {
|
|
1104
|
-
pendingRequests.forEach((controller) => {
|
|
1105
|
-
controller.abort();
|
|
1106
|
-
});
|
|
1107
|
-
pendingRequests = [];
|
|
1108
|
-
}
|
|
1132
|
+
export const fetchContactHistory = (endpoint, ticket = undefined, before = undefined, after = undefined) => {
|
|
1109
1133
|
return new Promise((resolve) => {
|
|
1110
1134
|
const controller = new AbortController();
|
|
1111
1135
|
pendingRequests.push(controller);
|
|
1112
1136
|
let url = endpoint;
|
|
1137
|
+
const params = [];
|
|
1113
1138
|
if (before) {
|
|
1114
|
-
|
|
1139
|
+
params.push(`before=${before}`);
|
|
1115
1140
|
}
|
|
1116
1141
|
if (after) {
|
|
1117
|
-
|
|
1142
|
+
params.push(`after=${after}`);
|
|
1118
1143
|
}
|
|
1119
1144
|
if (ticket) {
|
|
1120
|
-
|
|
1145
|
+
params.push(`ticket=${ticket}`);
|
|
1146
|
+
}
|
|
1147
|
+
if (params.length > 0) {
|
|
1148
|
+
url += (url.includes('?') ? '&' : '?') + params.join('&');
|
|
1121
1149
|
}
|
|
1122
1150
|
const store = document.querySelector('temba-store');
|
|
1123
1151
|
getUrl(url, controller)
|