1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 06:42:42 +01:00

Allow profile menu items to be locked to the top or bottom of the menu

Summary:
Depends on D20353. Ref T13275. This is just some small quality-of-life fixes:

  - When you add items to menus, they currently go below the "Edit Menu/Manage Menu" links by default. This isn't a very good place for them. Instead, lock "edit" items to the bottom of the menu.
  - Lock profile pictures to the top of the menu. This just simplifies things a little.
  - Show more iconography hints on the "edit menu items" UI.
  - Add a "drag stuff to do things" hint if some stuff can be dragged.

Test Plan:
  - Added new items to a Portal, they didn't go to the very bottom. Instead, they went above the "Edit/Manage" links; a sensible place for them.
  - Viewed the "edit menu items" screen, saw more hints and visual richness.
  - Viewed/edited Home, Projects, Portals, Favorites

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13275

Differential Revision: https://secure.phabricator.com/D20355
This commit is contained in:
epriestley 2019-03-30 14:22:08 -07:00
parent 36a8b4ea17
commit 47bf382435
18 changed files with 129 additions and 22 deletions

View file

@ -9,7 +9,7 @@ return array(
'names' => array(
'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf',
'core.pkg.css' => '7e6e954b',
'core.pkg.css' => 'a1c2d49b',
'core.pkg.js' => 'a747b035',
'differential.pkg.css' => '8d8360fb',
'differential.pkg.js' => '67e02996',
@ -132,7 +132,7 @@ return array(
'rsrc/css/phui/object-item/phui-oi-color.css' => 'b517bfa0',
'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => 'da15d3dc',
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '490e2e2e',
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'a65865a7',
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'f14f2422',
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => '6a30fa46',
'rsrc/css/phui/phui-action-list.css' => 'c4972757',
'rsrc/css/phui/phui-action-panel.css' => '6c386cbf',
@ -853,7 +853,7 @@ return array(
'phui-oi-color-css' => 'b517bfa0',
'phui-oi-drag-ui-css' => 'da15d3dc',
'phui-oi-flush-ui-css' => '490e2e2e',
'phui-oi-list-view-css' => 'a65865a7',
'phui-oi-list-view-css' => 'f14f2422',
'phui-oi-simple-ui-css' => '6a30fa46',
'phui-pager-css' => 'd022c7ad',
'phui-pinboard-view-css' => '1f08f5d8',

View file

@ -24,7 +24,8 @@ final class PhabricatorDashboardPortalProfileMenuEngine
$items[] = $this->newItem()
->setMenuItemKey(PhabricatorDashboardPortalMenuItem::MENUITEMKEY)
->setBuiltinKey('manage');
->setBuiltinKey('manage')
->setIsTailItem(true);
return $items;
}

View file

@ -6,7 +6,7 @@ final class PhabricatorDashboardPortalMenuItem
const MENUITEMKEY = 'portal';
public function getMenuItemTypeIcon() {
return 'fa-compass';
return 'fa-pencil';
}
public function getDefaultName() {

View file

@ -13,6 +13,10 @@ final class PhabricatorHomeLauncherProfileMenuItem
return pht('More Applications');
}
public function getMenuItemTypeIcon() {
return 'fa-ellipsis-h';
}
public function canHideMenuItem(
PhabricatorProfileMenuItemConfiguration $config) {
return false;
@ -50,7 +54,7 @@ final class PhabricatorHomeLauncherProfileMenuItem
$viewer = $this->getViewer();
$name = $this->getDisplayName($config);
$icon = 'fa-globe';
$icon = 'fa-ellipsis-h';
$href = '/applications/';
$item = $this->newItem()

View file

@ -13,6 +13,10 @@ final class PhabricatorHomeProfileMenuItem
return pht('Home');
}
public function getMenuItemTypeIcon() {
return 'fa-home';
}
public function canMakeDefault(
PhabricatorProfileMenuItemConfiguration $config) {
return true;

View file

@ -22,7 +22,8 @@ final class PhabricatorProjectProfileMenuEngine
$items[] = $this->newItem()
->setBuiltinKey(PhabricatorProject::ITEM_PICTURE)
->setMenuItemKey(PhabricatorProjectPictureProfileMenuItem::MENUITEMKEY);
->setMenuItemKey(PhabricatorProjectPictureProfileMenuItem::MENUITEMKEY)
->setIsHeadItem(true);
$items[] = $this->newItem()
->setBuiltinKey(PhabricatorProject::ITEM_PROFILE)
@ -47,7 +48,8 @@ final class PhabricatorProjectProfileMenuEngine
$items[] = $this->newItem()
->setBuiltinKey(PhabricatorProject::ITEM_MANAGE)
->setMenuItemKey(PhabricatorProjectManageProfileMenuItem::MENUITEMKEY);
->setMenuItemKey(PhabricatorProjectManageProfileMenuItem::MENUITEMKEY)
->setIsTailItem(true);
return $items;
}

View file

@ -13,6 +13,10 @@ final class PhabricatorProjectDetailsProfileMenuItem
return pht('Project Details');
}
public function getMenuItemTypeIcon() {
return 'fa-file-text-o';
}
public function canHideMenuItem(
PhabricatorProfileMenuItemConfiguration $config) {
return false;

View file

@ -13,6 +13,10 @@ final class PhabricatorProjectManageProfileMenuItem
return pht('Manage');
}
public function getMenuItemTypeIcon() {
return 'fa-cog';
}
public function canHideMenuItem(
PhabricatorProfileMenuItemConfiguration $config) {
return false;

View file

@ -13,6 +13,10 @@ final class PhabricatorProjectMembersProfileMenuItem
return pht('Members');
}
public function getMenuItemTypeIcon() {
return 'fa-users';
}
public function getDisplayName(
PhabricatorProfileMenuItemConfiguration $config) {
$name = $config->getMenuItemProperty('name');

View file

@ -13,6 +13,10 @@ final class PhabricatorProjectPictureProfileMenuItem
return pht('Project Picture');
}
public function getMenuItemTypeIcon() {
return 'fa-image';
}
public function canHideMenuItem(
PhabricatorProfileMenuItemConfiguration $config) {
return false;

View file

@ -13,6 +13,10 @@ final class PhabricatorProjectSubprojectsProfileMenuItem
return pht('Subprojects');
}
public function getMenuItemTypeIcon() {
return 'fa-sitemap';
}
public function shouldEnableForObject($object) {
if ($object->isMilestone()) {
return false;

View file

@ -13,6 +13,10 @@ final class PhabricatorProjectWorkboardProfileMenuItem
return pht('Workboard');
}
public function getMenuItemTypeIcon() {
return 'fa-columns';
}
public function canMakeDefault(
PhabricatorProfileMenuItemConfiguration $config) {
return true;

View file

@ -460,6 +460,12 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
// stored config: it corresponds to an out-of-date or uninstalled
// item.
if (isset($items[$builtin_key])) {
$builtin_item = $items[$builtin_key];
// Copy runtime properties from the builtin item to the stored item.
$stored_item->setIsHeadItem($builtin_item->getIsHeadItem());
$stored_item->setIsTailItem($builtin_item->getIsTailItem());
$items[$builtin_key] = $stored_item;
} else {
continue;
@ -802,6 +808,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
->setID($list_id)
->setNoDataString(pht('This menu currently has no items.'));
$any_draggable = false;
foreach ($items as $item) {
$id = $item->getID();
$builtin_key = $item->getBuiltinKey();
@ -822,14 +829,25 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
$view->setHeader($name);
$view->addAttribute($type);
$icon = $item->getMenuItem()->getMenuItemTypeIcon();
if ($icon !== null) {
$view->setStatusIcon($icon);
}
if ($can_edit) {
$view
->setGrippable(true)
->addSigil('profile-menu-item')
->setMetadata(
array(
'key' => nonempty($id, $builtin_key),
));
$can_move = (!$item->getIsHeadItem() && !$item->getIsTailItem());
if ($can_move) {
$view
->setGrippable(true)
->addSigil('profile-menu-item')
->setMetadata(
array(
'key' => nonempty($id, $builtin_key),
));
$any_draggable = true;
} else {
$view->setGrippable(false);
}
if ($id) {
$default_uri = $this->getItemURI("default/{$id}/");
@ -944,8 +962,16 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
->setHeader(pht('Menu Items'))
->setHeaderIcon('fa-list');
$list_header = id(new PHUIHeaderView())
->setHeader(pht('Current Menu Items'));
if ($any_draggable) {
$list_header->setSubheader(
pht('Drag items in this list to reorder them.'));
}
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Current Menu Items'))
->setHeader($list_header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($list);
@ -1190,7 +1216,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
protected function newManageItem() {
return $this->newItem()
->setBuiltinKey(self::ITEM_MANAGE)
->setMenuItemKey(PhabricatorManageProfileMenuItem::MENUITEMKEY);
->setMenuItemKey(PhabricatorManageProfileMenuItem::MENUITEMKEY)
->setIsTailItem(true);
}
public function adjustDefault($key) {

View file

@ -7,7 +7,7 @@ final class PhabricatorLabelProfileMenuItem
const FIELD_NAME = 'name';
public function getMenuItemTypeIcon() {
return 'fa-map-signs';
return 'fa-tag';
}
public function getMenuItemTypeName() {

View file

@ -13,6 +13,10 @@ final class PhabricatorManageProfileMenuItem
return pht('Edit Menu');
}
public function getMenuItemTypeIcon() {
return 'fa-pencil';
}
public function canHideMenuItem(
PhabricatorProfileMenuItemConfiguration $config) {
return false;

View file

@ -17,6 +17,8 @@ final class PhabricatorProfileMenuItemConfiguration
private $profileObject = self::ATTACHABLE;
private $menuItem = self::ATTACHABLE;
private $isHeadItem = false;
private $isTailItem = false;
const VISIBILITY_DEFAULT = 'default';
const VISIBILITY_VISIBLE = 'visible';
@ -158,6 +160,15 @@ final class PhabricatorProfileMenuItemConfiguration
$is_global = 1;
}
// Sort "head" items above other items and "tail" items after other items.
if ($this->getIsHeadItem()) {
$force_position = 0;
} else if ($this->getIsTailItem()) {
$force_position = 2;
} else {
$force_position = 1;
}
// Sort items with an explicit order above items without an explicit order,
// so any newly created builtins go to the bottom.
$order = $this->getMenuItemOrder();
@ -169,6 +180,7 @@ final class PhabricatorProfileMenuItemConfiguration
return id(new PhutilSortVector())
->addInt($is_global)
->addInt($force_position)
->addInt($has_order)
->addInt((int)$order)
->addInt((int)$this->getID());
@ -207,6 +219,25 @@ final class PhabricatorProfileMenuItemConfiguration
return $this->getMenuItem()->newPageContent($this);
}
public function setIsHeadItem($is_head_item) {
$this->isHeadItem = $is_head_item;
return $this;
}
public function getIsHeadItem() {
return $this->isHeadItem;
}
public function setIsTailItem($is_tail_item) {
$this->isTailItem = $is_tail_item;
return $this;
}
public function getIsTailItem() {
return $this->isTailItem;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -330,8 +330,14 @@ final class PHUIObjectItemView extends AphrontTagView {
Javelin::initBehavior('phui-selectable-list');
}
if ($this->getGrippable()) {
$item_classes[] = 'phui-oi-grippable';
$is_grippable = $this->getGrippable();
if ($is_grippable !== null) {
$item_classes[] = 'phui-oi-has-grip';
if ($is_grippable) {
$item_classes[] = 'phui-oi-grippable';
} else {
$item_classes[] = 'phui-oi-ungrippable';
}
}
if ($this->getImageURI()) {
@ -580,7 +586,7 @@ final class PHUIObjectItemView extends AphrontTagView {
}
$grippable = null;
if ($this->getGrippable()) {
if ($this->getGrippable() !== null) {
$grippable = phutil_tag(
'div',
array(

View file

@ -132,11 +132,15 @@ ul.phui-oi-list-view {
background: url('/rsrc/image/texture/grip.png') center center no-repeat;
}
.phui-oi-ungrippable .phui-oi-grip {
opacity: 0.25;
}
.device .phui-oi-grip {
display: none;
}
.phui-oi-grippable .phui-oi-frame {
.phui-oi-has-grip .phui-oi-frame {
padding-left: 16px;
}