forked from extern/egroupware
Get templates working in Et2Dialog
This commit is contained in:
parent
689e7e6ee5
commit
5fdc594d00
@ -17,6 +17,8 @@ import {et2_createWidget, et2_widget} from "../et2_core_widget";
|
|||||||
import {html, LitElement, ScopedElementsMixin, SlotMixin} from "@lion/core";
|
import {html, LitElement, ScopedElementsMixin, SlotMixin} from "@lion/core";
|
||||||
import {Et2DialogOverlay} from "./Et2DialogOverlay";
|
import {Et2DialogOverlay} from "./Et2DialogOverlay";
|
||||||
import {Et2DialogContent} from "./Et2DialogContent";
|
import {Et2DialogContent} from "./Et2DialogContent";
|
||||||
|
import {et2_template} from "../et2_widget_template";
|
||||||
|
import {etemplate2} from "../etemplate2";
|
||||||
|
|
||||||
export interface DialogButton
|
export interface DialogButton
|
||||||
{
|
{
|
||||||
@ -46,6 +48,16 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
*/
|
*/
|
||||||
protected __egw : IegwAppLocal
|
protected __egw : IegwAppLocal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As long as the template is a legacy widget, we want to hold on to the widget
|
||||||
|
* When it becomes a WebComponent, we can just include it in render()
|
||||||
|
*
|
||||||
|
* @type {et2_template | null}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
protected __template_widget : etemplate2 | null;
|
||||||
|
protected __template_promise : Promise<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
* @constant
|
* @constant
|
||||||
@ -73,10 +85,18 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
return {
|
return {
|
||||||
...super.properties(),
|
...super.properties(),
|
||||||
callback: Function,
|
callback: Function,
|
||||||
|
|
||||||
|
// There's an issue with Et2DialogContent.style being undefined, so this has to stay false until it gets
|
||||||
|
// figured out
|
||||||
modal: Boolean,
|
modal: Boolean,
|
||||||
title: String,
|
title: String,
|
||||||
buttons: Number,
|
buttons: Number,
|
||||||
|
|
||||||
|
template: String,
|
||||||
|
|
||||||
|
width: Number,
|
||||||
|
height: Number,
|
||||||
|
|
||||||
// We just pass these on to Et2DialogContent
|
// We just pass these on to Et2DialogContent
|
||||||
message: String,
|
message: String,
|
||||||
dialog_type: Number,
|
dialog_type: Number,
|
||||||
@ -140,11 +160,16 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor()
|
constructor(parent_egw? : string | IegwAppLocal)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.modal = true;
|
if(parent_egw)
|
||||||
|
{
|
||||||
|
this._setApiInstance(parent_egw);
|
||||||
|
}
|
||||||
|
// Needs to not be modal until the style thing is figured out
|
||||||
|
this.modal = false;
|
||||||
this.__value = {};
|
this.__value = {};
|
||||||
|
|
||||||
this._onClose = this._onClose.bind(this);
|
this._onClose = this._onClose.bind(this);
|
||||||
@ -154,6 +179,12 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
connectedCallback()
|
connectedCallback()
|
||||||
{
|
{
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
|
// Wait for everything to complete, then auto-open
|
||||||
|
this.getUpdateComplete().then(() =>
|
||||||
|
{
|
||||||
|
window.setTimeout(this.open, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to wait for Overlay
|
// Need to wait for Overlay
|
||||||
@ -162,15 +193,18 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
await super.getUpdateComplete();
|
await super.getUpdateComplete();
|
||||||
await this._overlayContentNode.getUpdateComplete();
|
await this._overlayContentNode.getUpdateComplete();
|
||||||
|
|
||||||
|
// Wait for template to finish loading
|
||||||
|
if(this.__template_widget)
|
||||||
|
{
|
||||||
|
await this.__template_promise;
|
||||||
|
}
|
||||||
|
|
||||||
// This calls _onClose() when the dialog is closed
|
// This calls _onClose() when the dialog is closed
|
||||||
this._overlayContentNode.addEventListener(
|
this._overlayContentNode.addEventListener(
|
||||||
'close-overlay',
|
'close-overlay',
|
||||||
this._onClose,
|
this._onClose,
|
||||||
);
|
);
|
||||||
this._overlayContentNode.addEventListener(
|
this._overlayContentNode.querySelectorAll("et2-button").forEach((button) => button.addEventListener("click", this._onClick));
|
||||||
'click',
|
|
||||||
this._onClick
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClose(ev : PointerEvent)
|
_onClose(ev : PointerEvent)
|
||||||
@ -185,23 +219,36 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
const button_id = parseInt(ev.target?.getAttribute("button_id")) || ev.target?.getAttribute("id") || null;
|
const button_id = parseInt(ev.target?.getAttribute("button_id")) || ev.target?.getAttribute("id") || null;
|
||||||
|
|
||||||
// Handle anything bound via et2 onclick property
|
// Handle anything bound via et2 onclick property
|
||||||
let et2_widget_result = super._handleClick(ev);
|
try
|
||||||
|
|
||||||
if(!et2_widget_result)
|
|
||||||
{
|
{
|
||||||
ev.preventDefault();
|
let et2_widget_result = super._handleClick(ev);
|
||||||
ev.stopPropagation();
|
if(!et2_widget_result)
|
||||||
return false;
|
{
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
console.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback expects (button_id, value)
|
|
||||||
let callback_result = this.callback ? this.callback(button_id, this.value) : true;
|
|
||||||
|
|
||||||
if(callback_result === false)
|
// Callback expects (button_id, value)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ev.preventDefault();
|
let callback_result = this.callback ? this.callback(button_id, this.value) : true;
|
||||||
ev.stopPropagation();
|
if(callback_result === false)
|
||||||
return false;
|
{
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
console.log(e);
|
||||||
}
|
}
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
@ -213,18 +260,97 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
get value() : Object
|
get value() : Object
|
||||||
{
|
{
|
||||||
let value = this.__value;
|
let value = this.__value;
|
||||||
if(this.template)
|
if(this.__template_widget)
|
||||||
{
|
{
|
||||||
value = this.template.getValues(this.template.widgetContainer);
|
value = this.__template_widget.getValues(this.__template_widget.widgetContainer);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire the close-overlay event to use all registered listeners
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
this._overlayContentNode.dispatchEvent(new Event('close-overlay'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
get_value() : Object
|
||||||
|
{
|
||||||
|
console.warn("Deprecated get_value() called");
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
set value(new_value)
|
set value(new_value)
|
||||||
{
|
{
|
||||||
this.__value = new_value;
|
this.__value = new_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set template(new_template_name)
|
||||||
|
{
|
||||||
|
let old_template = this.template;
|
||||||
|
this.__template = new_template_name;
|
||||||
|
this.requestUpdate("template", old_template);
|
||||||
|
}
|
||||||
|
|
||||||
|
get template()
|
||||||
|
{
|
||||||
|
return this.__template;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
updated(changedProperties)
|
||||||
|
{
|
||||||
|
super.updated(changedProperties);
|
||||||
|
if(changedProperties.has("template"))
|
||||||
|
{
|
||||||
|
this._loadTemplate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadTemplate()
|
||||||
|
{
|
||||||
|
if(this.__template_widget)
|
||||||
|
{
|
||||||
|
this.__template_widget.clear();
|
||||||
|
}
|
||||||
|
this.__template_widget = new etemplate2(this._overlayContentNode._contentNode);
|
||||||
|
if(this.template.indexOf('.xet') > 0)
|
||||||
|
{
|
||||||
|
// File name provided, fetch from server
|
||||||
|
this.__template_promise = this.__template_widget.load("", this.template, this.__value || {content: {}},);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just template name, it better be loaded already
|
||||||
|
this.__template_promise = this.__template_widget.load(this.template, '', this.__value || {},
|
||||||
|
// true: do NOT call et2_ready, as it would overwrite this.et2 in app.js
|
||||||
|
undefined, undefined, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't let dialog closing destroy the parent session
|
||||||
|
if(this.__template_widget.etemplate_exec_id && this.__template_widget.app)
|
||||||
|
{
|
||||||
|
for(let et of etemplate2.getByApplication(this.__template_widget.app))
|
||||||
|
{
|
||||||
|
if(et !== this.__template_widget && et.etemplate_exec_id === this.__template_widget.etemplate_exec_id)
|
||||||
|
{
|
||||||
|
// Found another template using that exec_id, don't destroy when dialog closes.
|
||||||
|
this.__template_widget.unbind_unload();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set template-name as id, to allow to style dialogs
|
||||||
|
//this.div.children().attr('id', new_template_name.replace(/^(.*\/)?([^/]+)(\.xet)?$/, '$2').replace(/\./g, '-'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
render()
|
render()
|
||||||
{
|
{
|
||||||
return this._overlayTemplate();
|
return this._overlayTemplate();
|
||||||
@ -240,6 +366,8 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
return html`
|
return html`
|
||||||
<div id="overlay-content-node-wrapper">
|
<div id="overlay-content-node-wrapper">
|
||||||
<et2-dialog-overlay-frame class="dialog__overlay-frame"
|
<et2-dialog-overlay-frame class="dialog__overlay-frame"
|
||||||
|
.width=${this.width}
|
||||||
|
.height=${this.height}
|
||||||
._dialog=${this}
|
._dialog=${this}
|
||||||
.buttons=${this._getButtons()}>
|
.buttons=${this._getButtons()}>
|
||||||
<span slot="heading">${this.title}</span>
|
<span slot="heading">${this.title}</span>
|
||||||
@ -267,16 +395,22 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
|
|
||||||
_contentTemplate()
|
_contentTemplate()
|
||||||
{
|
{
|
||||||
|
if(this.template)
|
||||||
return html`
|
{
|
||||||
<et2-dialog-content slot="content" ?icon=${this.icon}
|
return html`
|
||||||
.dialog_type=${this.dialog_type}
|
<div slot="content"></div>`;
|
||||||
.value=${this.value}
|
}
|
||||||
>
|
else
|
||||||
${this.message}
|
{
|
||||||
</et2-dialog-content>
|
return html`
|
||||||
`;
|
<et2-dialog-content slot="content" ?icon=${this.icon}
|
||||||
|
.dialog_type=${this.dialog_type}
|
||||||
|
.value=${this.value}
|
||||||
|
>
|
||||||
|
${this.message}
|
||||||
|
</et2-dialog-content>
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getButtons()
|
_getButtons()
|
||||||
@ -379,12 +513,15 @@ export class Et2Dialog extends Et2Widget(ScopedElementsMixin(SlotMixin(LionDialo
|
|||||||
icon: _icon,
|
icon: _icon,
|
||||||
value: _value,
|
value: _value,
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
|
/*
|
||||||
|
TODO: There's something going on with our Et2Widgets that they don't get a proper .style property
|
||||||
|
This lack of .style causes problems when we go modal. Non-modal works.
|
||||||
|
*/
|
||||||
modal: false
|
modal: false
|
||||||
});
|
});
|
||||||
// Let other things run, then open
|
// Let other things run, then open
|
||||||
dialog.getUpdateComplete().then(() =>
|
dialog.getUpdateComplete().then(() =>
|
||||||
{
|
{
|
||||||
window.setTimeout(dialog.open, 0);
|
|
||||||
});
|
});
|
||||||
document.body.appendChild(<LitElement><unknown>dialog);
|
document.body.appendChild(<LitElement><unknown>dialog);
|
||||||
return dialog;
|
return dialog;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
import {css, CSSResultArray, html, LitElement} from "@lion/core";
|
||||||
import {Et2Widget} from "../Et2Widget/Et2Widget";
|
import {Et2Widget} from "../Et2Widget/Et2Widget";
|
||||||
import {css, html, LitElement} from "@lion/core";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widget for the actual content of a dialog, used when we're not doing a template
|
* Widget for the actual content of a dialog, used when we're not doing a template
|
||||||
@ -7,11 +7,8 @@ import {css, html, LitElement} from "@lion/core";
|
|||||||
*/
|
*/
|
||||||
export class Et2DialogContent extends Et2Widget(LitElement)
|
export class Et2DialogContent extends Et2Widget(LitElement)
|
||||||
{
|
{
|
||||||
static get styles()
|
static styles : CSSResultArray = [
|
||||||
{
|
css`
|
||||||
return [
|
|
||||||
...super.styles,
|
|
||||||
css`
|
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
@ -25,8 +22,8 @@ export class Et2DialogContent extends Et2Widget(LitElement)
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
];
|
];
|
||||||
}
|
|
||||||
|
|
||||||
get properties()
|
get properties()
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import {css, html, LitElement, repeat, SlotMixin} from '@lion/core';
|
import {css, html, LitElement, repeat, SlotMixin} from '@lion/core';
|
||||||
import {DialogButton, Et2Dialog} from "./Et2Dialog";
|
import {DialogButton, Et2Dialog} from "./Et2Dialog";
|
||||||
import {Et2Widget} from "../Et2Widget/Et2Widget";
|
import {et2_template} from "../et2_widget_template";
|
||||||
|
import {Et2DialogContent} from "./Et2DialogContent";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles the visible portion of the dialog, including the title & close button.
|
* This handles the visible portion of the dialog, including the title & close button.
|
||||||
*
|
*
|
||||||
|
* Note we can't extend Et2Widget. If I try, something in the render / creation breaks and calling open() gives an
|
||||||
|
* error with modal: true
|
||||||
*/
|
*/
|
||||||
export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
export class Et2DialogOverlay extends SlotMixin(LitElement)
|
||||||
{
|
{
|
||||||
|
|
||||||
protected buttons : DialogButton[];
|
protected buttons : DialogButton[];
|
||||||
@ -30,6 +33,10 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
.overlay__header {
|
.overlay__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@ -39,6 +46,9 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
padding: 6px 16px 8px;
|
padding: 6px 16px 8px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
#overlay-content-node-wrapper {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.overlay__heading > .overlay__close-button {
|
.overlay__heading > .overlay__close-button {
|
||||||
flex: none;
|
flex: none;
|
||||||
@ -69,6 +79,15 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get properties()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
// Allow to force size, otherwise it sizes to contents
|
||||||
|
width: Number,
|
||||||
|
height: Number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get slots()
|
get slots()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
@ -84,7 +103,6 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.buttons = [];
|
this.buttons = [];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated(_changedProperties)
|
firstUpdated(_changedProperties)
|
||||||
@ -92,22 +110,39 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
super.firstUpdated(_changedProperties);
|
super.firstUpdated(_changedProperties);
|
||||||
// Tell content about its parent, but don't move it
|
// Tell content about its parent, but don't move it
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
(<Et2Widget><unknown>this.querySelector("[slot='content']"))._parent = this._dialog;
|
//(<Et2Widget><unknown>this.querySelector("[slot='content']"))._parent = this._dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Need to wait for Overlay
|
// Need to wait for Overlay
|
||||||
async getUpdateComplete()
|
async getUpdateComplete()
|
||||||
{
|
{
|
||||||
await super.getUpdateComplete();
|
let result = await super.getUpdateComplete();
|
||||||
await this._contentNode.getUpdateComplete();
|
if(this._contentNode && this._contentNode.getUpdateComplete)
|
||||||
|
{
|
||||||
|
await this._contentNode.getUpdateComplete();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback()
|
||||||
|
{
|
||||||
|
super.connectedCallback();
|
||||||
|
// Need to wait for Overlay
|
||||||
|
this.updateComplete
|
||||||
|
.then(async() =>
|
||||||
|
{
|
||||||
|
if(this._contentNode && this._contentNode.getUpdateComplete)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Re-do render to get proper images
|
||||||
|
this._contentNode.requestUpdate();
|
||||||
|
|
||||||
|
await this._contentNode.getUpdateComplete();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog might not be part of an etemplate, use dialog's egw
|
|
||||||
*
|
|
||||||
* @returns {IegwAppLocal}
|
|
||||||
*/
|
|
||||||
egw() : IegwAppLocal
|
egw() : IegwAppLocal
|
||||||
{
|
{
|
||||||
if(this._dialog)
|
if(this._dialog)
|
||||||
@ -132,8 +167,9 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
return super.performUpdate();
|
return super.performUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
get _contentNode()
|
get _contentNode() : Et2DialogContent | et2_template
|
||||||
{
|
{
|
||||||
|
// @ts-ignore
|
||||||
return this.querySelector("[slot='content']");
|
return this.querySelector("[slot='content']");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +181,17 @@ export class Et2DialogOverlay extends Et2Widget(SlotMixin(LitElement))
|
|||||||
|
|
||||||
render()
|
render()
|
||||||
{
|
{
|
||||||
// eslint-disable-line class-methods-use-this
|
// This style is just for this dialog
|
||||||
|
let style = html`
|
||||||
|
<style>
|
||||||
|
.overlay {
|
||||||
|
${this.width ? "width: " + this.width + "px" : ""};
|
||||||
|
${this.height ? "height: " + this.height + "px" : ""};
|
||||||
|
}
|
||||||
|
</style>`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
|
${(this.width || this.height) ? style : ""}
|
||||||
<div class="overlay">
|
<div class="overlay">
|
||||||
<div class="overlay__header">
|
<div class="overlay__header">
|
||||||
<h1 class="overlay__heading">
|
<h1 class="overlay__heading">
|
||||||
|
Loading…
Reference in New Issue
Block a user