Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15383762
D20349.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D20349.id.diff
View Options
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
@@ -2953,13 +2953,16 @@
'PhabricatorDashboardPortalEditEngine' => 'applications/dashboard/editor/PhabricatorDashboardPortalEditEngine.php',
'PhabricatorDashboardPortalEditor' => 'applications/dashboard/editor/PhabricatorDashboardPortalEditor.php',
'PhabricatorDashboardPortalListController' => 'applications/dashboard/controller/portal/PhabricatorDashboardPortalListController.php',
+ 'PhabricatorDashboardPortalMenuItem' => 'applications/dashboard/menuitem/PhabricatorDashboardPortalMenuItem.php',
'PhabricatorDashboardPortalNameTransaction' => 'applications/dashboard/xaction/portal/PhabricatorDashboardPortalNameTransaction.php',
'PhabricatorDashboardPortalPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardPortalPHIDType.php',
+ 'PhabricatorDashboardPortalProfileMenuEngine' => 'applications/dashboard/engine/PhabricatorDashboardPortalProfileMenuEngine.php',
'PhabricatorDashboardPortalQuery' => 'applications/dashboard/query/PhabricatorDashboardPortalQuery.php',
'PhabricatorDashboardPortalSearchConduitAPIMethod' => 'applications/dashboard/conduit/PhabricatorDashboardPortalSearchConduitAPIMethod.php',
'PhabricatorDashboardPortalSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPortalSearchEngine.php',
'PhabricatorDashboardPortalStatus' => 'applications/dashboard/constants/PhabricatorDashboardPortalStatus.php',
'PhabricatorDashboardPortalTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPortalTransaction.php',
+ 'PhabricatorDashboardPortalTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPortalTransactionQuery.php',
'PhabricatorDashboardPortalTransactionType' => 'applications/dashboard/xaction/portal/PhabricatorDashboardPortalTransactionType.php',
'PhabricatorDashboardPortalViewController' => 'applications/dashboard/controller/portal/PhabricatorDashboardPortalViewController.php',
'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php',
@@ -8924,13 +8927,16 @@
'PhabricatorDashboardPortalEditEngine' => 'PhabricatorEditEngine',
'PhabricatorDashboardPortalEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorDashboardPortalListController' => 'PhabricatorDashboardPortalController',
+ 'PhabricatorDashboardPortalMenuItem' => 'PhabricatorProfileMenuItem',
'PhabricatorDashboardPortalNameTransaction' => 'PhabricatorDashboardPortalTransactionType',
'PhabricatorDashboardPortalPHIDType' => 'PhabricatorPHIDType',
+ 'PhabricatorDashboardPortalProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
'PhabricatorDashboardPortalQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorDashboardPortalSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'PhabricatorDashboardPortalSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorDashboardPortalStatus' => 'Phobject',
'PhabricatorDashboardPortalTransaction' => 'PhabricatorModularTransaction',
+ 'PhabricatorDashboardPortalTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorDashboardPortalTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorDashboardPortalViewController' => 'PhabricatorDashboardPortalController',
'PhabricatorDashboardProfileController' => 'PhabricatorController',
diff --git a/src/applications/dashboard/application/PhabricatorDashboardApplication.php b/src/applications/dashboard/application/PhabricatorDashboardApplication.php
--- a/src/applications/dashboard/application/PhabricatorDashboardApplication.php
+++ b/src/applications/dashboard/application/PhabricatorDashboardApplication.php
@@ -27,6 +27,9 @@
}
public function getRoutes() {
+ $menu_rules = $this->getProfileMenuRouting(
+ 'PhabricatorDashboardPortalViewController');
+
return array(
'/W(?P<id>\d+)' => 'PhabricatorDashboardPanelViewController',
'/dashboard/' => array(
@@ -62,8 +65,10 @@
'PhabricatorDashboardPortalListController',
$this->getEditRoutePattern('edit/') =>
'PhabricatorDashboardPortalEditController',
- 'view/(?P<id>\d)/' =>
- 'PhabricatorDashboardPortalViewController',
+ 'view/(?P<portalID>\d)/' => array(
+ '' => 'PhabricatorDashboardPortalViewController',
+ ) + $menu_rules,
+
),
);
}
diff --git a/src/applications/dashboard/controller/portal/PhabricatorDashboardPortalViewController.php b/src/applications/dashboard/controller/portal/PhabricatorDashboardPortalViewController.php
--- a/src/applications/dashboard/controller/portal/PhabricatorDashboardPortalViewController.php
+++ b/src/applications/dashboard/controller/portal/PhabricatorDashboardPortalViewController.php
@@ -3,13 +3,24 @@
final class PhabricatorDashboardPortalViewController
extends PhabricatorDashboardPortalController {
+ private $portal;
+
+ public function setPortal(PhabricatorDashboardPortal $portal) {
+ $this->portal = $portal;
+ return $this;
+ }
+
+ public function getPortal() {
+ return $this->portal;
+ }
+
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
- $id = $request->getURIData('id');
+ $id = $request->getURIData('portalID');
$portal = id(new PhabricatorDashboardPortalQuery())
->setViewer($viewer)
@@ -19,16 +30,30 @@
return new Aphront404Response();
}
- $content = $portal->getObjectName();
+ $this->setPortal($portal);
+
+ $engine = id(new PhabricatorDashboardPortalProfileMenuEngine())
+ ->setProfileObject($portal)
+ ->setController($this);
+
+ return $engine->buildResponse();
+ }
+
+ protected function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ $portal = $this->getPortal();
+ if ($portal) {
+ $crumbs->addTextCrumb($portal->getName(), $portal->getURI());
+ }
+
+ return $crumbs;
+ }
- return $this->newPage()
- ->setTitle(
- array(
- pht('Portal'),
- $portal->getName(),
- ))
- ->setPageObjectPHIDs(array($portal->getPHID()))
- ->appendChild($content);
+ public function newTimelineView() {
+ return $this->buildTransactionTimeline(
+ $this->getPortal(),
+ new PhabricatorDashboardPortalTransactionQuery());
}
}
diff --git a/src/applications/dashboard/editor/PhabricatorDashboardPortalEditEngine.php b/src/applications/dashboard/editor/PhabricatorDashboardPortalEditEngine.php
--- a/src/applications/dashboard/editor/PhabricatorDashboardPortalEditEngine.php
+++ b/src/applications/dashboard/editor/PhabricatorDashboardPortalEditEngine.php
@@ -58,7 +58,11 @@
}
protected function getObjectViewURI($object) {
- return $object->getURI();
+ if ($this->getIsCreate()) {
+ return $object->getURI();
+ } else {
+ return '/portal/view/'.$object->getID().'/view/manage/';
+ }
}
protected function getEditorURI() {
diff --git a/src/applications/dashboard/engine/PhabricatorDashboardPortalProfileMenuEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardPortalProfileMenuEngine.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/engine/PhabricatorDashboardPortalProfileMenuEngine.php
@@ -0,0 +1,38 @@
+<?php
+
+final class PhabricatorDashboardPortalProfileMenuEngine
+ extends PhabricatorProfileMenuEngine {
+
+ protected function isMenuEngineConfigurable() {
+ return true;
+ }
+
+ protected function isMenuEnginePersonalizable() {
+ return false;
+ }
+
+ public function getItemURI($path) {
+ $portal = $this->getProfileObject();
+
+ return $portal->getURI().$path;
+ }
+
+ protected function getBuiltinProfileItems($object) {
+ $items = array();
+
+ $items[] = $this->newManageItem();
+
+ $items[] = $this->newItem()
+ ->setMenuItemKey(PhabricatorDashboardPortalMenuItem::MENUITEMKEY)
+ ->setBuiltinKey('manage');
+
+ return $items;
+ }
+
+ protected function newNoMenuItemsView() {
+ return $this->newEmptyView(
+ pht('New Portal'),
+ pht('Use "Edit Menu" to add menu items to this portal.'));
+ }
+
+}
diff --git a/src/applications/dashboard/menuitem/PhabricatorDashboardPortalMenuItem.php b/src/applications/dashboard/menuitem/PhabricatorDashboardPortalMenuItem.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/menuitem/PhabricatorDashboardPortalMenuItem.php
@@ -0,0 +1,117 @@
+<?php
+
+final class PhabricatorDashboardPortalMenuItem
+ extends PhabricatorProfileMenuItem {
+
+ const MENUITEMKEY = 'portal';
+
+ public function getMenuItemTypeIcon() {
+ return 'fa-compass';
+ }
+
+ public function getDefaultName() {
+ return pht('Manage Portal');
+ }
+
+ public function getMenuItemTypeName() {
+ return pht('Manage Portal');
+ }
+
+ public function canHideMenuItem(
+ PhabricatorProfileMenuItemConfiguration $config) {
+ return false;
+ }
+
+ public function canMakeDefault(
+ PhabricatorProfileMenuItemConfiguration $config) {
+ return false;
+ }
+
+ public function getDisplayName(
+ PhabricatorProfileMenuItemConfiguration $config) {
+ $name = $config->getMenuItemProperty('name');
+
+ if (strlen($name)) {
+ return $name;
+ }
+
+ return $this->getDefaultName();
+ }
+
+ public function buildEditEngineFields(
+ PhabricatorProfileMenuItemConfiguration $config) {
+ return array(
+ id(new PhabricatorTextEditField())
+ ->setKey('name')
+ ->setLabel(pht('Name'))
+ ->setPlaceholder($this->getDefaultName())
+ ->setValue($config->getMenuItemProperty('name')),
+ );
+ }
+
+ protected function newNavigationMenuItems(
+ PhabricatorProfileMenuItemConfiguration $config) {
+ $viewer = $this->getViewer();
+
+ if (!$viewer->isLoggedIn()) {
+ return array();
+ }
+
+ $href = $this->getItemViewURI($config);
+ $name = $this->getDisplayName($config);
+ $icon = 'fa-pencil';
+
+ $item = $this->newItem()
+ ->setHref($href)
+ ->setName($name)
+ ->setIcon($icon);
+
+ return array(
+ $item,
+ );
+ }
+
+ public function newPageContent(
+ PhabricatorProfileMenuItemConfiguration $config) {
+ $viewer = $this->getViewer();
+ $engine = $this->getEngine();
+ $portal = $engine->getProfileObject();
+ $controller = $engine->getController();
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Manage Portal'));
+
+ $edit_uri = urisprintf(
+ '/portal/edit/%d/',
+ $portal->getID());
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $portal,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $curtain = $controller->newCurtainView($portal)
+ ->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Portal'))
+ ->setIcon('fa-pencil')
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit)
+ ->setHref($edit_uri));
+
+ $timeline = $controller->newTimelineView()
+ ->setShouldTerminate(true);
+
+ $view = id(new PHUITwoColumnView())
+ ->setHeader($header)
+ ->setCurtain($curtain)
+ ->setMainColumn(
+ array(
+ $timeline,
+ ));
+
+ return $view;
+ }
+
+
+}
diff --git a/src/applications/dashboard/query/PhabricatorDashboardPortalTransactionQuery.php b/src/applications/dashboard/query/PhabricatorDashboardPortalTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/query/PhabricatorDashboardPortalTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorDashboardPortalTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhabricatorDashboardPortalTransaction();
+ }
+
+}
diff --git a/src/applications/search/engine/PhabricatorProfileMenuEngine.php b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
--- a/src/applications/search/engine/PhabricatorProfileMenuEngine.php
+++ b/src/applications/search/engine/PhabricatorProfileMenuEngine.php
@@ -181,6 +181,10 @@
switch ($item_action) {
case 'view':
+ // If we were not able to select an item, we're still going to render
+ // a page state. For example, this happens when you create a new
+ // portal for the first time.
+ break;
case 'info':
case 'hide':
case 'default':
@@ -231,24 +235,35 @@
}
$page_title = pht('Configure Menu');
} else {
- $page_title = $selected_item->getDisplayName();
+ if ($selected_item) {
+ $page_title = $selected_item->getDisplayName();
+ } else {
+ $page_title = pht('Empty');
+ }
}
switch ($item_action) {
case 'view':
- $navigation->selectFilter($selected_item->getDefaultMenuItemKey());
-
- try {
- $content = $this->buildItemViewContent($selected_item);
- } catch (Exception $ex) {
- $content = id(new PHUIInfoView())
- ->setTitle(pht('Unable to Render Dashboard'))
- ->setErrors(array($ex->getMessage()));
+ if ($selected_item) {
+ $navigation->selectFilter($selected_item->getDefaultMenuItemKey());
+
+ try {
+ $content = $this->buildItemViewContent($selected_item);
+ } catch (Exception $ex) {
+ $content = id(new PHUIInfoView())
+ ->setTitle(pht('Unable to Render Dashboard'))
+ ->setErrors(array($ex->getMessage()));
+ }
+
+ $crumbs->addTextCrumb($selected_item->getDisplayName());
+ } else {
+ $content = $this->newNoMenuItemsView();
}
- $crumbs->addTextCrumb($selected_item->getDisplayName());
if (!$content) {
- return new Aphront404Response();
+ $content = $this->newEmptyView(
+ pht('Empty'),
+ pht('There is nothing here.'));
}
break;
case 'configure':
@@ -346,6 +361,7 @@
if ($this->navigation) {
return $this->navigation;
}
+
$nav = id(new AphrontSideNavFilterView())
->setIsProfileMenu(true)
->setBaseURI(new PhutilURI($this->getItemURI('')));
@@ -365,6 +381,7 @@
$first_item->willBuildNavigationItems($group);
}
+ $has_items = false;
foreach ($menu_items as $menu_item) {
if ($menu_item->isDisabled()) {
continue;
@@ -389,9 +406,18 @@
foreach ($items as $item) {
$nav->addMenuItem($item);
+ $has_items = true;
}
}
+ if (!$has_items) {
+ // If the navigation menu has no items, add an empty label item to
+ // force it to render something.
+ $empty_item = id(new PHUIListItemView())
+ ->setType(PHUIListItemView::TYPE_LABEL);
+ $nav->addMenuItem($empty_item);
+ }
+
$nav->selectFilter(null);
$this->navigation = $nav;
@@ -1319,5 +1345,20 @@
return $items;
}
+ final protected function newEmptyView($title, $message) {
+ return id(new PHUIInfoView())
+ ->setTitle($title)
+ ->setSeverity(PHUIInfoView::SEVERITY_NODATA)
+ ->setErrors(
+ array(
+ $message,
+ ));
+ }
+
+ protected function newNoMenuItemsView() {
+ return $this->newEmptyView(
+ pht('No Menu Items'),
+ pht('There are no menu items.'));
+ }
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 15, 5:51 PM (1 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225201
Default Alt Text
D20349.id.diff (15 KB)
Attached To
Mode
D20349: Allow Portals to be edited, and improve empty/blank states
Attached
Detach File
Event Timeline
Log In to Comment