diff --git a/src/applications/diffusion/controller/DiffusionBrowseController.php b/src/applications/diffusion/controller/DiffusionBrowseController.php index 48313014c0..ea960bdae0 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseController.php @@ -1,202 +1,202 @@ getDiffusionRequest(); $form = id(new AphrontFormView()) ->setUser($this->getRequest()->getUser()) ->setMethod('GET'); switch ($drequest->getRepository()->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: $form->appendChild(pht('Search is not available in Subversion.')); break; default: $form ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Search Here')) ->setName('grep') ->setValue($this->getRequest()->getStr('grep')) ->setCaption(pht('Enter a regular expression.'))) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Search File Content'))); break; } $filter = new AphrontListFilterView(); $filter->appendChild($form); if ($collapsed) { $filter->setCollapsed( pht('Show Search'), pht('Hide Search'), pht('Search for file content in this directory.'), '#'); } return $filter; } protected function markupText($text) { $engine = PhabricatorMarkupEngine::newDiffusionMarkupEngine(); $engine->setConfig('viewer', $this->getRequest()->getUser()); $text = $engine->markupText($text); $text = phutil_tag( 'div', array( 'class' => 'phabricator-remarkup', ), $text); return $text; } protected function buildHeaderView(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); $header = id(new PHUIHeaderView()) ->setUser($viewer) - ->setHeader($this->renderPathLinks($drequest, 'browse')) + ->setHeader($this->renderPathLinks($drequest, $mode = 'browse')) ->setPolicyObject($drequest->getRepository()); return $header; } protected function buildActionView(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setUser($viewer); $history_uri = $drequest->generateURI( array( 'action' => 'history', )); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('View History')) ->setHref($history_uri) ->setIcon('history')); $behind_head = $drequest->getRawCommit(); $head_uri = $drequest->generateURI( array( 'commit' => '', 'action' => 'browse', )); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Jump to HEAD')) ->setHref($head_uri) ->setIcon('home') ->setDisabled(!$behind_head)); // TODO: Ideally, this should live in Owners and be event-triggered, but // there's no reasonable object for it to react to right now. $owners_uri = id(new PhutilURI('/owners/view/search/')) ->setQueryParams( array( 'repository' => $drequest->getCallsign(), 'path' => '/'.$drequest->getPath(), )); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Find Owners')) ->setHref((string)$owners_uri) ->setIcon('preview')); return $view; } protected function buildPropertyView(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorPropertyListView()) ->setUser($viewer); $stable_commit = $drequest->getStableCommitName(); $callsign = $drequest->getRepository()->getCallsign(); $view->addProperty( pht('Commit'), phutil_tag( 'a', array( 'href' => $drequest->generateURI( array( 'action' => 'commit', 'commit' => $stable_commit, )), ), $drequest->getRepository()->formatCommitName($stable_commit))); if ($drequest->getTagContent()) { $view->addProperty( pht('Tag'), $drequest->getSymbolicCommit()); $view->addSectionHeader(pht('Tag Content')); $view->addTextContent($this->markupText($drequest->getTagContent())); } return $view; } protected function buildOpenRevisions() { $user = $this->getRequest()->getUser(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $path = $drequest->getPath(); $path_map = id(new DiffusionPathIDQuery(array($path)))->loadPathIDs(); $path_id = idx($path_map, $path); if (!$path_id) { return null; } $revisions = id(new DifferentialRevisionQuery()) ->setViewer($user) ->withPath($repository->getID(), $path_id) ->withStatus(DifferentialRevisionQuery::STATUS_OPEN) ->setOrder(DifferentialRevisionQuery::ORDER_PATH_MODIFIED) ->setLimit(10) ->needRelationships(true) ->execute(); if (!$revisions) { return null; } $view = id(new DifferentialRevisionListView()) ->setRevisions($revisions) ->setFields(DifferentialRevisionListView::getDefaultFields($user)) ->setUser($user) ->loadAssets(); $phids = $view->getRequiredHandlePHIDs(); $handles = $this->loadViewerHandles($phids); $view->setHandles($handles); $header = id(new PHUIHeaderView()) ->setHeader(pht('Pending Differential Revisions')); return array( $header, $view, ); } } diff --git a/src/applications/diffusion/controller/DiffusionChangeController.php b/src/applications/diffusion/controller/DiffusionChangeController.php index ee803f1da2..1e8192c35e 100644 --- a/src/applications/diffusion/controller/DiffusionChangeController.php +++ b/src/applications/diffusion/controller/DiffusionChangeController.php @@ -1,159 +1,154 @@ diffusionRequest; $viewer = $this->getRequest()->getUser(); $content = array(); $data = $this->callConduitWithDiffusionRequest( 'diffusion.diffquery', array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), )); $drequest->setCommit($data['effectiveCommit']); $raw_changes = ArcanistDiffChange::newFromConduit($data['changes']); $diff = DifferentialDiff::newFromRawChanges($raw_changes); $changesets = $diff->getChangesets(); $changeset = reset($changesets); if (!$changeset) { // TODO: Refine this. return new Aphront404Response(); } $repository = $drequest->getRepository(); $callsign = $repository->getCallsign(); $commit = $drequest->getRawCommit(); $changesets = array( 0 => $changeset, ); $changeset_view = new DifferentialChangesetListView(); $changeset_view->setChangesets($changesets); $changeset_view->setVisibleChangesets($changesets); $changeset_view->setRenderingReferences( array( 0 => $drequest->generateURI(array('action' => 'rendering-ref')) )); $raw_params = array( 'action' => 'browse', 'params' => array( 'view' => 'raw', ), ); $right_uri = $drequest->generateURI($raw_params); $raw_params['params']['before'] = $drequest->getRawCommit(); $left_uri = $drequest->generateURI($raw_params); $changeset_view->setRawFileURIs($left_uri, $right_uri); $changeset_view->setRenderURI('/diffusion/'.$callsign.'/diff/'); $changeset_view->setWhitespace( DifferentialChangesetParser::WHITESPACE_SHOW_ALL); $changeset_view->setUser($this->getRequest()->getUser()); // TODO: This is pretty awkward, unify the CSS between Diffusion and // Differential better. require_celerity_resource('differential-core-view-css'); $content[] = $changeset_view->render(); $crumbs = $this->buildCrumbs( array( 'branch' => true, 'path' => true, 'view' => 'change', )); - $links = $this->renderPathLinks($drequest); + $links = $this->renderPathLinks($drequest, $mode = 'browse'); $header = id(new PHUIHeaderView()) ->setHeader($links) ->setUser($viewer) ->setPolicyObject($drequest->getRepository()); $actions = $this->buildActionView($drequest); $properties = $this->buildPropertyView($drequest); return $this->buildApplicationPage( array( $crumbs, $header, $actions, $properties, $content, ), array( 'title' => pht('Change'), )); } private function buildActionView(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorActionListView()) ->setUser($viewer); $history_uri = $drequest->generateURI( array( 'action' => 'history', )); - $browse_uri = $drequest->generateURI( - array( - 'action' => 'browse', - )); - $view->addAction( id(new PhabricatorActionView()) ->setName(pht('View History')) ->setHref($history_uri) ->setIcon('history')); - $history_uri = $drequest->generateURI( + $browse_uri = $drequest->generateURI( array( 'action' => 'browse', )); $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Browse Content')) ->setHref($browse_uri) ->setIcon('file')); return $view; } protected function buildPropertyView(DiffusionRequest $drequest) { $viewer = $this->getRequest()->getUser(); $view = id(new PhabricatorPropertyListView()) ->setUser($viewer); $stable_commit = $drequest->getStableCommitName(); $callsign = $drequest->getRepository()->getCallsign(); $view->addProperty( pht('Commit'), phutil_tag( 'a', array( 'href' => $drequest->generateURI( array( 'action' => 'commit', 'commit' => $stable_commit, )), ), $drequest->getRepository()->formatCommitName($stable_commit))); return $view; } } diff --git a/src/applications/diffusion/controller/DiffusionController.php b/src/applications/diffusion/controller/DiffusionController.php index b45c4b010d..f75a75f389 100644 --- a/src/applications/diffusion/controller/DiffusionController.php +++ b/src/applications/diffusion/controller/DiffusionController.php @@ -1,333 +1,333 @@ getRequest()); $this->diffusionRequest = $drequest; } } public function setDiffusionRequest(DiffusionRequest $request) { $this->diffusionRequest = $request; return $this; } protected function getDiffusionRequest() { if (!$this->diffusionRequest) { throw new Exception("No Diffusion request object!"); } return $this->diffusionRequest; } final protected function buildSideNav($selected, $has_change_view) { $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI('')); $navs = array( 'history' => pht('History View'), 'browse' => pht('Browse View'), 'change' => pht('Change View'), ); if (!$has_change_view) { unset($navs['change']); } $drequest = $this->getDiffusionRequest(); $branch = $drequest->loadBranch(); if ($branch && $branch->getLintCommit()) { $navs['lint'] = pht('Lint View'); } $selected_href = null; foreach ($navs as $action => $name) { $href = $drequest->generateURI( array( 'action' => $action, )); if ($action == $selected) { $selected_href = $href; } $nav->addFilter($href, $name, $href); } $nav->selectFilter($selected_href, null); // TODO: URI encoding might need to be sorted out for this link. $nav->addFilter( '', pht("Search Owners \xE2\x86\x97"), '/owners/view/search/'. '?repository='.phutil_escape_uri($drequest->getCallsign()). '&path='.phutil_escape_uri('/'.$drequest->getPath())); return $nav; } public function buildCrumbs(array $spec = array()) { $crumbs = $this->buildApplicationCrumbs(); $crumb_list = $this->buildCrumbList($spec); foreach ($crumb_list as $crumb) { $crumbs->addCrumb($crumb); } return $crumbs; } private function buildCrumbList(array $spec = array()) { $spec = $spec + array( 'commit' => null, 'tags' => null, 'branches' => null, 'view' => null, ); $crumb_list = array(); // On the home page, we don't have a DiffusionRequest. if ($this->diffusionRequest) { $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); } else { $drequest = null; $repository = null; } if (!$repository) { return $crumb_list; } $callsign = $repository->getCallsign(); $repository_name = 'r'.$callsign; if (!$spec['commit'] && !$spec['tags'] && !$spec['branches']) { $branch_name = $drequest->getBranch(); if ($branch_name) { $repository_name .= ' ('.$branch_name.')'; } } $crumb = id(new PhabricatorCrumbView()) ->setName($repository_name); if (!$spec['view'] && !$spec['commit'] && !$spec['tags'] && !$spec['branches']) { $crumb_list[] = $crumb; return $crumb_list; } $crumb->setHref( $drequest->generateURI( array( 'action' => 'branch', 'path' => '/', ))); $crumb_list[] = $crumb; $raw_commit = $drequest->getRawCommit(); if ($spec['tags']) { $crumb = new PhabricatorCrumbView(); if ($spec['commit']) { $crumb->setName( pht("Tags for %s", 'r'.$callsign.$raw_commit)); $crumb->setHref($drequest->generateURI( array( 'action' => 'commit', 'commit' => $raw_commit, ))); } else { $crumb->setName(pht('Tags')); } $crumb_list[] = $crumb; return $crumb_list; } if ($spec['branches']) { $crumb = id(new PhabricatorCrumbView()) ->setName(pht('Branches')); $crumb_list[] = $crumb; return $crumb_list; } if ($spec['commit']) { $crumb = id(new PhabricatorCrumbView()) ->setName("r{$callsign}{$raw_commit}") ->setHref("r{$callsign}{$raw_commit}"); $crumb_list[] = $crumb; return $crumb_list; } $crumb = new PhabricatorCrumbView(); $view = $spec['view']; $path = null; if (isset($spec['path'])) { $path = $drequest->getPath(); } if ($raw_commit) { $commit_link = DiffusionView::linkCommit( $repository, $raw_commit); } else { $commit_link = ''; } switch ($view) { case 'history': $view_name = pht('History'); break; case 'browse': $view_name = pht('Browse'); break; case 'lint': $view_name = pht('Lint'); break; case 'change': $view_name = pht('Change'); break; } $uri_params = array( 'action' => $view, ); $crumb = id(new PhabricatorCrumbView()) ->setName($view_name); - if ($view == 'browse' || $view == 'change') { + if ($view == 'browse' || $view == 'change' || $view == 'history') { $crumb_list[] = $crumb; return $crumb_list; } $crumb->setHref($drequest->generateURI( array( 'path' => '', ) + $uri_params)); $crumb_list[] = $crumb; $path_parts = explode('/', $path); do { $last = array_pop($path_parts); } while (count($path_parts) && $last == ''); $path_sections = array(); $thus_far = ''; foreach ($path_parts as $path_part) { $thus_far .= $path_part.'/'; $path_sections[] = '/'; $path_sections[] = phutil_tag( 'a', array( 'href' => $drequest->generateURI( array( 'path' => $thus_far, ) + $uri_params), ), $path_part); } $path_sections[] = '/'.$last; $crumb_list[] = id(new PhabricatorCrumbView()) ->setName($path_sections); $last_crumb = array_pop($crumb_list); if ($raw_commit) { $jump_link = phutil_tag( 'a', array( 'href' => $drequest->generateURI( array( 'commit' => '', ) + $uri_params), ), pht('Jump to HEAD')); $name = $last_crumb->getName(); $name = hsprintf('%s @ %s (%s)', $name, $commit_link, $jump_link); $last_crumb->setName($name); } else if ($spec['view'] != 'lint') { $name = $last_crumb->getName(); $name = hsprintf('%s @ HEAD', $name); $last_crumb->setName($name); } $crumb_list[] = $last_crumb; return $crumb_list; } protected function callConduitWithDiffusionRequest( $method, array $params = array()) { $user = $this->getRequest()->getUser(); $drequest = $this->getDiffusionRequest(); return DiffusionQuery::callConduitWithDiffusionRequest( $user, $drequest, $method, $params); } protected function getRepositoryControllerURI( PhabricatorRepository $repository, $path) { return $this->getApplicationURI($repository->getCallsign().'/'.$path); } - protected function renderPathLinks(DiffusionRequest $drequest) { + protected function renderPathLinks(DiffusionRequest $drequest, $action) { $path = $drequest->getPath(); $path_parts = array_filter(explode('/', trim($path, '/'))); $links = array(); if ($path_parts) { $links[] = phutil_tag( 'a', array( 'href' => $drequest->generateURI( array( - 'action' => 'browse', + 'action' => $action, 'path' => '', )), ), 'r'.$drequest->getRepository()->getCallsign().'/'); $accum = ''; $last_key = last_key($path_parts); foreach ($path_parts as $key => $part) { $links[] = ' '; $accum .= '/'.$part; if ($key === $last_key) { $links[] = $part; } else { $links[] = phutil_tag( 'a', array( 'href' => $drequest->generateURI( array( - 'action' => 'browse', + 'action' => $action, 'path' => $accum, )), ), $part.'/'); } } } else { $links[] = 'r'.$drequest->getRepository()->getCallsign().'/'; } return $links; } } diff --git a/src/applications/diffusion/controller/DiffusionHistoryController.php b/src/applications/diffusion/controller/DiffusionHistoryController.php index ab37b920a5..e243c48bb0 100644 --- a/src/applications/diffusion/controller/DiffusionHistoryController.php +++ b/src/applications/diffusion/controller/DiffusionHistoryController.php @@ -1,106 +1,170 @@ diffusionRequest; $request = $this->getRequest(); + $viewer = $request->getUser(); + $repository = $drequest->getRepository(); $page_size = $request->getInt('pagesize', 100); - $offset = $request->getInt('page', 0); + $offset = $request->getInt('offset', 0); $params = array( 'commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), 'offset' => $offset, 'limit' => $page_size + 1); + if (!$request->getBool('copies')) { $params['needDirectChanges'] = true; $params['needChildChanges'] = true; } $history_results = $this->callConduitWithDiffusionRequest( 'diffusion.historyquery', $params); $history = DiffusionPathChange::newFromConduit( $history_results['pathChanges']); $pager = new AphrontPagerView(); $pager->setPageSize($page_size); $pager->setOffset($offset); - if (count($history) == $page_size + 1) { - array_pop($history); - $pager->setHasMorePages(true); - } else { - $pager->setHasMorePages(false); - } - $pager->setURI($request->getRequestURI(), 'page'); + $history = $pager->sliceResults($history); + + $pager->setURI($request->getRequestURI(), 'offset'); $show_graph = !strlen($drequest->getPath()); $content = array(); - if ($request->getBool('copies')) { - $button_title = pht('Hide Copies/Branches'); - $copies_new = null; - } else { - $button_title = pht('Show Copies/Branches'); - $copies_new = true; - } - - $button = phutil_tag( - 'a', - array( - 'class' => 'button small grey', - 'href' => $request->getRequestURI()->alter('copies', $copies_new), - ), - $button_title); - $history_table = new DiffusionHistoryTableView(); $history_table->setUser($request->getUser()); $history_table->setDiffusionRequest($drequest); $history_table->setHistory($history); $history_table->loadRevisions(); $phids = $history_table->getRequiredHandlePHIDs(); $handles = $this->loadViewerHandles($phids); $history_table->setHandles($handles); if ($show_graph) { $history_table->setParents($history_results['parents']); $history_table->setIsHead($offset == 0); } $history_panel = new AphrontPanelView(); - $history_panel->setHeader(pht('History')); - $history_panel->addButton($button); $history_panel->appendChild($history_table); $history_panel->appendChild($pager); $history_panel->setNoBackground(); $content[] = $history_panel; - // TODO: Sometimes we do have a change view, we need to look at the most - // recent history entry to figure it out. + $header = id(new PHUIHeaderView()) + ->setUser($viewer) + ->setPolicyObject($repository) + ->setHeader($this->renderPathLinks($drequest, $mode = 'history')); + + $actions = $this->buildActionView($drequest); + $properties = $this->buildPropertyView($drequest); - $nav = $this->buildSideNav('history', false); - $nav->appendChild($content); $crumbs = $this->buildCrumbs( array( 'branch' => true, 'path' => true, 'view' => 'history', )); - $nav->setCrumbs($crumbs); return $this->buildApplicationPage( - $nav, + array( + $crumbs, + $header, + $actions, + $properties, + $content, + ), array( 'device' => true, 'title' => array( pht('History'), pht('%s Repository', $drequest->getRepository()->getCallsign()), ), )); } + private function buildActionView(DiffusionRequest $drequest) { + $viewer = $this->getRequest()->getUser(); + + $view = id(new PhabricatorActionListView()) + ->setUser($viewer); + + $browse_uri = $drequest->generateURI( + array( + 'action' => 'browse', + )); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Browse Content')) + ->setHref($browse_uri) + ->setIcon('file')); + + // TODO: Sometimes we do have a change view, we need to look at the most + // recent history entry to figure it out. + + $request = $this->getRequest(); + if ($request->getBool('copies')) { + $branch_name = pht('Hide Copies/Branches'); + $branch_icon = 'fork-grey'; + $branch_uri = $request->getRequestURI() + ->alter('offset', null) + ->alter('copies', null); + } else { + $branch_name = pht('Show Copies/Branches'); + $branch_icon = 'fork'; + $branch_uri = $request->getRequestURI() + ->alter('offset', null) + ->alter('copies', true); + } + + $view->addAction( + id(new PhabricatorActionView()) + ->setName($branch_name) + ->setIcon($branch_icon) + ->setHref($branch_uri)); + + return $view; + } + + protected function buildPropertyView(DiffusionRequest $drequest) { + $viewer = $this->getRequest()->getUser(); + + $view = id(new PhabricatorPropertyListView()) + ->setUser($viewer); + + $stable_commit = $drequest->getStableCommitName(); + $callsign = $drequest->getRepository()->getCallsign(); + + $view->addProperty( + pht('Commit'), + phutil_tag( + 'a', + array( + 'href' => $drequest->generateURI( + array( + 'action' => 'commit', + 'commit' => $stable_commit, + )), + ), + $drequest->getRepository()->formatCommitName($stable_commit))); + + return $view; + } + + + }