@nyaruka/temba-components 0.125.0 → 0.126.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.
@@ -1 +1 @@
1
- {"version":3,"file":"EditorNode.js","sourceRoot":"","sources":["../../../src/flow/EditorNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { EDITOR_CONFIG, UIConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { state } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\n\nexport class EditorNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @state()\n private plumber: Plumber;\n\n @state()\n private node: Node;\n\n @state()\n private ui: NodeUI;\n\n static get styles() {\n return css`\n .node {\n position: absolute;\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: calc(var(--curvature) * 1.5);\n overflow: hidden;\n color: #333;\n }\n \n .action {\n max-width: 200px;\n }\n\n .action .body {\n padding: 1em;\n }\n\n .action .title,\n .router .title {\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n }\n\n .action-exits {\n padding-bottom: 0.75em;\n margin-top: -0.75em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit {\n padding-top: 10px;\n margin-bottom: -10px;\n }\n }`;\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n this.plumber.makeTarget(this.node.uuid);\n\n // our node was changed, see if we have new destinations\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(exit.uuid, exit.destination_uuid);\n }\n }\n\n const ele = this.querySelector('.node');\n const rect = ele.getBoundingClientRect();\n\n getStore()\n .getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n }\n }\n\n private renderTitle(config: UIConfig) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${config.name}\n </div>`;\n }\n\n private renderAction(node: Node, action: Action) {\n const config = EDITOR_CONFIG[action.type];\n\n if (config) {\n return html`<div class=\"action ${action.type}\">\n ${this.renderTitle(config)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>`;\n }\n return html`<div>${action.type}</div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const config = EDITOR_CONFIG[ui.type];\n if (config) {\n return html`<div class=\"router\">\n ${this.renderTitle(config)}\n ${router.result_name\n ? html`<div class=\"body\">\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n const categories = node.router.categories.map((category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div class=\"category\">\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n });\n\n return html`<div class=\"categories\">${categories}</div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid\n })}\n ></div>`;\n }\n\n public render() {\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${this.node.actions.map((actionSpec) => {\n return this.renderAction(this.node, actionSpec);\n })}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${this.node.exits.map((exit) => {\n return this.renderExit(exit);\n })}\n </div>`}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"EditorNode.js","sourceRoot":"","sources":["../../../src/flow/EditorNode.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { EDITOR_CONFIG, UIConfig } from './config';\nimport { Action, Exit, Node, NodeUI, Router } from '../store/flow-definition';\nimport { property } from 'lit/decorators.js';\nimport { RapidElement } from '../RapidElement';\nimport { getClasses } from '../utils';\nimport { Plumber } from './Plumber';\nimport { getStore } from '../store/Store';\n\nexport class EditorNode extends RapidElement {\n createRenderRoot() {\n return this;\n }\n\n @property({ type: Object })\n private plumber: Plumber;\n\n @property({ type: Object })\n private node: Node;\n\n @property({ type: Object })\n private ui: NodeUI;\n\n // Drag state properties\n private isDragging = false;\n private dragStartPos = { x: 0, y: 0 };\n private nodeStartPos = { left: 0, top: 0 };\n\n // Bound event handlers to maintain proper 'this' context\n private boundMouseMove = this.handleMouseMove.bind(this);\n private boundMouseUp = this.handleMouseUp.bind(this);\n\n /**\n * Snaps a coordinate value to the nearest 20px grid position\n */\n private snapToGrid(value: number): number {\n return Math.round(value / 20) * 20;\n }\n\n static get styles() {\n return css`\n .node {\n position: absolute;\n background-color: #fff;\n box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\n min-width: 200px;\n border-radius: calc(var(--curvature) * 1.5);\n overflow: hidden;\n color: #333;\n cursor: move;\n user-select: none;\n z-index: 500;\n }\n\n .node:hover {\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);\n }\n\n .node.dragging {\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);\n transform: scale(1.02);\n z-index: 1000;\n }\n \n .action {\n max-width: 200px;\n }\n\n .action .body {\n padding: 1em;\n }\n\n .action .title,\n .router .title {\n color: #fff;\n padding: 5px 1px;\n text-align: center;\n font-size: 1em;\n font-weight: normal;\n }\n\n .quick-replies {\n margin-top: 0.5em;\n }\n\n .quick-reply {\n background-color: #f0f0f0;\n border: 1px solid #e0e0e0;\n border-radius: calc(var(--curvature) * 1.5);\n padding: 0.2em 1em;\n display: inline-block;\n font-size: 0.8em;\n margin: 0.2em;\n }\n\n .categories {\n display: flex;\n flex-direction: row;\n\n }\n\n .category {\n margin:-1px -0.5px;\n border: 1px solid #f3f3f3;\n padding: 0.75em;\n flex-grow:1;\n text-align: center;\n }\n\n .action-exits {\n padding-bottom: 0.75em;\n margin-top: -0.75em;\n }\n\n .category .title {\n font-weight: normal;\n font-size: 1em;\n }\n\n .router .body {\n padding: 0.75em;\n }\n\n .result-name {\n font-weight: bold;\n display: inline-block;\n }\n \n .exit {\n padding-top: 10px;\n margin-bottom: -10px;\n }\n }`;\n }\n\n protected updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('node')) {\n this.plumber.makeTarget(this.node.uuid);\n\n // our node was changed, see if we have new destinations\n for (const exit of this.node.exits) {\n if (!exit.destination_uuid) {\n this.plumber.makeSource(exit.uuid);\n } else {\n this.plumber.connectIds(exit.uuid, exit.destination_uuid);\n }\n }\n\n const ele = this.querySelector('.node');\n const rect = ele.getBoundingClientRect();\n\n getStore()\n .getState()\n .expandCanvas(\n this.ui.position.left + rect.width,\n this.ui.position.top + rect.height\n );\n\n // Add drag event listeners to the node\n this.addDragEventListeners();\n }\n }\n\n private addDragEventListeners(): void {\n const nodeElement = this.querySelector('.node') as HTMLElement;\n if (!nodeElement) return;\n\n nodeElement.addEventListener('mousedown', this.handleMouseDown.bind(this));\n document.addEventListener('mousemove', this.boundMouseMove);\n document.addEventListener('mouseup', this.boundMouseUp);\n }\n\n private handleMouseDown(event: MouseEvent): void {\n // Only start dragging if clicking on the node itself, not on exits or other interactive elements\n const target = event.target as HTMLElement;\n if (target.classList.contains('exit') || target.closest('.exit')) {\n return;\n }\n\n this.isDragging = true;\n this.dragStartPos = { x: event.clientX, y: event.clientY };\n this.nodeStartPos = {\n left: this.ui.position.left,\n top: this.ui.position.top\n };\n\n // Add dragging class for visual feedback\n const nodeElement = this.querySelector('.node') as HTMLElement;\n if (nodeElement) {\n nodeElement.classList.add('dragging');\n }\n\n // Elevate connections for this node during dragging\n if (this.plumber) {\n this.plumber.elevateNodeConnections(this.node.uuid);\n }\n\n event.preventDefault();\n event.stopPropagation();\n }\n\n private handleMouseMove(event: MouseEvent): void {\n if (!this.isDragging) return;\n\n const deltaX = event.clientX - this.dragStartPos.x;\n const deltaY = event.clientY - this.dragStartPos.y;\n\n const newLeft = this.nodeStartPos.left + deltaX;\n const newTop = this.nodeStartPos.top + deltaY;\n\n // Snap to 20px grid\n const snappedLeft = this.snapToGrid(newLeft);\n const snappedTop = this.snapToGrid(newTop);\n\n // Update the UI position temporarily (for visual feedback)\n const nodeElement = this.querySelector('.node') as HTMLElement;\n if (nodeElement) {\n nodeElement.style.left = `${snappedLeft}px`;\n nodeElement.style.top = `${snappedTop}px`;\n }\n\n // Repaint connections during dragging for smooth updates\n if (this.plumber) {\n this.plumber.repaintEverything();\n }\n }\n\n private handleMouseUp(event: MouseEvent): void {\n if (!this.isDragging) return;\n\n this.isDragging = false;\n\n // Remove dragging class\n const nodeElement = this.querySelector('.node') as HTMLElement;\n if (nodeElement) {\n nodeElement.classList.remove('dragging');\n }\n\n // Restore normal z-index for connections\n if (this.plumber) {\n this.plumber.restoreNodeConnections(this.node.uuid);\n }\n\n const deltaX = event.clientX - this.dragStartPos.x;\n const deltaY = event.clientY - this.dragStartPos.y;\n\n const newLeft = this.nodeStartPos.left + deltaX;\n const newTop = this.nodeStartPos.top + deltaY;\n\n // Snap to 20px grid for final position\n const snappedLeft = this.snapToGrid(newLeft);\n const snappedTop = this.snapToGrid(newTop);\n\n // Update the store with the new snapped position\n const newPosition = { left: snappedLeft, top: snappedTop };\n getStore()\n .getState()\n .updateCanvasPositions({\n [this.node.uuid]: newPosition\n });\n\n // Repaint connections if plumber is available\n if (this.plumber) {\n this.plumber.repaintEverything();\n }\n\n getStore().getState().updateNodePosition(this.node.uuid, newPosition);\n\n // Fire a custom event with the new coordinates\n /*this.fireCustomEvent(CustomEventType.Moved, {\n nodeId: this.node.uuid,\n position: newPosition,\n oldPosition: {\n left: this.nodeStartPos.left,\n top: this.nodeStartPos.top\n }\n });*/\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n // Clean up event listeners\n document.removeEventListener('mousemove', this.boundMouseMove);\n document.removeEventListener('mouseup', this.boundMouseUp);\n }\n\n private renderTitle(config: UIConfig) {\n return html`<div class=\"title\" style=\"background:${config.color}\">\n ${config.name}\n </div>`;\n }\n\n private renderAction(node: Node, action: Action) {\n const config = EDITOR_CONFIG[action.type];\n\n if (config) {\n return html`<div class=\"action ${action.type}\">\n ${this.renderTitle(config)}\n <div class=\"body\">\n ${config.render\n ? config.render(node, action)\n : html`<pre>${action.type}</pre>`}\n </div>\n </div>`;\n }\n return html`<div>${action.type}</div>`;\n }\n\n private renderRouter(router: Router, ui: NodeUI) {\n const config = EDITOR_CONFIG[ui.type];\n if (config) {\n return html`<div class=\"router\">\n ${this.renderTitle(config)}\n ${router.result_name\n ? html`<div class=\"body\">\n Save as\n <div class=\"result-name\">${router.result_name}</div>\n </div>`\n : null}\n </div>`;\n }\n }\n\n private renderCategories(node: Node) {\n if (!node.router || !node.router.categories) {\n return null;\n }\n const categories = node.router.categories.map((category) => {\n const exit = node.exits.find(\n (exit: Exit) => exit.uuid == category.exit_uuid\n );\n\n return html`<div class=\"category\">\n <div class=\"title\">${category.name}</div>\n ${this.renderExit(exit)}\n </div>`;\n });\n\n return html`<div class=\"categories\">${categories}</div>`;\n }\n\n private renderExit(exit: Exit): TemplateResult {\n return html`<div\n id=\"${exit.uuid}\"\n class=${getClasses({\n exit: true,\n connected: !!exit.destination_uuid\n })}\n ></div>`;\n }\n\n public render() {\n if (!this.node || !this.ui) {\n return html`<div class=\"node\">Loading...</div>`;\n }\n\n return html`\n <div\n id=\"${this.node.uuid}\"\n class=\"node\"\n style=\"left:${this.ui.position.left}px;top:${this.ui.position.top}px\"\n >\n ${this.node.actions.map((actionSpec) => {\n return this.renderAction(this.node, actionSpec);\n })}\n ${this.node.router\n ? html` ${this.renderRouter(this.node.router, this.ui)}\n ${this.renderCategories(this.node)}`\n : html`<div class=\"action-exits\">\n ${this.node.exits.map((exit) => {\n return this.renderExit(exit);\n })}\n </div>`}\n </div>\n `;\n }\n}\n"]}
@@ -115,5 +115,62 @@ export class Plumber {
115
115
  this.pendingConnections.push({ fromId, toId });
116
116
  this.processPendingConnections();
117
117
  }
118
+ repaintEverything() {
119
+ if (this.jsPlumb) {
120
+ this.jsPlumb.repaintEverything();
121
+ }
122
+ }
123
+ elevateNodeConnections(nodeId) {
124
+ if (!this.jsPlumb)
125
+ return;
126
+ // Get all connections
127
+ const connections = this.jsPlumb.getConnections();
128
+ // Get the node element to find its exit elements
129
+ const nodeElement = document.getElementById(nodeId);
130
+ const exitElements = nodeElement
131
+ ? nodeElement.querySelectorAll('.exit')
132
+ : [];
133
+ const exitIds = Array.from(exitElements).map((exit) => exit.id);
134
+ connections.forEach((connection) => {
135
+ const sourceId = connection.source.id;
136
+ const targetId = connection.target.id;
137
+ // Check if this connection involves the dragged node:
138
+ // - Incoming: target is the node itself
139
+ // - Outgoing: source is one of the node's exits
140
+ if (targetId === nodeId || exitIds.includes(sourceId)) {
141
+ // Add elevated class to the connector element
142
+ const connectorElement = connection.connector.canvas;
143
+ if (connectorElement) {
144
+ connectorElement.classList.add('elevated');
145
+ }
146
+ }
147
+ });
148
+ }
149
+ restoreNodeConnections(nodeId) {
150
+ if (!this.jsPlumb)
151
+ return;
152
+ // Get all connections
153
+ const connections = this.jsPlumb.getConnections();
154
+ // Get the node element to find its exit elements
155
+ const nodeElement = document.getElementById(nodeId);
156
+ const exitElements = nodeElement
157
+ ? nodeElement.querySelectorAll('.exit')
158
+ : [];
159
+ const exitIds = Array.from(exitElements).map((exit) => exit.id);
160
+ connections.forEach((connection) => {
161
+ const sourceId = connection.source.id;
162
+ const targetId = connection.target.id;
163
+ // Check if this connection involves the node:
164
+ // - Incoming: target is the node itself
165
+ // - Outgoing: source is one of the node's exits
166
+ if (targetId === nodeId || exitIds.includes(sourceId)) {
167
+ // Remove elevated class from the connector element
168
+ const connectorElement = connection.connector.canvas;
169
+ if (connectorElement) {
170
+ connectorElement.classList.remove('elevated');
171
+ }
172
+ }
173
+ });
174
+ }
118
175
  }
119
176
  //# sourceMappingURL=Plumber.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DotEndpoint,\n FlowchartConnector,\n newInstance,\n ready,\n RectangleEndpoint\n} from '@jsplumb/browser-ui';\n\nexport const SOURCE_DEFAULTS = {\n endpoint: {\n type: DotEndpoint.type,\n options: {\n radius: 6,\n connectedClass: 'plumb-connected',\n cssClass: 'plumb-source',\n hoverClass: 'plumb-source-hover'\n }\n },\n anchors: ['Bottom', 'Continuous'],\n maxConnections: 1,\n dragAllowedWhenFull: false,\n deleteEndpointsOnEmpty: true,\n isSource: true\n};\n\nexport const TARGET_DEFAULTS = {\n endpoint: {\n type: RectangleEndpoint.type,\n options: {\n width: 23,\n height: 23,\n cssClass: 'plumb-target',\n hoverClass: 'plumb-target-hover'\n }\n },\n anchor: {\n type: 'Continuous',\n options: {\n faces: ['top', 'left', 'right'],\n cssClass: 'continuos plumb-target-anchor'\n }\n },\n dragAllowedWhenFull: false,\n deleteEndpointsOnEmpty: true,\n isTarget: true\n};\n\nexport class Plumber {\n private jsPlumb = null;\n private pendingConnections = [];\n\n constructor(canvas: HTMLElement) {\n ready(() => {\n this.jsPlumb = newInstance({\n container: canvas\n });\n });\n }\n\n public makeTarget(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);\n }\n\n public makeSource(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);\n }\n\n private connectionWait = null;\n\n // we'll process our pending connections, but we want to debounce this\n public processPendingConnections() {\n // if we have a pending connection wait, clear it\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n\n // debounce the connection processing\n this.connectionWait = setTimeout(() => {\n this.jsPlumb.batch(() => {\n this.pendingConnections.forEach((connection) => {\n const { fromId, toId } = connection;\n const fromElement = document.getElementById(fromId);\n const toElement = document.getElementById(toId);\n\n const source = this.jsPlumb.addEndpoint(fromElement, {\n ...SOURCE_DEFAULTS,\n endpoint: {\n ...SOURCE_DEFAULTS.endpoint,\n options: {\n ...SOURCE_DEFAULTS.endpoint.options,\n cssClass: 'plumb-source connected'\n }\n }\n });\n const target = this.jsPlumb.addEndpoint(toElement, TARGET_DEFAULTS);\n this.jsPlumb.connect({\n source,\n target,\n connector: {\n type: FlowchartConnector.type,\n options: {\n stub: 12,\n midpoint: 0.75,\n alwaysRespectStubs: false,\n gap: [0, 5],\n cornerRadius: 3,\n cssClass: 'plumb-connector'\n }\n },\n overlays: [\n {\n type: 'PlainArrow',\n options: {\n width: 13,\n length: 13,\n location: 0.999,\n cssClass: 'plumb-arrow'\n }\n }\n ]\n });\n });\n this.pendingConnections = [];\n });\n }, 50);\n }\n\n public connectIds(fromId: string, toId: string) {\n this.pendingConnections.push({ fromId, toId });\n this.processPendingConnections();\n }\n}\n"]}
1
+ {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE;QACR,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,OAAO,EAAE;YACP,MAAM,EAAE,CAAC;YACT,cAAc,EAAE,iBAAiB;YACjC,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,oBAAoB;SACjC;KACF;IACD,OAAO,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;IACjC,cAAc,EAAE,CAAC;IACjB,mBAAmB,EAAE,KAAK;IAC1B,sBAAsB,EAAE,IAAI;IAC5B,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE;QACR,IAAI,EAAE,iBAAiB,CAAC,IAAI;QAC5B,OAAO,EAAE;YACP,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,oBAAoB;SACjC;KACF;IACD,MAAM,EAAE;QACN,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE;YACP,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC;YAC/B,QAAQ,EAAE,+BAA+B;SAC1C;KACF;IACD,mBAAmB,EAAE,KAAK;IAC1B,sBAAsB,EAAE,IAAI;IAC5B,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF,MAAM,OAAO,OAAO;IAIlB,YAAY,MAAmB;QAHvB,YAAO,GAAG,IAAI,CAAC;QACf,uBAAkB,GAAG,EAAE,CAAC;QAoBxB,mBAAc,GAAG,IAAI,CAAC;QAjB5B,KAAK,CAAC,GAAG,EAAE;YACT,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;gBACzB,SAAS,EAAE,MAAM;aAClB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,UAAU,CAAC,IAAY;QAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACrD,CAAC;IAEM,UAAU,CAAC,IAAY;QAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACrD,CAAC;IAID,sEAAsE;IAC/D,yBAAyB;QAC9B,iDAAiD;QACjD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACtB,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;oBAC7C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC;oBACpC,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;oBACpD,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;oBAEhD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE;wBACnD,GAAG,eAAe;wBAClB,QAAQ,EAAE;4BACR,GAAG,eAAe,CAAC,QAAQ;4BAC3B,OAAO,EAAE;gCACP,GAAG,eAAe,CAAC,QAAQ,CAAC,OAAO;gCACnC,QAAQ,EAAE,wBAAwB;6BACnC;yBACF;qBACF,CAAC,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;oBACpE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;wBACnB,MAAM;wBACN,MAAM;wBACN,SAAS,EAAE;4BACT,IAAI,EAAE,kBAAkB,CAAC,IAAI;4BAC7B,OAAO,EAAE;gCACP,IAAI,EAAE,EAAE;gCACR,QAAQ,EAAE,IAAI;gCACd,kBAAkB,EAAE,KAAK;gCACzB,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;gCACX,YAAY,EAAE,CAAC;gCACf,QAAQ,EAAE,iBAAiB;6BAC5B;yBACF;wBACD,QAAQ,EAAE;4BACR;gCACE,IAAI,EAAE,YAAY;gCAClB,OAAO,EAAE;oCACP,KAAK,EAAE,EAAE;oCACT,MAAM,EAAE,EAAE;oCACV,QAAQ,EAAE,KAAK;oCACf,QAAQ,EAAE,aAAa;iCACxB;6BACF;yBACF;qBACF,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAEM,UAAU,CAAC,MAAc,EAAE,IAAY;QAC5C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,yBAAyB,EAAE,CAAC;IACnC,CAAC;IAEM,iBAAiB;QACtB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IACM,sBAAsB,CAAC,MAAc;QAC1C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAE1B,sBAAsB;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAElD,iDAAiD;QACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,WAAW;YAC9B,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACvC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEhE,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAEtC,sDAAsD;YACtD,wCAAwC;YACxC,gDAAgD;YAChD,IAAI,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtD,8CAA8C;gBAC9C,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC;gBACrD,IAAI,gBAAgB,EAAE,CAAC;oBACrB,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,sBAAsB,CAAC,MAAc;QAC1C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAE1B,sBAAsB;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAElD,iDAAiD;QACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,WAAW;YAC9B,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACvC,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEhE,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAEtC,8CAA8C;YAC9C,wCAAwC;YACxC,gDAAgD;YAChD,IAAI,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtD,mDAAmD;gBACnD,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC;gBACrD,IAAI,gBAAgB,EAAE,CAAC;oBACrB,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import {\n DotEndpoint,\n FlowchartConnector,\n newInstance,\n ready,\n RectangleEndpoint\n} from '@jsplumb/browser-ui';\n\nexport const SOURCE_DEFAULTS = {\n endpoint: {\n type: DotEndpoint.type,\n options: {\n radius: 6,\n connectedClass: 'plumb-connected',\n cssClass: 'plumb-source',\n hoverClass: 'plumb-source-hover'\n }\n },\n anchors: ['Bottom', 'Continuous'],\n maxConnections: 1,\n dragAllowedWhenFull: false,\n deleteEndpointsOnEmpty: true,\n isSource: true\n};\n\nexport const TARGET_DEFAULTS = {\n endpoint: {\n type: RectangleEndpoint.type,\n options: {\n width: 23,\n height: 23,\n cssClass: 'plumb-target',\n hoverClass: 'plumb-target-hover'\n }\n },\n anchor: {\n type: 'Continuous',\n options: {\n faces: ['top', 'left', 'right'],\n cssClass: 'continuos plumb-target-anchor'\n }\n },\n dragAllowedWhenFull: false,\n deleteEndpointsOnEmpty: true,\n isTarget: true\n};\n\nexport class Plumber {\n private jsPlumb = null;\n private pendingConnections = [];\n\n constructor(canvas: HTMLElement) {\n ready(() => {\n this.jsPlumb = newInstance({\n container: canvas\n });\n });\n }\n\n public makeTarget(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);\n }\n\n public makeSource(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);\n }\n\n private connectionWait = null;\n\n // we'll process our pending connections, but we want to debounce this\n public processPendingConnections() {\n // if we have a pending connection wait, clear it\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n\n // debounce the connection processing\n this.connectionWait = setTimeout(() => {\n this.jsPlumb.batch(() => {\n this.pendingConnections.forEach((connection) => {\n const { fromId, toId } = connection;\n const fromElement = document.getElementById(fromId);\n const toElement = document.getElementById(toId);\n\n const source = this.jsPlumb.addEndpoint(fromElement, {\n ...SOURCE_DEFAULTS,\n endpoint: {\n ...SOURCE_DEFAULTS.endpoint,\n options: {\n ...SOURCE_DEFAULTS.endpoint.options,\n cssClass: 'plumb-source connected'\n }\n }\n });\n const target = this.jsPlumb.addEndpoint(toElement, TARGET_DEFAULTS);\n this.jsPlumb.connect({\n source,\n target,\n connector: {\n type: FlowchartConnector.type,\n options: {\n stub: 12,\n midpoint: 0.75,\n alwaysRespectStubs: false,\n gap: [0, 5],\n cornerRadius: 3,\n cssClass: 'plumb-connector'\n }\n },\n overlays: [\n {\n type: 'PlainArrow',\n options: {\n width: 13,\n length: 13,\n location: 0.999,\n cssClass: 'plumb-arrow'\n }\n }\n ]\n });\n });\n this.pendingConnections = [];\n });\n }, 50);\n }\n\n public connectIds(fromId: string, toId: string) {\n this.pendingConnections.push({ fromId, toId });\n this.processPendingConnections();\n }\n\n public repaintEverything() {\n if (this.jsPlumb) {\n this.jsPlumb.repaintEverything();\n }\n }\n public elevateNodeConnections(nodeId: string) {\n if (!this.jsPlumb) return;\n\n // Get all connections\n const connections = this.jsPlumb.getConnections();\n\n // Get the node element to find its exit elements\n const nodeElement = document.getElementById(nodeId);\n const exitElements = nodeElement\n ? nodeElement.querySelectorAll('.exit')\n : [];\n const exitIds = Array.from(exitElements).map((exit) => exit.id);\n\n connections.forEach((connection) => {\n const sourceId = connection.source.id;\n const targetId = connection.target.id;\n\n // Check if this connection involves the dragged node:\n // - Incoming: target is the node itself\n // - Outgoing: source is one of the node's exits\n if (targetId === nodeId || exitIds.includes(sourceId)) {\n // Add elevated class to the connector element\n const connectorElement = connection.connector.canvas;\n if (connectorElement) {\n connectorElement.classList.add('elevated');\n }\n }\n });\n }\n\n public restoreNodeConnections(nodeId: string) {\n if (!this.jsPlumb) return;\n\n // Get all connections\n const connections = this.jsPlumb.getConnections();\n\n // Get the node element to find its exit elements\n const nodeElement = document.getElementById(nodeId);\n const exitElements = nodeElement\n ? nodeElement.querySelectorAll('.exit')\n : [];\n const exitIds = Array.from(exitElements).map((exit) => exit.id);\n\n connections.forEach((connection) => {\n const sourceId = connection.source.id;\n const targetId = connection.target.id;\n\n // Check if this connection involves the node:\n // - Incoming: target is the node itself\n // - Outgoing: source is one of the node's exits\n if (targetId === nodeId || exitIds.includes(sourceId)) {\n // Remove elevated class from the connector element\n const connectorElement = connection.connector.canvas;\n if (connectorElement) {\n connectorElement.classList.remove('elevated');\n }\n }\n });\n }\n}\n"]}
@@ -44,5 +44,6 @@ export var CustomEventType;
44
44
  CustomEventType["Interrupt"] = "temba-interrupt";
45
45
  CustomEventType["Opened"] = "temba-opened";
46
46
  CustomEventType["TicketUpdated"] = "temba-ticket-updated";
47
+ CustomEventType["Moved"] = "temba-moved";
47
48
  })(CustomEventType || (CustomEventType = {}));
48
49
  //# sourceMappingURL=interfaces.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,mCAAsB,CAAA;IACtB,uCAA0B,CAAA;IAC1B,qCAAwB,CAAA;AAC1B,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,sDAAgC,CAAA;IAChC,gEAA0C,CAAA;IAC1C,4DAAsC,CAAA;AACxC,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,iCAAiB,CAAA;AACnB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AA4ND,MAAM,CAAN,IAAY,eA4BX;AA5BD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;IACzB,8CAA2B,CAAA;IAC3B,yDAAsC,CAAA;IACtC,gDAA6B,CAAA;IAC7B,gDAA6B,CAAA;IAC7B,yDAAsC,CAAA;IACtC,uDAAoC,CAAA;IACpC,6DAA0C,CAAA;IAC1C,2DAAwC,CAAA;IACxC,2DAAwC,CAAA;IACxC,yDAAsC,CAAA;IACtC,qDAAkC,CAAA;IAClC,gDAA6B,CAAA;IAC7B,kDAA+B,CAAA;IAC/B,2CAAwB,CAAA;IACxB,uDAAoC,CAAA;IACpC,wCAAqB,CAAA;IACrB,uDAAoC,CAAA;IACpC,iDAA8B,CAAA;IAC9B,+CAA4B,CAAA;IAC5B,4CAAyB,CAAA;IACzB,2DAAwC,CAAA;IACxC,wCAAqB,CAAA;IACrB,gDAA6B,CAAA;IAC7B,0CAAuB,CAAA;IACvB,yDAAsC,CAAA;AACxC,CAAC,EA5BW,eAAe,KAAf,eAAe,QA4B1B","sourcesContent":["export interface Workspace {\n uuid: string;\n name: string;\n country: string;\n languages: string[];\n timezone: string;\n date_style: DateStyle;\n anon: boolean;\n}\n\nexport interface Language {\n iso: string;\n name: string;\n}\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n url: string;\n filename: string;\n size: number;\n error: string;\n}\n\nexport enum DateStyle {\n DayFirst = 'day_first',\n MonthFirst = 'month_first',\n YearFirst = 'year_first'\n}\n\nexport enum ScheduledEventType {\n CampaignEvent = 'campaign_event',\n ScheduledBroadcast = 'scheduled_broadcast',\n ScheduledTrigger = 'scheduled_trigger'\n}\n\nexport enum TicketStatus {\n Open = 'open',\n Closed = 'closed'\n}\n\nexport interface ScheduledEvent {\n type: ScheduledEventType;\n scheduled: string;\n repeat_period: string;\n campaign?: ObjectReference;\n flow?: ObjectReference;\n message?: string;\n}\n\nexport interface NamedUser extends User {\n name: string;\n}\n\nexport interface User {\n id?: number;\n first_name?: string;\n last_name?: string;\n name?: string;\n email?: string;\n role?: string;\n created_on?: string;\n avatar?: string;\n}\n\nexport interface Ticket {\n uuid: string;\n subject: string;\n body?: string;\n closed_on: string;\n opened_on: string;\n status: string;\n contact: ObjectReference;\n topic: ObjectReference;\n assignee?: { email: string; name: string; avatar?: string };\n}\n\nexport interface FlowResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface FlowDetails {\n name: string;\n results: FlowResult[];\n modified_on: string;\n runs: {\n active: number;\n completed: number;\n expired: number;\n interrupted: number;\n };\n}\n\nexport interface Msg {\n text: string;\n status: string;\n channel: ObjectReference;\n quick_replies: string[];\n urn: string;\n id: number;\n direction: string;\n type: string;\n attachments: string[];\n}\n\nexport interface ObjectReference {\n uuid: string;\n name: string;\n}\n\nexport interface Shortcut {\n uuid: string;\n name: string;\n text: string;\n modified_on: string;\n}\n\nexport interface ContactField {\n key: string;\n label: string;\n value_type: string;\n featured: boolean;\n priority: number;\n agent_access: string;\n type: string;\n usages: { campaign_events: number; flows: number; groups: number };\n}\n\nexport interface ContactGroup {\n uuid: string;\n count: number;\n name: string;\n query?: string;\n status: string;\n}\n\nexport interface URN {\n scheme: string;\n path: string;\n}\n\nexport interface Group {\n name: string;\n uuid: string;\n is_dynamic?: boolean;\n}\n\nexport interface ContactNote {\n text: string;\n created_on: string;\n created_by: NamedUser;\n}\n\nexport interface ContactTicket {\n name: string;\n uuid: string;\n status: string;\n\n contact: {\n uuid: string;\n name: string;\n created_on: Date;\n last_seen_on: Date;\n };\n}\n\nexport interface Contact {\n name: string;\n uuid: string;\n stopped: boolean;\n blocked: boolean;\n urns: string[];\n language?: string;\n fields: { [key: string]: string };\n groups: Group[];\n notes: ContactNote[];\n modified_on: string;\n created_on: string;\n last_seen_on: string;\n status: string;\n\n anon_display?: string;\n flow?: ObjectReference;\n last_msg?: Msg;\n direction?: string;\n ticket: {\n uuid: string;\n subject: string;\n closed_on?: string;\n last_activity_on: string;\n assignee?: User;\n topic?: ObjectReference;\n };\n}\n\nexport interface FeatureProperties {\n name: string;\n osm_id: string;\n level: number;\n children?: FeatureProperties[];\n has_children?: boolean;\n aliases?: string;\n parent_osm_id?: string;\n id?: number;\n path?: string;\n}\n\nexport interface Position {\n top: number;\n left: number;\n}\n\nexport interface FunctionExample {\n template: string;\n output: string;\n}\n\nexport interface CompletionOption {\n name?: string;\n summary: string;\n\n // functions\n signature?: string;\n detail?: string;\n examples?: FunctionExample[];\n}\n\nexport interface CompletionResult {\n anchorPosition: Position;\n query: string;\n options: CompletionOption[];\n currentFunction: CompletionOption;\n}\n\nexport interface CompletionProperty {\n key: string;\n help: string;\n type: string;\n}\n\nexport interface CompletionType {\n name: string;\n\n key_source?: string;\n property_template?: CompletionProperty;\n properties?: CompletionProperty[];\n}\n\nexport interface CompletionSchema {\n types: CompletionType[];\n root: CompletionProperty[];\n root_no_session: CompletionProperty[];\n}\n\nexport type KeyedAssets = { [assetType: string]: string[] };\n\nexport enum CustomEventType {\n Loaded = 'temba-loaded',\n Loading = 'temba-loading',\n Canceled = 'temba-canceled',\n CursorChanged = 'temba-cursor-changed',\n Refreshed = 'temba-refreshed',\n Selection = 'temba-selection',\n ButtonClicked = 'temba-button-clicked',\n DialogHidden = 'temba-dialog-hidden',\n ScrollThreshold = 'temba-scroll-threshold',\n ContentChanged = 'temba-content-changed',\n ContextChanged = 'temba-context-changed',\n FetchComplete = 'temba-fetch-complete',\n MessageSent = 'temba-message-sent',\n Submitted = 'temba-submitted',\n Redirected = 'temba-redirected',\n NoPath = 'temba-no-path',\n StoreUpdated = 'temba-store-updated',\n Ready = 'temba-ready',\n OrderChanged = 'temba-order-changed',\n DragStart = 'temba-drag-start',\n DragStop = 'temba-drag-stop',\n Resized = 'temba-resized',\n DetailsChanged = 'temba-details-changed',\n Error = 'temba-error',\n Interrupt = 'temba-interrupt',\n Opened = 'temba-opened',\n TicketUpdated = 'temba-ticket-updated'\n}\n"]}
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,mCAAsB,CAAA;IACtB,uCAA0B,CAAA;IAC1B,qCAAwB,CAAA;AAC1B,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,sDAAgC,CAAA;IAChC,gEAA0C,CAAA;IAC1C,4DAAsC,CAAA;AACxC,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,iCAAiB,CAAA;AACnB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AA4ND,MAAM,CAAN,IAAY,eA6BX;AA7BD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;IACzB,8CAA2B,CAAA;IAC3B,yDAAsC,CAAA;IACtC,gDAA6B,CAAA;IAC7B,gDAA6B,CAAA;IAC7B,yDAAsC,CAAA;IACtC,uDAAoC,CAAA;IACpC,6DAA0C,CAAA;IAC1C,2DAAwC,CAAA;IACxC,2DAAwC,CAAA;IACxC,yDAAsC,CAAA;IACtC,qDAAkC,CAAA;IAClC,gDAA6B,CAAA;IAC7B,kDAA+B,CAAA;IAC/B,2CAAwB,CAAA;IACxB,uDAAoC,CAAA;IACpC,wCAAqB,CAAA;IACrB,uDAAoC,CAAA;IACpC,iDAA8B,CAAA;IAC9B,+CAA4B,CAAA;IAC5B,4CAAyB,CAAA;IACzB,2DAAwC,CAAA;IACxC,wCAAqB,CAAA;IACrB,gDAA6B,CAAA;IAC7B,0CAAuB,CAAA;IACvB,yDAAsC,CAAA;IACtC,wCAAqB,CAAA;AACvB,CAAC,EA7BW,eAAe,KAAf,eAAe,QA6B1B","sourcesContent":["export interface Workspace {\n uuid: string;\n name: string;\n country: string;\n languages: string[];\n timezone: string;\n date_style: DateStyle;\n anon: boolean;\n}\n\nexport interface Language {\n iso: string;\n name: string;\n}\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n url: string;\n filename: string;\n size: number;\n error: string;\n}\n\nexport enum DateStyle {\n DayFirst = 'day_first',\n MonthFirst = 'month_first',\n YearFirst = 'year_first'\n}\n\nexport enum ScheduledEventType {\n CampaignEvent = 'campaign_event',\n ScheduledBroadcast = 'scheduled_broadcast',\n ScheduledTrigger = 'scheduled_trigger'\n}\n\nexport enum TicketStatus {\n Open = 'open',\n Closed = 'closed'\n}\n\nexport interface ScheduledEvent {\n type: ScheduledEventType;\n scheduled: string;\n repeat_period: string;\n campaign?: ObjectReference;\n flow?: ObjectReference;\n message?: string;\n}\n\nexport interface NamedUser extends User {\n name: string;\n}\n\nexport interface User {\n id?: number;\n first_name?: string;\n last_name?: string;\n name?: string;\n email?: string;\n role?: string;\n created_on?: string;\n avatar?: string;\n}\n\nexport interface Ticket {\n uuid: string;\n subject: string;\n body?: string;\n closed_on: string;\n opened_on: string;\n status: string;\n contact: ObjectReference;\n topic: ObjectReference;\n assignee?: { email: string; name: string; avatar?: string };\n}\n\nexport interface FlowResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface FlowDetails {\n name: string;\n results: FlowResult[];\n modified_on: string;\n runs: {\n active: number;\n completed: number;\n expired: number;\n interrupted: number;\n };\n}\n\nexport interface Msg {\n text: string;\n status: string;\n channel: ObjectReference;\n quick_replies: string[];\n urn: string;\n id: number;\n direction: string;\n type: string;\n attachments: string[];\n}\n\nexport interface ObjectReference {\n uuid: string;\n name: string;\n}\n\nexport interface Shortcut {\n uuid: string;\n name: string;\n text: string;\n modified_on: string;\n}\n\nexport interface ContactField {\n key: string;\n label: string;\n value_type: string;\n featured: boolean;\n priority: number;\n agent_access: string;\n type: string;\n usages: { campaign_events: number; flows: number; groups: number };\n}\n\nexport interface ContactGroup {\n uuid: string;\n count: number;\n name: string;\n query?: string;\n status: string;\n}\n\nexport interface URN {\n scheme: string;\n path: string;\n}\n\nexport interface Group {\n name: string;\n uuid: string;\n is_dynamic?: boolean;\n}\n\nexport interface ContactNote {\n text: string;\n created_on: string;\n created_by: NamedUser;\n}\n\nexport interface ContactTicket {\n name: string;\n uuid: string;\n status: string;\n\n contact: {\n uuid: string;\n name: string;\n created_on: Date;\n last_seen_on: Date;\n };\n}\n\nexport interface Contact {\n name: string;\n uuid: string;\n stopped: boolean;\n blocked: boolean;\n urns: string[];\n language?: string;\n fields: { [key: string]: string };\n groups: Group[];\n notes: ContactNote[];\n modified_on: string;\n created_on: string;\n last_seen_on: string;\n status: string;\n\n anon_display?: string;\n flow?: ObjectReference;\n last_msg?: Msg;\n direction?: string;\n ticket: {\n uuid: string;\n subject: string;\n closed_on?: string;\n last_activity_on: string;\n assignee?: User;\n topic?: ObjectReference;\n };\n}\n\nexport interface FeatureProperties {\n name: string;\n osm_id: string;\n level: number;\n children?: FeatureProperties[];\n has_children?: boolean;\n aliases?: string;\n parent_osm_id?: string;\n id?: number;\n path?: string;\n}\n\nexport interface Position {\n top: number;\n left: number;\n}\n\nexport interface FunctionExample {\n template: string;\n output: string;\n}\n\nexport interface CompletionOption {\n name?: string;\n summary: string;\n\n // functions\n signature?: string;\n detail?: string;\n examples?: FunctionExample[];\n}\n\nexport interface CompletionResult {\n anchorPosition: Position;\n query: string;\n options: CompletionOption[];\n currentFunction: CompletionOption;\n}\n\nexport interface CompletionProperty {\n key: string;\n help: string;\n type: string;\n}\n\nexport interface CompletionType {\n name: string;\n\n key_source?: string;\n property_template?: CompletionProperty;\n properties?: CompletionProperty[];\n}\n\nexport interface CompletionSchema {\n types: CompletionType[];\n root: CompletionProperty[];\n root_no_session: CompletionProperty[];\n}\n\nexport type KeyedAssets = { [assetType: string]: string[] };\n\nexport enum CustomEventType {\n Loaded = 'temba-loaded',\n Loading = 'temba-loading',\n Canceled = 'temba-canceled',\n CursorChanged = 'temba-cursor-changed',\n Refreshed = 'temba-refreshed',\n Selection = 'temba-selection',\n ButtonClicked = 'temba-button-clicked',\n DialogHidden = 'temba-dialog-hidden',\n ScrollThreshold = 'temba-scroll-threshold',\n ContentChanged = 'temba-content-changed',\n ContextChanged = 'temba-context-changed',\n FetchComplete = 'temba-fetch-complete',\n MessageSent = 'temba-message-sent',\n Submitted = 'temba-submitted',\n Redirected = 'temba-redirected',\n NoPath = 'temba-no-path',\n StoreUpdated = 'temba-store-updated',\n Ready = 'temba-ready',\n OrderChanged = 'temba-order-changed',\n DragStart = 'temba-drag-start',\n DragStop = 'temba-drag-stop',\n Resized = 'temba-resized',\n DetailsChanged = 'temba-details-changed',\n Error = 'temba-error',\n Interrupt = 'temba-interrupt',\n Opened = 'temba-opened',\n TicketUpdated = 'temba-ticket-updated',\n Moved = 'temba-moved'\n}\n"]}
@@ -13,6 +13,12 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
13
13
  flowDefinition: null,
14
14
  flowInfo: null,
15
15
  isTranslating: false,
16
+ dirtyDate: null,
17
+ setDirtyDate: (date) => {
18
+ set((state) => {
19
+ state.dirtyDate = date;
20
+ });
21
+ },
16
22
  fetchRevision: async (endpoint, id = null) => {
17
23
  if (!id) {
18
24
  id = 'latest';
@@ -78,11 +84,6 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
78
84
  state.isTranslating = state.flowDefinition.language !== languageCode;
79
85
  });
80
86
  },
81
- setTestUpdate: () => {
82
- set((state) => {
83
- state.flowDefinition.name = 'Bloop!';
84
- });
85
- },
86
87
  expandCanvas: (width, height) => {
87
88
  set((state) => {
88
89
  const minWidth = Math.max(state.canvasSize.width, width + CANVAS_PADDING);
@@ -101,6 +102,22 @@ export const zustand = createStore()(subscribeWithSelector(immer((set, get) => (
101
102
  }
102
103
  });
103
104
  },
105
+ updateNodePosition: (uuid, newPosition) => {
106
+ set((state) => {
107
+ if (state.flowDefinition._ui.nodes[uuid]) {
108
+ state.flowDefinition._ui.nodes[uuid].position = newPosition;
109
+ }
110
+ else {
111
+ // If the node doesn't exist in _ui, we can add it
112
+ state.flowDefinition._ui.nodes[uuid] = {
113
+ position: newPosition,
114
+ type: null,
115
+ config: {}
116
+ };
117
+ }
118
+ state.dirtyDate = new Date();
119
+ });
120
+ },
104
121
  removeNodes: (uuids) => {
105
122
  set((state) => {
106
123
  for (const uuid of uuids) {
@@ -1 +1 @@
1
- {"version":3,"file":"AppState.js","sourceRoot":"","sources":["../../../src/store/AppState.ts"],"names":[],"mappings":"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","sourcesContent":["import { createStore, StoreApi } from 'zustand/vanilla';\nimport { fetchResults } from '../utils';\nimport { FlowDefinition, FlowPosition } from './flow-definition';\nimport { immer } from 'zustand/middleware/immer';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { property } from 'lit/decorators.js';\n\nexport const FLOW_SPEC_VERSION = '14.3';\nconst CANVAS_PADDING = 800;\n\nexport interface InfoResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface ObjectRef {\n uuid: string;\n name: string;\n}\n\nexport interface TypedObjectRef extends ObjectRef {\n type: string;\n}\n\nexport interface Language {\n code: string;\n name: string;\n}\n\nexport interface FlowInfo {\n results: InfoResult[];\n dependencies: TypedObjectRef[];\n counts: { nodes: number; languages: number };\n locals: string[];\n}\n\nexport interface FlowContents {\n definition: FlowDefinition;\n info: FlowInfo;\n}\n\nexport interface Workspace {\n anon: boolean;\n country: string;\n date_style: string;\n languages: string[];\n name: string;\n primary_language: string;\n timezone: string;\n uuid: string;\n}\n\nexport interface CanvasPositions {\n [uuid: string]: FlowPosition;\n}\n\nexport interface AppState {\n flowDefinition: FlowDefinition;\n flowInfo: FlowInfo;\n\n languageCode: string;\n languageNames: { [code: string]: Language };\n workspace: Workspace;\n isTranslating: boolean;\n\n canvasSize: { width: number; height: number };\n\n fetchRevision: (endpoint: string, id?: string) => void;\n fetchWorkspace: (endpoint: string) => Promise<void>;\n fetchAllLanguages: (endpoint: string) => Promise<void>;\n\n getFlowResults: () => InfoResult[];\n getResultByKey(id: any): InfoResult;\n\n setFlowContents: (flow: FlowContents) => void;\n setFlowInfo: (info: FlowInfo) => void;\n setLanguageCode: (languageCode: string) => void;\n setTestUpdate: () => void;\n expandCanvas: (width: number, height: number) => void;\n\n updateCanvasPositions: (positions: CanvasPositions) => void;\n removeNodes: (uuids: string[]) => void;\n}\n\nexport const zustand = createStore<AppState>()(\n subscribeWithSelector(\n immer((set, get) => ({\n languageNames: {},\n canvasSize: { width: 0, height: 0 },\n languageCode: '',\n workspace: null,\n flowDefinition: null,\n flowInfo: null,\n isTranslating: false,\n\n fetchRevision: async (endpoint: string, id: string = null) => {\n if (!id) {\n id = 'latest';\n }\n const response = await fetch(\n `${endpoint}/${id}/?version=${FLOW_SPEC_VERSION}`\n );\n\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = (await response.json()) as FlowContents;\n set({ flowInfo: data.info, flowDefinition: data.definition });\n },\n\n fetchWorkspace: async (endpoint) => {\n const response = await fetch(endpoint);\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = await response.json();\n set({ workspace: data });\n },\n\n fetchAllLanguages: async (endpoint) => {\n const results = await fetchResults(endpoint);\n\n // convert array to map for easier lookup\n const allLanguages = results.reduce(function (\n languages: any,\n result: any\n ) {\n languages[result.value] = result.name;\n return languages;\n },\n {});\n\n set({ languageNames: allLanguages });\n },\n\n getFlowResults: () => {\n const state = get();\n return state.flowInfo.results;\n },\n\n getResultByKey: (id: any) => {\n const state = get();\n const results = state.flowInfo.results;\n return results.find((result) => result.key === id);\n },\n\n getLanguage: () => {\n const state = get();\n const languageCode = state.languageCode;\n const languageNames = state.languageNames;\n return { name: languageNames[languageCode], code: languageCode };\n },\n\n // todo: eventually we should be doing the fetching\n setFlowContents: (flow: FlowContents) => {\n set((state: AppState) => {\n const flowLang = flow.definition.language;\n state.flowDefinition = flow.definition;\n state.flowInfo = flow.info;\n // Reset to the flow's default language when loading a new flow\n state.languageCode = flowLang;\n state.isTranslating = false;\n });\n },\n\n setFlowInfo: (info: FlowInfo) => {\n set((state: AppState) => {\n state.flowInfo = info;\n });\n },\n\n setLanguageCode: (languageCode: string) => {\n set((state: AppState) => {\n state.languageCode = languageCode;\n state.isTranslating = state.flowDefinition.language !== languageCode;\n });\n },\n\n setTestUpdate: () => {\n set((state: AppState) => {\n state.flowDefinition.name = 'Bloop!';\n });\n },\n\n expandCanvas: (width: number, height: number) => {\n set((state: AppState) => {\n const minWidth = Math.max(\n state.canvasSize.width,\n width + CANVAS_PADDING\n );\n const minHeight = Math.max(\n state.canvasSize.height,\n height + CANVAS_PADDING\n );\n\n state.canvasSize.width = minWidth;\n state.canvasSize.height = minHeight;\n });\n },\n\n updateCanvasPositions: (positions: CanvasPositions) => {\n set((state: AppState) => {\n for (const uuid in positions) {\n // todo: add nodes that are created and then moved, for now ignore\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = positions[uuid];\n }\n }\n });\n },\n\n removeNodes: (uuids: string[]) => {\n set((state: AppState) => {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.nodes[uuid];\n }\n\n state.flowDefinition.nodes = state.flowDefinition.nodes.filter(\n (node) => !uuids.includes(node.uuid)\n );\n });\n }\n }))\n )\n);\n\ntype SelectorAwareStoreApi<S extends object> = StoreApi<S> & {\n subscribe: <U>(\n selector: (state: S) => U,\n listener: (value: U, previous: U) => void\n ) => () => void;\n};\n\n/**\n * Custom Lit property decorator that binds a property to a Zustand store subscription.\n *\n * @param store - The Zustand store to subscribe to.\n * @param selector - A function selecting the slice of state to bind to the property.\n */\nexport function fromStore<S extends object, V = unknown>(\n store: SelectorAwareStoreApi<S>,\n selector: (state: S) => V\n): PropertyDecorator {\n return (proto: any, name: string | symbol) => {\n property()(proto, name as string);\n\n const connectedKey = 'connectedCallback';\n const disconnectedKey = 'disconnectedCallback';\n\n const userConnected = proto[connectedKey];\n const userDisconnected = proto[disconnectedKey];\n\n proto[connectedKey] = function () {\n this._zustandUnsubscribe ??= {};\n this[name] = selector(store.getState());\n\n this._zustandUnsubscribe[name] = store.subscribe(selector, (val: V) => {\n this[name] = val;\n });\n\n if (userConnected) userConnected.call(this);\n };\n\n proto[disconnectedKey] = function () {\n this._zustandUnsubscribe?.[name]?.();\n if (userDisconnected) userDisconnected.call(this);\n };\n };\n}\n"]}
1
+ {"version":3,"file":"AppState.js","sourceRoot":"","sources":["../../../src/store/AppState.ts"],"names":[],"mappings":"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","sourcesContent":["import { createStore, StoreApi } from 'zustand/vanilla';\nimport { fetchResults } from '../utils';\nimport { FlowDefinition, FlowPosition } from './flow-definition';\nimport { immer } from 'zustand/middleware/immer';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { property } from 'lit/decorators.js';\n\nexport const FLOW_SPEC_VERSION = '14.3';\nconst CANVAS_PADDING = 800;\n\nexport interface InfoResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface ObjectRef {\n uuid: string;\n name: string;\n}\n\nexport interface TypedObjectRef extends ObjectRef {\n type: string;\n}\n\nexport interface Language {\n code: string;\n name: string;\n}\n\nexport interface FlowInfo {\n results: InfoResult[];\n dependencies: TypedObjectRef[];\n counts: { nodes: number; languages: number };\n locals: string[];\n}\n\nexport interface FlowContents {\n definition: FlowDefinition;\n info: FlowInfo;\n}\n\nexport interface Workspace {\n anon: boolean;\n country: string;\n date_style: string;\n languages: string[];\n name: string;\n primary_language: string;\n timezone: string;\n uuid: string;\n}\n\nexport interface CanvasPositions {\n [uuid: string]: FlowPosition;\n}\n\nexport interface AppState {\n flowDefinition: FlowDefinition;\n flowInfo: FlowInfo;\n\n languageCode: string;\n languageNames: { [code: string]: Language };\n workspace: Workspace;\n isTranslating: boolean;\n\n dirtyDate: Date | null;\n\n canvasSize: { width: number; height: number };\n\n fetchRevision: (endpoint: string, id?: string) => void;\n fetchWorkspace: (endpoint: string) => Promise<void>;\n fetchAllLanguages: (endpoint: string) => Promise<void>;\n\n getFlowResults: () => InfoResult[];\n getResultByKey(id: any): InfoResult;\n\n setFlowContents: (flow: FlowContents) => void;\n setFlowInfo: (info: FlowInfo) => void;\n setLanguageCode: (languageCode: string) => void;\n setDirtyDate: (date: Date) => void;\n expandCanvas: (width: number, height: number) => void;\n\n updateCanvasPositions: (positions: CanvasPositions) => void;\n updateNodePosition(uuid: string, newPosition: FlowPosition): void;\n removeNodes: (uuids: string[]) => void;\n}\n\nexport const zustand = createStore<AppState>()(\n subscribeWithSelector(\n immer((set, get) => ({\n languageNames: {},\n canvasSize: { width: 0, height: 0 },\n languageCode: '',\n workspace: null,\n flowDefinition: null,\n flowInfo: null,\n isTranslating: false,\n dirtyDate: null,\n\n setDirtyDate: (date: Date) => {\n set((state: AppState) => {\n state.dirtyDate = date;\n });\n },\n\n fetchRevision: async (endpoint: string, id: string = null) => {\n if (!id) {\n id = 'latest';\n }\n const response = await fetch(\n `${endpoint}/${id}/?version=${FLOW_SPEC_VERSION}`\n );\n\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = (await response.json()) as FlowContents;\n set({ flowInfo: data.info, flowDefinition: data.definition });\n },\n\n fetchWorkspace: async (endpoint) => {\n const response = await fetch(endpoint);\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = await response.json();\n set({ workspace: data });\n },\n\n fetchAllLanguages: async (endpoint) => {\n const results = await fetchResults(endpoint);\n\n // convert array to map for easier lookup\n const allLanguages = results.reduce(function (\n languages: any,\n result: any\n ) {\n languages[result.value] = result.name;\n return languages;\n },\n {});\n\n set({ languageNames: allLanguages });\n },\n\n getFlowResults: () => {\n const state = get();\n return state.flowInfo.results;\n },\n\n getResultByKey: (id: any) => {\n const state = get();\n const results = state.flowInfo.results;\n return results.find((result) => result.key === id);\n },\n\n getLanguage: () => {\n const state = get();\n const languageCode = state.languageCode;\n const languageNames = state.languageNames;\n return { name: languageNames[languageCode], code: languageCode };\n },\n\n // todo: eventually we should be doing the fetching\n setFlowContents: (flow: FlowContents) => {\n set((state: AppState) => {\n const flowLang = flow.definition.language;\n state.flowDefinition = flow.definition;\n state.flowInfo = flow.info;\n // Reset to the flow's default language when loading a new flow\n state.languageCode = flowLang;\n state.isTranslating = false;\n });\n },\n\n setFlowInfo: (info: FlowInfo) => {\n set((state: AppState) => {\n state.flowInfo = info;\n });\n },\n\n setLanguageCode: (languageCode: string) => {\n set((state: AppState) => {\n state.languageCode = languageCode;\n state.isTranslating = state.flowDefinition.language !== languageCode;\n });\n },\n\n expandCanvas: (width: number, height: number) => {\n set((state: AppState) => {\n const minWidth = Math.max(\n state.canvasSize.width,\n width + CANVAS_PADDING\n );\n const minHeight = Math.max(\n state.canvasSize.height,\n height + CANVAS_PADDING\n );\n\n state.canvasSize.width = minWidth;\n state.canvasSize.height = minHeight;\n });\n },\n\n updateCanvasPositions: (positions: CanvasPositions) => {\n set((state: AppState) => {\n for (const uuid in positions) {\n // todo: add nodes that are created and then moved, for now ignore\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = positions[uuid];\n }\n }\n });\n },\n\n updateNodePosition: (uuid: string, newPosition: FlowPosition) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = newPosition;\n } else {\n // If the node doesn't exist in _ui, we can add it\n state.flowDefinition._ui.nodes[uuid] = {\n position: newPosition,\n type: null,\n config: {}\n };\n }\n\n state.dirtyDate = new Date();\n });\n },\n\n removeNodes: (uuids: string[]) => {\n set((state: AppState) => {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.nodes[uuid];\n }\n\n state.flowDefinition.nodes = state.flowDefinition.nodes.filter(\n (node) => !uuids.includes(node.uuid)\n );\n });\n }\n }))\n )\n);\n\ntype SelectorAwareStoreApi<S extends object> = StoreApi<S> & {\n subscribe: <U>(\n selector: (state: S) => U,\n listener: (value: U, previous: U) => void\n ) => () => void;\n};\n\n/**\n * Custom Lit property decorator that binds a property to a Zustand store subscription.\n *\n * @param store - The Zustand store to subscribe to.\n * @param selector - A function selecting the slice of state to bind to the property.\n */\nexport function fromStore<S extends object, V = unknown>(\n store: SelectorAwareStoreApi<S>,\n selector: (state: S) => V\n): PropertyDecorator {\n return (proto: any, name: string | symbol) => {\n property()(proto, name as string);\n\n const connectedKey = 'connectedCallback';\n const disconnectedKey = 'disconnectedCallback';\n\n const userConnected = proto[connectedKey];\n const userDisconnected = proto[disconnectedKey];\n\n proto[connectedKey] = function () {\n this._zustandUnsubscribe ??= {};\n this[name] = selector(store.getState());\n\n this._zustandUnsubscribe[name] = store.subscribe(selector, (val: V) => {\n this[name] = val;\n });\n\n if (userConnected) userConnected.call(this);\n };\n\n proto[disconnectedKey] = function () {\n this._zustandUnsubscribe?.[name]?.();\n if (userDisconnected) userDisconnected.call(this);\n };\n };\n}\n"]}
@@ -114,6 +114,32 @@ describe('temba-chart', () => {
114
114
  expect(tickCallback.call({}, 604800, 9, [])).to.equal('7d'); // 1 week in seconds
115
115
  expect(tickCallback.call({}, 1209600, 10, [])).to.equal('14d'); // 2 weeks in seconds
116
116
  });
117
+ it('applies xFormat when xType is time', async () => {
118
+ const chart = await getChart({
119
+ xType: 'time',
120
+ xFormat: 'DD'
121
+ });
122
+ chart.data = sampleData;
123
+ await chart.updateComplete;
124
+ // Wait for the chart to be created after data is set
125
+ await new Promise((resolve) => setTimeout(resolve, 50));
126
+ expect(chart.chart).to.exist;
127
+ expect(chart.chart.options.scales.x.type).to.equal('time');
128
+ expect(chart.chart.options.scales.x.time.displayFormats.day).to.equal('DD');
129
+ });
130
+ it('does not include time config when xType is category', async () => {
131
+ const chart = await getChart({
132
+ xType: 'category',
133
+ xFormat: 'DD'
134
+ });
135
+ chart.data = sampleData;
136
+ await chart.updateComplete;
137
+ // Wait for the chart to be created after data is set
138
+ await new Promise((resolve) => setTimeout(resolve, 50));
139
+ expect(chart.chart).to.exist;
140
+ expect(chart.chart.options.scales.x.type).to.equal('category');
141
+ expect(chart.chart.options.scales.x.time).to.be.undefined;
142
+ });
117
143
  });
118
144
  describe('formatDurationFromSeconds', () => {
119
145
  it('formats zero correctly', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"temba-chart.test.js","sourceRoot":"","sources":["../../test/temba-chart.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport {\n RapidChartData,\n TembaChart,\n formatDurationFromSeconds\n} from '../src/chart/TembaChart';\nimport { getComponent } from './utils.test';\n\nconst sampleData: RapidChartData = {\n labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],\n datasets: [\n {\n label: 'General',\n data: [65, 59, 80, 81, 56, 55, 40]\n },\n {\n label: 'Support',\n data: [28, 48, 40, 19, 86, 27, 90]\n },\n {\n label: 'VIPs',\n data: [58, 28, 10, 1, 0, 19, 20]\n }\n ]\n};\n\nconst TAG = 'temba-chart';\nconst getChart = async (attrs: any = {}) => {\n const picker = (await getComponent(TAG, attrs, '', 400)) as TembaChart;\n return picker;\n};\n\ndescribe('temba-chart', () => {\n it('calculates others', async () => {\n const chart: TembaChart = await getChart();\n\n chart.data = sampleData;\n await chart.updateComplete;\n\n // if we haven't set any splits, everything should be summed as \"All\"\n expect(chart.datasets[0].data).to.deep.equal([\n 151, 135, 130, 101, 142, 101, 150\n ]);\n\n // add a split\n chart.splits = ['General'];\n await chart.updateComplete;\n\n // now we should get an \"Others\" dataset\n expect(chart.datasets[1].data).to.deep.equal([86, 76, 50, 20, 86, 46, 110]);\n\n // add another split\n chart.splits = ['General', 'Support'];\n await chart.updateComplete;\n\n // now others should be everything but general and support\n expect(chart.datasets[2].data).to.deep.equal([58, 28, 10, 1, 0, 19, 20]);\n });\n\n it('supports duration formatting', async () => {\n const chart: TembaChart = await getChart();\n\n // Test that formatDuration property exists and defaults to false\n expect(chart.yType).to.equal('count');\n\n // Test that we can set formatDuration to true\n chart.yType = 'duration';\n expect(chart.yType).to.equal('duration');\n });\n\n it('formats duration values correctly', async () => {\n const chart: TembaChart = await getChart();\n\n // Access the formatDurationFromSeconds function through the chart's module\n // We need to test the duration formatting logic\n const durationData: RapidChartData = {\n labels: ['Day 1', 'Day 2', 'Day 3'],\n datasets: [\n {\n label: 'Process Time',\n data: [68787, 958000, 3661] // seconds that should be formatted as durations\n }\n ]\n };\n\n chart.yType = 'duration';\n chart.data = durationData;\n await chart.updateComplete;\n\n // Wait for the chart to be created after data is set\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n // Test that the chart was created and has the duration formatting enabled\n expect(chart.yType).to.equal('duration');\n expect(chart.chart).to.exist;\n\n // Test that the chart configuration includes the duration formatting\n const chartConfig = chart.chart.options;\n expect(chartConfig.scales.y.ticks).to.exist;\n expect(chartConfig.scales.y.ticks.callback).to.be.a('function');\n\n // Test the tick callback function formatting\n const tickCallback = chartConfig.scales.y.ticks.callback;\n expect(tickCallback.call({}, 68787, 0, [])).to.equal('19h 6m');\n expect(tickCallback.call({}, 958000, 1, [])).to.equal('11d 2h');\n expect(tickCallback.call({}, 3661, 2, [])).to.equal('1h 1m');\n expect(tickCallback.call({}, 120, 3, [])).to.equal('2m');\n expect(tickCallback.call({}, 0, 4, [])).to.equal('0s');\n\n // Test tooltip formatting\n expect(chartConfig.plugins.tooltip.callbacks.label).to.be.a('function');\n const tooltipCallback = chartConfig.plugins.tooltip.callbacks.label;\n\n const mockContext = {\n dataset: { label: 'Process Time' },\n parsed: { y: 68787 }\n };\n\n expect(tooltipCallback.call({}, mockContext)).to.equal(\n 'Process Time: 19h 6m'\n );\n });\n\n it('formats various duration edge cases correctly', async () => {\n const chart: TembaChart = await getChart();\n chart.yType = 'duration';\n chart.data = sampleData;\n await chart.updateComplete;\n\n // Wait for the chart to be created after data is set\n await new Promise((resolve) => setTimeout(resolve, 50));\n\n expect(chart.chart).to.exist;\n const tickCallback = chart.chart.options.scales.y.ticks.callback;\n\n // Test edge cases for duration formatting\n expect(tickCallback.call({}, 0, 0, [])).to.equal('0s');\n expect(tickCallback.call({}, 1, 1, [])).to.equal('1s');\n expect(tickCallback.call({}, 59, 2, [])).to.equal('59s');\n expect(tickCallback.call({}, 60, 3, [])).to.equal('1m');\n expect(tickCallback.call({}, 61, 4, [])).to.equal('1m 1s');\n expect(tickCallback.call({}, 3600, 5, [])).to.equal('1h');\n expect(tickCallback.call({}, 3661, 6, [])).to.equal('1h 1m');\n expect(tickCallback.call({}, 86400, 7, [])).to.equal('1d');\n expect(tickCallback.call({}, 90061, 8, [])).to.equal('1d 1h'); // 1 day, 1 hour, 1 minute, 1 second - should show only first two units\n expect(tickCallback.call({}, 604800, 9, [])).to.equal('7d'); // 1 week in seconds\n expect(tickCallback.call({}, 1209600, 10, [])).to.equal('14d'); // 2 weeks in seconds\n });\n});\n\ndescribe('formatDurationFromSeconds', () => {\n it('formats zero correctly', () => {\n expect(formatDurationFromSeconds(0)).to.equal('0s');\n });\n\n it('formats seconds only', () => {\n expect(formatDurationFromSeconds(1)).to.equal('1s');\n expect(formatDurationFromSeconds(30)).to.equal('30s');\n expect(formatDurationFromSeconds(59)).to.equal('59s');\n });\n\n it('formats minutes and seconds', () => {\n expect(formatDurationFromSeconds(60)).to.equal('1m');\n expect(formatDurationFromSeconds(61)).to.equal('1m 1s');\n expect(formatDurationFromSeconds(90)).to.equal('1m 30s');\n expect(formatDurationFromSeconds(120)).to.equal('2m');\n expect(formatDurationFromSeconds(3599)).to.equal('59m 59s');\n });\n\n it('formats hours and minutes', () => {\n expect(formatDurationFromSeconds(3600)).to.equal('1h');\n expect(formatDurationFromSeconds(3661)).to.equal('1h 1m');\n expect(formatDurationFromSeconds(7200)).to.equal('2h');\n expect(formatDurationFromSeconds(68787)).to.equal('19h 6m');\n });\n\n it('formats days and hours', () => {\n expect(formatDurationFromSeconds(86400)).to.equal('1d');\n expect(formatDurationFromSeconds(90000)).to.equal('1d 1h');\n expect(formatDurationFromSeconds(958000)).to.equal('11d 2h');\n });\n\n it('shows only two most significant units', () => {\n // 1 day, 1 hour, 1 minute, 1 second - should show only \"1d 1h\"\n expect(formatDurationFromSeconds(90061)).to.equal('1d 1h');\n\n // 2 hours, 30 minutes, 45 seconds - should show only \"2h 30m\"\n expect(formatDurationFromSeconds(9045)).to.equal('2h 30m');\n\n // 5 minutes, 30 seconds - should show \"5m 30s\"\n expect(formatDurationFromSeconds(330)).to.equal('5m 30s');\n });\n\n it('handles large durations', () => {\n expect(formatDurationFromSeconds(604800)).to.equal('7d'); // 1 week\n expect(formatDurationFromSeconds(1209600)).to.equal('14d'); // 2 weeks\n expect(formatDurationFromSeconds(2678400)).to.equal('31d'); // ~1 month\n });\n});\n"]}
1
+ {"version":3,"file":"temba-chart.test.js","sourceRoot":"","sources":["../../test/temba-chart.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport {\n RapidChartData,\n TembaChart,\n formatDurationFromSeconds\n} from '../src/chart/TembaChart';\nimport { getComponent } from './utils.test';\n\nconst sampleData: RapidChartData = {\n labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],\n datasets: [\n {\n label: 'General',\n data: [65, 59, 80, 81, 56, 55, 40]\n },\n {\n label: 'Support',\n data: [28, 48, 40, 19, 86, 27, 90]\n },\n {\n label: 'VIPs',\n data: [58, 28, 10, 1, 0, 19, 20]\n }\n ]\n};\n\nconst TAG = 'temba-chart';\nconst getChart = async (attrs: any = {}) => {\n const picker = (await getComponent(TAG, attrs, '', 400)) as TembaChart;\n return picker;\n};\n\ndescribe('temba-chart', () => {\n it('calculates others', async () => {\n const chart: TembaChart = await getChart();\n\n chart.data = sampleData;\n await chart.updateComplete;\n\n // if we haven't set any splits, everything should be summed as \"All\"\n expect(chart.datasets[0].data).to.deep.equal([\n 151, 135, 130, 101, 142, 101, 150\n ]);\n\n // add a split\n chart.splits = ['General'];\n await chart.updateComplete;\n\n // now we should get an \"Others\" dataset\n expect(chart.datasets[1].data).to.deep.equal([86, 76, 50, 20, 86, 46, 110]);\n\n // add another split\n chart.splits = ['General', 'Support'];\n await chart.updateComplete;\n\n // now others should be everything but general and support\n expect(chart.datasets[2].data).to.deep.equal([58, 28, 10, 1, 0, 19, 20]);\n });\n\n it('supports duration formatting', async () => {\n const chart: TembaChart = await getChart();\n\n // Test that formatDuration property exists and defaults to false\n expect(chart.yType).to.equal('count');\n\n // Test that we can set formatDuration to true\n chart.yType = 'duration';\n expect(chart.yType).to.equal('duration');\n });\n\n it('formats duration values correctly', async () => {\n const chart: TembaChart = await getChart();\n\n // Access the formatDurationFromSeconds function through the chart's module\n // We need to test the duration formatting logic\n const durationData: RapidChartData = {\n labels: ['Day 1', 'Day 2', 'Day 3'],\n datasets: [\n {\n label: 'Process Time',\n data: [68787, 958000, 3661] // seconds that should be formatted as durations\n }\n ]\n };\n\n chart.yType = 'duration';\n chart.data = durationData;\n await chart.updateComplete;\n\n // Wait for the chart to be created after data is set\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n // Test that the chart was created and has the duration formatting enabled\n expect(chart.yType).to.equal('duration');\n expect(chart.chart).to.exist;\n\n // Test that the chart configuration includes the duration formatting\n const chartConfig = chart.chart.options;\n expect(chartConfig.scales.y.ticks).to.exist;\n expect(chartConfig.scales.y.ticks.callback).to.be.a('function');\n\n // Test the tick callback function formatting\n const tickCallback = chartConfig.scales.y.ticks.callback;\n expect(tickCallback.call({}, 68787, 0, [])).to.equal('19h 6m');\n expect(tickCallback.call({}, 958000, 1, [])).to.equal('11d 2h');\n expect(tickCallback.call({}, 3661, 2, [])).to.equal('1h 1m');\n expect(tickCallback.call({}, 120, 3, [])).to.equal('2m');\n expect(tickCallback.call({}, 0, 4, [])).to.equal('0s');\n\n // Test tooltip formatting\n expect(chartConfig.plugins.tooltip.callbacks.label).to.be.a('function');\n const tooltipCallback = chartConfig.plugins.tooltip.callbacks.label;\n\n const mockContext = {\n dataset: { label: 'Process Time' },\n parsed: { y: 68787 }\n };\n\n expect(tooltipCallback.call({}, mockContext)).to.equal(\n 'Process Time: 19h 6m'\n );\n });\n\n it('formats various duration edge cases correctly', async () => {\n const chart: TembaChart = await getChart();\n chart.yType = 'duration';\n chart.data = sampleData;\n await chart.updateComplete;\n\n // Wait for the chart to be created after data is set\n await new Promise((resolve) => setTimeout(resolve, 50));\n\n expect(chart.chart).to.exist;\n const tickCallback = chart.chart.options.scales.y.ticks.callback;\n\n // Test edge cases for duration formatting\n expect(tickCallback.call({}, 0, 0, [])).to.equal('0s');\n expect(tickCallback.call({}, 1, 1, [])).to.equal('1s');\n expect(tickCallback.call({}, 59, 2, [])).to.equal('59s');\n expect(tickCallback.call({}, 60, 3, [])).to.equal('1m');\n expect(tickCallback.call({}, 61, 4, [])).to.equal('1m 1s');\n expect(tickCallback.call({}, 3600, 5, [])).to.equal('1h');\n expect(tickCallback.call({}, 3661, 6, [])).to.equal('1h 1m');\n expect(tickCallback.call({}, 86400, 7, [])).to.equal('1d');\n expect(tickCallback.call({}, 90061, 8, [])).to.equal('1d 1h'); // 1 day, 1 hour, 1 minute, 1 second - should show only first two units\n expect(tickCallback.call({}, 604800, 9, [])).to.equal('7d'); // 1 week in seconds\n expect(tickCallback.call({}, 1209600, 10, [])).to.equal('14d'); // 2 weeks in seconds\n });\n\n it('applies xFormat when xType is time', async () => {\n const chart: TembaChart = await getChart({\n xType: 'time',\n xFormat: 'DD'\n });\n\n chart.data = sampleData;\n await chart.updateComplete;\n\n // Wait for the chart to be created after data is set\n await new Promise((resolve) => setTimeout(resolve, 50));\n\n expect(chart.chart).to.exist;\n expect(chart.chart.options.scales.x.type).to.equal('time');\n expect(\n (chart.chart.options.scales.x as any).time.displayFormats.day\n ).to.equal('DD');\n });\n\n it('does not include time config when xType is category', async () => {\n const chart: TembaChart = await getChart({\n xType: 'category',\n xFormat: 'DD'\n });\n\n chart.data = sampleData;\n await chart.updateComplete;\n\n // Wait for the chart to be created after data is set\n await new Promise((resolve) => setTimeout(resolve, 50));\n\n expect(chart.chart).to.exist;\n expect(chart.chart.options.scales.x.type).to.equal('category');\n expect((chart.chart.options.scales.x as any).time).to.be.undefined;\n });\n});\n\ndescribe('formatDurationFromSeconds', () => {\n it('formats zero correctly', () => {\n expect(formatDurationFromSeconds(0)).to.equal('0s');\n });\n\n it('formats seconds only', () => {\n expect(formatDurationFromSeconds(1)).to.equal('1s');\n expect(formatDurationFromSeconds(30)).to.equal('30s');\n expect(formatDurationFromSeconds(59)).to.equal('59s');\n });\n\n it('formats minutes and seconds', () => {\n expect(formatDurationFromSeconds(60)).to.equal('1m');\n expect(formatDurationFromSeconds(61)).to.equal('1m 1s');\n expect(formatDurationFromSeconds(90)).to.equal('1m 30s');\n expect(formatDurationFromSeconds(120)).to.equal('2m');\n expect(formatDurationFromSeconds(3599)).to.equal('59m 59s');\n });\n\n it('formats hours and minutes', () => {\n expect(formatDurationFromSeconds(3600)).to.equal('1h');\n expect(formatDurationFromSeconds(3661)).to.equal('1h 1m');\n expect(formatDurationFromSeconds(7200)).to.equal('2h');\n expect(formatDurationFromSeconds(68787)).to.equal('19h 6m');\n });\n\n it('formats days and hours', () => {\n expect(formatDurationFromSeconds(86400)).to.equal('1d');\n expect(formatDurationFromSeconds(90000)).to.equal('1d 1h');\n expect(formatDurationFromSeconds(958000)).to.equal('11d 2h');\n });\n\n it('shows only two most significant units', () => {\n // 1 day, 1 hour, 1 minute, 1 second - should show only \"1d 1h\"\n expect(formatDurationFromSeconds(90061)).to.equal('1d 1h');\n\n // 2 hours, 30 minutes, 45 seconds - should show only \"2h 30m\"\n expect(formatDurationFromSeconds(9045)).to.equal('2h 30m');\n\n // 5 minutes, 30 seconds - should show \"5m 30s\"\n expect(formatDurationFromSeconds(330)).to.equal('5m 30s');\n });\n\n it('handles large durations', () => {\n expect(formatDurationFromSeconds(604800)).to.equal('7d'); // 1 week\n expect(formatDurationFromSeconds(1209600)).to.equal('14d'); // 2 weeks\n expect(formatDurationFromSeconds(2678400)).to.equal('31d'); // ~1 month\n });\n});\n"]}