Page MenuHomePhabricator

D20349.id48603.diff
No OneTemporary

D20349.id48603.diff

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

Mime Type
text/plain
Expires
Sat, Mar 22, 9:57 AM (3 d, 4 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225201
Default Alt Text
D20349.id48603.diff (15 KB)

Event Timeline