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}
</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>
<!-- Currently open app -->

View File

@ -8,6 +8,7 @@ import styles from "./EgwFramework.styles";
import {egw} from "../../api/js/jsapi/egw_global";
import {SlDropdown, SlTab, SlTabGroup} from "@shoelace-style/shoelace";
import {EgwFrameworkApp} from "./EgwFrameworkApp";
import {until} from "lit/directives/until.js";
/**
* @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.
@ -617,7 +633,7 @@ export class EgwFramework extends LitElement
}
classes[`egw_fw__layout-${this.layout}`] = true;
return html`
return html`${until(this.getEgwComplete().then(() => html`
<div class=${classMap(classes)} part="base">
<div class="egw_fw__banner" part="banner" role="banner">
<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>
</footer>
</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 {et2_IPrint} from "../../api/js/etemplate/et2_core_interfaces";
import {repeat} from "lit/directives/repeat.js";
import {until} from "lit/directives/until.js";
/**
* @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 */
protected useIframe = false;
protected _sideboxData : any;
connectedCallback()
{
@ -161,7 +163,6 @@ export class EgwFrameworkApp extends LitElement
firstUpdated()
{
this.load(this.url);
}
@ -259,7 +260,8 @@ export class EgwFrameworkApp extends LitElement
public setSidebox(sideboxData, hash?)
{
console.log("Not implemented");
this._sideboxData = sideboxData;
this.requestUpdate();
}
public showLeft()
@ -519,36 +521,99 @@ export class EgwFrameworkApp extends LitElement
protected _rightHeaderTemplate()
{
return html`
<sl-button-group>
<et2-button-icon nosubmit name="arrow-clockwise"
label=${this.egw.lang("Reload %1", this.egw.lang(this.name))}
statustext=${this.egw.lang("Reload %1", this.egw.lang(this.name))}
@click=${(e) =>
{
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")}
statustext=${this.egw.lang("Print")}
@click=${(e) => this.framework.print()}
></et2-button-icon>
${this.egw.user('apps')['waffles'] !== "undefined" ? html`
<et2-button-icon nosubmit name="gear-wide"
label=${this.egw.lang("Site configuration for %1", this.egw.lang(this.name))}
statustext=${this.egw.lang("App configuration")}
@click=${(e) =>
{
// @ts-ignore
egw_link_handler(`/egroupware/index.php?menuaction=admin.admin_ui.index&load=admin.uiconfig.index&appname=${this.name}&ajax=true`, 'admin');
}}
></et2-button-icon>` : nothing
}
</sl-button-group>
<sl-tooltip content=${this.egw.lang("Application menu")}>
<sl-dropdown>
<sl-icon slot="trigger" name="three-dots-vertical"></sl-icon>
<sl-menu>
<sl-menu-item
@click=${(e) =>
{
this.egw.refresh("", this.name);
/* Could also be this.load(false); this.load(this.url) */
}}
>
<sl-icon slot="prefix" name="arrow-clockwise"></sl-icon>
${this.egw.lang("Reload %1", this.egw.lang(this.name))}
</sl-menu-item>
<sl-menu-item
@click=${(e) => this.framework.print()}
>
<sl-icon slot="prefix" name="printer"></sl-icon>
${this.egw.lang("Print")}
</sl-menu-item>
${this.egw.user('apps')['admin'] !== undefined ? html`
<sl-menu-item
@click=${(e) =>
{
// @ts-ignore
egw_link_handler(`/egroupware/index.php?menuaction=admin.admin_ui.index&load=admin.uiconfig.index&appname=${this.name}&ajax=true`, 'admin');
}}
>
<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()
{
const hasLeftSlots = this.hasSideContent("left");
@ -579,7 +644,8 @@ export class EgwFrameworkApp extends LitElement
<header class="egw_fw_app__header" part="header">
<slot name="main-header"><span class="placeholder"> ${this.name} main-header</span></slot>
</header>
${this._rightHeaderTemplate()}
${until(this.framework.getEgwComplete().then(() => this._rightHeaderTemplate()), html`
<sl-spinner></sl-spinner>`)}
</div>
<div class="egw_fw_app__main" part="main">
<sl-split-panel class=${classMap({"egw_fw_app__outerSplit": true, "no-content": !hasLeftSlots})}