diff --git a/edge-apps/powerbi/screenly.yml b/edge-apps/powerbi/screenly.yml index a7f64c284..49400d2e8 100644 --- a/edge-apps/powerbi/screenly.yml +++ b/edge-apps/powerbi/screenly.yml @@ -36,3 +36,14 @@ settings: help_text: The URL of the Power BI dashboard or report to display. type: oauth:power_bi:embed_url schema_version: 1 +app_refresh_interval: + type: string + title: App Refresh Interval (minutes) + optional: true + default_value: '30' + help_text: + properties: + advanced: true + help_text: How often to refresh the Power BI report/dashboard (in minutes). Default is 30 minutes. Minimum is 1 minute. + type: number + schema_version: 1 diff --git a/edge-apps/powerbi/screenly_qc.yml b/edge-apps/powerbi/screenly_qc.yml index f5470a997..ebe628034 100644 --- a/edge-apps/powerbi/screenly_qc.yml +++ b/edge-apps/powerbi/screenly_qc.yml @@ -36,3 +36,14 @@ settings: help_text: The URL of the Power BI dashboard or report to display. type: oauth:power_bi:embed_url schema_version: 1 +app_refresh_interval: + type: string + title: App Refresh Interval (minutes) + optional: true + default_value: '30' + help_text: + properties: + advanced: true + help_text: How often to refresh the Power BI report/dashboard (in minutes). Default is 30 minutes. Minimum is 1 minute. + type: number + schema_version: 1 diff --git a/edge-apps/powerbi/static/js/main.js b/edge-apps/powerbi/static/js/main.js index e697706ca..075243a57 100644 --- a/edge-apps/powerbi/static/js/main.js +++ b/edge-apps/powerbi/static/js/main.js @@ -1,14 +1,23 @@ /* global screenly, panic */ (function () { - const DEFAULT_TOKEN_REFRESH_SEC = 30 * 60; // refresh token every 30 minutes + const MIN_TOKEN_REFRESH_MIN = 1; + const DEFAULT_TOKEN_REFRESH_MIN = 30; + + function getTokenRefreshInterval() { + var intervalMinutes = parseInt(screenly.settings.app_refresh_interval, 10); + if (isNaN(intervalMinutes) || intervalMinutes < MIN_TOKEN_REFRESH_MIN) { + return DEFAULT_TOKEN_REFRESH_MIN * 60; + } + return intervalMinutes * 60; + } function getEmbedTypeFromUrl(url) { switch (true) { - case url.indexOf('/dashboard') !== -1: - return 'dashboard'; + case url.indexOf("/dashboard") !== -1: + return "dashboard"; default: - return 'report'; + return "report"; } } @@ -17,13 +26,16 @@ return screenly.settings.embed_token; } - var response = await fetch(screenly.settings.screenly_oauth_tokens_url + 'embed_token/', { - method: 'GET', - headers: { - Accept: 'application/json', - Authorization: `Bearer ${screenly.settings.screenly_app_auth_token}`, + var response = await fetch( + screenly.settings.screenly_oauth_tokens_url + "embed_token/", + { + method: "GET", + headers: { + Accept: "application/json", + Authorization: `Bearer ${screenly.settings.screenly_app_auth_token}`, + }, }, - }); + ); const { token } = await response.json(); return token; @@ -33,15 +45,19 @@ var currentErrorStep = 0; var initErrorDelaySec = 15; var maxErrorStep = 7; + var tokenRefreshInterval = getTokenRefreshInterval(); async function run() { - var nextTimeout = DEFAULT_TOKEN_REFRESH_SEC; + var nextTimeout = tokenRefreshInterval; try { var newToken = await getEmbedToken(); await report.setAccessToken(newToken); currentErrorStep = 0; } catch { - nextTimeout = Math.min(initErrorDelaySec * Math.pow(2, currentErrorStep), nextTimeout); + nextTimeout = Math.min( + initErrorDelaySec * Math.pow(2, currentErrorStep), + nextTimeout, + ); if (currentErrorStep >= maxErrorStep) { return; } @@ -50,30 +66,33 @@ setTimeout(run, nextTimeout * 1000); } - setTimeout(run, DEFAULT_TOKEN_REFRESH_SEC * 1000); + setTimeout(run, tokenRefreshInterval * 1000); } async function initializePowerBI() { - const models = window['powerbi-client'].models; + const models = window["powerbi-client"].models; const embedUrl = screenly.settings.embed_url; const resourceType = getEmbedTypeFromUrl(embedUrl); - const report = window.powerbi.embed(document.getElementById('embed-container'), { - embedUrl: embedUrl, - accessToken: await getEmbedToken(), - type: resourceType, - tokenType: models.TokenType.Embed, - permissions: models.Permissions.All, - settings: { - filterPaneEnabled: false, - navContentPaneEnabled: false, + const report = window.powerbi.embed( + document.getElementById("embed-container"), + { + embedUrl: embedUrl, + accessToken: await getEmbedToken(), + type: resourceType, + tokenType: models.TokenType.Embed, + permissions: models.Permissions.All, + settings: { + filterPaneEnabled: false, + navContentPaneEnabled: false, + }, }, - }); + ); - if (resourceType === 'report') { - report.on('rendered', screenly.signalReadyForRendering); - } else if (resourceType === 'dashboard') { - report.on('loaded', () => { + if (resourceType === "report") { + report.on("rendered", screenly.signalReadyForRendering); + } else if (resourceType === "dashboard") { + report.on("loaded", () => { setTimeout(screenly.signalReadyForRendering, 1000); }); } @@ -81,14 +100,19 @@ if (!screenly.settings.embed_token) { initTokenRefreshLoop(report); } + + return report; } panic.configure({ - handleErrors: screenly.settings.display_errors == 'true' || false, + handleErrors: screenly.settings.display_errors == "true" || false, }); - if (screenly.settings.display_errors == 'true') { - window.addEventListener('error', screenly.signalReadyForRendering); - window.addEventListener('unhandledrejection', screenly.signalReadyForRendering); + if (screenly.settings.display_errors == "true") { + window.addEventListener("error", screenly.signalReadyForRendering); + window.addEventListener( + "unhandledrejection", + screenly.signalReadyForRendering, + ); } initializePowerBI();