forked from extern/egroupware
ported timestamper to a web-component
also implemented legacy methods activateTab() and setActiveTab() for new tabs widget
This commit is contained in:
parent
839f5f9284
commit
c3673b1126
@ -269,15 +269,21 @@ function send_template()
|
|||||||
|
|
||||||
$str = preg_replace('#<passwd ([^>]+)(/|></passwd)>#', '<et2-password $1></et2-password>', $str);
|
$str = preg_replace('#<passwd ([^>]+)(/|></passwd)>#', '<et2-password $1></et2-password>', $str);
|
||||||
|
|
||||||
// fix <button(only)?.../> --> <et2-(button|image) (noSubmit="true")?.../>
|
// fix <(button|buttononly|timestamper).../> --> <et2-(button|image|button-timestamp) (noSubmit="true")?.../>
|
||||||
$str = preg_replace_callback('#<button(only)?\s(.*?)(/|></button)>#s', function ($matches) use ($name)
|
$str = preg_replace_callback('#<(button|buttononly|timestamper|button-timestamp)\s(.*?)(/|></(button|buttononly|timestamper|button-timestamp))>#s', function ($matches) use ($name)
|
||||||
{
|
{
|
||||||
$tag = 'et2-button';
|
$tag = 'et2-button';
|
||||||
$attrs = parseAttrs($matches[2]);
|
$attrs = parseAttrs($matches[2]);
|
||||||
// replace buttononly tag with noSubmit="true" attribute
|
switch ($matches[1])
|
||||||
if (!empty($matches[1]))
|
|
||||||
{
|
{
|
||||||
|
case 'buttononly': // replace buttononly tag with noSubmit="true" attribute
|
||||||
$attrs['noSubmit'] = 'true';
|
$attrs['noSubmit'] = 'true';
|
||||||
|
break;
|
||||||
|
case 'timestamper':
|
||||||
|
case 'button-timestamp':
|
||||||
|
$tag .= '-timestamp';
|
||||||
|
$attrs['background_image'] = 'true';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// novalidation --> noValidation
|
// novalidation --> noValidation
|
||||||
if (!empty($attrs['novalidation']) && in_array($attrs['novalidation'], ['true', '1'], true))
|
if (!empty($attrs['novalidation']) && in_array($attrs['novalidation'], ['true', '1'], true))
|
||||||
|
@ -136,9 +136,9 @@ export class Et2Button extends Et2InputWidget(SlButton)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor()
|
constructor(...args : any[])
|
||||||
{
|
{
|
||||||
super();
|
super(...args);
|
||||||
|
|
||||||
// Property default values
|
// Property default values
|
||||||
this.__image = '';
|
this.__image = '';
|
||||||
@ -259,7 +259,7 @@ export class Et2Button extends Et2InputWidget(SlButton)
|
|||||||
if(!this.image)
|
if(!this.image)
|
||||||
{
|
{
|
||||||
let image = this._get_default_image(this._widget_id);
|
let image = this._get_default_image(this._widget_id);
|
||||||
if(image && image != this._image)
|
if(image && image != this.__image)
|
||||||
{
|
{
|
||||||
this.image = image;
|
this.image = image;
|
||||||
}
|
}
|
||||||
|
@ -9,63 +9,59 @@
|
|||||||
* @copyright Nathan Gray 2017
|
* @copyright Nathan Gray 2017
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*egw:uses
|
import {et2_IInput} from "../et2_core_interfaces";
|
||||||
et2_button;
|
import {date} from "../lib/date.js";
|
||||||
*/
|
import {Et2Button} from "./Et2Button";
|
||||||
|
import {Et2Tabs} from "../Layout/Et2Tabs/Et2Tabs";
|
||||||
|
|
||||||
import {et2_register_widget, WidgetConfig} from "./et2_core_widget";
|
|
||||||
import {et2_button} from "./et2_widget_button";
|
|
||||||
import {ClassWithAttributes} from "./et2_core_inheritance";
|
|
||||||
import {et2_no_init} from "./et2_core_common";
|
|
||||||
import {egw} from "../jsapi/egw_global";
|
|
||||||
import {et2_IInput} from "./et2_core_interfaces";
|
|
||||||
import {date} from "./lib/date.js";
|
|
||||||
/**
|
/**
|
||||||
* Class which implements the "button-timestamper" XET-Tag
|
* Class which implements the "et2-button-timestamp" tag
|
||||||
*
|
*
|
||||||
* Clicking the button puts the current time and current user at the end of
|
* Clicking the button puts the current time and current user at the end of
|
||||||
* the provided field.
|
* the provided field.
|
||||||
*
|
|
||||||
* @augments et2_button
|
|
||||||
*/
|
*/
|
||||||
export class et2_timestamper extends et2_button
|
export class Et2ButtonTimestamper extends Et2Button
|
||||||
{
|
{
|
||||||
static readonly _attributes : any = {
|
static get properties()
|
||||||
target: {
|
|
||||||
name: "Target field",
|
|
||||||
type: "string",
|
|
||||||
default: et2_no_init,
|
|
||||||
description: "Which field to place the timestamp in"
|
|
||||||
},
|
|
||||||
format: {
|
|
||||||
name: "Time format",
|
|
||||||
type: "string",
|
|
||||||
default: et2_no_init,
|
|
||||||
description: "Format for the timestamp. User is always after."
|
|
||||||
},
|
|
||||||
timezone: {
|
|
||||||
name: "Timezone",
|
|
||||||
type: "string",
|
|
||||||
default: et2_no_init,
|
|
||||||
description: "Timezone. Default is user time."
|
|
||||||
},
|
|
||||||
statustext: {
|
|
||||||
default: "Insert timestamp into description field"
|
|
||||||
},
|
|
||||||
image: {
|
|
||||||
default: "timestamp"
|
|
||||||
},
|
|
||||||
background_image: {
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
target : string;
|
|
||||||
|
|
||||||
constructor(_parent, _attrs? : WidgetConfig, _child? : object)
|
|
||||||
{
|
{
|
||||||
// Call the inherited constructor
|
return {
|
||||||
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_timestamper._attributes, _child || {}));
|
...super.properties,
|
||||||
jQuery(this.getDOMNode()).addClass('et2_timestamper');
|
/**
|
||||||
|
* Which field to place the timestamp in
|
||||||
|
*/
|
||||||
|
target: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Format for the timestamp. User is always after.
|
||||||
|
*/
|
||||||
|
format: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Timezone. Default is user time.
|
||||||
|
*/
|
||||||
|
timezone: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Icon to use, default "timestamp"
|
||||||
|
*/
|
||||||
|
image: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(...args : any[])
|
||||||
|
{
|
||||||
|
super(...args);
|
||||||
|
|
||||||
|
// Property default values
|
||||||
|
this.image = 'timestamp';
|
||||||
|
this.noSubmit = true;
|
||||||
|
|
||||||
|
this.onclick = this.stamp.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,40 +70,21 @@ export class et2_timestamper extends et2_button
|
|||||||
* @param _ev
|
* @param _ev
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
click(_ev) {
|
stamp(event: MouseEvent): boolean
|
||||||
// ignore click on readonly button
|
{
|
||||||
if (this.options.readonly) return false;
|
const now = new Date(new Date().toLocaleString('en-US', {
|
||||||
|
timeZone: this.timezone || egw.preference('tz')
|
||||||
this._insert_text();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _insert_text() {
|
|
||||||
let text = "";
|
|
||||||
let now = new Date(new Date().toLocaleString('en-US', {
|
|
||||||
timeZone: this.options.timezone ? this.options.timezone : egw.preference('tz')
|
|
||||||
}));
|
}));
|
||||||
let format = (this.options.format ?
|
const format = this.format || egw.preference('dateformat') + ' ' + (egw.preference("timeformat") === "12" ? "h:ia" : "H:i")+' ';
|
||||||
this.options.format :
|
|
||||||
egw.preference('dateformat') + ' ' + (egw.preference("timeformat") === "12" ? "h:ia" : "H:i"))+' ';
|
|
||||||
|
|
||||||
text += date(format, now);
|
let text = date(format, now);
|
||||||
|
|
||||||
// Get properly formatted user name
|
// Get properly formatted user name
|
||||||
let user = parseInt(egw.user('account_id'));
|
const user = parseInt(egw.user('account_id'));
|
||||||
let accounts = egw.accounts('accounts');
|
const account = egw.accounts('accounts').filter(option => option.value == user)[0];
|
||||||
for(let j = 0; j < accounts.length; j++)
|
text += account.label + ': ';
|
||||||
{
|
|
||||||
if(accounts[j]["value"] === user)
|
|
||||||
{
|
|
||||||
text += accounts[j]["label"];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text += ': ';
|
|
||||||
|
|
||||||
let widget = this._get_input(this.target);
|
const widget = this._get_input(this.target);
|
||||||
let input = widget.input ? widget.input : widget.getDOMNode();
|
let input = widget.input ? widget.input : widget.getDOMNode();
|
||||||
if(input.context)
|
if(input.context)
|
||||||
{
|
{
|
||||||
@ -134,6 +111,14 @@ export class et2_timestamper extends et2_button
|
|||||||
pos = input.selectionStart;
|
pos = input.selectionStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If on a tab, switch to that tab so user can see it
|
||||||
|
let tabbox = widget;
|
||||||
|
while(tabbox._parent && tabbox.nodeName !== 'ET2-TABBOX')
|
||||||
|
{
|
||||||
|
tabbox = tabbox._parent;
|
||||||
|
}
|
||||||
|
if (tabbox.nodeName === 'ET2-TABBOX') (<Et2Tabs>tabbox).activateTab(widget);
|
||||||
|
|
||||||
// If tinymce, update it
|
// If tinymce, update it
|
||||||
if(tinymce)
|
if(tinymce)
|
||||||
{
|
{
|
||||||
@ -144,6 +129,11 @@ export class et2_timestamper extends et2_button
|
|||||||
// Insert the text
|
// Insert the text
|
||||||
let front = (input.value).substring(0, pos);
|
let front = (input.value).substring(0, pos);
|
||||||
let back = (input.value).substring(pos, input.value.length);
|
let back = (input.value).substring(pos, input.value.length);
|
||||||
|
// for webComponent, we need to set the component value too, otherwise the change is lost!
|
||||||
|
if (typeof widget.tagName !== 'undefined')
|
||||||
|
{
|
||||||
|
widget.value = front+text+back;
|
||||||
|
}
|
||||||
input.value = front+text+back;
|
input.value = front+text+back;
|
||||||
|
|
||||||
// Clean up a little
|
// Clean up a little
|
||||||
@ -164,13 +154,6 @@ export class et2_timestamper extends et2_button
|
|||||||
input.scrollTop = scrollPos;
|
input.scrollTop = scrollPos;
|
||||||
input.focus();
|
input.focus();
|
||||||
}
|
}
|
||||||
// If on a tab, switch to that tab so user can see it
|
|
||||||
let tab = widget;
|
|
||||||
while(tab._parent && tab._type != 'tabbox')
|
|
||||||
{
|
|
||||||
tab = tab._parent;
|
|
||||||
}
|
|
||||||
if (tab._type == 'tabbox') tab.activateTab(widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _get_input(target)
|
private _get_input(target)
|
||||||
@ -201,4 +184,6 @@ export class et2_timestamper extends et2_button
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
et2_register_widget(et2_timestamper, ["button-timestamp", "timestamper"]);
|
|
||||||
|
// @ts-ignore TypeScript is not recognizing that Et2Button is a LitElement
|
||||||
|
customElements.define("et2-button-timestamp", Et2ButtonTimestamper);
|
@ -393,6 +393,51 @@ export class Et2Tabs extends Et2Widget(SlTabGroup)
|
|||||||
{
|
{
|
||||||
this.setActiveTab(this._selectedIndex);
|
this.setActiveTab(this._selectedIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate the tab containing the given widget
|
||||||
|
*
|
||||||
|
* @param {et2_widget} widget
|
||||||
|
* @return {bool} widget was found in a tab
|
||||||
|
*/
|
||||||
|
activateTab(widget)
|
||||||
|
{
|
||||||
|
let tab = widget;
|
||||||
|
while(tab._parent && tab._parent.nodeName !== 'ET2-TABBOX')
|
||||||
|
{
|
||||||
|
tab = tab._parent;
|
||||||
|
}
|
||||||
|
if (tab.nodeName === 'ET2-TAB-PANEL')
|
||||||
|
{
|
||||||
|
this.show(tab.name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reimplement to allow our existing function signatures too
|
||||||
|
*
|
||||||
|
* @deprecated use this.show(name : string)
|
||||||
|
* @param tab number or name of tab (Sl uses that internally with a SlTab!)
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
setActiveTab(tab: SlTab|String|Number, options?: {
|
||||||
|
emitEvents?: boolean;
|
||||||
|
scrollBehavior?: 'auto' | 'smooth';
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if (typeof tab === 'number')
|
||||||
|
{
|
||||||
|
tab = this.getAllTabs()[tab];
|
||||||
|
return this.show(tab.panel);
|
||||||
|
}
|
||||||
|
if (typeof tab === 'string')
|
||||||
|
{
|
||||||
|
return this.show(tab);
|
||||||
|
}
|
||||||
|
return super.setActiveTab(<SlTab>tab, options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("et2-tabbox", Et2Tabs);
|
customElements.define("et2-tabbox", Et2Tabs);
|
@ -30,6 +30,7 @@ import './Layout/Et2Tabs/Et2Tabs';
|
|||||||
import './Layout/Et2Tabs/Et2TabPanel';
|
import './Layout/Et2Tabs/Et2TabPanel';
|
||||||
import './Et2Avatar/Et2Avatar';
|
import './Et2Avatar/Et2Avatar';
|
||||||
import './Et2Button/Et2Button';
|
import './Et2Button/Et2Button';
|
||||||
|
import './Et2Button/Et2ButtonTimestamper';
|
||||||
import './Et2Checkbox/Et2Checkbox';
|
import './Et2Checkbox/Et2Checkbox';
|
||||||
import './Et2Checkbox/Et2CheckboxReadonly';
|
import './Et2Checkbox/Et2CheckboxReadonly';
|
||||||
import './Et2Date/Et2Date';
|
import './Et2Date/Et2Date';
|
||||||
@ -121,7 +122,6 @@ import './et2_widget_html';
|
|||||||
import './et2_widget_htmlarea';
|
import './et2_widget_htmlarea';
|
||||||
import './et2_widget_tabs';
|
import './et2_widget_tabs';
|
||||||
import './et2_widget_taglist';
|
import './et2_widget_taglist';
|
||||||
import './et2_widget_timestamper';
|
|
||||||
import './et2_widget_toolbar';
|
import './et2_widget_toolbar';
|
||||||
import './et2_widget_tree';
|
import './et2_widget_tree';
|
||||||
import './et2_widget_historylog';
|
import './et2_widget_historylog';
|
||||||
|
@ -69,7 +69,9 @@ button.infologExtraButton:hover {
|
|||||||
|
|
||||||
.tab_toolbar {
|
.tab_toolbar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 6px;
|
||||||
|
right: 0;
|
||||||
|
z-index: 10000; /* otherwise et2-tabs gets our clicks! */
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab_toolbar > button, .tab_toolbar > et2-button {
|
.tab_toolbar > button, .tab_toolbar > et2-button {
|
||||||
|
@ -125,7 +125,10 @@ button.infologExtraButton:hover {
|
|||||||
}
|
}
|
||||||
.tab_toolbar {
|
.tab_toolbar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 6px;
|
||||||
|
right: 0;
|
||||||
|
z-index: 10000;
|
||||||
|
/* otherwise et2-tabs gets our clicks! */
|
||||||
}
|
}
|
||||||
.tab_toolbar > button,
|
.tab_toolbar > button,
|
||||||
.tab_toolbar > et2-button {
|
.tab_toolbar > et2-button {
|
||||||
|
Loading…
Reference in New Issue
Block a user