@thoughtspot/ts-chart-sdk 0.0.1-alpha.7 → 0.0.1-alpha.9

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 (86) hide show
  1. package/cjs/main/custom-chart-context.d.ts +10 -3
  2. package/cjs/main/custom-chart-context.d.ts.map +1 -1
  3. package/cjs/main/custom-chart-context.js +110 -3
  4. package/cjs/main/custom-chart-context.js.map +1 -1
  5. package/cjs/main/custom-chart-context.spec.js +251 -8
  6. package/cjs/main/custom-chart-context.spec.js.map +1 -1
  7. package/cjs/react/custom-chart-context-service.d.ts +16 -5
  8. package/cjs/react/custom-chart-context-service.d.ts.map +1 -1
  9. package/cjs/react/custom-chart-context-service.js +35 -34
  10. package/cjs/react/custom-chart-context-service.js.map +1 -1
  11. package/cjs/react/custom-chart.spec.js +53 -282
  12. package/cjs/react/custom-chart.spec.js.map +1 -1
  13. package/cjs/react/mocks/custom-chart-context-mock.d.ts.map +1 -1
  14. package/cjs/react/mocks/custom-chart-context-mock.js +30 -32
  15. package/cjs/react/mocks/custom-chart-context-mock.js.map +1 -1
  16. package/cjs/types/chart-to-ts-event.types.d.ts +28 -1
  17. package/cjs/types/chart-to-ts-event.types.d.ts.map +1 -1
  18. package/cjs/types/chart-to-ts-event.types.js +9 -1
  19. package/cjs/types/chart-to-ts-event.types.js.map +1 -1
  20. package/cjs/types/common.types.d.ts +1 -0
  21. package/cjs/types/common.types.d.ts.map +1 -1
  22. package/cjs/types/ts-to-chart-event.types.d.ts +23 -1
  23. package/cjs/types/ts-to-chart-event.types.d.ts.map +1 -1
  24. package/cjs/types/ts-to-chart-event.types.js +2 -0
  25. package/cjs/types/ts-to-chart-event.types.js.map +1 -1
  26. package/cjs/types/visual-prop.types.d.ts +23 -9
  27. package/cjs/types/visual-prop.types.d.ts.map +1 -1
  28. package/dist/ts-chart-sdk.d.ts +312 -0
  29. package/lib/dist/ts-chart-sdk.d.ts +312 -0
  30. package/lib/main/custom-chart-context.d.ts +10 -3
  31. package/lib/main/custom-chart-context.d.ts.map +1 -1
  32. package/lib/main/custom-chart-context.js +111 -3
  33. package/lib/main/custom-chart-context.js.map +1 -1
  34. package/lib/main/custom-chart-context.spec.js +248 -8
  35. package/lib/main/custom-chart-context.spec.js.map +1 -1
  36. package/lib/react/custom-chart-context-service.d.ts +16 -5
  37. package/lib/react/custom-chart-context-service.d.ts.map +1 -1
  38. package/lib/react/custom-chart-context-service.js +35 -34
  39. package/lib/react/custom-chart-context-service.js.map +1 -1
  40. package/lib/react/custom-chart.spec.js +54 -260
  41. package/lib/react/custom-chart.spec.js.map +1 -1
  42. package/lib/react/mocks/custom-chart-context-mock.d.ts.map +1 -1
  43. package/lib/react/mocks/custom-chart-context-mock.js +30 -32
  44. package/lib/react/mocks/custom-chart-context-mock.js.map +1 -1
  45. package/lib/types/chart-to-ts-event.types.d.ts +28 -1
  46. package/lib/types/chart-to-ts-event.types.d.ts.map +1 -1
  47. package/lib/types/chart-to-ts-event.types.js +8 -0
  48. package/lib/types/chart-to-ts-event.types.js.map +1 -1
  49. package/lib/types/common.types.d.ts +1 -0
  50. package/lib/types/common.types.d.ts.map +1 -1
  51. package/lib/types/ts-to-chart-event.types.d.ts +23 -1
  52. package/lib/types/ts-to-chart-event.types.d.ts.map +1 -1
  53. package/lib/types/ts-to-chart-event.types.js +2 -0
  54. package/lib/types/ts-to-chart-event.types.js.map +1 -1
  55. package/lib/types/visual-prop.types.d.ts +23 -9
  56. package/lib/types/visual-prop.types.d.ts.map +1 -1
  57. package/package.json +1 -1
  58. package/src/main/custom-chart-context.spec.ts +310 -0
  59. package/src/main/custom-chart-context.ts +227 -1
  60. package/src/types/chart-to-ts-event.types.ts +125 -6
  61. package/src/types/common.types.ts +14 -0
  62. package/src/types/ts-to-chart-event.types.ts +70 -0
  63. package/cjs/react/custom-chart-context-hook.d.ts +0 -22
  64. package/cjs/react/custom-chart-context-hook.d.ts.map +0 -1
  65. package/cjs/react/custom-chart-context-hook.js +0 -116
  66. package/cjs/react/custom-chart-context-hook.js.map +0 -1
  67. package/cjs/react/custom-chart-context-hook.spec.d.ts +0 -2
  68. package/cjs/react/custom-chart-context-hook.spec.d.ts.map +0 -1
  69. package/cjs/react/custom-chart-context-hook.spec.js +0 -343
  70. package/cjs/react/custom-chart-context-hook.spec.js.map +0 -1
  71. package/cjs/react/mocks/custom-chart-context-hook.d.ts +0 -3
  72. package/cjs/react/mocks/custom-chart-context-hook.d.ts.map +0 -1
  73. package/cjs/react/mocks/custom-chart-context-hook.js +0 -100
  74. package/cjs/react/mocks/custom-chart-context-hook.js.map +0 -1
  75. package/lib/react/custom-chart-context-hook.d.ts +0 -22
  76. package/lib/react/custom-chart-context-hook.d.ts.map +0 -1
  77. package/lib/react/custom-chart-context-hook.js +0 -86
  78. package/lib/react/custom-chart-context-hook.js.map +0 -1
  79. package/lib/react/custom-chart-context-hook.spec.d.ts +0 -2
  80. package/lib/react/custom-chart-context-hook.spec.d.ts.map +0 -1
  81. package/lib/react/custom-chart-context-hook.spec.js +0 -315
  82. package/lib/react/custom-chart-context-hook.spec.js.map +0 -1
  83. package/lib/react/mocks/custom-chart-context-hook.d.ts +0 -3
  84. package/lib/react/mocks/custom-chart-context-hook.d.ts.map +0 -1
  85. package/lib/react/mocks/custom-chart-context-hook.js +0 -94
  86. package/lib/react/mocks/custom-chart-context-hook.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  export interface InputValidation {
2
- required: boolean;
3
- requiredError: string;
4
- regex: string;
5
- regexError: string;
6
- minLength: number;
7
- minLengthError: string;
8
- range: string;
9
- rangeError: string;
2
+ required?: boolean;
3
+ requiredError?: string;
4
+ regex?: string;
5
+ regexError?: string;
6
+ minLength?: number;
7
+ minLengthError?: string;
8
+ range?: string;
9
+ rangeError?: string;
10
10
  }
11
11
  export interface TextInputFormDetail {
12
12
  type: 'text';
@@ -18,6 +18,20 @@ export interface TextInputFormDetail {
18
18
  defaultValue?: string;
19
19
  inputValidation?: InputValidation;
20
20
  }
21
+ export interface NumberInputFormDetail {
22
+ type: 'number';
23
+ key: string;
24
+ label?: string;
25
+ defaultValue?: number;
26
+ inputValidation?: InputValidation;
27
+ }
28
+ export interface ColorPickerFormDetail {
29
+ type: 'colorpicker';
30
+ key: string;
31
+ label?: string;
32
+ selectorType?: 'FONT' | 'COLOR';
33
+ defaultValue?: string;
34
+ }
21
35
  export interface ToggleFormDetail {
22
36
  type: 'toggle';
23
37
  key: string;
@@ -52,7 +66,7 @@ export interface Section {
52
66
  alignment?: 'row' | 'column';
53
67
  layoutType?: 'accordion' | 'tab' | 'none';
54
68
  }
55
- export type PropElement = Section | TextInputFormDetail | ToggleFormDetail | CheckboxFormDetail | RadioButtonFormDetail | DropDownFormDetail;
69
+ export type PropElement = Section | TextInputFormDetail | NumberInputFormDetail | ColorPickerFormDetail | ToggleFormDetail | CheckboxFormDetail | RadioButtonFormDetail | DropDownFormDetail;
56
70
  export interface VisualPropEditorDefinition {
57
71
  elements: PropElement[];
58
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"visual-prop.types.d.ts","sourceRoot":"","sources":["../../src/types/visual-prop.types.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,eAAe;IAM5B,QAAQ,EAAE,OAAO,CAAC;IAMlB,aAAa,EAAE,MAAM,CAAC;IAMtB,KAAK,EAAE,MAAM,CAAC;IAMd,UAAU,EAAE,MAAM,CAAC;IAMnB,SAAS,EAAE,MAAM,CAAC;IAMlB,cAAc,EAAE,MAAM,CAAC;IAMvB,KAAK,EAAE,MAAM,CAAC;IAMd,UAAU,EAAE,MAAM,CAAC;CACtB;AAOD,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IAMb,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAOf,QAAQ,CAAC,EAAE,OAAO,CAAC;IAOnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAMpB,WAAW,CAAC,EAAE,MAAM,CAAC;IAMrB,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,eAAe,CAAC,EAAE,eAAe,CAAC;CACrC;AAOD,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,QAAQ,CAAC;IAMf,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAOD,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,UAAU,CAAC;IAMjB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAOD,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,OAAO,CAAC;IAMd,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,UAAU,CAAC;IAMjB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,SAAS,CAAC;IAMhB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IAMzB,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAQ7B,UAAU,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7C;AAOD,MAAM,MAAM,WAAW,GACjB,OAAO,GACP,mBAAmB,GACnB,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,kBAAkB,CAAC;AAOzB,MAAM,WAAW,0BAA0B;IAOvC,QAAQ,EAAE,WAAW,EAAE,CAAC;CAC3B"}
1
+ {"version":3,"file":"visual-prop.types.d.ts","sourceRoot":"","sources":["../../src/types/visual-prop.types.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,eAAe;IAM5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAMnB,aAAa,CAAC,EAAE,MAAM,CAAC;IAMvB,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,UAAU,CAAC,EAAE,MAAM,CAAC;IAMpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAMnB,cAAc,CAAC,EAAE,MAAM,CAAC;IAMxB,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAOD,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IAMb,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAOf,QAAQ,CAAC,EAAE,OAAO,CAAC;IAOnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAMpB,WAAW,CAAC,EAAE,MAAM,CAAC;IAMrB,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,eAAe,CAAC,EAAE,eAAe,CAAC;CACrC;AAOD,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,QAAQ,CAAC;IAMf,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,eAAe,CAAC,EAAE,eAAe,CAAC;CACrC;AAOD,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,aAAa,CAAC;IAMpB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAOf,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAMhC,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAOD,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,QAAQ,CAAC;IAMf,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAOD,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,UAAU,CAAC;IAMjB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAOD,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,OAAO,CAAC;IAMd,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,UAAU,CAAC;IAMjB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,YAAY,CAAC,EAAE,MAAM,CAAC;IAMtB,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAOD,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,SAAS,CAAC;IAMhB,GAAG,EAAE,MAAM,CAAC;IAMZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IAMzB,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAQ7B,UAAU,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7C;AAOD,MAAM,MAAM,WAAW,GACjB,OAAO,GACP,mBAAmB,GACnB,qBAAqB,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,kBAAkB,CAAC;AAOzB,MAAM,WAAW,0BAA0B;IAOvC,QAAQ,EAAE,WAAW,EAAE,CAAC;CAC3B"}
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.1-alpha.7",
4
+ "version": "0.0.1-alpha.9",
5
5
  "module": "lib/index",
6
6
  "main": "lib/index",
7
7
  "types": "lib/index",
@@ -4,6 +4,7 @@
4
4
  * @author Chetan Agrawal <chetan.agrawal@thoughtspot.com>
5
5
  */
6
6
 
7
+ import _ from 'lodash';
7
8
  import { mockInitializeContextPayload } from '../test/test-utils';
8
9
  import { ChartToTSEvent, ErrorType } from '../types/chart-to-ts-event.types';
9
10
  import { TSToChartEvent } from '../types/ts-to-chart-event.types';
@@ -330,6 +331,71 @@ describe('CustomChartContext', () => {
330
331
  expect(customChartContext.getChartModel().visualProps).toBe(
331
332
  'random data',
332
333
  );
334
+ mockPostMessage.mockReset();
335
+
336
+ // mock the event trigger for AxisMenuActionClick
337
+ customChartContext.axisMenuCustomActionPreProcessor([
338
+ {
339
+ customActions: [
340
+ {
341
+ icon: '',
342
+ id: 'custom-action-1',
343
+ label: 'Custom user action 1',
344
+ onClick: () => _.noop(),
345
+ },
346
+ ],
347
+ },
348
+ ] as any);
349
+ eventProcessor({
350
+ data: {
351
+ payload: {
352
+ customAction: {
353
+ id: 'custom-action-1',
354
+ columnIds: ['9f96b5b0-f7e4-4a5e-aa11-4c77fdf42125'],
355
+ },
356
+ },
357
+ eventType: TSToChartEvent.AxisMenuActionClick,
358
+ source: 'ts-host-app',
359
+ },
360
+ ports: [{ postMessage: mockPostMessage }],
361
+ });
362
+ // Check that the response was valid which means action gets
363
+ // executed successfully
364
+ expect(mockPostMessage).toHaveBeenCalledWith({
365
+ isValid: true,
366
+ });
367
+
368
+ // mock the event trigger for ContextMenuActionClick
369
+ customChartContext.contextMenuCustomActionPreProcessor([
370
+ {
371
+ customActions: [
372
+ {
373
+ icon: '',
374
+ id: 'custom-action-1',
375
+ label: 'Custom user action 1',
376
+ onClick: () => _.noop(),
377
+ },
378
+ ],
379
+ },
380
+ ] as any);
381
+ eventProcessor({
382
+ data: {
383
+ payload: {
384
+ customAction: {
385
+ id: 'custom-action-1',
386
+ columnIds: ['9f96b5b0-f7e4-4a5e-aa11-4c77fdf42125'],
387
+ },
388
+ },
389
+ eventType: TSToChartEvent.ContextMenuActionClick,
390
+ source: 'ts-host-app',
391
+ },
392
+ ports: [{ postMessage: mockPostMessage }],
393
+ });
394
+ // Check that the response was valid which means action gets
395
+ // executed successfully
396
+ expect(mockPostMessage).toHaveBeenCalledWith({
397
+ isValid: true,
398
+ });
333
399
  });
334
400
 
335
401
  test('should add an event listener to the specified event type', () => {
@@ -605,5 +671,249 @@ describe('CustomChartContext', () => {
605
671
  ChartToTSEvent.RenderStart,
606
672
  );
607
673
  });
674
+ test('should process the event payload for context menu custom actions', async () => {
675
+ const mockPostMessage = jest.fn();
676
+ const mockCustomAction = jest.fn();
677
+ let resolve: any;
678
+ eventProcessor({
679
+ data: {
680
+ payload: mockInitializeContextPayload,
681
+ eventType: TSToChartEvent.Initialize,
682
+ source: 'ts-host-app',
683
+ },
684
+ ports: [{ postMessage: mockPostMessage }],
685
+ });
686
+ eventProcessor({
687
+ data: {
688
+ payload: {},
689
+ eventType: TSToChartEvent.InitializeComplete,
690
+ source: 'ts-host-app',
691
+ },
692
+ ports: [{ postMessage: mockPostMessage }],
693
+ });
694
+ customChartContext.initialize();
695
+ mockPostMessageToHost.mockImplementation(
696
+ () =>
697
+ new global.Promise<any>((res) => {
698
+ resolve = res;
699
+ }),
700
+ );
701
+
702
+ // Define a test event type and payload
703
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenContextMenu as any;
704
+ const testPayload = {
705
+ customActions: [
706
+ {
707
+ id: 'custom-action-1',
708
+ label: 'Custom user action 1',
709
+ icon: '',
710
+ onClick: mockCustomAction,
711
+ },
712
+ ],
713
+ };
714
+
715
+ // Call the emitEvent function and wait for it to resolve
716
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
717
+
718
+ // Check that the result is defined
719
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
720
+ mockInitializeContextPayload.componentId,
721
+ mockInitializeContextPayload.hostUrl,
722
+ {
723
+ customActions: [
724
+ {
725
+ icon: '',
726
+ id: 'custom-action-1',
727
+ label: 'Custom user action 1',
728
+ },
729
+ ],
730
+ },
731
+ TEST_EVENT_TYPE,
732
+ );
733
+ eventProcessor({
734
+ data: {
735
+ payload: {
736
+ customAction: {
737
+ id: 'custom-action-1',
738
+ clickedPoint: {},
739
+ event: {},
740
+ selectedPoints: [{}],
741
+ },
742
+ },
743
+ eventType: TSToChartEvent.ContextMenuActionClick,
744
+ source: 'ts-host-app',
745
+ },
746
+ ports: [{ postMessage: mockPostMessage }],
747
+ });
748
+ expect(mockCustomAction).toHaveBeenCalled();
749
+ expect(mockCustomAction).toHaveBeenCalledWith({
750
+ clickedPoint: {},
751
+ event: {},
752
+ id: 'custom-action-1',
753
+ selectedPoints: [{}],
754
+ });
755
+ });
756
+ test('should process the event payload for axis menu custom actions', async () => {
757
+ const mockPostMessage = jest.fn();
758
+ const mockCustomAction = jest.fn();
759
+ let resolve: any;
760
+ eventProcessor({
761
+ data: {
762
+ payload: mockInitializeContextPayload,
763
+ eventType: TSToChartEvent.Initialize,
764
+ source: 'ts-host-app',
765
+ },
766
+ ports: [{ postMessage: mockPostMessage }],
767
+ });
768
+ eventProcessor({
769
+ data: {
770
+ payload: {},
771
+ eventType: TSToChartEvent.InitializeComplete,
772
+ source: 'ts-host-app',
773
+ },
774
+ ports: [{ postMessage: mockPostMessage }],
775
+ });
776
+ customChartContext.initialize();
777
+ mockPostMessageToHost.mockImplementation(
778
+ () =>
779
+ new global.Promise<any>((res) => {
780
+ resolve = res;
781
+ }),
782
+ );
783
+
784
+ // Define a test event type and payload
785
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenAxisMenu as any;
786
+ const testPayload = {
787
+ customActions: [
788
+ {
789
+ id: 'custom-action-1',
790
+ label: 'Custom user action 1',
791
+ icon: '',
792
+ onClick: mockCustomAction,
793
+ },
794
+ ],
795
+ };
796
+
797
+ // Call the emitEvent function and wait for it to resolve
798
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
799
+ // Check that the result is defined
800
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
801
+ mockInitializeContextPayload.componentId,
802
+ mockInitializeContextPayload.hostUrl,
803
+ {
804
+ customActions: [
805
+ {
806
+ icon: '',
807
+ id: 'custom-action-1',
808
+ label: 'Custom user action 1',
809
+ },
810
+ ],
811
+ },
812
+ TEST_EVENT_TYPE,
813
+ );
814
+
815
+ eventProcessor({
816
+ data: {
817
+ payload: {
818
+ customAction: {
819
+ id: 'custom-action-1',
820
+ columnIds: ['123'],
821
+ event: {},
822
+ },
823
+ },
824
+ eventType: TSToChartEvent.AxisMenuActionClick,
825
+ source: 'ts-host-app',
826
+ },
827
+ ports: [{ postMessage: mockPostMessage }],
828
+ });
829
+ expect(mockCustomAction).toHaveBeenCalled();
830
+ expect(mockCustomAction).toHaveBeenCalledWith({
831
+ id: 'custom-action-1',
832
+ columnIds: ['123'],
833
+ event: {},
834
+ });
835
+ });
836
+
837
+ test('should process the event payload for axis menu when custom actions are not defined', async () => {
838
+ const mockPostMessage = jest.fn();
839
+ let resolve: any;
840
+ eventProcessor({
841
+ data: {
842
+ payload: mockInitializeContextPayload,
843
+ eventType: TSToChartEvent.Initialize,
844
+ source: 'ts-host-app',
845
+ },
846
+ ports: [{ postMessage: mockPostMessage }],
847
+ });
848
+ eventProcessor({
849
+ data: {
850
+ payload: {},
851
+ eventType: TSToChartEvent.InitializeComplete,
852
+ source: 'ts-host-app',
853
+ },
854
+ ports: [{ postMessage: mockPostMessage }],
855
+ });
856
+ customChartContext.initialize();
857
+ mockPostMessageToHost.mockImplementation(
858
+ () =>
859
+ new global.Promise<any>((res) => {
860
+ resolve = res;
861
+ }),
862
+ );
863
+
864
+ // Define a test event type and payload
865
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenAxisMenu as any;
866
+ const testPayload = {};
867
+ // Call the emitEvent function and wait for it to resolve
868
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
869
+ // Check that the result is defined
870
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
871
+ mockInitializeContextPayload.componentId,
872
+ mockInitializeContextPayload.hostUrl,
873
+ {},
874
+ TEST_EVENT_TYPE,
875
+ );
876
+ });
877
+
878
+ test('should process the event payload for context menu when custom actions are not defined', async () => {
879
+ const mockPostMessage = jest.fn();
880
+ let resolve: any;
881
+ eventProcessor({
882
+ data: {
883
+ payload: mockInitializeContextPayload,
884
+ eventType: TSToChartEvent.Initialize,
885
+ source: 'ts-host-app',
886
+ },
887
+ ports: [{ postMessage: mockPostMessage }],
888
+ });
889
+ eventProcessor({
890
+ data: {
891
+ payload: {},
892
+ eventType: TSToChartEvent.InitializeComplete,
893
+ source: 'ts-host-app',
894
+ },
895
+ ports: [{ postMessage: mockPostMessage }],
896
+ });
897
+ customChartContext.initialize();
898
+ mockPostMessageToHost.mockImplementation(
899
+ () =>
900
+ new global.Promise<any>((res) => {
901
+ resolve = res;
902
+ }),
903
+ );
904
+
905
+ // Define a test event type and payload
906
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenContextMenu as any;
907
+ const testPayload = {};
908
+ // Call the emitEvent function and wait for it to resolve
909
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
910
+ // Check that the result is defined
911
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
912
+ mockInitializeContextPayload.componentId,
913
+ mockInitializeContextPayload.hostUrl,
914
+ {},
915
+ TEST_EVENT_TYPE,
916
+ );
917
+ });
608
918
  });
609
919
  });
@@ -5,13 +5,20 @@
5
5
  *
6
6
  * Copyright: ThoughtSpot Inc. 2023
7
7
  */
8
+
8
9
  import _ from 'lodash';
9
10
  import {
11
+ AxisMenuActionHandler,
10
12
  ChartToTSEvent,
11
13
  ChartToTSEventsPayloadMap,
14
+ ContextMenuActionHandler,
15
+ CustomAction,
12
16
  ErrorType,
17
+ OpenAxisMenuEventPayload,
18
+ OpenContextMenuEventPayload,
13
19
  } from '../types/chart-to-ts-event.types';
14
20
  import {
21
+ AppConfig,
15
22
  ChartConfig,
16
23
  ChartModel,
17
24
  ValidationResponse,
@@ -19,8 +26,10 @@ import {
19
26
  } from '../types/common.types';
20
27
  import { ChartConfigEditorDefinition } from '../types/configurator.types';
21
28
  import {
29
+ AxisMenuCustomActionPayload,
22
30
  ChartConfigValidateEventPayload,
23
31
  ChartModelUpdateEventPayload,
32
+ ContextMenuCustomActionPayload,
24
33
  DataUpdateEventPayload,
25
34
  GetDataQueryPayload,
26
35
  GetDataQueryResponsePayload,
@@ -149,6 +158,13 @@ export class CustomChartContext {
149
158
  */
150
159
  private chartModel: ChartModel = {} as any;
151
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
+
152
168
  /**
153
169
  * Chart Props Object to define the workflow of the application
154
170
  *
@@ -185,6 +201,22 @@ export class CustomChartContext {
185
201
  */
186
202
  private triggerInitResolve: () => void = _.noop;
187
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
+
188
220
  /**
189
221
  * Constructor to only accept context props as payload
190
222
  *
@@ -284,6 +316,107 @@ export class CustomChartContext {
284
316
  */
285
317
  public getChartModel = (): ChartModel => this.chartModel;
286
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
+
287
420
  /**
288
421
  * Function to emit Chart to TS Events to the TS application.
289
422
 
@@ -302,10 +435,14 @@ export class CustomChartContext {
302
435
  );
303
436
  return Promise.reject(new Error('Context not initialized'));
304
437
  }
438
+ const processedPayload = this.eventPayloadPreProcessor(
439
+ eventType,
440
+ eventPayload,
441
+ );
305
442
  return PostMessageEventBridge.postMessageToHostApp(
306
443
  this.componentId,
307
444
  this.hostUrl,
308
- eventPayload?.[0] ?? null,
445
+ processedPayload?.[0] ?? null,
309
446
  eventType,
310
447
  );
311
448
  }
@@ -447,6 +584,94 @@ export class CustomChartContext {
447
584
  this.chartContextProps.renderChart(this);
448
585
  });
449
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
+
450
675
  // Register External Events
451
676
  // These events are readable by the developer
452
677
 
@@ -517,6 +742,7 @@ export class CustomChartContext {
517
742
  this.componentId = payload.componentId;
518
743
  this.hostUrl = payload.hostUrl;
519
744
  this.chartModel = payload.chartModel;
745
+ this.appConfig = payload.appConfig ?? {};
520
746
 
521
747
  return this.publishChartContextPropsToHost();
522
748
  };