From 38e6961cbd632267b4ae7d09da4974ac19b70b9c Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Wed, 29 May 2013 17:21:07 -0700 Subject: [PATCH] Conpherence - make adding participants be a little dialogue. Summary: and now you can add more than one at a time! Also adds the 'add participants' and 'new calendar event' options to mobile view. Fixes T3251. Ref T3253. Test Plan: loaded up these "adders" on both desktop and device-ish views and it went well! Reviewers: epriestley, chad Reviewed By: chad CC: chad, aran, Korvin Maniphest Tasks: T3251, T3253 Differential Revision: https://secure.phabricator.com/D6075 --- src/__celerity_resource_map__.php | 4 +- .../controller/ConpherenceController.php | 16 +++ .../ConpherenceUpdateController.php | 31 ++++- .../ConpherenceWidgetController.php | 1 + .../view/ConpherenceLayoutView.php | 15 ++- .../view/ConpherencePeopleWidgetView.php | 42 +------ .../application/conpherence/widget-pane.css | 2 +- .../conpherence/behavior-widget-pane.js | 116 ++++++++++-------- 8 files changed, 125 insertions(+), 102 deletions(-) diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 975aed318c..5afef99f1d 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -945,7 +945,7 @@ celerity_register_resource_map(array( ), 'conpherence-widget-pane-css' => array( - 'uri' => '/res/e06804b6/rsrc/css/application/conpherence/widget-pane.css', + 'uri' => '/res/40be33e2/rsrc/css/application/conpherence/widget-pane.css', 'type' => 'css', 'requires' => array( @@ -1325,7 +1325,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-conpherence-widget-pane' => array( - 'uri' => '/res/3b06849a/rsrc/js/application/conpherence/behavior-widget-pane.js', + 'uri' => '/res/440f5bdf/rsrc/js/application/conpherence/behavior-widget-pane.js', 'type' => 'js', 'requires' => array( diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index 348507011b..6d2b1cd69f 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -13,6 +13,22 @@ abstract class ConpherenceController extends PhabricatorController { pht('New Message'), $this->getApplicationURI('new/')); + $nav->addMenuItem( + id(new PhabricatorMenuItemView()) + ->setName(pht('Add Participants')) + ->setType(PhabricatorMenuItemView::TYPE_LINK) + ->setHref('#') + ->addSigil('conpherence-widget-adder') + ->setMetadata(array('widget' => 'widgets-people'))); + + $nav->addMenuItem( + id(new PhabricatorMenuItemView()) + ->setName(pht('New Calendar Item')) + ->setType(PhabricatorMenuItemView::TYPE_LINK) + ->setHref('/calendar/status/create/') + ->addSigil('conpherence-widget-adder') + ->setMetadata(array('widget' => 'widgets-calendar'))); + return $nav; } diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index a5adad8bc3..d1f3eb81aa 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -54,13 +54,12 @@ final class ConpherenceUpdateController break; case ConpherenceUpdateActions::ADD_PERSON: $xactions = array(); - $person_tokenizer = $request->getArr('add_person'); - $person_phid = reset($person_tokenizer); - if ($person_phid) { + $person_phids = $request->getArr('add_person'); + if (!empty($person_phids)) { $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType( ConpherenceTransactionType::TYPE_PARTICIPANTS) - ->setNewValue(array('+' => array($person_phid))); + ->setNewValue(array('+' => $person_phids)); } break; case ConpherenceUpdateActions::REMOVE_PERSON: @@ -153,6 +152,9 @@ final class ConpherenceUpdateController } switch ($action) { + case ConpherenceUpdateActions::ADD_PERSON: + $dialogue = $this->renderAddPersonDialogue($conpherence); + break; case ConpherenceUpdateActions::REMOVE_PERSON: $dialogue = $this->renderRemovePersonDialogue($conpherence); break; @@ -172,6 +174,27 @@ final class ConpherenceUpdateController } + private function renderAddPersonDialogue( + ConpherenceThread $conpherence) { + + $request = $this->getRequest(); + $user = $request->getUser(); + $add_person = $request->getStr('add_person'); + + $body = id(new AphrontFormTokenizerControl()) + ->setPlaceholder(pht('Add participants...')) + ->setName('add_person') + ->setUser($user) + ->setDatasource('/typeahead/common/users/') + ->setLimit(1); + + require_celerity_resource('conpherence-update-css'); + return id(new AphrontDialogView()) + ->setTitle(pht('Update Conpherence Participants')) + ->addHiddenInput('action', 'add_person') + ->appendChild($body); + } + private function renderRemovePersonDialogue( ConpherenceThread $conpherence) { diff --git a/src/applications/conpherence/controller/ConpherenceWidgetController.php b/src/applications/conpherence/controller/ConpherenceWidgetController.php index 1764a87e94..123df65de7 100644 --- a/src/applications/conpherence/controller/ConpherenceWidgetController.php +++ b/src/applications/conpherence/controller/ConpherenceWidgetController.php @@ -69,6 +69,7 @@ final class ConpherenceWidgetController extends ->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS) ->setSpriteIcon('new-grey') ->setHref($this->getWidgetURI()) + ->setMetadata(array('widget' => null)) ->addSigil('conpherence-widget-adder'); $widgets[] = phutil_tag( 'div', diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php index 267b28905b..97d34cc28f 100644 --- a/src/applications/conpherence/view/ConpherenceLayoutView.php +++ b/src/applications/conpherence/view/ConpherenceLayoutView.php @@ -77,7 +77,7 @@ final class ConpherenceLayoutView extends AphrontView { Javelin::initBehavior( 'conpherence-widget-pane', array( - 'selectChar' => "\xE2\x96\xBC", + 'widgetBaseUpdateURI' => $this->baseURI . 'update/', 'widgetRegistry' => array( 'conpherence-message-pane' => array( 'name' => pht('Thread'), @@ -87,7 +87,12 @@ final class ConpherenceLayoutView extends AphrontView { 'widgets-people' => array( 'name' => pht('Participants'), 'deviceOnly' => false, - 'hasCreate' => false + 'hasCreate' => true, + 'createData' => array( + 'refreshFromResponse' => true, + 'action' => ConpherenceUpdateActions::ADD_PERSON, + 'customHref' => null + ) ), 'widgets-files' => array( 'name' => pht('Files'), @@ -98,7 +103,11 @@ final class ConpherenceLayoutView extends AphrontView { 'name' => pht('Calendar'), 'deviceOnly' => false, 'hasCreate' => true, - 'createHref' => '/calendar/status/create/' + 'createData' => array( + 'refreshFromResponse' => false, + 'action' => ConpherenceUpdateActions::ADD_STATUS, + 'customHref' => '/calendar/status/create/' + ) ), 'widgets-settings' => array( 'name' => pht('Settings'), diff --git a/src/applications/conpherence/view/ConpherencePeopleWidgetView.php b/src/applications/conpherence/view/ConpherencePeopleWidgetView.php index d2716ad781..cc5300842a 100644 --- a/src/applications/conpherence/view/ConpherencePeopleWidgetView.php +++ b/src/applications/conpherence/view/ConpherencePeopleWidgetView.php @@ -12,46 +12,6 @@ final class ConpherencePeopleWidgetView extends ConpherenceWidgetView { $participants = $conpherence->getParticipants(); $handles = $conpherence->getHandles(); - // ye olde add people widget - $add_widget = phabricator_form( - $user, - array( - 'method' => 'POST', - 'action' => $this->getUpdateURI(), - 'sigil' => 'add-person', - 'meta' => array( - 'action' => 'add_person' - ) - ), - array( - id(new AphrontFormTokenizerControl()) - ->setPlaceholder(pht('Add a person...')) - ->setName('add_person') - ->setUser($user) - ->setDatasource('/typeahead/common/users/') - ->setLimit(1), - phutil_tag( - 'button', - array( - 'type' => 'submit', - 'class' => 'people-add-button', - ), - pht('Add')) - )); - $header = phutil_tag( - 'div', - array( - 'class' => 'people-widget-header' - ), - array( - phutil_tag( - 'div', - array( - 'class' => 'add-people-widget', - ), - $add_widget) - )); - $body = array(); // future proof by using participants to iterate through handles; // we may have non-people handles sooner or later @@ -97,6 +57,6 @@ final class ConpherencePeopleWidgetView extends ConpherenceWidgetView { $remove_html)); } - return array($header, $body); + return $body; } } diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css index 2a8c3b314c..9a6541a241 100644 --- a/webroot/rsrc/css/application/conpherence/widget-pane.css +++ b/webroot/rsrc/css/application/conpherence/widget-pane.css @@ -344,7 +344,7 @@ .conpherence-widget-pane .person-entry { clear: both; - padding: 5px 0 0 10px; + padding: 10px 0px 0px 10px; } .conpherence-widget-pane .person-entry a { diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js index 71d53f8857..097dfdeeb6 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js +++ b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js @@ -229,67 +229,82 @@ JX.behavior('conpherence-widget-pane', function(config) { 'conpherence-widget-adder', function (e) { e.kill(); + var widgets = config.widgetRegistry; - var active_widget = null; - var href = null; + // the widget key might be in node data, but otherwise use the + // selected widget + var event_data = e.getNodeData('conpherence-widget-adder'); + var widget_key = _selectedWidgetName; + if (event_data.widget) { + widget_key = widgets[event_data.widget].name; + } + + var widget_to_update = null; + var create_data = null; for (var widget in widgets) { - if (widgets[widget].name == _selectedWidgetName) { - href = widgets[widget].createHref; - active_widget = widget; + if (widgets[widget].name == widget_key) { + create_data = widgets[widget].createData; + widget_to_update = widget; break; } } - new JX.Workflow(href, {}) - .setHandler(function () { - JX.Stratcom.invoke( - 'conpherence-reload-widget', - null, - { - threadID : _loadedWidgetsID, - widget : active_widget - } - ); - }) - .start(); - } - ); - - /* people widget */ - JX.Stratcom.listen( - ['submit', 'didSyntheticSubmit'], - 'add-person', - function (e) { - e.kill(); - var root = e.getNode('conpherence-layout'); - var form = e.getNode('tag:form'); - var data = e.getNodeData('add-person'); - var people_root = e.getNode('widgets-people'); - var messages = null; - try { - messages = JX.DOM.find(root, 'div', 'conpherence-messages'); - } catch (ex) { + // this should be impossible, but hey + if (!widget_to_update) { + return; } + var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/'; + if (create_data.customHref) { + href = create_data.customHref; + } + + var root = JX.DOM.find(document, 'div', 'conpherence-layout'); var latest_transaction_data = JX.Stratcom.getData( JX.DOM.find( root, 'input', 'latest-transaction-id' )); - data.latest_transaction_id = latest_transaction_data.id; - JX.Workflow.newFromForm(form, data) - .setHandler(JX.bind(this, function (r) { - if (messages) { - JX.DOM.appendContent(messages, JX.$H(r.transactions)); - messages.scrollTop = messages.scrollHeight; - } + var data = { + latest_transaction_id : latest_transaction_data.id, + action : create_data.action + }; - // update the people widget - JX.DOM.setContent( - people_root, - JX.$H(r.people_widget) - ); - })) - .start(); + new JX.Workflow(href, data) + .setHandler(function (r) { + if (create_data.refreshFromResponse) { + var messages = null; + try { + messages = JX.DOM.find(root, 'div', 'conpherence-messages'); + } catch (ex) { + } + if (messages) { + JX.DOM.appendContent(messages, JX.$H(r.transactions)); + messages.scrollTop = messages.scrollHeight; + } + + if (r.people_widget) { + try { + var people_root = JX.DOM.find(root, 'div', 'widgets-people'); + // update the people widget + JX.DOM.setContent( + people_root, + JX.$H(r.people_widget)); + } catch (ex) { + } + } + + // otherwise let's redraw the widget somewhat lazily + } else { + JX.Stratcom.invoke( + 'conpherence-reload-widget', + null, + { + threadID : _loadedWidgetsID, + widget : widget_to_update + }); + } + }) + .start(); } ); @@ -297,11 +312,10 @@ JX.behavior('conpherence-widget-pane', function(config) { ['touchstart', 'mousedown'], 'remove-person', function (e) { - var people_root = e.getNode('widgets-people'); - var form = JX.DOM.find(peopleRoot, 'form'); + var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/'; var data = e.getNodeData('remove-person'); // we end up re-directing to conpherence home - JX.Workflow.newFromForm(form, data) + new JX.Workflow(href, data) .start(); } );