mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
Change tabs to use Shoelace
Includes changes to historylog, since it did some deferred loading & sizing magic based on tab
This commit is contained in:
parent
358a6a8ac8
commit
db143f047a
23
api/js/etemplate/Layout/Et2Tabs/Et2Tab.ts
Normal file
23
api/js/etemplate/Layout/Et2Tabs/Et2Tab.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {Et2Widget} from "../../Et2Widget/Et2Widget";
|
||||
import {SlTab} from "@shoelace-style/shoelace";
|
||||
|
||||
export class Et2Tab extends Et2Widget(SlTab)
|
||||
{
|
||||
|
||||
static get properties()
|
||||
{
|
||||
return {
|
||||
...super.properties,
|
||||
|
||||
hidden: {type: Boolean, reflect: true}
|
||||
}
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("et2-tab", Et2Tab);
|
52
api/js/etemplate/Layout/Et2Tabs/Et2TabPanel.ts
Normal file
52
api/js/etemplate/Layout/Et2Tabs/Et2TabPanel.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import {Et2Widget} from "../../Et2Widget/Et2Widget";
|
||||
import {SlTabPanel} from "@shoelace-style/shoelace";
|
||||
import shoelace from "../../Styles/shoelace";
|
||||
import {css} from "@lion/core";
|
||||
|
||||
export class Et2TabPanel extends Et2Widget(SlTabPanel)
|
||||
{
|
||||
static get styles()
|
||||
{
|
||||
return [
|
||||
// @ts-ignore
|
||||
...super.styles,
|
||||
...shoelace,
|
||||
css`
|
||||
:host {
|
||||
|
||||
height: 100%;
|
||||
/*
|
||||
width: 100%;
|
||||
|
||||
min-height: fit-content;
|
||||
min-width: fit-content;
|
||||
*/
|
||||
}
|
||||
.tab-panel {
|
||||
height: 100%;
|
||||
}
|
||||
::slotted(*) {
|
||||
height: 100%;
|
||||
}
|
||||
`
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
static get properties()
|
||||
{
|
||||
return {
|
||||
...super.properties,
|
||||
|
||||
hidden: {type: Boolean, reflect: true}
|
||||
}
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("et2-tab-panel", Et2TabPanel);
|
388
api/js/etemplate/Layout/Et2Tabs/Et2Tabs.ts
Normal file
388
api/js/etemplate/Layout/Et2Tabs/Et2Tabs.ts
Normal file
@ -0,0 +1,388 @@
|
||||
/**
|
||||
* EGroupware eTemplate2 - Box widget
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link https://www.egroupware.org
|
||||
* @author Nathan Gray
|
||||
*/
|
||||
import {SlTab, SlTabGroup, SlTabPanel} from "@shoelace-style/shoelace";
|
||||
import {Et2Widget, loadWebComponent} from "../../Et2Widget/Et2Widget";
|
||||
import {et2_directChildrenByTagName, et2_filteredNodeIterator, et2_readAttrWithDefault} from "../../et2_core_xml";
|
||||
import {css, PropertyValues} from "@lion/core";
|
||||
import shoelace from "../../Styles/shoelace";
|
||||
|
||||
|
||||
export class Et2Tabs extends Et2Widget(SlTabGroup)
|
||||
{
|
||||
static get styles()
|
||||
{
|
||||
return [
|
||||
...super.styles,
|
||||
...shoelace,
|
||||
css`
|
||||
.tab-group--top {
|
||||
height: 100%;
|
||||
min-height: fit-content;
|
||||
}
|
||||
.tab-group__body {
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden auto;
|
||||
}
|
||||
.tab-group__body-fixed-height {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
::slotted([hidden]) {
|
||||
display: none;
|
||||
}
|
||||
::slotted(et2-tab-panel) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
`
|
||||
];
|
||||
}
|
||||
|
||||
static get properties()
|
||||
{
|
||||
return {
|
||||
...super.properties,
|
||||
|
||||
/**
|
||||
* Array of [extra] tabs.
|
||||
* Each tab needs {label:..., template:...}.
|
||||
* Additional optional keys are prepend, hidden and id, for access into content array
|
||||
*/
|
||||
extraTabs: {type: Object},
|
||||
|
||||
/**
|
||||
* Add tabs to template
|
||||
* Set to true if tabs specified in tabs property should be added to tabs read from template,
|
||||
* default false if not which replaces what's in template
|
||||
*/
|
||||
addTabs: {type: Boolean},
|
||||
|
||||
/**
|
||||
* Set the height for tabs
|
||||
* Leave unset to size automatically
|
||||
*/
|
||||
tabHeight: {type: String},
|
||||
|
||||
/**
|
||||
* @deprecated use "placement" instead
|
||||
* @see https://shoelace.style/components/tab-group
|
||||
*/
|
||||
alignTabs: {type: String}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Index of currently selected tab
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
protected _selectedIndex = -1;
|
||||
protected tabData = [];
|
||||
protected lazyLoaded = false;
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
|
||||
this.extraTabs = [];
|
||||
this.addTabs = false;
|
||||
}
|
||||
|
||||
loadFromXML(_node)
|
||||
{
|
||||
// Get the tabs and tabpanels tags
|
||||
const tabsElems = et2_directChildrenByTagName(_node, "tabs");
|
||||
const tabpanelsElems = et2_directChildrenByTagName(_node, "tabpanels");
|
||||
const tabData = [];
|
||||
|
||||
// Check for a parent height, we'll apply it to tab panels
|
||||
var height = et2_readAttrWithDefault(_node.parentNode, "height", null);
|
||||
if(height)
|
||||
{
|
||||
this.tabContainer.css("height", height);
|
||||
}
|
||||
|
||||
// if no tabs set or they should be added to tabs from xml
|
||||
if(!this.extraTabs || this.extraTabs.length == 0 || this.addTabs)
|
||||
{
|
||||
if(tabsElems.length == 1 && tabpanelsElems.length == 1)
|
||||
{
|
||||
var tabs = tabsElems[0];
|
||||
var tabpanels = tabpanelsElems[0];
|
||||
|
||||
// Parse the "tabs" tag
|
||||
this._readTabs(tabData, tabs);
|
||||
|
||||
// Read and create the widgets defined in the "tabpanels"
|
||||
this._readTabPanels(tabData, tabpanels);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.egw().debug("error", "Error while parsing tabbox, none or multiple tabs or tabpanels tags!", this);
|
||||
}
|
||||
}
|
||||
// Add in additional tabs
|
||||
if(this.extraTabs)
|
||||
{
|
||||
let readonly = this.getArrayMgr("readonlys").getEntry(this.id) || {};
|
||||
for(let i = 0; i < this.extraTabs.length; i++)
|
||||
{
|
||||
let tab = this.extraTabs[i];
|
||||
let tab_id = tab.id || tab.template;
|
||||
let tab_options = {id: tab_id, template: tab.template, url: tab.url, content: undefined};
|
||||
if(tab.id)
|
||||
{
|
||||
tab_options.content = tab.id;
|
||||
}
|
||||
tabData[tab.prepend ? 'unshift' : 'push'].call(tabData, {
|
||||
"id": tab_id,
|
||||
"label": this.egw().lang(tab.label),
|
||||
"widget": null,
|
||||
"widget_options": tab_options,
|
||||
"contentDiv": null,
|
||||
"flagDiv": null,
|
||||
"hidden": typeof tab.hidden != "undefined" ? tab.hidden : readonly[tab_id] || false,
|
||||
"XMLNode": null,
|
||||
"promise": null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Create the tab DOM-Nodes
|
||||
this.createTabs(tabData);
|
||||
}
|
||||
|
||||
_readTabs(tabData, tabs)
|
||||
{
|
||||
let selected = "";
|
||||
this._selectedIndex = -1;
|
||||
let hidden = {};
|
||||
if(this.id)
|
||||
{
|
||||
// Set the value for this element
|
||||
let contentMgr = this.getArrayMgr("content");
|
||||
if(contentMgr != null)
|
||||
{
|
||||
let val = contentMgr.getEntry(this.id);
|
||||
if(val !== null)
|
||||
{
|
||||
selected = val;
|
||||
}
|
||||
}
|
||||
contentMgr = this.getArrayMgr("readonlys");
|
||||
if(contentMgr != null)
|
||||
{
|
||||
let val = contentMgr.getEntry(this.id);
|
||||
if(val !== null && typeof val !== 'undefined')
|
||||
{
|
||||
hidden = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
let i = 0;
|
||||
et2_filteredNodeIterator(tabs, function(node, nodeName)
|
||||
{
|
||||
if(nodeName == "tab")
|
||||
{
|
||||
const index_name = et2_readAttrWithDefault(node, "id", '');
|
||||
var hide = false;
|
||||
var widget_options = {};
|
||||
if(index_name)
|
||||
{
|
||||
if(selected == index_name)
|
||||
{
|
||||
this.selected_index = i;
|
||||
}
|
||||
if(hidden[index_name])
|
||||
{
|
||||
hide = true;
|
||||
}
|
||||
// Get the class attribute and add it as widget_options
|
||||
const classAttr = et2_readAttrWithDefault(node, "class", '');
|
||||
if(classAttr)
|
||||
{
|
||||
widget_options = {'class': classAttr};
|
||||
}
|
||||
}
|
||||
tabData.push({
|
||||
"id": index_name,
|
||||
"label": this.egw().lang(et2_readAttrWithDefault(node, "label", "Tab")),
|
||||
"widget": null,
|
||||
"widget_options": widget_options,
|
||||
"contentDiv": null,
|
||||
"flagDiv": null,
|
||||
"hidden": hide,
|
||||
"XMLNode": null,
|
||||
"promise": null
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("Error while parsing: Invalid tag '" + nodeName +
|
||||
"' in tabs tag");
|
||||
}
|
||||
i++;
|
||||
}, this);
|
||||
|
||||
// Make sure we don't try to display a hidden tab
|
||||
for(let i = 0; i < tabData.length && this._selectedIndex < 0; i++)
|
||||
{
|
||||
if(!tabData[i].hidden)
|
||||
{
|
||||
this._selectedIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_readTabPanels(tabData, tabpanels)
|
||||
{
|
||||
var i = 0;
|
||||
et2_filteredNodeIterator(tabpanels, function(node, nodeName)
|
||||
{
|
||||
if(i < tabData.length)
|
||||
{
|
||||
// Store node for later evaluation
|
||||
tabData[i].XMLNode = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("Error while reading tabpanels tag, too many widgets!");
|
||||
}
|
||||
i++;
|
||||
}, this);
|
||||
}
|
||||
|
||||
protected update(changedProperties : PropertyValues)
|
||||
{
|
||||
super.update(changedProperties);
|
||||
if(changedProperties.has("tabHeight"))
|
||||
{
|
||||
const body = this.shadowRoot.querySelector(".tab-group__body");
|
||||
body.style.setProperty("height", this.tabHeight == parseInt(this.tabHeight) + "" ? this.tabHeight + "px" : this.tabHeight);
|
||||
body.classList.toggle("tab-group__body-fixed-height", this.tabHeight !== '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the nodes for tabs
|
||||
*
|
||||
* @param tabData
|
||||
* @protected
|
||||
*/
|
||||
protected createTabs(tabData)
|
||||
{
|
||||
this.tabData = tabData;
|
||||
tabData.forEach((tab, index) =>
|
||||
{
|
||||
// Tab - SlTabGroup looks for sl-tab, so we can't use our own without overriding a lot
|
||||
tab.flagDiv = loadWebComponent("et2-tab", {
|
||||
slot: "nav",
|
||||
panel: tab.id,
|
||||
active: index == this._selectedIndex,
|
||||
hidden: tab.hidden
|
||||
}, this);
|
||||
|
||||
// Set tab label
|
||||
tab.flagDiv.appendChild(document.createTextNode(tab.label));
|
||||
});
|
||||
tabData.forEach((tab, index) =>
|
||||
{
|
||||
this.createPanel(tab);
|
||||
});
|
||||
}
|
||||
|
||||
protected createPanel(tab, active = false)
|
||||
{
|
||||
// Tab panel
|
||||
tab.contentDiv = loadWebComponent('et2-tab-panel', {
|
||||
name: tab.id,
|
||||
active: active,
|
||||
hidden: tab.hidden
|
||||
}, this);
|
||||
|
||||
// Tab content
|
||||
let tabContent = tab.contentDiv.createElementFromNode(tab.XMLNode);
|
||||
tab.contentDiv.appendChild(
|
||||
typeof window.customElements.get(tab.XMLNode.nodeName) == "undefined" ?
|
||||
tabContent.getDOMNode() : tabContent
|
||||
);
|
||||
|
||||
return tab.contentDiv;
|
||||
}
|
||||
|
||||
getAllTabs(includeDisabled = false)
|
||||
{
|
||||
const slot = <HTMLSlotElement>this.shadowRoot.querySelector('slot[name="nav"]');
|
||||
const tabNames = ["sl-tab", "et2-tab"];
|
||||
return <SlTab[]>[...slot.assignedElements()].filter((el) =>
|
||||
{
|
||||
return includeDisabled ? tabNames.indexOf(el.tagName.toLowerCase()) != -1 : tabNames.indexOf(el.tagName.toLowerCase()) !== -1 && !el.disabled;
|
||||
});
|
||||
}
|
||||
|
||||
getAllPanels()
|
||||
{
|
||||
const slot = this.body.querySelector('slot')!;
|
||||
return [...slot.assignedElements()].filter(el => ['et2-tab-panel', 'sl-tab-panel'].indexOf(el.tagName.toLowerCase()) != -1) as [SlTabPanel];
|
||||
}
|
||||
|
||||
handleClick(event : MouseEvent)
|
||||
{
|
||||
const target = event.target as HTMLElement;
|
||||
const tab = target.closest('et2-tab');
|
||||
const tabGroup = tab?.closest('sl-tab-group') || tab?.closest('et2-tabbox');
|
||||
|
||||
// Ensure the target tab is in this tab group
|
||||
if(tabGroup !== this)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(tab !== null)
|
||||
{
|
||||
this.setActiveTab(tab, {scrollBehavior: 'smooth'});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up for printing
|
||||
*
|
||||
* @return {undefined|Deferred} Return a jQuery Deferred object if not done setting up
|
||||
* (waiting for data)
|
||||
*/
|
||||
beforePrint()
|
||||
{
|
||||
// Remove the "active" flag from all tabs-flags
|
||||
this.querySelector("[active]").removeAttribute("active");
|
||||
|
||||
// Remove height limit
|
||||
this.style.height = '';
|
||||
|
||||
// Show all enabled tabs
|
||||
for(let i = 0; i < this.tabData.length; i++)
|
||||
{
|
||||
let entry = this.tabData[i];
|
||||
if(entry.hidden)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
entry.flagDiv.insertBefore(entry.contentDiv);
|
||||
entry.contentDiv.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset after printing
|
||||
*/
|
||||
afterPrint()
|
||||
{
|
||||
this.setActiveTab(this._selectedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("et2-tabbox", Et2Tabs);
|
@ -18,11 +18,18 @@ import {ClassWithAttributes} from './et2_core_inheritance';
|
||||
import {et2_IDOMNode} from "./et2_core_interfaces";
|
||||
import {et2_hasChild, et2_no_init} from "./et2_core_common";
|
||||
import {et2_widget, WidgetConfig} from "./et2_core_widget";
|
||||
import {egw_getActionManager, egwActionObject, egwActionObjectInterface, egw_getAppObjectManager,egw_getObjectManager} from '../egw_action/egw_action.js';
|
||||
import {EGW_AI_DRAG_OVER, EGW_AI_DRAG_OUT} from '../egw_action/egw_action_constants.js';
|
||||
import {
|
||||
egw_getActionManager,
|
||||
egw_getAppObjectManager,
|
||||
egw_getObjectManager,
|
||||
egwActionObject,
|
||||
egwActionObjectInterface
|
||||
} from '../egw_action/egw_action.js';
|
||||
import {EGW_AI_DRAG_OUT, EGW_AI_DRAG_OVER} from '../egw_action/egw_action_constants.js';
|
||||
import {egw} from "../jsapi/egw_global";
|
||||
// fixing circular dependencies by only importing type
|
||||
import type {et2_tabbox} from "./et2_widget_tabs";
|
||||
import {Et2Tab} from "./Layout/Et2Tabs/Et2Tab";
|
||||
import {Et2TabPanel} from "./Layout/Et2Tabs/Et2TabPanel";
|
||||
import {Et2Tabs} from "./Layout/Et2Tabs/Et2Tabs";
|
||||
|
||||
/**
|
||||
* Abstract widget class which can be inserted into the DOM. All widget classes
|
||||
@ -320,12 +327,14 @@ export abstract class et2_DOMWidget extends et2_widget implements et2_IDOMNode
|
||||
*
|
||||
* @returns {Object|null} Data for tab the widget is on
|
||||
*/
|
||||
get_tab_info() : {id: string, label: string, widget: et2_widget, contentDiv: JQuery, flagDiv: JQuery} | null
|
||||
get_tab_info() : { id : string, label : string, widget : et2_widget, contentDiv : Et2TabPanel, flagDiv : Et2Tab } | null
|
||||
{
|
||||
var parent : et2_widget = this;
|
||||
do {
|
||||
do
|
||||
{
|
||||
parent = parent.getParent();
|
||||
} while (parent !== this.getRoot() && parent.getType() !== 'tabbox');
|
||||
}
|
||||
while(parent !== this.getRoot() && ['tabbox', 'ET2-TABBOX'].indexOf(parent.getType()) == -1);
|
||||
|
||||
// No tab
|
||||
if(parent === this.getRoot())
|
||||
@ -333,14 +342,14 @@ export abstract class et2_DOMWidget extends et2_widget implements et2_IDOMNode
|
||||
return null;
|
||||
}
|
||||
|
||||
let tabbox : et2_tabbox = <et2_tabbox><unknown>parent;
|
||||
let tabbox : Et2Tabs = <Et2Tabs><unknown>parent;
|
||||
|
||||
// Find the tab index
|
||||
for(var i = 0; i < tabbox.tabData.length; i++)
|
||||
{
|
||||
// Find the tab by DOM heritage
|
||||
// @ts-ignore
|
||||
if(tabbox.tabData[i].contentDiv.has(this.div).length)
|
||||
if(tabbox.tabData[i].contentDiv.contains(this.div[0] || this))
|
||||
{
|
||||
return tabbox.tabData[i];
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import {et2_dataview_column} from "./et2_dataview_model_columns";
|
||||
import {et2_dataview_controller} from "./et2_dataview_controller";
|
||||
import {et2_diff} from "./et2_widget_diff";
|
||||
import {et2_IDetachedDOM, et2_IResizeable} from "./et2_core_interfaces";
|
||||
import {et2_dynheight} from "./et2_widget_dynheight";
|
||||
import {et2_customfields_list} from "./et2_extension_customfields";
|
||||
import {et2_selectbox} from "./et2_widget_selectbox";
|
||||
import {loadWebComponent} from "./Et2Widget/Et2Widget";
|
||||
@ -96,7 +95,6 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
private div: JQuery;
|
||||
private innerDiv: JQuery;
|
||||
private _filters: { appname: string; record_id: string; get_rows: string; };
|
||||
private dynheight: et2_dynheight;
|
||||
private dataview: et2_dataview;
|
||||
private controller: et2_dataview_controller;
|
||||
private fields: any;
|
||||
@ -114,6 +112,8 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
|
||||
this.innerDiv = jQuery(document.createElement("div"))
|
||||
.appendTo(this.div);
|
||||
|
||||
this._resize = this._resize.bind(this);
|
||||
}
|
||||
|
||||
set_status_id( _new_id)
|
||||
@ -130,36 +130,16 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
if(tab)
|
||||
{
|
||||
// Bind the action to when the tab is selected
|
||||
const handler = function(e)
|
||||
const handler = (e) =>
|
||||
{
|
||||
e.data.div.unbind("click.history");
|
||||
// Bind on click tap, because we need to update history size
|
||||
// after a rezise happend and history log was not the active tab
|
||||
e.data.div.bind("click.history", {"history": e.data.history, div: tab.flagDiv}, function (e) {
|
||||
if (e.data.history && e.data.history.dynheight) {
|
||||
e.data.history.dynheight.update(function (_w, _h) {
|
||||
e.data.history.dataview.resize(_w, _h);
|
||||
});
|
||||
if(typeof this.dataview == "undefined")
|
||||
{
|
||||
this.finishInit();
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof e.data.history.dataview == "undefined") {
|
||||
e.data.history.finishInit();
|
||||
if (e.data.history.dynheight) {
|
||||
e.data.history.dynheight.update(function (_w, _h) {
|
||||
e.data.history.dataview.resize(_w, _h);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Find a better way to get this to wait
|
||||
window.setTimeout(this._resize, 10);
|
||||
};
|
||||
tab.flagDiv.bind("click.history",{"history": this, div: tab.flagDiv}, handler);
|
||||
|
||||
// Display if history tab is selected
|
||||
if(tab.contentDiv.is(':visible') && typeof this.dataview == 'undefined')
|
||||
{
|
||||
tab.flagDiv.trigger("click.history");
|
||||
}
|
||||
tab.flagDiv.addEventListener("click", handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -194,13 +174,7 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
this.egw().debug("warn", "status_id attribute should not be the same as historylog ID");
|
||||
}
|
||||
|
||||
// Create the dynheight component which dynamically scales the inner
|
||||
// container.
|
||||
this.div.parentsUntil('.et2_tabs').height('100%');
|
||||
const parent = this.get_tab_info();
|
||||
this.dynheight = new et2_dynheight(parent ? parent.contentDiv : this.div.parent(),
|
||||
this.innerDiv, 250
|
||||
);
|
||||
|
||||
// Create the outer grid container
|
||||
this.dataview = new et2_dataview(this.innerDiv, this.egw());
|
||||
@ -267,9 +241,7 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
// Register a resize callback
|
||||
jQuery(window).on('resize.' +this.options.value.app + this.options.value.id, function()
|
||||
{
|
||||
if (this && typeof this.dynheight != 'undefined') this.dynheight.update(function(_w, _h) {
|
||||
this.dataview.resize(_w, _h);
|
||||
}.bind(this));
|
||||
this.dataview.resize();
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
@ -297,7 +269,6 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
// Free the grid components
|
||||
if(this.dataview) this.dataview.destroy();
|
||||
if(this.controller) this.controller.destroy();
|
||||
if(this.dynheight) this.dynheight.destroy();
|
||||
|
||||
super.destroy();
|
||||
}
|
||||
@ -757,30 +728,26 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
||||
row.parents("td").next().remove();
|
||||
}
|
||||
|
||||
_resize()
|
||||
{
|
||||
let tab = this.get_tab_info();
|
||||
if(this.dataview)
|
||||
{
|
||||
// -# to avoid scrollbars
|
||||
this.dataview.resize(
|
||||
Math.min(
|
||||
window.innerWidth - 15,
|
||||
parseInt(getComputedStyle(tab.contentDiv).width)
|
||||
) - 5,
|
||||
parseInt(getComputedStyle(tab.contentDiv).height) - 5
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
resize(_height)
|
||||
{
|
||||
if (typeof this.options != 'undefined' && _height
|
||||
&& typeof this.options.resize_ratio != 'undefined')
|
||||
{
|
||||
// apply the ratio
|
||||
_height = (this.options.resize_ratio != '')? _height * this.options.resize_ratio: _height;
|
||||
if (_height != 0)
|
||||
{
|
||||
// 250px is the default value for history widget
|
||||
// if it's not loaded yet and window is resized
|
||||
// then add the default height with excess_height
|
||||
if (this.div.height() == 0) _height += 250;
|
||||
this.div.height(this.div.height() + _height);
|
||||
|
||||
// trigger the history registered resize
|
||||
// in order to update the height with new value
|
||||
this.div.trigger('resize.' +this.options.value.app + this.options.value.id);
|
||||
}
|
||||
}
|
||||
if(this.dynheight)
|
||||
{
|
||||
this.dynheight.update();
|
||||
}
|
||||
this._resize();
|
||||
// Resize diff widgets to match new space
|
||||
if(this.dataview)
|
||||
{
|
||||
|
@ -25,6 +25,9 @@ import '../jsapi/egw_json.js';
|
||||
import {egwIsMobile} from "../egw_action/egw_action_common.js";
|
||||
import './Layout/Et2Box/Et2Box';
|
||||
import './Layout/Et2Details/Et2Details';
|
||||
import './Layout/Et2Tabs/Et2Tab';
|
||||
import './Layout/Et2Tabs/Et2Tabs';
|
||||
import './Layout/Et2Tabs/Et2TabPanel';
|
||||
import './Et2Avatar/Et2Avatar';
|
||||
import './Et2Button/Et2Button';
|
||||
import './Et2Checkbox/Et2Checkbox';
|
||||
@ -666,6 +669,8 @@ export class etemplate2
|
||||
if(egw.debug_level() >= 4 && console.timeStamp)
|
||||
{
|
||||
console.timeStamp("Begin rendering template");
|
||||
console.time("Template load");
|
||||
console.time("loadFromXML");
|
||||
}
|
||||
|
||||
// Add into indexed list - do this before, so anything looking can find it,
|
||||
@ -678,6 +683,8 @@ export class etemplate2
|
||||
|
||||
// Read the XML structure of the requested template
|
||||
this._widgetContainer.loadFromXML(etemplate2.templates[this.name]);
|
||||
console.timeEnd("loadFromXML");
|
||||
console.time("deferred");
|
||||
|
||||
// List of Promises from widgets that are not quite fully loaded
|
||||
const deferred = [];
|
||||
@ -693,6 +700,10 @@ export class etemplate2
|
||||
|
||||
if(egw.debug_level() >= 3 && console.groupEnd)
|
||||
{
|
||||
if(console.timeStamp)
|
||||
{
|
||||
console.timeStamp("loading finished, waiting for deferred");
|
||||
}
|
||||
egw.window.console.groupEnd();
|
||||
}
|
||||
|
||||
@ -702,6 +713,9 @@ export class etemplate2
|
||||
{
|
||||
Promise.all(deferred).then(() =>
|
||||
{
|
||||
|
||||
console.timeEnd("deferred");
|
||||
console.timeStamp("Deferred done");
|
||||
// Clear dirty now that it's all loaded
|
||||
this.widgetContainer.iterateOver((_widget) =>
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user