Merge remote-tracking branch 'powerbi/master' into release-2.19.1
This commit is contained in:
Коммит
8b1fe7ca1c
|
@ -1,4 +1,4 @@
|
|||
// powerbi-client v2.18.7
|
||||
// powerbi-client v2.19.1
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
declare module "config" {
|
||||
|
@ -190,6 +190,13 @@ declare module "embed" {
|
|||
* @hidden
|
||||
*/
|
||||
eventHandlers: IInternalEventHandler<any>[];
|
||||
/**
|
||||
* Gets or sets the eventHooks.
|
||||
*
|
||||
* @type {models.EventHooks}
|
||||
* @hidden
|
||||
*/
|
||||
eventHooks: models.EventHooks;
|
||||
/**
|
||||
* Gets or sets the Power BI embed service.
|
||||
*
|
||||
|
@ -418,6 +425,14 @@ declare module "embed" {
|
|||
* @returns {void}
|
||||
*/
|
||||
populateConfig(config: IBootstrapEmbedConfiguration, isBootstrap: boolean): void;
|
||||
/**
|
||||
* Validate EventHooks
|
||||
*
|
||||
* @private
|
||||
* @param {models.EventHooks} eventHooks
|
||||
* @hidden
|
||||
*/
|
||||
private validateEventHooks;
|
||||
/**
|
||||
* Adds locale parameters to embedUrl
|
||||
*
|
||||
|
@ -2159,10 +2174,6 @@ declare module "service" {
|
|||
* @hidden
|
||||
*/
|
||||
private embedExisting;
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
private registerApplicationContextHook;
|
||||
/**
|
||||
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
|
||||
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.
|
||||
|
@ -2211,6 +2222,7 @@ declare module "service" {
|
|||
* @hidden
|
||||
*/
|
||||
handleTileEvents(event: IEvent<any>): void;
|
||||
private invokeSDKHook;
|
||||
/**
|
||||
* Given an event object, finds the embed component with the matching type and ID, and invokes its handleEvent method with the event object.
|
||||
*
|
||||
|
@ -2771,6 +2783,7 @@ declare module "powerbi-client" {
|
|||
global {
|
||||
interface Window {
|
||||
powerbi: service.Service;
|
||||
powerBISDKGlobalServiceInstanceName?: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// powerbi-client v2.18.7
|
||||
// powerbi-client v2.19.1
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
|
@ -290,7 +290,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
// powerbi-models v1.9.7
|
||||
// powerbi-models v1.9.8
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
|
@ -6987,7 +6987,7 @@ var BookmarksManager = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -7021,7 +7021,7 @@ var BookmarksManager = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
request = {
|
||||
|
@ -7057,7 +7057,7 @@ var BookmarksManager = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
playBookmarkRequest = {
|
||||
|
@ -7092,7 +7092,7 @@ var BookmarksManager = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
request = {
|
||||
|
@ -7129,7 +7129,7 @@ var BookmarksManager = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
request = {
|
||||
|
@ -7167,7 +7167,7 @@ exports.BookmarksManager = BookmarksManager;
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/** @ignore */ /** */
|
||||
var config = {
|
||||
version: '2.18.7',
|
||||
version: '2.19.1',
|
||||
type: 'js'
|
||||
};
|
||||
exports.default = config;
|
||||
|
@ -7271,7 +7271,7 @@ var Create = /** @class */ (function (_super) {
|
|||
* Validate create report configuration.
|
||||
*/
|
||||
Create.prototype.validate = function (config) {
|
||||
return powerbi_models_1.validateCreateReport(config);
|
||||
return (0, powerbi_models_1.validateCreateReport)(config);
|
||||
};
|
||||
/**
|
||||
* Handle config changes.
|
||||
|
@ -7438,7 +7438,7 @@ var Dashboard = /** @class */ (function (_super) {
|
|||
*/
|
||||
Dashboard.prototype.validate = function (baseConfig) {
|
||||
var config = baseConfig;
|
||||
var error = powerbi_models_1.validateDashboardLoad(config);
|
||||
var error = (0, powerbi_models_1.validateDashboardLoad)(config);
|
||||
return error ? error : this.validatePageView(config.pageView);
|
||||
};
|
||||
/**
|
||||
|
@ -7560,7 +7560,7 @@ var Embed = /** @class */ (function () {
|
|||
function Embed(service, element, config, iframe, phasedRender, isBootstrap) {
|
||||
/** @hidden */
|
||||
this.allowedEvents = [];
|
||||
if (util_1.autoAuthInEmbedUrl(config.embedUrl)) {
|
||||
if ((0, util_1.autoAuthInEmbedUrl)(config.embedUrl)) {
|
||||
throw new Error(errors_1.EmbedUrlNotSupported);
|
||||
}
|
||||
Array.prototype.push.apply(this.allowedEvents, Embed.allowedEvents);
|
||||
|
@ -7746,7 +7746,7 @@ var Embed = /** @class */ (function () {
|
|||
sdkVersion: sdkConfig.default.version
|
||||
};
|
||||
timeNow = new Date();
|
||||
if (this.lastLoadRequest && util_1.getTimeDiffInMilliseconds(this.lastLoadRequest, timeNow) < 100) {
|
||||
if (this.lastLoadRequest && (0, util_1.getTimeDiffInMilliseconds)(this.lastLoadRequest, timeNow) < 100) {
|
||||
console.debug("Power BI SDK sent more than two /report/load requests in the last 100ms interval.");
|
||||
return [2 /*return*/];
|
||||
}
|
||||
|
@ -7791,7 +7791,7 @@ var Embed = /** @class */ (function () {
|
|||
var _this = this;
|
||||
var fakeEvent = { name: eventName, type: null, id: null, value: null };
|
||||
if (handler) {
|
||||
util_1.remove(function (eventHandler) { return eventHandler.test(fakeEvent) && (eventHandler.handle === handler); }, this.eventHandlers);
|
||||
(0, util_1.remove)(function (eventHandler) { return eventHandler.test(fakeEvent) && (eventHandler.handle === handler); }, this.eventHandlers);
|
||||
this.element.removeEventListener(eventName, handler);
|
||||
}
|
||||
else {
|
||||
|
@ -7799,7 +7799,7 @@ var Embed = /** @class */ (function () {
|
|||
.filter(function (eventHandler) { return eventHandler.test(fakeEvent); });
|
||||
eventHandlersToRemove
|
||||
.forEach(function (eventHandlerToRemove) {
|
||||
util_1.remove(function (eventHandler) { return eventHandler === eventHandlerToRemove; }, _this.eventHandlers);
|
||||
(0, util_1.remove)(function (eventHandler) { return eventHandler === eventHandlerToRemove; }, _this.eventHandlers);
|
||||
_this.element.removeEventListener(eventName, eventHandlerToRemove.handle);
|
||||
});
|
||||
}
|
||||
|
@ -7903,16 +7903,16 @@ var Embed = /** @class */ (function () {
|
|||
*/
|
||||
Embed.prototype.populateConfig = function (config, isBootstrap) {
|
||||
var _this = this;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
||||
if (this.bootstrapConfig) {
|
||||
this.config = util_1.assign({}, this.bootstrapConfig, config);
|
||||
this.config = (0, util_1.assign)({}, this.bootstrapConfig, config);
|
||||
// reset bootstrapConfig because we do not want to merge it in re-embed scenario.
|
||||
this.bootstrapConfig = null;
|
||||
}
|
||||
else {
|
||||
// Copy config - important for multiple iframe scenario.
|
||||
// Otherwise, if a user uses the same config twice, same unique Id which will be used in different iframes.
|
||||
this.config = util_1.assign({}, config);
|
||||
this.config = (0, util_1.assign)({}, config);
|
||||
}
|
||||
this.config.embedUrl = this.getEmbedUrl(isBootstrap);
|
||||
this.config.groupId = this.getGroupId();
|
||||
|
@ -7938,12 +7938,41 @@ var Embed = /** @class */ (function () {
|
|||
else {
|
||||
this.config.accessToken = this.getAccessToken(this.service.accessToken);
|
||||
}
|
||||
var registerQueryCallback = !!((_k = this.config.eventHooks) === null || _k === void 0 ? void 0 : _k.applicationContextProvider);
|
||||
this.eventHooks = this.config.eventHooks;
|
||||
this.validateEventHooks(this.eventHooks);
|
||||
delete this.config.eventHooks;
|
||||
if (registerQueryCallback && this.embedtype === "report")
|
||||
this.config.embedUrl = util_1.addParamToUrl(this.config.embedUrl, "registerQueryCallback", "true");
|
||||
this.configChanged(isBootstrap);
|
||||
};
|
||||
/**
|
||||
* Validate EventHooks
|
||||
*
|
||||
* @private
|
||||
* @param {models.EventHooks} eventHooks
|
||||
* @hidden
|
||||
*/
|
||||
Embed.prototype.validateEventHooks = function (eventHooks) {
|
||||
if (!eventHooks) {
|
||||
return;
|
||||
}
|
||||
for (var key in eventHooks) {
|
||||
if (eventHooks.hasOwnProperty(key) && typeof eventHooks[key] !== 'function') {
|
||||
throw new Error(key + " must be a function");
|
||||
}
|
||||
}
|
||||
var applicationContextProvider = eventHooks.applicationContextProvider;
|
||||
if (!!applicationContextProvider) {
|
||||
if (this.embedtype.toLowerCase() !== "report") {
|
||||
throw new Error("applicationContextProvider is only supported in report embed");
|
||||
}
|
||||
this.config.embedUrl = (0, util_1.addParamToUrl)(this.config.embedUrl, "registerQueryCallback", "true");
|
||||
}
|
||||
var accessTokenProvider = eventHooks.accessTokenProvider;
|
||||
if (!!accessTokenProvider) {
|
||||
if (this.embedtype.toLowerCase() !== "report" || this.config.tokenType !== models.TokenType.Aad) {
|
||||
throw new Error("accessTokenProvider is only supported in report SaaS embed");
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Adds locale parameters to embedUrl
|
||||
*
|
||||
|
@ -7957,10 +7986,10 @@ var Embed = /** @class */ (function () {
|
|||
}
|
||||
var localeSettings = config.settings.localeSettings;
|
||||
if (localeSettings && localeSettings.language) {
|
||||
this.config.embedUrl = util_1.addParamToUrl(this.config.embedUrl, 'language', localeSettings.language);
|
||||
this.config.embedUrl = (0, util_1.addParamToUrl)(this.config.embedUrl, 'language', localeSettings.language);
|
||||
}
|
||||
if (localeSettings && localeSettings.formatLocale) {
|
||||
this.config.embedUrl = util_1.addParamToUrl(this.config.embedUrl, 'formatLocale', localeSettings.formatLocale);
|
||||
this.config.embedUrl = (0, util_1.addParamToUrl)(this.config.embedUrl, 'formatLocale', localeSettings.formatLocale);
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
@ -8008,7 +8037,7 @@ var Embed = /** @class */ (function () {
|
|||
* @hidden
|
||||
*/
|
||||
Embed.prototype.getUniqueId = function () {
|
||||
return this.config.uniqueId || this.element.getAttribute(Embed.nameAttribute) || util_1.createRandomString();
|
||||
return this.config.uniqueId || this.element.getAttribute(Embed.nameAttribute) || (0, util_1.createRandomString)();
|
||||
};
|
||||
/**
|
||||
* Gets the group ID from the first available location: options, embeddedUrl.
|
||||
|
@ -8059,7 +8088,7 @@ var Embed = /** @class */ (function () {
|
|||
var _this = this;
|
||||
if (!this.iframe) {
|
||||
var iframeContent = document.createElement("iframe");
|
||||
var embedUrl = this.config.uniqueId ? util_1.addParamToUrl(this.config.embedUrl, 'uid', this.config.uniqueId) : this.config.embedUrl;
|
||||
var embedUrl = this.config.uniqueId ? (0, util_1.addParamToUrl)(this.config.embedUrl, 'uid', this.config.uniqueId) : this.config.embedUrl;
|
||||
iframeContent.style.width = '100%';
|
||||
iframeContent.style.height = '100%';
|
||||
iframeContent.setAttribute("src", embedUrl);
|
||||
|
@ -8184,7 +8213,7 @@ var Embed = /** @class */ (function () {
|
|||
});
|
||||
};
|
||||
/** @hidden */
|
||||
Embed.allowedEvents = ["loaded", "saved", "rendered", "saveAsTriggered", "error", "dataSelected", "buttonClicked"];
|
||||
Embed.allowedEvents = ["loaded", "saved", "rendered", "saveAsTriggered", "error", "dataSelected", "buttonClicked", "info"];
|
||||
/** @hidden */
|
||||
Embed.accessTokenAttribute = 'powerbi-access-token';
|
||||
/** @hidden */
|
||||
|
@ -8573,7 +8602,7 @@ var Page = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.report.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.report.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -8611,7 +8640,7 @@ var Page = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.report.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.report.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -8746,7 +8775,7 @@ var Page = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.report.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.report.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -8782,7 +8811,7 @@ var Page = /** @class */ (function () {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.report.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.report.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
layoutTypeEnum = powerbi_models_1.LayoutType[layoutType];
|
||||
|
@ -8856,7 +8885,14 @@ Object.defineProperty(exports, "RelativeTimeFilterBuilder", { enumerable: true,
|
|||
* Note: create an instance of the class with the default configuration for normal usage, or save the class so that you can create an instance of the service.
|
||||
*/
|
||||
var powerbi = new service.Service(factories.hpmFactory, factories.wpmpFactory, factories.routerFactory);
|
||||
window.powerbi = powerbi;
|
||||
// powerBI SDK may use Power BI object under different key, in order to avoid name collisions
|
||||
if (window.powerbi && window.powerBISDKGlobalServiceInstanceName) {
|
||||
window[window.powerBISDKGlobalServiceInstanceName] = powerbi;
|
||||
}
|
||||
else {
|
||||
// Default to Power BI.
|
||||
window.powerbi = powerbi;
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
@ -8999,7 +9035,7 @@ var Qna = /** @class */ (function (_super) {
|
|||
* Validate load configuration.
|
||||
*/
|
||||
Qna.prototype.validate = function (config) {
|
||||
return powerbi_models_1.validateLoadQnaConfiguration(config);
|
||||
return (0, powerbi_models_1.validateLoadQnaConfiguration)(config);
|
||||
};
|
||||
/** @hidden */
|
||||
Qna.type = "Qna";
|
||||
|
@ -9072,10 +9108,14 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||||
to[j] = from[i];
|
||||
return to;
|
||||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
||||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||
if (ar || !(i in from)) {
|
||||
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||
ar[i] = from[i];
|
||||
}
|
||||
}
|
||||
return to.concat(ar || Array.prototype.slice.call(from));
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Report = void 0;
|
||||
|
@ -9286,7 +9326,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9350,7 +9390,7 @@ var Report = /** @class */ (function (_super) {
|
|||
Report.prototype.removeFilters = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
return [2 /*return*/, this.updateFilters(powerbi_models_1.FiltersOperations.RemoveAll)];
|
||||
|
@ -9380,7 +9420,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9428,7 +9468,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9466,7 +9506,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9506,7 +9546,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9552,7 +9592,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9587,7 +9627,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
page = {
|
||||
|
@ -9635,7 +9675,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl) && settings.customLayout != null) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl) && settings.customLayout != null) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_c.label = 1;
|
||||
|
@ -9669,10 +9709,10 @@ var Report = /** @class */ (function (_super) {
|
|||
* @hidden
|
||||
*/
|
||||
Report.prototype.validate = function (config) {
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
return powerbi_models_1.validatePaginatedReportLoad(config);
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return (0, powerbi_models_1.validatePaginatedReportLoad)(config);
|
||||
}
|
||||
return powerbi_models_1.validateReportLoad(config);
|
||||
return (0, powerbi_models_1.validateReportLoad)(config);
|
||||
};
|
||||
/**
|
||||
* Handle config changes.
|
||||
|
@ -9682,7 +9722,7 @@ var Report = /** @class */ (function (_super) {
|
|||
Report.prototype.configChanged = function (isBootstrap) {
|
||||
var config = this.config;
|
||||
if (this.isMobileSettings(config.settings)) {
|
||||
config.embedUrl = util_1.addParamToUrl(config.embedUrl, "isMobile", "true");
|
||||
config.embedUrl = (0, util_1.addParamToUrl)(config.embedUrl, "isMobile", "true");
|
||||
}
|
||||
// Calculate settings from HTML element attributes if available.
|
||||
var filterPaneEnabledAttribute = this.element.getAttribute(Report.filterPaneEnabledAttribute);
|
||||
|
@ -9692,7 +9732,7 @@ var Report = /** @class */ (function (_super) {
|
|||
navContentPaneEnabled: (navContentPaneEnabledAttribute == null) ? undefined : (navContentPaneEnabledAttribute !== "false")
|
||||
};
|
||||
// Set the settings back into the config.
|
||||
this.config.settings = util_1.assign({}, elementAttrSettings, config.settings);
|
||||
this.config.settings = (0, util_1.assign)({}, elementAttrSettings, config.settings);
|
||||
if (isBootstrap) {
|
||||
return;
|
||||
}
|
||||
|
@ -9778,10 +9818,10 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
return [4 /*yield*/, util_1.isSavedInternal(this.service.hpm, this.config.uniqueId, this.iframe.contentWindow)];
|
||||
return [4 /*yield*/, (0, util_1.isSavedInternal)(this.service.hpm, this.config.uniqueId, this.iframe.contentWindow)];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
|
@ -9799,7 +9839,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
return [4 /*yield*/, this.applyThemeInternal(theme)];
|
||||
|
@ -9820,7 +9860,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
return [4 /*yield*/, this.applyThemeInternal({})];
|
||||
|
@ -9842,7 +9882,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
_a.label = 1;
|
||||
|
@ -9957,7 +9997,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
commandCopy = JSON.parse(JSON.stringify(this.commands));
|
||||
|
@ -10008,7 +10048,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
newCommands = this.createMenuCommand("visualContextMenu", commandName, commandTitle, contextMenuTitle, menuLocation, visualName, visualType, groupName);
|
||||
|
@ -10044,7 +10084,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
commandCopy = JSON.parse(JSON.stringify(this.commands));
|
||||
|
@ -10099,7 +10139,7 @@ var Report = /** @class */ (function (_super) {
|
|||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (util_1.isRDLEmbed(this.config.embedUrl)) {
|
||||
if ((0, util_1.isRDLEmbed)(this.config.embedUrl)) {
|
||||
return [2 /*return*/, Promise.reject(errors_1.APINotSupportedForRDLError)];
|
||||
}
|
||||
newCommands = this.createMenuCommand("visualOptionsMenu", commandName, commandTitle, optionsMenuTitle, menuLocation, visualName, visualType, groupName, commandIcon);
|
||||
|
@ -10322,7 +10362,7 @@ var Report = /** @class */ (function (_super) {
|
|||
visualType: visualType
|
||||
};
|
||||
}
|
||||
return __spreadArray(__spreadArray([], this.commands), [newCommandObj]);
|
||||
return __spreadArray(__spreadArray([], this.commands, true), [newCommandObj], false);
|
||||
};
|
||||
/**
|
||||
* @hidden
|
||||
|
@ -10480,6 +10520,17 @@ exports.Report = Report;
|
|||
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
|
@ -10551,6 +10602,43 @@ var Service = /** @class */ (function () {
|
|||
this.hpm = hpmFactory(this.wpmp, null, config.version, config.type);
|
||||
this.router = routerFactory(this.wpmp);
|
||||
this.uniqueSessionId = utils.generateUUID();
|
||||
this.router.post('/reports/:uniqueId/eventHooks/:eventName', function (req, _res) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var embed, _a;
|
||||
var _b, _c;
|
||||
return __generator(this, function (_d) {
|
||||
switch (_d.label) {
|
||||
case 0:
|
||||
embed = utils.find(function (embed) {
|
||||
return (embed.config.uniqueId === req.params.uniqueId);
|
||||
}, this.embeds);
|
||||
if (!embed) {
|
||||
return [2 /*return*/];
|
||||
}
|
||||
_a = req.params.eventName;
|
||||
switch (_a) {
|
||||
case "preQuery": return [3 /*break*/, 1];
|
||||
case "newAccessToken": return [3 /*break*/, 3];
|
||||
}
|
||||
return [3 /*break*/, 5];
|
||||
case 1:
|
||||
req.body = req.body || {};
|
||||
req.body.report = embed;
|
||||
return [4 /*yield*/, this.invokeSDKHook((_b = embed.eventHooks) === null || _b === void 0 ? void 0 : _b.applicationContextProvider, req, _res)];
|
||||
case 2:
|
||||
_d.sent();
|
||||
return [3 /*break*/, 6];
|
||||
case 3:
|
||||
req.body = req.body || {};
|
||||
req.body.report = embed;
|
||||
return [4 /*yield*/, this.invokeSDKHook((_c = embed.eventHooks) === null || _c === void 0 ? void 0 : _c.accessTokenProvider, req, _res)];
|
||||
case 4:
|
||||
_d.sent();
|
||||
return [3 /*break*/, 6];
|
||||
case 5: return [3 /*break*/, 6];
|
||||
case 6: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
/**
|
||||
* Adds handler for report events.
|
||||
*/
|
||||
|
@ -10671,7 +10759,6 @@ var Service = /** @class */ (function () {
|
|||
*/
|
||||
Service.prototype.embed = function (element, config) {
|
||||
if (config === void 0) { config = {}; }
|
||||
this.registerApplicationContextHook(config);
|
||||
return this.embedInternal(element, config);
|
||||
};
|
||||
/**
|
||||
|
@ -10686,7 +10773,6 @@ var Service = /** @class */ (function () {
|
|||
*/
|
||||
Service.prototype.load = function (element, config) {
|
||||
if (config === void 0) { config = {}; }
|
||||
this.registerApplicationContextHook(config);
|
||||
return this.embedInternal(element, config, /* phasedRender */ true, /* isBootstrap */ false);
|
||||
};
|
||||
/**
|
||||
|
@ -10696,7 +10782,6 @@ var Service = /** @class */ (function () {
|
|||
* @param {IBootstrapEmbedConfiguration} config: a bootstrap config which is an embed config without access token.
|
||||
*/
|
||||
Service.prototype.bootstrap = function (element, config) {
|
||||
this.registerApplicationContextHook(config);
|
||||
return this.embedInternal(element, config, /* phasedRender */ false, /* isBootstrap */ true);
|
||||
};
|
||||
/** @hidden */
|
||||
|
@ -10738,7 +10823,8 @@ var Service = /** @class */ (function () {
|
|||
Service.prototype.embedNew = function (element, config, phasedRender, isBootstrap) {
|
||||
var componentType = config.type || element.getAttribute(embed_1.Embed.typeAttribute);
|
||||
if (!componentType) {
|
||||
throw new Error("Attempted to embed using config " + JSON.stringify(config) + " on element " + element.outerHTML + ", but could not determine what type of component to embed. You must specify a type in the configuration or as an attribute such as '" + embed_1.Embed.typeAttribute + "=\"" + report_1.Report.type.toLowerCase() + "\"'.");
|
||||
var scrubbedConfig = __assign(__assign({}, config), { accessToken: "" });
|
||||
throw new Error("Attempted to embed using config " + JSON.stringify(scrubbedConfig) + " on element " + element.outerHTML + ", but could not determine what type of component to embed. You must specify a type in the configuration or as an attribute such as '" + embed_1.Embed.typeAttribute + "=\"" + report_1.Report.type.toLowerCase() + "\"'.");
|
||||
}
|
||||
// Saves the type as part of the configuration so that it can be referenced later at a known location.
|
||||
config.type = componentType;
|
||||
|
@ -10763,7 +10849,8 @@ var Service = /** @class */ (function () {
|
|||
Service.prototype.embedExisting = function (element, config, phasedRender) {
|
||||
var component = utils.find(function (x) { return x.element === element; }, this.embeds);
|
||||
if (!component) {
|
||||
throw new Error("Attempted to embed using config " + JSON.stringify(config) + " on element " + element.outerHTML + " which already has embedded component associated, but could not find the existing component in the list of active components. This could indicate the embeds list is out of sync with the DOM, or the component is referencing the incorrect HTML element.");
|
||||
var scrubbedConfig = __assign(__assign({}, config), { accessToken: "" });
|
||||
throw new Error("Attempted to embed using config " + JSON.stringify(scrubbedConfig) + " on element " + element.outerHTML + " which already has embedded component associated, but could not find the existing component in the list of active components. This could indicate the embeds list is out of sync with the DOM, or the component is referencing the incorrect HTML element.");
|
||||
}
|
||||
// TODO: Multiple embedding to the same iframe is not supported in QnA
|
||||
if (config.type && config.type.toLowerCase() === "qna") {
|
||||
|
@ -10786,49 +10873,13 @@ var Service = /** @class */ (function () {
|
|||
this.addOrOverwriteEmbed(component, element);
|
||||
return report;
|
||||
}
|
||||
throw new Error("Embedding on an existing element with a different type than the previous embed object is not supported. Attempted to embed using config " + JSON.stringify(config) + " on element " + element.outerHTML + ", but the existing element contains an embed of type: " + this.config.type + " which does not match the new type: " + config.type);
|
||||
var scrubbedConfig = __assign(__assign({}, config), { accessToken: "" });
|
||||
throw new Error("Embedding on an existing element with a different type than the previous embed object is not supported. Attempted to embed using config " + JSON.stringify(scrubbedConfig) + " on element " + element.outerHTML + ", but the existing element contains an embed of type: " + this.config.type + " which does not match the new type: " + config.type);
|
||||
}
|
||||
component.populateConfig(config, /* isBootstrap */ false);
|
||||
component.load(phasedRender);
|
||||
return component;
|
||||
};
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
Service.prototype.registerApplicationContextHook = function (config) {
|
||||
var _this = this;
|
||||
var _a;
|
||||
var applicationContextProvider = (_a = config === null || config === void 0 ? void 0 : config.eventHooks) === null || _a === void 0 ? void 0 : _a.applicationContextProvider;
|
||||
if (!applicationContextProvider) {
|
||||
return;
|
||||
}
|
||||
if ((config === null || config === void 0 ? void 0 : config.type.toLowerCase()) !== "report") {
|
||||
throw new Error("applicationContextProvider is only supported in report embed");
|
||||
}
|
||||
if (typeof applicationContextProvider !== 'function') {
|
||||
throw new Error("applicationContextProvider must be a function");
|
||||
}
|
||||
this.router.post("preQuery", function (req, _res) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var result, error_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
_a.trys.push([0, 2, , 3]);
|
||||
return [4 /*yield*/, applicationContextProvider(req.body)];
|
||||
case 1:
|
||||
result = _a.sent();
|
||||
_res.send(200, result);
|
||||
return [3 /*break*/, 3];
|
||||
case 2:
|
||||
error_1 = _a.sent();
|
||||
_res.send(400, null);
|
||||
console.error(error_1);
|
||||
return [3 /*break*/, 3];
|
||||
case 3: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
};
|
||||
/**
|
||||
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
|
||||
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.
|
||||
|
@ -10927,6 +10978,34 @@ var Service = /** @class */ (function () {
|
|||
this.handleEvent(event);
|
||||
}
|
||||
};
|
||||
Service.prototype.invokeSDKHook = function (hook, req, res) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var result, error_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!hook) {
|
||||
res.send(404, null);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, hook(req.body)];
|
||||
case 2:
|
||||
result = _a.sent();
|
||||
res.send(200, result);
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
error_1 = _a.sent();
|
||||
res.send(400, null);
|
||||
console.error(error_1);
|
||||
return [3 /*break*/, 4];
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Given an event object, finds the embed component with the matching type and ID, and invokes its handleEvent method with the event object.
|
||||
*
|
||||
|
@ -11071,7 +11150,7 @@ var Tile = /** @class */ (function (_super) {
|
|||
*/
|
||||
Tile.prototype.validate = function (config) {
|
||||
var embedConfig = config;
|
||||
return powerbi_models_1.validateTileLoad(embedConfig);
|
||||
return (0, powerbi_models_1.validateTileLoad)(embedConfig);
|
||||
};
|
||||
/**
|
||||
* Handle config changes.
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -220,8 +220,9 @@ gulp.task('test:js', 'Run js tests', function (done) {
|
|||
configFile: __dirname + '/karma.conf.js',
|
||||
singleRun: argv.watch ? false : true,
|
||||
captureTimeout: argv.timeout || 60000
|
||||
}, function () {
|
||||
}, function (exitStatus) {
|
||||
done();
|
||||
process.exit(exitStatus);
|
||||
})
|
||||
.on('browser_register', (browser) => {
|
||||
if (argv.chrome) {
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = function (config) {
|
|||
{ pattern: './test/**/*.html', served: true, included: false }
|
||||
],
|
||||
exclude: [],
|
||||
reporters: argv.debug ? ['spec', 'kjhtml'] : ['spec', 'coverage', 'kjhtml'],
|
||||
reporters: argv.chrome ? ['kjhtml'] : ['spec', 'junit'],
|
||||
autoWatch: true,
|
||||
browsers: [browserName],
|
||||
browserNoActivityTimeout: 300000,
|
||||
|
@ -33,27 +33,24 @@ module.exports = function (config) {
|
|||
'karma-jasmine',
|
||||
'karma-spec-reporter',
|
||||
'karma-phantomjs-launcher',
|
||||
'karma-coverage',
|
||||
'karma-jasmine-html-reporter'
|
||||
'karma-jasmine-html-reporter',
|
||||
'karma-junit-reporter'
|
||||
],
|
||||
customLaunchers: {
|
||||
'Chrome_headless': {
|
||||
base: argv.debug ? 'Chrome' : 'ChromeHeadless',
|
||||
base: 'Chrome',
|
||||
flags: flags.concat("--no-sandbox", "--window-size=800,800"),
|
||||
},
|
||||
},
|
||||
preprocessors: { './tmp/**/*.js': ['coverage'] },
|
||||
coverageReporter: {
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
junitReporter: {
|
||||
outputDir: 'tmp',
|
||||
outputFile: 'testresults.xml',
|
||||
useBrowserName: false
|
||||
},
|
||||
retryLimit: 0,
|
||||
logLevel: argv.debug ? config.LOG_DEBUG : config.LOG_INFO,
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
args: argv.logMessages ? ['logMessages'] : []
|
||||
}
|
||||
});
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "powerbi-client",
|
||||
"version": "2.18.7",
|
||||
"version": "2.19.1",
|
||||
"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.",
|
||||
"main": "dist/powerbi.js",
|
||||
"types": "dist/powerbi-client.d.ts",
|
||||
|
@ -16,7 +16,7 @@
|
|||
"prestart": "cd demo && npm install",
|
||||
"test": "gulp test",
|
||||
"gulp": "gulp",
|
||||
"tests": "npm test -- --chrome --watch --debug"
|
||||
"tests": "npm test -- --chrome --watch"
|
||||
},
|
||||
"keywords": [
|
||||
"microsoft",
|
||||
|
@ -64,10 +64,10 @@
|
|||
"json-loader": "^0.5.4",
|
||||
"karma": "6.3.5",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-coverage": "^2.0.3",
|
||||
"karma-firefox-launcher": "^1.2.0",
|
||||
"karma-jasmine": "4.0.1",
|
||||
"karma-jasmine-html-reporter": "1.7.0",
|
||||
"karma-junit-reporter": "^2.0.1",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"karma-spec-reporter": "0.0.32",
|
||||
"moment": "^2.14.1",
|
||||
|
@ -81,7 +81,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"http-post-message": "^0.2",
|
||||
"powerbi-models": "^1.9.7",
|
||||
"powerbi-models": "^1.9.8",
|
||||
"powerbi-router": "^0.1",
|
||||
"window-post-message-proxy": "^0.2"
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/** @ignore *//** */
|
||||
const config = {
|
||||
version: '2.18.7',
|
||||
version: '2.19.1',
|
||||
type: 'js'
|
||||
};
|
||||
|
||||
|
|
50
src/embed.ts
50
src/embed.ts
|
@ -70,7 +70,7 @@ export interface IInternalEventHandler<T> {
|
|||
*/
|
||||
export abstract class Embed {
|
||||
/** @hidden */
|
||||
static allowedEvents = ["loaded", "saved", "rendered", "saveAsTriggered", "error", "dataSelected", "buttonClicked"];
|
||||
static allowedEvents = ["loaded", "saved", "rendered", "saveAsTriggered", "error", "dataSelected", "buttonClicked", "info"];
|
||||
/** @hidden */
|
||||
static accessTokenAttribute = 'powerbi-access-token';
|
||||
/** @hidden */
|
||||
|
@ -108,6 +108,14 @@ export abstract class Embed {
|
|||
*/
|
||||
eventHandlers: IInternalEventHandler<any>[];
|
||||
|
||||
/**
|
||||
* Gets or sets the eventHooks.
|
||||
*
|
||||
* @type {models.EventHooks}
|
||||
* @hidden
|
||||
*/
|
||||
eventHooks: models.EventHooks;
|
||||
|
||||
/**
|
||||
* Gets or sets the Power BI embed service.
|
||||
*
|
||||
|
@ -537,14 +545,48 @@ export abstract class Embed {
|
|||
this.config.accessToken = this.getAccessToken(this.service.accessToken);
|
||||
}
|
||||
|
||||
const registerQueryCallback = !!(<IEmbedConfiguration>this.config).eventHooks?.applicationContextProvider;
|
||||
this.eventHooks = (<IEmbedConfiguration>this.config).eventHooks;
|
||||
this.validateEventHooks(this.eventHooks);
|
||||
delete (<IEmbedConfiguration>this.config).eventHooks;
|
||||
if (registerQueryCallback && this.embedtype === "report")
|
||||
this.config.embedUrl = addParamToUrl(this.config.embedUrl, "registerQueryCallback", "true");
|
||||
|
||||
this.configChanged(isBootstrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate EventHooks
|
||||
*
|
||||
* @private
|
||||
* @param {models.EventHooks} eventHooks
|
||||
* @hidden
|
||||
*/
|
||||
private validateEventHooks(eventHooks: models.EventHooks): void {
|
||||
if (!eventHooks) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let key in eventHooks) {
|
||||
if (eventHooks.hasOwnProperty(key) && typeof eventHooks[key] !== 'function') {
|
||||
throw new Error(key + " must be a function");
|
||||
}
|
||||
}
|
||||
|
||||
const applicationContextProvider = eventHooks.applicationContextProvider;
|
||||
if (!!applicationContextProvider) {
|
||||
if (this.embedtype.toLowerCase() !== "report") {
|
||||
throw new Error("applicationContextProvider is only supported in report embed");
|
||||
}
|
||||
|
||||
this.config.embedUrl = addParamToUrl(this.config.embedUrl, "registerQueryCallback", "true");
|
||||
}
|
||||
|
||||
const accessTokenProvider = eventHooks.accessTokenProvider;
|
||||
if (!!accessTokenProvider) {
|
||||
if (this.embedtype.toLowerCase() !== "report" || this.config.tokenType !== models.TokenType.Aad) {
|
||||
throw new Error("accessTokenProvider is only supported in report SaaS embed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds locale parameters to embedUrl
|
||||
*
|
||||
|
|
|
@ -60,6 +60,7 @@ declare var powerbi: service.Service;
|
|||
declare global {
|
||||
interface Window {
|
||||
powerbi: service.Service;
|
||||
powerBISDKGlobalServiceInstanceName?: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,4 +70,10 @@ declare global {
|
|||
* Note: create an instance of the class with the default configuration for normal usage, or save the class so that you can create an instance of the service.
|
||||
*/
|
||||
var powerbi = new service.Service(factories.hpmFactory, factories.wpmpFactory, factories.routerFactory);
|
||||
window.powerbi = powerbi;
|
||||
// powerBI SDK may use Power BI object under different key, in order to avoid name collisions
|
||||
if (window.powerbi && window.powerBISDKGlobalServiceInstanceName) {
|
||||
window[window.powerBISDKGlobalServiceInstanceName] = powerbi;
|
||||
} else {
|
||||
// Default to Power BI.
|
||||
window.powerbi = powerbi;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { WindowPostMessageProxy } from 'window-post-message-proxy';
|
||||
import { HttpPostMessage } from 'http-post-message';
|
||||
import { Router } from 'powerbi-router';
|
||||
import { Router, IExtendedRequest, Response as IExtendedResponse } from 'powerbi-router';
|
||||
import { IPage, IReportCreateConfiguration } from 'powerbi-models';
|
||||
import {
|
||||
Embed,
|
||||
|
@ -162,6 +162,33 @@ export class Service implements IService {
|
|||
this.router = routerFactory(this.wpmp);
|
||||
this.uniqueSessionId = utils.generateUUID();
|
||||
|
||||
this.router.post('/reports/:uniqueId/eventHooks/:eventName', async (req, _res) => {
|
||||
let embed = utils.find(embed => {
|
||||
return (embed.config.uniqueId === req.params.uniqueId);
|
||||
}, this.embeds);
|
||||
|
||||
if (!embed) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (req.params.eventName) {
|
||||
case "preQuery":
|
||||
req.body = req.body || {};
|
||||
req.body.report = embed;
|
||||
await this.invokeSDKHook(embed.eventHooks?.applicationContextProvider, req, _res);
|
||||
break;
|
||||
|
||||
case "newAccessToken":
|
||||
req.body = req.body || {};
|
||||
req.body.report = embed;
|
||||
await this.invokeSDKHook(embed.eventHooks?.accessTokenProvider, req, _res);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Adds handler for report events.
|
||||
*/
|
||||
|
@ -300,7 +327,6 @@ export class Service implements IService {
|
|||
* @returns {Embed}
|
||||
*/
|
||||
embed(element: HTMLElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase = {}): Embed {
|
||||
this.registerApplicationContextHook(config as IEmbedConfiguration);
|
||||
return this.embedInternal(element, config);
|
||||
}
|
||||
|
||||
|
@ -315,7 +341,6 @@ export class Service implements IService {
|
|||
* @returns {Embed}
|
||||
*/
|
||||
load(element: HTMLElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase = {}): Embed {
|
||||
this.registerApplicationContextHook(config as IEmbedConfiguration);
|
||||
return this.embedInternal(element, config, /* phasedRender */ true, /* isBootstrap */ false);
|
||||
}
|
||||
|
||||
|
@ -326,7 +351,6 @@ export class Service implements IService {
|
|||
* @param {IBootstrapEmbedConfiguration} config: a bootstrap config which is an embed config without access token.
|
||||
*/
|
||||
bootstrap(element: HTMLElement, config: IComponentEmbedConfiguration | IBootstrapEmbedConfiguration): Embed {
|
||||
this.registerApplicationContextHook(config as IEmbedConfiguration);
|
||||
return this.embedInternal(element, config, /* phasedRender */ false, /* isBootstrap */ true);
|
||||
}
|
||||
|
||||
|
@ -375,7 +399,8 @@ export class Service implements IService {
|
|||
private embedNew(element: IPowerBiElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase, phasedRender?: boolean, isBootstrap?: boolean): Embed {
|
||||
const componentType = config.type || element.getAttribute(Embed.typeAttribute);
|
||||
if (!componentType) {
|
||||
throw new Error(`Attempted to embed using config ${JSON.stringify(config)} on element ${element.outerHTML}, but could not determine what type of component to embed. You must specify a type in the configuration or as an attribute such as '${Embed.typeAttribute}="${Report.type.toLowerCase()}"'.`);
|
||||
const scrubbedConfig = { ...config, accessToken: "" };
|
||||
throw new Error(`Attempted to embed using config ${JSON.stringify(scrubbedConfig)} on element ${element.outerHTML}, but could not determine what type of component to embed. You must specify a type in the configuration or as an attribute such as '${Embed.typeAttribute}="${Report.type.toLowerCase()}"'.`);
|
||||
}
|
||||
|
||||
// Saves the type as part of the configuration so that it can be referenced later at a known location.
|
||||
|
@ -405,7 +430,8 @@ export class Service implements IService {
|
|||
private embedExisting(element: IPowerBiElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase, phasedRender?: boolean): Embed {
|
||||
const component = utils.find((x) => x.element === element, this.embeds);
|
||||
if (!component) {
|
||||
throw new Error(`Attempted to embed using config ${JSON.stringify(config)} on element ${element.outerHTML} which already has embedded component associated, but could not find the existing component in the list of active components. This could indicate the embeds list is out of sync with the DOM, or the component is referencing the incorrect HTML element.`);
|
||||
const scrubbedConfig = { ...config, accessToken: "" };
|
||||
throw new Error(`Attempted to embed using config ${JSON.stringify(scrubbedConfig)} on element ${element.outerHTML} which already has embedded component associated, but could not find the existing component in the list of active components. This could indicate the embeds list is out of sync with the DOM, or the component is referencing the incorrect HTML element.`);
|
||||
}
|
||||
|
||||
// TODO: Multiple embedding to the same iframe is not supported in QnA
|
||||
|
@ -433,8 +459,8 @@ export class Service implements IService {
|
|||
|
||||
return report;
|
||||
}
|
||||
|
||||
throw new Error(`Embedding on an existing element with a different type than the previous embed object is not supported. Attempted to embed using config ${JSON.stringify(config)} on element ${element.outerHTML}, but the existing element contains an embed of type: ${this.config.type} which does not match the new type: ${config.type}`);
|
||||
const scrubbedConfig = { ...config, accessToken: "" };
|
||||
throw new Error(`Embedding on an existing element with a different type than the previous embed object is not supported. Attempted to embed using config ${JSON.stringify(scrubbedConfig)} on element ${element.outerHTML}, but the existing element contains an embed of type: ${this.config.type} which does not match the new type: ${config.type}`);
|
||||
}
|
||||
|
||||
component.populateConfig(config, /* isBootstrap */ false);
|
||||
|
@ -443,34 +469,6 @@ export class Service implements IService {
|
|||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
private registerApplicationContextHook(config: IEmbedConfiguration): void {
|
||||
const applicationContextProvider = config?.eventHooks?.applicationContextProvider;
|
||||
if (!applicationContextProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config?.type.toLowerCase() !== "report") {
|
||||
throw new Error("applicationContextProvider is only supported in report embed");
|
||||
}
|
||||
|
||||
if (typeof applicationContextProvider !== 'function') {
|
||||
throw new Error("applicationContextProvider must be a function");
|
||||
}
|
||||
|
||||
this.router.post(`preQuery`, async (req, _res) => {
|
||||
try {
|
||||
const result = await applicationContextProvider(req.body);
|
||||
_res.send(200, result);
|
||||
} catch (error) {
|
||||
_res.send(400, null);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
|
||||
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.
|
||||
|
@ -581,6 +579,21 @@ export class Service implements IService {
|
|||
}
|
||||
}
|
||||
|
||||
private async invokeSDKHook(hook: Function, req: IExtendedRequest, res: IExtendedResponse): Promise<void> {
|
||||
if (!hook) {
|
||||
res.send(404, null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let result = await hook(req.body);
|
||||
res.send(200, result);
|
||||
} catch (error) {
|
||||
res.send(400, null);
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an event object, finds the embed component with the matching type and ID, and invokes its handleEvent method with the event object.
|
||||
*
|
||||
|
|
|
@ -2072,7 +2072,7 @@ describe('SDK-to-HPM', function () {
|
|||
spyHpm.get.and.returnValue(Promise.resolve(testData.response));
|
||||
try {
|
||||
await report.getTheme();
|
||||
expect(spyHpm.put).toHaveBeenCalledWith('/report/theme', expectedHeaders, jasmine.any(Object));
|
||||
expect(spyHpm.get).toHaveBeenCalledWith('/report/theme', expectedHeaders, jasmine.any(Object));
|
||||
} catch (error) {
|
||||
console.log("getTheme failed with", error);
|
||||
fail("getTheme failed");
|
||||
|
|
|
@ -11,7 +11,7 @@ import * as models from 'powerbi-models';
|
|||
import * as factories from '../src/factories';
|
||||
import * as util from '../src/util';
|
||||
import { spyApp, setupEmbedMockApp } from './utility/mockEmbed';
|
||||
import { logMessages, iframeSrc } from './constsants';
|
||||
import { iframeSrc } from './constsants';
|
||||
|
||||
describe('SDK-to-MockApp', function () {
|
||||
let element: HTMLDivElement;
|
||||
|
@ -29,8 +29,7 @@ describe('SDK-to-MockApp', function () {
|
|||
|
||||
beforeEach(async function () {
|
||||
powerbi = new service.Service(factories.hpmFactory, factories.wpmpFactory, factories.routerFactory, {
|
||||
wpmpName: 'SDK-to-MockApp HostWpmp',
|
||||
logMessages
|
||||
wpmpName: 'SDK-to-MockApp HostWpmp'
|
||||
});
|
||||
element = document.createElement('div');
|
||||
element.id = "reportContainer1";
|
||||
|
@ -49,7 +48,7 @@ describe('SDK-to-MockApp', function () {
|
|||
(<any>powerbi.wpmp).eventSourceOverrideWindow = iframe.contentWindow;
|
||||
// Register Iframe side
|
||||
let hpmPostSpy = spyOn(powerbi.hpm, "post").and.returnValue(Promise.resolve(<any>{}));
|
||||
iframeHpm = setupEmbedMockApp(iframe.contentWindow, window, logMessages, 'SDK-to-MockApp IframeWpmp');
|
||||
iframeHpm = setupEmbedMockApp(iframe.contentWindow, window, 'SDK-to-MockApp IframeWpmp');
|
||||
|
||||
await new Promise<void>((resolve, _reject) => {
|
||||
iframe.addEventListener('load', () => {
|
||||
|
@ -542,7 +541,7 @@ describe('SDK-to-MockApp', function () {
|
|||
document.body.appendChild(element2);
|
||||
const report2 = <report.Report>powerbi.embed(element2, embedConfiguration);
|
||||
const iframe2 = element2.getElementsByTagName('iframe')[0];
|
||||
setupEmbedMockApp(iframe2.contentWindow, window, logMessages, 'SDK-to-MockApp IframeWpmp2');
|
||||
setupEmbedMockApp(iframe2.contentWindow, window, 'SDK-to-MockApp IframeWpmp2');
|
||||
await new Promise<void>((resolve, _reject) => {
|
||||
iframe2.addEventListener('load', () => {
|
||||
resolve(null);
|
||||
|
|
|
@ -7,8 +7,6 @@ declare global {
|
|||
}
|
||||
}
|
||||
|
||||
export const logMessages = (window.__karma__.config.args[0] === 'logMessages');
|
||||
|
||||
export const iframeSrc = "base/test/utility/noop.html";
|
||||
window.onbeforeunload = null;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import { WindowPostMessageProxy } from 'window-post-message-proxy';
|
|||
import { HttpPostMessage } from 'http-post-message';
|
||||
import { spyApp, setupEmbedMockApp } from './utility/mockEmbed';
|
||||
import { hpmFactory, routerFactory, wpmpFactory } from '../src/factories';
|
||||
import { iframeSrc, logMessages } from './constsants';
|
||||
import { iframeSrc } from './constsants';
|
||||
import * as models from 'powerbi-models';
|
||||
|
||||
describe('Protocol', function () {
|
||||
|
@ -27,10 +27,10 @@ describe('Protocol', function () {
|
|||
await new Promise(resolve => iframe.addEventListener('load', () => resolve(null)));
|
||||
|
||||
// Register Iframe side
|
||||
iframeHpm = setupEmbedMockApp(iframe.contentWindow, window, logMessages, 'ProtocolMockAppWpmp');
|
||||
iframeHpm = setupEmbedMockApp(iframe.contentWindow, window, 'ProtocolMockAppWpmp');
|
||||
|
||||
// Register SDK side WPMP
|
||||
wpmp = wpmpFactory('HostProxyDefaultNoHandlers', logMessages, iframe.contentWindow);
|
||||
wpmp = wpmpFactory('HostProxyDefaultNoHandlers',false, iframe.contentWindow);
|
||||
hpm = hpmFactory(wpmp, iframe.contentWindow, 'testVersion');
|
||||
|
||||
const router = routerFactory(wpmp);
|
||||
|
|
|
@ -9,7 +9,7 @@ import * as models from 'powerbi-models';
|
|||
|
||||
export const spyApp = mockAppSpyObj;
|
||||
|
||||
export function setupEmbedMockApp(iframeContentWindow: Window, parentWindow: Window, logMessages: boolean, name: string = 'MockAppWindowPostMessageProxy'): HttpPostMessage {
|
||||
export function setupEmbedMockApp(iframeContentWindow: Window, parentWindow: Window, name: string = 'MockAppWindowPostMessageProxy'): HttpPostMessage {
|
||||
const parent = parentWindow || iframeContentWindow.parent;
|
||||
const wpmp = new WindowPostMessageProxy({
|
||||
processTrackingProperties: {
|
||||
|
@ -19,7 +19,6 @@ export function setupEmbedMockApp(iframeContentWindow: Window, parentWindow: Win
|
|||
isErrorMessage: HttpPostMessage.isErrorMessage,
|
||||
receiveWindow: iframeContentWindow,
|
||||
name,
|
||||
logMessages
|
||||
});
|
||||
const hpm = new HttpPostMessage(wpmp, {
|
||||
'origin': 'reportEmbedMock',
|
||||
|
|
Загрузка…
Ссылка в новой задаче