@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+129 -22
+3 -3
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => '3c8a0668', 11 11 'conpherence.pkg.js' => '020aebcf', 12 - 'core.pkg.css' => '7e6e954b', 12 + 'core.pkg.css' => 'a1c2d49b', 13 13 'core.pkg.js' => 'a747b035', 14 14 'differential.pkg.css' => '8d8360fb', 15 15 'differential.pkg.js' => '67e02996', ··· 132 132 'rsrc/css/phui/object-item/phui-oi-color.css' => 'b517bfa0', 133 133 'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => 'da15d3dc', 134 134 'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '490e2e2e', 135 - 'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'a65865a7', 135 + 'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'f14f2422', 136 136 'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => '6a30fa46', 137 137 'rsrc/css/phui/phui-action-list.css' => 'c4972757', 138 138 'rsrc/css/phui/phui-action-panel.css' => '6c386cbf', ··· 853 853 'phui-oi-color-css' => 'b517bfa0', 854 854 'phui-oi-drag-ui-css' => 'da15d3dc', 855 855 'phui-oi-flush-ui-css' => '490e2e2e', 856 - 'phui-oi-list-view-css' => 'a65865a7', 856 + 'phui-oi-list-view-css' => 'f14f2422', 857 857 'phui-oi-simple-ui-css' => '6a30fa46', 858 858 'phui-pager-css' => 'd022c7ad', 859 859 'phui-pinboard-view-css' => '1f08f5d8',
+2 -1
src/applications/dashboard/engine/PhabricatorDashboardPortalProfileMenuEngine.php
··· 24 24 25 25 $items[] = $this->newItem() 26 26 ->setMenuItemKey(PhabricatorDashboardPortalMenuItem::MENUITEMKEY) 27 - ->setBuiltinKey('manage'); 27 + ->setBuiltinKey('manage') 28 + ->setIsTailItem(true); 28 29 29 30 return $items; 30 31 }
+1 -1
src/applications/dashboard/menuitem/PhabricatorDashboardPortalMenuItem.php
··· 6 6 const MENUITEMKEY = 'portal'; 7 7 8 8 public function getMenuItemTypeIcon() { 9 - return 'fa-compass'; 9 + return 'fa-pencil'; 10 10 } 11 11 12 12 public function getDefaultName() {
+5 -1
src/applications/home/menuitem/PhabricatorHomeLauncherProfileMenuItem.php
··· 13 13 return pht('More Applications'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-ellipsis-h'; 18 + } 19 + 16 20 public function canHideMenuItem( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return false; ··· 50 54 $viewer = $this->getViewer(); 51 55 52 56 $name = $this->getDisplayName($config); 53 - $icon = 'fa-globe'; 57 + $icon = 'fa-ellipsis-h'; 54 58 $href = '/applications/'; 55 59 56 60 $item = $this->newItem()
+4
src/applications/home/menuitem/PhabricatorHomeProfileMenuItem.php
··· 13 13 return pht('Home'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-home'; 18 + } 19 + 16 20 public function canMakeDefault( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return true;
+4 -2
src/applications/project/engine/PhabricatorProjectProfileMenuEngine.php
··· 22 22 23 23 $items[] = $this->newItem() 24 24 ->setBuiltinKey(PhabricatorProject::ITEM_PICTURE) 25 - ->setMenuItemKey(PhabricatorProjectPictureProfileMenuItem::MENUITEMKEY); 25 + ->setMenuItemKey(PhabricatorProjectPictureProfileMenuItem::MENUITEMKEY) 26 + ->setIsHeadItem(true); 26 27 27 28 $items[] = $this->newItem() 28 29 ->setBuiltinKey(PhabricatorProject::ITEM_PROFILE) ··· 47 48 48 49 $items[] = $this->newItem() 49 50 ->setBuiltinKey(PhabricatorProject::ITEM_MANAGE) 50 - ->setMenuItemKey(PhabricatorProjectManageProfileMenuItem::MENUITEMKEY); 51 + ->setMenuItemKey(PhabricatorProjectManageProfileMenuItem::MENUITEMKEY) 52 + ->setIsTailItem(true); 51 53 52 54 return $items; 53 55 }
+4
src/applications/project/menuitem/PhabricatorProjectDetailsProfileMenuItem.php
··· 13 13 return pht('Project Details'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-file-text-o'; 18 + } 19 + 16 20 public function canHideMenuItem( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return false;
+4
src/applications/project/menuitem/PhabricatorProjectManageProfileMenuItem.php
··· 13 13 return pht('Manage'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-cog'; 18 + } 19 + 16 20 public function canHideMenuItem( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return false;
+4
src/applications/project/menuitem/PhabricatorProjectMembersProfileMenuItem.php
··· 13 13 return pht('Members'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-users'; 18 + } 19 + 16 20 public function getDisplayName( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 $name = $config->getMenuItemProperty('name');
+4
src/applications/project/menuitem/PhabricatorProjectPictureProfileMenuItem.php
··· 13 13 return pht('Project Picture'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-image'; 18 + } 19 + 16 20 public function canHideMenuItem( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return false;
+4
src/applications/project/menuitem/PhabricatorProjectSubprojectsProfileMenuItem.php
··· 13 13 return pht('Subprojects'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-sitemap'; 18 + } 19 + 16 20 public function shouldEnableForObject($object) { 17 21 if ($object->isMilestone()) { 18 22 return false;
+4
src/applications/project/menuitem/PhabricatorProjectWorkboardProfileMenuItem.php
··· 13 13 return pht('Workboard'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-columns'; 18 + } 19 + 16 20 public function canMakeDefault( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return true;
+36 -9
src/applications/search/engine/PhabricatorProfileMenuEngine.php
··· 460 460 // stored config: it corresponds to an out-of-date or uninstalled 461 461 // item. 462 462 if (isset($items[$builtin_key])) { 463 + $builtin_item = $items[$builtin_key]; 464 + 465 + // Copy runtime properties from the builtin item to the stored item. 466 + $stored_item->setIsHeadItem($builtin_item->getIsHeadItem()); 467 + $stored_item->setIsTailItem($builtin_item->getIsTailItem()); 468 + 463 469 $items[$builtin_key] = $stored_item; 464 470 } else { 465 471 continue; ··· 802 808 ->setID($list_id) 803 809 ->setNoDataString(pht('This menu currently has no items.')); 804 810 811 + $any_draggable = false; 805 812 foreach ($items as $item) { 806 813 $id = $item->getID(); 807 814 $builtin_key = $item->getBuiltinKey(); ··· 822 829 $view->setHeader($name); 823 830 $view->addAttribute($type); 824 831 832 + $icon = $item->getMenuItem()->getMenuItemTypeIcon(); 833 + if ($icon !== null) { 834 + $view->setStatusIcon($icon); 835 + } 836 + 825 837 if ($can_edit) { 826 - $view 827 - ->setGrippable(true) 828 - ->addSigil('profile-menu-item') 829 - ->setMetadata( 830 - array( 831 - 'key' => nonempty($id, $builtin_key), 832 - )); 838 + $can_move = (!$item->getIsHeadItem() && !$item->getIsTailItem()); 839 + if ($can_move) { 840 + $view 841 + ->setGrippable(true) 842 + ->addSigil('profile-menu-item') 843 + ->setMetadata( 844 + array( 845 + 'key' => nonempty($id, $builtin_key), 846 + )); 847 + $any_draggable = true; 848 + } else { 849 + $view->setGrippable(false); 850 + } 833 851 834 852 if ($id) { 835 853 $default_uri = $this->getItemURI("default/{$id}/"); ··· 944 962 ->setHeader(pht('Menu Items')) 945 963 ->setHeaderIcon('fa-list'); 946 964 965 + $list_header = id(new PHUIHeaderView()) 966 + ->setHeader(pht('Current Menu Items')); 967 + 968 + if ($any_draggable) { 969 + $list_header->setSubheader( 970 + pht('Drag items in this list to reorder them.')); 971 + } 972 + 947 973 $box = id(new PHUIObjectBoxView()) 948 - ->setHeaderText(pht('Current Menu Items')) 974 + ->setHeader($list_header) 949 975 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 950 976 ->setObjectList($list); 951 977 ··· 1190 1216 protected function newManageItem() { 1191 1217 return $this->newItem() 1192 1218 ->setBuiltinKey(self::ITEM_MANAGE) 1193 - ->setMenuItemKey(PhabricatorManageProfileMenuItem::MENUITEMKEY); 1219 + ->setMenuItemKey(PhabricatorManageProfileMenuItem::MENUITEMKEY) 1220 + ->setIsTailItem(true); 1194 1221 } 1195 1222 1196 1223 public function adjustDefault($key) {
+1 -1
src/applications/search/menuitem/PhabricatorLabelProfileMenuItem.php
··· 7 7 const FIELD_NAME = 'name'; 8 8 9 9 public function getMenuItemTypeIcon() { 10 - return 'fa-map-signs'; 10 + return 'fa-tag'; 11 11 } 12 12 13 13 public function getMenuItemTypeName() {
+4
src/applications/search/menuitem/PhabricatorManageProfileMenuItem.php
··· 13 13 return pht('Edit Menu'); 14 14 } 15 15 16 + public function getMenuItemTypeIcon() { 17 + return 'fa-pencil'; 18 + } 19 + 16 20 public function canHideMenuItem( 17 21 PhabricatorProfileMenuItemConfiguration $config) { 18 22 return false;
+31
src/applications/search/storage/PhabricatorProfileMenuItemConfiguration.php
··· 17 17 18 18 private $profileObject = self::ATTACHABLE; 19 19 private $menuItem = self::ATTACHABLE; 20 + private $isHeadItem = false; 21 + private $isTailItem = false; 20 22 21 23 const VISIBILITY_DEFAULT = 'default'; 22 24 const VISIBILITY_VISIBLE = 'visible'; ··· 158 160 $is_global = 1; 159 161 } 160 162 163 + // Sort "head" items above other items and "tail" items after other items. 164 + if ($this->getIsHeadItem()) { 165 + $force_position = 0; 166 + } else if ($this->getIsTailItem()) { 167 + $force_position = 2; 168 + } else { 169 + $force_position = 1; 170 + } 171 + 161 172 // Sort items with an explicit order above items without an explicit order, 162 173 // so any newly created builtins go to the bottom. 163 174 $order = $this->getMenuItemOrder(); ··· 169 180 170 181 return id(new PhutilSortVector()) 171 182 ->addInt($is_global) 183 + ->addInt($force_position) 172 184 ->addInt($has_order) 173 185 ->addInt((int)$order) 174 186 ->addInt((int)$this->getID()); ··· 206 218 public function newPageContent() { 207 219 return $this->getMenuItem()->newPageContent($this); 208 220 } 221 + 222 + public function setIsHeadItem($is_head_item) { 223 + $this->isHeadItem = $is_head_item; 224 + return $this; 225 + } 226 + 227 + public function getIsHeadItem() { 228 + return $this->isHeadItem; 229 + } 230 + 231 + public function setIsTailItem($is_tail_item) { 232 + $this->isTailItem = $is_tail_item; 233 + return $this; 234 + } 235 + 236 + public function getIsTailItem() { 237 + return $this->isTailItem; 238 + } 239 + 209 240 210 241 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 211 242
+9 -3
src/view/phui/PHUIObjectItemView.php
··· 330 330 Javelin::initBehavior('phui-selectable-list'); 331 331 } 332 332 333 - if ($this->getGrippable()) { 334 - $item_classes[] = 'phui-oi-grippable'; 333 + $is_grippable = $this->getGrippable(); 334 + if ($is_grippable !== null) { 335 + $item_classes[] = 'phui-oi-has-grip'; 336 + if ($is_grippable) { 337 + $item_classes[] = 'phui-oi-grippable'; 338 + } else { 339 + $item_classes[] = 'phui-oi-ungrippable'; 340 + } 335 341 } 336 342 337 343 if ($this->getImageURI()) { ··· 580 586 } 581 587 582 588 $grippable = null; 583 - if ($this->getGrippable()) { 589 + if ($this->getGrippable() !== null) { 584 590 $grippable = phutil_tag( 585 591 'div', 586 592 array(
+5 -1
webroot/rsrc/css/phui/object-item/phui-oi-list-view.css
··· 132 132 background: url('/rsrc/image/texture/grip.png') center center no-repeat; 133 133 } 134 134 135 + .phui-oi-ungrippable .phui-oi-grip { 136 + opacity: 0.25; 137 + } 138 + 135 139 .device .phui-oi-grip { 136 140 display: none; 137 141 } 138 142 139 - .phui-oi-grippable .phui-oi-frame { 143 + .phui-oi-has-grip .phui-oi-frame { 140 144 padding-left: 16px; 141 145 } 142 146