@thoughtspot/ts-chart-sdk 0.0.2-alpha.1 → 0.0.2-alpha.11
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 +122 -50
- package/dist/ts-chart-sdk.d.ts +730 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/main/custom-chart-context.d.ts +9 -4
- package/lib/main/custom-chart-context.d.ts.map +1 -1
- package/lib/main/custom-chart-context.js +46 -3
- package/lib/main/custom-chart-context.js.map +1 -1
- package/lib/main/custom-chart-context.spec.js +164 -3
- package/lib/main/custom-chart-context.spec.js.map +1 -1
- package/lib/main/post-message-event-bridge.js +2 -2
- package/lib/main/post-message-event-bridge.js.map +1 -1
- package/lib/react/use-custom-chart-context.spec.js +54 -2
- package/lib/react/use-custom-chart-context.spec.js.map +1 -1
- package/lib/test/test-conditional-formatting-utils.d.ts +5 -0
- package/lib/test/test-conditional-formatting-utils.d.ts.map +1 -0
- package/lib/test/test-conditional-formatting-utils.js +43 -0
- package/lib/test/test-conditional-formatting-utils.js.map +1 -0
- package/lib/types/answer-column.types.d.ts +54 -1
- package/lib/types/answer-column.types.d.ts.map +1 -1
- package/lib/types/answer-column.types.js +47 -0
- package/lib/types/answer-column.types.js.map +1 -1
- package/lib/types/common.types.d.ts +50 -4
- package/lib/types/common.types.d.ts.map +1 -1
- package/lib/types/common.types.js +15 -1
- package/lib/types/common.types.js.map +1 -1
- package/lib/types/conditional-formatting.types.d.ts +155 -0
- package/lib/types/conditional-formatting.types.d.ts.map +1 -0
- package/lib/types/conditional-formatting.types.js +60 -0
- package/lib/types/conditional-formatting.types.js.map +1 -0
- package/lib/types/configurator.types.d.ts +5 -0
- package/lib/types/configurator.types.d.ts.map +1 -1
- package/lib/types/ts-to-chart-event.types.d.ts.map +1 -1
- package/lib/types/visual-prop.types.d.ts +3 -0
- package/lib/types/visual-prop.types.d.ts.map +1 -1
- package/lib/utils/conditional-formatting/conditional-formatting.d.ts +10 -0
- package/lib/utils/conditional-formatting/conditional-formatting.d.ts.map +1 -0
- package/lib/utils/conditional-formatting/conditional-formatting.js +103 -0
- package/lib/utils/conditional-formatting/conditional-formatting.js.map +1 -0
- package/lib/utils/conditional-formatting/conditional-formatting.spec.d.ts +2 -0
- package/lib/utils/conditional-formatting/conditional-formatting.spec.d.ts.map +1 -0
- package/lib/utils/conditional-formatting/conditional-formatting.spec.js +142 -0
- package/lib/utils/conditional-formatting/conditional-formatting.spec.js.map +1 -0
- package/lib/utils/date-formatting.d.ts +19 -0
- package/lib/utils/date-formatting.d.ts.map +1 -0
- package/lib/utils/date-formatting.js +56 -0
- package/lib/utils/date-formatting.js.map +1 -0
- package/lib/utils/date-formatting.spec.d.ts +2 -0
- package/lib/utils/date-formatting.spec.d.ts.map +1 -0
- package/lib/utils/date-formatting.spec.js +124 -0
- package/lib/utils/date-formatting.spec.js.map +1 -0
- package/package.json +6 -4
- package/src/index.ts +3 -0
- package/src/main/custom-chart-context.spec.ts +194 -5
- package/src/main/custom-chart-context.ts +116 -9
- package/src/main/post-message-event-bridge.ts +2 -2
- package/src/react/use-custom-chart-context.spec.tsx +65 -2
- package/src/test/test-conditional-formatting-utils.ts +95 -0
- package/src/types/answer-column.types.ts +98 -0
- package/src/types/common.types.ts +81 -9
- package/src/types/conditional-formatting.types.ts +172 -0
- package/src/types/configurator.types.ts +21 -0
- package/src/types/ts-to-chart-event.types.ts +2 -1
- package/src/types/visual-prop.types.ts +7 -0
- package/src/utils/conditional-formatting/conditional-formatting.spec.ts +469 -0
- package/src/utils/conditional-formatting/conditional-formatting.ts +229 -0
- package/src/utils/date-formatting.spec.ts +168 -0
- package/src/utils/date-formatting.ts +109 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thoughtspot/ts-chart-sdk",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.2-alpha.
|
|
4
|
+
"version": "0.0.2-alpha.11",
|
|
5
5
|
"module": "lib/index",
|
|
6
6
|
"main": "lib/index",
|
|
7
7
|
"types": "lib/index",
|
|
@@ -23,26 +23,27 @@
|
|
|
23
23
|
"dev:bar": "vite serve example/custom-bar-chart --port 3000",
|
|
24
24
|
"about:bundle-dts": "echo '===== add ts types bundle in dist ====='",
|
|
25
25
|
"bundle-dts": "npx dts-bundle --name ../dist/ts-chart-sdk --main lib/index.d.ts --outputAsModuleFolder=true",
|
|
26
|
-
"
|
|
26
|
+
"prepublishOnly": "npm run ci; npm run build; npm run bundle-dts;",
|
|
27
27
|
"about:publish-dev": "echo '===== patch dev workflow ====='",
|
|
28
28
|
"patch-dev": "npm version prerelease --no-git-tag-version",
|
|
29
29
|
"publish-dev": "npm publish --tag dev --access public",
|
|
30
30
|
"about:publish-prod": "echo '===== patch prod workflow ====='",
|
|
31
31
|
"patch-prod": "npm version prepatch --no-git-tag-version",
|
|
32
|
-
"publish-prod": "npm publish --access public"
|
|
32
|
+
"publish-prod": "npm publish --tag latest --access public"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@testing-library/react": "12.1.5",
|
|
36
36
|
"@testing-library/react-hooks": "^7.0.2",
|
|
37
37
|
"@types/jest": "^27.0.3",
|
|
38
38
|
"@types/lodash": "4.14.175",
|
|
39
|
+
"@types/luxon": "^3.4.2",
|
|
39
40
|
"@types/node": "18.16.3",
|
|
40
41
|
"@types/react": "^17.0.2",
|
|
41
42
|
"@types/react-dom": "^17.0.11",
|
|
42
43
|
"@typescript-eslint/eslint-plugin": "^5.59.5",
|
|
43
44
|
"@typescript-eslint/parser": "^5.59.5",
|
|
44
45
|
"dts-bundle": "^0.7.3",
|
|
45
|
-
"eslint": "
|
|
46
|
+
"eslint": "^8.56.0",
|
|
46
47
|
"eslint-config-airbnb-base": "15.0.0",
|
|
47
48
|
"eslint-config-prettier": "^6.9.0",
|
|
48
49
|
"eslint-import-resolver-typescript": "^2.0.0",
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
},
|
|
75
76
|
"dependencies": {
|
|
76
77
|
"lodash": "^4.17.21",
|
|
78
|
+
"luxon": "^3.4.4",
|
|
77
79
|
"promise-postmessage": "^3.5.0",
|
|
78
80
|
"react": "^17.0.2",
|
|
79
81
|
"react-dom": "^17.0.2"
|
package/src/index.ts
CHANGED
|
@@ -6,3 +6,6 @@ export * from './types/chart-to-ts-event.types';
|
|
|
6
6
|
export * from './types/ts-to-chart-event.types';
|
|
7
7
|
export * from './main/custom-chart-context';
|
|
8
8
|
export * from './react/use-custom-chart-context';
|
|
9
|
+
export * from './types/conditional-formatting.types';
|
|
10
|
+
export * from './utils/date-formatting';
|
|
11
|
+
export * from './utils/conditional-formatting/conditional-formatting';
|
|
@@ -107,28 +107,100 @@ describe('CustomChartContext', () => {
|
|
|
107
107
|
allowedConfigurations: {
|
|
108
108
|
allowColumnNumberFormatting: false,
|
|
109
109
|
allowColumnConditionalFormatting: false,
|
|
110
|
+
allowMeasureNamesAndValues: false,
|
|
110
111
|
},
|
|
111
112
|
});
|
|
112
113
|
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
113
114
|
});
|
|
114
115
|
|
|
115
|
-
test('
|
|
116
|
+
test('should return responseMessage as empty instead of undefine', async () => {
|
|
117
|
+
expect(mockInitMessage).toHaveBeenCalled();
|
|
118
|
+
|
|
119
|
+
const initResp = await eventProcessor({
|
|
120
|
+
payload: {},
|
|
121
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
122
|
+
});
|
|
123
|
+
expect(initResp).toEqual({});
|
|
124
|
+
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('type check string for visualProps on initialize payload should not throw an error.', async () => {
|
|
128
|
+
expect(mockInitMessage).toHaveBeenCalled();
|
|
129
|
+
|
|
116
130
|
// Call the initialize function and wait for it to resolve
|
|
117
131
|
const promise = customChartContext.initialize();
|
|
118
132
|
|
|
119
133
|
// Check that the hasInitializedPromise has resolved
|
|
120
|
-
|
|
121
|
-
|
|
134
|
+
|
|
135
|
+
const mockInitializeContextPayloadWithVisualProps = {
|
|
136
|
+
...mockInitializeContextPayload,
|
|
137
|
+
chartModel: {
|
|
138
|
+
...mockInitializeContextPayload.chartModel,
|
|
139
|
+
visualProps: 'visualPropStringPayload',
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
await eventProcessor({
|
|
144
|
+
payload: mockInitializeContextPayloadWithVisualProps,
|
|
122
145
|
eventType: TSToChartEvent.Initialize,
|
|
123
146
|
});
|
|
124
|
-
|
|
125
147
|
eventProcessor({
|
|
126
148
|
payload: {},
|
|
127
149
|
eventType: TSToChartEvent.InitializeComplete,
|
|
128
150
|
});
|
|
151
|
+
await expect(promise).resolves.toBeUndefined();
|
|
152
|
+
const chartModel = customChartContext.getChartModel();
|
|
153
|
+
expect(typeof chartModel.visualProps).toEqual('string');
|
|
154
|
+
expect(chartModel.visualProps).toEqual('visualPropStringPayload');
|
|
155
|
+
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('type check object for visualProps on initialize payload should not throw an error.', async () => {
|
|
159
|
+
expect(mockInitMessage).toHaveBeenCalled();
|
|
160
|
+
|
|
161
|
+
// Call the initialize function and wait for it to resolve
|
|
162
|
+
const promise = customChartContext.initialize();
|
|
163
|
+
|
|
164
|
+
// Check that the hasInitializedPromise has resolved
|
|
129
165
|
|
|
166
|
+
const mockInitializeContextPayloadWithVisualProps = {
|
|
167
|
+
...mockInitializeContextPayload,
|
|
168
|
+
chartModel: {
|
|
169
|
+
...mockInitializeContextPayload.chartModel,
|
|
170
|
+
visualProps: {
|
|
171
|
+
data: 'sample data',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
await eventProcessor({
|
|
177
|
+
payload: mockInitializeContextPayloadWithVisualProps,
|
|
178
|
+
eventType: TSToChartEvent.Initialize,
|
|
179
|
+
});
|
|
180
|
+
eventProcessor({
|
|
181
|
+
payload: {},
|
|
182
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
183
|
+
});
|
|
130
184
|
await expect(promise).resolves.toBeUndefined();
|
|
185
|
+
const chartModel = customChartContext.getChartModel();
|
|
186
|
+
expect(typeof chartModel.visualProps).toEqual('object');
|
|
187
|
+
expect(chartModel.visualProps).toEqual({
|
|
188
|
+
data: 'sample data',
|
|
189
|
+
});
|
|
190
|
+
expect(mockPostMessageToHost).not.toHaveBeenCalled();
|
|
191
|
+
});
|
|
131
192
|
|
|
193
|
+
test('multiple intializations should throw an error', async () => {
|
|
194
|
+
// Call the initialize function and wait for it to resolve
|
|
195
|
+
getChartContext({
|
|
196
|
+
getDefaultChartConfig,
|
|
197
|
+
getQueriesFromChartConfig,
|
|
198
|
+
renderChart,
|
|
199
|
+
});
|
|
200
|
+
eventProcessor({
|
|
201
|
+
payload: {},
|
|
202
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
203
|
+
});
|
|
132
204
|
let error;
|
|
133
205
|
try {
|
|
134
206
|
customChartContext = new CustomChartContext({
|
|
@@ -170,7 +242,124 @@ describe('CustomChartContext', () => {
|
|
|
170
242
|
eventProcessor = null;
|
|
171
243
|
});
|
|
172
244
|
|
|
173
|
-
test('
|
|
245
|
+
test('TSToChartEvent.ChartConfigValidate validation response testing', async () => {
|
|
246
|
+
// Define initial context with object definitions
|
|
247
|
+
customChartContext = new CustomChartContext({
|
|
248
|
+
getDefaultChartConfig,
|
|
249
|
+
getQueriesFromChartConfig,
|
|
250
|
+
renderChart,
|
|
251
|
+
visualPropEditorDefinition: { elements: [] },
|
|
252
|
+
chartConfigEditorDefinition: [],
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Trigger event processor with initial context
|
|
256
|
+
const responseWithInitialContext = await eventProcessor({
|
|
257
|
+
payload: mockInitializeContextPayload,
|
|
258
|
+
eventType: TSToChartEvent.ChartConfigValidate,
|
|
259
|
+
source: 'ts-host-app',
|
|
260
|
+
});
|
|
261
|
+
// Verify response with object definitions
|
|
262
|
+
expect(responseWithInitialContext).toStrictEqual({
|
|
263
|
+
isValid: true,
|
|
264
|
+
visualPropEditorDefinition: { elements: [] },
|
|
265
|
+
chartConfigEditorDefinition: [],
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Redefine context with function-returned definitions
|
|
269
|
+
customChartContext = new CustomChartContext({
|
|
270
|
+
getDefaultChartConfig,
|
|
271
|
+
getQueriesFromChartConfig,
|
|
272
|
+
renderChart,
|
|
273
|
+
visualPropEditorDefinition: () => {
|
|
274
|
+
return { elements: [] };
|
|
275
|
+
},
|
|
276
|
+
chartConfigEditorDefinition: () => {
|
|
277
|
+
return [
|
|
278
|
+
{
|
|
279
|
+
key: 'x',
|
|
280
|
+
columnSections: [{ label: 'x-axis', key: 'x' }],
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
// Trigger event processor with updated context
|
|
286
|
+
const responseWithUpdatedContext = await eventProcessor({
|
|
287
|
+
payload: mockInitializeContextPayload,
|
|
288
|
+
eventType: TSToChartEvent.ChartConfigValidate,
|
|
289
|
+
source: 'ts-host-app',
|
|
290
|
+
});
|
|
291
|
+
// Verify response with function-returned definitions
|
|
292
|
+
expect(responseWithUpdatedContext).toStrictEqual({
|
|
293
|
+
isValid: true,
|
|
294
|
+
visualPropEditorDefinition: { elements: [] },
|
|
295
|
+
chartConfigEditorDefinition: [
|
|
296
|
+
{
|
|
297
|
+
key: 'x',
|
|
298
|
+
columnSections: [{ label: 'x-axis', key: 'x' }],
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test('TSToChartEvent.validateVisualProps validation response testing', () => {
|
|
305
|
+
// Define initial context with object definitions
|
|
306
|
+
customChartContext = new CustomChartContext({
|
|
307
|
+
getDefaultChartConfig,
|
|
308
|
+
getQueriesFromChartConfig,
|
|
309
|
+
renderChart,
|
|
310
|
+
visualPropEditorDefinition: { elements: [] },
|
|
311
|
+
chartConfigEditorDefinition: [],
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Trigger event processor with initial context
|
|
315
|
+
const responseWithInitialContext = eventProcessor({
|
|
316
|
+
payload: mockInitializeContextPayload,
|
|
317
|
+
eventType: TSToChartEvent.VisualPropsValidate,
|
|
318
|
+
source: 'ts-host-app',
|
|
319
|
+
});
|
|
320
|
+
// Verify response with object definitions
|
|
321
|
+
expect(responseWithInitialContext).toStrictEqual({
|
|
322
|
+
isValid: true,
|
|
323
|
+
visualPropEditorDefinition: { elements: [] },
|
|
324
|
+
chartConfigEditorDefinition: [],
|
|
325
|
+
});
|
|
326
|
+
// Redefine context with function-returned definitions
|
|
327
|
+
customChartContext = new CustomChartContext({
|
|
328
|
+
getDefaultChartConfig,
|
|
329
|
+
getQueriesFromChartConfig,
|
|
330
|
+
renderChart,
|
|
331
|
+
visualPropEditorDefinition: () => {
|
|
332
|
+
return { elements: [] };
|
|
333
|
+
},
|
|
334
|
+
chartConfigEditorDefinition: () => {
|
|
335
|
+
return [
|
|
336
|
+
{
|
|
337
|
+
key: 'x',
|
|
338
|
+
columnSections: [{ label: 'x-axis', key: 'x' }],
|
|
339
|
+
},
|
|
340
|
+
];
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
// Trigger event processor with updated context
|
|
344
|
+
const responseWithFunctionReturnedValues = eventProcessor({
|
|
345
|
+
payload: mockInitializeContextPayload,
|
|
346
|
+
eventType: TSToChartEvent.VisualPropsValidate,
|
|
347
|
+
source: 'ts-host-app',
|
|
348
|
+
});
|
|
349
|
+
// Verify response with function-returned definitions
|
|
350
|
+
expect(responseWithFunctionReturnedValues).toStrictEqual({
|
|
351
|
+
isValid: true,
|
|
352
|
+
visualPropEditorDefinition: { elements: [] },
|
|
353
|
+
chartConfigEditorDefinition: [
|
|
354
|
+
{
|
|
355
|
+
key: 'x',
|
|
356
|
+
columnSections: [{ label: 'x-axis', key: 'x' }],
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
test('should not trigger post message if host is not accurate', async () => {
|
|
174
363
|
expect(mockInitMessage).toHaveBeenCalled();
|
|
175
364
|
|
|
176
365
|
// mock the event trigger for ChartConfigValidate
|
|
@@ -21,10 +21,14 @@ import {
|
|
|
21
21
|
AppConfig,
|
|
22
22
|
ChartConfig,
|
|
23
23
|
ChartModel,
|
|
24
|
+
SuccessValidationResponse,
|
|
24
25
|
ValidationResponse,
|
|
25
26
|
VisualProps,
|
|
26
27
|
} from '../types/common.types';
|
|
27
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
ChartConfigEditorDefinition,
|
|
30
|
+
ConfigEditorDefinitionSetter,
|
|
31
|
+
} from '../types/configurator.types';
|
|
28
32
|
import {
|
|
29
33
|
AxisMenuCustomActionPayload,
|
|
30
34
|
ChartConfigValidateEventPayload,
|
|
@@ -42,7 +46,10 @@ import {
|
|
|
42
46
|
VisualPropsUpdateEventPayload,
|
|
43
47
|
VisualPropsValidateEventPayload,
|
|
44
48
|
} from '../types/ts-to-chart-event.types';
|
|
45
|
-
import {
|
|
49
|
+
import {
|
|
50
|
+
VisualEditorDefinitionSetter,
|
|
51
|
+
VisualPropEditorDefinition,
|
|
52
|
+
} from '../types/visual-prop.types';
|
|
46
53
|
import {
|
|
47
54
|
globalThis,
|
|
48
55
|
initMessageListener,
|
|
@@ -52,6 +59,7 @@ import {
|
|
|
52
59
|
export type AllowedConfigurations = {
|
|
53
60
|
allowColumnNumberFormatting: boolean;
|
|
54
61
|
allowColumnConditionalFormatting: boolean;
|
|
62
|
+
allowMeasureNamesAndValues: boolean;
|
|
55
63
|
};
|
|
56
64
|
|
|
57
65
|
export type CustomChartContextProps = {
|
|
@@ -116,7 +124,9 @@ export type CustomChartContextProps = {
|
|
|
116
124
|
*
|
|
117
125
|
* @version SDK: 0.1 | ThoughtSpot:
|
|
118
126
|
*/
|
|
119
|
-
chartConfigEditorDefinition?:
|
|
127
|
+
chartConfigEditorDefinition?:
|
|
128
|
+
| ConfigEditorDefinitionSetter
|
|
129
|
+
| ChartConfigEditorDefinition[];
|
|
120
130
|
|
|
121
131
|
/**
|
|
122
132
|
* Definition to help edit/customize the visual properties from chart settings editor
|
|
@@ -127,12 +137,18 @@ export type CustomChartContextProps = {
|
|
|
127
137
|
* @returns {@link VisualPropEditorDefinition}
|
|
128
138
|
* @version SDK: 0.1 | ThoughtSpot:
|
|
129
139
|
*/
|
|
130
|
-
visualPropEditorDefinition?:
|
|
140
|
+
visualPropEditorDefinition?:
|
|
141
|
+
| VisualEditorDefinitionSetter
|
|
142
|
+
| VisualPropEditorDefinition;
|
|
131
143
|
|
|
132
144
|
// Whether user wants thoughtspot default number and conditional formatting
|
|
133
145
|
allowedConfigurations?: AllowedConfigurations;
|
|
134
146
|
};
|
|
135
147
|
|
|
148
|
+
export type ValidationFunctions =
|
|
149
|
+
| CustomChartContextProps['validateVisualProps']
|
|
150
|
+
| CustomChartContextProps['validateConfig'];
|
|
151
|
+
|
|
136
152
|
/**
|
|
137
153
|
* Default configuration options for all the chart context properties
|
|
138
154
|
*/
|
|
@@ -143,6 +159,7 @@ const DEFAULT_CHART_CONTEXT_PROPS: Partial<CustomChartContextProps> = {
|
|
|
143
159
|
allowedConfigurations: {
|
|
144
160
|
allowColumnNumberFormatting: false,
|
|
145
161
|
allowColumnConditionalFormatting: false,
|
|
162
|
+
allowMeasureNamesAndValues: false,
|
|
146
163
|
},
|
|
147
164
|
};
|
|
148
165
|
|
|
@@ -379,6 +396,48 @@ export class CustomChartContext {
|
|
|
379
396
|
return processedPayload;
|
|
380
397
|
}
|
|
381
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Funtions return the chart config editor definition
|
|
401
|
+
* @param {ChartConfig[]} currentChartConfig
|
|
402
|
+
* @param {VisualProps}
|
|
403
|
+
* @returns {ChartConfigEditorDefinition[]}
|
|
404
|
+
*/
|
|
405
|
+
private getChartConfigEditorDefinition = (
|
|
406
|
+
currentState: Partial<ChartModel> = {},
|
|
407
|
+
) => {
|
|
408
|
+
if (_.isFunction(this.chartContextProps.chartConfigEditorDefinition)) {
|
|
409
|
+
return this.chartContextProps.chartConfigEditorDefinition(
|
|
410
|
+
{
|
|
411
|
+
...this.chartModel,
|
|
412
|
+
...currentState,
|
|
413
|
+
},
|
|
414
|
+
this,
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
return this.chartContextProps.chartConfigEditorDefinition;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Funtions returns the visual prop editor definition
|
|
422
|
+
* @param {ChartConfig[]} currentChartConfig
|
|
423
|
+
* @param {VisualProps}
|
|
424
|
+
* @returns {VisualPropEditorDefinition}
|
|
425
|
+
*/
|
|
426
|
+
private getVisualPropEditorDefinition = (
|
|
427
|
+
currentState: Partial<ChartModel> = {},
|
|
428
|
+
) => {
|
|
429
|
+
if (_.isFunction(this.chartContextProps.visualPropEditorDefinition)) {
|
|
430
|
+
return this.chartContextProps.visualPropEditorDefinition(
|
|
431
|
+
{
|
|
432
|
+
...this.chartModel,
|
|
433
|
+
...currentState,
|
|
434
|
+
},
|
|
435
|
+
this,
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
return this.chartContextProps.visualPropEditorDefinition;
|
|
439
|
+
};
|
|
440
|
+
|
|
382
441
|
/**
|
|
383
442
|
* Function to store the axis menu custom action callback mapped with action id
|
|
384
443
|
* @param {[OpenAxisMenuEventPayload]} eventPayload Event payload bound
|
|
@@ -438,6 +497,24 @@ export class CustomChartContext {
|
|
|
438
497
|
}
|
|
439
498
|
}
|
|
440
499
|
|
|
500
|
+
private validationsResponseProcessor(
|
|
501
|
+
currentValidationState: Partial<ChartModel>,
|
|
502
|
+
validationResponse: ValidationResponse,
|
|
503
|
+
) {
|
|
504
|
+
const visualPropEditorDefinition = this.getVisualPropEditorDefinition(
|
|
505
|
+
currentValidationState,
|
|
506
|
+
);
|
|
507
|
+
const chartConfigEditorDefinition = this.getChartConfigEditorDefinition(
|
|
508
|
+
currentValidationState,
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
return {
|
|
512
|
+
...validationResponse,
|
|
513
|
+
visualPropEditorDefinition,
|
|
514
|
+
chartConfigEditorDefinition,
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
|
|
441
518
|
/**
|
|
442
519
|
* Function to emit Chart to TS Events to the TS application.
|
|
443
520
|
|
|
@@ -495,7 +572,7 @@ export class CustomChartContext {
|
|
|
495
572
|
const messageResponse = this.executeEventListenerCBs(data);
|
|
496
573
|
|
|
497
574
|
// respond back to parent to confirm/ack the receipt
|
|
498
|
-
return messageResponse;
|
|
575
|
+
return messageResponse || {};
|
|
499
576
|
};
|
|
500
577
|
|
|
501
578
|
/**
|
|
@@ -530,13 +607,27 @@ export class CustomChartContext {
|
|
|
530
607
|
*/
|
|
531
608
|
this.onInternal(
|
|
532
609
|
TSToChartEvent.VisualPropsValidate,
|
|
533
|
-
(
|
|
610
|
+
(
|
|
611
|
+
payload: VisualPropsValidateEventPayload,
|
|
612
|
+
):
|
|
613
|
+
| (ValidationResponse & SuccessValidationResponse)
|
|
614
|
+
| ValidationResponse => {
|
|
534
615
|
if (this.chartContextProps.validateVisualProps) {
|
|
535
616
|
const validationResponse =
|
|
536
617
|
this.chartContextProps.validateVisualProps(
|
|
537
618
|
payload.visualProps,
|
|
538
619
|
this.chartModel,
|
|
539
620
|
);
|
|
621
|
+
if (validationResponse.isValid) {
|
|
622
|
+
const currentVisualState = {
|
|
623
|
+
visualProps: payload.visualProps,
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
return this.validationsResponseProcessor(
|
|
627
|
+
currentVisualState,
|
|
628
|
+
validationResponse,
|
|
629
|
+
);
|
|
630
|
+
}
|
|
540
631
|
return validationResponse;
|
|
541
632
|
}
|
|
542
633
|
// this will never be true
|
|
@@ -551,13 +642,29 @@ export class CustomChartContext {
|
|
|
551
642
|
*/
|
|
552
643
|
this.onInternal(
|
|
553
644
|
TSToChartEvent.ChartConfigValidate,
|
|
554
|
-
(
|
|
645
|
+
(
|
|
646
|
+
payload: ChartConfigValidateEventPayload,
|
|
647
|
+
):
|
|
648
|
+
| (ValidationResponse & SuccessValidationResponse)
|
|
649
|
+
| ValidationResponse => {
|
|
555
650
|
if (this.chartContextProps.validateConfig) {
|
|
556
651
|
const validationResponse =
|
|
557
652
|
this.chartContextProps.validateConfig(
|
|
558
653
|
payload.chartConfig,
|
|
559
654
|
this.chartModel,
|
|
560
655
|
);
|
|
656
|
+
if (validationResponse.isValid) {
|
|
657
|
+
const currentConfigState = {
|
|
658
|
+
config: {
|
|
659
|
+
...this.chartModel.config,
|
|
660
|
+
chartConfig: payload.chartConfig,
|
|
661
|
+
},
|
|
662
|
+
};
|
|
663
|
+
return this.validationsResponseProcessor(
|
|
664
|
+
currentConfigState,
|
|
665
|
+
validationResponse,
|
|
666
|
+
);
|
|
667
|
+
}
|
|
561
668
|
return validationResponse;
|
|
562
669
|
}
|
|
563
670
|
// this will never be true
|
|
@@ -789,9 +896,9 @@ export class CustomChartContext {
|
|
|
789
896
|
isConfigValid: isValid,
|
|
790
897
|
defaultChartConfig,
|
|
791
898
|
chartConfigEditorDefinition:
|
|
792
|
-
this.
|
|
899
|
+
this.getChartConfigEditorDefinition(),
|
|
793
900
|
visualPropEditorDefinition:
|
|
794
|
-
this.
|
|
901
|
+
this.getVisualPropEditorDefinition(),
|
|
795
902
|
allowedConfigurations:
|
|
796
903
|
this.chartContextProps.allowedConfigurations,
|
|
797
904
|
};
|
|
@@ -9,7 +9,7 @@ const target =
|
|
|
9
9
|
(elSelector && (document.querySelector(elSelector) as HTMLElement)) ||
|
|
10
10
|
window.parent;
|
|
11
11
|
|
|
12
|
-
const globalThis = (target
|
|
12
|
+
const globalThis = (target === window.parent ? window : target) as any;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* method to listen to messages using postMessage from the parent.
|
|
@@ -53,7 +53,7 @@ const postMessageToHostApp = async (
|
|
|
53
53
|
TIMEOUT_THRESHOLD,
|
|
54
54
|
'ChartContext: postMessage operation timed out.',
|
|
55
55
|
);
|
|
56
|
-
if (resp
|
|
56
|
+
if (resp?.hasError) {
|
|
57
57
|
throw new Error(resp.error);
|
|
58
58
|
}
|
|
59
59
|
return resp;
|
|
@@ -3,6 +3,7 @@ import { renderHook } from '@testing-library/react-hooks';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import * as PostMessageEventBridge from '../main/post-message-event-bridge';
|
|
5
5
|
import { mockInitializeContextPayload } from '../test/test-utils';
|
|
6
|
+
import { ColumnType } from '../types/answer-column.types';
|
|
6
7
|
import { ChartToTSEvent } from '../types/chart-to-ts-event.types';
|
|
7
8
|
import { TSToChartEvent } from '../types/ts-to-chart-event.types';
|
|
8
9
|
import { contextChartProps } from './mocks/custom-chart-context-mock';
|
|
@@ -12,7 +13,10 @@ describe('useChartContext initialization', () => {
|
|
|
12
13
|
let eventProcessor: any;
|
|
13
14
|
let mockInitMessage;
|
|
14
15
|
let mockPostMessageToHost;
|
|
15
|
-
const mockedChartModel = {
|
|
16
|
+
const mockedChartModel = {
|
|
17
|
+
columns: [{ type: ColumnType.MEASURE }, { type: ColumnType.ATTRIBUTE }],
|
|
18
|
+
config: {},
|
|
19
|
+
};
|
|
16
20
|
beforeEach(() => {
|
|
17
21
|
mockInitMessage = jest.spyOn(
|
|
18
22
|
PostMessageEventBridge,
|
|
@@ -67,6 +71,66 @@ describe('useChartContext initialization', () => {
|
|
|
67
71
|
});
|
|
68
72
|
});
|
|
69
73
|
|
|
74
|
+
test('should trigger getDataQuery and fetch correct query response', async () => {
|
|
75
|
+
// Render the hook with the custom chart context props
|
|
76
|
+
const { result, waitFor } = renderHook(() =>
|
|
77
|
+
useChartContext(contextChartProps),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// Assert that the context is not initialized initially
|
|
81
|
+
expect(result.current.hasInitialized).toBe(false);
|
|
82
|
+
expect(result.current.chartModel).toBeUndefined();
|
|
83
|
+
await eventProcessor({
|
|
84
|
+
payload: {
|
|
85
|
+
componentId: 'COMPONENT_ID',
|
|
86
|
+
hostUrl: 'https://some.chart.app',
|
|
87
|
+
chartModel: mockedChartModel,
|
|
88
|
+
},
|
|
89
|
+
eventType: TSToChartEvent.Initialize,
|
|
90
|
+
});
|
|
91
|
+
const response = await eventProcessor({
|
|
92
|
+
payload: {
|
|
93
|
+
config: [
|
|
94
|
+
{
|
|
95
|
+
key: 'column',
|
|
96
|
+
dimensions: [
|
|
97
|
+
{
|
|
98
|
+
key: 'x',
|
|
99
|
+
columns: [mockedChartModel.columns[0]],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: 'y',
|
|
103
|
+
columns: [mockedChartModel.columns[1]],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
eventType: TSToChartEvent.GetDataQuery,
|
|
110
|
+
source: 'ts-host-app',
|
|
111
|
+
});
|
|
112
|
+
await eventProcessor({
|
|
113
|
+
payload: {},
|
|
114
|
+
eventType: TSToChartEvent.TriggerRenderChart,
|
|
115
|
+
source: 'ts-host-app',
|
|
116
|
+
});
|
|
117
|
+
await eventProcessor({
|
|
118
|
+
payload: {},
|
|
119
|
+
eventType: TSToChartEvent.InitializeComplete,
|
|
120
|
+
source: 'ts-host-app',
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
await waitFor(() => {
|
|
124
|
+
expect(response.queries[0].queryColumns[0]).toBe(
|
|
125
|
+
mockedChartModel.columns[0],
|
|
126
|
+
);
|
|
127
|
+
expect(response.queries[0].queryColumns[1]).toBe(
|
|
128
|
+
mockedChartModel.columns[1],
|
|
129
|
+
);
|
|
130
|
+
expect(result.current.hasInitialized).toBeTruthy();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
70
134
|
test('should make sure hasInitialized to remain false when context initialization failed', async () => {
|
|
71
135
|
jest.mock('../main/custom-chart-context', () => ({
|
|
72
136
|
CustomChartContext: jest.fn().mockImplementation(() => ({
|
|
@@ -76,7 +140,6 @@ describe('useChartContext initialization', () => {
|
|
|
76
140
|
emitEvent: jest.fn(),
|
|
77
141
|
on: jest.fn(),
|
|
78
142
|
getChartModel: jest.fn(),
|
|
79
|
-
renderChart: jest.fn(),
|
|
80
143
|
destroy: jest.fn(),
|
|
81
144
|
})),
|
|
82
145
|
}));
|