@thoughtspot/visual-embed-sdk 1.42.0 → 1.42.1-alpha.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/cjs/package.json +2 -2
- package/cjs/src/api-intercept.d.ts +27 -0
- package/cjs/src/api-intercept.d.ts.map +1 -0
- package/cjs/src/api-intercept.js +115 -0
- package/cjs/src/api-intercept.js.map +1 -0
- package/cjs/src/api-intercept.spec.d.ts +2 -0
- package/cjs/src/api-intercept.spec.d.ts.map +1 -0
- package/cjs/src/api-intercept.spec.js +122 -0
- package/cjs/src/api-intercept.spec.js.map +1 -0
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +7 -2
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +20 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.js +1 -0
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +4 -1
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +22 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +3 -1
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +15 -0
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +94 -26
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +168 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/types.d.ts +100 -4
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +39 -1
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processData.d.ts +1 -1
- package/cjs/src/utils/processData.d.ts.map +1 -1
- package/cjs/src/utils/processData.js +8 -8
- package/cjs/src/utils/processData.js.map +1 -1
- package/dist/index-BCC3Z072.js +7371 -0
- package/dist/index-BEzW4MDA.js +7371 -0
- package/dist/{index-BpSohedu.js → index-DvNA626T.js} +1 -1
- package/dist/src/api-intercept.d.ts +27 -0
- package/dist/src/api-intercept.d.ts.map +1 -0
- package/dist/src/api-intercept.spec.d.ts +2 -0
- package/dist/src/api-intercept.spec.d.ts.map +1 -0
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +15 -0
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/types.d.ts +100 -4
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/processData.d.ts +1 -1
- package/dist/src/utils/processData.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +266 -51
- package/dist/tsembed-react.js +265 -50
- package/dist/tsembed.es.js +267 -52
- package/dist/tsembed.js +265 -50
- package/dist/visual-embed-sdk-react-full.d.ts +124 -4
- package/dist/visual-embed-sdk-react.d.ts +121 -4
- package/dist/visual-embed-sdk.d.ts +124 -4
- package/lib/package.json +2 -2
- package/lib/src/api-intercept.d.ts +27 -0
- package/lib/src/api-intercept.d.ts.map +1 -0
- package/lib/src/api-intercept.js +108 -0
- package/lib/src/api-intercept.js.map +1 -0
- package/lib/src/api-intercept.spec.d.ts +2 -0
- package/lib/src/api-intercept.spec.d.ts.map +1 -0
- package/lib/src/api-intercept.spec.js +119 -0
- package/lib/src/api-intercept.spec.js.map +1 -0
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +7 -2
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +20 -0
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.js +1 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +4 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +22 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +3 -1
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +15 -0
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +94 -26
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +168 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -2
- package/lib/src/index.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/types.d.ts +100 -4
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +38 -0
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processData.d.ts +1 -1
- package/lib/src/utils/processData.d.ts.map +1 -1
- package/lib/src/utils/processData.js +8 -8
- package/lib/src/utils/processData.js.map +1 -1
- package/package.json +2 -2
- package/src/api-intercept.spec.ts +147 -0
- package/src/api-intercept.ts +134 -0
- package/src/embed/app.spec.ts +28 -0
- package/src/embed/app.ts +9 -1
- package/src/embed/hostEventClient/contracts.ts +10 -0
- package/src/embed/liveboard.spec.ts +30 -0
- package/src/embed/liveboard.ts +5 -0
- package/src/embed/search.ts +3 -1
- package/src/embed/ts-embed.spec.ts +221 -5
- package/src/embed/ts-embed.ts +129 -43
- package/src/errors.ts +1 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +1 -0
- package/src/types.ts +102 -3
- package/src/utils/processData.ts +11 -11
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { getInterceptInitData, processApiIntercept, handleInterceptEvent, processLegacyInterceptResponse } from './api-intercept';
|
|
2
|
+
import { EmbedEvent, InterceptedApiType } from './types';
|
|
3
|
+
import * as embedCfg from './embed/embedConfig';
|
|
4
|
+
import * as cfg from './config';
|
|
5
|
+
import { logger } from './utils/logger';
|
|
6
|
+
|
|
7
|
+
describe('api-intercept', () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
jest.restoreAllMocks();
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('getInterceptInitData', () => {
|
|
14
|
+
test('returns disabled when not enabled in either config', () => {
|
|
15
|
+
const init = getInterceptInitData({} as any, {} as any);
|
|
16
|
+
expect(init).toEqual({ enableApiIntercept: false });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('merges urls and expands api types, formats with host', () => {
|
|
20
|
+
jest.spyOn(embedCfg, 'getEmbedConfig').mockReturnValue({ thoughtSpotHost: 'http://tshost' } as any);
|
|
21
|
+
jest.spyOn(cfg, 'getThoughtSpotHost').mockReturnValue('http://tshost');
|
|
22
|
+
|
|
23
|
+
const embedConfig: any = { enableApiIntercept: true };
|
|
24
|
+
const viewConfig: any = { interceptUrls: [InterceptedApiType.METADATA, '/custom/path'] };
|
|
25
|
+
|
|
26
|
+
const init = getInterceptInitData(embedConfig, viewConfig);
|
|
27
|
+
|
|
28
|
+
expect(init.enableApiIntercept).toBe(true);
|
|
29
|
+
expect(init.interceptUrls).toEqual(expect.arrayContaining([
|
|
30
|
+
'http://tshost/prism/?op=CreateAnswerSession',
|
|
31
|
+
'http://tshost/prism/?op=GetV2SourceDetail',
|
|
32
|
+
'http://tshost/custom/path',
|
|
33
|
+
]));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('honors InterceptedApiType.ALL and interceptTimeout', () => {
|
|
37
|
+
const embedConfig: any = { enableApiIntercept: true, interceptTimeout: 2500 };
|
|
38
|
+
const viewConfig: any = { interceptUrls: [InterceptedApiType.ALL] };
|
|
39
|
+
|
|
40
|
+
const init = getInterceptInitData(embedConfig, viewConfig);
|
|
41
|
+
|
|
42
|
+
expect(init).toEqual({
|
|
43
|
+
enableApiIntercept: true,
|
|
44
|
+
interceptUrls: [InterceptedApiType.ALL],
|
|
45
|
+
interceptTimeout: 2500,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('legacy flag isOnBeforeGetVizDataInterceptEnabled adds ANSWER_DATA', () => {
|
|
50
|
+
jest.spyOn(embedCfg, 'getEmbedConfig').mockReturnValue({ thoughtSpotHost: 'http://tshost' } as any);
|
|
51
|
+
jest.spyOn(cfg, 'getThoughtSpotHost').mockReturnValue('http://tshost');
|
|
52
|
+
|
|
53
|
+
const embedConfig: any = { enableApiIntercept: true };
|
|
54
|
+
const viewConfig: any = { isOnBeforeGetVizDataInterceptEnabled: true, interceptUrls: [] };
|
|
55
|
+
|
|
56
|
+
const init = getInterceptInitData(embedConfig, viewConfig);
|
|
57
|
+
|
|
58
|
+
// Should expand to concrete ANSWER_DATA URLs
|
|
59
|
+
expect(init.interceptUrls).toEqual(expect.arrayContaining([
|
|
60
|
+
'http://tshost/prism/?op=GetChartWithData',
|
|
61
|
+
'http://tshost/prism/?op=GetTableWithHeadlineData',
|
|
62
|
+
]));
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('viewConfig enableApiIntercept=false overrides embed config', () => {
|
|
66
|
+
const embedConfig: any = { enableApiIntercept: true };
|
|
67
|
+
const viewConfig: any = { enableApiIntercept: false };
|
|
68
|
+
const init = getInterceptInitData(embedConfig, viewConfig);
|
|
69
|
+
expect(init).toEqual({ enableApiIntercept: false });
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('processApiIntercept', () => {
|
|
74
|
+
test('parses data JSON string', async () => {
|
|
75
|
+
const result = await processApiIntercept({ data: JSON.stringify({ foo: 'bar' }) });
|
|
76
|
+
expect(result).toEqual({ foo: 'bar' });
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('handleInterceptEvent', () => {
|
|
81
|
+
test('emits error on body parse failure', async () => {
|
|
82
|
+
const executeEvent = jest.fn();
|
|
83
|
+
const loggerErrSpy = jest.spyOn(logger, 'error').mockImplementation(() => undefined as any);
|
|
84
|
+
await handleInterceptEvent({
|
|
85
|
+
eventData: { data: 'not-a-json' },
|
|
86
|
+
executeEvent,
|
|
87
|
+
embedConfig: {} as any,
|
|
88
|
+
viewConfig: {} as any,
|
|
89
|
+
getUnsavedAnswerTml: jest.fn(),
|
|
90
|
+
});
|
|
91
|
+
expect(executeEvent).toHaveBeenCalledWith(EmbedEvent.Error, { error: 'Error parsing api intercept body' });
|
|
92
|
+
loggerErrSpy.mockReset();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('calls getUnsavedAnswerTml and emits legacy + ApiIntercept events when applicable', async () => {
|
|
96
|
+
const executeEvent = jest.fn();
|
|
97
|
+
const getUnsavedAnswerTml = jest.fn().mockResolvedValue({ tml: 'TML_STRING' });
|
|
98
|
+
|
|
99
|
+
const eventPayload = {
|
|
100
|
+
input: '/prism/?op=GetChartWithData',
|
|
101
|
+
init: {
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
variables: {
|
|
104
|
+
session: { sessionId: 'S1' },
|
|
105
|
+
contextBookId: 'V1',
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
await handleInterceptEvent({
|
|
112
|
+
eventData: { data: JSON.stringify(eventPayload) },
|
|
113
|
+
executeEvent,
|
|
114
|
+
embedConfig: {} as any,
|
|
115
|
+
viewConfig: { isOnBeforeGetVizDataInterceptEnabled: true } as any,
|
|
116
|
+
getUnsavedAnswerTml,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
expect(getUnsavedAnswerTml).toHaveBeenCalledWith({ sessionId: 'S1', vizId: 'V1' });
|
|
120
|
+
expect(executeEvent).toHaveBeenCalledWith(
|
|
121
|
+
EmbedEvent.OnBeforeGetVizDataIntercept,
|
|
122
|
+
{ data: { data: { tml: 'TML_STRING' } } },
|
|
123
|
+
);
|
|
124
|
+
expect(executeEvent).toHaveBeenCalledWith(
|
|
125
|
+
EmbedEvent.ApiIntercept,
|
|
126
|
+
expect.objectContaining({ input: '/prism/?op=GetChartWithData' }),
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('processLegacyInterceptResponse', () => {
|
|
132
|
+
test('wraps legacy error payload as expected', () => {
|
|
133
|
+
const payload = { data: { errorText: 'Title', errorDescription: 'Desc' } } as any;
|
|
134
|
+
const res = processLegacyInterceptResponse(payload);
|
|
135
|
+
expect(Array.isArray(res)).toBe(true);
|
|
136
|
+
expect(res[0]).toEqual(expect.objectContaining({
|
|
137
|
+
errors: [
|
|
138
|
+
expect.objectContaining({
|
|
139
|
+
errorObj: expect.objectContaining({ title: 'Title', desc: 'Desc' }),
|
|
140
|
+
}),
|
|
141
|
+
],
|
|
142
|
+
}));
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { getThoughtSpotHost } from "./config";
|
|
2
|
+
import { getEmbedConfig } from "./embed/embedConfig";
|
|
3
|
+
import { InterceptedApiType, BaseViewConfig, EmbedConfig, InterceptV2Flags, EmbedEvent } from "./types";
|
|
4
|
+
import { logger } from "./utils/logger";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const defaultUrls: Record<Exclude<InterceptedApiType, InterceptedApiType.ALL>, string[]> = {
|
|
8
|
+
[InterceptedApiType.METADATA]: [
|
|
9
|
+
'/prism/?op=CreateAnswerSession',
|
|
10
|
+
'/prism/?op=GetV2SourceDetail',
|
|
11
|
+
] as string[],
|
|
12
|
+
[InterceptedApiType.ANSWER_DATA]: [
|
|
13
|
+
'/prism/?op=GetChartWithData',
|
|
14
|
+
'/prism/?op=GetTableWithHeadlineData',
|
|
15
|
+
] as string[],
|
|
16
|
+
[InterceptedApiType.LIVEBOARD_DATA]: [
|
|
17
|
+
'/prism/?op=LoadContextBook'
|
|
18
|
+
] as string[],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const formatInterceptUrl = (url: string) => {
|
|
22
|
+
const host = getThoughtSpotHost(getEmbedConfig());
|
|
23
|
+
if (url.startsWith('/')) return `${host}${url}`;
|
|
24
|
+
return url;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const processApiIntercept = async (eventData: any) => {
|
|
28
|
+
|
|
29
|
+
return JSON.parse(eventData.data);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface LegacyInterceptFlags {
|
|
33
|
+
isOnBeforeGetVizDataInterceptEnabled: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const processInterceptUrls = (interceptUrls: (string | InterceptedApiType)[]) => {
|
|
37
|
+
let processedUrls = [...interceptUrls];
|
|
38
|
+
Object.entries(defaultUrls).forEach(([apiType, apiTypeUrls]) => {
|
|
39
|
+
if (!processedUrls.includes(apiType)) return;
|
|
40
|
+
processedUrls = processedUrls.filter(url => url !== apiType);
|
|
41
|
+
processedUrls = [...processedUrls, ...apiTypeUrls];
|
|
42
|
+
})
|
|
43
|
+
return processedUrls.map(url => formatInterceptUrl(url));
|
|
44
|
+
}
|
|
45
|
+
export const getInterceptInitData = (embedConfig: EmbedConfig, viewConfig: BaseViewConfig): InterceptV2Flags => {
|
|
46
|
+
|
|
47
|
+
const enableApiIntercept = (embedConfig.enableApiIntercept || viewConfig.enableApiIntercept) && (viewConfig.enableApiIntercept !== false);
|
|
48
|
+
|
|
49
|
+
if (!enableApiIntercept) return {
|
|
50
|
+
enableApiIntercept: false,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const combinedUrls = [...(embedConfig.interceptUrls || []), ...(viewConfig.interceptUrls || [])];
|
|
54
|
+
|
|
55
|
+
if ((viewConfig as LegacyInterceptFlags).isOnBeforeGetVizDataInterceptEnabled) {
|
|
56
|
+
combinedUrls.push(InterceptedApiType.ANSWER_DATA);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const shouldInterceptAll = combinedUrls.includes(InterceptedApiType.ALL);
|
|
60
|
+
const interceptUrls = shouldInterceptAll ? [InterceptedApiType.ALL] : processInterceptUrls(combinedUrls);
|
|
61
|
+
|
|
62
|
+
const interceptTimeout = embedConfig.interceptTimeout || viewConfig.interceptTimeout;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
interceptUrls,
|
|
66
|
+
interceptTimeout,
|
|
67
|
+
enableApiIntercept,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param fetchInit
|
|
74
|
+
*/
|
|
75
|
+
const parseInterceptData = (eventDataString: any) => {
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const { input, init } = JSON.parse(eventDataString);
|
|
79
|
+
|
|
80
|
+
init.body = JSON.parse(init.body);
|
|
81
|
+
|
|
82
|
+
const parsedInit = { input, init };
|
|
83
|
+
return [parsedInit, null];
|
|
84
|
+
} catch (error) {
|
|
85
|
+
return [null, error];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const handleInterceptEvent = async (params: { eventData: any, executeEvent: (eventType: EmbedEvent, data: any) => void, embedConfig: EmbedConfig, viewConfig: BaseViewConfig, getUnsavedAnswerTml: (props: { sessionId?: string, vizId?: string }) => Promise<{ tml: string }> }) => {
|
|
90
|
+
|
|
91
|
+
const { eventData, executeEvent, viewConfig, getUnsavedAnswerTml } = params;
|
|
92
|
+
|
|
93
|
+
const [interceptData, bodyParseError] = parseInterceptData(eventData.data);
|
|
94
|
+
|
|
95
|
+
if (bodyParseError) {
|
|
96
|
+
executeEvent(EmbedEvent.Error, {
|
|
97
|
+
error: 'Error parsing api intercept body',
|
|
98
|
+
});
|
|
99
|
+
logger.error('Error parsing request body', bodyParseError);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const { input: requestUrl, init } = interceptData;
|
|
104
|
+
|
|
105
|
+
const sessionId = init?.body?.variables?.session?.sessionId;
|
|
106
|
+
const vizId = init?.body?.variables?.contextBookId;
|
|
107
|
+
|
|
108
|
+
if (defaultUrls.ANSWER_DATA.includes(requestUrl) && (viewConfig as LegacyInterceptFlags).isOnBeforeGetVizDataInterceptEnabled) {
|
|
109
|
+
const answerTml = await getUnsavedAnswerTml({ sessionId, vizId });
|
|
110
|
+
executeEvent(EmbedEvent.OnBeforeGetVizDataIntercept, { data: { data: answerTml } });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
executeEvent(EmbedEvent.ApiIntercept, interceptData);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const processLegacyInterceptResponse = (payload: any) => {
|
|
117
|
+
|
|
118
|
+
const title = payload?.data?.errorText;
|
|
119
|
+
const desc = payload?.data?.errorDescription;
|
|
120
|
+
|
|
121
|
+
const payloadToSend = {
|
|
122
|
+
execute: payload?.data?.execute,
|
|
123
|
+
errors: [
|
|
124
|
+
{
|
|
125
|
+
errorObj: {
|
|
126
|
+
title,
|
|
127
|
+
desc
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
return { data : payloadToSend };
|
|
134
|
+
}
|
package/src/embed/app.spec.ts
CHANGED
|
@@ -358,6 +358,34 @@ describe('App embed tests', () => {
|
|
|
358
358
|
});
|
|
359
359
|
});
|
|
360
360
|
|
|
361
|
+
test('should set isLinkParametersEnabled to true in url', async () => {
|
|
362
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
363
|
+
...defaultViewConfig,
|
|
364
|
+
isLinkParametersEnabled: true,
|
|
365
|
+
} as AppViewConfig);
|
|
366
|
+
appEmbed.render();
|
|
367
|
+
await executeAfterWait(() => {
|
|
368
|
+
expectUrlMatchesWithParams(
|
|
369
|
+
getIFrameSrc(),
|
|
370
|
+
`http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLinkParametersEnabled=true${defaultParamsPost}#/home`,
|
|
371
|
+
);
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
test('should set isLinkParametersEnabled to false in url', async () => {
|
|
376
|
+
const appEmbed = new AppEmbed(getRootEl(), {
|
|
377
|
+
...defaultViewConfig,
|
|
378
|
+
isLinkParametersEnabled: false,
|
|
379
|
+
} as AppViewConfig);
|
|
380
|
+
appEmbed.render();
|
|
381
|
+
await executeAfterWait(() => {
|
|
382
|
+
expectUrlMatchesWithParams(
|
|
383
|
+
getIFrameSrc(),
|
|
384
|
+
`http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLinkParametersEnabled=false${defaultParamsPost}#/home`,
|
|
385
|
+
);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
361
389
|
test('should set liveboardXLSXCSVDownload to true in url', async () => {
|
|
362
390
|
const appEmbed = new AppEmbed(getRootEl(), {
|
|
363
391
|
...defaultViewConfig,
|
package/src/embed/app.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
AllEmbedViewConfig,
|
|
20
20
|
} from '../types';
|
|
21
21
|
import { V1Embed } from './ts-embed';
|
|
22
|
+
import { getInterceptInitData } from '../api-intercept';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Pages within the ThoughtSpot app that can be embedded.
|
|
@@ -663,6 +664,7 @@ export class AppEmbed extends V1Embed {
|
|
|
663
664
|
liveboardXLSXCSVDownload = false,
|
|
664
665
|
isLiveboardStylingAndGroupingEnabled,
|
|
665
666
|
isPNGInScheduledEmailsEnabled = false,
|
|
667
|
+
isLinkParametersEnabled,
|
|
666
668
|
} = this.viewConfig;
|
|
667
669
|
|
|
668
670
|
let params: any = {};
|
|
@@ -727,7 +729,9 @@ export class AppEmbed extends V1Embed {
|
|
|
727
729
|
params[Param.enableAskSage] = enableAskSage;
|
|
728
730
|
}
|
|
729
731
|
|
|
730
|
-
|
|
732
|
+
const { enableApiIntercept } = getInterceptInitData(this.embedConfig, this.viewConfig);
|
|
733
|
+
|
|
734
|
+
if (isOnBeforeGetVizDataInterceptEnabled && !enableApiIntercept) {
|
|
731
735
|
|
|
732
736
|
params[
|
|
733
737
|
Param.IsOnBeforeGetVizDataInterceptEnabled
|
|
@@ -750,6 +754,10 @@ export class AppEmbed extends V1Embed {
|
|
|
750
754
|
params[Param.isPNGInScheduledEmailsEnabled] = isPNGInScheduledEmailsEnabled;
|
|
751
755
|
}
|
|
752
756
|
|
|
757
|
+
if (isLinkParametersEnabled !== undefined) {
|
|
758
|
+
params[Param.isLinkParametersEnabled] = isLinkParametersEnabled;
|
|
759
|
+
}
|
|
760
|
+
|
|
753
761
|
params[Param.DataPanelV2Enabled] = dataPanelV2;
|
|
754
762
|
params[Param.HideHomepageLeftNav] = hideHomepageLeftNav;
|
|
755
763
|
params[Param.ModularHomeExperienceEnabled] = modularHomeExperience;
|
|
@@ -7,6 +7,7 @@ export enum UIPassthroughEvent {
|
|
|
7
7
|
GetAvailableUIPassthroughs = 'getAvailableUiPassthroughs',
|
|
8
8
|
GetAnswerConfig = 'getAnswerPageConfig',
|
|
9
9
|
GetLiveboardConfig = 'getPinboardPageConfig',
|
|
10
|
+
GetUnsavedAnswerTML = 'getUnsavedAnswerTML',
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
// UI Passthrough Contract
|
|
@@ -63,6 +64,15 @@ export type UIPassthroughContractBase = {
|
|
|
63
64
|
request: any;
|
|
64
65
|
response: any;
|
|
65
66
|
};
|
|
67
|
+
[UIPassthroughEvent.GetUnsavedAnswerTML]: {
|
|
68
|
+
request: {
|
|
69
|
+
sessionId?: string;
|
|
70
|
+
vizId?: string;
|
|
71
|
+
};
|
|
72
|
+
response: {
|
|
73
|
+
tml: string;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
66
76
|
};
|
|
67
77
|
|
|
68
78
|
// UI Passthrough Request and Response
|
|
@@ -183,6 +183,36 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
test('should set isLinkParametersEnabled to true in url', async () => {
|
|
187
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
188
|
+
isLinkParametersEnabled: true,
|
|
189
|
+
...defaultViewConfig,
|
|
190
|
+
liveboardId,
|
|
191
|
+
} as LiveboardViewConfig);
|
|
192
|
+
liveboardEmbed.render();
|
|
193
|
+
await executeAfterWait(() => {
|
|
194
|
+
expectUrlMatchesWithParams(
|
|
195
|
+
getIFrameSrc(),
|
|
196
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLinkParametersEnabled=true${prefixParams}#/embed/viz/${liveboardId}`,
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('should set isLinkParametersEnabled to false in url', async () => {
|
|
202
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
203
|
+
isLinkParametersEnabled: false,
|
|
204
|
+
...defaultViewConfig,
|
|
205
|
+
liveboardId,
|
|
206
|
+
} as LiveboardViewConfig);
|
|
207
|
+
liveboardEmbed.render();
|
|
208
|
+
await executeAfterWait(() => {
|
|
209
|
+
expectUrlMatchesWithParams(
|
|
210
|
+
getIFrameSrc(),
|
|
211
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLinkParametersEnabled=false${prefixParams}#/embed/viz/${liveboardId}`,
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
186
216
|
test('should set visible actions as empty array', async () => {
|
|
187
217
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
188
218
|
visibleActions: [],
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -477,6 +477,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
477
477
|
isLiveboardStylingAndGroupingEnabled,
|
|
478
478
|
isPNGInScheduledEmailsEnabled = false,
|
|
479
479
|
showSpotterLimitations,
|
|
480
|
+
isLinkParametersEnabled,
|
|
480
481
|
} = this.viewConfig;
|
|
481
482
|
|
|
482
483
|
const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
|
|
@@ -552,6 +553,10 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
552
553
|
params[Param.ShowSpotterLimitations] = showSpotterLimitations;
|
|
553
554
|
}
|
|
554
555
|
|
|
556
|
+
if (isLinkParametersEnabled !== undefined) {
|
|
557
|
+
params[Param.isLinkParametersEnabled] = isLinkParametersEnabled;
|
|
558
|
+
}
|
|
559
|
+
|
|
555
560
|
params[Param.LiveboardHeaderSticky] = isLiveboardHeaderSticky;
|
|
556
561
|
params[Param.LiveboardHeaderV2] = isLiveboardCompactHeaderEnabled;
|
|
557
562
|
params[Param.ShowLiveboardVerifiedBadge] = showLiveboardVerifiedBadge;
|
package/src/embed/search.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { ERROR_MESSAGE } from '../errors';
|
|
|
26
26
|
import { getAuthPromise } from './base';
|
|
27
27
|
import { getReleaseVersion } from '../auth';
|
|
28
28
|
import { getEmbedConfig } from './embedConfig';
|
|
29
|
+
import { getInterceptInitData } from '../api-intercept';
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Configuration for search options.
|
|
@@ -442,7 +443,8 @@ export class SearchEmbed extends TsEmbed {
|
|
|
442
443
|
queryParams[Param.HideSearchBar] = true;
|
|
443
444
|
}
|
|
444
445
|
|
|
445
|
-
|
|
446
|
+
const { enableApiIntercept } = getInterceptInitData(this.embedConfig, this.viewConfig);
|
|
447
|
+
if (isOnBeforeGetVizDataInterceptEnabled && !enableApiIntercept) {
|
|
446
448
|
|
|
447
449
|
queryParams[Param.IsOnBeforeGetVizDataInterceptEnabled] = isOnBeforeGetVizDataInterceptEnabled;
|
|
448
450
|
}
|