Page MenuHomePhabricator

D8685.diff
No OneTemporary

D8685.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,7 +7,7 @@
return array(
'names' =>
array(
- 'core.pkg.css' => 'c00e58c8',
+ 'core.pkg.css' => '9dc1daac',
'core.pkg.js' => 'b2ed04a2',
'darkconsole.pkg.js' => 'ca8671ce',
'differential.pkg.css' => '4b8686e3',
@@ -105,7 +105,7 @@
'rsrc/css/application/subscriptions/subscribers-list.css' => '5bb30c78',
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
'rsrc/css/application/uiexample/example.css' => '528b19de',
- 'rsrc/css/core/core.css' => '40151074',
+ 'rsrc/css/core/core.css' => '7c767604',
'rsrc/css/core/remarkup.css' => '80c3a48c',
'rsrc/css/core/syntax.css' => '3c18c1cb',
'rsrc/css/core/z-index.css' => 'efb673ac',
@@ -115,7 +115,7 @@
'rsrc/css/font/font-source-sans-pro.css' => '91d53463',
'rsrc/css/font/phui-font-icon-base.css' => 'cd92ff25',
'rsrc/css/layout/phabricator-action-header-view.css' => 'c14dfc57',
- 'rsrc/css/layout/phabricator-action-list-view.css' => '6f7ef696',
+ 'rsrc/css/layout/phabricator-action-list-view.css' => '64c0d17c',
'rsrc/css/layout/phabricator-crumbs-view.css' => '0222cbe0',
'rsrc/css/layout/phabricator-filetree-view.css' => 'a8c86ace',
'rsrc/css/layout/phabricator-hovercard-view.css' => '46a13cf0',
@@ -139,7 +139,7 @@
'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec',
'rsrc/css/phui/phui-object-item-list-view.css' => '7cf6ccf9',
'rsrc/css/phui/phui-pinboard-view.css' => 'e7d3b05e',
- 'rsrc/css/phui/phui-property-list-view.css' => 'af4b381f',
+ 'rsrc/css/phui/phui-property-list-view.css' => 'ddb13477',
'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b',
'rsrc/css/phui/phui-spacing.css' => '042804d6',
'rsrc/css/phui/phui-status.css' => '2f562399',
@@ -688,12 +688,12 @@
'path-typeahead' => 'f7fc67ec',
'people-profile-css' => 'ba7b2762',
'phabricator-action-header-view-css' => 'c14dfc57',
- 'phabricator-action-list-view-css' => '6f7ef696',
+ 'phabricator-action-list-view-css' => '64c0d17c',
'phabricator-application-launch-view-css' => 'd290ba21',
'phabricator-busy' => '6453c869',
'phabricator-chatlog-css' => '852140ff',
'phabricator-content-source-view-css' => '4b8b05d4',
- 'phabricator-core-css' => '40151074',
+ 'phabricator-core-css' => '7c767604',
'phabricator-countdown-css' => '86b7b0a0',
'phabricator-crumbs-view-css' => '0222cbe0',
'phabricator-drag-and-drop-file-upload' => 'ae6abfba',
@@ -768,7 +768,7 @@
'phui-object-box-css' => 'ce92d8ec',
'phui-object-item-list-view-css' => '7cf6ccf9',
'phui-pinboard-view-css' => 'e7d3b05e',
- 'phui-property-list-view-css' => 'af4b381f',
+ 'phui-property-list-view-css' => 'ddb13477',
'phui-remarkup-preview-css' => '19ad512b',
'phui-spacing-css' => '042804d6',
'phui-status-list-view-css' => '2f562399',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -3821,7 +3821,7 @@
'PhabricatorActionHeaderView' => 'AphrontView',
'PhabricatorActionListExample' => 'PhabricatorUIExample',
'PhabricatorActionListView' => 'AphrontView',
- 'PhabricatorActionView' => 'AphrontView',
+ 'PhabricatorActionView' => 'AphrontTagView',
'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
'PhabricatorAnchorView' => 'AphrontView',
'PhabricatorAphrontBarExample' => 'PhabricatorUIExample',
diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php
--- a/src/applications/people/controller/PhabricatorPeopleProfileController.php
+++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php
@@ -64,24 +64,35 @@
->setWorkflow(!$can_edit));
if ($viewer->getIsAdmin()) {
+ $dd = phutil_tag('span', array('class' => 'action-view-caret'), '');
+ $admin_text = pht('Admisistrate User %s', $dd);
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('wrench')
+ ->setIsContainer(true)
+ ->setIcon('user')
+ ->setGroupKey('user.admin')
+ ->setName($admin_text));
+
+ $actions->addAction(
+ id(new PhabricatorActionView())
+ ->setGroupKey('user.admin')
+ ->setIcon('none')
->setName(pht('Edit Settings'))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)
->setHref('/settings/'.$user->getID().'/'));
if ($user->getIsAdmin()) {
- $empower_icon = 'lower-priority';
+ $empower_icon = 'none';
$empower_name = pht('Remove Administrator');
} else {
- $empower_icon = 'raise-priority';
+ $empower_icon = 'none';
$empower_name = pht('Make Administrator');
}
$actions->addAction(
id(new PhabricatorActionView())
+ ->setGroupKey('user.admin')
->setIcon($empower_icon)
->setName($empower_name)
->setDisabled(($user->getPHID() == $viewer->getPHID()))
@@ -90,21 +101,23 @@
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('tag')
+ ->setGroupKey('user.admin')
+ ->setIcon('none')
->setName(pht('Change Username'))
->setWorkflow(true)
->setHref($this->getApplicationURI('rename/'.$user->getID().'/')));
if ($user->getIsDisabled()) {
- $disable_icon = 'enable';
+ $disable_icon = 'none';
$disable_name = pht('Enable User');
} else {
- $disable_icon = 'disable';
+ $disable_icon = 'none';
$disable_name = pht('Disable User');
}
$actions->addAction(
id(new PhabricatorActionView())
+ ->setGroupKey('user.admin')
->setIcon($disable_icon)
->setName($disable_name)
->setDisabled(($user->getPHID() == $viewer->getPHID()))
@@ -113,7 +126,8 @@
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('delete')
+ ->setGroupKey('user.admin')
+ ->setIcon('none')
->setName(pht('Delete User'))
->setDisabled(($user->getPHID() == $viewer->getPHID()))
->setWorkflow(true)
@@ -121,7 +135,8 @@
$actions->addAction(
id(new PhabricatorActionView())
- ->setIcon('message')
+ ->setGroupKey('user.admin')
+ ->setIcon('none')
->setName(pht('Send Welcome Email'))
->setWorkflow(true)
->setHref($this->getApplicationURI('welcome/'.$user->getID().'/')));
@@ -131,6 +146,7 @@
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($user->getUsername());
+ $crumbs->setActionList($actions);
$feed = $this->renderUserFeed($user);
$calendar = $this->renderUserCalendar($user);
$activity = phutil_tag(
diff --git a/src/view/AphrontTagView.php b/src/view/AphrontTagView.php
--- a/src/view/AphrontTagView.php
+++ b/src/view/AphrontTagView.php
@@ -41,6 +41,11 @@
return $this->metadata;
}
+ final protected function clearMetadata() {
+ $this->metadata = null;
+ return $this;
+ }
+
final public function setStyle($style) {
$this->style = $style;
return $this;
@@ -59,6 +64,11 @@
return $this->sigils;
}
+ final protected function setSigils(array $sigils) {
+ $this->sigils = $sigils;
+ return $this;
+ }
+
public function addClass($class) {
$this->classes[] = $class;
return $this;
diff --git a/src/view/layout/PhabricatorActionListView.php b/src/view/layout/PhabricatorActionListView.php
--- a/src/view/layout/PhabricatorActionListView.php
+++ b/src/view/layout/PhabricatorActionListView.php
@@ -51,6 +51,69 @@
$action->setUser($this->user);
}
+ $groups = array();
+ foreach ($actions as $key => $action) {
+ if (!$action->getIsContainer()) {
+ if ($action->getGroupKey()) {
+ $groups[$action->getGroupKey()][] = $action;
+ unset($actions[$key]);
+ }
+ }
+ }
+
+ $output = array();
+ foreach ($actions as $key => $action) {
+ if (!$action->getIsContainer()) {
+ $output[] = $action;
+ continue;
+ }
+
+ $group = idx($groups, $action->getGroupKey(), array());
+ if (!$group) {
+ continue;
+ }
+
+ Javelin::initBehavior('phabricator-reveal-content');
+
+ $closed_id = celerity_generate_unique_node_id();
+
+ $open_id = celerity_generate_unique_node_id();
+ $item_ids = array($open_id);
+
+ foreach ($group as $item) {
+ if (!$item->getID()) {
+ $item->setID(celerity_generate_unique_node_id());
+ }
+ $item_ids[] = $item->getID();
+ $item->setStyle('display: none');
+ $item->addClass('phabricator-action-list-subitem');
+ }
+
+ $output[] = id(clone $action)
+ ->setHref('#')
+ ->setID($closed_id)
+ ->addSigil('reveal-content')
+ ->setMetadata(
+ array(
+ 'hideIDs' => array($closed_id),
+ 'showIDs' => $item_ids,
+ ));
+
+ $output[] = id(clone $action)
+ ->setHref('#')
+ ->setID($open_id)
+ ->addSigil('reveal-content')
+ ->setStyle('display: none')
+ ->addClass('phabricator-action-list-group-header')
+ ->setMetadata(
+ array(
+ 'hideIDs' => $item_ids,
+ 'showIDs' => array($closed_id),
+ ));
+
+ $output[] = $group;
+ }
+
require_celerity_resource('phabricator-action-list-view-css');
return phutil_tag(
@@ -59,7 +122,7 @@
'class' => 'phabricator-action-list-view',
'id' => $this->id
),
- $actions);
+ $output);
}
diff --git a/src/view/layout/PhabricatorActionView.php b/src/view/layout/PhabricatorActionView.php
--- a/src/view/layout/PhabricatorActionView.php
+++ b/src/view/layout/PhabricatorActionView.php
@@ -1,6 +1,6 @@
<?php
-final class PhabricatorActionView extends AphrontView {
+final class PhabricatorActionView extends AphrontTagView {
private $name;
private $icon;
@@ -11,22 +11,36 @@
private $renderAsForm;
private $download;
private $objectURI;
- private $sigils = array();
- private $metadata;
+ private $isContainer;
+ private $groupKey;
- public function setMetadata($metadata) {
- $this->metadata = $metadata;
+ private $actionSigils;
+ private $actionMetadata;
+ private $actionWorkflow;
+
+ public function setGroupKey($group_key) {
+ $this->groupKey = $group_key;
+ return $this;
+ }
+
+ public function getGroupKey() {
+ return $this->groupKey;
+ }
+
+ public function setIsContainer($is_container) {
+ $this->isContainer = $is_container;
return $this;
}
- public function getMetadata() {
- return $this->metadata;
+ public function getIsContainer() {
+ return $this->isContainer;
}
public function setObjectURI($object_uri) {
$this->objectURI = $object_uri;
return $this;
}
+
public function getObjectURI() {
return $this->objectURI;
}
@@ -45,11 +59,6 @@
return $this;
}
- public function addSigil($sigil) {
- $this->sigils[] = $sigil;
- return $this;
- }
-
/**
* If the user is not logged in and the action is relatively complicated,
* give them a generic login link that will re-direct to the page they're
@@ -86,17 +95,42 @@
return $this;
}
- public function setWorkflow($workflow) {
- $this->workflow = $workflow;
- return $this;
- }
-
public function setRenderAsForm($form) {
$this->renderAsForm = $form;
return $this;
}
- public function render() {
+ public function getTagName() {
+ return 'li';
+ }
+
+ protected function willRender() {
+ // Before rendering, move attribute that we want to put on the actual link
+ // off this object. This is kind of sketchy, but we don't have any other
+ // similar use cases yet.
+ $this->actionSigils = $this->getSigils();
+ $this->setSigils(array());
+
+ $this->actionWorkflow = $this->getWorkflow();
+ $this->setWorkflow(false);
+
+ $this->actionMetadata = $this->getMetadata();
+ $this->clearMetadata();
+ }
+
+ public function getTagAttributes() {
+ $classes = array();
+ $classes[] = 'phabricator-action-view';
+ if ($this->disabled) {
+ $classes[] = 'phabricator-action-view-disabled';
+ }
+
+ return array(
+ 'class' => $classes,
+ );
+ }
+
+ public function getTagContent() {
$icon = null;
if ($this->icon) {
@@ -115,18 +149,16 @@
if ($this->href) {
- $sigils = array();
- if ($this->workflow) {
+ $sigils = $this->actionSigils;
+
+ if ($this->actionWorkflow) {
$sigils[] = 'workflow';
}
+
if ($this->download) {
$sigils[] = 'download';
}
- if ($this->sigils) {
- $sigils = array_merge($sigils, $this->sigils);
- }
-
$sigils = $sigils ? implode(' ', $sigils) : null;
if ($this->renderAsForm) {
@@ -148,7 +180,7 @@
'action' => $this->getHref(),
'method' => 'POST',
'sigil' => $sigils,
- 'meta' => $this->metadata,
+ 'meta' => $this->actionMetadata,
),
$item);
} else {
@@ -158,7 +190,7 @@
'href' => $this->getHref(),
'class' => 'phabricator-action-view-item',
'sigil' => $sigils,
- 'meta' => $this->metadata,
+ 'meta' => $this->actionMetadata,
),
$this->name);
}
@@ -171,18 +203,7 @@
$this->name);
}
- $classes = array();
- $classes[] = 'phabricator-action-view';
- if ($this->disabled) {
- $classes[] = 'phabricator-action-view-disabled';
- }
-
- return phutil_tag(
- 'li',
- array(
- 'class' => implode(' ', $classes),
- ),
- array($icon, $item));
+ return array($icon, $item);
}
public static function getAvailableIcons() {
diff --git a/webroot/rsrc/css/core/core.css b/webroot/rsrc/css/core/core.css
--- a/webroot/rsrc/css/core/core.css
+++ b/webroot/rsrc/css/core/core.css
@@ -93,7 +93,7 @@
cursor: pointer;
}
-a:hover {
+.device-desktop a:hover {
text-decoration: underline;
}
diff --git a/webroot/rsrc/css/layout/phabricator-action-list-view.css b/webroot/rsrc/css/layout/phabricator-action-list-view.css
--- a/webroot/rsrc/css/layout/phabricator-action-list-view.css
+++ b/webroot/rsrc/css/layout/phabricator-action-list-view.css
@@ -70,6 +70,14 @@
left: 9px;
}
+.phabricator-action-list-group-header {
+ background-color: #f7f7f7;
+}
+
+.phabricator-action-list-subitem .phabricator-action-view-icon {
+ left: 17px;
+}
+
.device-desktop .phabricator-action-view:hover .phabricator-action-view-item {
text-decoration: none;
background-color: {$blue};
@@ -96,3 +104,39 @@
background-color: #dfdfdf;
color: {$lightgreytext};
}
+
+.phabricator-action-list-group-header .action-view-caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ vertical-align: top;
+ margin: 7px 0 0 3px;
+ border-top: 5px solid {$darkgreytext};
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+ border-bottom: none;
+ content: "";
+}
+
+.action-view-caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ vertical-align: middle;
+ border-left: 6px solid {$darkgreytext};
+ border-top: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ content: "";
+ margin: 0 0 2px 3px;
+}
+
+.device-desktop .phabricator-action-view:hover .action-view-caret {
+ border-left-color: #fff;
+}
+
+.device-desktop
+ .phabricator-action-view:hover.phabricator-action-list-group-header
+ .action-view-caret {
+ border-left-color: transparent;
+ border-top-color: #fff;
+}
diff --git a/webroot/rsrc/css/phui/phui-property-list-view.css b/webroot/rsrc/css/phui/phui-property-list-view.css
--- a/webroot/rsrc/css/phui/phui-property-list-view.css
+++ b/webroot/rsrc/css/phui/phui-property-list-view.css
@@ -171,6 +171,7 @@
float: none;
width: auto;
margin: -12px 0 12px 0;
+ border: none;
}
.phui-property-list-image-content img {

File Metadata

Mime Type
text/plain
Expires
Sun, May 12, 4:44 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6274839
Default Alt Text
D8685.diff (16 KB)

Event Timeline