diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 3f824ea715..d9e077aab3 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/b218398a/rsrc/css/application/conpherence/widget-pane.css', + 'uri' => '/res/e06804b6/rsrc/css/application/conpherence/widget-pane.css', 'type' => 'css', 'requires' => array( @@ -1294,7 +1294,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-conpherence-menu' => array( - 'uri' => '/res/478fc4f3/rsrc/js/application/conpherence/behavior-menu.js', + 'uri' => '/res/87e901c2/rsrc/js/application/conpherence/behavior-menu.js', 'type' => 'js', 'requires' => array( @@ -1325,7 +1325,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-conpherence-widget-pane' => array( - 'uri' => '/res/232893cf/rsrc/js/application/conpherence/behavior-widget-pane.js', + 'uri' => '/res/3b06849a/rsrc/js/application/conpherence/behavior-widget-pane.js', 'type' => 'js', 'requires' => array( diff --git a/src/applications/calendar/controller/PhabricatorCalendarEditStatusController.php b/src/applications/calendar/controller/PhabricatorCalendarEditStatusController.php index b31deeb0c4..342f364144 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarEditStatusController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarEditStatusController.php @@ -86,8 +86,14 @@ final class PhabricatorCalendarEditStatusController 'Y'), $redirect => true, )); - return id(new AphrontRedirectResponse()) - ->setURI($uri); + if ($request->isAjax()) { + $response = id(new AphrontAjaxResponse()) + ->setContent(array('redirect_uri' => $uri)); + } else { + $response = id(new AphrontRedirectResponse()) + ->setURI($uri); + } + return $response; } } @@ -109,16 +115,40 @@ final class PhabricatorCalendarEditStatusController ->setName('description') ->setValue($status->getDescription()); - $form = id(new AphrontFormView()) - ->setUser($user) - ->setFlexible(true) + if ($request->isAjax()) { + $dialog = id(new AphrontDialogView()) + ->setUser($user) + ->setTitle($page_title) + ->setWidth(AphrontDialogView::WIDTH_FORM); + if ($this->isCreate()) { + $dialog->setSubmitURI($this->getApplicationURI('status/create/')); + } else { + $dialog->setSubmitURI( + $this->getApplicationURI('status/edit/'.$status->getID().'/')); + } + $form = new AphrontFormLayoutView(); + if ($error_view) { + $form->appendChild($error_view); + } + } else { + $form = id(new AphrontFormView()) + ->setUser($user) + ->setFlexible(true); + } + + $form ->appendChild($status_select) ->appendChild($start_time) ->appendChild($end_time) ->appendChild($description); - $submit = id(new AphrontFormSubmitControl()) - ->setValue($submit_label); + if ($request->isAjax()) { + $dialog->addSubmitButton($submit_label); + $submit = $dialog; + } else { + $submit = id(new AphrontFormSubmitControl()) + ->setValue($submit_label); + } if ($this->isCreate()) { $submit->addCancelButton($this->getApplicationURI()); } else { @@ -126,6 +156,12 @@ final class PhabricatorCalendarEditStatusController $this->getApplicationURI('status/delete/'.$status->getID().'/'), pht('Delete Status')); } + + if ($request->isAjax()) { + $dialog->appendChild($form); + return id(new AphrontDialogResponse()) + ->setDialog($dialog); + } $form->appendChild($submit); $nav = $this->buildSideNavView($status); diff --git a/src/applications/conpherence/constants/ConpherenceUpdateActions.php b/src/applications/conpherence/constants/ConpherenceUpdateActions.php index c137a2e52d..b5669dea5b 100644 --- a/src/applications/conpherence/constants/ConpherenceUpdateActions.php +++ b/src/applications/conpherence/constants/ConpherenceUpdateActions.php @@ -7,4 +7,5 @@ final class ConpherenceUpdateActions extends ConpherenceConstants { const ADD_PERSON = 'add_person'; const REMOVE_PERSON = 'remove_person'; const NOTIFICATIONS = 'notifications'; + const ADD_STATUS = 'add_status'; } diff --git a/src/applications/conpherence/controller/ConpherenceWidgetController.php b/src/applications/conpherence/controller/ConpherenceWidgetController.php index 764088bac1..1764a87e94 100644 --- a/src/applications/conpherence/controller/ConpherenceWidgetController.php +++ b/src/applications/conpherence/controller/ConpherenceWidgetController.php @@ -65,6 +65,11 @@ final class ConpherenceWidgetController extends $conpherence = $this->getConpherence(); $widgets = array(); + $new_icon = id(new PHUIIconView()) + ->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS) + ->setSpriteIcon('new-grey') + ->setHref($this->getWidgetURI()) + ->addSigil('conpherence-widget-adder'); $widgets[] = phutil_tag( 'div', array( @@ -75,6 +80,7 @@ final class ConpherenceWidgetController extends ->setHeaderTitle(pht('Participants')) ->setHeaderHref('#') ->setDropdown(true) + ->addAction($new_icon) ->addHeaderSigil('widgets-selector')); $user = $this->getRequest()->getUser(); // now the widget bodies @@ -193,11 +199,11 @@ final class ConpherenceWidgetController extends $content = array(); $layout = id(new AphrontMultiColumnView()) ->setFluidLayout(true); - $timestamps = $this->getCalendarWidgetWeekTimestamps(); + $timestamps = $this->getCalendarWidgetTimestamps(); $today = $timestamps['today']; - $weekstamps = $timestamps['weekstamps']; + $epoch_stamps = $timestamps['epoch_stamps']; $one_day = 24 * 60 * 60; - foreach ($weekstamps as $time => $day) { + foreach ($epoch_stamps as $time => $day) { // build a header for the new day if ($day->format('w') == $today->format('w')) { $active_class = 'today'; @@ -227,7 +233,6 @@ final class ConpherenceWidgetController extends $week_day_number = $day->format('w'); - $day->setTime(0, 0, 0); $epoch_start = $day->format('U'); $next_day = clone $day; @@ -371,24 +376,20 @@ final class ConpherenceWidgetController extends ); } - private function getCalendarWidgetWeekTimestamps() { + private function getCalendarWidgetTimestamps() { $user = $this->getRequest()->getUser(); $timezone = new DateTimeZone($user->getTimezoneIdentifier()); - $today = id(new DateTime('now', $timezone)); - $monday = clone $today; - $monday - ->modify('+1 day') - ->modify('last monday'); + $today = id(new DateTime('today', $timezone)); $timestamps = array(); - for ($day = 0; $day < 7; $day++) { - $timestamp = clone $monday; + for ($day = 0; $day < 3; $day++) { + $timestamp = clone $today; $timestamps[] = $timestamp->modify(sprintf('+%d days', $day)); } return array( 'today' => $today, - 'weekstamps' => $timestamps + 'epoch_stamps' => $timestamps ); } diff --git a/src/applications/conpherence/query/ConpherenceThreadQuery.php b/src/applications/conpherence/query/ConpherenceThreadQuery.php index a0eb702529..1de9d4a86d 100644 --- a/src/applications/conpherence/query/ConpherenceThreadQuery.php +++ b/src/applications/conpherence/query/ConpherenceThreadQuery.php @@ -217,21 +217,21 @@ final class ConpherenceThreadQuery $file_phids = array_mergev($file_phids); // statuses of everyone currently in the conpherence - // for a rolling one week window - $start_of_week = phabricator_format_local_time( - strtotime('last monday', strtotime('tomorrow')), + // for a rolling three day window + $start_epoch = phabricator_format_local_time( + strtotime('today', strtotime('tomorrow')), $this->getViewer(), 'U'); - $end_of_week = phabricator_format_local_time( - strtotime('last monday +1 week', strtotime('tomorrow')), + $end_epoch = phabricator_format_local_time( + strtotime('+3 days', strtotime('tomorrow')), $this->getViewer(), 'U'); $statuses = id(new PhabricatorUserStatus()) ->loadAllWhere( 'userPHID in (%Ls) AND dateTo >= %d AND dateFrom <= %d', $participant_phids, - $start_of_week, - $end_of_week); + $start_epoch, + $end_epoch); $statuses = mgroup($statuses, 'getUserPHID'); // attached files diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php index 7509295402..267b28905b 100644 --- a/src/applications/conpherence/view/ConpherenceLayoutView.php +++ b/src/applications/conpherence/view/ConpherenceLayoutView.php @@ -82,22 +82,28 @@ final class ConpherenceLayoutView extends AphrontView { 'conpherence-message-pane' => array( 'name' => pht('Thread'), 'deviceOnly' => true, + 'hasCreate' => false ), 'widgets-people' => array( 'name' => pht('Participants'), 'deviceOnly' => false, + 'hasCreate' => false ), 'widgets-files' => array( 'name' => pht('Files'), 'deviceOnly' => false, + 'hasCreate' => false ), 'widgets-calendar' => array( 'name' => pht('Calendar'), 'deviceOnly' => false, + 'hasCreate' => true, + 'createHref' => '/calendar/status/create/' ), 'widgets-settings' => array( 'name' => pht('Settings'), 'deviceOnly' => false, + 'hasCreate' => false ), ))); diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css index 4f755efab7..2a8c3b314c 100644 --- a/webroot/rsrc/css/application/conpherence/widget-pane.css +++ b/webroot/rsrc/css/application/conpherence/widget-pane.css @@ -145,10 +145,10 @@ /* calendar widget */ .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view { - margin: 2px 0px 0px 0px; width: 240px; } .device .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view { + margin: 2px 0px 0px 0px; width: 100%; } .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view diff --git a/webroot/rsrc/js/application/conpherence/behavior-menu.js b/webroot/rsrc/js/application/conpherence/behavior-menu.js index b24dd683cf..e049781181 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-menu.js +++ b/webroot/rsrc/js/application/conpherence/behavior-menu.js @@ -138,11 +138,7 @@ JX.behavior('conpherence-menu', function(config) { } if (_thread.visible !== null || !config.hasWidgets) { - markWidgetLoading(true); - var widget_uri = config.baseURI + 'widget/' + data.threadID + '/'; - new JX.Workflow(widget_uri, {}) - .setHandler(JX.bind(null, onWidgetResponse, data.threadID)) - .start(); + reloadWidget(data); } else { JX.Stratcom.invoke( 'conpherence-update-widgets', @@ -191,7 +187,29 @@ JX.behavior('conpherence-menu', function(config) { JX.DOM.alterClass(widgets_root, 'loading', loading); } - function onWidgetResponse(thread_id, response) { + function reloadWidget(data) { + markWidgetLoading(true); + if (!data.widget) { + data.widget = getDefaultWidget(); + } + var widget_uri = config.baseURI + 'widget/' + data.threadID + '/'; + new JX.Workflow(widget_uri, {}) + .setHandler(JX.bind(null, onWidgetResponse, data.threadID, data.widget)) + .start(); + } + JX.Stratcom.listen( + 'conpherence-reload-widget', + null, + function (e) { + var data = e.getData(); + if (data.threadID != _thread.selected) { + return; + } + reloadWidget(data); + } + ); + + function onWidgetResponse(thread_id, widget, response) { // we got impatient and this is no longer the right answer :/ if (_thread.selected != thread_id) { return; @@ -204,7 +222,7 @@ JX.behavior('conpherence-menu', function(config) { 'conpherence-update-widgets', null, { - widget : getDefaultWidget(), + widget : widget, buildSelectors : true, toggleWidget : true, threadID : _thread.selected diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js index d9ea8afa30..71d53f8857 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js +++ b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js @@ -169,12 +169,18 @@ JX.behavior('conpherence-widget-pane', function(config) { var root = JX.DOM.find(document, 'div', 'conpherence-layout'); var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane'); var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector'); + var adder = JX.DOM.find(widget_pane, 'a', 'conpherence-widget-adder'); JX.DOM.setContent( widget_header, widget_data.name); JX.DOM.appendContent( widget_header, JX.$N('span', { className : 'caret' })); + if (widget_data.hasCreate) { + JX.DOM.show(adder); + } else { + JX.DOM.hide(adder); + } } for (var widget in config.widgetRegistry) { @@ -215,6 +221,39 @@ JX.behavior('conpherence-widget-pane', function(config) { } }); + /** + * Generified adding new stuff to widgets technology! + */ + JX.Stratcom.listen( + ['click'], + 'conpherence-widget-adder', + function (e) { + e.kill(); + var widgets = config.widgetRegistry; + var active_widget = null; + var href = null; + for (var widget in widgets) { + if (widgets[widget].name == _selectedWidgetName) { + href = widgets[widget].createHref; + active_widget = 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'],