@nyaruka/temba-components 0.135.9 → 0.136.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/demo/components/webchat/example.html +4 -2
  3. package/dist/static/svg/index.svg +1 -1
  4. package/dist/temba-components.js +1351 -322
  5. package/dist/temba-components.js.map +1 -1
  6. package/out-tsc/src/Icons.js +2 -1
  7. package/out-tsc/src/Icons.js.map +1 -1
  8. package/out-tsc/src/display/FloatingTab.js +2 -6
  9. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  10. package/out-tsc/src/flow/CanvasNode.js +29 -1
  11. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  12. package/out-tsc/src/flow/Editor.js +229 -5
  13. package/out-tsc/src/flow/Editor.js.map +1 -1
  14. package/out-tsc/src/flow/Plumber.js +320 -1
  15. package/out-tsc/src/flow/Plumber.js.map +1 -1
  16. package/out-tsc/src/interfaces.js +1 -0
  17. package/out-tsc/src/interfaces.js.map +1 -1
  18. package/out-tsc/src/layout/FloatingWindow.js +30 -8
  19. package/out-tsc/src/layout/FloatingWindow.js.map +1 -1
  20. package/out-tsc/src/simulator/Simulator.js +1861 -0
  21. package/out-tsc/src/simulator/Simulator.js.map +1 -0
  22. package/out-tsc/src/store/AppState.js +66 -0
  23. package/out-tsc/src/store/AppState.js.map +1 -1
  24. package/out-tsc/src/utils.js +48 -0
  25. package/out-tsc/src/utils.js.map +1 -1
  26. package/out-tsc/temba-modules.js +2 -0
  27. package/out-tsc/temba-modules.js.map +1 -1
  28. package/out-tsc/test/temba-appstate-node-sorting.test.js +430 -0
  29. package/out-tsc/test/temba-appstate-node-sorting.test.js.map +1 -0
  30. package/out-tsc/test/temba-floating-tab.test.js +0 -9
  31. package/out-tsc/test/temba-floating-tab.test.js.map +1 -1
  32. package/out-tsc/test/temba-flow-editor.test.js +262 -1
  33. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  34. package/out-tsc/test/temba-flow-plumber-connections.test.js +3 -1
  35. package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -1
  36. package/out-tsc/test/temba-flow-plumber.test.js +3 -1
  37. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  38. package/out-tsc/test/temba-simulator.test.js +642 -0
  39. package/out-tsc/test/temba-simulator.test.js.map +1 -0
  40. package/out-tsc/test/utils.test.js +1 -1
  41. package/out-tsc/test/utils.test.js.map +1 -1
  42. package/package.json +1 -1
  43. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  44. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  45. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  46. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  47. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  48. package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
  49. package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
  50. package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
  51. package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
  52. package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
  53. package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
  54. package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
  55. package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
  56. package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
  57. package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
  58. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  59. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  60. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  61. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  62. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  63. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  64. package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
  65. package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
  66. package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
  67. package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
  68. package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
  69. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  70. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  71. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  72. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  73. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  74. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  75. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  76. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  77. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  78. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  79. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  80. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  81. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  82. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  83. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  84. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  85. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  86. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  87. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  88. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  89. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  90. package/screenshots/truth/floating-tab/gray.png +0 -0
  91. package/screenshots/truth/floating-tab/green.png +0 -0
  92. package/screenshots/truth/floating-tab/purple.png +0 -0
  93. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  94. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  95. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  96. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  97. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  98. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  99. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  100. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  101. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  102. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  103. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  104. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  105. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  106. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  107. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  108. package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
  109. package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
  110. package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
  111. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  112. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  113. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  114. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  115. package/screenshots/truth/simulator/after-message-sent.png +0 -0
  116. package/screenshots/truth/simulator/after-reset.png +0 -0
  117. package/screenshots/truth/simulator/attachment-menu.png +0 -0
  118. package/screenshots/truth/simulator/context-expanded.png +0 -0
  119. package/screenshots/truth/simulator/context-explorer-open.png +0 -0
  120. package/screenshots/truth/simulator/event-info.png +0 -0
  121. package/screenshots/truth/simulator/image-attachment.png +0 -0
  122. package/screenshots/truth/simulator/open-initial.png +0 -0
  123. package/screenshots/truth/simulator/quick-replies.png +0 -0
  124. package/src/Icons.ts +2 -1
  125. package/src/display/FloatingTab.ts +2 -7
  126. package/src/flow/CanvasNode.ts +30 -1
  127. package/src/flow/Editor.ts +246 -4
  128. package/src/flow/Plumber.ts +371 -2
  129. package/src/interfaces.ts +2 -1
  130. package/src/layout/FloatingWindow.ts +37 -12
  131. package/src/simulator/Simulator.ts +2061 -0
  132. package/src/store/AppState.ts +109 -0
  133. package/src/utils.ts +53 -0
  134. package/static/svg/index.svg +1 -1
  135. package/static/svg/work/traced/route.svg +1 -0
  136. package/static/svg/work/used/route.svg +3 -0
  137. package/temba-modules.ts +2 -0
  138. package/test/temba-appstate-node-sorting.test.ts +506 -0
  139. package/test/temba-floating-tab.test.ts +0 -11
  140. package/test/temba-flow-editor.test.ts +298 -1
  141. package/test/temba-flow-plumber-connections.test.ts +4 -1
  142. package/test/temba-flow-plumber.test.ts +4 -1
  143. package/test/temba-simulator.test.ts +866 -0
  144. package/test/utils.test.ts +1 -1
@@ -169,6 +169,125 @@ export class Editor extends RapidElement {
169
169
  z-index: 10;
170
170
  }
171
171
 
172
+ /* Activity overlays on connections */
173
+ .jtk-overlay.activity-overlay {
174
+ background: #f3f3f3;
175
+ border: 1px solid #d9d9d9;
176
+ color: #333;
177
+ border-radius: 4px;
178
+ padding: 2px 4px;
179
+ font-size: 10px;
180
+ font-weight: 600;
181
+ line-height: 0.9;
182
+ cursor: pointer;
183
+ z-index: 500;
184
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
185
+ }
186
+
187
+ /* Active contact count on nodes */
188
+ .active-count {
189
+ position: absolute;
190
+ background: #3498db;
191
+ border: 1px solid #2980b9;
192
+ border-radius: 12px;
193
+ padding: 3px 5px;
194
+ color: #fff;
195
+ font-weight: 500;
196
+ top: -10px;
197
+ left: -10px;
198
+ font-size: 13px;
199
+ min-width: 22px;
200
+ text-align: center;
201
+ z-index: 600;
202
+ line-height: 1;
203
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
204
+ }
205
+
206
+ /* Recent contacts popup */
207
+ @keyframes popupBounceIn {
208
+ 0% {
209
+ transform: scale(0.8);
210
+ opacity: 0;
211
+ }
212
+ 50% {
213
+ transform: scale(1.05);
214
+ }
215
+ 100% {
216
+ transform: scale(1);
217
+ opacity: 1;
218
+ }
219
+ }
220
+
221
+ .recent-contacts-popup {
222
+ display: none;
223
+ position: absolute;
224
+ width: 200px;
225
+ background: #f3f3f3;
226
+ border-radius: 10px;
227
+ box-shadow: 0 1px 3px 1px rgba(130, 130, 130, 0.2);
228
+ z-index: 1015;
229
+ transform-origin: top center;
230
+ }
231
+
232
+ .recent-contacts-popup.show {
233
+ display: block;
234
+ animation: popupBounceIn 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
235
+ }
236
+
237
+ .recent-contacts-popup .popup-title {
238
+ background: #999;
239
+ color: #fff;
240
+ padding: 6px 0;
241
+ text-align: center;
242
+ border-top-left-radius: 10px;
243
+ border-top-right-radius: 10px;
244
+ font-size: 12px;
245
+ }
246
+
247
+ .recent-contacts-popup .no-contacts-message {
248
+ padding: 15px;
249
+ text-align: center;
250
+ color: #999;
251
+ font-size: 12px;
252
+ }
253
+
254
+ .recent-contacts-popup .contact-row {
255
+ padding: 8px 10px;
256
+ border-top: 1px solid #e0e0e0;
257
+ text-align: left;
258
+ }
259
+
260
+ .recent-contacts-popup .contact-row:last-child {
261
+ border-bottom-left-radius: 10px;
262
+ border-bottom-right-radius: 10px;
263
+ }
264
+
265
+ .recent-contacts-popup .contact-name {
266
+ display: block;
267
+ font-weight: 500;
268
+ font-size: 12px;
269
+ color: var(--color-link-primary, #1d4ed8);
270
+ cursor: pointer;
271
+ }
272
+
273
+ .recent-contacts-popup .contact-name:hover {
274
+ text-decoration: underline;
275
+ color: var(--color-link-primary, #1d4ed8);
276
+ }
277
+
278
+ .recent-contacts-popup .contact-operand {
279
+ padding-top: 3px;
280
+ font-size: 11px;
281
+ color: #666;
282
+ word-wrap: break-word;
283
+ }
284
+
285
+ .recent-contacts-popup .contact-time {
286
+ padding-top: 3px;
287
+ font-size: 10px;
288
+ color: #999;
289
+ }
290
+
172
291
  /* Connection dragging feedback */
173
292
  body svg.jtk-connector.jtk-dragging {
174
293
  z-index: 99999 !important;
@@ -399,6 +518,8 @@ export class Editor extends RapidElement {
399
518
  this.saveTimer = null;
400
519
  this.flowType = 'message';
401
520
  this.features = [];
521
+ this.activityTimer = null;
522
+ this.activityInterval = 100; // Start with 100ms interval for fast initial load
402
523
  // Drag state
403
524
  this.isDragging = false;
404
525
  this.isMouseDown = false;
@@ -446,7 +567,7 @@ export class Editor extends RapidElement {
446
567
  }
447
568
  firstUpdated(changes) {
448
569
  super.firstUpdated(changes);
449
- this.plumber = new Plumber(this.querySelector('#canvas'));
570
+ this.plumber = new Plumber(this.querySelector('#canvas'), this);
450
571
  this.setupGlobalEventListeners();
451
572
  if (changes.has('flow')) {
452
573
  getStore().getState().fetchRevision(`/flow/revisions/${this.flow}`);
@@ -484,7 +605,7 @@ export class Editor extends RapidElement {
484
605
  this.isValidTarget = true;
485
606
  }
486
607
  updated(changes) {
487
- var _b, _c, _d;
608
+ var _b, _c, _d, _e;
488
609
  super.updated(changes);
489
610
  if (changes.has('canvasSize')) {
490
611
  // console.log('Setting canvas size', this.canvasSize);
@@ -505,6 +626,27 @@ export class Editor extends RapidElement {
505
626
  this.translationFilters = normalizedFilters;
506
627
  }
507
628
  this.translationCache.clear();
629
+ // Start fetching activity data when definition is loaded
630
+ if ((_e = this.definition) === null || _e === void 0 ? void 0 : _e.uuid) {
631
+ this.startActivityFetching();
632
+ }
633
+ }
634
+ if (changes.has('simulatorActive')) {
635
+ if (this.simulatorActive) {
636
+ // Stop polling when simulator becomes active
637
+ this.stopActivityFetching();
638
+ }
639
+ else {
640
+ // Resume polling and refresh activity when simulator closes
641
+ this.activityInterval = 100; // Reset to fast initial interval
642
+ this.startActivityFetching();
643
+ }
644
+ }
645
+ if (changes.has('activityData')) {
646
+ // Update plumber with new activity data
647
+ if (this.plumber) {
648
+ this.plumber.setActivityData(this.activityData);
649
+ }
508
650
  }
509
651
  if (changes.has('dirtyDate')) {
510
652
  if (this.dirtyDate) {
@@ -572,6 +714,46 @@ export class Editor extends RapidElement {
572
714
  });
573
715
  getStore().getState().setDirtyDate(null);
574
716
  }
717
+ startActivityFetching() {
718
+ // Don't start if simulator is active
719
+ if (this.simulatorActive) {
720
+ return;
721
+ }
722
+ // Fetch immediately
723
+ this.fetchActivityData();
724
+ }
725
+ stopActivityFetching() {
726
+ if (this.activityTimer !== null) {
727
+ clearTimeout(this.activityTimer);
728
+ this.activityTimer = null;
729
+ }
730
+ }
731
+ fetchActivityData() {
732
+ var _b;
733
+ if (!((_b = this.definition) === null || _b === void 0 ? void 0 : _b.uuid)) {
734
+ return;
735
+ }
736
+ // Don't fetch if simulator is active
737
+ if (this.simulatorActive) {
738
+ return;
739
+ }
740
+ const activityEndpoint = `/flow/activity/${this.definition.uuid}/`;
741
+ const store = getStore();
742
+ if (!store) {
743
+ return;
744
+ }
745
+ const state = store.getState();
746
+ state.fetchActivity(activityEndpoint).then(() => {
747
+ // Schedule next fetch with exponential backoff (max 5 minutes)
748
+ this.activityInterval = Math.min(60000 * 5, this.activityInterval + 100);
749
+ if (this.activityTimer !== null) {
750
+ clearTimeout(this.activityTimer);
751
+ }
752
+ this.activityTimer = window.setTimeout(() => {
753
+ this.fetchActivityData();
754
+ }, this.activityInterval);
755
+ });
756
+ }
575
757
  handleLanguageChange(languageCode) {
576
758
  zustand.getState().setLanguageCode(languageCode);
577
759
  // Repaint connections after language change since node sizes can change
@@ -587,6 +769,10 @@ export class Editor extends RapidElement {
587
769
  clearTimeout(this.saveTimer);
588
770
  this.saveTimer = null;
589
771
  }
772
+ if (this.activityTimer !== null) {
773
+ clearTimeout(this.activityTimer);
774
+ this.activityTimer = null;
775
+ }
590
776
  document.removeEventListener('mousemove', this.boundMouseMove);
591
777
  document.removeEventListener('mouseup', this.boundMouseUp);
592
778
  document.removeEventListener('mousedown', this.boundGlobalMouseDown);
@@ -2100,7 +2286,7 @@ export class Editor extends RapidElement {
2100
2286
  header="Translations"
2101
2287
  .width=${360}
2102
2288
  .maxHeight=${600}
2103
- .top=${170}
2289
+ .top=${75}
2104
2290
  color="#6b7280"
2105
2291
  .hidden=${this.localizationWindowHidden}
2106
2292
  @temba-dialog-hidden=${this.handleLocalizationWindowClosed}
@@ -2264,6 +2450,36 @@ export class Editor extends RapidElement {
2264
2450
  ></temba-floating-tab>
2265
2451
  `;
2266
2452
  }
2453
+ /**
2454
+ * Focus on a specific node by smoothly scrolling it to the center of the canvas
2455
+ */
2456
+ focusNode(nodeUuid) {
2457
+ const nodeElement = this.querySelector(`temba-flow-node[uuid="${nodeUuid}"]`);
2458
+ if (!nodeElement) {
2459
+ return;
2460
+ }
2461
+ const editor = this.querySelector('#editor');
2462
+ if (!editor) {
2463
+ return;
2464
+ }
2465
+ // Get the editor's dimensions and scroll position
2466
+ const editorRect = editor.getBoundingClientRect();
2467
+ const editorCenterX = editorRect.width / 2;
2468
+ const editorCenterY = editorRect.height / 2;
2469
+ // Get node position relative to the editor's scroll container
2470
+ const nodeRect = nodeElement.getBoundingClientRect();
2471
+ const nodeCenterX = nodeElement.offsetLeft + nodeRect.width / 2;
2472
+ const nodeCenterY = nodeElement.offsetTop + nodeRect.height / 2;
2473
+ // Calculate the scroll position needed to center the node
2474
+ const targetScrollX = nodeCenterX - editorCenterX;
2475
+ const targetScrollY = nodeCenterY - editorCenterY;
2476
+ // Smooth scroll the editor container to the target position
2477
+ editor.scrollTo({
2478
+ left: Math.max(0, targetScrollX),
2479
+ top: Math.max(0, targetScrollY),
2480
+ behavior: 'smooth'
2481
+ });
2482
+ }
2267
2483
  render() {
2268
2484
  var _b, _c;
2269
2485
  // we have to embed our own style since we are in light DOM
@@ -2282,7 +2498,7 @@ export class Editor extends RapidElement {
2282
2498
  >
2283
2499
  <div id="canvas">
2284
2500
  ${this.definition
2285
- ? repeat(this.definition.nodes, (node) => node.uuid, (node) => {
2501
+ ? repeat(this.definition.nodes, (node) => node.uuid, (node, index) => {
2286
2502
  var _b, _c, _d;
2287
2503
  const position = ((_c = (_b = this.definition._ui) === null || _b === void 0 ? void 0 : _b.nodes[node.uuid]) === null || _c === void 0 ? void 0 : _c.position) || {
2288
2504
  left: 0,
@@ -2291,10 +2507,12 @@ export class Editor extends RapidElement {
2291
2507
  const dragging = this.isDragging &&
2292
2508
  ((_d = this.currentDragItem) === null || _d === void 0 ? void 0 : _d.uuid) === node.uuid;
2293
2509
  const selected = this.selectedItems.has(node.uuid);
2510
+ // first node is the flow start (nodes are sorted by position)
2511
+ const isFlowStart = index === 0;
2294
2512
  return html `<temba-flow-node
2295
2513
  class="draggable ${dragging ? 'dragging' : ''} ${selected
2296
2514
  ? 'selected'
2297
- : ''}"
2515
+ : ''} ${isFlowStart ? 'flow-start' : ''}"
2298
2516
  @mousedown=${this.handleMouseDown.bind(this)}
2299
2517
  uuid=${node.uuid}
2300
2518
  data-node-uuid=${node.uuid}
@@ -2364,6 +2582,9 @@ __decorate([
2364
2582
  __decorate([
2365
2583
  fromStore(zustand, (state) => state.flowDefinition)
2366
2584
  ], Editor.prototype, "definition", void 0);
2585
+ __decorate([
2586
+ fromStore(zustand, (state) => state.simulatorActive)
2587
+ ], Editor.prototype, "simulatorActive", void 0);
2367
2588
  __decorate([
2368
2589
  fromStore(zustand, (state) => state.canvasSize)
2369
2590
  ], Editor.prototype, "canvasSize", void 0);
@@ -2379,6 +2600,9 @@ __decorate([
2379
2600
  __decorate([
2380
2601
  fromStore(zustand, (state) => state.workspace)
2381
2602
  ], Editor.prototype, "workspace", void 0);
2603
+ __decorate([
2604
+ fromStore(zustand, (state) => state.getCurrentActivity())
2605
+ ], Editor.prototype, "activityData", void 0);
2382
2606
  __decorate([
2383
2607
  state()
2384
2608
  ], Editor.prototype, "isDragging", void 0);