From 4095572468ab9a103b2be6f14c531615b60a0fe0 Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Mon, 24 May 2010 19:57:23 +0200 Subject: [PATCH] Automatically add and remove free/busy information for added/removed attendees. --- framework/Ajax/lib/Horde/Ajax/Application/Base.php | 33 ++++++++++++++++++++ horde/js/prettyautocomplete.js | 7 +++-- kronolith/js/kronolith.js | 35 ++++++++++++++++++++-- kronolith/lib/Ajax/Application.php | 12 ++++++++ kronolith/lib/Ajax/Imple/ContactAutoCompleter.php | 4 ++- 5 files changed, 85 insertions(+), 6 deletions(-) diff --git a/framework/Ajax/lib/Horde/Ajax/Application/Base.php b/framework/Ajax/lib/Horde/Ajax/Application/Base.php index 89988ad25..1ee2e2a2e 100644 --- a/framework/Ajax/lib/Horde/Ajax/Application/Base.php +++ b/framework/Ajax/lib/Horde/Ajax/Application/Base.php @@ -48,6 +48,14 @@ abstract class Horde_Ajax_Application_Base protected $_readOnly = array(); /** + * Default domain. + * + * @see parseEmailAddress() + * @var string + */ + protected $_defaultDomain; + + /** * Constructor. * * @param string $app The application name. @@ -143,6 +151,31 @@ abstract class Horde_Ajax_Application_Base } /** + * Parses a valid email address out of a complete address string. + * + * Variables used: + * - mbox (string): The name of the new mailbox. + * - parent (string): The parent mailbox. + * + * @return string The parsed email address. + * @throws Horde_Exception + * @throws Horde_Mail_Exception + */ + public function parseEmailAddress() + { + $rfc822 = new Horde_Mail_Rfc822(); + $params = array(); + if ($this->_defaultDomain) { + $params['default_domain'] = $this->_defaultDomain; + } + $res = $rfc822->parseAddressList($this->_vars->email, $params); + if (!count($res)) { + throw new Horde_Exception(_("No valid email address found")); + } + return (object)array('email' => Horde_Mime_Address::writeAddress($res[0]->mailbox, $res[0]->host)); + } + + /** * Loads a chunk of PHP code (usually an HTML template) from the * application's templates directory. * diff --git a/horde/js/prettyautocomplete.js b/horde/js/prettyautocomplete.js index 069c4bdc4..a18b16674 100644 --- a/horde/js/prettyautocomplete.js +++ b/horde/js/prettyautocomplete.js @@ -18,7 +18,8 @@ var PrettyAutocompleter = Class.create({ // This function should *always* return escaped HTML displayFilter: function(t) { return t.escapeHTML() }, filterCallback: this._filterChoices.bind(this), - onAdd: Prototype.K + onAdd: Prototype.K, + onRemove: Prototype.K }, params || {}); // Array to hold the currently selected items to ease with removing @@ -167,6 +168,7 @@ var PrettyAutocompleter = Class.create({ var value = $F(this.p.trigger).replace(/^,/, '').strip(); if (value.length) { this.addNewItemNode(value); + this.p.onAdd(value); } }, @@ -182,6 +184,7 @@ var PrettyAutocompleter = Class.create({ _updateElement: function(item) { this.addNewItemNode(item); + this.p.onAdd(item); }, addNewItemNode: function(value) @@ -211,7 +214,6 @@ var PrettyAutocompleter = Class.create({ // ...and keep the selectedItems array up to date. this.selectedItems.push({ rawValue: value, displayValue: displayValue }); - this.p.onAdd(value); }, removeItemNode: function(item) @@ -224,6 +226,7 @@ var PrettyAutocompleter = Class.create({ } } item.remove(); + this.p.onRemove(value); }, disable: function() diff --git a/kronolith/js/kronolith.js b/kronolith/js/kronolith.js index 9a2893e12..55cacfbef 100644 --- a/kronolith/js/kronolith.js +++ b/kronolith/js/kronolith.js @@ -4775,7 +4775,21 @@ KronolithCore = { */ addAttendee: function(attendee) { - var tr = new Element('tr'), i; + if (typeof attendee == 'string') { + if (attendee.include('@')) { + this.doAction('parseEmailAddress', + { email: attendee }, + function (r) { + if (r.response.email) { + this.addAttendee({ e: r.response.email, l: attendee }); + } + }.bind(this)); + return; + } else { + attendee = { l: attendee }; + } + } + if (attendee.e) { this.fbLoading++; this.doAction('getFreeBusy', @@ -4788,11 +4802,14 @@ KronolithCore = { if (Object.isUndefined(r.response.fb)) { return; } - this.freeBusy.set(attendee.e, [ tr, r.response.fb ]); + this.freeBusy.get(attendee.l)[1] = r.response.fb; this.insertFreeBusy(attendee.e); }.bind(this)); } - tr.insert(new Element('td').writeAttribute('title', attendee.l).insert(attendee.e ? attendee.e.escapeHTML() : attendee.l)); + + var tr = new Element('tr'), i; + this.freeBusy.set(attendee.l, [ tr ]); + tr.insert(new Element('td').writeAttribute('title', attendee.l).insert(attendee.e ? attendee.e.escapeHTML() : attendee.l.escapeHTML())); for (i = 0; i < 24; i++) { tr.insert(new Element('td', { className: 'kronolithFBUnknown' })); } @@ -4800,6 +4817,18 @@ KronolithCore = { }, /** + * Removes an attendee row from the free/busy table. + * + * @param object attendee An attendee object with the properties: + * - e: email address + * - l: the display name of the attendee + */ + removeAttendee: function(attendee) + { + this.freeBusy.get(attendee)[0].remove(); + }, + + /** * Updates rows with free/busy information in the attendees table. * * @todo Update when changing dates; only show free time for fb times we diff --git a/kronolith/lib/Ajax/Application.php b/kronolith/lib/Ajax/Application.php index afec82e1e..20e342aea 100644 --- a/kronolith/lib/Ajax/Application.php +++ b/kronolith/lib/Ajax/Application.php @@ -22,6 +22,18 @@ class Kronolith_Ajax_Application extends Horde_Ajax_Application_Base public $notify = true; /** + * Constructor. + * + * @param string $app The application name. + * @param string $action The AJAX action to perform. + */ + public function __construct($app, $action = null) + { + parent::__construct($app, $action); + $this->_defaultDomain = empty($GLOBALS['conf']['storage']['default_domain']) ? null : $GLOBALS['conf']['storage']['default_domain']; + } + + /** * TODO */ public function listEvents() diff --git a/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php b/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php index cfc6cc69f..06582b302 100644 --- a/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php +++ b/kronolith/lib/Ajax/Imple/ContactAutoCompleter.php @@ -26,7 +26,9 @@ class Kronolith_Ajax_Imple_ContactAutoCompleter extends Horde_Ajax_Imple_AutoCom $ret = array('params' => $js_params, 'raw_params' => array( 'onSelect' => 'function (v) { if (!v.endsWith(";")) { v += ","; } return v + " "; }', - 'onType' => 'function (e) { return e.include("<") ? "" : e; }' + 'onType' => 'function (e) { return e.include("<") ? "" : e; }', + 'onAdd' => 'KronolithCore.addAttendee.bind(KronolithCore)', + 'onRemove' => 'KronolithCore.removeAttendee.bind(KronolithCore)', )); if (empty($this->_params['pretty'])) { $ret['ajax'] = 'ContactAutoCompleter'; -- 2.11.0