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);