Framework WIP:

- Wait some stuff until egw is loaded
- Put old sidebox into 3 dots menu
This commit is contained in:
nathan 2024-05-30 15:19:21 -06:00
parent 9076110345
commit 1fb0df009b
3 changed files with 116 additions and 33 deletions

View File

@ -42,7 +42,7 @@
{topmenu_info_items} {topmenu_info_items}
</div> </div>
<!-- status app is looking for this --> <!-- status app is looking for this, but it could slot itself -->
<div slot="status" id="egw_fw_sidebar_r"></div> <div slot="status" id="egw_fw_sidebar_r"></div>
<!-- Currently open app --> <!-- Currently open app -->

View File

@ -8,6 +8,7 @@ import styles from "./EgwFramework.styles";
import {egw} from "../../api/js/jsapi/egw_global"; import {egw} from "../../api/js/jsapi/egw_global";
import {SlDropdown, SlTab, SlTabGroup} from "@shoelace-style/shoelace"; import {SlDropdown, SlTab, SlTabGroup} from "@shoelace-style/shoelace";
import {EgwFrameworkApp} from "./EgwFrameworkApp"; import {EgwFrameworkApp} from "./EgwFrameworkApp";
import {until} from "lit/directives/until.js";
/** /**
* @summary Accessable, webComponent-based EGroupware framework * @summary Accessable, webComponent-based EGroupware framework
@ -160,6 +161,21 @@ export class EgwFramework extends LitElement
}; };
} }
/**
* A promise for if egw is loaded
*
* @returns {Promise<void>}
*/
getEgwComplete()
{
let egwLoading = Promise.resolve();
if(typeof this.egw.window['egw_ready'] !== "undefined")
{
egwLoading = this.egw.window['egw_ready'];
}
return egwLoading;
}
/** /**
* *
* @param _function Framework function to be called on the server. * @param _function Framework function to be called on the server.
@ -617,7 +633,7 @@ export class EgwFramework extends LitElement
} }
classes[`egw_fw__layout-${this.layout}`] = true; classes[`egw_fw__layout-${this.layout}`] = true;
return html` return html`${until(this.getEgwComplete().then(() => html`
<div class=${classMap(classes)} part="base"> <div class=${classMap(classes)} part="base">
<div class="egw_fw__banner" part="banner" role="banner"> <div class="egw_fw__banner" part="banner" role="banner">
<slot name="banner"><span class="placeholder">Banner</span></slot> <slot name="banner"><span class="placeholder">Banner</span></slot>
@ -661,7 +677,8 @@ export class EgwFramework extends LitElement
<slot name="footer"><span class="placeholder">footer</span></slot> <slot name="footer"><span class="placeholder">footer</span></slot>
</footer> </footer>
</div> </div>
`; `), html`<span>Waiting for egw...</span>
<slot></slot>`)}`;
} }
} }

View File

@ -12,6 +12,7 @@ import type {EgwFramework} from "./EgwFramework";
import {etemplate2} from "../../api/js/etemplate/etemplate2"; import {etemplate2} from "../../api/js/etemplate/etemplate2";
import {et2_IPrint} from "../../api/js/etemplate/et2_core_interfaces"; import {et2_IPrint} from "../../api/js/etemplate/et2_core_interfaces";
import {repeat} from "lit/directives/repeat.js"; import {repeat} from "lit/directives/repeat.js";
import {until} from "lit/directives/until.js";
/** /**
* @summary Application component inside EgwFramework * @summary Application component inside EgwFramework
@ -137,6 +138,7 @@ export class EgwFrameworkApp extends LitElement
/** The application's content must be in an iframe instead of handled normally */ /** The application's content must be in an iframe instead of handled normally */
protected useIframe = false; protected useIframe = false;
protected _sideboxData : any;
connectedCallback() connectedCallback()
{ {
@ -161,7 +163,6 @@ export class EgwFrameworkApp extends LitElement
firstUpdated() firstUpdated()
{ {
this.load(this.url); this.load(this.url);
} }
@ -259,7 +260,8 @@ export class EgwFrameworkApp extends LitElement
public setSidebox(sideboxData, hash?) public setSidebox(sideboxData, hash?)
{ {
console.log("Not implemented"); this._sideboxData = sideboxData;
this.requestUpdate();
} }
public showLeft() public showLeft()
@ -519,36 +521,99 @@ export class EgwFrameworkApp extends LitElement
protected _rightHeaderTemplate() protected _rightHeaderTemplate()
{ {
return html` return html`
<sl-button-group> <sl-tooltip content=${this.egw.lang("Application menu")}>
<et2-button-icon nosubmit name="arrow-clockwise" <sl-dropdown>
label=${this.egw.lang("Reload %1", this.egw.lang(this.name))} <sl-icon slot="trigger" name="three-dots-vertical"></sl-icon>
statustext=${this.egw.lang("Reload %1", this.egw.lang(this.name))} <sl-menu>
@click=${(e) => <sl-menu-item
{ @click=${(e) =>
this.egw.refresh("", this.name); {
/* Could also be this.load(false); this.load(this.url) */ this.egw.refresh("", this.name);
}} /* Could also be this.load(false); this.load(this.url) */
></et2-button-icon> }}
<et2-button-icon nosubmit name="printer" >
label=${this.egw.lang("Print")} <sl-icon slot="prefix" name="arrow-clockwise"></sl-icon>
statustext=${this.egw.lang("Print")} ${this.egw.lang("Reload %1", this.egw.lang(this.name))}
@click=${(e) => this.framework.print()} </sl-menu-item>
></et2-button-icon> <sl-menu-item
${this.egw.user('apps')['waffles'] !== "undefined" ? html` @click=${(e) => this.framework.print()}
<et2-button-icon nosubmit name="gear-wide" >
label=${this.egw.lang("Site configuration for %1", this.egw.lang(this.name))} <sl-icon slot="prefix" name="printer"></sl-icon>
statustext=${this.egw.lang("App configuration")} ${this.egw.lang("Print")}
@click=${(e) => </sl-menu-item>
{ ${this.egw.user('apps')['admin'] !== undefined ? html`
// @ts-ignore <sl-menu-item
egw_link_handler(`/egroupware/index.php?menuaction=admin.admin_ui.index&load=admin.uiconfig.index&appname=${this.name}&ajax=true`, 'admin'); @click=${(e) =>
}} {
></et2-button-icon>` : nothing // @ts-ignore
} egw_link_handler(`/egroupware/index.php?menuaction=admin.admin_ui.index&load=admin.uiconfig.index&appname=${this.name}&ajax=true`, 'admin');
</sl-button-group> }}
>
<sl-icon slot="prefix" name="gear-wide"></sl-icon>
${this.egw.lang("App configuration")}
</sl-menu-item>
<sl-divider></sl-divider>
` : nothing}
${this._sideboxMenuTemplate()}
</sl-menu>
</sl-dropdown>
</sl-tooltip>
`; `;
} }
protected _sideboxMenuTemplate()
{
if(!this._sideboxData)
{
return nothing;
}
return html`${repeat(this._sideboxData, (menu) => menu['menu_name'], (menu) =>
{
// No favorites here
if(menu["title"] == "Favorites" || menu["title"] == this.egw.lang("favorites"))
{
return nothing;
}
// Just one thing, don't bother with submenu
if(menu["entries"].length == 1)
{
return html`
<sl-menu-item
@click=${() => this.egw.open_link(menu["entries"][0]["item_link"])}
>
${menu["title"]}
</sl-menu-item>`;
}
return html`
<sl-menu-item>
${menu["title"]}
<sl-menu slot="submenu">
${repeat(menu["entries"], (entry) =>
{
return this._sideboxMenuItemTemplate(entry);
})}
</sl-menu>
</sl-menu-item>`;
})}`;
}
_sideboxMenuItemTemplate(item)
{
if(item["lang_item"] == "<hr />")
{
return html`
<sl-divider></sl-divider>`;
}
return html`
<sl-menu-item
@click=${() => this.egw.open_link(item["item_link"])}
>
${item["lang_item"]}
</sl-menu-item>`;
}
render() render()
{ {
const hasLeftSlots = this.hasSideContent("left"); const hasLeftSlots = this.hasSideContent("left");
@ -579,7 +644,8 @@ export class EgwFrameworkApp extends LitElement
<header class="egw_fw_app__header" part="header"> <header class="egw_fw_app__header" part="header">
<slot name="main-header"><span class="placeholder"> ${this.name} main-header</span></slot> <slot name="main-header"><span class="placeholder"> ${this.name} main-header</span></slot>
</header> </header>
${this._rightHeaderTemplate()} ${until(this.framework.getEgwComplete().then(() => this._rightHeaderTemplate()), html`
<sl-spinner></sl-spinner>`)}
</div> </div>
<div class="egw_fw_app__main" part="main"> <div class="egw_fw_app__main" part="main">
<sl-split-panel class=${classMap({"egw_fw_app__outerSplit": true, "no-content": !hasLeftSlots})} <sl-split-panel class=${classMap({"egw_fw_app__outerSplit": true, "no-content": !hasLeftSlots})}