mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 23:02:42 +01:00
Conpherence calendar updates
Summary: Fixes T3253 by shifting the display to the "next 3 days". Also adds in the "create" functionality for calendar on desktop view only, ref T3251. As part of T3251, I plan to make this work on mobile too. Test Plan: added statuses and noted errors showed up. noted on success the widget pane refreshed. also made sure the regular old /calendar/status/create/ page still worked. Reviewers: epriestley Reviewed By: epriestley CC: chad, aran, Korvin Maniphest Tasks: T3251, T3253 Differential Revision: https://secure.phabricator.com/D6072
This commit is contained in:
parent
545dbabbca
commit
73bd2e94a8
9 changed files with 139 additions and 38 deletions
|
@ -945,7 +945,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'conpherence-widget-pane-css' =>
|
'conpherence-widget-pane-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/b218398a/rsrc/css/application/conpherence/widget-pane.css',
|
'uri' => '/res/e06804b6/rsrc/css/application/conpherence/widget-pane.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -1294,7 +1294,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'javelin-behavior-conpherence-menu' =>
|
'javelin-behavior-conpherence-menu' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/478fc4f3/rsrc/js/application/conpherence/behavior-menu.js',
|
'uri' => '/res/87e901c2/rsrc/js/application/conpherence/behavior-menu.js',
|
||||||
'type' => 'js',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -1325,7 +1325,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'javelin-behavior-conpherence-widget-pane' =>
|
'javelin-behavior-conpherence-widget-pane' =>
|
||||||
array(
|
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',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -86,9 +86,15 @@ final class PhabricatorCalendarEditStatusController
|
||||||
'Y'),
|
'Y'),
|
||||||
$redirect => true,
|
$redirect => true,
|
||||||
));
|
));
|
||||||
return id(new AphrontRedirectResponse())
|
if ($request->isAjax()) {
|
||||||
|
$response = id(new AphrontAjaxResponse())
|
||||||
|
->setContent(array('redirect_uri' => $uri));
|
||||||
|
} else {
|
||||||
|
$response = id(new AphrontRedirectResponse())
|
||||||
->setURI($uri);
|
->setURI($uri);
|
||||||
}
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$error_view = null;
|
$error_view = null;
|
||||||
|
@ -109,16 +115,40 @@ final class PhabricatorCalendarEditStatusController
|
||||||
->setName('description')
|
->setName('description')
|
||||||
->setValue($status->getDescription());
|
->setValue($status->getDescription());
|
||||||
|
|
||||||
|
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())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->setFlexible(true)
|
->setFlexible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$form
|
||||||
->appendChild($status_select)
|
->appendChild($status_select)
|
||||||
->appendChild($start_time)
|
->appendChild($start_time)
|
||||||
->appendChild($end_time)
|
->appendChild($end_time)
|
||||||
->appendChild($description);
|
->appendChild($description);
|
||||||
|
|
||||||
|
if ($request->isAjax()) {
|
||||||
|
$dialog->addSubmitButton($submit_label);
|
||||||
|
$submit = $dialog;
|
||||||
|
} else {
|
||||||
$submit = id(new AphrontFormSubmitControl())
|
$submit = id(new AphrontFormSubmitControl())
|
||||||
->setValue($submit_label);
|
->setValue($submit_label);
|
||||||
|
}
|
||||||
if ($this->isCreate()) {
|
if ($this->isCreate()) {
|
||||||
$submit->addCancelButton($this->getApplicationURI());
|
$submit->addCancelButton($this->getApplicationURI());
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,6 +156,12 @@ final class PhabricatorCalendarEditStatusController
|
||||||
$this->getApplicationURI('status/delete/'.$status->getID().'/'),
|
$this->getApplicationURI('status/delete/'.$status->getID().'/'),
|
||||||
pht('Delete Status'));
|
pht('Delete Status'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->isAjax()) {
|
||||||
|
$dialog->appendChild($form);
|
||||||
|
return id(new AphrontDialogResponse())
|
||||||
|
->setDialog($dialog);
|
||||||
|
}
|
||||||
$form->appendChild($submit);
|
$form->appendChild($submit);
|
||||||
|
|
||||||
$nav = $this->buildSideNavView($status);
|
$nav = $this->buildSideNavView($status);
|
||||||
|
|
|
@ -7,4 +7,5 @@ final class ConpherenceUpdateActions extends ConpherenceConstants {
|
||||||
const ADD_PERSON = 'add_person';
|
const ADD_PERSON = 'add_person';
|
||||||
const REMOVE_PERSON = 'remove_person';
|
const REMOVE_PERSON = 'remove_person';
|
||||||
const NOTIFICATIONS = 'notifications';
|
const NOTIFICATIONS = 'notifications';
|
||||||
|
const ADD_STATUS = 'add_status';
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,11 @@ final class ConpherenceWidgetController extends
|
||||||
$conpherence = $this->getConpherence();
|
$conpherence = $this->getConpherence();
|
||||||
|
|
||||||
$widgets = array();
|
$widgets = array();
|
||||||
|
$new_icon = id(new PHUIIconView())
|
||||||
|
->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS)
|
||||||
|
->setSpriteIcon('new-grey')
|
||||||
|
->setHref($this->getWidgetURI())
|
||||||
|
->addSigil('conpherence-widget-adder');
|
||||||
$widgets[] = phutil_tag(
|
$widgets[] = phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
|
@ -75,6 +80,7 @@ final class ConpherenceWidgetController extends
|
||||||
->setHeaderTitle(pht('Participants'))
|
->setHeaderTitle(pht('Participants'))
|
||||||
->setHeaderHref('#')
|
->setHeaderHref('#')
|
||||||
->setDropdown(true)
|
->setDropdown(true)
|
||||||
|
->addAction($new_icon)
|
||||||
->addHeaderSigil('widgets-selector'));
|
->addHeaderSigil('widgets-selector'));
|
||||||
$user = $this->getRequest()->getUser();
|
$user = $this->getRequest()->getUser();
|
||||||
// now the widget bodies
|
// now the widget bodies
|
||||||
|
@ -193,11 +199,11 @@ final class ConpherenceWidgetController extends
|
||||||
$content = array();
|
$content = array();
|
||||||
$layout = id(new AphrontMultiColumnView())
|
$layout = id(new AphrontMultiColumnView())
|
||||||
->setFluidLayout(true);
|
->setFluidLayout(true);
|
||||||
$timestamps = $this->getCalendarWidgetWeekTimestamps();
|
$timestamps = $this->getCalendarWidgetTimestamps();
|
||||||
$today = $timestamps['today'];
|
$today = $timestamps['today'];
|
||||||
$weekstamps = $timestamps['weekstamps'];
|
$epoch_stamps = $timestamps['epoch_stamps'];
|
||||||
$one_day = 24 * 60 * 60;
|
$one_day = 24 * 60 * 60;
|
||||||
foreach ($weekstamps as $time => $day) {
|
foreach ($epoch_stamps as $time => $day) {
|
||||||
// build a header for the new day
|
// build a header for the new day
|
||||||
if ($day->format('w') == $today->format('w')) {
|
if ($day->format('w') == $today->format('w')) {
|
||||||
$active_class = 'today';
|
$active_class = 'today';
|
||||||
|
@ -227,7 +233,6 @@ final class ConpherenceWidgetController extends
|
||||||
|
|
||||||
$week_day_number = $day->format('w');
|
$week_day_number = $day->format('w');
|
||||||
|
|
||||||
|
|
||||||
$day->setTime(0, 0, 0);
|
$day->setTime(0, 0, 0);
|
||||||
$epoch_start = $day->format('U');
|
$epoch_start = $day->format('U');
|
||||||
$next_day = clone $day;
|
$next_day = clone $day;
|
||||||
|
@ -371,24 +376,20 @@ final class ConpherenceWidgetController extends
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getCalendarWidgetWeekTimestamps() {
|
private function getCalendarWidgetTimestamps() {
|
||||||
$user = $this->getRequest()->getUser();
|
$user = $this->getRequest()->getUser();
|
||||||
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
|
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
|
||||||
|
|
||||||
$today = id(new DateTime('now', $timezone));
|
$today = id(new DateTime('today', $timezone));
|
||||||
$monday = clone $today;
|
|
||||||
$monday
|
|
||||||
->modify('+1 day')
|
|
||||||
->modify('last monday');
|
|
||||||
$timestamps = array();
|
$timestamps = array();
|
||||||
for ($day = 0; $day < 7; $day++) {
|
for ($day = 0; $day < 3; $day++) {
|
||||||
$timestamp = clone $monday;
|
$timestamp = clone $today;
|
||||||
$timestamps[] = $timestamp->modify(sprintf('+%d days', $day));
|
$timestamps[] = $timestamp->modify(sprintf('+%d days', $day));
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'today' => $today,
|
'today' => $today,
|
||||||
'weekstamps' => $timestamps
|
'epoch_stamps' => $timestamps
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,21 +217,21 @@ final class ConpherenceThreadQuery
|
||||||
$file_phids = array_mergev($file_phids);
|
$file_phids = array_mergev($file_phids);
|
||||||
|
|
||||||
// statuses of everyone currently in the conpherence
|
// statuses of everyone currently in the conpherence
|
||||||
// for a rolling one week window
|
// for a rolling three day window
|
||||||
$start_of_week = phabricator_format_local_time(
|
$start_epoch = phabricator_format_local_time(
|
||||||
strtotime('last monday', strtotime('tomorrow')),
|
strtotime('today', strtotime('tomorrow')),
|
||||||
$this->getViewer(),
|
$this->getViewer(),
|
||||||
'U');
|
'U');
|
||||||
$end_of_week = phabricator_format_local_time(
|
$end_epoch = phabricator_format_local_time(
|
||||||
strtotime('last monday +1 week', strtotime('tomorrow')),
|
strtotime('+3 days', strtotime('tomorrow')),
|
||||||
$this->getViewer(),
|
$this->getViewer(),
|
||||||
'U');
|
'U');
|
||||||
$statuses = id(new PhabricatorUserStatus())
|
$statuses = id(new PhabricatorUserStatus())
|
||||||
->loadAllWhere(
|
->loadAllWhere(
|
||||||
'userPHID in (%Ls) AND dateTo >= %d AND dateFrom <= %d',
|
'userPHID in (%Ls) AND dateTo >= %d AND dateFrom <= %d',
|
||||||
$participant_phids,
|
$participant_phids,
|
||||||
$start_of_week,
|
$start_epoch,
|
||||||
$end_of_week);
|
$end_epoch);
|
||||||
$statuses = mgroup($statuses, 'getUserPHID');
|
$statuses = mgroup($statuses, 'getUserPHID');
|
||||||
|
|
||||||
// attached files
|
// attached files
|
||||||
|
|
|
@ -82,22 +82,28 @@ final class ConpherenceLayoutView extends AphrontView {
|
||||||
'conpherence-message-pane' => array(
|
'conpherence-message-pane' => array(
|
||||||
'name' => pht('Thread'),
|
'name' => pht('Thread'),
|
||||||
'deviceOnly' => true,
|
'deviceOnly' => true,
|
||||||
|
'hasCreate' => false
|
||||||
),
|
),
|
||||||
'widgets-people' => array(
|
'widgets-people' => array(
|
||||||
'name' => pht('Participants'),
|
'name' => pht('Participants'),
|
||||||
'deviceOnly' => false,
|
'deviceOnly' => false,
|
||||||
|
'hasCreate' => false
|
||||||
),
|
),
|
||||||
'widgets-files' => array(
|
'widgets-files' => array(
|
||||||
'name' => pht('Files'),
|
'name' => pht('Files'),
|
||||||
'deviceOnly' => false,
|
'deviceOnly' => false,
|
||||||
|
'hasCreate' => false
|
||||||
),
|
),
|
||||||
'widgets-calendar' => array(
|
'widgets-calendar' => array(
|
||||||
'name' => pht('Calendar'),
|
'name' => pht('Calendar'),
|
||||||
'deviceOnly' => false,
|
'deviceOnly' => false,
|
||||||
|
'hasCreate' => true,
|
||||||
|
'createHref' => '/calendar/status/create/'
|
||||||
),
|
),
|
||||||
'widgets-settings' => array(
|
'widgets-settings' => array(
|
||||||
'name' => pht('Settings'),
|
'name' => pht('Settings'),
|
||||||
'deviceOnly' => false,
|
'deviceOnly' => false,
|
||||||
|
'hasCreate' => false
|
||||||
),
|
),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
|
|
@ -145,10 +145,10 @@
|
||||||
/* calendar widget */
|
/* calendar widget */
|
||||||
|
|
||||||
.conpherence-widget-pane #widgets-calendar .aphront-multi-column-view {
|
.conpherence-widget-pane #widgets-calendar .aphront-multi-column-view {
|
||||||
margin: 2px 0px 0px 0px;
|
|
||||||
width: 240px;
|
width: 240px;
|
||||||
}
|
}
|
||||||
.device .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view {
|
.device .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view {
|
||||||
|
margin: 2px 0px 0px 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.conpherence-widget-pane #widgets-calendar .aphront-multi-column-view
|
.conpherence-widget-pane #widgets-calendar .aphront-multi-column-view
|
||||||
|
|
|
@ -138,11 +138,7 @@ JX.behavior('conpherence-menu', function(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_thread.visible !== null || !config.hasWidgets) {
|
if (_thread.visible !== null || !config.hasWidgets) {
|
||||||
markWidgetLoading(true);
|
reloadWidget(data);
|
||||||
var widget_uri = config.baseURI + 'widget/' + data.threadID + '/';
|
|
||||||
new JX.Workflow(widget_uri, {})
|
|
||||||
.setHandler(JX.bind(null, onWidgetResponse, data.threadID))
|
|
||||||
.start();
|
|
||||||
} else {
|
} else {
|
||||||
JX.Stratcom.invoke(
|
JX.Stratcom.invoke(
|
||||||
'conpherence-update-widgets',
|
'conpherence-update-widgets',
|
||||||
|
@ -191,7 +187,29 @@ JX.behavior('conpherence-menu', function(config) {
|
||||||
JX.DOM.alterClass(widgets_root, 'loading', loading);
|
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 :/
|
// we got impatient and this is no longer the right answer :/
|
||||||
if (_thread.selected != thread_id) {
|
if (_thread.selected != thread_id) {
|
||||||
return;
|
return;
|
||||||
|
@ -204,7 +222,7 @@ JX.behavior('conpherence-menu', function(config) {
|
||||||
'conpherence-update-widgets',
|
'conpherence-update-widgets',
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
widget : getDefaultWidget(),
|
widget : widget,
|
||||||
buildSelectors : true,
|
buildSelectors : true,
|
||||||
toggleWidget : true,
|
toggleWidget : true,
|
||||||
threadID : _thread.selected
|
threadID : _thread.selected
|
||||||
|
|
|
@ -169,12 +169,18 @@ JX.behavior('conpherence-widget-pane', function(config) {
|
||||||
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
||||||
var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
|
var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
|
||||||
var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector');
|
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(
|
JX.DOM.setContent(
|
||||||
widget_header,
|
widget_header,
|
||||||
widget_data.name);
|
widget_data.name);
|
||||||
JX.DOM.appendContent(
|
JX.DOM.appendContent(
|
||||||
widget_header,
|
widget_header,
|
||||||
JX.$N('span', { className : 'caret' }));
|
JX.$N('span', { className : 'caret' }));
|
||||||
|
if (widget_data.hasCreate) {
|
||||||
|
JX.DOM.show(adder);
|
||||||
|
} else {
|
||||||
|
JX.DOM.hide(adder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var widget in config.widgetRegistry) {
|
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 */
|
/* people widget */
|
||||||
JX.Stratcom.listen(
|
JX.Stratcom.listen(
|
||||||
['submit', 'didSyntheticSubmit'],
|
['submit', 'didSyntheticSubmit'],
|
||||||
|
|
Loading…
Reference in a new issue