mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-03 04:29:28 +01:00
got LinkEntry mostly working
This commit is contained in:
parent
9b0e1b9206
commit
0aa813a0ff
@ -17,7 +17,7 @@ const ADD_ET2_PREFIX_REGEXP = '#<((/?)([vh]?box|date(-time[^\s]*|-duration|-sinc
|
|||||||
const ADD_ET2_PREFIX_LAST_GROUP = 6;
|
const ADD_ET2_PREFIX_LAST_GROUP = 6;
|
||||||
|
|
||||||
// unconditional of legacy add et2- prefix to this widgets
|
// unconditional of legacy add et2- prefix to this widgets
|
||||||
const ADD_ET2_PREFIX_LEGACY_REGEXP = '#<(description|label|image|vfs-mime|vfs-uid|vfs-gid|link|link-string|link-list|favorites)\s([^>]+)/>#m';
|
const ADD_ET2_PREFIX_LEGACY_REGEXP = '#<(description|label|image|vfs-mime|vfs-uid|vfs-gid|link|link-string|link-list|link-search|link-entry|link-apps|favorites)\s([^>]+)/>#m';
|
||||||
|
|
||||||
// switch evtl. set output-compression off, as we can't calculate a Content-Length header with transparent compression
|
// switch evtl. set output-compression off, as we can't calculate a Content-Length header with transparent compression
|
||||||
ini_set('zlib.output_compression', 0);
|
ini_set('zlib.output_compression', 0);
|
||||||
@ -67,6 +67,59 @@ function send_template()
|
|||||||
// fix <menulist...><menupopup type="select-*"/></menulist> --> <select type="select-*" .../>
|
// fix <menulist...><menupopup type="select-*"/></menulist> --> <select type="select-*" .../>
|
||||||
$str = preg_replace('#<menulist([^>]*)>[\r\n\s]*<menupopup([^>]+>)[\r\n\s]*</menulist>#', '<select$1$2', $str);
|
$str = preg_replace('#<menulist([^>]*)>[\r\n\s]*<menupopup([^>]+>)[\r\n\s]*</menulist>#', '<select$1$2', $str);
|
||||||
|
|
||||||
|
// fix legacy options, so new client-side has not to deal with them
|
||||||
|
$str = preg_replace_callback('#<([^- />]+)(-[^ ]+)?[^>]* (options="([^"]+)")[ />]#', static function ($matches) {
|
||||||
|
// take care of (static) type attribute, if used
|
||||||
|
if (preg_match('/ type="([a-z-]+)"/', $matches[0], $type))
|
||||||
|
{
|
||||||
|
str_replace('<' . $matches[1] . $matches[2], '<' . $type[1], $matches[0]);
|
||||||
|
str_replace($type[0], '', $matches[0]);
|
||||||
|
list($matches[1], $matches[2]) = explode('-', $type[1], 2);
|
||||||
|
}
|
||||||
|
static $legacy_options = array( // use "ignore" to ignore further comma-sep. values, otherwise they are all in last attribute
|
||||||
|
'select' => 'empty_label,ignore',
|
||||||
|
'select-account' => 'empty_label,account_type,ignore',
|
||||||
|
'box' => ',cellpadding,cellspacing,keep',
|
||||||
|
'hbox' => 'cellpadding,cellspacing,keep',
|
||||||
|
'vbox' => 'cellpadding,cellspacing,keep',
|
||||||
|
'groupbox' => 'cellpadding,cellspacing,keep',
|
||||||
|
'checkbox' => 'selected_value,unselected_value,ro_true,ro_false',
|
||||||
|
'radio' => 'set_value,ro_true,ro_false',
|
||||||
|
'customfields' => 'sub-type,use-private,field-names',
|
||||||
|
'date' => 'data_format,ignore', // Legacy option "mode" was never implemented in et2
|
||||||
|
'description' => 'bold-italic,link,activate_links,label_for,link_target,link_popup_size,link_title',
|
||||||
|
'button' => 'image,ro_image',
|
||||||
|
'buttononly' => 'image,ro_image',
|
||||||
|
'link-entry' => 'only_app,application_list',
|
||||||
|
);
|
||||||
|
// prefer more specific type-subtype over just type
|
||||||
|
$names = $legacy_options[$matches[1] . $matches[2]] ?? $legacy_options[$matches[1]] ?? null;
|
||||||
|
if (isset($names))
|
||||||
|
{
|
||||||
|
$names = explode(',', $names);
|
||||||
|
$values = Api\Etemplate\Widget::csv_split($matches[4], count($names));
|
||||||
|
if (count($values) < count($names))
|
||||||
|
{
|
||||||
|
$values = array_merge($values, array_fill(count($values), count($names) - count($values), ''));
|
||||||
|
}
|
||||||
|
$attrs = array_diff(array_combine($names, $values), ['', null]);
|
||||||
|
unset($attrs['ignore']);
|
||||||
|
// fix select options can be either multiple or empty_label
|
||||||
|
if ($matches[1] === 'select' && !empty($attrs['empty_label']) && (int)$attrs['empty_label'] > 0)
|
||||||
|
{
|
||||||
|
$attrs['multiple'] = (int)$attrs['empty_label'];
|
||||||
|
unset($matches['empty_label']);
|
||||||
|
}
|
||||||
|
$options = '';
|
||||||
|
foreach ($attrs as $attr => $value)
|
||||||
|
{
|
||||||
|
$options .= $attr . '="' . $value . '" ';
|
||||||
|
}
|
||||||
|
return str_replace($matches[3], $options, $matches[0]);
|
||||||
|
}
|
||||||
|
return $matches[0];
|
||||||
|
}, $str);
|
||||||
|
|
||||||
// Change splitter dockside -> primary + vertical
|
// Change splitter dockside -> primary + vertical
|
||||||
$str = preg_replace_callback('#<split([^>]*?)>(.*)</split>#su', static function ($matches) use ($name) {
|
$str = preg_replace_callback('#<split([^>]*?)>(.*)</split>#su', static function ($matches) use ($name) {
|
||||||
$tag = 'et2-split';
|
$tag = 'et2-split';
|
||||||
@ -110,58 +163,6 @@ function send_template()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// fix legacy options, so new client-side has not to deal with them
|
|
||||||
$str = preg_replace_callback('#<([^- />]+)(-[^ ]+)?[^>]* (options="([^"]+)")[ />]#', static function ($matches) {
|
|
||||||
// take care of (static) type attribute, if used
|
|
||||||
if (preg_match('/ type="([a-z-]+)"/', $matches[0], $type))
|
|
||||||
{
|
|
||||||
str_replace('<' . $matches[1] . $matches[2], '<' . $type[1], $matches[0]);
|
|
||||||
str_replace($type[0], '', $matches[0]);
|
|
||||||
list($matches[1], $matches[2]) = explode('-', $type[1], 2);
|
|
||||||
}
|
|
||||||
static $legacy_options = array( // use "ignore" to ignore further comma-sep. values, otherwise they are all in last attribute
|
|
||||||
'select' => 'empty_label,ignore',
|
|
||||||
'select-account' => 'empty_label,account_type,ignore',
|
|
||||||
'box' => ',cellpadding,cellspacing,keep',
|
|
||||||
'hbox' => 'cellpadding,cellspacing,keep',
|
|
||||||
'vbox' => 'cellpadding,cellspacing,keep',
|
|
||||||
'groupbox' => 'cellpadding,cellspacing,keep',
|
|
||||||
'checkbox' => 'selected_value,unselected_value,ro_true,ro_false',
|
|
||||||
'radio' => 'set_value,ro_true,ro_false',
|
|
||||||
'customfields' => 'sub-type,use-private,field-names',
|
|
||||||
'date' => 'data_format,ignore', // Legacy option "mode" was never implemented in et2
|
|
||||||
'description' => 'bold-italic,link,activate_links,label_for,link_target,link_popup_size,link_title',
|
|
||||||
'button' => 'image,ro_image',
|
|
||||||
'buttononly' => 'image,ro_image',
|
|
||||||
);
|
|
||||||
// prefer more specific type-subtype over just type
|
|
||||||
$names = $legacy_options[$matches[1] . $matches[2]] ?? $legacy_options[$matches[1]] ?? null;
|
|
||||||
if (isset($names))
|
|
||||||
{
|
|
||||||
$names = explode(',', $names);
|
|
||||||
$values = Api\Etemplate\Widget::csv_split($matches[4], count($names));
|
|
||||||
if (count($values) < count($names))
|
|
||||||
{
|
|
||||||
$values = array_merge($values, array_fill(count($values), count($names) - count($values), ''));
|
|
||||||
}
|
|
||||||
$attrs = array_diff(array_combine($names, $values), ['', null]);
|
|
||||||
unset($attrs['ignore']);
|
|
||||||
// fix select options can be either multiple or empty_label
|
|
||||||
if ($matches[1] === 'select' && !empty($attrs['empty_label']) && (int)$attrs['empty_label'] > 0)
|
|
||||||
{
|
|
||||||
$attrs['multiple'] = (int)$attrs['empty_label'];
|
|
||||||
unset($matches['empty_label']);
|
|
||||||
}
|
|
||||||
$options = '';
|
|
||||||
foreach ($attrs as $attr => $value)
|
|
||||||
{
|
|
||||||
$options .= $attr . '="' . $value . '" ';
|
|
||||||
}
|
|
||||||
return str_replace($matches[3], $options, $matches[0]);
|
|
||||||
}
|
|
||||||
return $matches[0];
|
|
||||||
}, $str);
|
|
||||||
|
|
||||||
// fix deprecated attributes: needed, blur, ...
|
// fix deprecated attributes: needed, blur, ...
|
||||||
static $deprecated = [
|
static $deprecated = [
|
||||||
'needed' => 'required',
|
'needed' => 'required',
|
||||||
|
@ -71,8 +71,8 @@ export class Et2LinkAppSelect extends SlotMixin(Et2Select)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __app_icons : boolean;
|
|
||||||
protected __application_list : string[];
|
protected __application_list : string[];
|
||||||
|
protected __only_app : string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -91,6 +91,17 @@ export class Et2LinkAppSelect extends SlotMixin(Et2Select)
|
|||||||
this._handleChange = this._handleChange.bind(this);
|
this._handleChange = this._handleChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set only_app(app : string)
|
||||||
|
{
|
||||||
|
this.__only_app = app;
|
||||||
|
this.style.display = app ? 'inline' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
get only_app() : string
|
||||||
|
{
|
||||||
|
return this.__only_app;
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback()
|
connectedCallback()
|
||||||
{
|
{
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@ -108,6 +119,8 @@ export class Et2LinkAppSelect extends SlotMixin(Et2Select)
|
|||||||
|
|
||||||
// Register to
|
// Register to
|
||||||
this.addEventListener("change", this._handleChange);
|
this.addEventListener("change", this._handleChange);
|
||||||
|
|
||||||
|
if (this.__only_app) this.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback()
|
disconnectedCallback()
|
||||||
|
@ -4,6 +4,12 @@ import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
|||||||
import {FormControlMixin, ValidateMixin} from "@lion/form-core";
|
import {FormControlMixin, ValidateMixin} from "@lion/form-core";
|
||||||
import {Et2LinkSearch} from "./Et2LinkSearch";
|
import {Et2LinkSearch} from "./Et2LinkSearch";
|
||||||
|
|
||||||
|
export interface LinkEntry {
|
||||||
|
app: string;
|
||||||
|
id: string|number;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EGroupware eTemplate2 - Search & select link entry WebComponent
|
* EGroupware eTemplate2 - Search & select link entry WebComponent
|
||||||
*
|
*
|
||||||
@ -62,12 +68,24 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
|||||||
...super.slots,
|
...super.slots,
|
||||||
app: () =>
|
app: () =>
|
||||||
{
|
{
|
||||||
const app = document.createElement("et2-link-apps")
|
const app = <Et2LinkAppSelect>document.createElement("et2-link-apps")
|
||||||
|
app.only_app = this.__only_app;
|
||||||
return app;
|
return app;
|
||||||
},
|
},
|
||||||
select: () =>
|
select: () =>
|
||||||
{
|
{
|
||||||
const select = <Et2LinkSearch><unknown>document.createElement("et2-link-search");
|
const select = <Et2LinkSearch><unknown>document.createElement("et2-link-search");
|
||||||
|
select.app = this.__only_app || this.__app;
|
||||||
|
if (this.__value && typeof this.__value === 'object')
|
||||||
|
{
|
||||||
|
select.app = this.__value.app;
|
||||||
|
select.select_options = [{value: this.__value.id, label: this.__value.title}];
|
||||||
|
select.value = this.__value.id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
select.value = this.__value;
|
||||||
|
}
|
||||||
return select;
|
return select;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,15 +103,31 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
|||||||
this._handleAppChange = this._handleAppChange.bind(this);
|
this._handleAppChange = this._handleAppChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected __only_app : string;
|
||||||
|
protected __app : string;
|
||||||
|
|
||||||
set only_app(app)
|
set only_app(app)
|
||||||
{
|
{
|
||||||
this._appNode.only_app = app;
|
this.__only_app = app;
|
||||||
this._searchNode.app = app;
|
if (this._appNode) this._appNode.only_app = app;
|
||||||
|
if (this._searchNode) this._searchNode.app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
get only_app()
|
get only_app()
|
||||||
{
|
{
|
||||||
return this._appNode.only_app;
|
return this.__only_app;
|
||||||
|
}
|
||||||
|
|
||||||
|
set app(app)
|
||||||
|
{
|
||||||
|
this.__app = app;
|
||||||
|
if (this._appNode) this._appNode.value = app;
|
||||||
|
if (this._searchNode) this._searchNode.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
get app()
|
||||||
|
{
|
||||||
|
return this._appNode?.value || this.__app;
|
||||||
}
|
}
|
||||||
|
|
||||||
get _appNode() : Et2LinkAppSelect
|
get _appNode() : Et2LinkAppSelect
|
||||||
@ -122,6 +156,49 @@ export class Et2LinkEntry extends Et2InputWidget(FormControlMixin(ValidateMixin(
|
|||||||
this._searchNode.app = this._appNode.value;
|
this._searchNode.app = this._appNode.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected __value : LinkEntry|string|number;
|
||||||
|
|
||||||
|
get value() : LinkEntry|string|number
|
||||||
|
{
|
||||||
|
if (this.only_app)
|
||||||
|
{
|
||||||
|
return this._searchNode?.value || this.__value;
|
||||||
|
}
|
||||||
|
return this._searchNode ? {
|
||||||
|
id: this._searchNode?.value || this.__value,
|
||||||
|
app: this._appNode?.value || this.__onlyApp || this.__app,
|
||||||
|
//search: this._searchNode... // content of search field
|
||||||
|
} : this.__value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(val: LinkEntry|string|number)
|
||||||
|
{
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
if (this._searchNode) this._searchNode.value = '';
|
||||||
|
}
|
||||||
|
else if (typeof val === 'string')
|
||||||
|
{
|
||||||
|
if (val.indexOf(',') > 0) val = val.replace(",", ":");
|
||||||
|
const vals = val.split(':');
|
||||||
|
this.app = vals[0];
|
||||||
|
if (this._searchNode)
|
||||||
|
{
|
||||||
|
this._searchNode.value = vals[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // object with attributes: app, id, title
|
||||||
|
{
|
||||||
|
this.app = val.app;
|
||||||
|
if (this._searchNode)
|
||||||
|
{
|
||||||
|
this._searchNode.value = val.id;
|
||||||
|
this._searchNode.select_options = [{value: val.id, label: val.title}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.__value = val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {TemplateResult}
|
* @return {TemplateResult}
|
||||||
* @protected
|
* @protected
|
||||||
|
@ -61,9 +61,16 @@ export class Et2LinkSearch extends Et2Select
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ToDo use egw.request(), not old egw.json()
|
||||||
request.sendRequest().then((result) =>
|
request.sendRequest().then((result) =>
|
||||||
{
|
{
|
||||||
this.processRemoteResults(result);
|
result.response.forEach((response) =>
|
||||||
|
{
|
||||||
|
if (typeof response.data !== 'undefined')
|
||||||
|
{
|
||||||
|
this.processRemoteResults(response.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,13 @@ export const Et2widgetWithSelectMixin = dedupeMixin((superclass) =>
|
|||||||
let fixed_options = [];
|
let fixed_options = [];
|
||||||
for(let key in <any>new_options)
|
for(let key in <any>new_options)
|
||||||
{
|
{
|
||||||
fixed_options.push({value: key, label: new_options[key]});
|
let option : any = new_options[key];
|
||||||
|
if (typeof option === 'string')
|
||||||
|
{
|
||||||
|
option = { label: option };
|
||||||
|
}
|
||||||
|
option.value = key.trim(); // link_search prefixes keys with one space
|
||||||
|
fixed_options.push(option);
|
||||||
}
|
}
|
||||||
this.__select_options = fixed_options;
|
this.__select_options = fixed_options;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ export const Et2WithSearchMixin = dedupeMixin((superclass) =>
|
|||||||
if(this.getItems().length === 1)
|
if(this.getItems().length === 1)
|
||||||
{
|
{
|
||||||
this.getItems()[0].click();
|
this.getItems()[0].click();
|
||||||
this.hide();
|
// not jQuery this.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -379,7 +379,7 @@ export const Et2WithSearchMixin = dedupeMixin((superclass) =>
|
|||||||
|
|
||||||
protected remoteQuery(search : string, options : object)
|
protected remoteQuery(search : string, options : object)
|
||||||
{
|
{
|
||||||
return this.egw().json(this.searchUrl, [search]).sendRequest().then((result) =>
|
return this.egw().request(this.searchUrl, [search]).sendRequest().then((result) =>
|
||||||
{
|
{
|
||||||
this.processRemoteResults(result);
|
this.processRemoteResults(result);
|
||||||
});
|
});
|
||||||
@ -392,7 +392,7 @@ export const Et2WithSearchMixin = dedupeMixin((superclass) =>
|
|||||||
*/
|
*/
|
||||||
protected processRemoteResults(results)
|
protected processRemoteResults(results)
|
||||||
{
|
{
|
||||||
// TODO: Add the results in
|
this.select_options = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -441,4 +441,4 @@ export const Et2WithSearchMixin = dedupeMixin((superclass) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Et2WidgetWithSearch as Constructor<SearchMixinInterface> & T & LitElement;
|
return Et2WidgetWithSearch as Constructor<SearchMixinInterface> & T & LitElement;
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user