@thoughtspot/visual-embed-sdk 1.13.0-alpha.1 → 1.13.0-alpha.4

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 (59) hide show
  1. package/dist/src/auth.d.ts +13 -0
  2. package/dist/src/embed/app.d.ts +5 -0
  3. package/dist/src/embed/base.d.ts +1 -0
  4. package/dist/src/embed/ts-embed.d.ts +9 -1
  5. package/dist/src/types.d.ts +191 -6
  6. package/dist/src/utils.d.ts +2 -1
  7. package/dist/tsembed.es.js +222 -8
  8. package/dist/tsembed.js +222 -8
  9. package/lib/package.json +1 -1
  10. package/lib/src/auth.d.ts +13 -0
  11. package/lib/src/auth.js +14 -0
  12. package/lib/src/auth.js.map +1 -1
  13. package/lib/src/auth.spec.js +9 -0
  14. package/lib/src/auth.spec.js.map +1 -1
  15. package/lib/src/config.spec.js +7 -0
  16. package/lib/src/config.spec.js.map +1 -1
  17. package/lib/src/embed/app.d.ts +5 -0
  18. package/lib/src/embed/app.js +1 -1
  19. package/lib/src/embed/app.js.map +1 -1
  20. package/lib/src/embed/app.spec.js +10 -0
  21. package/lib/src/embed/app.spec.js.map +1 -1
  22. package/lib/src/embed/base.d.ts +1 -0
  23. package/lib/src/embed/base.js +10 -0
  24. package/lib/src/embed/base.js.map +1 -1
  25. package/lib/src/embed/base.spec.js +16 -0
  26. package/lib/src/embed/base.spec.js.map +1 -1
  27. package/lib/src/embed/liveboard.js +4 -1
  28. package/lib/src/embed/liveboard.js.map +1 -1
  29. package/lib/src/embed/liveboard.spec.js +3 -2
  30. package/lib/src/embed/liveboard.spec.js.map +1 -1
  31. package/lib/src/embed/pinboard.spec.js +3 -2
  32. package/lib/src/embed/pinboard.spec.js.map +1 -1
  33. package/lib/src/embed/ts-embed.d.ts +9 -1
  34. package/lib/src/embed/ts-embed.js +21 -3
  35. package/lib/src/embed/ts-embed.js.map +1 -1
  36. package/lib/src/embed/ts-embed.spec.js +26 -0
  37. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  38. package/lib/src/types.d.ts +191 -6
  39. package/lib/src/types.js +163 -3
  40. package/lib/src/types.js.map +1 -1
  41. package/lib/src/utils.d.ts +2 -1
  42. package/lib/src/utils.js +9 -0
  43. package/lib/src/utils.js.map +1 -1
  44. package/lib/src/visual-embed-sdk.d.ts +211 -7
  45. package/package.json +2 -2
  46. package/src/auth.spec.ts +10 -0
  47. package/src/auth.ts +14 -0
  48. package/src/config.spec.ts +11 -0
  49. package/src/embed/app.spec.ts +14 -0
  50. package/src/embed/app.ts +6 -0
  51. package/src/embed/base.spec.ts +18 -0
  52. package/src/embed/base.ts +10 -0
  53. package/src/embed/liveboard.spec.ts +4 -2
  54. package/src/embed/liveboard.ts +4 -0
  55. package/src/embed/pinboard.spec.ts +4 -3
  56. package/src/embed/ts-embed.spec.ts +32 -0
  57. package/src/embed/ts-embed.ts +25 -1
  58. package/src/types.ts +189 -3
  59. package/src/utils.ts +18 -1
@@ -110,6 +110,11 @@ declare module '@thoughtspot/visual-embed-sdk/embed/app' {
110
110
  * @hidden
111
111
  */
112
112
  liveboardV2?: boolean;
113
+ /**
114
+ * If set to true, the Search Assist feature is enabled.
115
+ * @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl
116
+ */
117
+ enableSearchAssist?: boolean;
113
118
  }
114
119
  /**
115
120
  * Embeds full ThoughtSpot experience in a host application.
@@ -151,6 +156,7 @@ declare module '@thoughtspot/visual-embed-sdk/embed/base' {
151
156
  export let authPromise: Promise<boolean>;
152
157
  export const getEmbedConfig: () => EmbedConfig;
153
158
  export const getAuthPromise: () => Promise<boolean>;
159
+ export function notifyAuthSDKSuccess(): void;
154
160
  export function notifyAuthSuccess(): void;
155
161
  export function notifyAuthFailure(failureType: AuthFailureType): void;
156
162
  export function notifyLogout(): void;
@@ -414,8 +420,21 @@ declare module '@thoughtspot/visual-embed-sdk/auth' {
414
420
  OTHER = "OTHER"
415
421
  }
416
422
  export enum AuthStatus {
423
+ /**
424
+ * Emits when the SDK fails to authenticate
425
+ */
417
426
  FAILURE = "FAILURE",
427
+ /**
428
+ * Emits when the SDK succeeds to authenticate
429
+ */
430
+ SDK_SUCCESS = "SDK_SUCCESS",
431
+ /**
432
+ * Emits when the App sends a auth success
433
+ */
418
434
  SUCCESS = "SUCCESS",
435
+ /**
436
+ * Emits when there is a logout
437
+ */
419
438
  LOGOUT = "LOGOUT"
420
439
  }
421
440
  /**
@@ -467,8 +486,13 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
467
486
  None = "None",
468
487
  /**
469
488
  * SSO using SAML
489
+ * @deprecated Use {@link SAML} instead
470
490
  */
471
491
  SSO = "SSO_SAML",
492
+ /**
493
+ * SSO using SAML
494
+ */
495
+ SAML = "SSO_SAML",
472
496
  /**
473
497
  * SSO using OIDC
474
498
  */
@@ -486,6 +510,26 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
486
510
  Basic = "Basic"
487
511
  }
488
512
  export type DOMSelector = string | HTMLElement;
513
+ interface customCssInterface {
514
+ variables?: {
515
+ [variableName: string]: string;
516
+ };
517
+ rules_UNSTABLE?: {
518
+ [selector: string]: {
519
+ [declaration: string]: string;
520
+ };
521
+ };
522
+ }
523
+ interface CustomStyles {
524
+ customCSSUrl?: string;
525
+ customCss?: customCssInterface;
526
+ }
527
+ export interface CustomisationsInterface {
528
+ style: CustomStyles;
529
+ content: {
530
+ [key: string]: string;
531
+ };
532
+ }
489
533
  /**
490
534
  * The configuration object for embedding ThoughtSpot content.
491
535
  * It includes the ThoughtSpot hostname or IP address,
@@ -617,6 +661,10 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
617
661
  * @version SDK: 1.12.0 | ThoughtSpot: *
618
662
  */
619
663
  suppressSearchEmbedBetaWarning?: boolean;
664
+ /**
665
+ * Custom style params for embed Config
666
+ */
667
+ customisations?: CustomisationsInterface;
620
668
  }
621
669
  /**
622
670
  * MessagePayload: Embed event payload: message type, data and status (start/end)
@@ -971,7 +1019,66 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
971
1019
  * Emitted when an answer is switched to a chart or table view
972
1020
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl
973
1021
  */
974
- AnswerChartSwitcher = "answerChartSwitcher"
1022
+ AnswerChartSwitcher = "answerChartSwitcher",
1023
+ /**
1024
+ *
1025
+ */
1026
+ APP_INIT = "appInit",
1027
+ /**
1028
+ * Emitted when a user clicks Show Liveboard details on a Liveboard
1029
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1030
+ */
1031
+ LiveboardInfo = "pinboardInfo",
1032
+ /**
1033
+ * Emitted when a user clicks on the Favorite icon on a Liveboard
1034
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1035
+ */
1036
+ AddToFavorites = "addToFavorites",
1037
+ /**
1038
+ * Emitted when a user clicks Schedule on a Liveboard
1039
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1040
+ */
1041
+ Schedule = "subscription",
1042
+ /**
1043
+ * Emitted when a user clicks Edit on a Liveboard or visualization
1044
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1045
+ */
1046
+ Edit = "edit",
1047
+ /**
1048
+ * Emitted when a user clicks Make a copy on a Liveboard
1049
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1050
+ */
1051
+ MakeACopy = "makeACopy",
1052
+ /**
1053
+ * Emitted when a user clicks Present on a Liveboard or visualization
1054
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1055
+ */
1056
+ Present = "present",
1057
+ /**
1058
+ * Emitted when a user clicks Delete on a Liveboard
1059
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1060
+ */
1061
+ Delete = "delete",
1062
+ /**
1063
+ * Emitted when a user clicks Manage schedules on a Liveboard
1064
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1065
+ */
1066
+ SchedulesList = "schedule-list",
1067
+ /**
1068
+ * Emitted when a user clicks Cancel in edit mode on a Liveboard
1069
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1070
+ */
1071
+ Cancel = "cancel",
1072
+ /**
1073
+ * Emitted when a user clicks Explore on a visualization
1074
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1075
+ */
1076
+ Explore = "explore",
1077
+ /**
1078
+ * Emitted when a user clicks Copy link action on a visualization
1079
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1080
+ */
1081
+ CopyLink = "copyLink"
975
1082
  }
976
1083
  /**
977
1084
  * Event types that can be triggered by the host application
@@ -1033,12 +1140,106 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1033
1140
  */
1034
1141
  getExportRequestForCurrentPinboard = "getExportRequestForCurrentPinboard",
1035
1142
  /**
1036
- * Fires the pin action on an embedded object
1037
- * @param - incase of liveboard embed, takes in an object with vizId as a key
1038
- * can be left empty for search and viz embeds
1143
+ * Triggers the Pin action on an embedded object
1144
+ * @param - incase of Liveboard embed, takes in an object with vizId as a key
1145
+ * can be left empty for search and visualization embeds
1146
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1147
+ */
1148
+ Pin = "pin",
1149
+ /**
1150
+ * Triggers the Show Liveboard details action on a Liveboard
1151
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1152
+ */
1153
+ LiveboardInfo = "pinboardInfo",
1154
+ /**
1155
+ * Triggers the Schedule action on a Liveboard
1156
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1157
+ */
1158
+ Schedule = "subscription",
1159
+ /**
1160
+ * Triggers the Manage schedule action on a Liveboard
1161
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1162
+ */
1163
+ SchedulesList = "schedule-list",
1164
+ /**
1165
+ * Triggers the Export TML action on a Liveboard
1166
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1167
+ */
1168
+ ExportTML = "exportTSL",
1169
+ /**
1170
+ * Triggers the Edit TML action on a Liveboard
1171
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1172
+ */
1173
+ EditTML = "editTSL",
1174
+ /**
1175
+ * Triggers the Update TML action on a Liveboard
1176
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1177
+ */
1178
+ UpdateTML = "updateTSL",
1179
+ /**
1180
+ * Triggers the Download PDF action on a Liveboard
1039
1181
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1040
1182
  */
1041
- Pin = "pin"
1183
+ DownloadAsPdf = "downloadAsPdf",
1184
+ /**
1185
+ * Triggers the Make a copy action on a Liveboard
1186
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1187
+ */
1188
+ MakeACopy = "makeACopy",
1189
+ /**
1190
+ * Triggers the Delete action on a Liveboard
1191
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1192
+ */
1193
+ Remove = "delete",
1194
+ /**
1195
+ * Triggers the Explore action on a visualization
1196
+ * @param - an object with vizId as a key
1197
+ * eg: {vizId: '730496d6-6903-4601-937e-2c691821af3c'}
1198
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1199
+ */
1200
+ Explore = "explore",
1201
+ /**
1202
+ * Triggers the Create alert action on a visualization
1203
+ * @param - an object with vizId as a key
1204
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1205
+ */
1206
+ CreateMonitor = "createMonitor",
1207
+ /**
1208
+ * Triggers the Manage alert action on a visualization
1209
+ * @param - an object with vizId as a key
1210
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1211
+ */
1212
+ ManageMonitor = "manageMonitor",
1213
+ /**
1214
+ * Triggers the Edit action on a Liveboard or visualization
1215
+ * @param - object - to trigger the action for a specfic visualization in Liveboard embed, pass in vizId as a key
1216
+ * @example
1217
+ * liveboardEmbed.trigger(HostEvent.Edit)
1218
+ * liveboardEmbed.trigger(HostEvent.Edit, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
1219
+ * vizEmbed.trigger((HostEvent.Edit)
1220
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1221
+ */
1222
+ Edit = "edit",
1223
+ /**
1224
+ * Triggers the Copy link action on a Liveboard or visualization
1225
+ * @param - object - to trigger the action for a specfic visualization in Liveboard embed, pass in vizId as a key
1226
+ * @example
1227
+ * liveboardEmbed.trigger(HostEvent.CopyLink)
1228
+ * liveboardEmbed.trigger(HostEvent.CopyLink, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
1229
+ * vizEmbed.trigger((HostEvent.CopyLink)
1230
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1231
+ */
1232
+ CopyLink = "embedDocument",
1233
+ /**
1234
+ * Triggers the Present action on a Liveboard or visualization
1235
+ * @param - object - to trigger the action for a specfic visualization in Liveboard embed, pass in vizId as a key
1236
+ * @example
1237
+ * liveboardEmbed.trigger(HostEvent.Present)
1238
+ * liveboardEmbed.trigger(HostEvent.Present, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
1239
+ * vizEmbed.trigger((HostEvent.Present)
1240
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
1241
+ */
1242
+ Present = "present"
1042
1243
  }
1043
1244
  /**
1044
1245
  * The different visual modes that the data sources panel within
@@ -1083,6 +1284,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1083
1284
  fullHeight = "isFullHeightPinboard",
1084
1285
  livedBoardEmbed = "isLiveboardEmbed",
1085
1286
  searchEmbed = "isSearchEmbed",
1287
+ vizEmbed = "isVizEmbed",
1086
1288
  Version = "sdkVersion",
1087
1289
  ViewPortHeight = "viewPortHeight",
1088
1290
  ViewPortWidth = "viewPortWidth",
@@ -1092,7 +1294,8 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1092
1294
  visibleVizs = "pinboardVisibleVizs",
1093
1295
  LiveboardV2Enabled = "isPinboardV2Enabled",
1094
1296
  ShowAlerts = "showAlerts",
1095
- Locale = "locale"
1297
+ Locale = "locale",
1298
+ CustomStyle = "customStyle"
1096
1299
  }
1097
1300
  /**
1098
1301
  * The list of actions that can be performed on visual ThoughtSpot
@@ -1253,6 +1456,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1253
1456
  export interface AnswerServiceType {
1254
1457
  getAnswer?: (offset: number, batchSize: number) => any;
1255
1458
  }
1459
+ export {};
1256
1460
  }
1257
1461
 
1258
1462
  declare module '@thoughtspot/visual-embed-sdk/embed/ts-embed' {
@@ -1397,7 +1601,7 @@ declare module '@thoughtspot/visual-embed-sdk/embed/ts-embed' {
1397
1601
  * @param isAppEmbed A Boolean parameter to specify if you are embedding
1398
1602
  * the full application.
1399
1603
  */
1400
- protected getV1EmbedBasePath(queryString: string, showPrimaryNavbar?: boolean, disableProfileAndHelp?: boolean, isAppEmbed?: boolean): string;
1604
+ protected getV1EmbedBasePath(queryString: string, showPrimaryNavbar?: boolean, disableProfileAndHelp?: boolean, isAppEmbed?: boolean, enableSearchAssist?: boolean): string;
1401
1605
  /**
1402
1606
  * Renders the embedded ThoughtSpot app in an iframe and sets up
1403
1607
  * event listeners.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thoughtspot/visual-embed-sdk",
3
- "version": "1.13.0-alpha.1",
3
+ "version": "1.13.0-alpha.4",
4
4
  "description": "ThoughtSpot Embed SDK",
5
5
  "module": "lib/src/index.js",
6
6
  "main": "dist/tsembed.js",
@@ -146,4 +146,4 @@
146
146
  "globals": {
147
147
  "window": {}
148
148
  }
149
- }
149
+ }
package/src/auth.spec.ts CHANGED
@@ -49,6 +49,9 @@ export const embedConfig: any = {
49
49
  SSOAuth: {
50
50
  authType: AuthType.SSO,
51
51
  },
52
+ SAMLAuth: {
53
+ authType: AuthType.SAML,
54
+ },
52
55
  OIDCAuth: {
53
56
  authType: AuthType.OIDC,
54
57
  },
@@ -386,6 +389,13 @@ describe('Unit test for auth', () => {
386
389
  expect(authInstance.doSamlAuth).toBeCalled();
387
390
  });
388
391
 
392
+ it('authenticate: when authType is SMAL', async () => {
393
+ jest.spyOn(authInstance, 'doSamlAuth');
394
+ await authInstance.authenticate(embedConfig.SAMLAuth);
395
+ expect(window.location.hash).toBe('');
396
+ expect(authInstance.doSamlAuth).toBeCalled();
397
+ });
398
+
389
399
  it('authenticate: when authType is OIDC', async () => {
390
400
  jest.spyOn(authInstance, 'doOIDCAuth');
391
401
  await authInstance.authenticate(embedConfig.OIDCAuth);
package/src/auth.ts CHANGED
@@ -41,8 +41,21 @@ export enum AuthFailureType {
41
41
  }
42
42
 
43
43
  export enum AuthStatus {
44
+ /**
45
+ * Emits when the SDK fails to authenticate
46
+ */
44
47
  FAILURE = 'FAILURE',
48
+ /**
49
+ * Emits when the SDK succeeds to authenticate
50
+ */
51
+ SDK_SUCCESS = 'SDK_SUCCESS',
52
+ /**
53
+ * Emits when the App sends a auth success
54
+ */
45
55
  SUCCESS = 'SUCCESS',
56
+ /**
57
+ * Emits when there is a logout
58
+ */
46
59
  LOGOUT = 'LOGOUT',
47
60
  }
48
61
 
@@ -319,6 +332,7 @@ export const authenticate = async (
319
332
  const { authType } = embedConfig;
320
333
  switch (authType) {
321
334
  case AuthType.SSO:
335
+ case AuthType.SAML:
322
336
  return doSamlAuth(embedConfig);
323
337
  case AuthType.OIDC:
324
338
  return doOIDCAuth(embedConfig);
@@ -64,4 +64,15 @@ describe('getThoughtSpotHost', () => {
64
64
  }),
65
65
  ).toBe('http://1.2.3.4:8088/v2');
66
66
  });
67
+
68
+ test('when authtype SAML, fully formed URL with', () => {
69
+ expect(
70
+ getThoughtSpotHost({
71
+ ...embedConfig,
72
+ authType: AuthType.SAML,
73
+ thoughtSpotHost:
74
+ 'http://1.2.3.4:8088/v2/?foo=bar&baz=42#myhash',
75
+ }),
76
+ ).toBe('http://1.2.3.4:8088/v2');
77
+ });
67
78
  });
@@ -176,6 +176,20 @@ describe('App embed tests', () => {
176
176
  });
177
177
  });
178
178
 
179
+ test('Should add enableSearchAssist flagto the iframe src', async () => {
180
+ const appEmbed = new AppEmbed(getRootEl(), {
181
+ ...defaultViewConfig,
182
+ enableSearchAssist: true,
183
+ } as AppViewConfig);
184
+
185
+ appEmbed.render();
186
+ await executeAfterWait(() => {
187
+ expect(getIFrameSrc()).toBe(
188
+ `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&enableSearchAssist=true${defaultParams}${defaultParamsPost}#/home`,
189
+ );
190
+ });
191
+ });
192
+
179
193
  describe('Navigate to Page API', () => {
180
194
  const path = 'pinboard/e0836cad-4fdf-42d4-bd97-567a6b2a6058';
181
195
  beforeEach(() => {
package/src/embed/app.ts CHANGED
@@ -91,6 +91,11 @@ export interface AppViewConfig extends ViewConfig {
91
91
  * @hidden
92
92
  */
93
93
  liveboardV2?: boolean;
94
+ /**
95
+ * If set to true, the Search Assist feature is enabled.
96
+ * @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl
97
+ */
98
+ enableSearchAssist?: boolean;
94
99
  }
95
100
 
96
101
  /**
@@ -141,6 +146,7 @@ export class AppEmbed extends V1Embed {
141
146
  this.viewConfig.showPrimaryNavbar,
142
147
  this.viewConfig.disableProfileAndHelp,
143
148
  true,
149
+ this.viewConfig.enableSearchAssist,
144
150
  )}/${pageId}`;
145
151
 
146
152
  const tsPostHashParams = this.getThoughtSpotPostUrlParams();
@@ -113,6 +113,24 @@ describe('Base TS Embed', () => {
113
113
  });
114
114
  });
115
115
 
116
+ test('handleAuth notifies for SDK auth success', (done) => {
117
+ jest.spyOn(auth, 'authenticate').mockResolvedValue(true);
118
+ const failureCallback = jest.fn();
119
+ const authEmitter = index.init({
120
+ thoughtSpotHost,
121
+ authType: index.AuthType.Basic,
122
+ username: 'test',
123
+ password: 'test',
124
+ });
125
+
126
+ authEmitter.on(auth.AuthStatus.FAILURE, failureCallback);
127
+ authEmitter.on(auth.AuthStatus.SDK_SUCCESS, (reason) => {
128
+ expect(failureCallback).not.toBeCalled();
129
+ expect(reason).toBe(undefined);
130
+ done();
131
+ });
132
+ });
133
+
116
134
  test('Logout method should disable autoLogin', () => {
117
135
  jest.spyOn(window, 'fetch').mockResolvedValue({
118
136
  type: 'opaque',
package/src/embed/base.ts CHANGED
@@ -32,6 +32,14 @@ export const getAuthPromise = (): Promise<boolean> => authPromise;
32
32
 
33
33
  let authEE: EventEmitter;
34
34
 
35
+ export function notifyAuthSDKSuccess(): void {
36
+ if (!authEE) {
37
+ console.error('SDK not initialized');
38
+ return;
39
+ }
40
+ authEE.emit(AuthStatus.SDK_SUCCESS);
41
+ }
42
+
35
43
  export function notifyAuthSuccess(): void {
36
44
  if (!authEE) {
37
45
  console.error('SDK not initialized');
@@ -64,6 +72,8 @@ export const handleAuth = (): Promise<boolean> => {
64
72
  (isLoggedIn) => {
65
73
  if (!isLoggedIn) {
66
74
  notifyAuthFailure(AuthFailureType.SDK);
75
+ } else {
76
+ notifyAuthSDKSuccess();
67
77
  }
68
78
  },
69
79
  () => {
@@ -28,6 +28,8 @@ const thoughtSpotHost = 'tshost';
28
28
  const defaultParamsSansHideAction = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
29
29
  const defaultParams = `${defaultParamsSansHideAction}&hideAction=[%22${Action.ReportError}%22]`;
30
30
  const prefixParams = '&isLiveboardEmbed=true&isPinboardV2Enabled=false';
31
+ const prefixParamsVizEmbed =
32
+ '&isLiveboardEmbed=true&isVizEmbed=true&isPinboardV2Enabled=false';
31
33
 
32
34
  beforeAll(() => {
33
35
  init({
@@ -160,7 +162,7 @@ describe('Liveboard/viz embed tests', () => {
160
162
  liveboardEmbed.render();
161
163
  await executeAfterWait(() => {
162
164
  expect(getIFrameSrc()).toBe(
163
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}#/embed/viz/${liveboardId}/${vizId}`,
165
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`,
164
166
  );
165
167
  });
166
168
  });
@@ -181,7 +183,7 @@ describe('Liveboard/viz embed tests', () => {
181
183
  liveboardEmbed.render();
182
184
  await executeAfterWait(() => {
183
185
  expect(getIFrameSrc()).toBe(
184
- `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParams}#/embed/viz/${liveboardId}/${vizId}`,
186
+ `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`,
185
187
  );
186
188
  });
187
189
  });
@@ -110,6 +110,7 @@ export class LiveboardEmbed extends V1Embed {
110
110
  defaultHeight,
111
111
  visibleVizs,
112
112
  liveboardV2 = false,
113
+ vizId,
113
114
  } = this.viewConfig;
114
115
 
115
116
  const preventLiveboardFilterRemoval =
@@ -134,6 +135,9 @@ export class LiveboardEmbed extends V1Embed {
134
135
  params[Param.visibleVizs] = visibleVizs;
135
136
  }
136
137
  params[Param.livedBoardEmbed] = true;
138
+ if (vizId) {
139
+ params[Param.vizEmbed] = true;
140
+ }
137
141
  params[Param.LiveboardV2Enabled] = liveboardV2;
138
142
  const queryParams = getQueryParamString(params, true);
139
143
 
@@ -21,7 +21,8 @@ const thoughtSpotHost = 'tshost';
21
21
  const defaultParamsWithoutHideActions = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
22
22
  const defaultParams = `${defaultParamsWithoutHideActions}&hideAction=[%22${Action.ReportError}%22]`;
23
23
  const prefixParams = '&isLiveboardEmbed=true&isPinboardV2Enabled=false';
24
-
24
+ const prefixParamsVizEmbed =
25
+ '&isLiveboardEmbed=true&isVizEmbed=true&isPinboardV2Enabled=false';
25
26
  beforeAll(() => {
26
27
  init({
27
28
  thoughtSpotHost,
@@ -153,7 +154,7 @@ describe('Pinboard/viz embed tests', () => {
153
154
  pinboardEmbed.render();
154
155
  await executeAfterWait(() => {
155
156
  expect(getIFrameSrc()).toBe(
156
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}#/embed/viz/${pinboardId}/${vizId}`,
157
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${pinboardId}/${vizId}`,
157
158
  );
158
159
  });
159
160
  });
@@ -174,7 +175,7 @@ describe('Pinboard/viz embed tests', () => {
174
175
  pinboardEmbed.render();
175
176
  await executeAfterWait(() => {
176
177
  expect(getIFrameSrc()).toBe(
177
- `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParams}#/embed/viz/${pinboardId}/${vizId}`,
178
+ `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${pinboardId}/${vizId}`,
178
179
  );
179
180
  });
180
181
  });
@@ -41,6 +41,13 @@ beforeAll(() => {
41
41
  spyOn(window, 'alert');
42
42
  });
43
43
 
44
+ const customisations = {
45
+ style: {
46
+ customCSSUrl: 'http://localhost:3000',
47
+ },
48
+ content: {},
49
+ };
50
+
44
51
  describe('Unit test case for ts embed', () => {
45
52
  const mockMixPanelEvent = jest.spyOn(
46
53
  mixpanelInstance,
@@ -59,6 +66,31 @@ describe('Unit test case for ts embed', () => {
59
66
  init({
60
67
  thoughtSpotHost: 'tshost',
61
68
  authType: AuthType.None,
69
+ customisations,
70
+ });
71
+ });
72
+
73
+ test('verify Customisations', async () => {
74
+ const mockEmbedEventPayload = {
75
+ type: EmbedEvent.APP_INIT,
76
+ data: {},
77
+ };
78
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
79
+ searchEmbed.render();
80
+ const mockPort: any = {
81
+ postMessage: jest.fn(),
82
+ };
83
+ await executeAfterWait(() => {
84
+ const iframe = getIFrameEl();
85
+ postMessageToParent(
86
+ iframe.contentWindow,
87
+ mockEmbedEventPayload,
88
+ mockPort,
89
+ );
90
+ });
91
+ expect(mockPort.postMessage).toHaveBeenCalledWith({
92
+ type: EmbedEvent.APP_INIT,
93
+ data: { customisations },
62
94
  });
63
95
  });
64
96
 
@@ -13,6 +13,7 @@ import {
13
13
  getOffsetTop,
14
14
  embedEventStatus,
15
15
  setAttributes,
16
+ getCustomisations,
16
17
  } from '../utils';
17
18
  import {
18
19
  getThoughtSpotHost,
@@ -31,6 +32,7 @@ import {
31
32
  Param,
32
33
  EmbedConfig,
33
34
  MessageOptions,
35
+ MessagePayload,
34
36
  MessageCallbackObj,
35
37
  } from '../types';
36
38
  import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
@@ -214,6 +216,7 @@ export class TsEmbed {
214
216
  this.isError = false;
215
217
  this.viewConfig = viewConfig;
216
218
  this.shouldEncodeUrlQueryParams = this.embedConfig.shouldEncodeUrlQueryParams;
219
+ this.registerAppInit();
217
220
  }
218
221
 
219
222
  /**
@@ -310,6 +313,23 @@ export class TsEmbed {
310
313
  });
311
314
  }
312
315
 
316
+ /**
317
+ * Send Custom style as part of payload of APP_INIT
318
+ */
319
+ private appInitCb = (_: any, responder: any) => {
320
+ responder({
321
+ type: EmbedEvent.APP_INIT,
322
+ data: { customisations: getCustomisations(this.embedConfig) },
323
+ });
324
+ };
325
+
326
+ /**
327
+ * Register APP_INIT event and sendback init payload
328
+ */
329
+ private registerAppInit = () => {
330
+ this.on(EmbedEvent.APP_INIT, this.appInitCb);
331
+ };
332
+
313
333
  /**
314
334
  * Constructs the base URL string to load the ThoughtSpot app.
315
335
  */
@@ -357,6 +377,7 @@ export class TsEmbed {
357
377
  ) {
358
378
  queryParams[Param.DisableLoginRedirect] = true;
359
379
  }
380
+ // TODO remove this
360
381
  if (this.embedConfig.customCssUrl) {
361
382
  queryParams[Param.CustomCSSUrl] = this.embedConfig.customCssUrl;
362
383
  }
@@ -415,12 +436,16 @@ export class TsEmbed {
415
436
  showPrimaryNavbar = false,
416
437
  disableProfileAndHelp = false,
417
438
  isAppEmbed = false,
439
+ enableSearchAssist = false,
418
440
  ): string {
419
441
  const queryStringFrag = queryString ? `&${queryString}` : '';
420
442
  const primaryNavParam = `&primaryNavHidden=${!showPrimaryNavbar}`;
421
443
  const disableProfileAndHelpParam = `&profileAndHelpInNavBarHidden=${disableProfileAndHelp}`;
444
+ const enableSearchAssistParam = `&${Param.EnableSearchAssist}=${enableSearchAssist}`;
422
445
  let queryParams = `?embedApp=true${isAppEmbed ? primaryNavParam : ''}${
423
446
  isAppEmbed ? disableProfileAndHelpParam : ''
447
+ }${
448
+ enableSearchAssist ? enableSearchAssistParam : ''
424
449
  }${queryStringFrag}`;
425
450
  if (this.shouldEncodeUrlQueryParams) {
426
451
  queryParams = `?base64UrlEncodedFlags=${getEncodedQueryParamsString(
@@ -462,7 +487,6 @@ export class TsEmbed {
462
487
  });
463
488
 
464
489
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_START);
465
-
466
490
  getAuthPromise()
467
491
  ?.then((isLoggedIn: boolean) => {
468
492
  if (!isLoggedIn) {