@carto/ps-react-ui 4.5.1 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/{download-config-DemuQ3Jm.js → download-config-C3I0jWIL.js} +2 -2
  2. package/dist/{download-config-DemuQ3Jm.js.map → download-config-C3I0jWIL.js.map} +1 -1
  3. package/dist/{row-D4VOhcNI.js → row-DZSP99LW.js} +2 -2
  4. package/dist/{row-D4VOhcNI.js.map → row-DZSP99LW.js.map} +1 -1
  5. package/dist/{series-Bola3CmD.js → series-DLNHDWs0.js} +3 -3
  6. package/dist/{series-Bola3CmD.js.map → series-DLNHDWs0.js.map} +1 -1
  7. package/dist/types/hooks/index.d.ts +0 -1
  8. package/dist/types/widgets/actions/brush-toggle/brush-toggle.d.ts +3 -0
  9. package/dist/types/widgets/actions/index.d.ts +4 -4
  10. package/dist/types/widgets/actions/lock-selection/types.d.ts +2 -0
  11. package/dist/types/widgets/actions/relative-data/relative-data.d.ts +7 -2
  12. package/dist/types/widgets/actions/relative-data/types.d.ts +2 -0
  13. package/dist/types/widgets/actions/zoom-toggle/zoom-toggle.d.ts +4 -0
  14. package/dist/types/widgets/category/index.d.ts +10 -2
  15. package/dist/types/widgets/no-data/no-data.d.ts +3 -2
  16. package/dist/types/widgets/no-data/types.d.ts +5 -1
  17. package/dist/types/widgets/stores/index.d.ts +1 -1
  18. package/dist/types/widgets/stores/types.d.ts +10 -10
  19. package/dist/types/widgets/stores/widget-store.d.ts +2 -3
  20. package/dist/types/widgets/table/index.d.ts +6 -2
  21. package/dist/{use-widget-ref-BFazQvJK.js → use-widget-ref-Ddr_SlJJ.js} +2 -2
  22. package/dist/{use-widget-ref-BFazQvJK.js.map → use-widget-ref-Ddr_SlJJ.js.map} +1 -1
  23. package/dist/{use-widget-selector-DqRmWQ1K.js → use-widget-selector-DFl2hW0R.js} +2 -2
  24. package/dist/{use-widget-selector-DqRmWQ1K.js.map → use-widget-selector-DFl2hW0R.js.map} +1 -1
  25. package/dist/{widget-store-CIrb9RKP.js → widget-store-Bw5zRUGg.js} +93 -95
  26. package/dist/widget-store-Bw5zRUGg.js.map +1 -0
  27. package/dist/widgets/actions.js +770 -755
  28. package/dist/widgets/actions.js.map +1 -1
  29. package/dist/widgets/bar.js +2 -2
  30. package/dist/widgets/category.js +3 -3
  31. package/dist/widgets/category.js.map +1 -1
  32. package/dist/widgets/echart.js +2 -2
  33. package/dist/widgets/error.js +37 -2
  34. package/dist/widgets/error.js.map +1 -1
  35. package/dist/widgets/formula.js +5 -5
  36. package/dist/widgets/histogram.js +1 -1
  37. package/dist/widgets/loader.js +1 -1
  38. package/dist/widgets/markdown.js +2 -2
  39. package/dist/widgets/no-data.js +58 -2
  40. package/dist/widgets/no-data.js.map +1 -1
  41. package/dist/widgets/note.js +121 -2
  42. package/dist/widgets/note.js.map +1 -1
  43. package/dist/widgets/pie.js +2 -2
  44. package/dist/widgets/range.js +3 -3
  45. package/dist/widgets/scatterplot.js +2 -2
  46. package/dist/widgets/skeleton-loader.js +1 -1
  47. package/dist/widgets/spread.js +5 -5
  48. package/dist/widgets/stores.js +2 -2
  49. package/dist/widgets/table.js +3 -3
  50. package/dist/widgets/timeseries.js +2 -2
  51. package/dist/widgets/utils.js +1 -1
  52. package/dist/widgets/wrapper.js +2 -2
  53. package/package.json +1 -5
  54. package/src/hooks/index.ts +0 -1
  55. package/src/widgets/actions/brush-toggle/brush-toggle.tsx +18 -22
  56. package/src/widgets/actions/change-column/change-column.test.tsx +1 -1
  57. package/src/widgets/actions/download/download.test.tsx +1 -1
  58. package/src/widgets/actions/index.ts +11 -2
  59. package/src/widgets/actions/lock-selection/lock-selection.test.tsx +14 -0
  60. package/src/widgets/actions/lock-selection/lock-selection.tsx +18 -11
  61. package/src/widgets/actions/lock-selection/types.ts +2 -0
  62. package/src/widgets/actions/relative-data/relative-data.test.tsx +211 -20
  63. package/src/widgets/actions/relative-data/relative-data.tsx +65 -34
  64. package/src/widgets/actions/relative-data/types.ts +2 -0
  65. package/src/widgets/actions/searcher/searcher.tsx +28 -30
  66. package/src/widgets/actions/stack-toggle/stack-toggle.tsx +11 -2
  67. package/src/widgets/actions/zoom-toggle/zoom-toggle.tsx +53 -45
  68. package/src/widgets/category/category-ui.tsx +4 -6
  69. package/src/widgets/category/index.ts +13 -14
  70. package/src/widgets/no-data/no-data.test.tsx +90 -40
  71. package/src/widgets/no-data/no-data.tsx +7 -5
  72. package/src/widgets/no-data/types.ts +5 -1
  73. package/src/widgets/stores/index.ts +2 -0
  74. package/src/widgets/stores/types.ts +10 -18
  75. package/src/widgets/stores/widget-store.test.ts +132 -13
  76. package/src/widgets/stores/widget-store.ts +29 -35
  77. package/src/widgets/table/index.ts +6 -4
  78. package/dist/error-Cj8eUMrl.js +0 -40
  79. package/dist/error-Cj8eUMrl.js.map +0 -1
  80. package/dist/no-data-DkIt7Qt1.js +0 -61
  81. package/dist/no-data-DkIt7Qt1.js.map +0 -1
  82. package/dist/note-t51drNe0.js +0 -124
  83. package/dist/note-t51drNe0.js.map +0 -1
  84. package/dist/types/hooks/use-debounce.d.ts +0 -19
  85. package/dist/types/widgets/category/components/index.d.ts +0 -10
  86. package/dist/types/widgets/index.d.ts +0 -9
  87. package/dist/types/widgets/table/hooks/index.d.ts +0 -6
  88. package/dist/widget-store-CIrb9RKP.js.map +0 -1
  89. package/dist/widgets.js +0 -13
  90. package/dist/widgets.js.map +0 -1
  91. package/src/hooks/use-debounce.ts +0 -55
  92. package/src/widgets/category/components/index.ts +0 -14
  93. package/src/widgets/index.ts +0 -25
  94. package/src/widgets/table/hooks/index.ts +0 -7
@@ -10,12 +10,12 @@ describe('WidgetNoData', () => {
10
10
  useWidgetStore.getState().clearWidgets()
11
11
  })
12
12
 
13
- describe('when data is empty', () => {
13
+ describe('when sourceData is empty', () => {
14
14
  test('renders NoData UI with empty array', () => {
15
15
  useWidgetStore.getState().setWidget(widgetId, {
16
16
  isLoading: false,
17
17
  isFetching: false,
18
- data: [],
18
+ sourceData: [],
19
19
  })
20
20
 
21
21
  render(
@@ -31,11 +31,11 @@ describe('WidgetNoData', () => {
31
31
  expect(screen.queryByText('Widget Content')).toBeNull()
32
32
  })
33
33
 
34
- test('renders NoData UI with null data', () => {
34
+ test('renders NoData UI with null sourceData', () => {
35
35
  useWidgetStore.getState().setWidget(widgetId, {
36
36
  isLoading: false,
37
37
  isFetching: false,
38
- data: null,
38
+ sourceData: null,
39
39
  })
40
40
 
41
41
  render(
@@ -48,11 +48,11 @@ describe('WidgetNoData', () => {
48
48
  expect(screen.queryByText('Widget Content')).toBeNull()
49
49
  })
50
50
 
51
- test('renders NoData UI with undefined data', () => {
51
+ test('renders NoData UI with undefined sourceData', () => {
52
52
  useWidgetStore.getState().setWidget(widgetId, {
53
53
  isLoading: false,
54
54
  isFetching: false,
55
- data: undefined,
55
+ sourceData: undefined,
56
56
  })
57
57
 
58
58
  render(
@@ -69,7 +69,7 @@ describe('WidgetNoData', () => {
69
69
  useWidgetStore.getState().setWidget(widgetId, {
70
70
  isLoading: false,
71
71
  isFetching: false,
72
- data: [[], []],
72
+ sourceData: [[], []],
73
73
  })
74
74
 
75
75
  render(
@@ -86,7 +86,7 @@ describe('WidgetNoData', () => {
86
86
  useWidgetStore.getState().setWidget(widgetId, {
87
87
  isLoading: false,
88
88
  isFetching: false,
89
- data: {},
89
+ sourceData: {},
90
90
  })
91
91
 
92
92
  render(
@@ -100,12 +100,12 @@ describe('WidgetNoData', () => {
100
100
  })
101
101
  })
102
102
 
103
- describe('when data exists', () => {
104
- test('renders children with array data', () => {
103
+ describe('when sourceData exists', () => {
104
+ test('renders children with array sourceData', () => {
105
105
  useWidgetStore.getState().setWidget(widgetId, {
106
106
  isLoading: false,
107
107
  isFetching: false,
108
- data: [{ value: 1 }],
108
+ sourceData: [{ value: 1 }],
109
109
  })
110
110
 
111
111
  render(
@@ -118,11 +118,11 @@ describe('WidgetNoData', () => {
118
118
  expect(screen.queryByText('No data available')).toBeNull()
119
119
  })
120
120
 
121
- test('renders children with object data', () => {
121
+ test('renders children with object sourceData', () => {
122
122
  useWidgetStore.getState().setWidget(widgetId, {
123
123
  isLoading: false,
124
124
  isFetching: false,
125
- data: { content: 'Hello' },
125
+ sourceData: { content: 'Hello' },
126
126
  })
127
127
 
128
128
  render(
@@ -135,11 +135,11 @@ describe('WidgetNoData', () => {
135
135
  expect(screen.queryByText('No data available')).toBeNull()
136
136
  })
137
137
 
138
- test('renders children with nested array data', () => {
138
+ test('renders children with nested array sourceData', () => {
139
139
  useWidgetStore.getState().setWidget(widgetId, {
140
140
  isLoading: false,
141
141
  isFetching: false,
142
- data: [[{ name: 'A', value: 1 }]],
142
+ sourceData: [[{ name: 'A', value: 1 }]],
143
143
  })
144
144
 
145
145
  render(
@@ -152,11 +152,11 @@ describe('WidgetNoData', () => {
152
152
  expect(screen.queryByText('No data available')).toBeNull()
153
153
  })
154
154
 
155
- test('renders children with primitive data (number)', () => {
155
+ test('renders children with primitive sourceData (number)', () => {
156
156
  useWidgetStore.getState().setWidget(widgetId, {
157
157
  isLoading: false,
158
158
  isFetching: false,
159
- data: 0,
159
+ sourceData: 0,
160
160
  })
161
161
 
162
162
  render(
@@ -169,11 +169,11 @@ describe('WidgetNoData', () => {
169
169
  expect(screen.queryByText('No data available')).toBeNull()
170
170
  })
171
171
 
172
- test('renders children with primitive data (string)', () => {
172
+ test('renders children with primitive sourceData (string)', () => {
173
173
  useWidgetStore.getState().setWidget(widgetId, {
174
174
  isLoading: false,
175
175
  isFetching: false,
176
- data: 'test',
176
+ sourceData: 'test',
177
177
  })
178
178
 
179
179
  render(
@@ -186,11 +186,11 @@ describe('WidgetNoData', () => {
186
186
  expect(screen.queryByText('No data available')).toBeNull()
187
187
  })
188
188
 
189
- test('renders children with primitive data (boolean)', () => {
189
+ test('renders children with primitive sourceData (boolean)', () => {
190
190
  useWidgetStore.getState().setWidget(widgetId, {
191
191
  isLoading: false,
192
192
  isFetching: false,
193
- data: false,
193
+ sourceData: false,
194
194
  })
195
195
 
196
196
  render(
@@ -205,11 +205,10 @@ describe('WidgetNoData', () => {
205
205
  })
206
206
 
207
207
  describe('when loading or fetching', () => {
208
- test('renders children when isLoading=true even if data is empty', () => {
208
+ test('renders children when isLoading=true even if sourceData is empty', () => {
209
209
  useWidgetStore.getState().setWidget(widgetId, {
210
210
  isLoading: true,
211
211
  isFetching: false,
212
- data: [],
213
212
  })
214
213
 
215
214
  render(
@@ -222,11 +221,10 @@ describe('WidgetNoData', () => {
222
221
  expect(screen.queryByText('No data available')).toBeNull()
223
222
  })
224
223
 
225
- test('renders children when isFetching=true even if data is empty', () => {
224
+ test('renders children when isFetching=true even if sourceData is empty', () => {
226
225
  useWidgetStore.getState().setWidget(widgetId, {
227
226
  isLoading: false,
228
227
  isFetching: true,
229
- data: [],
230
228
  })
231
229
 
232
230
  render(
@@ -243,7 +241,6 @@ describe('WidgetNoData', () => {
243
241
  useWidgetStore.getState().setWidget(widgetId, {
244
242
  isLoading: true,
245
243
  isFetching: true,
246
- data: [],
247
244
  })
248
245
 
249
246
  render(
@@ -262,7 +259,7 @@ describe('WidgetNoData', () => {
262
259
  useWidgetStore.getState().setWidget(widgetId, {
263
260
  isLoading: false,
264
261
  isFetching: false,
265
- data: [],
262
+ sourceData: [],
266
263
  })
267
264
 
268
265
  render(
@@ -279,7 +276,7 @@ describe('WidgetNoData', () => {
279
276
  useWidgetStore.getState().setWidget(widgetId, {
280
277
  isLoading: false,
281
278
  isFetching: false,
282
- data: [],
279
+ sourceData: [],
283
280
  })
284
281
 
285
282
  render(
@@ -298,10 +295,10 @@ describe('WidgetNoData', () => {
298
295
  useWidgetStore.getState().setWidget(widgetId, {
299
296
  isLoading: false,
300
297
  isFetching: false,
301
- data: { customField: 'value' },
298
+ sourceData: { customField: 'value' },
302
299
  })
303
300
 
304
- // Custom isEmpty that treats this object as empty
301
+ // Custom isEmpty that treats this sourceData as empty
305
302
  const customIsEmpty = (data: unknown) => {
306
303
  const d = data as { customField: string }
307
304
  return d?.customField === 'value'
@@ -321,7 +318,7 @@ describe('WidgetNoData', () => {
321
318
  useWidgetStore.getState().setWidget(widgetId, {
322
319
  isLoading: false,
323
320
  isFetching: false,
324
- data: [],
321
+ sourceData: [],
325
322
  })
326
323
 
327
324
  // Custom isEmpty that treats empty array as having data
@@ -352,12 +349,66 @@ describe('WidgetNoData', () => {
352
349
  })
353
350
  })
354
351
 
352
+ describe('sourceData vs pipeline-transformed data', () => {
353
+ test('renders children when sourceData has data but pipeline data is empty', () => {
354
+ useWidgetStore.getState().setWidget(widgetId, {
355
+ isLoading: false,
356
+ isFetching: false,
357
+ sourceData: [{ value: 1 }, { value: 2 }],
358
+ data: [], // pipeline filtered everything out
359
+ })
360
+
361
+ render(
362
+ <WidgetNoData id={widgetId}>
363
+ <div>Widget Content</div>
364
+ </WidgetNoData>,
365
+ )
366
+
367
+ // Should show children because sourceData is not empty
368
+ expect(screen.getByText('Widget Content')).toBeTruthy()
369
+ expect(screen.queryByText('No data available')).toBeNull()
370
+ })
371
+
372
+ test('renders NoData when both sourceData and data are empty', () => {
373
+ useWidgetStore.getState().setWidget(widgetId, {
374
+ isLoading: false,
375
+ isFetching: false,
376
+ sourceData: [],
377
+ })
378
+
379
+ render(
380
+ <WidgetNoData id={widgetId}>
381
+ <div>Widget Content</div>
382
+ </WidgetNoData>,
383
+ )
384
+
385
+ expect(screen.getByText('No data available')).toBeTruthy()
386
+ expect(screen.queryByText('Widget Content')).toBeNull()
387
+ })
388
+
389
+ test('renders NoData when sourceData is null (API returned nothing)', () => {
390
+ useWidgetStore.getState().setWidget(widgetId, {
391
+ isLoading: false,
392
+ isFetching: false,
393
+ sourceData: null,
394
+ })
395
+
396
+ render(
397
+ <WidgetNoData id={widgetId}>
398
+ <div>Widget Content</div>
399
+ </WidgetNoData>,
400
+ )
401
+
402
+ expect(screen.getByText('No data available')).toBeTruthy()
403
+ expect(screen.queryByText('Widget Content')).toBeNull()
404
+ })
405
+ })
406
+
355
407
  describe('reactivity to store changes', () => {
356
- test('updates from NoData to content when data arrives', () => {
408
+ test('updates from NoData to content when sourceData arrives', () => {
357
409
  useWidgetStore.getState().setWidget(widgetId, {
358
410
  isLoading: false,
359
411
  isFetching: false,
360
- data: [],
361
412
  })
362
413
 
363
414
  const { rerender } = render(
@@ -369,9 +420,9 @@ describe('WidgetNoData', () => {
369
420
  expect(screen.getByText('No data available')).toBeTruthy()
370
421
  expect(screen.queryByText('Widget Content')).toBeNull()
371
422
 
372
- // Update with data
423
+ // Update with sourceData
373
424
  useWidgetStore.getState().setWidget(widgetId, {
374
- data: [{ value: 1 }],
425
+ sourceData: [{ value: 1 }],
375
426
  })
376
427
 
377
428
  // Force rerender to pick up store changes
@@ -385,11 +436,11 @@ describe('WidgetNoData', () => {
385
436
  expect(screen.queryByText('No data available')).toBeNull()
386
437
  })
387
438
 
388
- test('updates from content to NoData when data becomes empty', () => {
439
+ test('updates from content to NoData when sourceData becomes empty', () => {
389
440
  useWidgetStore.getState().setWidget(widgetId, {
390
441
  isLoading: false,
391
442
  isFetching: false,
392
- data: [{ value: 1 }],
443
+ sourceData: [{ value: 1 }],
393
444
  })
394
445
 
395
446
  const { rerender } = render(
@@ -401,8 +452,8 @@ describe('WidgetNoData', () => {
401
452
  expect(screen.getByText('Widget Content')).toBeTruthy()
402
453
  expect(screen.queryByText('No data available')).toBeNull()
403
454
 
404
- // Clear data
405
- useWidgetStore.getState().setWidget(widgetId, { data: [] })
455
+ // Clear sourceData
456
+ useWidgetStore.getState().setWidget(widgetId, { sourceData: [] })
406
457
 
407
458
  // Force rerender to pick up store changes
408
459
  rerender(
@@ -419,7 +470,6 @@ describe('WidgetNoData', () => {
419
470
  useWidgetStore.getState().setWidget(widgetId, {
420
471
  isLoading: false,
421
472
  isFetching: false,
422
- data: [],
423
473
  })
424
474
 
425
475
  const { rerender } = render(
@@ -6,8 +6,9 @@ import { styles } from './style'
6
6
  /**
7
7
  * NoData wrapper component that displays empty state UI when widget has no data
8
8
  *
9
- * Integrates with widget store to check loading/fetching state and data availability.
10
- * Works in conjunction with SkeletonLoader for complete loading/empty state handling.
9
+ * Integrates with widget store to check loading/fetching state and source data availability.
10
+ * Uses `sourceData` (pre-pipeline data) instead of `data` (post-pipeline) to distinguish
11
+ * "API returned nothing" from "pipeline tools filtered everything out".
11
12
  *
12
13
  * @example Basic usage
13
14
  * ```tsx
@@ -44,10 +45,11 @@ export function WidgetNoData({
44
45
  isEmpty = defaultIsEmpty,
45
46
  }: WidgetNoDataProps) {
46
47
  // Single consolidated subscription instead of 3 separate ones.
47
- const { isLoading, isFetching, data } = useWidgetSelector(id, (w) => ({
48
+ // Reads sourceData (pre-pipeline) to check emptiness, not data (post-pipeline).
49
+ const { isLoading, isFetching, sourceData } = useWidgetSelector(id, (w) => ({
48
50
  isLoading: w?.isLoading,
49
51
  isFetching: w?.isFetching,
50
- data: w?.data,
52
+ sourceData: w?.sourceData,
51
53
  }))
52
54
 
53
55
  // If loading or fetching, show children
@@ -57,7 +59,7 @@ export function WidgetNoData({
57
59
  }
58
60
 
59
61
  // Check if data is empty
60
- if (isEmpty(data)) {
62
+ if (isEmpty(sourceData)) {
61
63
  return (
62
64
  <Box sx={styles.root}>
63
65
  <Typography variant='body2' color='text.primary'>
@@ -59,7 +59,11 @@ export interface WidgetNoDataProps {
59
59
  description?: string
60
60
 
61
61
  /**
62
- * Optional custom function to determine if data is empty
62
+ * Optional custom function to determine if source data is empty.
63
+ * Receives `sourceData` (pre-pipeline data from the API), not `data`
64
+ * (post-pipeline). This allows distinguishing "API returned nothing"
65
+ * from "pipeline tools filtered everything out".
66
+ *
63
67
  * If not provided, uses default isEmpty logic that handles:
64
68
  * - null/undefined → empty
65
69
  * - [] (empty array) → empty
@@ -2,6 +2,8 @@ export { useWidgetStore, widgetStoreActions } from './widget-store'
2
2
  export { useWidgetSelector } from './use-widget-selector'
3
3
  export type {
4
4
  BaseWidgetState,
5
+ ToolRegistration,
6
+ ToolTransformFunction,
5
7
  ToolType,
6
8
  WidgetsStoreProps,
7
9
  WidgetState,
@@ -14,6 +14,10 @@ export interface WidgetsStoreProps {
14
14
  type: string
15
15
  /** Widget data - flexible to accommodate different widget types */
16
16
  data: unknown
17
+ /** Original pre-pipeline data. Used by NoData to distinguish
18
+ * "no data from API" from "pipeline tools filtered everything out".
19
+ * Set automatically by executeToolPipeline — not a component prop. */
20
+ sourceData?: unknown
17
21
  /** Loading state */
18
22
  isLoading: boolean
19
23
  /** Fetching state (e.g., for async data) */
@@ -41,11 +45,7 @@ export interface WidgetsStoreProps {
41
45
  * Tool transformation function type
42
46
  * Can be synchronous or asynchronous to support remote operations
43
47
  */
44
- export type ToolTransformFunction = (
45
- data: unknown,
46
- config?: Record<string, unknown>,
47
- // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
48
- ) => Promise<unknown> | unknown
48
+ export type ToolTransformFunction = (data: unknown) => unknown
49
49
 
50
50
  /**
51
51
  * Tool registration for widget pipeline
@@ -88,8 +88,6 @@ export interface ToolRegistration {
88
88
  enabled: boolean
89
89
  /** 'data' (default) transforms data, 'config' transforms widget config/option */
90
90
  type?: ToolType
91
- /** Tool-specific configuration */
92
- config?: Record<string, unknown>
93
91
  /**
94
92
  * Array of tool IDs to disable when this tool is active.
95
93
  * During pipeline execution, if this tool is enabled, any tools listed
@@ -169,24 +167,18 @@ export interface WidgetStoreActions {
169
167
  unregisterTool: (widgetId: string, toolId: string) => void
170
168
 
171
169
  /**
172
- * Update tool configuration
170
+ * Set tool enabled state
173
171
  * @param widgetId - Widget ID
174
172
  * @param toolId - Tool ID
175
- * @param config - New configuration to merge
173
+ * @param enabled - Whether tool should be enabled
176
174
  */
177
- updateToolConfig: (
178
- widgetId: string,
179
- toolId: string,
180
- config: Record<string, unknown>,
181
- ) => void
175
+ setToolEnabled: (widgetId: string, toolId: string, enabled: boolean) => void
182
176
 
183
177
  /**
184
- * Set tool enabled state
178
+ * Trigger pipeline re-execution by bumping the registeredTools reference.
185
179
  * @param widgetId - Widget ID
186
- * @param toolId - Tool ID
187
- * @param enabled - Whether tool should be enabled
188
180
  */
189
- setToolEnabled: (widgetId: string, toolId: string, enabled: boolean) => void
181
+ triggerToolPipeline: (widgetId: string) => void
190
182
 
191
183
  /**
192
184
  * Execute the tool transformation pipeline