mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-30 09:20:58 +01:00
Put feed on project home, move history to a separate page
Summary: Ref T10054. This shuffles some stuff around to move us closer to mocks in M1450 in terms of what information is on which pages. Home now has feed, members, watchers, link to "edit project / project edit history". History now has edit history, edit details, edit picture, archive/unarchive. Test Plan: New home page: {F1064889} New edit/history page: {F1064890} Reviewers: chad Reviewed By: chad Maniphest Tasks: T10054 Differential Revision: https://secure.phabricator.com/D15060
This commit is contained in:
parent
6b1b21c999
commit
9f36594100
11 changed files with 234 additions and 153 deletions
|
@ -2881,9 +2881,9 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectFeedController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PhabricatorProjectHeraldAction' => 'HeraldAction',
|
||||
'PhabricatorProjectHistoryController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectIconSet' => 'PhabricatorIconSet',
|
||||
'PhabricatorProjectListController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectListView' => 'AphrontView',
|
||||
|
|
|
@ -44,7 +44,7 @@ final class PhabricatorFileComposeController
|
|||
));
|
||||
|
||||
if ($project_phid) {
|
||||
$edit_uri = '/project/profile/'.$project->getID().'/';
|
||||
$edit_uri = '/project/history/'.$project->getID().'/';
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorProjectTransaction())
|
||||
|
|
|
@ -55,8 +55,6 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorProjectMembersRemoveController',
|
||||
'profile/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorProjectProfileController',
|
||||
'feed/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorProjectFeedController',
|
||||
'view/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorProjectViewController',
|
||||
'picture/(?P<id>[1-9]\d*)/'
|
||||
|
|
|
@ -20,7 +20,7 @@ final class PhabricatorProjectArchiveController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$edit_uri = $this->getApplicationURI('profile/'.$project->getID().'/');
|
||||
$edit_uri = $this->getApplicationURI('history/'.$project->getID().'/');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
if ($project->isArchived()) {
|
||||
|
|
|
@ -23,8 +23,8 @@ final class PhabricatorProjectEditPictureController
|
|||
|
||||
$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;
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectFeedController
|
||||
extends PhabricatorProjectController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->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());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectHistoryController
|
||||
extends PhabricatorProjectController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->loadProject();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$viewer = $request->getUser();
|
||||
$project = $this->getProject();
|
||||
$id = $project->getID();
|
||||
$picture = $project->getProfileImageURI();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Project History'))
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($project)
|
||||
->setImage($picture);
|
||||
|
||||
if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) {
|
||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||
} else {
|
||||
$header->setStatus('fa-ban', 'red', pht('Archived'));
|
||||
}
|
||||
|
||||
$actions = $this->buildActionListView($project);
|
||||
$properties = $this->buildPropertyListView($project, $actions);
|
||||
|
||||
$object_box = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->addPropertyList($properties);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$project,
|
||||
new PhabricatorProjectTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$nav = $this->getProfileMenu();
|
||||
$nav->selectFilter(PhabricatorProject::PANEL_PROFILE);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('History'));
|
||||
|
||||
return $this->newPage()
|
||||
->setNavigation($nav)
|
||||
->setCrumbs($crumbs)
|
||||
->setTitle($project->getName())
|
||||
->appendChild(
|
||||
array(
|
||||
$object_box,
|
||||
$timeline,
|
||||
));
|
||||
}
|
||||
|
||||
private function buildActionListView(PhabricatorProject $project) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$id = $project->getID();
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$project,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$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}/"))
|
||||
->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));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildPropertyListView(
|
||||
PhabricatorProject $project,
|
||||
PhabricatorActionListView $actions) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setActionList($actions);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -8,13 +8,12 @@ final class PhabricatorProjectProfileController
|
|||
}
|
||||
|
||||
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 @@ final class PhabricatorProjectProfileController
|
|||
->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 @@ final class PhabricatorProjectProfileController
|
|||
->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 @@ final class PhabricatorProjectProfileController
|
|||
->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 @@ final class PhabricatorProjectProfileController
|
|||
->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 @@ final class PhabricatorProjectProfileController
|
|||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,12 @@ final class PhabricatorProjectEditEngine
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -32,15 +32,6 @@ final class PhabricatorProjectProfilePanelEngine
|
|||
->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);
|
||||
|
|
|
@ -4,6 +4,7 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
|
|||
|
||||
private $project;
|
||||
private $userPHIDs;
|
||||
private $limit;
|
||||
|
||||
public function setProject(PhabricatorProject $project) {
|
||||
$this->project = $project;
|
||||
|
@ -23,6 +24,15 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
|
|||
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 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
|
|||
$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 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
|
|||
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 @@ abstract class PhabricatorProjectUserListView extends AphrontView {
|
|||
$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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue