@thoughtspot/ts-chart-sdk 0.0.1-alpha.0 → 0.0.1-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +782 -0
- package/cjs/index.d.ts +9 -0
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +25 -0
- package/cjs/index.js.map +1 -0
- package/cjs/main/custom-chart-context.d.ts +47 -0
- package/cjs/main/custom-chart-context.d.ts.map +1 -0
- package/cjs/main/custom-chart-context.js +326 -0
- package/cjs/main/custom-chart-context.js.map +1 -0
- package/cjs/main/custom-chart-context.spec.d.ts +2 -0
- package/cjs/main/custom-chart-context.spec.d.ts.map +1 -0
- package/cjs/main/custom-chart-context.spec.js +699 -0
- package/cjs/main/custom-chart-context.spec.js.map +1 -0
- package/cjs/main/post-message-event-bridge.d.ts +6 -0
- package/cjs/main/post-message-event-bridge.d.ts.map +1 -0
- package/cjs/main/post-message-event-bridge.js +46 -0
- package/cjs/main/post-message-event-bridge.js.map +1 -0
- package/cjs/main/post-message-event-bridge.spec.d.ts +2 -0
- package/cjs/main/post-message-event-bridge.spec.d.ts.map +1 -0
- package/cjs/main/post-message-event-bridge.spec.js +124 -0
- package/cjs/main/post-message-event-bridge.spec.js.map +1 -0
- package/cjs/react/mocks/custom-chart-context-mock.d.ts +3 -0
- package/cjs/react/mocks/custom-chart-context-mock.d.ts.map +1 -0
- package/cjs/react/mocks/custom-chart-context-mock.js +100 -0
- package/cjs/react/mocks/custom-chart-context-mock.js.map +1 -0
- package/cjs/react/use-custom-chart-context.d.ts +4 -0
- package/cjs/react/use-custom-chart-context.d.ts.map +1 -0
- package/cjs/react/use-custom-chart-context.js +95 -0
- package/cjs/react/use-custom-chart-context.js.map +1 -0
- package/cjs/react/use-custom-chart-context.spec.d.ts +2 -0
- package/cjs/react/use-custom-chart-context.spec.d.ts.map +1 -0
- package/cjs/react/use-custom-chart-context.spec.js +391 -0
- package/cjs/react/use-custom-chart-context.spec.js.map +1 -0
- package/cjs/react/use-custom-chart-context.util.d.ts +6 -0
- package/cjs/react/use-custom-chart-context.util.d.ts.map +1 -0
- package/cjs/react/use-custom-chart-context.util.js +60 -0
- package/cjs/react/use-custom-chart-context.util.js.map +1 -0
- package/cjs/react/use-custom-chart-types.d.ts +23 -0
- package/cjs/react/use-custom-chart-types.d.ts.map +1 -0
- package/cjs/react/use-custom-chart-types.js +3 -0
- package/cjs/react/use-custom-chart-types.js.map +1 -0
- package/cjs/test/test-utils.d.ts +7 -0
- package/cjs/test/test-utils.d.ts.map +1 -0
- package/cjs/test/test-utils.js +14 -0
- package/cjs/test/test-utils.js.map +1 -0
- package/cjs/types/answer-column.types.d.ts +69 -0
- package/cjs/types/answer-column.types.d.ts.map +1 -0
- package/cjs/types/answer-column.types.js +59 -0
- package/cjs/types/answer-column.types.js.map +1 -0
- package/cjs/types/chart-to-ts-event.types.d.ts +98 -0
- package/cjs/types/chart-to-ts-event.types.d.ts.map +1 -0
- package/cjs/types/chart-to-ts-event.types.js +32 -0
- package/cjs/types/chart-to-ts-event.types.js.map +1 -0
- package/cjs/types/common.types.d.ts +52 -0
- package/cjs/types/common.types.d.ts.map +1 -0
- package/cjs/types/common.types.js +3 -0
- package/cjs/types/common.types.js.map +1 -0
- package/cjs/types/configurator.types.d.ts +15 -0
- package/cjs/types/configurator.types.d.ts.map +1 -0
- package/cjs/types/configurator.types.js +3 -0
- package/cjs/types/configurator.types.js.map +1 -0
- package/cjs/types/ts-to-chart-event.types.d.ts +91 -0
- package/cjs/types/ts-to-chart-event.types.d.ts.map +1 -0
- package/cjs/types/ts-to-chart-event.types.js +18 -0
- package/cjs/types/ts-to-chart-event.types.js.map +1 -0
- package/cjs/types/visual-prop.types.d.ts +73 -0
- package/cjs/types/visual-prop.types.d.ts.map +1 -0
- package/cjs/types/visual-prop.types.js +3 -0
- package/cjs/types/visual-prop.types.js.map +1 -0
- package/dist/ts-chart-sdk.d.ts +151 -23
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/main/custom-chart-context.d.ts +12 -3
- package/lib/main/custom-chart-context.d.ts.map +1 -1
- package/lib/main/custom-chart-context.js +128 -9
- package/lib/main/custom-chart-context.js.map +1 -1
- package/lib/main/custom-chart-context.spec.js +381 -25
- package/lib/main/custom-chart-context.spec.js.map +1 -1
- package/lib/main/post-message-event-bridge.js +1 -1
- package/lib/main/post-message-event-bridge.js.map +1 -1
- package/lib/main/post-message-event-bridge.spec.js +5 -3
- package/lib/main/post-message-event-bridge.spec.js.map +1 -1
- package/lib/react/mocks/custom-chart-context-mock.d.ts +3 -0
- package/lib/react/mocks/custom-chart-context-mock.d.ts.map +1 -0
- package/lib/react/mocks/custom-chart-context-mock.js +94 -0
- package/lib/react/mocks/custom-chart-context-mock.js.map +1 -0
- package/lib/react/use-custom-chart-context.d.ts +4 -0
- package/lib/react/use-custom-chart-context.d.ts.map +1 -0
- package/lib/react/use-custom-chart-context.js +68 -0
- package/lib/react/use-custom-chart-context.js.map +1 -0
- package/lib/react/use-custom-chart-context.spec.d.ts +2 -0
- package/lib/react/use-custom-chart-context.spec.d.ts.map +1 -0
- package/lib/react/use-custom-chart-context.spec.js +363 -0
- package/lib/react/use-custom-chart-context.spec.js.map +1 -0
- package/lib/react/use-custom-chart-context.util.d.ts +6 -0
- package/lib/react/use-custom-chart-context.util.d.ts.map +1 -0
- package/lib/react/use-custom-chart-context.util.js +51 -0
- package/lib/react/use-custom-chart-context.util.js.map +1 -0
- package/lib/react/use-custom-chart-types.d.ts +23 -0
- package/lib/react/use-custom-chart-types.d.ts.map +1 -0
- package/lib/react/use-custom-chart-types.js +2 -0
- package/lib/react/use-custom-chart-types.js.map +1 -0
- package/lib/types/chart-to-ts-event.types.d.ts +63 -13
- package/lib/types/chart-to-ts-event.types.d.ts.map +1 -1
- package/lib/types/chart-to-ts-event.types.js +13 -0
- package/lib/types/chart-to-ts-event.types.js.map +1 -1
- package/lib/types/common.types.d.ts +9 -8
- package/lib/types/common.types.d.ts.map +1 -1
- package/lib/types/ts-to-chart-event.types.d.ts +25 -1
- package/lib/types/ts-to-chart-event.types.d.ts.map +1 -1
- package/lib/types/ts-to-chart-event.types.js +3 -0
- package/lib/types/ts-to-chart-event.types.js.map +1 -1
- package/lib/types/visual-prop.types.d.ts +27 -1
- package/lib/types/visual-prop.types.d.ts.map +1 -1
- package/package.json +9 -3
- package/src/index.ts +1 -0
- package/src/main/custom-chart-context.spec.ts +513 -26
- package/src/main/custom-chart-context.ts +269 -18
- package/src/main/post-message-event-bridge.spec.ts +5 -3
- package/src/main/post-message-event-bridge.ts +3 -3
- package/src/react/mocks/custom-chart-context-mock.ts +114 -0
- package/src/react/use-custom-chart-context.spec.tsx +464 -0
- package/src/react/use-custom-chart-context.tsx +180 -0
- package/src/react/use-custom-chart-context.util.ts +101 -0
- package/src/react/use-custom-chart-types.ts +70 -0
- package/src/types/answer-column.types.ts +5 -5
- package/src/types/chart-to-ts-event.types.ts +233 -31
- package/src/types/common.types.ts +37 -26
- package/src/types/configurator.types.ts +8 -8
- package/src/types/ts-to-chart-event.types.ts +80 -4
- package/src/types/visual-prop.types.ts +148 -11
- package/lib/dist/ts-chart-sdk.d.ts +0 -312
|
@@ -5,12 +5,20 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Copyright: ThoughtSpot Inc. 2023
|
|
7
7
|
*/
|
|
8
|
+
|
|
8
9
|
import _ from 'lodash';
|
|
9
10
|
import {
|
|
11
|
+
AxisMenuActionHandler,
|
|
12
|
+
ChartToTSEvent,
|
|
10
13
|
ChartToTSEventsPayloadMap,
|
|
14
|
+
ContextMenuActionHandler,
|
|
15
|
+
CustomAction,
|
|
11
16
|
ErrorType,
|
|
17
|
+
OpenAxisMenuEventPayload,
|
|
18
|
+
OpenContextMenuEventPayload,
|
|
12
19
|
} from '../types/chart-to-ts-event.types';
|
|
13
20
|
import {
|
|
21
|
+
AppConfig,
|
|
14
22
|
ChartConfig,
|
|
15
23
|
ChartModel,
|
|
16
24
|
ValidationResponse,
|
|
@@ -18,8 +26,10 @@ import {
|
|
|
18
26
|
} from '../types/common.types';
|
|
19
27
|
import { ChartConfigEditorDefinition } from '../types/configurator.types';
|
|
20
28
|
import {
|
|
29
|
+
AxisMenuCustomActionPayload,
|
|
21
30
|
ChartConfigValidateEventPayload,
|
|
22
31
|
ChartModelUpdateEventPayload,
|
|
32
|
+
ContextMenuCustomActionPayload,
|
|
23
33
|
DataUpdateEventPayload,
|
|
24
34
|
GetDataQueryPayload,
|
|
25
35
|
GetDataQueryResponsePayload,
|
|
@@ -63,7 +73,7 @@ export type CustomChartContextProps = {
|
|
|
63
73
|
*/
|
|
64
74
|
renderChart: (ctx: CustomChartContext) => Promise<void>;
|
|
65
75
|
/**
|
|
66
|
-
*
|
|
76
|
+
* Required to validate the current chart configuration
|
|
67
77
|
* that chart user has updated on the chart config editor
|
|
68
78
|
*
|
|
69
79
|
* @version SDK: 0.1 | ThoughtSpot:
|
|
@@ -77,7 +87,7 @@ export type CustomChartContextProps = {
|
|
|
77
87
|
) => ValidationResponse;
|
|
78
88
|
|
|
79
89
|
/**
|
|
80
|
-
*
|
|
90
|
+
* Required to validate the custom visual props that
|
|
81
91
|
* the chart user has updated on the chart settings editor.
|
|
82
92
|
*
|
|
83
93
|
* @param updatedVisualProps
|
|
@@ -103,6 +113,8 @@ export type CustomChartContextProps = {
|
|
|
103
113
|
* on the TS app. If not provided, visual properties will not be configurable in
|
|
104
114
|
* editor
|
|
105
115
|
*
|
|
116
|
+
* @param chartModel
|
|
117
|
+
* @returns {@link VisualPropEditorDefinition}
|
|
106
118
|
* @version SDK: 0.1 | ThoughtSpot:
|
|
107
119
|
*/
|
|
108
120
|
visualPropEditorDefinition?: VisualPropEditorDefinition;
|
|
@@ -115,13 +127,12 @@ const DEFAULT_CHART_CONTEXT_PROPS: Partial<CustomChartContextProps> = {
|
|
|
115
127
|
validateConfig: () => ({ isValid: true }),
|
|
116
128
|
validateVisualProps: () => ({ isValid: true }),
|
|
117
129
|
chartConfigEditorDefinition: undefined,
|
|
118
|
-
visualPropEditorDefinition: undefined,
|
|
119
130
|
};
|
|
120
131
|
|
|
121
132
|
export class CustomChartContext {
|
|
122
133
|
/**
|
|
123
|
-
*
|
|
124
|
-
* This is used to differentiate between multiple chart
|
|
134
|
+
* ID to map to the parent chart component.
|
|
135
|
+
* This is used to differentiate between multiple chart components rendered on the
|
|
125
136
|
* parent app Example: liveboards with multiple charts
|
|
126
137
|
*
|
|
127
138
|
* @hidden
|
|
@@ -147,6 +158,13 @@ export class CustomChartContext {
|
|
|
147
158
|
*/
|
|
148
159
|
private chartModel: ChartModel = {} as any;
|
|
149
160
|
|
|
161
|
+
/**
|
|
162
|
+
* App Config object. This contains the app state like locale and timezones.
|
|
163
|
+
*
|
|
164
|
+
* @version SDK: 0.1 | ThoughtSpot:
|
|
165
|
+
*/
|
|
166
|
+
private appConfig: AppConfig = {};
|
|
167
|
+
|
|
150
168
|
/**
|
|
151
169
|
* Chart Props Object to define the workflow of the application
|
|
152
170
|
*
|
|
@@ -183,6 +201,22 @@ export class CustomChartContext {
|
|
|
183
201
|
*/
|
|
184
202
|
private triggerInitResolve: () => void = _.noop;
|
|
185
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Stores the callbacks of context menu custom action based on custom action id
|
|
206
|
+
*
|
|
207
|
+
* @returns {@link ContextMenuActionHandler}
|
|
208
|
+
* @version SDK: 0.1 | ThoughtSpot:
|
|
209
|
+
*/
|
|
210
|
+
private contextMenuActionHandler: ContextMenuActionHandler = {};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Stores the callbacks of axis menu custom action based on custom action id
|
|
214
|
+
*
|
|
215
|
+
* @returns {@link AxisMenuActionHandler}
|
|
216
|
+
* @version SDK: 0.1 | ThoughtSpot:
|
|
217
|
+
*/
|
|
218
|
+
private axisMenuActionHandler: AxisMenuActionHandler = {};
|
|
219
|
+
|
|
186
220
|
/**
|
|
187
221
|
* Constructor to only accept context props as payload
|
|
188
222
|
*
|
|
@@ -194,7 +228,7 @@ export class CustomChartContext {
|
|
|
194
228
|
...chartContextProps,
|
|
195
229
|
};
|
|
196
230
|
this.registerEventProcessor();
|
|
197
|
-
this.hasInitializedPromise = new Promise((resolve) => {
|
|
231
|
+
this.hasInitializedPromise = new Promise((resolve, reject) => {
|
|
198
232
|
this.triggerInitResolve = resolve;
|
|
199
233
|
});
|
|
200
234
|
}
|
|
@@ -231,6 +265,21 @@ export class CustomChartContext {
|
|
|
231
265
|
this.eventListeners[eventType].push(callbackFn);
|
|
232
266
|
}
|
|
233
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Removes specific event listeners on the chart context.
|
|
270
|
+
*
|
|
271
|
+
* @param {T} eventType
|
|
272
|
+
* @returns void
|
|
273
|
+
*/
|
|
274
|
+
public off<T extends keyof TSToChartEventsPayloadMap>(eventType: T): void {
|
|
275
|
+
if (_.isNil(this.eventListeners[eventType])) {
|
|
276
|
+
console.log('No event listener found to remove');
|
|
277
|
+
this.eventListeners[eventType] = [];
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
this.eventListeners[eventType].splice(0, 1);
|
|
281
|
+
}
|
|
282
|
+
|
|
234
283
|
/**
|
|
235
284
|
* Add internal event listeners on the chart context with the required callback.
|
|
236
285
|
*
|
|
@@ -267,6 +316,107 @@ export class CustomChartContext {
|
|
|
267
316
|
*/
|
|
268
317
|
public getChartModel = (): ChartModel => this.chartModel;
|
|
269
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Getter for the chart model object
|
|
321
|
+
*
|
|
322
|
+
* @version SDK: 0.1 | ThoughtSpot:
|
|
323
|
+
*/
|
|
324
|
+
public getAppConfig = (): AppConfig => this.appConfig;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Function to store the context menu custom action callback mapped with action id
|
|
328
|
+
* @param {[OpenContextMenuEventPayload]} eventPayload Event payload bound
|
|
329
|
+
* to the type of the event
|
|
330
|
+
* @returns payload
|
|
331
|
+
*/
|
|
332
|
+
public contextMenuCustomActionPreProcessor(
|
|
333
|
+
eventPayload: [OpenContextMenuEventPayload],
|
|
334
|
+
): [OpenContextMenuEventPayload] {
|
|
335
|
+
// clear out the stored custom events callback for context menu
|
|
336
|
+
this.contextMenuActionHandler = {};
|
|
337
|
+
if (_.isEmpty(eventPayload?.[0]?.customActions)) {
|
|
338
|
+
return eventPayload;
|
|
339
|
+
}
|
|
340
|
+
eventPayload?.[0]?.customActions?.forEach((action: CustomAction) => {
|
|
341
|
+
this.contextMenuActionHandler[action.id] = action.onClick;
|
|
342
|
+
});
|
|
343
|
+
const processedCustomActions = eventPayload[0]?.customActions?.map(
|
|
344
|
+
(action: CustomAction) => {
|
|
345
|
+
return {
|
|
346
|
+
id: action.id,
|
|
347
|
+
label: action.label,
|
|
348
|
+
icon: action.icon,
|
|
349
|
+
};
|
|
350
|
+
},
|
|
351
|
+
);
|
|
352
|
+
const processedPayload: [OpenContextMenuEventPayload] = [
|
|
353
|
+
{
|
|
354
|
+
...eventPayload[0],
|
|
355
|
+
customActions: processedCustomActions as CustomAction[],
|
|
356
|
+
},
|
|
357
|
+
];
|
|
358
|
+
return processedPayload;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Function to store the axis menu custom action callback mapped with action id
|
|
363
|
+
* @param {[OpenAxisMenuEventPayload]} eventPayload Event payload bound
|
|
364
|
+
* to the type of the event
|
|
365
|
+
* @returns payload
|
|
366
|
+
*/
|
|
367
|
+
public axisMenuCustomActionPreProcessor(
|
|
368
|
+
eventPayload: [OpenAxisMenuEventPayload],
|
|
369
|
+
): [OpenAxisMenuEventPayload] {
|
|
370
|
+
// clear out the stored custom events callback for axis menu
|
|
371
|
+
this.axisMenuActionHandler = {};
|
|
372
|
+
if (_.isEmpty(eventPayload?.[0]?.customActions)) {
|
|
373
|
+
return eventPayload;
|
|
374
|
+
}
|
|
375
|
+
eventPayload[0].customActions?.forEach((action: CustomAction) => {
|
|
376
|
+
this.axisMenuActionHandler[action.id] = action.onClick;
|
|
377
|
+
});
|
|
378
|
+
const processedCustomActions = eventPayload?.[0].customActions?.map(
|
|
379
|
+
(action: CustomAction) => {
|
|
380
|
+
return {
|
|
381
|
+
id: action.id,
|
|
382
|
+
label: action.label,
|
|
383
|
+
icon: action.icon,
|
|
384
|
+
};
|
|
385
|
+
},
|
|
386
|
+
);
|
|
387
|
+
const processedPayload: [OpenAxisMenuEventPayload] = [
|
|
388
|
+
{
|
|
389
|
+
...eventPayload[0],
|
|
390
|
+
customActions: processedCustomActions as CustomAction[],
|
|
391
|
+
},
|
|
392
|
+
];
|
|
393
|
+
return processedPayload;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Function to process the event payload based on event type
|
|
398
|
+
* @param {ChartToTSEventsPayloadMap[T]} eventPayload Event payload bound
|
|
399
|
+
* to the type of the event
|
|
400
|
+
* @returns payload
|
|
401
|
+
*/
|
|
402
|
+
private eventPayloadPreProcessor<T extends keyof ChartToTSEventsPayloadMap>(
|
|
403
|
+
eventType: T,
|
|
404
|
+
eventPayload: ChartToTSEventsPayloadMap[T],
|
|
405
|
+
): ChartToTSEventsPayloadMap[T] {
|
|
406
|
+
switch (eventType) {
|
|
407
|
+
case ChartToTSEvent.OpenContextMenu:
|
|
408
|
+
return this.contextMenuCustomActionPreProcessor(
|
|
409
|
+
eventPayload as [OpenContextMenuEventPayload],
|
|
410
|
+
) as ChartToTSEventsPayloadMap[T];
|
|
411
|
+
case ChartToTSEvent.OpenAxisMenu:
|
|
412
|
+
return this.axisMenuCustomActionPreProcessor(
|
|
413
|
+
eventPayload as [OpenAxisMenuEventPayload],
|
|
414
|
+
) as ChartToTSEventsPayloadMap[T];
|
|
415
|
+
default:
|
|
416
|
+
return eventPayload;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
270
420
|
/**
|
|
271
421
|
* Function to emit Chart to TS Events to the TS application.
|
|
272
422
|
|
|
@@ -277,18 +427,22 @@ export class CustomChartContext {
|
|
|
277
427
|
*/
|
|
278
428
|
public emitEvent<T extends keyof ChartToTSEventsPayloadMap>(
|
|
279
429
|
eventType: T,
|
|
280
|
-
eventPayload: ChartToTSEventsPayloadMap[T]
|
|
430
|
+
...eventPayload: ChartToTSEventsPayloadMap[T]
|
|
281
431
|
): Promise<any> {
|
|
282
432
|
if (!isInitialized) {
|
|
283
433
|
console.log(
|
|
284
434
|
'Chart Context: not initialized the context, something went wrong',
|
|
285
435
|
);
|
|
286
|
-
return Promise.reject();
|
|
436
|
+
return Promise.reject(new Error('Context not initialized'));
|
|
287
437
|
}
|
|
438
|
+
const processedPayload = this.eventPayloadPreProcessor(
|
|
439
|
+
eventType,
|
|
440
|
+
eventPayload,
|
|
441
|
+
);
|
|
288
442
|
return PostMessageEventBridge.postMessageToHostApp(
|
|
289
443
|
this.componentId,
|
|
290
444
|
this.hostUrl,
|
|
291
|
-
|
|
445
|
+
processedPayload?.[0] ?? null,
|
|
292
446
|
eventType,
|
|
293
447
|
);
|
|
294
448
|
}
|
|
@@ -357,6 +511,13 @@ export class CustomChartContext {
|
|
|
357
511
|
this.initializeContext(payload),
|
|
358
512
|
);
|
|
359
513
|
|
|
514
|
+
/**
|
|
515
|
+
* This event is triggered when the TS app initialization is complete.
|
|
516
|
+
*/
|
|
517
|
+
this.onInternal(TSToChartEvent.InitializeComplete, () =>
|
|
518
|
+
this.initializationComplete(),
|
|
519
|
+
);
|
|
520
|
+
|
|
360
521
|
/**
|
|
361
522
|
* This event is triggered when the TS app asks for validating the updated visual
|
|
362
523
|
* props If {validateVisualProps} is not defined, default is always returned as
|
|
@@ -419,10 +580,98 @@ export class CustomChartContext {
|
|
|
419
580
|
/**
|
|
420
581
|
* This event is triggered when the TS app re-renders the chart
|
|
421
582
|
*/
|
|
422
|
-
this.onInternal(TSToChartEvent.TriggerRenderChart,
|
|
423
|
-
|
|
583
|
+
this.onInternal(TSToChartEvent.TriggerRenderChart, () => {
|
|
584
|
+
this.chartContextProps.renderChart(this);
|
|
424
585
|
});
|
|
425
586
|
|
|
587
|
+
/**
|
|
588
|
+
* This event is triggered when the custom context action is triggered from TS app
|
|
589
|
+
*/
|
|
590
|
+
this.onInternal(
|
|
591
|
+
TSToChartEvent.ContextMenuActionClick,
|
|
592
|
+
(
|
|
593
|
+
payload: ContextMenuCustomActionPayload,
|
|
594
|
+
): {
|
|
595
|
+
isValid: boolean;
|
|
596
|
+
error?: unknown;
|
|
597
|
+
} => {
|
|
598
|
+
try {
|
|
599
|
+
const {
|
|
600
|
+
id: customActionCallback,
|
|
601
|
+
clickedPoint,
|
|
602
|
+
selectedPoints,
|
|
603
|
+
event,
|
|
604
|
+
} = payload.customAction;
|
|
605
|
+
const customActionCallbackArgs = {
|
|
606
|
+
id: customActionCallback,
|
|
607
|
+
clickedPoint,
|
|
608
|
+
selectedPoints,
|
|
609
|
+
event,
|
|
610
|
+
};
|
|
611
|
+
this.contextMenuActionHandler[customActionCallback](
|
|
612
|
+
customActionCallbackArgs,
|
|
613
|
+
);
|
|
614
|
+
return {
|
|
615
|
+
isValid: true,
|
|
616
|
+
};
|
|
617
|
+
} catch (error: unknown) {
|
|
618
|
+
console.log(
|
|
619
|
+
'ContextMenuCustomAction: payload recieved:',
|
|
620
|
+
payload,
|
|
621
|
+
'CustomActionCallbackStore:',
|
|
622
|
+
this.axisMenuActionHandler,
|
|
623
|
+
);
|
|
624
|
+
return {
|
|
625
|
+
isValid: false,
|
|
626
|
+
error,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
);
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* This event is triggered when the custom axis action is triggered from TS app
|
|
634
|
+
*/
|
|
635
|
+
this.onInternal(
|
|
636
|
+
TSToChartEvent.AxisMenuActionClick,
|
|
637
|
+
(
|
|
638
|
+
payload: AxisMenuCustomActionPayload,
|
|
639
|
+
): {
|
|
640
|
+
isValid: boolean;
|
|
641
|
+
error?: unknown;
|
|
642
|
+
} => {
|
|
643
|
+
try {
|
|
644
|
+
const {
|
|
645
|
+
id: customActionCallback,
|
|
646
|
+
columnIds,
|
|
647
|
+
event,
|
|
648
|
+
} = payload.customAction;
|
|
649
|
+
const customActionCallbackArgs = {
|
|
650
|
+
id: customActionCallback,
|
|
651
|
+
columnIds,
|
|
652
|
+
event,
|
|
653
|
+
};
|
|
654
|
+
this.axisMenuActionHandler[customActionCallback](
|
|
655
|
+
customActionCallbackArgs,
|
|
656
|
+
);
|
|
657
|
+
return {
|
|
658
|
+
isValid: true,
|
|
659
|
+
};
|
|
660
|
+
} catch (error: unknown) {
|
|
661
|
+
console.log(
|
|
662
|
+
'AxisMenuCustomAction: payload recieved:',
|
|
663
|
+
payload,
|
|
664
|
+
'CustomActionCallbackStore:',
|
|
665
|
+
this.axisMenuActionHandler,
|
|
666
|
+
);
|
|
667
|
+
return {
|
|
668
|
+
isValid: false,
|
|
669
|
+
error,
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
);
|
|
674
|
+
|
|
426
675
|
// Register External Events
|
|
427
676
|
// These events are readable by the developer
|
|
428
677
|
|
|
@@ -481,8 +730,8 @@ export class CustomChartContext {
|
|
|
481
730
|
};
|
|
482
731
|
|
|
483
732
|
/**
|
|
484
|
-
*
|
|
485
|
-
* the
|
|
733
|
+
* Private function is going to initialize the flow from TS app and send back
|
|
734
|
+
* the configuration back to ts app to complete the handshake.
|
|
486
735
|
*
|
|
487
736
|
* @param {InitializeEventPayload} payload
|
|
488
737
|
* @returns InitializeEventResponsePayload
|
|
@@ -493,14 +742,17 @@ export class CustomChartContext {
|
|
|
493
742
|
this.componentId = payload.componentId;
|
|
494
743
|
this.hostUrl = payload.hostUrl;
|
|
495
744
|
this.chartModel = payload.chartModel;
|
|
745
|
+
this.appConfig = payload.appConfig ?? {};
|
|
496
746
|
|
|
747
|
+
return this.publishChartContextPropsToHost();
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
private initializationComplete = (): void => {
|
|
497
751
|
// context is now initialized
|
|
498
752
|
isInitialized = true;
|
|
499
753
|
|
|
500
754
|
// TODO: following can be done behind a promise
|
|
501
755
|
this.triggerInitResolve();
|
|
502
|
-
|
|
503
|
-
return this.publishChartContextPropsToHost();
|
|
504
756
|
};
|
|
505
757
|
|
|
506
758
|
private publishChartContextPropsToHost =
|
|
@@ -524,7 +776,6 @@ export class CustomChartContext {
|
|
|
524
776
|
this.chartModel,
|
|
525
777
|
);
|
|
526
778
|
}
|
|
527
|
-
|
|
528
779
|
return {
|
|
529
780
|
isConfigValid: isValid,
|
|
530
781
|
defaultChartConfig,
|
|
@@ -547,8 +798,8 @@ export class CustomChartContext {
|
|
|
547
798
|
let response;
|
|
548
799
|
if (_.isArray(this.eventListeners[event.data.eventType])) {
|
|
549
800
|
this.eventListeners[event.data.eventType].forEach((callback) => {
|
|
550
|
-
// this is a problem today if we have
|
|
551
|
-
// registered. only the last
|
|
801
|
+
// this is a problem today if we have multiple callbacks
|
|
802
|
+
// registered. only the last response will be sent back to the
|
|
552
803
|
// server
|
|
553
804
|
response = callback(payload);
|
|
554
805
|
});
|
|
@@ -13,7 +13,7 @@ describe('postMessageToHostApp', () => {
|
|
|
13
13
|
jest.resetAllMocks();
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
test('should resolve the promise with
|
|
16
|
+
test('should resolve the promise with data object when successful', async () => {
|
|
17
17
|
// Mock the necessary variables and functions
|
|
18
18
|
const componentId = '123';
|
|
19
19
|
const hostUrl = 'https://example.com';
|
|
@@ -39,7 +39,9 @@ describe('postMessageToHostApp', () => {
|
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
// Simulate a successful response
|
|
42
|
-
const response = {
|
|
42
|
+
const response = {
|
|
43
|
+
data: { hasError: false, randomData: 'randomString' },
|
|
44
|
+
};
|
|
43
45
|
if (_.isFunction(channel.port1.onmessage)) {
|
|
44
46
|
(channel.port1.onmessage as any)(response);
|
|
45
47
|
} else {
|
|
@@ -48,7 +50,7 @@ describe('postMessageToHostApp', () => {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
// Wait for the promise to resolve
|
|
51
|
-
await expect(promise).resolves.
|
|
53
|
+
await expect(promise).resolves.toEqual(response.data);
|
|
52
54
|
|
|
53
55
|
// Verify that the postMessage function was called with the correct
|
|
54
56
|
// arguments
|
|
@@ -3,7 +3,7 @@ import { ChartToTSEvent } from '../types/chart-to-ts-event.types';
|
|
|
3
3
|
const TIMEOUT_THRESHOLD = 30000; // 30sec
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* method to listen to messages using postMessage from parent.
|
|
6
|
+
* method to listen to messages using postMessage from the parent.
|
|
7
7
|
*
|
|
8
8
|
* @param {any} handleMessageEvent
|
|
9
9
|
*/
|
|
@@ -23,7 +23,7 @@ const destroy = (handleMessageEvent: any) => {
|
|
|
23
23
|
/**
|
|
24
24
|
* @param {string} componentId This is required to send the event to the
|
|
25
25
|
* right chart component in case of multiple components
|
|
26
|
-
* @param {string} hostUrl The host application
|
|
26
|
+
* @param {string} hostUrl The host application URL
|
|
27
27
|
* @param {any} eventPayload payload for the event
|
|
28
28
|
* @param {ChartToTSEvent} eventType type of the event
|
|
29
29
|
* @returns Promise
|
|
@@ -44,7 +44,7 @@ const postMessageToHostApp = (
|
|
|
44
44
|
reject(error);
|
|
45
45
|
} else {
|
|
46
46
|
console.log('ChartContext: message success:', res.data);
|
|
47
|
-
resolve(
|
|
47
|
+
resolve(res.data);
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { CustomChartContextProps } from '../../main/custom-chart-context';
|
|
3
|
+
import { ColumnType } from '../../types/answer-column.types';
|
|
4
|
+
import { ChartConfig, ChartModel } from '../../types/common.types';
|
|
5
|
+
import { Query } from '../../types/ts-to-chart-event.types';
|
|
6
|
+
|
|
7
|
+
export const contextChartProps: CustomChartContextProps = {
|
|
8
|
+
getDefaultChartConfig: (chartModel: ChartModel): ChartConfig[] => {
|
|
9
|
+
const cols = chartModel.columns;
|
|
10
|
+
|
|
11
|
+
const measureColumns = _.filter(
|
|
12
|
+
cols,
|
|
13
|
+
(col) => col.type === ColumnType.MEASURE,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const attributeColumns = _.filter(
|
|
17
|
+
cols,
|
|
18
|
+
(col) => col.type === ColumnType.ATTRIBUTE,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const axisConfig: ChartConfig = {
|
|
22
|
+
key: 'column',
|
|
23
|
+
dimensions: [
|
|
24
|
+
{
|
|
25
|
+
key: 'x',
|
|
26
|
+
columns: [attributeColumns[0]],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: 'y',
|
|
30
|
+
columns: measureColumns.slice(0, 2),
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
return [axisConfig];
|
|
35
|
+
},
|
|
36
|
+
getQueriesFromChartConfig: (chartConfig: ChartConfig[]): Array<Query> => {
|
|
37
|
+
const queries = chartConfig.map(
|
|
38
|
+
(config: ChartConfig): Query =>
|
|
39
|
+
_.reduce(
|
|
40
|
+
config.dimensions,
|
|
41
|
+
(acc: Query, dimension) => ({
|
|
42
|
+
queryColumns: [
|
|
43
|
+
...acc.queryColumns,
|
|
44
|
+
...dimension.columns,
|
|
45
|
+
],
|
|
46
|
+
}),
|
|
47
|
+
{
|
|
48
|
+
queryColumns: [],
|
|
49
|
+
} as Query,
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
return queries;
|
|
53
|
+
},
|
|
54
|
+
chartConfigEditorDefinition: [
|
|
55
|
+
{
|
|
56
|
+
key: 'column',
|
|
57
|
+
label: 'Custom Column',
|
|
58
|
+
descriptionText:
|
|
59
|
+
'X Axis can only have attributes, Y Axis can only have measures, Color can only have attributes. ' +
|
|
60
|
+
'Should have just 1 column in Y axis with colors columns.',
|
|
61
|
+
columnSections: [
|
|
62
|
+
{
|
|
63
|
+
key: 'x',
|
|
64
|
+
label: 'Custom X Axis',
|
|
65
|
+
allowAttributeColumns: true,
|
|
66
|
+
allowMeasureColumns: false,
|
|
67
|
+
allowTimeSeriesColumns: true,
|
|
68
|
+
maxColumnCount: 1,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: 'y',
|
|
72
|
+
label: 'Custom Y Axis',
|
|
73
|
+
allowAttributeColumns: false,
|
|
74
|
+
allowMeasureColumns: true,
|
|
75
|
+
allowTimeSeriesColumns: false,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
visualPropEditorDefinition: {
|
|
81
|
+
elements: [
|
|
82
|
+
{
|
|
83
|
+
key: 'color',
|
|
84
|
+
type: 'radio',
|
|
85
|
+
defaultValue: 'red',
|
|
86
|
+
values: ['red', 'green', 'yellow'],
|
|
87
|
+
label: 'Colors',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
type: 'section',
|
|
91
|
+
key: 'accordion',
|
|
92
|
+
label: 'Accordion',
|
|
93
|
+
children: [
|
|
94
|
+
{
|
|
95
|
+
key: 'Color2',
|
|
96
|
+
type: 'radio',
|
|
97
|
+
defaultValue: 'blue',
|
|
98
|
+
values: ['blue', 'white', 'red'],
|
|
99
|
+
label: 'Color2',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: 'datalabels',
|
|
103
|
+
type: 'toggle',
|
|
104
|
+
defaultValue: false,
|
|
105
|
+
label: 'Data Labels',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
renderChart: (cx) => {
|
|
112
|
+
return Promise.resolve();
|
|
113
|
+
},
|
|
114
|
+
};
|