1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-15 10:00:55 +01:00

(stable) Promote 2017 Week 39

This commit is contained in:
epriestley 2017-09-29 17:51:50 -07:00
commit ce9e30b020
13 changed files with 420 additions and 54 deletions

View file

@ -9,7 +9,7 @@ return array(
'names' => array(
'conpherence.pkg.css' => 'e68cf1fa',
'conpherence.pkg.js' => 'b5b51108',
'core.pkg.css' => 'e9473020',
'core.pkg.css' => '87a9a59b',
'core.pkg.js' => '28552e58',
'darkconsole.pkg.js' => '1f9a31bc',
'differential.pkg.css' => '45951e9e',
@ -114,7 +114,7 @@ return array(
'rsrc/css/application/slowvote/slowvote.css' => 'a94b7230',
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
'rsrc/css/application/uiexample/example.css' => '528b19de',
'rsrc/css/core/core.css' => '1760853c',
'rsrc/css/core/core.css' => '62fa3ace',
'rsrc/css/core/remarkup.css' => 'cad18339',
'rsrc/css/core/syntax.css' => 'cae95e89',
'rsrc/css/core/z-index.css' => '9d8f7c4b',
@ -137,7 +137,7 @@ return array(
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '9d9685d6',
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'bf094950',
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea',
'rsrc/css/phui/phui-action-list.css' => 'e7eba156',
'rsrc/css/phui/phui-action-list.css' => 'f7f61a34',
'rsrc/css/phui/phui-action-panel.css' => 'b4798122',
'rsrc/css/phui/phui-badge.css' => '22c0cf4f',
'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3',
@ -148,7 +148,7 @@ return array(
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
'rsrc/css/phui/phui-comment-panel.css' => 'f50152ad',
'rsrc/css/phui/phui-crumbs-view.css' => '6ece3bbb',
'rsrc/css/phui/phui-curtain-view.css' => 'ca363f15',
'rsrc/css/phui/phui-curtain-view.css' => '2bdaf026',
'rsrc/css/phui/phui-document-pro.css' => '8af7ea27',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => 'c32e8dec',
@ -177,7 +177,7 @@ return array(
'rsrc/css/phui/phui-status.css' => 'd5263e49',
'rsrc/css/phui/phui-tag-view.css' => 'b4719c50',
'rsrc/css/phui/phui-timeline-view.css' => 'f21db7ca',
'rsrc/css/phui/phui-two-column-view.css' => '1ade9c5f',
'rsrc/css/phui/phui-two-column-view.css' => '44ec4951',
'rsrc/css/phui/workboards/phui-workboard-color.css' => '783cdff5',
'rsrc/css/phui/workboards/phui-workboard.css' => '3bc85455',
'rsrc/css/phui/workboards/phui-workcard.css' => 'cca5fa92',
@ -765,11 +765,11 @@ return array(
'path-typeahead' => 'f7fc67ec',
'people-picture-menu-item-css' => 'a06f7f34',
'people-profile-css' => '4df76faf',
'phabricator-action-list-view-css' => 'e7eba156',
'phabricator-action-list-view-css' => 'f7f61a34',
'phabricator-busy' => '59a7976a',
'phabricator-chatlog-css' => 'd295b020',
'phabricator-content-source-view-css' => '4b8b05d4',
'phabricator-core-css' => '1760853c',
'phabricator-core-css' => '62fa3ace',
'phabricator-countdown-css' => '16c52f5c',
'phabricator-darklog' => 'c8e1ffe3',
'phabricator-darkmessage' => 'c48cccdd',
@ -833,7 +833,7 @@ return array(
'phui-comment-form-css' => 'ac68149f',
'phui-comment-panel-css' => 'f50152ad',
'phui-crumbs-view-css' => '6ece3bbb',
'phui-curtain-view-css' => 'ca363f15',
'phui-curtain-view-css' => '2bdaf026',
'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => 'c32e8dec',
'phui-document-view-pro-css' => '8af7ea27',
@ -872,7 +872,7 @@ return array(
'phui-tag-view-css' => 'b4719c50',
'phui-theme-css' => '9f261c6b',
'phui-timeline-view-css' => 'f21db7ca',
'phui-two-column-view-css' => '1ade9c5f',
'phui-two-column-view-css' => '44ec4951',
'phui-workboard-color-css' => '783cdff5',
'phui-workboard-view-css' => '3bc85455',
'phui-workcard-view-css' => 'cca5fa92',

View file

@ -2,6 +2,10 @@
abstract class DifferentialController extends PhabricatorController {
private $packageChangesetMap;
private $pathPackageMap;
private $authorityPackages;
public function buildSideNavView($for_app = false) {
$viewer = $this->getRequest()->getUser();
@ -21,6 +25,88 @@ abstract class DifferentialController extends PhabricatorController {
return $this->buildSideNavView(true)->getMenu();
}
protected function buildPackageMaps(array $changesets) {
assert_instances_of($changesets, 'DifferentialChangeset');
$this->packageChangesetMap = array();
$this->pathPackageMap = array();
$this->authorityPackages = array();
if (!$changesets) {
return;
}
$viewer = $this->getViewer();
$have_owners = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorOwnersApplication',
$viewer);
if (!$have_owners) {
return;
}
$changeset = head($changesets);
$diff = $changeset->getDiff();
$repository_phid = $diff->getRepositoryPHID();
if (!$repository_phid) {
return;
}
if ($viewer->getPHID()) {
$packages = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))
->withAuthorityPHIDs(array($viewer->getPHID()))
->execute();
$this->authorityPackages = $packages;
}
$paths = mpull($changesets, 'getOwnersFilename');
$control_query = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))
->withControl($repository_phid, $paths);
$control_query->execute();
foreach ($changesets as $changeset) {
$changeset_path = $changeset->getOwnersFilename();
$packages = $control_query->getControllingPackagesForPath(
$repository_phid,
$changeset_path);
$this->pathPackageMap[$changeset_path] = $packages;
foreach ($packages as $package) {
$this->packageChangesetMap[$package->getPHID()][] = $changeset;
}
}
}
protected function getAuthorityPackages() {
if ($this->authorityPackages === null) {
throw new PhutilInvalidStateException('buildPackageMaps');
}
return $this->authorityPackages;
}
protected function getChangesetPackages(DifferentialChangeset $changeset) {
if ($this->pathPackageMap === null) {
throw new PhutilInvalidStateException('buildPackageMaps');
}
$path = $changeset->getOwnersFilename();
return idx($this->pathPackageMap, $path, array());
}
protected function getPackageChangesets($package_phid) {
if ($this->packageChangesetMap === null) {
throw new PhutilInvalidStateException('buildPackageMaps');
}
return idx($this->packageChangesetMap, $package_phid, array());
}
protected function buildTableOfContents(
array $changesets,
array $visible_changesets,
@ -29,40 +115,8 @@ abstract class DifferentialController extends PhabricatorController {
$toc_view = id(new PHUIDiffTableOfContentsListView())
->setViewer($viewer)
->setBare(true);
$have_owners = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorOwnersApplication',
$viewer);
if ($have_owners) {
$repository_phid = null;
if ($changesets) {
$changeset = head($changesets);
$diff = $changeset->getDiff();
$repository_phid = $diff->getRepositoryPHID();
}
if (!$repository_phid) {
$have_owners = false;
} else {
if ($viewer->getPHID()) {
$packages = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))
->withAuthorityPHIDs(array($viewer->getPHID()))
->execute();
$toc_view->setAuthorityPackages($packages);
}
$paths = mpull($changesets, 'getOwnersFilename');
$control_query = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withStatuses(array(PhabricatorOwnersPackage::STATUS_ACTIVE))
->withControl($repository_phid, $paths);
$control_query->execute();
}
}
->setBare(true)
->setAuthorityPackages($this->getAuthorityPackages());
foreach ($changesets as $changeset_id => $changeset) {
$is_visible = isset($visible_changesets[$changeset_id]);
@ -78,12 +132,8 @@ abstract class DifferentialController extends PhabricatorController {
->setCoverage(idx($coverage, $filename))
->setCoverageID($coverage_id);
if ($have_owners) {
$packages = $control_query->getControllingPackagesForPath(
$repository_phid,
$changeset->getOwnersFilename());
$item->setPackages($packages);
}
$packages = $this->getChangesetPackages($changeset);
$item->setPackages($packages);
$toc_view->addItem($item);
}

View file

@ -118,6 +118,8 @@ final class DifferentialDiffViewController extends DifferentialController {
$changesets = $diff->loadChangesets();
$changesets = msort($changesets, 'getSortKey');
$this->buildPackageMaps($changesets);
$table_of_contents = $this->buildTableOfContents(
$changesets,
$changesets,

View file

@ -326,11 +326,21 @@ final class DifferentialRevisionViewController extends DifferentialController {
$other_view = $this->renderOtherRevisions($other_revisions);
}
$this->buildPackageMaps($changesets);
$toc_view = $this->buildTableOfContents(
$changesets,
$visible_changesets,
$target->loadCoverageMap($viewer));
// Attach changesets to each reviewer so we can show which Owners package
// reviewers own no files.
foreach ($revision->getReviewers() as $reviewer) {
$reviewer_phid = $reviewer->getReviewerPHID();
$reviewer_changesets = $this->getPackageChangesets($reviewer_phid);
$reviewer->attachChangesets($reviewer_changesets);
}
$tab_group = id(new PHUITabGroupView())
->addTab(
id(new PHUITabView())

View file

@ -12,6 +12,7 @@ final class DifferentialReviewer
protected $voidedPHID;
private $authority = array();
private $changesets = self::ATTACHABLE;
protected function getConfiguration() {
return array(
@ -54,6 +55,15 @@ final class DifferentialReviewer
return $this->assertAttachedKey($this->authority, $cache_fragment);
}
public function attachChangesets(array $changesets) {
$this->changesets = $changesets;
return $this;
}
public function getChangesets() {
return $this->assertAttached($this->changesets);
}
public function isResigned() {
$status_resigned = DifferentialReviewerStatus::STATUS_RESIGNED;
return ($this->getReviewerStatus() == $status_resigned);

View file

@ -150,6 +150,12 @@ final class DifferentialReviewersView extends AphrontView {
$item->setIcon($icon, $color, $label);
$item->setTarget($handle->renderHovercardLink());
if ($reviewer->isPackage()) {
if (!$reviewer->getChangesets()) {
$item->setNote(pht('(Owns No Changed Paths)'));
}
}
$view->addItem($item);
}

View file

@ -1557,7 +1557,8 @@ final class DiffusionBrowseController extends DiffusionController {
$commit_tag = $this->renderCommitHashTag($drequest);
$path = nonempty(basename($drequest->getPath()), '/');
$path = nonempty($drequest->getPath(), '/');
$search = $this->renderSearchForm($path);
$header = id(new PHUIHeaderView())

View file

@ -34,7 +34,9 @@ final class PhabricatorProjectBoardViewController
->setBaseURI($board_uri)
->setIsBoardView(true);
if ($request->isFormPost() && !$request->getBool('initialize')) {
if ($request->isFormPost()
&& !$request->getBool('initialize')
&& !$request->getStr('move')) {
$saved = $search_engine->buildSavedQueryFromRequest($request);
$search_engine->saveQuery($saved);
$filter_form = id(new AphrontFormView())
@ -238,6 +240,199 @@ final class PhabricatorProjectBoardViewController
->setURI($batch_uri);
}
$move_id = $request->getStr('move');
if (strlen($move_id)) {
$column_id_map = mpull($columns, null, 'getID');
$move_column = idx($column_id_map, $move_id);
if (!$move_column) {
return new Aphront404Response();
}
$move_task_phids = $layout_engine->getColumnObjectPHIDs(
$board_phid,
$move_column->getPHID());
foreach ($move_task_phids as $key => $move_task_phid) {
if (empty($task_can_edit_map[$move_task_phid])) {
unset($move_task_phids[$key]);
}
}
$move_tasks = array_select_keys($tasks, $move_task_phids);
$cancel_uri = $this->getURIWithState($board_uri);
if (!$move_tasks) {
return $this->newDialog()
->setTitle(pht('No Movable Tasks'))
->appendParagraph(
pht(
'The selected column contains no visible tasks which you '.
'have permission to move.'))
->addCancelButton($cancel_uri);
}
$move_project_phid = $project->getPHID();
$move_column_phid = null;
$move_project = null;
$move_column = null;
$columns = null;
$errors = array();
if ($request->isFormPost()) {
$move_project_phid = head($request->getArr('moveProjectPHID'));
if (!$move_project_phid) {
$move_project_phid = $request->getStr('moveProjectPHID');
}
if (!$move_project_phid) {
if ($request->getBool('hasProject')) {
$errors[] = pht('Choose a project to move tasks to.');
}
} else {
$target_project = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withPHIDs(array($move_project_phid))
->executeOne();
if (!$target_project) {
$errors[] = pht('You must choose a valid project.');
} else if (!$project->getHasWorkboard()) {
$errors[] = pht(
'You must choose a project with a workboard.');
} else {
$move_project = $target_project;
}
}
if ($move_project) {
$move_engine = id(new PhabricatorBoardLayoutEngine())
->setViewer($viewer)
->setBoardPHIDs(array($move_project->getPHID()))
->setFetchAllBoards(true)
->executeLayout();
$columns = $move_engine->getColumns($move_project->getPHID());
$columns = mpull($columns, null, 'getPHID');
$move_column_phid = $request->getStr('moveColumnPHID');
if (!$move_column_phid) {
if ($request->getBool('hasColumn')) {
$errors[] = pht('Choose a column to move tasks to.');
}
} else {
if (empty($columns[$move_column_phid])) {
$errors[] = pht(
'Choose a valid column on the target workboard to move '.
'tasks to.');
} else if ($columns[$move_column_phid]->getID() == $move_id) {
$errors[] = pht(
'You can not move tasks from a column to itself.');
} else {
$move_column = $columns[$move_column_phid];
}
}
}
}
if ($move_column && $move_project) {
foreach ($move_tasks as $move_task) {
$xactions = array();
// If we're switching projects, get out of the old project first
// and move to the new project.
if ($move_project->getID() != $project->getID()) {
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue(
'edge:type',
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST)
->setNewValue(
array(
'-' => array(
$project->getPHID() => $project->getPHID(),
),
'+' => array(
$move_project->getPHID() => $move_project->getPHID(),
),
));
}
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_COLUMNS)
->setNewValue(
array(
array(
'columnPHID' => $move_column->getPHID(),
),
));
$editor = id(new ManiphestTransactionEditor())
->setActor($viewer)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request);
$editor->applyTransactions($move_task, $xactions);
}
return id(new AphrontRedirectResponse())
->setURI($cancel_uri);
}
if ($move_project) {
$column_form = id(new AphrontFormView())
->setViewer($viewer)
->appendControl(
id(new AphrontFormSelectControl())
->setName('moveColumnPHID')
->setLabel(pht('Move to Column'))
->setValue($move_column_phid)
->setOptions(mpull($columns, 'getDisplayName', 'getPHID')));
return $this->newDialog()
->setTitle(pht('Move Tasks'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->setErrors($errors)
->addHiddenInput('move', $move_id)
->addHiddenInput('moveProjectPHID', $move_project->getPHID())
->addHiddenInput('hasColumn', true)
->addHiddenInput('hasProject', true)
->appendParagraph(
pht(
'Choose a column on the %s workboard to move tasks to:',
$viewer->renderHandle($move_project->getPHID())))
->appendForm($column_form)
->addSubmitButton(pht('Move Tasks'))
->addCancelButton($cancel_uri);
}
if ($move_project_phid) {
$move_project_phid_value = array($move_project_phid);
} else {
$move_project_phid_value = array();
}
$project_form = id(new AphrontFormView())
->setViewer($viewer)
->appendControl(
id(new AphrontFormTokenizerControl())
->setName('moveProjectPHID')
->setLimit(1)
->setLabel(pht('Move to Project'))
->setValue($move_project_phid_value)
->setDatasource(new PhabricatorProjectDatasource()));
return $this->newDialog()
->setTitle(pht('Move Tasks'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->setErrors($errors)
->addHiddenInput('move', $move_id)
->addHiddenInput('hasProject', true)
->appendForm($project_form)
->addSubmitButton(pht('Continue'))
->addCancelButton($cancel_uri);
}
$board_id = celerity_generate_unique_node_id();
$board = id(new PHUIWorkboardView())
@ -851,6 +1046,14 @@ final class PhabricatorProjectBoardViewController
->setHref($batch_edit_uri)
->setDisabled(!$can_batch_edit);
$batch_move_uri = $request->getRequestURI();
$batch_move_uri->setQueryParam('move', $column->getID());
$column_items[] = id(new PhabricatorActionView())
->setIcon('fa-arrow-right')
->setName(pht('Move Tasks to Column...'))
->setHref($batch_move_uri)
->setWorkflow(true);
// Column Related Actions Below
//
$edit_uri = 'board/'.$this->id.'/edit/'.$column->getID().'/';

View file

@ -50,17 +50,35 @@ final class PhabricatorJumpNavHandler extends Phobject {
return id(new AphrontRedirectResponse())
->setURI("/diffusion/symbol/$symbol/?jump=true$context");
case 'find-repository':
$name = $matches[1];
$raw_query = $matches[1];
$engine = id(new PhabricatorRepository())
->newFerretEngine();
$compiler = id(new PhutilSearchQueryCompiler())
->setEnableFunctions(true);
$raw_tokens = $compiler->newTokens($raw_query);
$fulltext_tokens = array();
foreach ($raw_tokens as $raw_token) {
$fulltext_token = id(new PhabricatorFulltextToken())
->setToken($raw_token);
$fulltext_tokens[] = $fulltext_token;
}
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($viewer)
->withNameContains($name)
->withFerretConstraint($engine, $fulltext_tokens)
->execute();
if (count($repositories) == 1) {
// Just one match, jump to repository.
$uri = head($repositories)->getURI();
} else {
// More than one match, jump to search.
$uri = urisprintf('/diffusion/?order=name&name=%s', $name);
$uri = urisprintf(
'/diffusion/?order=name&query=%s',
$raw_query);
}
return id(new AphrontRedirectResponse())->setURI($uri);
default:

View file

@ -61,6 +61,11 @@ body {
overflow-y: scroll;
}
body.printable,
!print body {
background: none;
}
textarea {
font: inherit;
}

View file

@ -7,6 +7,11 @@
display: none;
}
!print .phabricator-action-list-view {
padding: 4px 0;
display: none;
}
.device .phuix-dropdown-menu .phabricator-action-list-view {
/* When an action list view appears inside a dropdown menu, don't hide it
by default. */

View file

@ -21,6 +21,26 @@
border-top: 1px solid {$greybackground};
}
!print .phui-curtain-panel + .phui-curtain-panel {
padding: 8px 0;
border-top: none;
}
!print .device-desktop .phabricator-action-list-view + .phui-curtain-panel {
padding: 8px 0;
border-top: none;
}
!print .device-desktop .phui-curtain-panel + .phui-curtain-panel {
padding: 8px 0;
border-top: none;
}
!print .phabricator-action-list-view + .phui-curtain-panel {
padding: 8px 0;
border-top: none;
}
.phui-curtain-panel-header {
padding: 0 0 4px;
color: {$bluetext};
@ -37,6 +57,10 @@
padding: 0;
}
!print .phui-curtain-panel-body {
padding: 0;
}
/* Project tags */
.phui-curtain-panel-body .phabricator-handle-tag-list-item {
@ -50,3 +74,7 @@
.device .curtain-no-panels {
display: none;
}
!print .curtain-no-panels {
display: none;
}

View file

@ -79,6 +79,30 @@
width: 300px;
}
!print .phui-two-column-view .phui-main-column {
float: unset;
width: unset;
margin-bottom: 20px;
}
!print .phui-two-column-view .phui-side-column {
float: unset;
width: unset;
margin-bottom: 20px;
}
!print .device-desktop .phui-two-column-view .phui-main-column {
float: unset;
width: unset;
margin-bottom: 20px;
}
!print .device-desktop .phui-two-column-view .phui-side-column {
float: unset;
width: unset;
margin-bottom: 20px;
}
.device-desktop .phui-two-column-view.phui-side-column-left .phui-main-column {
float: right;
width: calc(100% - 280px);
@ -307,3 +331,7 @@
.phui-mobile-menu {
display: block;
}
!print .phabricator-side-menu {
display: none !important;
}