mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-03-13 15:48:17 +01:00
WIP address-selection for mail-compose with all filters from addressbook.index
This commit is contained in:
parent
054b33121e
commit
bd84b18b7e
@ -198,7 +198,7 @@ class addressbook_ui extends addressbook_bo
|
||||
}
|
||||
$typeselection = $_content['nm']['col_filter']['tid'];
|
||||
}
|
||||
elseif($_GET['add_list'])
|
||||
elseif(!empty($_GET['add_list']))
|
||||
{
|
||||
$list = $this->add_list($_GET['add_list'],$_GET['owner']?$_GET['owner']:$this->user);
|
||||
if ($list === true)
|
||||
@ -214,6 +214,10 @@ class addressbook_ui extends addressbook_bo
|
||||
$msg = lang('List creation failed, no rights!');
|
||||
}
|
||||
}
|
||||
elseif (!empty($_GET['template']) && $this->tmpl->read($_GET['template']))
|
||||
{
|
||||
$template = $_GET['template'];
|
||||
}
|
||||
$preserv = array();
|
||||
$content = array();
|
||||
if($msg || $_GET['msg'])
|
||||
@ -221,7 +225,7 @@ class addressbook_ui extends addressbook_bo
|
||||
Framework::message($msg ? $msg : $_GET['msg']);
|
||||
}
|
||||
|
||||
$content['nm'] = Api\Cache::getSession('addressbook', 'index');
|
||||
$content['nm'] = Api\Cache::getSession('addressbook', str_replace('addressbook.', '', $template ?? 'index'));
|
||||
if (!is_array($content['nm']))
|
||||
{
|
||||
$content['nm'] = array(
|
||||
@ -230,7 +234,8 @@ class addressbook_ui extends addressbook_bo
|
||||
'never_hide' => True, // I never hide the nextmatch-line if less then maxmatch entrie
|
||||
'start' => 0, // IO position in list
|
||||
'cat_id' => '', // IO category, if not 'no_cat' => True
|
||||
'search' => '', // IO search pattern
|
||||
'search' => ($template ?? 'addressbook.index') === 'addressbook.select' ? '@' : '', // IO search pattern
|
||||
'main-template' => $template ?? 'addressbook.index', // do NOT use "template"!
|
||||
'order' => 'n_family', // IO name of the column to sort after (optional for the sortheaders)
|
||||
'sort' => 'ASC', // IO direction of the sort: 'ASC' or 'DESC'
|
||||
'col_filter' => array(), // IO array of column-name value pairs (optional for the filterheaders)
|
||||
@ -244,11 +249,15 @@ class addressbook_ui extends addressbook_bo
|
||||
'filter2_no_lang'=> True, // I set no_lang for filter2 (=dont translate the options)
|
||||
'lettersearch' => true,
|
||||
// using a positiv list now, as we constantly adding new columns in addressbook, but not removing them from default
|
||||
'default_cols' => 'type,n_fileas_n_given_n_family_n_family_n_given_org_name_n_family_n_given_n_fileas,'.
|
||||
'default_cols' => !isset($template) ? 'type,n_fileas_n_given_n_family_n_family_n_given_org_name_n_family_n_given_n_fileas,'.
|
||||
'number,org_name,org_unit,'.
|
||||
'business_adr_one_countrycode_adr_one_postalcode,tel_work_tel_cell_tel_home,url_email_email_home',
|
||||
'business_adr_one_countrycode_adr_one_postalcode,tel_work_tel_cell_tel_home,url_email_email_home' :
|
||||
'!photo,home_adr_two_countrycode_adr_two_postalcode',
|
||||
/* old negative list
|
||||
'default_cols' => '!cat_id,contact_created_contact_modified,distribution_list,contact_id,owner,room',*/
|
||||
//'no_columnselection' => false, // I turns off the columnselection completly, turned on by default
|
||||
// I name of the preference (plus 'nextmatch-' prefix), default = template-name
|
||||
'columnselection_pref' => isset($template) ? 'nextmatch-'.$template : null,
|
||||
'filter2_onchange' => "return app.addressbook.filter2_onchange();",
|
||||
'filter2_tags' => true,
|
||||
//'actions' => $this->get_actions(), // set on each request, as it depends on some filters
|
||||
@ -261,7 +270,7 @@ class addressbook_ui extends addressbook_bo
|
||||
);
|
||||
|
||||
// use the state of the last session stored in the user prefs
|
||||
if (($state = @unserialize($this->prefs['index_state'])))
|
||||
if (($state = @unserialize($this->prefs[str_replace('addressbook.', '', $template ?? 'index').'_state'], ['allowed_classes' => false])))
|
||||
{
|
||||
$content['nm'] = array_merge($content['nm'],$state);
|
||||
}
|
||||
@ -300,8 +309,8 @@ class addressbook_ui extends addressbook_bo
|
||||
$sel_options['filter2']['add'] = lang('Add a new list').'...'; // put it at the end
|
||||
}
|
||||
|
||||
// Organisation stuff is not (yet) availible with ldap
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] != 'ldap' && Api\Header\UserAgent::mobile() == '')
|
||||
// Organisation stuff is not (yet) available with ldap
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] != 'ldap' && Api\Header\UserAgent::mobile() == '' && empty($_GET['template']))
|
||||
{
|
||||
$content['nm']['header_left'] = 'addressbook.index.left';
|
||||
}
|
||||
@ -347,6 +356,14 @@ class addressbook_ui extends addressbook_bo
|
||||
}
|
||||
|
||||
$content['nm']['actions'] = $this->get_actions($content['nm']['col_filter']['tid']);
|
||||
// only use a small subset of the full actions
|
||||
if (($template ?? null) === 'addressbook.select')
|
||||
{
|
||||
$content['nm']['actions'] = array_filter($content['nm']['actions'], static function($action)
|
||||
{
|
||||
return in_array($action, ['open', 'email', 'delete']);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
}
|
||||
|
||||
if (!isset($sel_options['grouped_view'][(string) $content['nm']['grouped_view']]))
|
||||
{
|
||||
@ -365,9 +382,12 @@ class addressbook_ui extends addressbook_bo
|
||||
'shared' => lang('shared'),
|
||||
];
|
||||
|
||||
if (!isset($template))
|
||||
{
|
||||
$this->tmpl->read('addressbook.index');
|
||||
}
|
||||
return $this->tmpl->exec('addressbook.addressbook_ui.index',
|
||||
$content,$sel_options,array(),$preserv);
|
||||
$content, $sel_options, array(), $preserv, empty($_GET['template']) ? 0 : 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1711,7 +1731,7 @@ class addressbook_ui extends addressbook_bo
|
||||
*/
|
||||
function get_rows(&$query,&$rows,&$readonlys,$id_only=false)
|
||||
{
|
||||
$what = $query['sitemgr_display'] ? $query['sitemgr_display'] : 'index';
|
||||
$what = str_replace('addressbook.', '', $_GET['template'] ?? $query['main-template'] ?? 'index');
|
||||
|
||||
if (!$id_only && !$query['csv_export']) // do NOT store state for csv_export or querying id's (no regular view)
|
||||
{
|
||||
@ -1881,7 +1901,7 @@ class addressbook_ui extends addressbook_bo
|
||||
}
|
||||
}
|
||||
}
|
||||
else if($query['actions'] && !$query['actions']['edit'])
|
||||
else if($query['actions'] && empty($query['actions']['open']))
|
||||
{
|
||||
// Just switched from grouped view, update actions
|
||||
$query['actions'] = $this->get_actions($query['col_filter']['tid']);
|
||||
@ -2172,6 +2192,12 @@ class addressbook_ui extends addressbook_bo
|
||||
$rows['sel_options']['grouped_view'] = $this->grouped_views;
|
||||
}
|
||||
}
|
||||
if ($what === 'select')
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('Select contacts to add to mail');
|
||||
}
|
||||
else
|
||||
{
|
||||
if($query['advanced_search'])
|
||||
{
|
||||
$header[] = lang('Advanced search');
|
||||
@ -2190,6 +2216,7 @@ class addressbook_ui extends addressbook_bo
|
||||
$header[] = lang("Search for '%1'",$query['search']);
|
||||
}
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = implode(': ', $header);
|
||||
}
|
||||
|
||||
if ($query['grouped_view'] === '' && $query['col_filter']['shared_by'] == $this->user)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@ import type {EgwAction} from "../../api/js/egw_action/EgwAction";
|
||||
import {EgwActionObject} from "../../api/js/egw_action/EgwActionObject";
|
||||
import {Et2MergeDialog} from "../../api/js/etemplate/Et2Dialog/Et2MergeDialog";
|
||||
import {et2_createWidget} from "../../api/js/etemplate/et2_core_widget";
|
||||
import type {et2_nextmatch} from "../../api/js/etemplate/et2_extension_nextmatch";
|
||||
|
||||
/**
|
||||
* Object to call app.addressbook.openCRMview with
|
||||
@ -1061,6 +1062,7 @@ class AddressbookApp extends EgwApp
|
||||
*/
|
||||
addEmail(action, selected)
|
||||
{
|
||||
console.log('addEmail', action, selected);
|
||||
// Check for all selected.
|
||||
var nm = this.et2.getWidgetById('nm');
|
||||
if(fetchAll(selected, nm, jQuery.proxy(function(ids) {
|
||||
@ -1114,6 +1116,22 @@ class AddressbookApp extends EgwApp
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Onclick of "addessbook.select" template for [To], [Cc] or [Bcc] button
|
||||
*
|
||||
* @param _event
|
||||
* @param _widget
|
||||
*/
|
||||
addEmailToCompose(_event, _widget)
|
||||
{
|
||||
const et2 = etemplate2.getByTemplate('addressbook.select');
|
||||
const nm = <et2_nextmatch>et2[0]?.widgetContainer.getWidgetById('nm');
|
||||
const selected = nm.getSelection().ids.map((uid) => {id: uid});
|
||||
console.log('addEmailToCompose', _widget.id, selected);
|
||||
debugger;
|
||||
this.addEmail({ id: _widget.id}, selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get email addresses from selected contacts
|
||||
*
|
||||
|
@ -440,6 +440,7 @@ select a view addressbook de Eine Ansicht auswählen
|
||||
select addressbook type addressbook de Typ des Adressbuchs auswählen
|
||||
select all addressbook de Alles auswählen
|
||||
select an opened dialog addressbook de Wählen Sie einen offenen Dialog
|
||||
select contacts to add to mail addressbook de Kontakte zum Hinzufügen zur Mail auswählen
|
||||
select migration type admin de Migrationstyp auswählen
|
||||
select multiple contacts for a further action addressbook de Mehrere Adressen für weiteren Befehl auswählen
|
||||
select phone number as prefered way of contact addressbook de Telefonnummer als präferierten Kontaktweg auswählen
|
||||
|
@ -440,6 +440,7 @@ select a view addressbook en Select a view
|
||||
select addressbook type addressbook en Select address book type
|
||||
select all addressbook en Select all
|
||||
select an opened dialog addressbook en Select an opened dialog
|
||||
select contacts to add to mail addressbook en Select contacts to add to mail
|
||||
select migration type admin en Select migration type
|
||||
select multiple contacts for a further action addressbook en Select multiple contacts for a further action
|
||||
select phone number as prefered way of contact addressbook en Select phone number as preferred way of contact
|
||||
|
118
addressbook/templates/default/select.xet
Normal file
118
addressbook/templates/default/select.xet
Normal file
@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2.0//EN" "https://www.egroupware.org/etemplate2.0.dtd">
|
||||
<overlay>
|
||||
<template id="addressbook.select.rows" template="" lang="" group="0" version="1.9.005">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column width="20"/> <!-- type -->
|
||||
<column width="30%" minWidth="150"/> <!-- file as -->
|
||||
<column width="80"/> <!-- photo -->
|
||||
<column width="180"/> <!-- business addr -->
|
||||
<column width="180"/> <!-- home addr -->
|
||||
<column width="200"/> <!-- url, email, email-home -->
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<nextmatch-header label="Type" id="type"/>
|
||||
<grid spacing="0" padding="0">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row disabled="!@order=n_fileas">
|
||||
<nextmatch-sortheader label="own sorting" id="n_fileas" span="all"/>
|
||||
</row>
|
||||
<row disabled="!@order=n_given">
|
||||
<nextmatch-sortheader label="Firstname" id="n_given"/>
|
||||
<nextmatch-sortheader label="Name" id="n_family"/>
|
||||
</row>
|
||||
<row disabled="!@order=n_family">
|
||||
<nextmatch-sortheader label="Name" id="n_family"/>
|
||||
<nextmatch-sortheader label="Firstname" id="n_given"/>
|
||||
</row>
|
||||
<row>
|
||||
<nextmatch-sortheader label="Organisation" id="org_name" span="all"/>
|
||||
</row>
|
||||
<row disabled="!@order=/^(org_name|n_fileas|adr_one_postalcode|contact_modified|contact_created|#)/">
|
||||
<nextmatch-sortheader label="Name" id="n_family"/>
|
||||
<nextmatch-sortheader label="Firstname" id="n_given" class="leftPad5"/>
|
||||
</row>
|
||||
<row disabled="@order=n_fileas">
|
||||
<nextmatch-sortheader label="own sorting" id="n_fileas" span="all"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<nextmatch-header label="Photo" id="photo"/>
|
||||
<et2-vbox>
|
||||
<nextmatch-header label="Business address" id="business"/>
|
||||
<et2-nextmatch-header-custom id="adr_one_countrycode" class="countrySelect" widgetType="select-country" emptyLabel="Country"/>
|
||||
<nextmatch-sortheader label="zip code" id="adr_one_postalcode"/>
|
||||
</et2-vbox>
|
||||
<et2-vbox>
|
||||
<nextmatch-header label="Home address" id="home"/>
|
||||
<et2-nextmatch-header-custom id="adr_two_countrycode" class="countrySelect" widgetType="select-country" emptyLabel="Country"/>
|
||||
<nextmatch-sortheader label="zip code" id="adr_two_postalcode"/>
|
||||
</et2-vbox>
|
||||
<et2-vbox>
|
||||
<nextmatch-header label="Business email" id="email"/>
|
||||
<nextmatch-header label="Home email" id="email_home"/>
|
||||
</et2-vbox>
|
||||
</row>
|
||||
<row class="$row_cont[class] $row_cont[cat_id]" valign="top">
|
||||
<et2-image align="center" label="$row_cont[type_label]" src="$row_cont[type]" noLang="1" style="font-size: 22px"/>
|
||||
<et2-vbox id="${row}[id]">
|
||||
<et2-description id="${row}[line1]" noLang="1"></et2-description>
|
||||
<et2-description id="${row}[line2]" noLang="1"></et2-description>
|
||||
<et2-description id="${row}[org_unit]" noLang="1"></et2-description>
|
||||
<et2-description id="${row}[title]" noLang="1"></et2-description>
|
||||
<et2-description id="${row}[first_org]" noLang="1"></et2-description>
|
||||
</et2-vbox>
|
||||
<et2-lavatar src="$row_cont[photo]" contactId="$row_cont[id]" lname="$row_cont[n_family]" fname="$row_cont[n_given]"></et2-lavatar>
|
||||
<et2-vbox>
|
||||
<et2-hbox>
|
||||
<et2-description id="${row}[adr_one_postalcode]" noLang="1"></et2-description>
|
||||
<et2-description value=" " id="${row}[adr_one_locality]" class="leftPad5" noLang="1"></et2-description>
|
||||
<et2-description id="${row}[adr_one_region]" class="leftPad5" noLang="1"></et2-description>
|
||||
</et2-hbox>
|
||||
<et2-description id="${row}[adr_one_countryname]" noLang="1"></et2-description>
|
||||
<et2-select-country id="${row}[adr_one_countrycode]" readonly="true"></et2-select-country>
|
||||
</et2-vbox>
|
||||
<et2-vbox>
|
||||
<et2-hbox>
|
||||
<et2-description id="${row}[adr_two_postalcode]" noLang="1"></et2-description>
|
||||
<et2-description value=" " id="${row}[adr_two_locality]" class="leftPad5" noLang="1"></et2-description>
|
||||
<et2-description id="${row}[adr_two_region]" class="leftPad5" noLang="1"></et2-description>
|
||||
</et2-hbox>
|
||||
<et2-description id="${row}[adr_two_countryname]" noLang="1"></et2-description>
|
||||
<et2-select-country id="${row}[adr_two_countrycode]" readonly="true"></et2-select-country>
|
||||
</et2-vbox>
|
||||
|
||||
<et2-vbox>
|
||||
<et2-url-email id="${row}[email]" readonly="true" class="fixedHeight" emailDisplay="email"></et2-url-email>
|
||||
<et2-url-email id="${row}[email_home]" readonly="true" class="fixedHeight" emailDisplay="email"></et2-url-email>
|
||||
</et2-vbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.select" template="" lang="" group="0" version="1.9.002">
|
||||
<nextmatch id="nm" template="addressbook.select.rows" span="all"/>
|
||||
<et2-hbox>
|
||||
<et2-select label="Add">
|
||||
<option value="">Business or home email</option>
|
||||
<option value="email">Business email</option>
|
||||
<option value="email_home">Home email</option>
|
||||
</et2-select>
|
||||
<et2-button label="To" id="add_to_to" onclick="app.addressbook.addEmailToCompose"></et2-button>
|
||||
<et2-button label="Cc" id="add_to_cc" onclick="app.addressbook.addEmailToCompose"></et2-button>
|
||||
<et2-button label="Bcc" id="add_to_bcc" onclick="app.addressbook.addEmailToCompose"></et2-button>
|
||||
<et2-button label="Close" onclick="alert('ToDo ;)'); return false;"></et2-button>
|
||||
</et2-hbox>
|
||||
<styles>
|
||||
div.dialog_content img.dialog_icon[src=""] { display: none; }
|
||||
et2-dialog#dialog-addressbook-select et2-button { max-width: 125px !important; }
|
||||
et2-dialog#dialog-addressbook-select::part(panel) { width: 90vh; height: 75vh; position: absolute; bottom: 1vh; }
|
||||
</styles>
|
||||
</template>
|
||||
</overlay>
|
@ -1700,6 +1700,47 @@ export const AppJS = (function(){ "use strict"; return Class.extend(
|
||||
width: 450,
|
||||
value: {content:{ "share_link": _data.share_link }}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens _menuaction in an Et2Dialog
|
||||
*
|
||||
* Equivalent to egw.openDialog, though this one works in popups too.
|
||||
*
|
||||
* @param _menuaction
|
||||
* @return Promise<Et2Dialog>
|
||||
*/
|
||||
openDialog: function (_menuaction)
|
||||
{
|
||||
let resolver;
|
||||
let rejector;
|
||||
const dialog_promise = new Promise((resolve, reject) =>
|
||||
{
|
||||
resolver = value => resolve(value);
|
||||
rejector = reason => reject(reason);
|
||||
});
|
||||
let request = this.egw.json(_menuaction.match(/^([^.:]+)/)[0] + '.jdots_framework.ajax_exec.template.' + _menuaction,
|
||||
['index.php?menuaction=' + _menuaction, true], _response =>
|
||||
{
|
||||
if(Array.isArray(_response) && typeof _response[0] === 'string')
|
||||
{
|
||||
let dialog = jQuery(_response[0]).appendTo(document.body);
|
||||
if(dialog.length > 0 && dialog.get(0))
|
||||
{
|
||||
resolver(dialog.get(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("Unable to add dialog with dialogExec('" + _menuaction + "')", _response);
|
||||
rejector(new Error("Unable to add dialog"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("Invalid response to dialogExec('" + _menuaction + "')", _response);
|
||||
rejector(new Error("Invalid response to dialogExec('" + _menuaction + "')"));
|
||||
}
|
||||
}).sendRequest();
|
||||
return dialog_promise;
|
||||
}
|
||||
});}).call(window);
|
@ -267,7 +267,7 @@ class Etemplate extends Etemplate\Widget\Template
|
||||
{
|
||||
if ($output_mode == 2)
|
||||
{
|
||||
$content = '<et2-dialog><form target="egw_iframe_autocomplete_helper" action="'.$form_action.'" id="'.$dom_id.'" class="et2_container dialog_content"></form></et2-dialog>'."\n";
|
||||
$content = '<et2-dialog id="dialog-'.$dom_id.'"><form target="egw_iframe_autocomplete_helper" action="'.$form_action.'" id="'.$dom_id.'" class="et2_container dialog_content"></form></et2-dialog>'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -69,7 +69,11 @@
|
||||
</et2-dropdown>
|
||||
<et2-email id="to" width="100%" onclick="app.mail.address_click" autofocus="true"
|
||||
onchange="app.mail.recipients_onchange"
|
||||
placeholder="select or insert email address" includeLists="true" allowPlaceholder="true"></et2-email>
|
||||
placeholder="select or insert email address" includeLists="true" allowPlaceholder="true">
|
||||
<et2-button-icon image="addressbook/navbar" statustext="click to select in addressbook"
|
||||
onclick="app.mail.openDialog('addressbook.addressbook_ui.index&template=addressbook.select')"
|
||||
slot="suffix"></et2-button-icon>
|
||||
</et2-email>
|
||||
</row>
|
||||
<row class="mailComposeHeaders mailComposeJQueryCc">
|
||||
<et2-description value="Cc"></et2-description>
|
||||
|
Loading…
Reference in New Issue
Block a user