mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-02 03:32:42 +01:00
Improve notification list view
Summary: - Provide a filter to show just unread notifications. - Visually show which notifications are unread. - Style tweaks to make notifications more readable. Test Plan: {F13494} Reviewers: btrahan, jungejason Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D2883
This commit is contained in:
parent
0c321d8176
commit
1e3cd8afa8
5 changed files with 107 additions and 30 deletions
|
@ -2315,7 +2315,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'phabricator-standard-page-view' =>
|
'phabricator-standard-page-view' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/b9c03b7b/rsrc/css/application/base/standard-page-view.css',
|
'uri' => '/res/a233253a/rsrc/css/application/base/standard-page-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -2570,7 +2570,7 @@ celerity_register_resource_map(array(
|
||||||
), array(
|
), array(
|
||||||
'packages' =>
|
'packages' =>
|
||||||
array(
|
array(
|
||||||
68157940 =>
|
'a05e3ec6' =>
|
||||||
array(
|
array(
|
||||||
'name' => 'core.pkg.css',
|
'name' => 'core.pkg.css',
|
||||||
'symbols' =>
|
'symbols' =>
|
||||||
|
@ -2599,7 +2599,7 @@ celerity_register_resource_map(array(
|
||||||
21 => 'phabricator-flag-css',
|
21 => 'phabricator-flag-css',
|
||||||
22 => 'aphront-error-view-css',
|
22 => 'aphront-error-view-css',
|
||||||
),
|
),
|
||||||
'uri' => '/res/pkg/68157940/core.pkg.css',
|
'uri' => '/res/pkg/a05e3ec6/core.pkg.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
),
|
),
|
||||||
'f363b322' =>
|
'f363b322' =>
|
||||||
|
@ -2766,20 +2766,20 @@ celerity_register_resource_map(array(
|
||||||
'reverse' =>
|
'reverse' =>
|
||||||
array(
|
array(
|
||||||
'aphront-attached-file-view-css' => '7839ae2d',
|
'aphront-attached-file-view-css' => '7839ae2d',
|
||||||
'aphront-crumbs-view-css' => '68157940',
|
'aphront-crumbs-view-css' => 'a05e3ec6',
|
||||||
'aphront-dialog-view-css' => '68157940',
|
'aphront-dialog-view-css' => 'a05e3ec6',
|
||||||
'aphront-error-view-css' => '68157940',
|
'aphront-error-view-css' => 'a05e3ec6',
|
||||||
'aphront-form-view-css' => '68157940',
|
'aphront-form-view-css' => 'a05e3ec6',
|
||||||
'aphront-headsup-action-list-view-css' => '32f461a4',
|
'aphront-headsup-action-list-view-css' => '32f461a4',
|
||||||
'aphront-headsup-view-css' => '68157940',
|
'aphront-headsup-view-css' => 'a05e3ec6',
|
||||||
'aphront-list-filter-view-css' => '68157940',
|
'aphront-list-filter-view-css' => 'a05e3ec6',
|
||||||
'aphront-pager-view-css' => '68157940',
|
'aphront-pager-view-css' => 'a05e3ec6',
|
||||||
'aphront-panel-view-css' => '68157940',
|
'aphront-panel-view-css' => 'a05e3ec6',
|
||||||
'aphront-side-nav-view-css' => '68157940',
|
'aphront-side-nav-view-css' => 'a05e3ec6',
|
||||||
'aphront-table-view-css' => '68157940',
|
'aphront-table-view-css' => 'a05e3ec6',
|
||||||
'aphront-tokenizer-control-css' => '68157940',
|
'aphront-tokenizer-control-css' => 'a05e3ec6',
|
||||||
'aphront-tooltip-css' => '68157940',
|
'aphront-tooltip-css' => 'a05e3ec6',
|
||||||
'aphront-typeahead-control-css' => '68157940',
|
'aphront-typeahead-control-css' => 'a05e3ec6',
|
||||||
'differential-changeset-view-css' => '32f461a4',
|
'differential-changeset-view-css' => '32f461a4',
|
||||||
'differential-core-view-css' => '32f461a4',
|
'differential-core-view-css' => '32f461a4',
|
||||||
'differential-inline-comment-editor' => 'f4bbbd84',
|
'differential-inline-comment-editor' => 'f4bbbd84',
|
||||||
|
@ -2845,15 +2845,15 @@ celerity_register_resource_map(array(
|
||||||
'javelin-workflow' => 'f363b322',
|
'javelin-workflow' => 'f363b322',
|
||||||
'maniphest-task-summary-css' => '7839ae2d',
|
'maniphest-task-summary-css' => '7839ae2d',
|
||||||
'maniphest-transaction-detail-css' => '7839ae2d',
|
'maniphest-transaction-detail-css' => '7839ae2d',
|
||||||
'phabricator-app-buttons-css' => '68157940',
|
'phabricator-app-buttons-css' => 'a05e3ec6',
|
||||||
'phabricator-content-source-view-css' => '32f461a4',
|
'phabricator-content-source-view-css' => '32f461a4',
|
||||||
'phabricator-core-buttons-css' => '68157940',
|
'phabricator-core-buttons-css' => 'a05e3ec6',
|
||||||
'phabricator-core-css' => '68157940',
|
'phabricator-core-css' => 'a05e3ec6',
|
||||||
'phabricator-directory-css' => '68157940',
|
'phabricator-directory-css' => 'a05e3ec6',
|
||||||
'phabricator-drag-and-drop-file-upload' => 'f4bbbd84',
|
'phabricator-drag-and-drop-file-upload' => 'f4bbbd84',
|
||||||
'phabricator-dropdown-menu' => 'f363b322',
|
'phabricator-dropdown-menu' => 'f363b322',
|
||||||
'phabricator-flag-css' => '68157940',
|
'phabricator-flag-css' => 'a05e3ec6',
|
||||||
'phabricator-jump-nav' => '68157940',
|
'phabricator-jump-nav' => 'a05e3ec6',
|
||||||
'phabricator-keyboard-shortcut' => 'f363b322',
|
'phabricator-keyboard-shortcut' => 'f363b322',
|
||||||
'phabricator-keyboard-shortcut-manager' => 'f363b322',
|
'phabricator-keyboard-shortcut-manager' => 'f363b322',
|
||||||
'phabricator-menu-item' => 'f363b322',
|
'phabricator-menu-item' => 'f363b322',
|
||||||
|
@ -2861,11 +2861,11 @@ celerity_register_resource_map(array(
|
||||||
'phabricator-paste-file-upload' => 'f363b322',
|
'phabricator-paste-file-upload' => 'f363b322',
|
||||||
'phabricator-prefab' => 'f363b322',
|
'phabricator-prefab' => 'f363b322',
|
||||||
'phabricator-project-tag-css' => '7839ae2d',
|
'phabricator-project-tag-css' => '7839ae2d',
|
||||||
'phabricator-remarkup-css' => '68157940',
|
'phabricator-remarkup-css' => 'a05e3ec6',
|
||||||
'phabricator-shaped-request' => 'f4bbbd84',
|
'phabricator-shaped-request' => 'f4bbbd84',
|
||||||
'phabricator-standard-page-view' => '68157940',
|
'phabricator-standard-page-view' => 'a05e3ec6',
|
||||||
'phabricator-tooltip' => 'f363b322',
|
'phabricator-tooltip' => 'f363b322',
|
||||||
'phabricator-transaction-view-css' => '68157940',
|
'phabricator-transaction-view-css' => 'a05e3ec6',
|
||||||
'syntax-highlighting-css' => '68157940',
|
'syntax-highlighting-css' => 'a05e3ec6',
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
|
@ -427,7 +427,8 @@ class AphrontDefaultApplicationConfiguration
|
||||||
),
|
),
|
||||||
|
|
||||||
'/notification/' => array(
|
'/notification/' => array(
|
||||||
'' => 'PhabricatorNotificationListController',
|
'(?:(?P<filter>all|unread)/)?'
|
||||||
|
=> 'PhabricatorNotificationListController',
|
||||||
'panel/' => 'PhabricatorNotificationPanelController',
|
'panel/' => 'PhabricatorNotificationPanelController',
|
||||||
'individual/' => 'PhabricatorNotificationIndividualController',
|
'individual/' => 'PhabricatorNotificationIndividualController',
|
||||||
'status/' => 'PhabricatorNotificationStatusController',
|
'status/' => 'PhabricatorNotificationStatusController',
|
||||||
|
|
|
@ -16,10 +16,19 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task config Configuring the Query
|
||||||
|
* @task exec Query Execution
|
||||||
|
*/
|
||||||
final class PhabricatorNotificationQuery extends PhabricatorOffsetPagedQuery {
|
final class PhabricatorNotificationQuery extends PhabricatorOffsetPagedQuery {
|
||||||
|
|
||||||
private $userPHID;
|
private $userPHID;
|
||||||
private $keys;
|
private $keys;
|
||||||
|
private $unread;
|
||||||
|
|
||||||
|
|
||||||
|
/* -( Configuring the Query )---------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
public function setUserPHID($user_phid) {
|
public function setUserPHID($user_phid) {
|
||||||
$this->userPHID = $user_phid;
|
$this->userPHID = $user_phid;
|
||||||
|
@ -31,6 +40,26 @@ final class PhabricatorNotificationQuery extends PhabricatorOffsetPagedQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter results by read/unread status. Note that `true` means to return
|
||||||
|
* only unread notifications, while `false` means to return only //read//
|
||||||
|
* notifications. The default is `null`, which returns both.
|
||||||
|
*
|
||||||
|
* @param mixed True or false to filter results by read status. Null to remove
|
||||||
|
* the filter.
|
||||||
|
* @return this
|
||||||
|
* @task config
|
||||||
|
*/
|
||||||
|
public function withUnread($unread) {
|
||||||
|
$this->unread = $unread;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( Query Execution )---------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
public function execute() {
|
public function execute() {
|
||||||
if (!$this->userPHID) {
|
if (!$this->userPHID) {
|
||||||
throw new Exception("Call setUser() before executing the query");
|
throw new Exception("Call setUser() before executing the query");
|
||||||
|
@ -89,6 +118,13 @@ final class PhabricatorNotificationQuery extends PhabricatorOffsetPagedQuery {
|
||||||
$this->userPHID);
|
$this->userPHID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->unread !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'notif.hasViewed = %d',
|
||||||
|
(int)!$this->unread);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->keys) {
|
if ($this->keys) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
|
|
|
@ -19,16 +19,41 @@
|
||||||
final class PhabricatorNotificationListController
|
final class PhabricatorNotificationListController
|
||||||
extends PhabricatorNotificationController {
|
extends PhabricatorNotificationController {
|
||||||
|
|
||||||
|
private $filter;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->filter = idx($data, 'filter');
|
||||||
|
}
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$nav = new AphrontSideNavFilterView();
|
||||||
|
$nav->setBaseURI(new PhutilURI('/notification/'));
|
||||||
|
$nav->addFilter('all', 'All Notifications');
|
||||||
|
$nav->addFilter('unread', 'Unread Notifications');
|
||||||
|
$filter = $nav->selectFilter($this->filter, 'all');
|
||||||
|
|
||||||
$pager = new AphrontPagerView();
|
$pager = new AphrontPagerView();
|
||||||
$pager->setURI($request->getRequestURI(), 'offset');
|
$pager->setURI($request->getRequestURI(), 'offset');
|
||||||
$pager->setOffset($request->getInt('offset'));
|
$pager->setOffset($request->getInt('offset'));
|
||||||
|
|
||||||
$query = new PhabricatorNotificationQuery();
|
$query = new PhabricatorNotificationQuery();
|
||||||
$query->setUserPHID($user->getPHID());
|
$query->setUserPHID($user->getPHID());
|
||||||
|
|
||||||
|
switch ($filter) {
|
||||||
|
case 'unread':
|
||||||
|
$query->withUnread(true);
|
||||||
|
$header = pht('Unread Notifications');
|
||||||
|
$no_data = pht('You have no unread notifications.');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$header = pht('Notifications');
|
||||||
|
$no_data = pht('You have no notifications.');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$notifications = $query->executeWithPager($pager);
|
$notifications = $query->executeWithPager($pager);
|
||||||
|
|
||||||
if ($notifications) {
|
if ($notifications) {
|
||||||
|
@ -37,12 +62,19 @@ final class PhabricatorNotificationListController
|
||||||
} else {
|
} else {
|
||||||
$view =
|
$view =
|
||||||
'<div class="phabricator-notification no-notifications">'.
|
'<div class="phabricator-notification no-notifications">'.
|
||||||
'You have no notifications.'.
|
$no_data.
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$view = array(
|
||||||
|
'<div class="phabricator-notification-list">',
|
||||||
|
$view,
|
||||||
|
'</div>',
|
||||||
|
);
|
||||||
|
|
||||||
$panel = new AphrontPanelView();
|
$panel = new AphrontPanelView();
|
||||||
$panel->setHeader('Notifications');
|
$panel->setHeader($header);
|
||||||
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
$panel->addButton(
|
$panel->addButton(
|
||||||
javelin_render_tag(
|
javelin_render_tag(
|
||||||
'a',
|
'a',
|
||||||
|
@ -55,8 +87,10 @@ final class PhabricatorNotificationListController
|
||||||
$panel->appendChild($view);
|
$panel->appendChild($view);
|
||||||
$panel->appendChild($pager);
|
$panel->appendChild($pager);
|
||||||
|
|
||||||
|
$nav->appendChild($panel);
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
$panel,
|
$nav,
|
||||||
array(
|
array(
|
||||||
'title' => 'Notifications',
|
'title' => 'Notifications',
|
||||||
));
|
));
|
||||||
|
|
|
@ -301,12 +301,18 @@ a.handle-disabled {
|
||||||
|
|
||||||
.phabricator-notification {
|
.phabricator-notification {
|
||||||
padding: 6px 6px;
|
padding: 6px 6px;
|
||||||
|
margin: 1px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-notifications {
|
.no-notifications {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phabricator-notification-list {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-notification-list .phabricator-notification-unread,
|
||||||
#phabricator-notification-dropdown .phabricator-notification-unread {
|
#phabricator-notification-dropdown .phabricator-notification-unread {
|
||||||
background: #aacfef;
|
background: #aacfef;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue