mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
* Collabora: Add address insert dialog
This commit is contained in:
parent
15a2e546ea
commit
d512238dc0
@ -36,6 +36,11 @@ export class et2_placeholder_select extends et2_inputWidget
|
|||||||
"name": "Insert callback",
|
"name": "Insert callback",
|
||||||
"description": "Method called with the selected placeholder text",
|
"description": "Method called with the selected placeholder text",
|
||||||
"type": "js"
|
"type": "js"
|
||||||
|
},
|
||||||
|
dialog_title: {
|
||||||
|
"name": "Dialog title",
|
||||||
|
"type": "string",
|
||||||
|
"default": "Insert Placeholder"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,7 +104,7 @@ export class et2_placeholder_select extends et2_inputWidget
|
|||||||
*
|
*
|
||||||
* @param {object} _data content
|
* @param {object} _data content
|
||||||
*/
|
*/
|
||||||
private _buildDialog(_data)
|
protected _buildDialog(_data)
|
||||||
{
|
{
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
@ -149,7 +154,7 @@ export class et2_placeholder_select extends et2_inputWidget
|
|||||||
{
|
{
|
||||||
if((submit_button_id == 'submit' || (extra_buttons_action && extra_buttons_action[submit_button_id])) && submit_value)
|
if((submit_button_id == 'submit' || (extra_buttons_action && extra_buttons_action[submit_button_id])) && submit_value)
|
||||||
{
|
{
|
||||||
this.options.insert_callback(submit_value.placeholder_list);
|
this._do_insert_callback(submit_value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
@ -238,6 +243,7 @@ export class et2_placeholder_select extends et2_inputWidget
|
|||||||
let preview_content = <et2_description>this.dialog.template.widgetContainer.getDOMWidgetById("preview_content");
|
let preview_content = <et2_description>this.dialog.template.widgetContainer.getDOMWidgetById("preview_content");
|
||||||
|
|
||||||
// Show the selected placeholder
|
// Show the selected placeholder
|
||||||
|
this.set_value(placeholder_list.get_value());
|
||||||
preview.set_value(placeholder_list.get_value());
|
preview.set_value(placeholder_list.get_value());
|
||||||
preview.getDOMNode().parentNode.style.visibility = placeholder_list.get_value().trim() ? null : 'hidden';
|
preview.getDOMNode().parentNode.style.visibility = placeholder_list.get_value().trim() ? null : 'hidden';
|
||||||
|
|
||||||
@ -301,6 +307,16 @@ export class et2_placeholder_select extends et2_inputWidget
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the correct insert text call the insert callback with it
|
||||||
|
*
|
||||||
|
* @param dialog_values
|
||||||
|
*/
|
||||||
|
_do_insert_callback(dialog_values : Object)
|
||||||
|
{
|
||||||
|
this.options.insert_callback(this.get_value());
|
||||||
|
}
|
||||||
|
|
||||||
set_value(value)
|
set_value(value)
|
||||||
{
|
{
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@ -313,3 +329,160 @@ export class et2_placeholder_select extends et2_inputWidget
|
|||||||
};
|
};
|
||||||
et2_register_widget(et2_placeholder_select, ["placeholder-select"]);
|
et2_register_widget(et2_placeholder_select, ["placeholder-select"]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a dialog to choose from a set list of placeholder snippets
|
||||||
|
*/
|
||||||
|
export class et2_placeholder_snippet_select extends et2_placeholder_select
|
||||||
|
{
|
||||||
|
static readonly _attributes : any = {
|
||||||
|
dialog_title: {
|
||||||
|
"default": "Insert address"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static placeholders = {
|
||||||
|
"addressbook": {
|
||||||
|
"addresses": {
|
||||||
|
"{{n_fn}}\n{{adr_one_street}}{{NELF adr_one_street2}}\n{{adr_one_formatted}}": "Work address",
|
||||||
|
"{{n_fn}}\n{{adr_two_street}}{{NELF adr_two_street2}}\n{{adr_two_formatted}}": "Home address",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
button : JQuery;
|
||||||
|
submit_callback : any;
|
||||||
|
dialog : et2_dialog;
|
||||||
|
protected value : any;
|
||||||
|
|
||||||
|
protected LIST_URL = 'EGroupware\\Api\\Etemplate\\Widget\\Placeholder::ajax_get_placeholders';
|
||||||
|
protected TEMPLATE = '/api/templates/default/placeholder_snippet.xet?1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post-load of the dialog
|
||||||
|
* Bind internal events, set some things that are difficult to do in the template
|
||||||
|
*/
|
||||||
|
_on_template_load()
|
||||||
|
{
|
||||||
|
let app = <et2_selectbox>this.dialog.template.widgetContainer.getDOMWidgetById("app");
|
||||||
|
let placeholder_list = <et2_selectbox>this.dialog.template.widgetContainer.getDOMWidgetById("placeholder_list");
|
||||||
|
let preview = <et2_description>this.dialog.template.widgetContainer.getDOMWidgetById("preview_content");
|
||||||
|
let entry = <et2_link_entry>this.dialog.template.widgetContainer.getDOMWidgetById("entry");
|
||||||
|
|
||||||
|
|
||||||
|
placeholder_list.set_select_options(this._get_placeholders("addressbook", "addresses"));
|
||||||
|
|
||||||
|
// Further setup / styling that can't be done in etemplate
|
||||||
|
app.getInputNode().setAttribute("readonly", true);
|
||||||
|
this.dialog.template.DOMContainer.style.display = "flex";
|
||||||
|
this.dialog.template.DOMContainer.firstChild.style.display = "flex";
|
||||||
|
placeholder_list.getDOMNode().size = 5;
|
||||||
|
|
||||||
|
// Bind some handlers
|
||||||
|
app.onchange = (node, widget) =>
|
||||||
|
{
|
||||||
|
entry.set_value({app: widget.get_value()});
|
||||||
|
placeholder_list.set_select_options(this._get_placeholders(app.get_value(), "addresses"));
|
||||||
|
}
|
||||||
|
placeholder_list.onchange = this._on_placeholder_select.bind(this);
|
||||||
|
entry.onchange = this._on_placeholder_select.bind(this);
|
||||||
|
|
||||||
|
this._on_placeholder_select();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User has selected a placeholder
|
||||||
|
* Update the UI, and if they have an entry selected do the replacement and show that.
|
||||||
|
*/
|
||||||
|
_on_placeholder_select()
|
||||||
|
{
|
||||||
|
let app = <et2_link_entry>this.dialog.template.widgetContainer.getDOMWidgetById("app");
|
||||||
|
let entry = <et2_link_entry>this.dialog.template.widgetContainer.getDOMWidgetById("entry");
|
||||||
|
let placeholder_list = <et2_selectbox>this.dialog.template.widgetContainer.getDOMWidgetById("placeholder_list");
|
||||||
|
let preview = <et2_description>this.dialog.template.widgetContainer.getDOMWidgetById("preview_placeholder");
|
||||||
|
let preview_content = <et2_description>this.dialog.template.widgetContainer.getDOMWidgetById("preview_content");
|
||||||
|
|
||||||
|
if(placeholder_list.get_value() && entry.get_value())
|
||||||
|
{
|
||||||
|
// Show the selected placeholder replaced with value from the selected entry
|
||||||
|
this.egw().json(
|
||||||
|
'EGroupware\\Api\\Etemplate\\Widget\\Placeholder::ajax_fill_placeholders',
|
||||||
|
[app.get_value(), placeholder_list.get_value(), entry.get_value()],
|
||||||
|
function(_content)
|
||||||
|
{
|
||||||
|
this.set_value(_content);
|
||||||
|
preview_content.set_value(_content);
|
||||||
|
preview_content.getDOMNode().parentNode.style.visibility = _content.trim() ? null : 'hidden';
|
||||||
|
}.bind(this)
|
||||||
|
).sendRequest(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No value, hide the row
|
||||||
|
preview_content.getDOMNode().parentNode.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
if(!entry.get_value())
|
||||||
|
{
|
||||||
|
entry.search.get(0).focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of placeholder groups under the selected application
|
||||||
|
* @param appname
|
||||||
|
* @returns {value:string, label:string}[]
|
||||||
|
*/
|
||||||
|
_get_group_options(appname : string)
|
||||||
|
{
|
||||||
|
let options = [];
|
||||||
|
Object.keys(et2_placeholder_select.placeholders[appname]).map((key) =>
|
||||||
|
{
|
||||||
|
options.push(
|
||||||
|
{
|
||||||
|
value: key,
|
||||||
|
label: this.egw().lang(key)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of placeholders under the given application + group
|
||||||
|
*
|
||||||
|
* @param appname
|
||||||
|
* @param group
|
||||||
|
* @returns {value:string, label:string}[]
|
||||||
|
*/
|
||||||
|
_get_placeholders(appname : string, group : string)
|
||||||
|
{
|
||||||
|
let options = [];
|
||||||
|
Object.keys(et2_placeholder_snippet_select.placeholders[appname][group]).map((key) =>
|
||||||
|
{
|
||||||
|
options.push(
|
||||||
|
{
|
||||||
|
value: key,
|
||||||
|
label: et2_placeholder_snippet_select.placeholders[appname][group][key]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the correct insert text call the insert callback with it
|
||||||
|
*
|
||||||
|
* @param dialog_values
|
||||||
|
*/
|
||||||
|
_do_insert_callback(dialog_values : Object)
|
||||||
|
{
|
||||||
|
this.options.insert_callback(this.get_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
set_value(value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
et2_register_widget(et2_placeholder_snippet_select, ["placeholder-snippet"]);
|
||||||
|
@ -309,6 +309,10 @@ class Merge extends Api\Storage\Merge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Correctly formatted address by country / preference
|
||||||
|
$placeholders['business']["{{adr_one_formatted}}"] = "Formatted business address";
|
||||||
|
$placeholders['private']["{{adr_two_formatted}}"] = "Formatted private address";
|
||||||
|
|
||||||
$group = 'customfields';
|
$group = 'customfields';
|
||||||
foreach($this->contacts->customfields as $name => $field)
|
foreach($this->contacts->customfields as $name => $field)
|
||||||
{
|
{
|
||||||
|
@ -283,22 +283,43 @@ abstract class Merge
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'account_id':
|
case 'account_id':
|
||||||
if ($value)
|
if($value)
|
||||||
{
|
{
|
||||||
$replacements['$$'.($prefix ? $prefix.'/':'').'account_lid$$'] = $GLOBALS['egw']->accounts->id2name($value);
|
$replacements['$$' . ($prefix ? $prefix . '/' : '') . 'account_lid$$'] = $GLOBALS['egw']->accounts->id2name($value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($name != 'photo') $replacements['$$'.($prefix ? $prefix.'/':'').$name.'$$'] = $value;
|
if($name != 'photo')
|
||||||
|
{
|
||||||
|
$replacements['$$' . ($prefix ? $prefix . '/' : '') . $name . '$$'] = $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Formatted address, according to preference or country
|
||||||
|
foreach(['one', 'two'] as $adr)
|
||||||
|
{
|
||||||
|
switch($this->contacts->addr_format_by_country($contact["adr_{$adr}_countryname"]))
|
||||||
|
{
|
||||||
|
case 'city_state_postcode':
|
||||||
|
$formatted_placeholder = $contact["adr_{$adr}_locality"] . " " .
|
||||||
|
$contact["adr_{$adr}_region"] . " " . $contact["adr_{$adr}_postalcode"];
|
||||||
|
break;
|
||||||
|
case 'postcode_city':
|
||||||
|
default:
|
||||||
|
$formatted_placeholder = $contact["adr_{$adr}_postalcode"] . ' ' . $contact["adr_{$adr}_locality"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$replacements['$$adr_' . $adr . '_formatted$$'] = $formatted_placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
// set custom fields, should probably go to a general method all apps can use
|
// set custom fields, should probably go to a general method all apps can use
|
||||||
// need to load all cfs for $ignore_acl=true
|
// need to load all cfs for $ignore_acl=true
|
||||||
foreach($ignore_acl ? Customfields::get('addressbook', true) : $this->contacts->customfields as $name => $field)
|
foreach($ignore_acl ? Customfields::get('addressbook', true) : $this->contacts->customfields as $name => $field)
|
||||||
{
|
{
|
||||||
$name = '#'.$name;
|
$name = '#' . $name;
|
||||||
if(!array_key_exists($name, $contact) || !$contact[$name])
|
if(!array_key_exists($name, $contact) || !$contact[$name])
|
||||||
{
|
{
|
||||||
$replacements['$$'.($prefix ? $prefix.'/':'').$name.'$$'] = '';
|
$replacements['$$' . ($prefix ? $prefix . '/' : '') . $name . '$$'] = '';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Format date cfs per user Api\Preferences
|
// Format date cfs per user Api\Preferences
|
||||||
|
72
api/templates/default/placeholder_snippet.xet
Normal file
72
api/templates/default/placeholder_snippet.xet
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
|
||||||
|
<!-- $Id$ -->
|
||||||
|
<overlay>
|
||||||
|
<template id="etemplate.placeholder_snippet" template="" lang="" group="0" version="21.1.001">
|
||||||
|
<vbox id="outer_box">
|
||||||
|
<vbox id="selects">
|
||||||
|
<select id="app"/>
|
||||||
|
<select id="placeholder_list"/>
|
||||||
|
</vbox>
|
||||||
|
<hrule/>
|
||||||
|
<link-entry id="entry" label="Select entry"/>
|
||||||
|
<hbox class="preview">
|
||||||
|
<description id="preview_content"/>
|
||||||
|
</hbox>
|
||||||
|
</vbox>
|
||||||
|
<styles>
|
||||||
|
|
||||||
|
#api\.insert_merge_placeholder_outer_box > #api\.insert_merge_placeholder_selects {
|
||||||
|
flex: 1 1 50%;
|
||||||
|
}
|
||||||
|
#api\.insert_merge_placeholder_outer_box > label.et2_label {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
#api\.insert_merge_placeholder_outer_box .preview {
|
||||||
|
flex: 1 1 50%;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
select#api\.insert_merge_placeholder_app {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
.ui-dialog-content, div.et2_box_widget, div.et2_box_widget > div.et2_box_widget {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
div.et2_hbox {
|
||||||
|
flex-direction: row;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
div.et2_vbox {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
div.et2_box_widget > * {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
div.et2_link_entry {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
div.et2_link_entry input.ui-autocomplete-input {
|
||||||
|
width: 75%
|
||||||
|
}
|
||||||
|
div.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button, button#cancel, .et2_button {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
div.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover, button#cancel:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
}
|
||||||
|
.preview .et2_button {
|
||||||
|
flex: 0 1 24px;
|
||||||
|
height: 24px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
</styles>
|
||||||
|
</template>
|
||||||
|
</overlay>
|
Loading…
Reference in New Issue
Block a user