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 @@ -3785,7 +3785,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 @@ -66,6 +66,13 @@ if ($viewer->getIsAdmin()) { $actions->addAction( id(new PhabricatorActionView()) + ->setIsContainer(true) + ->setGroupKey('user.admin') + ->setName(pht('Administrate User...'))); + + $actions->addAction( + id(new PhabricatorActionView()) + ->setGroupKey('user.admin') ->setIcon('wrench') ->setName(pht('Edit Settings')) ->setDisabled(!$can_edit) @@ -82,6 +89,7 @@ $actions->addAction( id(new PhabricatorActionView()) + ->setGroupKey('user.admin') ->setIcon($empower_icon) ->setName($empower_name) ->setDisabled(($user->getPHID() == $viewer->getPHID())) @@ -90,6 +98,7 @@ $actions->addAction( id(new PhabricatorActionView()) + ->setGroupKey('user.admin') ->setIcon('tag') ->setName(pht('Change Username')) ->setWorkflow(true) @@ -105,6 +114,7 @@ $actions->addAction( id(new PhabricatorActionView()) + ->setGroupKey('user.admin') ->setIcon($disable_icon) ->setName($disable_name) ->setDisabled(($user->getPHID() == $viewer->getPHID())) @@ -113,6 +123,7 @@ $actions->addAction( id(new PhabricatorActionView()) + ->setGroupKey('user.admin') ->setIcon('delete') ->setName(pht('Delete User')) ->setDisabled(($user->getPHID() == $viewer->getPHID())) @@ -121,6 +132,7 @@ $actions->addAction( id(new PhabricatorActionView()) + ->setGroupKey('user.admin') ->setIcon('message') ->setName(pht('Send Welcome Email')) ->setWorkflow(true) 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,70 @@ $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) + ->setIcon('play') + ->setHref('#') + ->setID($closed_id) + ->addSigil('reveal-content') + ->setMetadata( + array( + 'hideIDs' => array($closed_id), + 'showIDs' => $item_ids, + )); + + $output[] = id(clone $action) + ->setIcon('remove') + ->setHref('#') + ->setID($open_id) + ->addSigil('reveal-content') + ->setStyle('display: none') + ->setMetadata( + array( + 'hideIDs' => $item_ids, + 'showIDs' => array($closed_id), + )); + + $output[] = $group; + } + require_celerity_resource('phabricator-action-list-view-css'); return phutil_tag( @@ -59,7 +123,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 @@ groupKey = $group_key; + return $this; + } + + public function getGroupKey() { + return $this->groupKey; + } + + public function setIsContainer($is_container) { + $this->isContainer = $is_container; + return $this; + } + + public function getIsContainer() { + return $this->isContainer; + } + public function setObjectURI($object_uri) { $this->objectURI = $object_uri; return $this; @@ -80,7 +101,23 @@ return $this; } - public function render() { + public function getTagName() { + return 'li'; + } + + 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) { @@ -146,18 +183,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/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 @@ -64,6 +64,14 @@ left: 9px; } +.phabricator-action-list-subitem { + padding-left: 8px; +} + +.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};