mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-29 08:50:58 +01:00
Subscriptions - make a dialog for massive subscription lists
Summary: Ref T4430. This just deploys it on the property lists. (Help on how to do translations better? I tried a more traditional pht('%s, %s, %s, and %d other(s)') but I think the string lookup assumes the %d comes as the second param or something?) Test Plan: Made a Maniphest Task with a hojillion subscribers and noted the working dialogue. Also made a Pholio Mock with lots of subscribers and it worked. Reviewers: epriestley Reviewed By: epriestley Subscribers: aran, epriestley, Korvin, chad Maniphest Tasks: T4430 Differential Revision: https://secure.phabricator.com/D8525
This commit is contained in:
parent
f1637961e7
commit
c7079b52a2
10 changed files with 230 additions and 11 deletions
|
@ -109,6 +109,7 @@ return array(
|
||||||
'rsrc/css/application/search/search-results.css' => 'f240504c',
|
'rsrc/css/application/search/search-results.css' => 'f240504c',
|
||||||
'rsrc/css/application/settings/settings.css' => 'ea8f5915',
|
'rsrc/css/application/settings/settings.css' => 'ea8f5915',
|
||||||
'rsrc/css/application/slowvote/slowvote.css' => '266df6a1',
|
'rsrc/css/application/slowvote/slowvote.css' => '266df6a1',
|
||||||
|
'rsrc/css/application/subscriptions/subscribers-list.css' => '5bb30c78',
|
||||||
'rsrc/css/application/tokens/tokens.css' => 'fb286311',
|
'rsrc/css/application/tokens/tokens.css' => 'fb286311',
|
||||||
'rsrc/css/application/uiexample/example.css' => '4741b891',
|
'rsrc/css/application/uiexample/example.css' => '4741b891',
|
||||||
'rsrc/css/core/core.css' => 'da26ddb2',
|
'rsrc/css/core/core.css' => 'da26ddb2',
|
||||||
|
@ -804,6 +805,7 @@ return array(
|
||||||
'sprite-projects-css' => '7578fa56',
|
'sprite-projects-css' => '7578fa56',
|
||||||
'sprite-status-css' => '8bce1c97',
|
'sprite-status-css' => '8bce1c97',
|
||||||
'sprite-tokens-css' => '1706b943',
|
'sprite-tokens-css' => '1706b943',
|
||||||
|
'subscribers-list-css' => '5bb30c78',
|
||||||
'syntax-highlighting-css' => '3c18c1cb',
|
'syntax-highlighting-css' => '3c18c1cb',
|
||||||
'tokens-css' => 'fb286311',
|
'tokens-css' => 'fb286311',
|
||||||
),
|
),
|
||||||
|
|
|
@ -2092,6 +2092,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
|
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
|
||||||
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
|
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
|
||||||
'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
|
'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
|
||||||
|
'PhabricatorSubscriptionsListController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsListController.php',
|
||||||
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
|
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
|
||||||
'PhabricatorSymbolNameLinter' => 'infrastructure/lint/hook/PhabricatorSymbolNameLinter.php',
|
'PhabricatorSymbolNameLinter' => 'infrastructure/lint/hook/PhabricatorSymbolNameLinter.php',
|
||||||
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
|
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
|
||||||
|
@ -2521,6 +2522,8 @@ phutil_register_library_map(array(
|
||||||
'SleepBuildStepImplementation' => 'applications/harbormaster/step/SleepBuildStepImplementation.php',
|
'SleepBuildStepImplementation' => 'applications/harbormaster/step/SleepBuildStepImplementation.php',
|
||||||
'SlowvoteEmbedView' => 'applications/slowvote/view/SlowvoteEmbedView.php',
|
'SlowvoteEmbedView' => 'applications/slowvote/view/SlowvoteEmbedView.php',
|
||||||
'SlowvoteRemarkupRule' => 'applications/slowvote/remarkup/SlowvoteRemarkupRule.php',
|
'SlowvoteRemarkupRule' => 'applications/slowvote/remarkup/SlowvoteRemarkupRule.php',
|
||||||
|
'SubscriptionListDialogBuilder' => 'applications/subscriptions/view/SubscriptionListDialogBuilder.php',
|
||||||
|
'SubscriptionListStringBuilder' => 'applications/subscriptions/view/SubscriptionListStringBuilder.php',
|
||||||
'UploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/UploadArtifactBuildStepImplementation.php',
|
'UploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/UploadArtifactBuildStepImplementation.php',
|
||||||
'VariableBuildStepImplementation' => 'applications/harbormaster/step/VariableBuildStepImplementation.php',
|
'VariableBuildStepImplementation' => 'applications/harbormaster/step/VariableBuildStepImplementation.php',
|
||||||
'WaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php',
|
'WaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php',
|
||||||
|
@ -4889,6 +4892,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
|
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
|
||||||
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
|
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
|
||||||
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
|
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
|
||||||
|
'PhabricatorSubscriptionsListController' => 'PhabricatorController',
|
||||||
'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
|
'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
|
||||||
'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
|
'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
|
||||||
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
|
|
@ -516,11 +516,13 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||||
pht('Priority'),
|
pht('Priority'),
|
||||||
ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
|
ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
|
||||||
|
|
||||||
$view->addProperty(
|
$handles = $this->getLoadedHandles();
|
||||||
pht('Subscribers'),
|
$cc_handles = array_select_keys($handles, $task->getCCPHIDs());
|
||||||
$task->getCCPHIDs()
|
$subscriber_html = id(new SubscriptionListStringBuilder())
|
||||||
? $this->renderHandlesForPHIDs($task->getCCPHIDs(), ',')
|
->setObjectPHID($task->getPHID())
|
||||||
: phutil_tag('em', array(), pht('None')));
|
->setHandles($cc_handles)
|
||||||
|
->buildPropertyString();
|
||||||
|
$view->addProperty(pht('Subscribers'), $subscriber_html);
|
||||||
|
|
||||||
$view->addProperty(
|
$view->addProperty(
|
||||||
pht('Author'),
|
pht('Author'),
|
||||||
|
|
|
@ -21,6 +21,7 @@ final class PhabricatorApplicationSubscriptions extends PhabricatorApplication {
|
||||||
'/subscriptions/' => array(
|
'/subscriptions/' => array(
|
||||||
'(?P<action>add|delete)/'.
|
'(?P<action>add|delete)/'.
|
||||||
'(?P<phid>[^/]+)/' => 'PhabricatorSubscriptionsEditController',
|
'(?P<phid>[^/]+)/' => 'PhabricatorSubscriptionsEditController',
|
||||||
|
'list/(?P<phid>[^/]+)/' => 'PhabricatorSubscriptionsListController',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorSubscriptionsListController
|
||||||
|
extends PhabricatorController {
|
||||||
|
|
||||||
|
private $phid;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->phid = idx($data, 'phid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
$phid = $this->phid;
|
||||||
|
|
||||||
|
$object = id(new PhabricatorObjectQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($phid))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if ($object instanceof PhabricatorSubscribableInterface) {
|
||||||
|
$subscriber_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
||||||
|
$phid);
|
||||||
|
} else if ($object instanceof ManiphestTask) {
|
||||||
|
$subscriber_phids = $object->getCCPHIDs();
|
||||||
|
}
|
||||||
|
|
||||||
|
$handle_phids = $subscriber_phids;
|
||||||
|
$handle_phids[] = $phid;
|
||||||
|
|
||||||
|
$handles = id(new PhabricatorHandleQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs($handle_phids)
|
||||||
|
->execute();
|
||||||
|
$object_handle = $handles[$phid];
|
||||||
|
|
||||||
|
$dialog = id(new SubscriptionListDialogBuilder())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setTitle(pht('Subscribers for %s', $object_handle->getFullName()))
|
||||||
|
->setObjectPHID($phid)
|
||||||
|
->setHandles($handles)
|
||||||
|
->buildDialog();
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -113,14 +113,13 @@ final class PhabricatorSubscriptionsUIEventListener
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withPHIDs($subscribers)
|
->withPHIDs($subscribers)
|
||||||
->execute();
|
->execute();
|
||||||
$sub_view = array();
|
|
||||||
foreach ($subscribers as $subscriber) {
|
|
||||||
$sub_view[] = $handles[$subscriber]->renderLink();
|
|
||||||
}
|
|
||||||
$sub_view = phutil_implode_html(', ', $sub_view);
|
|
||||||
} else {
|
} else {
|
||||||
$sub_view = phutil_tag('em', array(), pht('None'));
|
$handles = array();
|
||||||
}
|
}
|
||||||
|
$sub_view = id(new SubscriptionListStringBuilder())
|
||||||
|
->setObjectPHID($object->getPHID())
|
||||||
|
->setHandles($handles)
|
||||||
|
->buildPropertyString();
|
||||||
|
|
||||||
$view = $event->getValue('view');
|
$view = $event->getValue('view');
|
||||||
$view->addProperty(pht('Subscribers'), $sub_view);
|
$view->addProperty(pht('Subscribers'), $sub_view);
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class SubscriptionListDialogBuilder {
|
||||||
|
|
||||||
|
private $viewer;
|
||||||
|
private $handles;
|
||||||
|
private $objectPHID;
|
||||||
|
private $title;
|
||||||
|
|
||||||
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
|
$this->viewer = $viewer;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViewer() {
|
||||||
|
return $this->viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setHandles(array $handles) {
|
||||||
|
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
||||||
|
$this->handles = $handles;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHandles() {
|
||||||
|
return $this->handles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setObjectPHID($object_phid) {
|
||||||
|
$this->objectPHID = $object_phid;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObjectPHID() {
|
||||||
|
return $this->objectPHID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle($title) {
|
||||||
|
$this->title = $title;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildDialog() {
|
||||||
|
$phid = $this->getObjectPHID();
|
||||||
|
$handles = $this->getHandles();
|
||||||
|
$object_handle = $handles[$phid];
|
||||||
|
unset($handles[$phid]);
|
||||||
|
|
||||||
|
require_celerity_resource('subscribers-list-css');
|
||||||
|
return id(new AphrontDialogView())
|
||||||
|
->setUser($this->getViewer())
|
||||||
|
->setClass('subscriber-list-dialog')
|
||||||
|
->setTitle($this->getTitle())
|
||||||
|
->appendChild($this->buildBody($this->getViewer(), $handles))
|
||||||
|
->addCancelButton($object_handle->getURI(), pht('Dismiss'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildBody(PhabricatorUser $viewer, array $handles) {
|
||||||
|
|
||||||
|
$list = id(new PHUIObjectItemListView())
|
||||||
|
->setUser($viewer);
|
||||||
|
foreach ($handles as $handle) {
|
||||||
|
// TODO - include $handle image - T4400
|
||||||
|
$item = id(new PHUIObjectItemView())
|
||||||
|
->setHeader($handle->getFullName())
|
||||||
|
->setHref($handle->getURI())
|
||||||
|
->setDisabled($handle->isDisabled());
|
||||||
|
$list->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class SubscriptionListStringBuilder {
|
||||||
|
|
||||||
|
private $handles;
|
||||||
|
private $objectPHID;
|
||||||
|
|
||||||
|
public function setHandles(array $handles) {
|
||||||
|
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
||||||
|
$this->handles = $handles;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHandles() {
|
||||||
|
return $this->handles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setObjectPHID($object_phid) {
|
||||||
|
$this->objectPHID = $object_phid;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObjectPHID() {
|
||||||
|
return $this->objectPHID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildPropertyString() {
|
||||||
|
$phid = $this->getObjectPHID();
|
||||||
|
$handles = $this->getHandles();
|
||||||
|
|
||||||
|
if (!$handles) {
|
||||||
|
return phutil_tag('em', array(), pht('None'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = array();
|
||||||
|
$show_count = 3;
|
||||||
|
$subscribers_count = count($handles);
|
||||||
|
if ($subscribers_count <= $show_count) {
|
||||||
|
return phutil_implode_html(', ', mpull($handles, 'renderLink'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array('%s, %s, %s, and %s');
|
||||||
|
$shown = 0;
|
||||||
|
foreach ($handles as $handle) {
|
||||||
|
$shown++;
|
||||||
|
if ($shown > $show_count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$args[] = $handle->renderLink();
|
||||||
|
}
|
||||||
|
$not_shown_count = $subscribers_count - $show_count;
|
||||||
|
$not_shown_txt = pht('%d other(s)', $not_shown_count);
|
||||||
|
$args[] = javelin_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/subscriptions/list/'.$phid.'/',
|
||||||
|
'sigil' => 'workflow'
|
||||||
|
),
|
||||||
|
$not_shown_txt);
|
||||||
|
|
||||||
|
return call_user_func_array('pht', $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -541,6 +541,11 @@ abstract class PhabricatorBaseEnglishTranslation
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'%d other(s)' => array(
|
||||||
|
'1 other',
|
||||||
|
'%d others',
|
||||||
|
),
|
||||||
|
|
||||||
'%s edited subscriber(s), added %d: %s; removed %d: %s.' =>
|
'%s edited subscriber(s), added %d: %s; removed %d: %s.' =>
|
||||||
'%s edited subscribers, added: %3$s; removed: %5$s',
|
'%s edited subscribers, added: %3$s; removed: %5$s',
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
/**
|
||||||
|
* @provides subscribers-list-css
|
||||||
|
*/
|
||||||
|
|
||||||
|
.subscriber-list-dialog {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subscriber-list-dialog .aphront-dialog-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subscriber-list-dialog .phui-object-item-list-view {
|
||||||
|
margin: 0;
|
||||||
|
}
|
Loading…
Reference in a new issue