From d9e12ecf4ae4cf2c58409226dc258fde30997260 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 7 Mar 2023 16:02:29 -0700 Subject: [PATCH] Home WIP: Better re-layout calcs, use correct portlet type (if possible) when adding --- api/js/etemplate/Et2Portlet/Et2Portlet.ts | 11 +++-- home/inc/class.home_ui.inc.php | 6 +-- home/js/app.ts | 51 ++++++++++++++--------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/api/js/etemplate/Et2Portlet/Et2Portlet.ts b/api/js/etemplate/Et2Portlet/Et2Portlet.ts index a79422769b..7b80c5b593 100644 --- a/api/js/etemplate/Et2Portlet/Et2Portlet.ts +++ b/api/js/etemplate/Et2Portlet/Et2Portlet.ts @@ -151,6 +151,9 @@ export class Et2Portlet extends Et2Widget(SlCard) } }; + protected static DEFAULT_WIDTH = 2; + protected static DEFAULT_HEIGHT = 2; + constructor() { super(); @@ -178,18 +181,18 @@ export class Et2Portlet extends Et2Widget(SlCard) transformAttributes(attrs) { super.transformAttributes(attrs); - let data = this.getArrayMgr("content").data.find(e => e.id && e.id == this.id); + let data = this.getArrayMgr("content").data.find(e => e.id && e.id == this.id) || {}; this.settings = typeof attrs.settings == "string" ? data.value || data.settings || {} : attrs.settings; // Set size & position, if available // NB: initial load can't find them by entry in array mgr, we check the data directly if(attrs.row || attrs.height || data.row || data.height) { - this.style.gridRow = (attrs.row || data.row || "auto") + " / span " + (attrs.height || data.height || 1); + this.style.gridRow = (attrs.row || data.row || "auto") + " / span " + (attrs.height || data.height || this.constructor.DEFAULT_HEIGHT); } if(attrs.col || attrs.width || data.col || data.width) { - this.style.gridColumn = (attrs.col || data.col || "auto") + " / span " + (attrs.width || data.width || 1); + this.style.gridColumn = (attrs.col || data.col || "auto") + " / span " + (attrs.width || data.width || this.constructor.DEFAULT_WIDTH); } } @@ -349,7 +352,7 @@ export class Et2Portlet extends Et2Widget(SlCard) this.update_settings({row: row, col: col, width: width, height: height}); // If there's a full etemplate living inside, make it resize - etemplate2.getById(this.id).resize(); + etemplate2.getById(this.id)?.resize(); } diff --git a/home/inc/class.home_ui.inc.php b/home/inc/class.home_ui.inc.php index d213647bde..25fff13d95 100644 --- a/home/inc/class.home_ui.inc.php +++ b/home/inc/class.home_ui.inc.php @@ -259,10 +259,10 @@ class home_ui } $attributes = array( - 'title' => $desc['title'], - 'color' => $settings['color'], + 'title' => $desc['title'], + 'color' => $settings['color'] ?: "", 'settings' => $settings, - 'actions' => $portlet->get_actions(), + 'actions' => $portlet->get_actions(), ); // Add in default settings self::create_default_actions($attributes['actions'], $id); diff --git a/home/js/app.ts b/home/js/app.ts index bf121f7c16..0324a9a59b 100644 --- a/home/js/app.ts +++ b/home/js/app.ts @@ -36,14 +36,6 @@ export class HomeApp extends EgwApp */ public static GRID = 150; - /** - * Default size for new portlets - */ - public static DEFAULT = { - WIDTH: 4, - HEIGHT: 1 - }; - // List of portlets private portlets = {}; portlet_container : any; @@ -248,10 +240,8 @@ export class HomeApp extends EgwApp { // Basic portlet attributes let attrs = { - ...HomeApp.DEFAULT, ...{ id: this._create_id(), class: action.data.class - } }; // Try to put it about where the menu was opened @@ -263,7 +253,7 @@ export class HomeApp extends EgwApp attrs.col = "auto"; } - let portlet = loadWebComponent('et2-portlet', attrs, this.portlet_container); + let portlet = loadWebComponent(this.get_portlet_tag(action), attrs, this.portlet_container); portlet.loadingFinished(); // Get actual attributes & settings, since they're not available client side yet @@ -289,7 +279,6 @@ export class HomeApp extends EgwApp // Basic portlet attributes let attrs = { - ...HomeApp.DEFAULT, id: this._create_id(), class: action.data.class || action.id.substr(5), dropped_data: [] @@ -316,7 +305,7 @@ export class HomeApp extends EgwApp } } - let portlet = loadWebComponent('et2-portlet', attrs, this.portlet_container); + let portlet = loadWebComponent(this.get_portlet_tag(action), attrs, this.portlet_container); portlet.loadingFinished(); // Get actual attributes & settings, since they're not available client side yet @@ -405,6 +394,22 @@ export class HomeApp extends EgwApp } } + /** + * Determine the correct portlet type to use for the given action + * + * @param {egwAction} action + */ + get_portlet_tag(action : egwAction) : string + { + // Try to turn action ID into tag (eg: home_list_portlet -> et2-portlet-list) + let tag = "et2-" + action.id.replace("add_", "").split("_").reverse().slice(0, -1).map(i => i.toLowerCase()).join("-"); + if(typeof customElements.get(tag) != "undefined") + { + return tag; + } + return "et2-portlet"; + } + /** * Determine the best fitting code to use for the given portlet, instanciate * it and add it to the list. @@ -485,21 +490,27 @@ export class HomeApp extends EgwApp this.portlet_container.getDOMNode().querySelectorAll("[style*='grid-area']").forEach((n) => { let [row] = (getComputedStyle(n).gridRow || "").split(" / "); - let [col, span] = (getComputedStyle(n).gridColumn || "").split(" / "); - if(parseInt(row) > last_row) + const colData = (getComputedStyle(n).gridColumn || "").split(" / span "); + let col = parseInt(colData[0]); + let span = parseInt(colData[1] || "1"); + if(parseInt(row) != last_row && typeof col_map[row] == "undefined") { last_row = parseInt(row); - col_map = {}; + col_map[row] = {}; } // If column is already occupied, or start off screen, or width pushes right side off screen - if(typeof col_map[col] !== "undefined" || parseInt(col) > maxColumn || parseInt(col) + (parseInt(span) || 1) > maxColumn) + if(typeof col_map[row][col] !== "undefined" || col > maxColumn || (col + span) > maxColumn) { + if(col + span > maxColumn) + { + span = Math.min(span, (maxColumn - (parseInt(Object.keys(col_map[row]).at(-1)) || col))); + } // Set column to auto to avoid overlap - n.style.gridColumn = "auto / " + span; + n.style.gridColumn = "auto / span " + span; } - for(let i = parseInt(col); i < (parseInt(span) || 1); i++) + for(let i = col; i <= span; i++) { - col_map[col + i] = true; + col_map[row][i] = true; } }); }