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 @@ -2881,9 +2881,9 @@ 'PhabricatorProjectEditController' => 'applications/project/controller/PhabricatorProjectEditController.php', 'PhabricatorProjectEditEngine' => 'applications/project/engine/PhabricatorProjectEditEngine.php', 'PhabricatorProjectEditPictureController' => 'applications/project/controller/PhabricatorProjectEditPictureController.php', - 'PhabricatorProjectFeedController' => 'applications/project/controller/PhabricatorProjectFeedController.php', 'PhabricatorProjectFulltextEngine' => 'applications/project/search/PhabricatorProjectFulltextEngine.php', 'PhabricatorProjectHeraldAction' => 'applications/project/herald/PhabricatorProjectHeraldAction.php', + 'PhabricatorProjectHistoryController' => 'applications/project/controller/PhabricatorProjectHistoryController.php', 'PhabricatorProjectIconSet' => 'applications/project/icon/PhabricatorProjectIconSet.php', 'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php', 'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php', @@ -7283,9 +7283,9 @@ 'PhabricatorProjectEditController' => 'PhabricatorProjectController', 'PhabricatorProjectEditEngine' => 'PhabricatorEditEngine', 'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController', - 'PhabricatorProjectFeedController' => 'PhabricatorProjectController', 'PhabricatorProjectFulltextEngine' => 'PhabricatorFulltextEngine', 'PhabricatorProjectHeraldAction' => 'HeraldAction', + 'PhabricatorProjectHistoryController' => 'PhabricatorProjectController', 'PhabricatorProjectIconSet' => 'PhabricatorIconSet', 'PhabricatorProjectListController' => 'PhabricatorProjectController', 'PhabricatorProjectListView' => 'AphrontView', diff --git a/src/applications/files/controller/PhabricatorFileComposeController.php b/src/applications/files/controller/PhabricatorFileComposeController.php --- a/src/applications/files/controller/PhabricatorFileComposeController.php +++ b/src/applications/files/controller/PhabricatorFileComposeController.php @@ -44,7 +44,7 @@ )); if ($project_phid) { - $edit_uri = '/project/profile/'.$project->getID().'/'; + $edit_uri = '/project/history/'.$project->getID().'/'; $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction()) diff --git a/src/applications/project/application/PhabricatorProjectApplication.php b/src/applications/project/application/PhabricatorProjectApplication.php --- a/src/applications/project/application/PhabricatorProjectApplication.php +++ b/src/applications/project/application/PhabricatorProjectApplication.php @@ -55,8 +55,6 @@ => 'PhabricatorProjectMembersRemoveController', 'profile/(?P[1-9]\d*)/' => 'PhabricatorProjectProfileController', - 'feed/(?P[1-9]\d*)/' - => 'PhabricatorProjectFeedController', 'view/(?P[1-9]\d*)/' => 'PhabricatorProjectViewController', 'picture/(?P[1-9]\d*)/' diff --git a/src/applications/project/controller/PhabricatorProjectArchiveController.php b/src/applications/project/controller/PhabricatorProjectArchiveController.php --- a/src/applications/project/controller/PhabricatorProjectArchiveController.php +++ b/src/applications/project/controller/PhabricatorProjectArchiveController.php @@ -20,7 +20,7 @@ return new Aphront404Response(); } - $edit_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); + $edit_uri = $this->getApplicationURI('history/'.$project->getID().'/'); if ($request->isFormPost()) { if ($project->isArchived()) { diff --git a/src/applications/project/controller/PhabricatorProjectEditPictureController.php b/src/applications/project/controller/PhabricatorProjectEditPictureController.php --- a/src/applications/project/controller/PhabricatorProjectEditPictureController.php +++ b/src/applications/project/controller/PhabricatorProjectEditPictureController.php @@ -23,8 +23,8 @@ $this->setProject($project); - $edit_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); - $view_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); + $edit_uri = $this->getApplicationURI('history/'.$project->getID().'/'); + $view_uri = $this->getApplicationURI('history/'.$project->getID().'/'); $supported_formats = PhabricatorFile::getTransformableImageFormats(); $e_file = true; diff --git a/src/applications/project/controller/PhabricatorProjectFeedController.php b/src/applications/project/controller/PhabricatorProjectFeedController.php deleted file mode 100644 --- a/src/applications/project/controller/PhabricatorProjectFeedController.php +++ /dev/null @@ -1,62 +0,0 @@ -getUser(); - - $response = $this->loadProject(); - if ($response) { - return $response; - } - - $project = $this->getProject(); - $id = $project->getID(); - - $stories = id(new PhabricatorFeedQuery()) - ->setViewer($viewer) - ->setFilterPHIDs( - array( - $project->getPHID(), - )) - ->setLimit(50) - ->execute(); - - $feed = $this->renderStories($stories); - - $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Project Activity')) - ->appendChild($feed); - - $nav = $this->getProfileMenu(); - $nav->selectFilter('feed'); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Feed')); - - return $this->newPage() - ->setNavigation($nav) - ->setCrumbs($crumbs) - ->setTitle(array($project->getName(), pht('Feed'))) - ->appendChild($box); - } - - private function renderStories(array $stories) { - assert_instances_of($stories, 'PhabricatorFeedStory'); - - $builder = new PhabricatorFeedBuilder($stories); - $builder->setUser($this->getRequest()->getUser()); - $builder->setShowHovercards(true); - $view = $builder->buildView(); - - return phutil_tag_div( - 'profile-feed', - $view->render()); - } - -} diff --git a/src/applications/project/controller/PhabricatorProjectProfileController.php b/src/applications/project/controller/PhabricatorProjectHistoryController.php copy from src/applications/project/controller/PhabricatorProjectProfileController.php copy to src/applications/project/controller/PhabricatorProjectHistoryController.php --- a/src/applications/project/controller/PhabricatorProjectProfileController.php +++ b/src/applications/project/controller/PhabricatorProjectHistoryController.php @@ -1,6 +1,6 @@ getUser(); - $response = $this->loadProject(); if ($response) { return $response; } + $viewer = $request->getUser(); $project = $this->getProject(); $id = $project->getID(); $picture = $project->getProfileImageURI(); $header = id(new PHUIHeaderView()) - ->setHeader($project->getName()) + ->setHeader(pht('Project History')) ->setUser($viewer) ->setPolicyObject($project) ->setImage($picture); @@ -47,14 +46,17 @@ $nav->selectFilter(PhabricatorProject::PANEL_PROFILE); $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('History')); return $this->newPage() ->setNavigation($nav) ->setCrumbs($crumbs) ->setTitle($project->getName()) - ->setPageObjectPHIDs(array($project->getPHID())) - ->appendChild($object_box) - ->appendChild($timeline); + ->appendChild( + array( + $object_box, + $timeline, + )); } private function buildActionListView(PhabricatorProject $project) { @@ -64,8 +66,7 @@ $id = $project->getID(); $view = id(new PhabricatorActionListView()) - ->setUser($viewer) - ->setObject($project); + ->setUser($viewer); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, @@ -74,6 +75,12 @@ $view->addAction( id(new PhabricatorActionView()) + ->setName(pht('Back to Profile')) + ->setIcon('fa-chevron-left') + ->setHref($project->getURI())); + + $view->addAction( + id(new PhabricatorActionView()) ->setName(pht('Edit Details')) ->setIcon('fa-pencil') ->setHref($this->getApplicationURI("edit/{$id}/")) @@ -117,45 +124,8 @@ $view = id(new PHUIPropertyListView()) ->setUser($viewer) - ->setObject($project) ->setActionList($actions); - $hashtags = array(); - foreach ($project->getSlugs() as $slug) { - $hashtags[] = id(new PHUITagView()) - ->setType(PHUITagView::TYPE_OBJECT) - ->setName('#'.$slug->getSlug()); - } - - if ($hashtags) { - $view->addProperty(pht('Hashtags'), phutil_implode_html(' ', $hashtags)); - } - - $view->addProperty( - pht('Members'), - $project->getMemberPHIDs() - ? $viewer - ->renderHandleList($project->getMemberPHIDs()) - ->setAsInline(true) - : phutil_tag('em', array(), pht('None'))); - - $view->addProperty( - pht('Watchers'), - $project->getWatcherPHIDs() - ? $viewer - ->renderHandleList($project->getWatcherPHIDs()) - ->setAsInline(true) - : phutil_tag('em', array(), pht('None'))); - - $view->addProperty( - pht('Looks Like'), - $viewer->renderHandle($project->getPHID())->setAsTag(true)); - - $field_list = PhabricatorCustomField::getObjectFields( - $project, - PhabricatorCustomField::ROLE_VIEW); - $field_list->appendFieldsToPropertyList($project, $viewer, $view); - return $view; } diff --git a/src/applications/project/controller/PhabricatorProjectProfileController.php b/src/applications/project/controller/PhabricatorProjectProfileController.php --- a/src/applications/project/controller/PhabricatorProjectProfileController.php +++ b/src/applications/project/controller/PhabricatorProjectProfileController.php @@ -8,13 +8,12 @@ } public function handleRequest(AphrontRequest $request) { - $viewer = $request->getUser(); - $response = $this->loadProject(); if ($response) { return $response; } + $viewer = $request->getUser(); $project = $this->getProject(); $id = $project->getID(); $picture = $project->getProfileImageURI(); @@ -38,14 +37,46 @@ ->setHeader($header) ->addPropertyList($properties); - $timeline = $this->buildTransactionTimeline( - $project, - new PhabricatorProjectTransactionQuery()); - $timeline->setShouldTerminate(true); + $member_list = id(new PhabricatorProjectMemberListView()) + ->setUser($viewer) + ->setProject($project) + ->setLimit(5) + ->setUserPHIDs($project->getMemberPHIDs()); + + $watcher_list = id(new PhabricatorProjectWatcherListView()) + ->setUser($viewer) + ->setProject($project) + ->setLimit(5) + ->setUserPHIDs($project->getWatcherPHIDs()); $nav = $this->getProfileMenu(); $nav->selectFilter(PhabricatorProject::PANEL_PROFILE); + + $stories = id(new PhabricatorFeedQuery()) + ->setViewer($viewer) + ->setFilterPHIDs( + array( + $project->getPHID(), + )) + ->setLimit(50) + ->execute(); + + $feed = $this->renderStories($stories); + + $feed = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Recent Activity')) + ->appendChild($feed); + + $columns = id(new AphrontMultiColumnView()) + ->setFluidLayout(true) + ->addColumn($feed) + ->addColumn( + array( + $member_list, + $watcher_list, + )); + $crumbs = $this->buildApplicationCrumbs(); return $this->newPage() @@ -53,8 +84,11 @@ ->setCrumbs($crumbs) ->setTitle($project->getName()) ->setPageObjectPHIDs(array($project->getPHID())) - ->appendChild($object_box) - ->appendChild($timeline); + ->appendChild( + array( + $object_box, + $columns, + )); } private function buildActionListView(PhabricatorProject $project) { @@ -67,44 +101,11 @@ ->setUser($viewer) ->setObject($project); - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $project, - PhabricatorPolicyCapability::CAN_EDIT); - $view->addAction( id(new PhabricatorActionView()) - ->setName(pht('Edit Details')) + ->setName(pht('Edit Project')) ->setIcon('fa-pencil') - ->setHref($this->getApplicationURI("edit/{$id}/")) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Edit Picture')) - ->setIcon('fa-picture-o') - ->setHref($this->getApplicationURI("picture/{$id}/")) - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)); - - if ($project->isArchived()) { - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Activate Project')) - ->setIcon('fa-check') - ->setHref($this->getApplicationURI("archive/{$id}/")) - ->setDisabled(!$can_edit) - ->setWorkflow(true)); - } else { - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Archive Project')) - ->setIcon('fa-ban') - ->setHref($this->getApplicationURI("archive/{$id}/")) - ->setDisabled(!$can_edit) - ->setWorkflow(true)); - } + ->setHref($this->getApplicationURI("history/{$id}/"))); return $view; } @@ -120,33 +121,6 @@ ->setObject($project) ->setActionList($actions); - $hashtags = array(); - foreach ($project->getSlugs() as $slug) { - $hashtags[] = id(new PHUITagView()) - ->setType(PHUITagView::TYPE_OBJECT) - ->setName('#'.$slug->getSlug()); - } - - if ($hashtags) { - $view->addProperty(pht('Hashtags'), phutil_implode_html(' ', $hashtags)); - } - - $view->addProperty( - pht('Members'), - $project->getMemberPHIDs() - ? $viewer - ->renderHandleList($project->getMemberPHIDs()) - ->setAsInline(true) - : phutil_tag('em', array(), pht('None'))); - - $view->addProperty( - pht('Watchers'), - $project->getWatcherPHIDs() - ? $viewer - ->renderHandleList($project->getWatcherPHIDs()) - ->setAsInline(true) - : phutil_tag('em', array(), pht('None'))); - $view->addProperty( pht('Looks Like'), $viewer->renderHandle($project->getPHID())->setAsTag(true)); @@ -159,5 +133,15 @@ return $view; } + private function renderStories(array $stories) { + assert_instances_of($stories, 'PhabricatorFeedStory'); + + $builder = new PhabricatorFeedBuilder($stories); + $builder->setUser($this->getRequest()->getUser()); + $builder->setShowHovercards(true); + $view = $builder->buildView(); + + return phutil_tag_div('profile-feed', $view->render()); + } } diff --git a/src/applications/project/engine/PhabricatorProjectEditEngine.php b/src/applications/project/engine/PhabricatorProjectEditEngine.php --- a/src/applications/project/engine/PhabricatorProjectEditEngine.php +++ b/src/applications/project/engine/PhabricatorProjectEditEngine.php @@ -78,7 +78,12 @@ } protected function getObjectViewURI($object) { - return $object->getURI(); + if ($this->getIsCreate()) { + return $object->getURI(); + } else { + $id = $object->getID(); + return "/project/history/{$id}/"; + } } protected function getObjectCreateCancelURI($object) { diff --git a/src/applications/project/engine/PhabricatorProjectProfilePanelEngine.php b/src/applications/project/engine/PhabricatorProjectProfilePanelEngine.php --- a/src/applications/project/engine/PhabricatorProjectProfilePanelEngine.php +++ b/src/applications/project/engine/PhabricatorProjectProfilePanelEngine.php @@ -32,15 +32,6 @@ ->setPanelProperty('name', pht('Open Tasks')) ->setPanelProperty('uri', $uri); - // TODO: This is temporary. - $id = $object->getID(); - $panels[] = $this->newPanel() - ->setBuiltinKey('feed') - ->setPanelKey(PhabricatorLinkProfilePanel::PANELKEY) - ->setPanelProperty('icon', 'feed') - ->setPanelProperty('name', pht('Feed')) - ->setPanelProperty('uri', "/project/feed/{$id}/"); - $panels[] = $this->newPanel() ->setBuiltinKey(PhabricatorProject::PANEL_MEMBERS) ->setPanelKey(PhabricatorProjectMembersProfilePanel::PANELKEY); diff --git a/src/applications/project/view/PhabricatorProjectUserListView.php b/src/applications/project/view/PhabricatorProjectUserListView.php --- a/src/applications/project/view/PhabricatorProjectUserListView.php +++ b/src/applications/project/view/PhabricatorProjectUserListView.php @@ -4,6 +4,7 @@ private $project; private $userPHIDs; + private $limit; public function setProject(PhabricatorProject $project) { $this->project = $project; @@ -23,6 +24,15 @@ return $this->userPHIDs; } + public function setLimit($limit) { + $this->limit = $limit; + return $this; + } + + public function getLimit() { + return $this->limit; + } + abstract protected function canEditList(); abstract protected function getNoDataString(); abstract protected function getRemoveURI($phid); @@ -39,7 +49,14 @@ $list = id(new PHUIObjectItemListView()) ->setNoDataString($no_data); - $user_phids = array_reverse($user_phids); + $limit = $this->getLimit(); + + // If we're showing everything, show oldest to newest. If we're showing + // only a slice, show newest to oldest. + if (!$limit) { + $user_phids = array_reverse($user_phids); + } + $handles = $viewer->loadHandles($user_phids); // Always put the viewer first if they are on the list. @@ -48,7 +65,13 @@ array_select_keys($user_phids, array($viewer->getPHID())) + $user_phids; - foreach ($user_phids as $user_phid) { + if ($limit) { + $render_phids = array_slice($user_phids, 0, $limit); + } else { + $render_phids = $user_phids; + } + + foreach ($render_phids as $user_phid) { $handle = $handles[$user_phid]; $item = id(new PHUIObjectItemView()) @@ -70,8 +93,17 @@ $list->addItem($item); } + if ($user_phids) { + $header = pht( + '%s (%s)', + $this->getHeaderText(), + phutil_count($user_phids)); + } else { + $header = $this->getHeaderText(); + } + return id(new PHUIObjectBoxView()) - ->setHeaderText($this->getHeaderText()) + ->setHeaderText($header) ->setObjectList($list); }