@thoughtspot/ts-chart-sdk 0.0.2-alpha.2 → 0.0.2-alpha.21

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 (107) hide show
  1. package/README.md +126 -50
  2. package/dist/ts-chart-sdk.d.ts +940 -0
  3. package/lib/index.d.ts +4 -0
  4. package/lib/index.d.ts.map +1 -1
  5. package/lib/index.js +4 -0
  6. package/lib/index.js.map +1 -1
  7. package/lib/main/custom-chart-context.d.ts +22 -7
  8. package/lib/main/custom-chart-context.d.ts.map +1 -1
  9. package/lib/main/custom-chart-context.js +59 -4
  10. package/lib/main/custom-chart-context.js.map +1 -1
  11. package/lib/main/custom-chart-context.spec.js +402 -5
  12. package/lib/main/custom-chart-context.spec.js.map +1 -1
  13. package/lib/main/post-message-event-bridge.js +2 -2
  14. package/lib/main/post-message-event-bridge.js.map +1 -1
  15. package/lib/main/util.spec.d.ts +2 -0
  16. package/lib/main/util.spec.d.ts.map +1 -0
  17. package/lib/main/util.spec.js +31 -0
  18. package/lib/main/util.spec.js.map +1 -0
  19. package/lib/react/use-custom-chart-context.spec.js +54 -3
  20. package/lib/react/use-custom-chart-context.spec.js.map +1 -1
  21. package/lib/test/test-conditional-formatting-utils.d.ts +5 -0
  22. package/lib/test/test-conditional-formatting-utils.d.ts.map +1 -0
  23. package/lib/test/test-conditional-formatting-utils.js +43 -0
  24. package/lib/test/test-conditional-formatting-utils.js.map +1 -0
  25. package/lib/types/answer-column.types.d.ts +57 -1
  26. package/lib/types/answer-column.types.d.ts.map +1 -1
  27. package/lib/types/answer-column.types.js +47 -0
  28. package/lib/types/answer-column.types.js.map +1 -1
  29. package/lib/types/chart-to-ts-event.types.d.ts +2 -0
  30. package/lib/types/chart-to-ts-event.types.d.ts.map +1 -1
  31. package/lib/types/chart-to-ts-event.types.js +1 -0
  32. package/lib/types/chart-to-ts-event.types.js.map +1 -1
  33. package/lib/types/common.types.d.ts +103 -4
  34. package/lib/types/common.types.d.ts.map +1 -1
  35. package/lib/types/common.types.js +15 -1
  36. package/lib/types/common.types.js.map +1 -1
  37. package/lib/types/conditional-formatting.types.d.ts +140 -0
  38. package/lib/types/conditional-formatting.types.d.ts.map +1 -0
  39. package/lib/types/conditional-formatting.types.js +60 -0
  40. package/lib/types/conditional-formatting.types.js.map +1 -0
  41. package/lib/types/configurator.types.d.ts +5 -0
  42. package/lib/types/configurator.types.d.ts.map +1 -1
  43. package/lib/types/number-formatting.types.d.ts +55 -0
  44. package/lib/types/number-formatting.types.d.ts.map +1 -0
  45. package/lib/types/number-formatting.types.js +23 -0
  46. package/lib/types/number-formatting.types.js.map +1 -0
  47. package/lib/types/ts-to-chart-event.types.d.ts +10 -5
  48. package/lib/types/ts-to-chart-event.types.d.ts.map +1 -1
  49. package/lib/types/ts-to-chart-event.types.js.map +1 -1
  50. package/lib/types/visual-prop.types.d.ts +21 -0
  51. package/lib/types/visual-prop.types.d.ts.map +1 -1
  52. package/lib/utils/conditional-formatting/conditional-formatting.d.ts +10 -0
  53. package/lib/utils/conditional-formatting/conditional-formatting.d.ts.map +1 -0
  54. package/lib/utils/conditional-formatting/conditional-formatting.js +103 -0
  55. package/lib/utils/conditional-formatting/conditional-formatting.js.map +1 -0
  56. package/lib/utils/conditional-formatting/conditional-formatting.spec.d.ts +2 -0
  57. package/lib/utils/conditional-formatting/conditional-formatting.spec.d.ts.map +1 -0
  58. package/lib/utils/conditional-formatting/conditional-formatting.spec.js +142 -0
  59. package/lib/utils/conditional-formatting/conditional-formatting.spec.js.map +1 -0
  60. package/lib/utils/date-formatting.d.ts +103 -0
  61. package/lib/utils/date-formatting.d.ts.map +1 -0
  62. package/lib/utils/date-formatting.js +389 -0
  63. package/lib/utils/date-formatting.js.map +1 -0
  64. package/lib/utils/date-formatting.spec.d.ts +2 -0
  65. package/lib/utils/date-formatting.spec.d.ts.map +1 -0
  66. package/lib/utils/date-formatting.spec.js +394 -0
  67. package/lib/utils/date-formatting.spec.js.map +1 -0
  68. package/lib/utils/date-utils.d.ts +6 -0
  69. package/lib/utils/date-utils.d.ts.map +1 -0
  70. package/lib/utils/date-utils.js +20 -0
  71. package/lib/utils/date-utils.js.map +1 -0
  72. package/lib/utils/date-utils.spec.d.ts +2 -0
  73. package/lib/utils/date-utils.spec.d.ts.map +1 -0
  74. package/lib/utils/date-utils.spec.js +63 -0
  75. package/lib/utils/date-utils.spec.js.map +1 -0
  76. package/lib/utils/formatting-util.d.ts +10 -0
  77. package/lib/utils/formatting-util.d.ts.map +1 -0
  78. package/lib/utils/formatting-util.js +78 -0
  79. package/lib/utils/formatting-util.js.map +1 -0
  80. package/lib/utils/formatting-util.spec.d.ts +2 -0
  81. package/lib/utils/formatting-util.spec.d.ts.map +1 -0
  82. package/lib/utils/formatting-util.spec.js +247 -0
  83. package/lib/utils/formatting-util.spec.js.map +1 -0
  84. package/package.json +6 -4
  85. package/src/index.ts +4 -0
  86. package/src/main/custom-chart-context.spec.ts +474 -9
  87. package/src/main/custom-chart-context.ts +246 -12
  88. package/src/main/post-message-event-bridge.ts +1 -1
  89. package/src/main/util.spec.ts +41 -0
  90. package/src/react/use-custom-chart-context.spec.tsx +65 -3
  91. package/src/test/test-conditional-formatting-utils.ts +95 -0
  92. package/src/types/answer-column.types.ts +102 -1
  93. package/src/types/chart-to-ts-event.types.ts +7 -0
  94. package/src/types/common.types.ts +165 -10
  95. package/src/types/conditional-formatting.types.ts +157 -0
  96. package/src/types/configurator.types.ts +21 -0
  97. package/src/types/number-formatting.types.ts +80 -0
  98. package/src/types/ts-to-chart-event.types.ts +38 -6
  99. package/src/types/visual-prop.types.ts +75 -1
  100. package/src/utils/conditional-formatting/conditional-formatting.spec.ts +469 -0
  101. package/src/utils/conditional-formatting/conditional-formatting.ts +229 -0
  102. package/src/utils/date-formatting.spec.ts +511 -0
  103. package/src/utils/date-formatting.ts +679 -0
  104. package/src/utils/date-utils.spec.ts +93 -0
  105. package/src/utils/date-utils.ts +69 -0
  106. package/src/utils/formatting-util.spec.ts +312 -0
  107. package/src/utils/formatting-util.ts +234 -0
@@ -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 { ChartConfigEditorDefinition } from '../types/configurator.types';
28
+ import {
29
+ ChartConfigEditorDefinition,
30
+ ConfigEditorDefinitionSetter,
31
+ } from '../types/configurator.types';
28
32
  import {
29
33
  AxisMenuCustomActionPayload,
30
34
  ChartConfigValidateEventPayload,
@@ -42,16 +46,113 @@ import {
42
46
  VisualPropsUpdateEventPayload,
43
47
  VisualPropsValidateEventPayload,
44
48
  } from '../types/ts-to-chart-event.types';
45
- import { VisualPropEditorDefinition } from '../types/visual-prop.types';
49
+ import {
50
+ VisualEditorDefinitionSetter,
51
+ VisualPropEditorDefinition,
52
+ } from '../types/visual-prop.types';
46
53
  import {
47
54
  globalThis,
48
55
  initMessageListener,
49
56
  postMessageToHostApp,
50
57
  } from './post-message-event-bridge';
51
58
 
59
+ /**
60
+ * Configuration for allowing or disallowing specific TS UI features.
61
+ *
62
+ * @fileoverview
63
+ * This configuration defines the ability to toggle specific features such as
64
+ * column number formatting, conditional formatting, and measure names/values.
65
+ *
66
+ * @version SDK: 0.1 | ThoughtSpot:
67
+ */
52
68
  export type AllowedConfigurations = {
53
- allowColumnNumberFormatting: boolean;
54
- allowColumnConditionalFormatting: boolean;
69
+ /**
70
+ * Allows column-level number formatting.
71
+ *
72
+ * @default false
73
+ * @version SDK: 0.1 | ThoughtSpot:
74
+ */
75
+ allowColumnNumberFormatting?: boolean;
76
+
77
+ /**
78
+ * Allows conditional formatting at the column level.
79
+ * This allows users to apply rules that visually highlight or differentiate data.
80
+ *
81
+ * @default false
82
+ * @version SDK: 0.1 | ThoughtSpot:
83
+ */
84
+ allowColumnConditionalFormatting?: boolean;
85
+
86
+ /**
87
+ * Enables measure_name and measure_values in the chart configuration.
88
+ *
89
+ * @default false
90
+ * @version SDK: 0.1 | ThoughtSpot:
91
+ */
92
+ allowMeasureNamesAndValues?: boolean;
93
+ };
94
+
95
+ /**
96
+ * Configuration parameters for setting chart-specific options.
97
+ *
98
+ * @fileoverview
99
+ * This configuration includes settings for controlling measure name/value columns
100
+ * and batch size limits for data processing.
101
+ *
102
+ * @version SDK: 0.1 | ThoughtSpot:
103
+ */
104
+ export type ChartConfigParameters = {
105
+ /**
106
+ * Configurations related to measure name and value columns.
107
+ * These parameters allow for enabling/disabling and aliasing the columns
108
+ * used to represent measure names and values.
109
+ *
110
+ * @version SDK: 0.1 | ThoughtSpot:
111
+ */
112
+ measureNameValueColumns?: {
113
+ /**
114
+ * Enables or disables the measure_name column.
115
+ *
116
+ * @default false
117
+ * @version SDK: 0.1 | ThoughtSpot:
118
+ */
119
+ enableMeasureNameColumn?: boolean;
120
+
121
+ /**
122
+ * Enables or disables the measure_value column.
123
+ *
124
+ * @default false
125
+ * @version SDK: 0.1 | ThoughtSpot:
126
+ */
127
+ enableMeasureValueColumn?: boolean;
128
+
129
+ /**
130
+ * Alias for the measure_name column.
131
+ * This allows users to define a custom name for the measure_name column.
132
+ *
133
+ * @default 'Measure Name'
134
+ * @version SDK: 0.1 | ThoughtSpot:
135
+ */
136
+ measureNameColumnAlias?: string;
137
+
138
+ /**
139
+ * Alias for the measure_value column.
140
+ * This allows users to define a custom name for the measure_value column.
141
+ *
142
+ * @default 'Measure Value'
143
+ * @version SDK: 0.1 | ThoughtSpot:
144
+ */
145
+ measureValueColumnAlias?: string;
146
+ };
147
+
148
+ /**
149
+ * Limit on the batch size for data processing.
150
+ * This sets an upper limit on how much data can be processed in a single batch.
151
+ *
152
+ * @default 20000
153
+ * @version SDK: 0.1 | ThoughtSpot:
154
+ */
155
+ batchSizeLimit?: number;
55
156
  };
56
157
 
57
158
  export type CustomChartContextProps = {
@@ -108,6 +209,7 @@ export type CustomChartContextProps = {
108
209
  validateVisualProps?: (
109
210
  updatedVisualProps: VisualProps,
110
211
  chartModel: ChartModel,
212
+ activeColumnId?: string,
111
213
  ) => ValidationResponse;
112
214
 
113
215
  /**
@@ -116,7 +218,9 @@ export type CustomChartContextProps = {
116
218
  *
117
219
  * @version SDK: 0.1 | ThoughtSpot:
118
220
  */
119
- chartConfigEditorDefinition?: ChartConfigEditorDefinition[];
221
+ chartConfigEditorDefinition?:
222
+ | ConfigEditorDefinitionSetter
223
+ | ChartConfigEditorDefinition[];
120
224
 
121
225
  /**
122
226
  * Definition to help edit/customize the visual properties from chart settings editor
@@ -127,12 +231,31 @@ export type CustomChartContextProps = {
127
231
  * @returns {@link VisualPropEditorDefinition}
128
232
  * @version SDK: 0.1 | ThoughtSpot:
129
233
  */
130
- visualPropEditorDefinition?: VisualPropEditorDefinition;
234
+ visualPropEditorDefinition?:
235
+ | VisualEditorDefinitionSetter
236
+ | VisualPropEditorDefinition;
131
237
 
132
- // Whether user wants thoughtspot default number and conditional formatting
238
+ /**
239
+ * Optional configuration to toggle native TS UI configurations, such as column number formatting
240
+ * and conditional formatting.
241
+ *
242
+ * @type {AllowedConfigurations}
243
+ * @version SDK: 0.1 | ThoughtSpot:
244
+ */
133
245
  allowedConfigurations?: AllowedConfigurations;
246
+ /**
247
+ * Optional parameters for configuring specific chart-related features, such as measure name and value columns.
248
+ *
249
+ * @type {ChartConfigParameters}
250
+ * @version SDK: 0.1 | ThoughtSpot:
251
+ */
252
+ chartConfigParameters?: ChartConfigParameters;
134
253
  };
135
254
 
255
+ export type ValidationFunctions =
256
+ | CustomChartContextProps['validateVisualProps']
257
+ | CustomChartContextProps['validateConfig'];
258
+
136
259
  /**
137
260
  * Default configuration options for all the chart context properties
138
261
  */
@@ -143,6 +266,16 @@ const DEFAULT_CHART_CONTEXT_PROPS: Partial<CustomChartContextProps> = {
143
266
  allowedConfigurations: {
144
267
  allowColumnNumberFormatting: false,
145
268
  allowColumnConditionalFormatting: false,
269
+ allowMeasureNamesAndValues: false,
270
+ },
271
+ chartConfigParameters: {
272
+ measureNameValueColumns: {
273
+ enableMeasureNameColumn: false,
274
+ enableMeasureValueColumn: false,
275
+ measureNameColumnAlias: 'Measure Name',
276
+ measureValueColumnAlias: 'Measure Values',
277
+ },
278
+ batchSizeLimit: 20000,
146
279
  },
147
280
  };
148
281
 
@@ -252,6 +385,9 @@ export class CustomChartContext {
252
385
  this.hasInitializedPromise = new Promise((resolve, reject) => {
253
386
  this.triggerInitResolve = resolve;
254
387
  });
388
+ // Not using this.emitEvent as the context is not yet completely
389
+ // initialized, thus short circuiting.
390
+ postMessageToHostApp('', '*', null, ChartToTSEvent.InitStart);
255
391
  }
256
392
 
257
393
  /**
@@ -379,6 +515,50 @@ export class CustomChartContext {
379
515
  return processedPayload;
380
516
  }
381
517
 
518
+ /**
519
+ * Funtions return the chart config editor definition
520
+ * @param {ChartConfig[]} currentChartConfig
521
+ * @param {VisualProps}
522
+ * @returns {ChartConfigEditorDefinition[]}
523
+ */
524
+ private getChartConfigEditorDefinition = (
525
+ currentState: Partial<ChartModel> = {},
526
+ ) => {
527
+ if (_.isFunction(this.chartContextProps.chartConfigEditorDefinition)) {
528
+ return this.chartContextProps.chartConfigEditorDefinition(
529
+ {
530
+ ...this.chartModel,
531
+ ...currentState,
532
+ },
533
+ this,
534
+ );
535
+ }
536
+ return this.chartContextProps.chartConfigEditorDefinition;
537
+ };
538
+
539
+ /**
540
+ * Funtions returns the visual prop editor definition
541
+ * @param {ChartConfig[]} currentChartConfig
542
+ * @param {VisualProps}
543
+ * @returns {VisualPropEditorDefinition}
544
+ */
545
+ private getVisualPropEditorDefinition = (
546
+ activeColumnId?: string,
547
+ currentState: Partial<ChartModel> = {},
548
+ ) => {
549
+ if (_.isFunction(this.chartContextProps.visualPropEditorDefinition)) {
550
+ return this.chartContextProps.visualPropEditorDefinition(
551
+ {
552
+ ...this.chartModel,
553
+ ...currentState,
554
+ },
555
+ this,
556
+ activeColumnId,
557
+ );
558
+ }
559
+ return this.chartContextProps.visualPropEditorDefinition;
560
+ };
561
+
382
562
  /**
383
563
  * Function to store the axis menu custom action callback mapped with action id
384
564
  * @param {[OpenAxisMenuEventPayload]} eventPayload Event payload bound
@@ -438,6 +618,26 @@ export class CustomChartContext {
438
618
  }
439
619
  }
440
620
 
621
+ private validationsResponseProcessor(
622
+ currentValidationState: Partial<ChartModel>,
623
+ validationResponse: ValidationResponse,
624
+ activeColumnId?: string,
625
+ ) {
626
+ const visualPropEditorDefinition = this.getVisualPropEditorDefinition(
627
+ activeColumnId,
628
+ currentValidationState,
629
+ );
630
+ const chartConfigEditorDefinition = this.getChartConfigEditorDefinition(
631
+ currentValidationState,
632
+ );
633
+
634
+ return {
635
+ ...validationResponse,
636
+ visualPropEditorDefinition,
637
+ chartConfigEditorDefinition,
638
+ };
639
+ }
640
+
441
641
  /**
442
642
  * Function to emit Chart to TS Events to the TS application.
443
643
 
@@ -495,7 +695,7 @@ export class CustomChartContext {
495
695
  const messageResponse = this.executeEventListenerCBs(data);
496
696
 
497
697
  // respond back to parent to confirm/ack the receipt
498
- return messageResponse;
698
+ return messageResponse || {};
499
699
  };
500
700
 
501
701
  /**
@@ -530,13 +730,29 @@ export class CustomChartContext {
530
730
  */
531
731
  this.onInternal(
532
732
  TSToChartEvent.VisualPropsValidate,
533
- (payload: VisualPropsValidateEventPayload): ValidationResponse => {
733
+ (
734
+ payload: VisualPropsValidateEventPayload,
735
+ ):
736
+ | (ValidationResponse & SuccessValidationResponse)
737
+ | ValidationResponse => {
534
738
  if (this.chartContextProps.validateVisualProps) {
535
739
  const validationResponse =
536
740
  this.chartContextProps.validateVisualProps(
537
741
  payload.visualProps,
538
742
  this.chartModel,
743
+ payload?.activeColumnId,
744
+ );
745
+ if (validationResponse.isValid) {
746
+ const currentVisualState = {
747
+ visualProps: payload.visualProps,
748
+ };
749
+ const activeColumnId = payload?.activeColumnId;
750
+ return this.validationsResponseProcessor(
751
+ currentVisualState,
752
+ validationResponse,
753
+ activeColumnId,
539
754
  );
755
+ }
540
756
  return validationResponse;
541
757
  }
542
758
  // this will never be true
@@ -551,13 +767,29 @@ export class CustomChartContext {
551
767
  */
552
768
  this.onInternal(
553
769
  TSToChartEvent.ChartConfigValidate,
554
- (payload: ChartConfigValidateEventPayload): ValidationResponse => {
770
+ (
771
+ payload: ChartConfigValidateEventPayload,
772
+ ):
773
+ | (ValidationResponse & SuccessValidationResponse)
774
+ | ValidationResponse => {
555
775
  if (this.chartContextProps.validateConfig) {
556
776
  const validationResponse =
557
777
  this.chartContextProps.validateConfig(
558
778
  payload.chartConfig,
559
779
  this.chartModel,
560
780
  );
781
+ if (validationResponse.isValid) {
782
+ const currentConfigState = {
783
+ config: {
784
+ ...this.chartModel.config,
785
+ chartConfig: payload.chartConfig,
786
+ },
787
+ };
788
+ return this.validationsResponseProcessor(
789
+ currentConfigState,
790
+ validationResponse,
791
+ );
792
+ }
561
793
  return validationResponse;
562
794
  }
563
795
  // this will never be true
@@ -789,11 +1021,13 @@ export class CustomChartContext {
789
1021
  isConfigValid: isValid,
790
1022
  defaultChartConfig,
791
1023
  chartConfigEditorDefinition:
792
- this.chartContextProps.chartConfigEditorDefinition,
1024
+ this.getChartConfigEditorDefinition(),
793
1025
  visualPropEditorDefinition:
794
- this.chartContextProps.visualPropEditorDefinition,
1026
+ this.getVisualPropEditorDefinition(),
795
1027
  allowedConfigurations:
796
1028
  this.chartContextProps.allowedConfigurations,
1029
+ chartConfigParameters:
1030
+ this.chartContextProps.chartConfigParameters,
797
1031
  };
798
1032
  };
799
1033
 
@@ -53,7 +53,7 @@ const postMessageToHostApp = async (
53
53
  TIMEOUT_THRESHOLD,
54
54
  'ChartContext: postMessage operation timed out.',
55
55
  );
56
- if (resp.hasError) {
56
+ if (resp?.hasError) {
57
57
  throw new Error(resp.error);
58
58
  }
59
59
  return resp;
@@ -0,0 +1,41 @@
1
+ import { timeout } from './util';
2
+
3
+ describe('timeout function', () => {
4
+ jest.useFakeTimers();
5
+
6
+ it('should resolve with the original promise result if it completes before timeout', async () => {
7
+ const promise = Promise.resolve('success');
8
+ const result = timeout(promise, 1000);
9
+
10
+ await expect(result).resolves.toBe('success');
11
+ });
12
+
13
+ it('should reject with a timeout error if the promise takes too long', async () => {
14
+ const promise = new Promise((resolve) => {
15
+ setTimeout(resolve, 2000);
16
+ });
17
+ const result = timeout(promise, 1000);
18
+
19
+ jest.advanceTimersByTime(1000);
20
+
21
+ await expect(result).rejects.toThrow('Operation timed out.');
22
+ });
23
+
24
+ it('should use the custom error message when provided', async () => {
25
+ const promise = new Promise((resolve) => {
26
+ setTimeout(resolve, 2000);
27
+ });
28
+ const result = timeout(promise, 1000, 'Custom timeout message');
29
+
30
+ jest.advanceTimersByTime(1000);
31
+
32
+ await expect(result).rejects.toThrow('Custom timeout message');
33
+ });
34
+
35
+ it('should reject with the original promise error if it rejects before timeout', async () => {
36
+ const promise = Promise.reject(new Error('Original error'));
37
+ const result = timeout(promise, 1000);
38
+
39
+ await expect(result).rejects.toThrow('Original error');
40
+ });
41
+ });
@@ -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 = { columns: [], config: {} };
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
  }));
@@ -173,7 +236,6 @@ describe('useChartContext emit', () => {
173
236
  });
174
237
  const promise = result.current.emitRenderStart();
175
238
  await expect(promise).rejects.toThrow('Context not initialized');
176
- expect(mockPostMessageToHost).not.toHaveBeenCalled();
177
239
  });
178
240
  });
179
241
 
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @file: Test Conditional Formatting Utils
3
+ *
4
+ * @author Yashvardhan Nehra <yashvardhan.nehra@thoughtspot.com>
5
+ *
6
+ * Copyright: ThoughtSpot Inc. 2023
7
+ */
8
+ import {
9
+ BackgroundFormatTypes,
10
+ ConditionalFormattingComparisonTypes,
11
+ ConditionalMetric,
12
+ Operators,
13
+ } from '../types/conditional-formatting.types';
14
+
15
+ /**
16
+ * Creates a metric operator for conditional formatting.
17
+ *
18
+ * @param operator - The operator to use for the metric (e.g., LessThan, GreaterThan).
19
+ * @param lhsColumnId - (Optional) The ID of the left-hand side column.
20
+ * @param rhsColumnId - (Optional) The ID of the right-hand side column.
21
+ * @param comparisonParameterId - (Optional) The ID of the comparison parameter.
22
+ * @param comparisonType - The type of comparison to use (default is ValueBased).
23
+ * @returns A ConditionalMetric object configured with the specified parameters.
24
+ */
25
+ export const createMetricOperator = (
26
+ operator: Operators,
27
+ lhsColumnId?: string,
28
+ rhsColumnId?: string,
29
+ comparisonParameterId?: string,
30
+ comparisonType = ConditionalFormattingComparisonTypes.ValueBased,
31
+ ): ConditionalMetric => {
32
+ return {
33
+ solidBackgroundAttrs: {
34
+ color: '#000',
35
+ },
36
+ backgroundFormatType: 'SOLID' as BackgroundFormatTypes,
37
+ operator,
38
+ value: '200',
39
+ plotAsBand: false,
40
+ comparisonParameterId,
41
+ comparisonType,
42
+ lhsColumnId,
43
+ rhsColumnId,
44
+ };
45
+ };
46
+
47
+ /**
48
+ * Creates a between metric operator for conditional formatting.
49
+ *
50
+ * @param operator - The operator to use for the metric (e.g., IsBetween).
51
+ * @param min - The minimum value for the range (default is 100).
52
+ * @param max - The maximum value for the range (default is 200).
53
+ * @returns A ConditionalMetric object configured with the specified parameters.
54
+ */
55
+ export const createBetweenMetricOperator = (
56
+ operator: Operators,
57
+ min = 100,
58
+ max = 200,
59
+ ): ConditionalMetric => {
60
+ return {
61
+ backgroundFormatType: 'SOLID' as BackgroundFormatTypes,
62
+ solidBackgroundAttrs: {
63
+ color: '#000',
64
+ },
65
+ operator,
66
+ rangeValues: {
67
+ min,
68
+ max,
69
+ },
70
+ plotAsBand: false,
71
+ lhsColumnId: undefined,
72
+ rhsColumnId: undefined,
73
+ comparisonParameterId: undefined,
74
+ comparisonType: ConditionalFormattingComparisonTypes.ValueBased,
75
+ };
76
+ };
77
+
78
+ /**
79
+ * Creates an attribute operator for conditional formatting.
80
+ *
81
+ * @param operator - The operator to use for the attribute (e.g., Is, IsNot).
82
+ * @param comparisonType - (Optional) The type of comparison to use.
83
+ * @returns A ConditionalMetric object configured with the specified parameters.
84
+ */
85
+ export const createAttributeOperator = (
86
+ operator: Operators,
87
+ comparisonType?: ConditionalFormattingComparisonTypes,
88
+ ): ConditionalMetric => {
89
+ return {
90
+ backgroundFormatType: 'SOLID' as BackgroundFormatTypes,
91
+ operator,
92
+ value: 'check attribute',
93
+ comparisonType,
94
+ };
95
+ };