import "@polymer/iron-collapse/iron-collapse.js"; import "@polymer/iron-flex-layout/iron-flex-layout.js"; import "@polymer/iron-localstorage/iron-localstorage.js"; import "@polymer/paper-styles/element-styles/paper-material-styles.js"; import "@polymer/paper-styles/typography.js"; import { initialize } from "@open-iframe-resizer/core"; import * as Polymer from "@polymer/polymer"; import { afterNextRender } from "@polymer/polymer/lib/utils/render-status.js"; const HEX_PARSE_SHORTHAND_REGEX = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; const HEX_PARSE_REGEX = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i; export class NcgDashboardPanel extends Polymer.PolymerElement { static get template() { return Polymer.html`
`; } static get is() { return "ncg-dashboard-panel"; } static get properties() { return { displayTitle: { type: String, reflectToAttribute: true, }, bundle: { type: String, reflectToAttribute: true, }, panel: { type: String, reflectToAttribute: true, }, opened: { type: Boolean, reflectToAttribute: true, observer: "_openedChanged", }, headerColor: { type: String, reflectToAttribute: true, observer: "_headerColorChanged", }, width: { type: Number, reflectToAttribute: true, }, transitioning: { type: Boolean, notify: true, }, fullbleed: { type: Boolean, reflectToAttribute: true, }, }; } override ready(): void { super.ready(); afterNextRender(this, async () => { const distributedNodes: HTMLElement[] = this.$.slot.assignedNodes({ flatten: true, }); const iframe = distributedNodes.find( (el) => el.tagName === "IFRAME", ) as HTMLIFrameElement; // If Sentry is enabled, use it to report errors in panels to Sentry.io. if (window.ncgConfig.sentry.enabled) { const Sentry = await import("@sentry/browser"); iframe.contentWindow!.addEventListener("error", (event) => { Sentry.captureException(event.error); }); iframe.contentWindow!.addEventListener("unhandledrejection", (err) => { Sentry.captureException(err.reason); }); } if (!this.fullbleed) { if (iframe.contentWindow!.document.readyState === "complete") { this._attachIframeResize(iframe); } else { iframe.addEventListener("load", () => { this._attachIframeResize(iframe); }); } } }); } _attachIframeResize(iframe: HTMLIFrameElement) { initialize( { onIframeResize: (context) => { this.$.collapse.updateSize("auto", false); context.iframe.dispatchEvent(new CustomEvent("iframe-resized")); }, }, iframe, ); } override connectedCallback(): void { super.connectedCallback(); const { src } = this.querySelector("iframe")!; this.standaloneUrl = `${src}?standalone=true`; } toggleCollapse() { this.$.collapse.toggle(); } initializeDefaultOpened() { this.opened = true; } _openedChanged(newVal: boolean) { this.$.expandBtn.icon = newVal ? "unfold-less" : "unfold-more"; } _headerColorChanged(newVal: string) { this.$.header.style.backgroundColor = newVal; this.$.buttons.style.background = this._calcLinearGradient( this._hexToRGB(newVal)!, ); } computeLocalStorageName(bundle: string, panel: string) { return [bundle, panel, "opened"].join("."); } _calcLinearGradient(rgb: { r: number; g: number; b: number }) { const rgbStr = `${rgb.r}, ${rgb.g}, ${rgb.b}`; return `linear-gradient(to right, rgba(${rgbStr}, 0) 0px,rgba(${rgbStr}, 1) 10px)`; } /* istanbul ignore next: tseems to confuse coverage */ _hexToRGB(hex: string) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") hex = hex.replace( HEX_PARSE_SHORTHAND_REGEX, (_m, r, g, b) => r + r + g + g + b + b, ); const result = HEX_PARSE_REGEX.exec(hex); return result ? { r: parseInt(result[1]!, 16), g: parseInt(result[2]!, 16), b: parseInt(result[3]!, 16), } : null; } } customElements.define("ncg-dashboard-panel", NcgDashboardPanel);