Skip to content

Commit 2a68994

Browse files
author
Shahak Yosef
committed
Merged PR 178588: Side channel JS SDK
From the end user's perspective, they will need to provide a third parameter to `powerbi.embed()` request. The new input may be extended in the future to support other event hooks. ```javascript powerbi.embed(..., config, { preQueryCallback: provideContext }) ``` The code in `service.ts` is similar to the event listeners we set in the [constructor](https://powerbi.visualstudio.com/Embedded/_git/powerbi-javascript?path=%2Fsrc%2Fservice.ts&version=GBmaster&line=168&lineEnd=168&lineStartColumn=5&lineEndColumn=21&lineStyle=plain&_a=contents)
1 parent 51fbf9f commit 2a68994

File tree

10 files changed

+131
-51
lines changed

10 files changed

+131
-51
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ dist/powerbi.js.map
99
*.js.map
1010
package-lock.json
1111
demo/package-lock.json
12+
.vscode

.vscode/settings.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

.vscode/tasks.json

Lines changed: 0 additions & 29 deletions
This file was deleted.

dist/powerbi-client.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// powerbi-client v2.18.3
1+
// powerbi-client v2.18.4
22
// Copyright (c) Microsoft Corporation.
33
// Licensed under the MIT License.
44
declare module "config" {
@@ -2127,6 +2127,10 @@ declare module "service" {
21272127
* @hidden
21282128
*/
21292129
private embedExisting;
2130+
/**
2131+
* @hidden
2132+
*/
2133+
private registerApplicationContextHook;
21302134
/**
21312135
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
21322136
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.

dist/powerbi.js

Lines changed: 83 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/powerbi.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "powerbi-client",
3-
"version": "2.18.3",
3+
"version": "2.18.4",
44
"description": "JavaScript library for embedding Power BI into your apps. Provides service which makes it easy to embed different types of components and an object model which allows easy interaction with these components such as changing pages, applying filters, and responding to data selection.",
55
"main": "dist/powerbi.js",
66
"types": "dist/powerbi-client.d.ts",
@@ -81,7 +81,7 @@
8181
},
8282
"dependencies": {
8383
"http-post-message": "^0.2",
84-
"powerbi-models": "^1.9.2",
84+
"powerbi-models": "^1.9.3",
8585
"powerbi-router": "^0.1",
8686
"window-post-message-proxy": "^0.2"
8787
},

src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
/** @ignore *//** */
55
const config = {
6-
version: '2.18.3',
6+
version: '2.18.4',
77
type: 'js'
88
};
99

src/embed.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,15 @@ export abstract class Embed {
227227
this.commands = [];
228228
this.groups = [];
229229

230+
const registerQueryCallback = !!(<IEmbedConfiguration>config).eventHooks?.applicationContextProvider;
231+
delete (<IEmbedConfiguration>config).eventHooks;
232+
230233
this.populateConfig(config, isBootstrap);
231234

232235
if (this.embedtype === 'create') {
233-
this.setIframe(false /* set EventListener to call create() on 'load' event*/, phasedRender, isBootstrap);
236+
this.setIframe(false /* set EventListener to call create() on 'load' event*/, phasedRender, isBootstrap, registerQueryCallback);
234237
} else {
235-
this.setIframe(true /* set EventListener to call load() on 'load' event*/, phasedRender, isBootstrap);
238+
this.setIframe(true /* set EventListener to call load() on 'load' event*/, phasedRender, isBootstrap, registerQueryCallback);
236239
}
237240
}
238241

@@ -702,10 +705,14 @@ export abstract class Embed {
702705
*
703706
* @hidden
704707
*/
705-
private setIframe(isLoad: boolean, phasedRender?: boolean, isBootstrap?: boolean): void {
708+
private setIframe(isLoad: boolean, phasedRender?: boolean, isBootstrap?: boolean, registerQueryCallback?: boolean): void {
706709
if (!this.iframe) {
707710
const iframeContent = document.createElement("iframe");
708-
const embedUrl = this.config.uniqueId ? addParamToUrl(this.config.embedUrl, 'uid', this.config.uniqueId) : this.config.embedUrl;
711+
let embedUrl = this.config.uniqueId ? addParamToUrl(this.config.embedUrl, 'uid', this.config.uniqueId) : this.config.embedUrl;
712+
713+
if (!isBootstrap && registerQueryCallback)
714+
embedUrl = addParamToUrl(embedUrl, "registerQueryCallback", "true");
715+
709716
iframeContent.style.width = '100%';
710717
iframeContent.style.height = '100%';
711718
iframeContent.setAttribute("src", embedUrl);

src/service.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ export class Service implements IService {
300300
* @returns {Embed}
301301
*/
302302
embed(element: HTMLElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase = {}): Embed {
303+
this.registerApplicationContextHook(config as IEmbedConfiguration);
303304
return this.embedInternal(element, config);
304305
}
305306

@@ -314,6 +315,7 @@ export class Service implements IService {
314315
* @returns {Embed}
315316
*/
316317
load(element: HTMLElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase = {}): Embed {
318+
this.registerApplicationContextHook(config as IEmbedConfiguration);
317319
return this.embedInternal(element, config, /* phasedRender */ true, /* isBootstrap */ false);
318320
}
319321

@@ -440,6 +442,30 @@ export class Service implements IService {
440442
return component;
441443
}
442444

445+
/**
446+
* @hidden
447+
*/
448+
private registerApplicationContextHook(config: IEmbedConfiguration): void {
449+
const applicationContextProvider = config?.eventHooks?.applicationContextProvider;
450+
if (!applicationContextProvider) {
451+
return;
452+
}
453+
454+
if (typeof applicationContextProvider !== 'function') {
455+
throw new Error("applicationContextProvider must be a function");
456+
}
457+
458+
this.router.post(`preQuery`, async (req, _res) => {
459+
try {
460+
let result = await applicationContextProvider(req.body);
461+
_res.send(200, result);
462+
} catch (error) {
463+
_res.send(400, null);
464+
console.error(error);
465+
}
466+
});
467+
}
468+
443469
/**
444470
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
445471
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.

0 commit comments

Comments
 (0)