From 2dba426ae6d98ad4d4f16c6d1a4fd3ef45183633 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 9 May 2024 13:10:30 -0600 Subject: [PATCH] Framework WIP: - Fix some size / scroll issues with aside content - Side content split improvements --- kdots/inc/class.kdots_framework.inc.php | 15 ++++++---- kdots/js/EgwFramework.styles.ts | 3 ++ kdots/js/EgwFrameworkApp.styles.ts | 17 ++++++++---- kdots/js/EgwFrameworkApp.ts | 37 +++++++++++++++++++------ 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/kdots/inc/class.kdots_framework.inc.php b/kdots/inc/class.kdots_framework.inc.php index fa7fa73d7e..241675ec28 100644 --- a/kdots/inc/class.kdots_framework.inc.php +++ b/kdots/inc/class.kdots_framework.inc.php @@ -28,13 +28,16 @@ class kdots_framework extends Api\Framework\Ajax protected function _get_header(array $extra = array()) { $data = parent::_get_header($extra); - $data['application-list'] = htmlentities(json_encode($extra['navbar-apps'], JSON_HEX_QUOT | JSON_HEX_AMP), ENT_QUOTES, 'UTF-8'); - $open_app = current(array_filter($extra['navbar-apps'], function ($app) + if($extra['navbar-apps']) { - return $app['active'] ?? false; - })) ?? []; - $data['open_app_name'] = $open_app['name']; - $data['open_app_url'] = $open_app['url']; + $data['application-list'] = htmlentities(json_encode($extra['navbar-apps'], JSON_HEX_QUOT | JSON_HEX_AMP), ENT_QUOTES, 'UTF-8'); + $open_app = current(array_filter($extra['navbar-apps'], function ($app) + { + return $app['active'] ?? false; + })) ?? []; + $data['open_app_name'] = $open_app['name']; + $data['open_app_url'] = $open_app['url']; + } return $data; } diff --git a/kdots/js/EgwFramework.styles.ts b/kdots/js/EgwFramework.styles.ts index 67371a7892..9d8676fc7d 100644 --- a/kdots/js/EgwFramework.styles.ts +++ b/kdots/js/EgwFramework.styles.ts @@ -73,6 +73,9 @@ export default css` @media (min-width: 600px) { + .egw_fw__main { + overflow: hidden; + } .egw_fw__layout-default { grid-template-columns: [start banner-start header-start footer-start main-start] 1fr [main-end header-end banner-end end]; grid-template-rows: [top banner] fit-content(2em) [header] fit-content(2em) [main-header] fit-content(2em) [main] 1fr [footer bottom] fit-content(2em); diff --git a/kdots/js/EgwFrameworkApp.styles.ts b/kdots/js/EgwFrameworkApp.styles.ts index 6b3385442f..17af33f5cd 100644 --- a/kdots/js/EgwFrameworkApp.styles.ts +++ b/kdots/js/EgwFrameworkApp.styles.ts @@ -11,6 +11,8 @@ export default css` display: flex; flex-direction: column; + + --application-color: var(--primary-background-color); } :host > * { @@ -63,7 +65,7 @@ export default css` sl-split-panel > sl-icon { position: absolute; border-radius: var(--sl-border-radius-small); - background-color: var(--primary-background-color); + background-color: var(--application-color); color: var(--sl-color-neutral-0); padding: 0.5rem 0.125rem; z-index: var(--sl-z-index-drawer); @@ -122,10 +124,6 @@ export default css` overflow: hidden; } - .egw_fw_app { - --application-color: var(--primary-background-color); - } - .egw_fw_app__loading { text-align: center; @@ -142,6 +140,15 @@ export default css` grid-template-rows: [start sub-header] fit-content(2em) [main] auto [footer] fit-content(2em) [end]; } + .egw_fw_app__aside { + overflow-y: hidden; + } + + .egw_fw_app__aside_content { + overflow-x: hidden; + overflow-y: auto; + } + ::slotted(*) { height: 100%; } diff --git a/kdots/js/EgwFrameworkApp.ts b/kdots/js/EgwFrameworkApp.ts index 12fa7e72d2..5cc3a071d1 100644 --- a/kdots/js/EgwFrameworkApp.ts +++ b/kdots/js/EgwFrameworkApp.ts @@ -36,6 +36,7 @@ import type {EgwFramework} from "./EgwFramework"; * @csspart right - Right optional content. * @csspart footer - Very bottom of the main content. * + * @cssproperty [--application-color=--primary-background-color] - Color to use for this application * @cssproperty [--left-min=0] - Minimum width of the left content * @cssproperty [--left-max=20%] - Maximum width of the left content * @cssproperty [--right-min=0] - Minimum width of the right content @@ -133,11 +134,11 @@ export class EgwFrameworkApp extends LitElement super.connectedCallback(); (>this.egw.preference(this.leftPanelInfo.preference, this.name, true)).then((width) => { - this.leftPanelInfo.preferenceWidth = parseInt(width) ?? this.leftPanelInfo.defaultWidth; + this.leftPanelInfo.preferenceWidth = typeof width !== "undefined" ? parseInt(width) : this.leftPanelInfo.defaultWidth; }); (>this.egw.preference(this.rightPanelInfo.preference, this.name, true)).then((width) => { - this.rightPanelInfo.preferenceWidth = parseInt(width) ?? this.rightPanelInfo.defaultWidth; + this.rightPanelInfo.preferenceWidth = typeof width !== "undefined" ? parseInt(width) : this.rightPanelInfo.defaultWidth; }); } @@ -187,6 +188,10 @@ export class EgwFrameworkApp extends LitElement { // Load request returns HTML. Shove it in. render(html`${unsafeHTML(data.join(""))}`, this); + + // Might have just slotted aside content, hasSlotController will requestUpdate() + // but we need to do it anyway + this.requestUpdate(); }); } @@ -220,8 +225,10 @@ export class EgwFrameworkApp extends LitElement protected hideSide(side : "left" | "right") { const attribute = `${side}Collapsed`; + const oldValue = this[attribute]; this[attribute] = true; this[`${side}Splitter`].position = this[`${side}PanelInfo`].hiddenWidth; + this.requestUpdate(attribute, oldValue); } get egw() @@ -234,6 +241,12 @@ export class EgwFrameworkApp extends LitElement return this.closest("egw-framework"); } + private hasSideContent(side : "left" | "right") + { + return this.hasSlotController.test(`${side}-header`) || + this.hasSlotController.test(side) || this.hasSlotController.test(`${side}-footer`); + } + /** * User adjusted side slider, update preference * @@ -242,15 +255,23 @@ export class EgwFrameworkApp extends LitElement */ protected async handleSlide(event) { + // Skip if there's no panelInfo - event is from the wrong place if(typeof event.target?.panelInfo != "object") { return; } + + // Skip if there's no side-content + if(!this.hasSideContent(event.target.panelInfo.side)) + { + return; + } + // Left side is in pixels, round to 2 decimals let newPosition = Math.round(event.target.panelInfo.side == "left" ? event.target.positionInPixels * 100 : event.target.position * 100) / 100; // Update collapsed - this[`${event.target.panelInfo.name}Collapsed`] = newPosition == event.target.panelInfo.hiddenWidth; + this[`${event.target.panelInfo.side}Collapsed`] = newPosition == event.target.panelInfo.hiddenWidth; let preferenceName = event.target.panelInfo.preference; if(newPosition != event.target.panelInfo.preferenceWidth) @@ -305,8 +326,8 @@ export class EgwFrameworkApp extends LitElement render() { - const hasLeftSlots = this.hasSlotController.test('left-header') || this.hasSlotController.test('left') || this.hasSlotController.test('left-footer'); - const hasRightSlots = this.hasSlotController.test('right-header') || this.hasSlotController.test('right') || this.hasSlotController.test('right-footer'); + const hasLeftSlots = this.hasSideContent("left"); + const hasRightSlots = this.hasSideContent("right"); const leftWidth = this.leftCollapsed || !hasLeftSlots ? this.leftPanelInfo.hiddenWidth : this.leftPanelInfo.preferenceWidth; @@ -351,8 +372,7 @@ export class EgwFrameworkApp extends LitElement > { - this.leftCollapsed = !this.leftCollapsed; - this.requestUpdate(); + this.hideLeft(); }}> ${this._asideTemplate("start", "left")} { - this.rightCollapsed = !this.rightCollapsed; - this.requestUpdate(); + this.hideRight(); }}>
header