@thoughtspot/ts-chart-sdk 2.4.0 → 2.4.2
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/dist/ts-chart-sdk.d.ts +20 -8
- package/lib/main/custom-chart-context.d.ts.map +1 -1
- package/lib/main/custom-chart-context.js +27 -6
- package/lib/main/custom-chart-context.js.map +1 -1
- package/lib/main/custom-chart-context.spec.js +293 -0
- package/lib/main/custom-chart-context.spec.js.map +1 -1
- package/lib/types/chart-to-ts-event.types.d.ts +17 -9
- package/lib/types/chart-to-ts-event.types.d.ts.map +1 -1
- package/lib/types/chart-to-ts-event.types.js +1 -0
- package/lib/types/chart-to-ts-event.types.js.map +1 -1
- package/lib/types/common.types.d.ts +4 -0
- package/lib/types/common.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/main/custom-chart-context.spec.ts +431 -0
- package/src/main/custom-chart-context.ts +26 -5
- package/src/types/chart-to-ts-event.types.ts +53 -20
- package/src/types/common.types.ts +9 -0
|
@@ -890,6 +890,437 @@ describe('CustomChartContext', () => {
|
|
|
890
890
|
error: `Event type not recognised or processed: ${TEST_EVENT_TYPE}`,
|
|
891
891
|
});
|
|
892
892
|
});
|
|
893
|
+
|
|
894
|
+
describe('axisMenuCustomActionPreProcessor', () => {
|
|
895
|
+
let customChartContext: CustomChartContext;
|
|
896
|
+
|
|
897
|
+
beforeEach(() => {
|
|
898
|
+
customChartContext = new CustomChartContext({
|
|
899
|
+
getDefaultChartConfig,
|
|
900
|
+
getQueriesFromChartConfig,
|
|
901
|
+
renderChart,
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
afterEach(() => {
|
|
906
|
+
customChartContext.destroy();
|
|
907
|
+
eventProcessor = null;
|
|
908
|
+
jest.resetAllMocks();
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
test('should return original payload when customActions is empty', () => {
|
|
912
|
+
const eventPayload = [
|
|
913
|
+
{
|
|
914
|
+
customActions: [],
|
|
915
|
+
event: { clientX: 100, clientY: 200 },
|
|
916
|
+
},
|
|
917
|
+
];
|
|
918
|
+
|
|
919
|
+
const result =
|
|
920
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
921
|
+
eventPayload as any,
|
|
922
|
+
);
|
|
923
|
+
|
|
924
|
+
expect(result).toEqual(eventPayload);
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
test('should return original payload when customActions is undefined', () => {
|
|
928
|
+
const eventPayload = [
|
|
929
|
+
{
|
|
930
|
+
customActions: undefined,
|
|
931
|
+
event: { clientX: 100, clientY: 200 },
|
|
932
|
+
},
|
|
933
|
+
];
|
|
934
|
+
|
|
935
|
+
const result =
|
|
936
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
937
|
+
eventPayload as any,
|
|
938
|
+
);
|
|
939
|
+
|
|
940
|
+
expect(result).toEqual(eventPayload);
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
test('should process basic custom actions correctly', () => {
|
|
944
|
+
const mockOnClick = jest.fn();
|
|
945
|
+
const eventPayload = [
|
|
946
|
+
{
|
|
947
|
+
customActions: [
|
|
948
|
+
{
|
|
949
|
+
id: 'action-1',
|
|
950
|
+
label: 'Action 1',
|
|
951
|
+
icon: 'icon-1',
|
|
952
|
+
onClick: mockOnClick,
|
|
953
|
+
itemDisabled: false,
|
|
954
|
+
itemDisabledTooltip: 'Tooltip 1',
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
id: 'action-2',
|
|
958
|
+
label: 'Action 2',
|
|
959
|
+
icon: 'icon-2',
|
|
960
|
+
onClick: undefined,
|
|
961
|
+
itemDisabled: true,
|
|
962
|
+
itemDisabledTooltip: 'Tooltip 2',
|
|
963
|
+
},
|
|
964
|
+
],
|
|
965
|
+
event: { clientX: 100, clientY: 200 },
|
|
966
|
+
},
|
|
967
|
+
];
|
|
968
|
+
|
|
969
|
+
const result =
|
|
970
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
971
|
+
eventPayload as any,
|
|
972
|
+
);
|
|
973
|
+
|
|
974
|
+
// Verify the processed payload structure
|
|
975
|
+
expect(result[0].customActions).toHaveLength(2);
|
|
976
|
+
expect(result[0].customActions?.[0]).toEqual({
|
|
977
|
+
id: 'action-1',
|
|
978
|
+
label: 'Action 1',
|
|
979
|
+
icon: 'icon-1',
|
|
980
|
+
itemDisabled: false,
|
|
981
|
+
itemDisabledTooltip: 'Tooltip 1',
|
|
982
|
+
cascadingItems: undefined,
|
|
983
|
+
});
|
|
984
|
+
expect(result[0].customActions?.[1]).toEqual({
|
|
985
|
+
id: 'action-2',
|
|
986
|
+
label: 'Action 2',
|
|
987
|
+
icon: 'icon-2',
|
|
988
|
+
itemDisabled: true,
|
|
989
|
+
itemDisabledTooltip: 'Tooltip 2',
|
|
990
|
+
cascadingItems: undefined,
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
// Verify callbacks are stored in handler
|
|
994
|
+
expect(
|
|
995
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
996
|
+
'action-1'
|
|
997
|
+
],
|
|
998
|
+
).toBe(mockOnClick);
|
|
999
|
+
expect(
|
|
1000
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1001
|
+
'action-2'
|
|
1002
|
+
],
|
|
1003
|
+
).toBe(_.noop);
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
test('should process cascading items correctly', () => {
|
|
1007
|
+
const mockParentOnClick = jest.fn();
|
|
1008
|
+
const mockChildOnClick = jest.fn();
|
|
1009
|
+
const eventPayload = [
|
|
1010
|
+
{
|
|
1011
|
+
customActions: [
|
|
1012
|
+
{
|
|
1013
|
+
id: 'parent-action',
|
|
1014
|
+
label: 'Parent Action',
|
|
1015
|
+
icon: 'parent-icon',
|
|
1016
|
+
onClick: mockParentOnClick,
|
|
1017
|
+
cascadingItems: [
|
|
1018
|
+
{
|
|
1019
|
+
title: 'Submenu 1',
|
|
1020
|
+
items: [
|
|
1021
|
+
{
|
|
1022
|
+
id: 'child-action-1',
|
|
1023
|
+
label: 'Child Action 1',
|
|
1024
|
+
icon: 'child-icon-1',
|
|
1025
|
+
onClick: mockChildOnClick,
|
|
1026
|
+
itemDisabled: false,
|
|
1027
|
+
itemDisabledTooltip:
|
|
1028
|
+
'Child Tooltip 1',
|
|
1029
|
+
isSelected: true,
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
id: 'child-action-2',
|
|
1033
|
+
label: 'Child Action 2',
|
|
1034
|
+
icon: 'child-icon-2',
|
|
1035
|
+
onClick: undefined,
|
|
1036
|
+
itemDisabled: true,
|
|
1037
|
+
itemDisabledTooltip:
|
|
1038
|
+
'Child Tooltip 2',
|
|
1039
|
+
isSelected: false,
|
|
1040
|
+
},
|
|
1041
|
+
],
|
|
1042
|
+
},
|
|
1043
|
+
],
|
|
1044
|
+
},
|
|
1045
|
+
],
|
|
1046
|
+
event: { clientX: 100, clientY: 200 },
|
|
1047
|
+
},
|
|
1048
|
+
];
|
|
1049
|
+
|
|
1050
|
+
const result =
|
|
1051
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
1052
|
+
eventPayload as any,
|
|
1053
|
+
);
|
|
1054
|
+
|
|
1055
|
+
// Verify the processed payload structure
|
|
1056
|
+
expect(result[0].customActions).toHaveLength(1);
|
|
1057
|
+
expect(
|
|
1058
|
+
result[0].customActions?.[0]?.cascadingItems,
|
|
1059
|
+
).toHaveLength(1);
|
|
1060
|
+
expect(
|
|
1061
|
+
result[0].customActions?.[0]?.cascadingItems?.[0],
|
|
1062
|
+
).toEqual({
|
|
1063
|
+
title: 'Submenu 1',
|
|
1064
|
+
items: [
|
|
1065
|
+
{
|
|
1066
|
+
id: 'child-action-1',
|
|
1067
|
+
label: 'Child Action 1',
|
|
1068
|
+
icon: 'child-icon-1',
|
|
1069
|
+
itemDisabled: false,
|
|
1070
|
+
itemDisabledTooltip: 'Child Tooltip 1',
|
|
1071
|
+
isSelected: true,
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
id: 'child-action-2',
|
|
1075
|
+
label: 'Child Action 2',
|
|
1076
|
+
icon: 'child-icon-2',
|
|
1077
|
+
itemDisabled: true,
|
|
1078
|
+
itemDisabledTooltip: 'Child Tooltip 2',
|
|
1079
|
+
isSelected: false,
|
|
1080
|
+
},
|
|
1081
|
+
],
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
// Verify callbacks are stored in handler
|
|
1085
|
+
expect(
|
|
1086
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1087
|
+
'parent-action'
|
|
1088
|
+
],
|
|
1089
|
+
).toBe(mockParentOnClick);
|
|
1090
|
+
expect(
|
|
1091
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1092
|
+
'child-action-1'
|
|
1093
|
+
],
|
|
1094
|
+
).toBe(mockChildOnClick);
|
|
1095
|
+
expect(
|
|
1096
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1097
|
+
'child-action-2'
|
|
1098
|
+
],
|
|
1099
|
+
).toBe(_.noop);
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
test('should handle multiple cascading items', () => {
|
|
1103
|
+
const mockOnClick = jest.fn();
|
|
1104
|
+
const eventPayload = [
|
|
1105
|
+
{
|
|
1106
|
+
customActions: [
|
|
1107
|
+
{
|
|
1108
|
+
id: 'parent-action',
|
|
1109
|
+
label: 'Parent Action',
|
|
1110
|
+
icon: 'parent-icon',
|
|
1111
|
+
onClick: mockOnClick,
|
|
1112
|
+
cascadingItems: [
|
|
1113
|
+
{
|
|
1114
|
+
title: 'Submenu 1',
|
|
1115
|
+
items: [
|
|
1116
|
+
{
|
|
1117
|
+
id: 'child-1-1',
|
|
1118
|
+
label: 'Child 1-1',
|
|
1119
|
+
icon: 'child-icon-1-1',
|
|
1120
|
+
onClick: mockOnClick,
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
id: 'child-1-2',
|
|
1124
|
+
label: 'Child 1-2',
|
|
1125
|
+
icon: 'child-icon-1-2',
|
|
1126
|
+
onClick: mockOnClick,
|
|
1127
|
+
},
|
|
1128
|
+
],
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
title: 'Submenu 2',
|
|
1132
|
+
items: [
|
|
1133
|
+
{
|
|
1134
|
+
id: 'child-2-1',
|
|
1135
|
+
label: 'Child 2-1',
|
|
1136
|
+
icon: 'child-icon-2-1',
|
|
1137
|
+
onClick: mockOnClick,
|
|
1138
|
+
},
|
|
1139
|
+
],
|
|
1140
|
+
},
|
|
1141
|
+
],
|
|
1142
|
+
},
|
|
1143
|
+
],
|
|
1144
|
+
event: { clientX: 100, clientY: 200 },
|
|
1145
|
+
},
|
|
1146
|
+
];
|
|
1147
|
+
|
|
1148
|
+
const result =
|
|
1149
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
1150
|
+
eventPayload as any,
|
|
1151
|
+
);
|
|
1152
|
+
|
|
1153
|
+
// Verify the processed payload structure
|
|
1154
|
+
expect(result[0].customActions).toHaveLength(1);
|
|
1155
|
+
expect(
|
|
1156
|
+
result[0].customActions?.[0]?.cascadingItems,
|
|
1157
|
+
).toHaveLength(2);
|
|
1158
|
+
expect(
|
|
1159
|
+
result[0].customActions?.[0]?.cascadingItems?.[0]?.title,
|
|
1160
|
+
).toBe('Submenu 1');
|
|
1161
|
+
expect(
|
|
1162
|
+
result[0].customActions?.[0]?.cascadingItems?.[0]?.items,
|
|
1163
|
+
).toHaveLength(2);
|
|
1164
|
+
expect(
|
|
1165
|
+
result[0].customActions?.[0]?.cascadingItems?.[1]?.title,
|
|
1166
|
+
).toBe('Submenu 2');
|
|
1167
|
+
expect(
|
|
1168
|
+
result[0].customActions?.[0]?.cascadingItems?.[1]?.items,
|
|
1169
|
+
).toHaveLength(1);
|
|
1170
|
+
|
|
1171
|
+
// Verify callbacks are stored in handler
|
|
1172
|
+
expect(
|
|
1173
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1174
|
+
'parent-action'
|
|
1175
|
+
],
|
|
1176
|
+
).toBe(mockOnClick);
|
|
1177
|
+
expect(
|
|
1178
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1179
|
+
'child-1-1'
|
|
1180
|
+
],
|
|
1181
|
+
).toBe(mockOnClick);
|
|
1182
|
+
expect(
|
|
1183
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1184
|
+
'child-1-2'
|
|
1185
|
+
],
|
|
1186
|
+
).toBe(mockOnClick);
|
|
1187
|
+
expect(
|
|
1188
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1189
|
+
'child-2-1'
|
|
1190
|
+
],
|
|
1191
|
+
).toBe(mockOnClick);
|
|
1192
|
+
});
|
|
1193
|
+
|
|
1194
|
+
test('should clear existing axisMenuActionHandler before processing', () => {
|
|
1195
|
+
// First, add some existing handlers
|
|
1196
|
+
(customChartContext as any).axisMenuActionHandler = {
|
|
1197
|
+
'existing-action': jest.fn(),
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
const eventPayload = [
|
|
1201
|
+
{
|
|
1202
|
+
customActions: [
|
|
1203
|
+
{
|
|
1204
|
+
id: 'new-action',
|
|
1205
|
+
label: 'New Action',
|
|
1206
|
+
icon: 'new-icon',
|
|
1207
|
+
onClick: jest.fn(),
|
|
1208
|
+
},
|
|
1209
|
+
],
|
|
1210
|
+
event: { clientX: 100, clientY: 200 },
|
|
1211
|
+
},
|
|
1212
|
+
];
|
|
1213
|
+
|
|
1214
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
1215
|
+
eventPayload as any,
|
|
1216
|
+
);
|
|
1217
|
+
|
|
1218
|
+
// Verify that only the new action handler exists
|
|
1219
|
+
expect(
|
|
1220
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1221
|
+
'existing-action'
|
|
1222
|
+
],
|
|
1223
|
+
).toBeUndefined();
|
|
1224
|
+
expect(
|
|
1225
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1226
|
+
'new-action'
|
|
1227
|
+
],
|
|
1228
|
+
).toBeDefined();
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
test('should handle mixed actions with and without cascading items', () => {
|
|
1232
|
+
const mockOnClick = jest.fn();
|
|
1233
|
+
const eventPayload = [
|
|
1234
|
+
{
|
|
1235
|
+
customActions: [
|
|
1236
|
+
{
|
|
1237
|
+
id: 'simple-action',
|
|
1238
|
+
label: 'Simple Action',
|
|
1239
|
+
icon: 'simple-icon',
|
|
1240
|
+
onClick: mockOnClick,
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
id: 'complex-action',
|
|
1244
|
+
label: 'Complex Action',
|
|
1245
|
+
icon: 'complex-icon',
|
|
1246
|
+
onClick: mockOnClick,
|
|
1247
|
+
cascadingItems: [
|
|
1248
|
+
{
|
|
1249
|
+
title: 'Submenu',
|
|
1250
|
+
items: [
|
|
1251
|
+
{
|
|
1252
|
+
id: 'nested-action',
|
|
1253
|
+
label: 'Nested Action',
|
|
1254
|
+
icon: 'nested-icon',
|
|
1255
|
+
onClick: mockOnClick,
|
|
1256
|
+
},
|
|
1257
|
+
],
|
|
1258
|
+
},
|
|
1259
|
+
],
|
|
1260
|
+
},
|
|
1261
|
+
],
|
|
1262
|
+
event: { clientX: 100, clientY: 200 },
|
|
1263
|
+
},
|
|
1264
|
+
];
|
|
1265
|
+
|
|
1266
|
+
const result =
|
|
1267
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
1268
|
+
eventPayload as any,
|
|
1269
|
+
);
|
|
1270
|
+
|
|
1271
|
+
// Verify the processed payload structure
|
|
1272
|
+
expect(result[0].customActions).toHaveLength(2);
|
|
1273
|
+
expect(
|
|
1274
|
+
result[0].customActions?.[0]?.cascadingItems,
|
|
1275
|
+
).toBeUndefined();
|
|
1276
|
+
expect(
|
|
1277
|
+
result[0].customActions?.[1]?.cascadingItems,
|
|
1278
|
+
).toBeDefined();
|
|
1279
|
+
|
|
1280
|
+
// Verify callbacks are stored in handler
|
|
1281
|
+
expect(
|
|
1282
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1283
|
+
'simple-action'
|
|
1284
|
+
],
|
|
1285
|
+
).toBe(mockOnClick);
|
|
1286
|
+
expect(
|
|
1287
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1288
|
+
'complex-action'
|
|
1289
|
+
],
|
|
1290
|
+
).toBe(mockOnClick);
|
|
1291
|
+
expect(
|
|
1292
|
+
(customChartContext as any).axisMenuActionHandler[
|
|
1293
|
+
'nested-action'
|
|
1294
|
+
],
|
|
1295
|
+
).toBe(mockOnClick);
|
|
1296
|
+
});
|
|
1297
|
+
|
|
1298
|
+
test('should preserve original event and other properties', () => {
|
|
1299
|
+
const eventPayload = [
|
|
1300
|
+
{
|
|
1301
|
+
customActions: [
|
|
1302
|
+
{
|
|
1303
|
+
id: 'action-1',
|
|
1304
|
+
label: 'Action 1',
|
|
1305
|
+
icon: 'icon-1',
|
|
1306
|
+
onClick: jest.fn(),
|
|
1307
|
+
},
|
|
1308
|
+
],
|
|
1309
|
+
event: { clientX: 100, clientY: 200 },
|
|
1310
|
+
otherProperty: 'other-value',
|
|
1311
|
+
},
|
|
1312
|
+
];
|
|
1313
|
+
|
|
1314
|
+
const result =
|
|
1315
|
+
customChartContext.axisMenuCustomActionPreProcessor(
|
|
1316
|
+
eventPayload as any,
|
|
1317
|
+
);
|
|
1318
|
+
|
|
1319
|
+
// Verify original properties are preserved
|
|
1320
|
+
expect(result[0].event).toEqual({ clientX: 100, clientY: 200 });
|
|
1321
|
+
expect((result[0] as any).otherProperty).toBe('other-value');
|
|
1322
|
+
});
|
|
1323
|
+
});
|
|
893
1324
|
});
|
|
894
1325
|
|
|
895
1326
|
describe('off', () => {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ChartToTSEventsPayloadMap,
|
|
14
14
|
ContextMenuActionHandler,
|
|
15
15
|
CustomAction,
|
|
16
|
+
CustomActionMenuItemGroup,
|
|
16
17
|
ErrorType,
|
|
17
18
|
OpenAxisMenuEventPayload,
|
|
18
19
|
OpenContextMenuEventPayload,
|
|
@@ -37,7 +38,6 @@ import {
|
|
|
37
38
|
ContextMenuCustomActionPayload,
|
|
38
39
|
DataUpdateEventPayload,
|
|
39
40
|
DownloadExcelTriggerPayload,
|
|
40
|
-
DownloadExcelTriggerResponse,
|
|
41
41
|
GetColumnDataPayload,
|
|
42
42
|
GetColumnDataResponsePayload,
|
|
43
43
|
GetDataQueryPayload,
|
|
@@ -555,7 +555,7 @@ export class CustomChartContext {
|
|
|
555
555
|
return eventPayload;
|
|
556
556
|
}
|
|
557
557
|
eventPayload?.[0]?.customActions?.forEach((action: CustomAction) => {
|
|
558
|
-
this.contextMenuActionHandler[action.id] = action.onClick;
|
|
558
|
+
this.contextMenuActionHandler[action.id] = action.onClick ?? _.noop;
|
|
559
559
|
});
|
|
560
560
|
const processedCustomActions = eventPayload[0]?.customActions?.map(
|
|
561
561
|
(action: CustomAction) => {
|
|
@@ -633,15 +633,36 @@ export class CustomChartContext {
|
|
|
633
633
|
if (_.isEmpty(eventPayload?.[0]?.customActions)) {
|
|
634
634
|
return eventPayload;
|
|
635
635
|
}
|
|
636
|
-
eventPayload[0].customActions?.forEach((action: CustomAction) => {
|
|
637
|
-
this.axisMenuActionHandler[action.id] = action.onClick;
|
|
638
|
-
});
|
|
639
636
|
const processedCustomActions = eventPayload?.[0].customActions?.map(
|
|
640
637
|
(action: CustomAction) => {
|
|
638
|
+
this.axisMenuActionHandler[action.id] =
|
|
639
|
+
action.onClick ?? _.noop;
|
|
641
640
|
return {
|
|
642
641
|
id: action.id,
|
|
643
642
|
label: action.label,
|
|
644
643
|
icon: action.icon,
|
|
644
|
+
itemDisabled: action.itemDisabled,
|
|
645
|
+
itemDisabledTooltip: action.itemDisabledTooltip,
|
|
646
|
+
cascadingItems: action.cascadingItems?.map(
|
|
647
|
+
(item: CustomActionMenuItemGroup) => {
|
|
648
|
+
return {
|
|
649
|
+
title: item.title,
|
|
650
|
+
items: item.items.map((item: CustomAction) => {
|
|
651
|
+
this.axisMenuActionHandler[item.id] =
|
|
652
|
+
item.onClick ?? _.noop;
|
|
653
|
+
return {
|
|
654
|
+
id: item.id,
|
|
655
|
+
label: item.label,
|
|
656
|
+
icon: item.icon,
|
|
657
|
+
itemDisabled: item.itemDisabled,
|
|
658
|
+
itemDisabledTooltip:
|
|
659
|
+
item.itemDisabledTooltip,
|
|
660
|
+
isSelected: item.isSelected,
|
|
661
|
+
};
|
|
662
|
+
}),
|
|
663
|
+
};
|
|
664
|
+
},
|
|
665
|
+
),
|
|
645
666
|
};
|
|
646
667
|
},
|
|
647
668
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VisualProps } from './common.types';
|
|
1
|
+
import { ChartConfig, VisualProps } from './common.types';
|
|
2
2
|
import {
|
|
3
3
|
CustomAxisMenuAction,
|
|
4
4
|
CustomContextMenuAction,
|
|
@@ -65,6 +65,10 @@ export enum ChartToTSEvent {
|
|
|
65
65
|
* Update visual prop editor definition
|
|
66
66
|
*/
|
|
67
67
|
UpdateVisualPropEditorDefinition = 'UpdateVisualPropEditorDefinition',
|
|
68
|
+
/**
|
|
69
|
+
* Update chart config
|
|
70
|
+
*/
|
|
71
|
+
UpdateChartConfig = 'UpdateChartConfig',
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
/**
|
|
@@ -182,6 +186,11 @@ export interface ChartToTSEventsPayloadMap {
|
|
|
182
186
|
[ChartToTSEvent.UpdateVisualPropEditorDefinition]: [
|
|
183
187
|
UpdateVisualPropEditorDefinitionEventPayload,
|
|
184
188
|
];
|
|
189
|
+
/**
|
|
190
|
+
* Trigger this event when you want to update the chart config.
|
|
191
|
+
* This event takes the updated chart config as payload.
|
|
192
|
+
*/
|
|
193
|
+
[ChartToTSEvent.UpdateChartConfig]: [UpdateChartConfigEventPayload];
|
|
185
194
|
}
|
|
186
195
|
|
|
187
196
|
/**
|
|
@@ -229,6 +238,22 @@ export interface Point {
|
|
|
229
238
|
tuple: PointVal[];
|
|
230
239
|
}
|
|
231
240
|
|
|
241
|
+
/**
|
|
242
|
+
* This interface is used to define the custom action menu item group for cascading menu items.
|
|
243
|
+
*
|
|
244
|
+
* @group Chart to ThoughtSpot Events / Context Menu
|
|
245
|
+
*/
|
|
246
|
+
export interface CustomActionMenuItemGroup {
|
|
247
|
+
/**
|
|
248
|
+
* Title of the custom action menu item group.
|
|
249
|
+
* */
|
|
250
|
+
title: string;
|
|
251
|
+
/**
|
|
252
|
+
* Items of the custom action menu item group.
|
|
253
|
+
* */
|
|
254
|
+
items: CustomAction[];
|
|
255
|
+
}
|
|
256
|
+
|
|
232
257
|
/**
|
|
233
258
|
*
|
|
234
259
|
* @group Chart to ThoughtSpot Events / Context Menu
|
|
@@ -245,7 +270,24 @@ export interface CustomAction {
|
|
|
245
270
|
*
|
|
246
271
|
* Callback will be triggered via postMessage API contract.
|
|
247
272
|
*/
|
|
248
|
-
onClick
|
|
273
|
+
onClick?: (...args: any[]) => void;
|
|
274
|
+
/**
|
|
275
|
+
* flag to disable MenuItem
|
|
276
|
+
*/
|
|
277
|
+
itemDisabled?: boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Tooltip when MenuItem is disabled
|
|
280
|
+
*/
|
|
281
|
+
itemDisabledTooltip?: string;
|
|
282
|
+
/**
|
|
283
|
+
* This is used to check if the custom action is selected.
|
|
284
|
+
* This is used to show the custom action as selected in the axis menu.
|
|
285
|
+
*/
|
|
286
|
+
isSelected?: boolean;
|
|
287
|
+
/**
|
|
288
|
+
* This is used to add cascading items to the custom action.
|
|
289
|
+
* */
|
|
290
|
+
cascadingItems?: CustomActionMenuItemGroup[];
|
|
249
291
|
}
|
|
250
292
|
|
|
251
293
|
/**
|
|
@@ -306,6 +348,14 @@ export interface UpdateVisualPropEditorDefinitionEventPayload {
|
|
|
306
348
|
visualPropEditorDefinition: VisualPropEditorDefinition;
|
|
307
349
|
}
|
|
308
350
|
|
|
351
|
+
export interface UpdateChartConfigEventPayload {
|
|
352
|
+
/**
|
|
353
|
+
* The updated chart config.
|
|
354
|
+
* This is used to update the chart config in the chart.
|
|
355
|
+
*/
|
|
356
|
+
chartConfig: ChartConfig[];
|
|
357
|
+
}
|
|
358
|
+
|
|
309
359
|
/**
|
|
310
360
|
*
|
|
311
361
|
* @group Chart to ThoughtSpot Events
|
|
@@ -369,24 +419,7 @@ export enum AxisMenuActions {
|
|
|
369
419
|
SEPARATOR = 'SEPARATOR',
|
|
370
420
|
}
|
|
371
421
|
|
|
372
|
-
export
|
|
373
|
-
/**
|
|
374
|
-
* ID of the custom action.
|
|
375
|
-
* */
|
|
376
|
-
id: string;
|
|
377
|
-
/**
|
|
378
|
-
* Label of the custom action.
|
|
379
|
-
* */
|
|
380
|
-
label: string;
|
|
381
|
-
/**
|
|
382
|
-
* Icon of the custom action.
|
|
383
|
-
* */
|
|
384
|
-
icon?: string;
|
|
385
|
-
/**
|
|
386
|
-
* Callback function that will be triggered when the custom action is clicked.
|
|
387
|
-
* */
|
|
388
|
-
onClick: (...args: any[]) => void;
|
|
389
|
-
}
|
|
422
|
+
export type AxisMenuCustomAction = CustomAction;
|
|
390
423
|
|
|
391
424
|
export interface OpenAxisMenuEventPayload {
|
|
392
425
|
/**
|
|
@@ -487,6 +487,15 @@ export interface AppConfig {
|
|
|
487
487
|
* }
|
|
488
488
|
*/
|
|
489
489
|
initFlags?: Record<string, { flagId: string; flagValue: boolean }>;
|
|
490
|
+
/**
|
|
491
|
+
* Object containing the placeholders for invalid data in TS.
|
|
492
|
+
* This can be used to replace invalid value in TS with custom values in charts vizualization
|
|
493
|
+
* Currently we support it for null and empty
|
|
494
|
+
*/
|
|
495
|
+
invalidValuePlaceholders?: {
|
|
496
|
+
nullPlaceholder: string;
|
|
497
|
+
emptyPlaceholder: string;
|
|
498
|
+
};
|
|
490
499
|
}
|
|
491
500
|
|
|
492
501
|
/**
|