import {css, html, LitElement} from "lit"; import {customElement} from "lit/decorators/custom-element.js"; import {property} from "lit/decorators/property.js"; import {classMap} from "lit/directives/class-map.js"; import "@shoelace-style/shoelace/dist/components/split-panel/split-panel.js"; import styles from "./EgwFramework.styles"; import {repeat} from "lit/directives/repeat.js"; /** * @summary Accessable, webComponent-based EGroupware framework * * @dependency sl-dropdown * @dependency sl-icon-button * * @slot - Current application * @slot banner - Very top, used for things like persistant, system wide messages. Normally hidden. * @slot header - Top of page, contains logo, app icons. * @slot header-right - Top right, contains user info / actions. * @slot status - Home of the status app, it is limited in size and can be resized and hidden. * @slot footer - Very bottom. Normally hidden. * * * @csspart base - Wraps it all. * @csspart banner - * @csspart header - * @csspart open-applications - Tab group that has the currently open applications * @csspart status-split - Status splitter * @csspart main * @csspart status * @csspart footer * * @cssproperty [--icon-size=32] - Height of icons used in the framework */ @customElement('egw-framework') //@ts-ignore export class EgwFramework extends LitElement { static get styles() { return [ styles, // TEMP STUFF css` :host .placeholder { display: none; } :host(.placeholder) .placeholder { width: 100%; display: block; font-size: 200%; text-align: center; background-color: var(--placeholder-background-color, silver); } .placeholder:after { content: " (placeholder)"; } .egw_fw__base { --placeholder-background-color: #75bd20; } .egw_fw__status .placeholder { writing-mode: vertical-rl; text-orientation: mixed; height: 100%; } :host(.placeholder) [class*="left"] .placeholder { background-color: color-mix(in lch, var(--placeholder-background-color), rgba(.5, .5, 1, .5)); } :host(.placeholder) [class*="right"] .placeholder { background-color: color-mix(in lch, var(--placeholder-background-color), rgba(.5, 1, .5, .5)); } :host(.placeholder) [class*="footer"] .placeholder { background-color: color-mix(in lch, var(--placeholder-background-color), rgba(1, 1, 1, .05)); } ::slotted(div#egw_fw_sidebar_r) { position: relative; } ` ]; } @property() layout = "default"; @property({type: Array, attribute: "application-list"}) applicationList = []; get egw() { return window.egw ?? { app_name: () => "", lang: (t) => t, preference: (n, app) => "" }; } /** * An application tab is chosen, show the app * * @param e * @protected */ protected handleApplicationTabShow(e) { } /** * Renders one application into the 9-dots application menu * * @param app * @returns {TemplateResult<1>} * @protected */ protected _applicationListAppTemplate(app) { return html` `; } protected _applicationTabTemplate(app) { return html` `; } render() { const iconSize = getComputedStyle(this).getPropertyValue("--icon-size"); const statusPosition = this.egw?.preference("statusPosition", "common") ?? parseInt(iconSize) ?? "36"; const classes = { "egw_fw__base": true } classes[`egw_fw__layout-${this.layout}`] = true; return html`
${repeat(this.applicationList, (app) => this._applicationListAppTemplate(app))} ${repeat(this.applicationList.filter(app => app.opened), (app) => this._applicationTabTemplate(app))} header header-right
`; } }