diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 90d0f49f78..facd569fc2 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1812,6 +1812,7 @@ phutil_register_library_map(array( 'PhrequentUserTime' => 'applications/phrequent/storage/PhrequentUserTime.php', 'PhrequentUserTimeQuery' => 'applications/phrequent/query/PhrequentUserTimeQuery.php', 'PhrictionActionConstants' => 'applications/phriction/constants/PhrictionActionConstants.php', + 'PhrictionActionMenuEventListener' => 'applications/phriction/event/PhrictionActionMenuEventListener.php', 'PhrictionChangeType' => 'applications/phriction/constants/PhrictionChangeType.php', 'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php', 'PhrictionContent' => 'applications/phriction/storage/PhrictionContent.php', @@ -3850,6 +3851,7 @@ phutil_register_library_map(array( 'PhrequentUserTime' => 'PhrequentDAO', 'PhrequentUserTimeQuery' => 'PhabricatorOffsetPagedQuery', 'PhrictionActionConstants' => 'PhrictionConstants', + 'PhrictionActionMenuEventListener' => 'PhutilEventListener', 'PhrictionChangeType' => 'PhrictionConstants', 'PhrictionContent' => array( diff --git a/src/applications/maniphest/event/ManiphestPeopleMenuEventListener.php b/src/applications/maniphest/event/ManiphestPeopleMenuEventListener.php index 476fd8f513..385aaa6bd8 100644 --- a/src/applications/maniphest/event/ManiphestPeopleMenuEventListener.php +++ b/src/applications/maniphest/event/ManiphestPeopleMenuEventListener.php @@ -15,20 +15,21 @@ final class ManiphestPeopleMenuEventListener extends PhutilEventListener { } private function handleActionsEvent($event) { - $person = $event->getValue('object'); - if (!($person instanceof PhabricatorUser)) { - return; - } - - $href = '/maniphest/view/action/?users='.$person->getPHID(); - $actions = $event->getValue('actions'); - $actions[] = id(new PhabricatorActionView()) + $action = id(new PhabricatorActionView()) ->setIcon('maniphest-dark') ->setIconSheet(PHUIIconView::SPRITE_APPS) - ->setName(pht('View Tasks')) - ->setHref($href); + ->setName(pht('View Tasks')); + + $object = $event->getValue('object'); + if ($object instanceof PhabricatorUser) { + $href = '/maniphest/view/action/?users='.$object->getPHID(); + $actions[] = $action->setHref($href); + } else if ($object instanceof PhabricatorProject) { + $href = '/maniphest/view/all/?projects='.$object->getPHID(); + $actions[] = $action->setHref($href); + } $event->setValue('actions', $actions); } diff --git a/src/applications/phriction/application/PhabricatorApplicationPhriction.php b/src/applications/phriction/application/PhabricatorApplicationPhriction.php index e5ade45e25..f27d3ef299 100644 --- a/src/applications/phriction/application/PhabricatorApplicationPhriction.php +++ b/src/applications/phriction/application/PhabricatorApplicationPhriction.php @@ -28,6 +28,12 @@ final class PhabricatorApplicationPhriction extends PhabricatorApplication { ); } + public function getEventListeners() { + return array( + new PhrictionActionMenuEventListener(), + ); + } + public function getRoutes() { return array( // Match "/w/" with slug "/". diff --git a/src/applications/phriction/event/PhrictionActionMenuEventListener.php b/src/applications/phriction/event/PhrictionActionMenuEventListener.php new file mode 100644 index 0000000000..31e00a1e3f --- /dev/null +++ b/src/applications/phriction/event/PhrictionActionMenuEventListener.php @@ -0,0 +1,35 @@ +listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS); + } + + public function handleEvent(PhutilEvent $event) { + switch ($event->getType()) { + case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS: + $this->handleActionsEvent($event); + break; + } + } + + private function handleActionsEvent($event) { + $actions = $event->getValue('actions'); + + $action = id(new PhabricatorActionView()) + ->setIcon('phriction-dark') + ->setIconSheet(PHUIIconView::SPRITE_APPS) + ->setName(pht('View Wiki')); + + $object = $event->getValue('object'); + if ($object instanceof PhabricatorProject) { + $slug = PhabricatorSlug::normalize($object->getPhrictionSlug()); + $href = '/w/projects/'.$slug; + $actions[] = $action->setHref($href); + } + + $event->setValue('actions', $actions); + } + +} diff --git a/src/applications/project/controller/PhabricatorProjectController.php b/src/applications/project/controller/PhabricatorProjectController.php index 17eab27667..f3f3d133a7 100644 --- a/src/applications/project/controller/PhabricatorProjectController.php +++ b/src/applications/project/controller/PhabricatorProjectController.php @@ -2,51 +2,6 @@ abstract class PhabricatorProjectController extends PhabricatorController { - protected function buildLocalNavigation(PhabricatorProject $project) { - $id = $project->getID(); - - $nav_view = new AphrontSideNavFilterView(); - $uri = new PhutilURI('/project/view/'.$id.'/'); - $nav_view->setBaseURI($uri); - - $external_arrow = "\xE2\x86\x97"; - $tasks_uri = '/maniphest/view/all/?projects='.$project->getPHID(); - $slug = PhabricatorSlug::normalize($project->getPhrictionSlug()); - $phriction_uri = '/w/projects/'.$slug; - - $edit_uri = '/project/edit/'.$id.'/'; - $members_uri = '/project/members/'.$id.'/'; - - $nav_view->addLabel(pht('Project')); - $nav_view->addFilter('dashboard', pht('Dashboard')); - $nav_view->addFilter(null, pht('Tasks').' '.$external_arrow, $tasks_uri); - $nav_view->addFilter(null, pht('Wiki').' '.$external_arrow, $phriction_uri); - - $user = $this->getRequest()->getUser(); - $can_edit = PhabricatorPolicyCapability::CAN_EDIT; - - $nav_view->addLabel(pht('Manage')); - if (PhabricatorPolicyFilter::hasCapability($user, $project, $can_edit)) { - $nav_view->addFilter('edit', pht("Edit Project"), $edit_uri); - $nav_view->addFilter('members', pht("Edit Members"), $members_uri); - } else { - $nav_view->addFilter( - 'edit', - pht("Edit Project"), - $edit_uri, - $relative = false, - 'disabled'); - $nav_view->addFilter( - 'members', - pht("Edit Members"), - $members_uri, - $relative = false, - 'disabled'); - } - - return $nav_view; - } - public function buildSideNavView($filter = null, $for_app = false) { $user = $this->getRequest()->getUser(); diff --git a/src/applications/project/controller/PhabricatorProjectMembersEditController.php b/src/applications/project/controller/PhabricatorProjectMembersEditController.php index e604900645..795c684658 100644 --- a/src/applications/project/controller/PhabricatorProjectMembersEditController.php +++ b/src/applications/project/controller/PhabricatorProjectMembersEditController.php @@ -113,11 +113,6 @@ final class PhabricatorProjectMembersEditController $box->addPadding(PHUI::PADDING_LARGE); $box->addMargin(PHUI::MARGIN_LARGE); - $nav = $this->buildLocalNavigation($project); - $nav->selectFilter('members'); - $nav->appendChild($form); - $nav->appendChild($box); - $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); $crumbs->addCrumb( id(new PhabricatorCrumbView()) @@ -127,10 +122,13 @@ final class PhabricatorProjectMembersEditController id(new PhabricatorCrumbView()) ->setName(pht('Edit Members')) ->setHref($this->getApplicationURI())); - $nav->setCrumbs($crumbs); return $this->buildApplicationPage( - $nav, + array( + $crumbs, + $form, + $box, + ), array( 'title' => $title, 'device' => true, diff --git a/src/applications/project/controller/PhabricatorProjectProfileController.php b/src/applications/project/controller/PhabricatorProjectProfileController.php index e6559f2bb9..6142aaf375 100644 --- a/src/applications/project/controller/PhabricatorProjectProfileController.php +++ b/src/applications/project/controller/PhabricatorProjectProfileController.php @@ -34,10 +34,6 @@ final class PhabricatorProjectProfileController $picture = $profile->loadProfileImageURI(); - $nav_view = $this->buildLocalNavigation($project); - - $this->page = $nav_view->selectFilter($this->page, 'dashboard'); - require_celerity_resource('phabricator-profile-css'); $tasks = $this->renderTasksPage($project, $profile); @@ -51,12 +47,10 @@ final class PhabricatorProjectProfileController $query->setViewer($this->getRequest()->getUser()); $stories = $query->execute(); $feed = $this->renderStories($stories); - $about = $this->renderAboutPage($project, $profile); $people = $this->renderPeoplePage($project, $profile); - $col1 = hsprintf('%s%s', $about, $people); $content = id(new AphrontMultiColumnView()) - ->addColumn($col1) + ->addColumn($people) ->addColumn($feed) ->setFluidLayout(true); @@ -70,97 +64,29 @@ final class PhabricatorProjectProfileController ->setSubheader(phutil_utf8_shorten($profile->getBlurb(), 1024)) ->setImage($picture); - $action = null; - if (!$project->isUserMember($user->getPHID())) { - $can_join = PhabricatorPolicyFilter::hasCapability( - $user, - $project, - PhabricatorPolicyCapability::CAN_JOIN); + $actions = $this->buildActionListView($project); + $properties = $this->buildPropertyListView($project); - $action = id(new PhabricatorActionView()) - ->setUser($user) - ->setRenderAsForm(true) - ->setHref('/project/update/'.$project->getID().'/join/') - ->setIcon('new') - ->setDisabled(!$can_join) - ->setName(pht('Join Project')); - } else { - $action = id(new PhabricatorActionView()) - ->setWorkflow(true) - ->setHref('/project/update/'.$project->getID().'/leave/') - ->setIcon('delete') - ->setName(pht('Leave Project...')); - } - - $action_list = id(new PhabricatorActionListView()) - ->setUser($user) - ->setObjectURI($request->getRequestURI()) - ->addAction($action); - - $nav_view->appendChild($header); - $nav_view->appendChild($action_list); - $nav_view->appendChild($content); + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName($project->getName())); return $this->buildApplicationPage( - $nav_view, array( - 'title' => pht('%s Project', $project->getName()), + $crumbs, + $header, + $actions, + $properties, + $content, + ), + array( + 'title' => $project->getName(), 'device' => true, 'dust' => true, )); } - private function renderAboutPage( - PhabricatorProject $project, - PhabricatorProjectProfile $profile) { - - $viewer = $this->getRequest()->getUser(); - - $blurb = $profile->getBlurb(); - $blurb = phutil_escape_html_newlines($blurb); - - $phids = array($project->getAuthorPHID()); - $phids = array_unique($phids); - $handles = $this->loadViewerHandles($phids); - - $timestamp = phabricator_datetime($project->getDateCreated(), $viewer); - - $about = hsprintf( - '
-

%s

-
- - - - - - - - - - - - - - - - - -
%s%s
%s%s
PHID%s
%s%s
-
-
', - pht('About This Project'), - pht('Creator'), - $handles[$project->getAuthorPHID()]->renderLink(), - pht('Created'), - $timestamp, - $project->getPHID(), - pht('Blurb'), - $blurb); - - return $about; - } - private function renderPeoplePage( PhabricatorProject $project, PhabricatorProjectProfile $profile) { @@ -272,8 +198,79 @@ final class PhabricatorProjectProfileController return $content; } - public function buildApplicationMenu() { - return $this->buildLocalNavigation($this->project)->getMenu(); + private function buildActionListView(PhabricatorProject $project) { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $id = $project->getID(); + + $view = id(new PhabricatorActionListView()) + ->setUser($viewer) + ->setObject($project) + ->setObjectURI($request->getRequestURI()); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $project, + PhabricatorPolicyCapability::CAN_EDIT); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Edit Project')) + ->setIcon('edit') + ->setHref($this->getApplicationURI("edit/{$id}/")) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit)); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Edit Members')) + ->setIcon('edit') + ->setHref($this->getApplicationURI("members/{$id}/")) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit)); + + + $action = null; + if (!$project->isUserMember($viewer->getPHID())) { + $can_join = PhabricatorPolicyFilter::hasCapability( + $viewer, + $project, + PhabricatorPolicyCapability::CAN_JOIN); + + $action = id(new PhabricatorActionView()) + ->setUser($viewer) + ->setRenderAsForm(true) + ->setHref('/project/update/'.$project->getID().'/join/') + ->setIcon('new') + ->setDisabled(!$can_join) + ->setName(pht('Join Project')); + } else { + $action = id(new PhabricatorActionView()) + ->setWorkflow(true) + ->setHref('/project/update/'.$project->getID().'/leave/') + ->setIcon('delete') + ->setName(pht('Leave Project...')); + } + $view->addAction($action); + + return $view; } + private function buildPropertyListView(PhabricatorProject $project) { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $view = id(new PhabricatorPropertyListView()) + ->setUser($viewer) + ->setObject($project); + + $view->addProperty( + pht('Created'), + phabricator_datetime($project->getDateCreated(), $viewer)); + + return $view; + } + + } diff --git a/src/applications/project/controller/PhabricatorProjectProfileEditController.php b/src/applications/project/controller/PhabricatorProjectProfileEditController.php index c4b6a35d49..eec98ff974 100644 --- a/src/applications/project/controller/PhabricatorProjectProfileEditController.php +++ b/src/applications/project/controller/PhabricatorProjectProfileEditController.php @@ -220,13 +220,6 @@ final class PhabricatorProjectProfileEditController ->addCancelButton('/project/view/'.$project->getID().'/') ->setValue(pht('Save'))); - $nav = $this->buildLocalNavigation($project); - $nav->selectFilter('edit'); - $nav->appendChild( - array( - $error_view, - $form, - )); $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); $crumbs->addCrumb( @@ -237,10 +230,13 @@ final class PhabricatorProjectProfileEditController id(new PhabricatorCrumbView()) ->setName(pht('Edit Project')) ->setHref($this->getApplicationURI())); - $nav->setCrumbs($crumbs); return $this->buildApplicationPage( - $nav, + array( + $crumbs, + $error_view, + $form, + ), array( 'title' => $title, 'device' => true,