mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-18 10:41:08 +01:00
Nearly complete lifting card-move code out of workboards
Summary: Ref T10010. This gets rid of the last dependency on the weird ColumnPositionQuery code. Test Plan: - Viewed workboards. - Used batch editor. - Created a new workboard. - Dragged stuff around. - Created new tasks into columns. - Changed order from natural to priority, dragged things around. - Switched filter to custom filter, "all tasks", etc. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10010 Differential Revision: https://secure.phabricator.com/D15176
This commit is contained in:
parent
a9e98e42f5
commit
e25a40236f
2 changed files with 125 additions and 148 deletions
|
@ -28,10 +28,93 @@ final class PhabricatorProjectBoardViewController
|
|||
$project = $this->getProject();
|
||||
|
||||
$this->readRequestState();
|
||||
$columns = $this->loadColumns($project);
|
||||
|
||||
// TODO: Expand the checks here if we add the ability
|
||||
// to hide the Backlog column
|
||||
$board_uri = $this->getApplicationURI('board/'.$project->getID().'/');
|
||||
|
||||
$search_engine = id(new ManiphestTaskSearchEngine())
|
||||
->setViewer($viewer)
|
||||
->setBaseURI($board_uri)
|
||||
->setIsBoardView(true);
|
||||
|
||||
if ($request->isFormPost() && !$request->getBool('initialize')) {
|
||||
$saved = $search_engine->buildSavedQueryFromRequest($request);
|
||||
$search_engine->saveQuery($saved);
|
||||
$filter_form = id(new AphrontFormView())
|
||||
->setUser($viewer);
|
||||
$search_engine->buildSearchForm($filter_form, $saved);
|
||||
if ($search_engine->getErrors()) {
|
||||
return $this->newDialog()
|
||||
->setWidth(AphrontDialogView::WIDTH_FULL)
|
||||
->setTitle(pht('Advanced Filter'))
|
||||
->appendChild($filter_form->buildLayoutView())
|
||||
->setErrors($search_engine->getErrors())
|
||||
->setSubmitURI($board_uri)
|
||||
->addSubmitButton(pht('Apply Filter'))
|
||||
->addCancelButton($board_uri);
|
||||
}
|
||||
return id(new AphrontRedirectResponse())->setURI(
|
||||
$this->getURIWithState(
|
||||
$search_engine->getQueryResultsPageURI($saved->getQueryKey())));
|
||||
}
|
||||
|
||||
$query_key = $request->getURIData('queryKey');
|
||||
if (!$query_key) {
|
||||
$query_key = 'open';
|
||||
}
|
||||
$this->queryKey = $query_key;
|
||||
|
||||
$custom_query = null;
|
||||
if ($search_engine->isBuiltinQuery($query_key)) {
|
||||
$saved = $search_engine->buildSavedQueryFromBuiltin($query_key);
|
||||
} else {
|
||||
$saved = id(new PhabricatorSavedQueryQuery())
|
||||
->setViewer($viewer)
|
||||
->withQueryKeys(array($query_key))
|
||||
->executeOne();
|
||||
|
||||
if (!$saved) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$custom_query = $saved;
|
||||
}
|
||||
|
||||
if ($request->getURIData('filter')) {
|
||||
$filter_form = id(new AphrontFormView())
|
||||
->setUser($viewer);
|
||||
$search_engine->buildSearchForm($filter_form, $saved);
|
||||
|
||||
return $this->newDialog()
|
||||
->setWidth(AphrontDialogView::WIDTH_FULL)
|
||||
->setTitle(pht('Advanced Filter'))
|
||||
->appendChild($filter_form->buildLayoutView())
|
||||
->setSubmitURI($board_uri)
|
||||
->addSubmitButton(pht('Apply Filter'))
|
||||
->addCancelButton($board_uri);
|
||||
}
|
||||
|
||||
$task_query = $search_engine->buildQueryFromSavedQuery($saved);
|
||||
|
||||
$tasks = $task_query
|
||||
->withEdgeLogicPHIDs(
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
|
||||
PhabricatorQueryConstraint::OPERATOR_AND,
|
||||
array($project->getPHID()))
|
||||
->setOrder(ManiphestTaskQuery::ORDER_PRIORITY)
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
$tasks = mpull($tasks, null, 'getPHID');
|
||||
|
||||
|
||||
$board_phid = $project->getPHID();
|
||||
|
||||
$layout_engine = id(new PhabricatorBoardLayoutEngine())
|
||||
->setViewer($viewer)
|
||||
->setBoardPHIDs(array($board_phid))
|
||||
->setObjectPHIDs(array_keys($tasks))
|
||||
->executeLayout();
|
||||
|
||||
$columns = $layout_engine->getColumns($board_phid);
|
||||
if (!$columns) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
|
@ -64,124 +147,6 @@ final class PhabricatorProjectBoardViewController
|
|||
->appendChild($content);
|
||||
}
|
||||
|
||||
$board_uri = $this->getApplicationURI('board/'.$project->getID().'/');
|
||||
|
||||
$engine = id(new ManiphestTaskSearchEngine())
|
||||
->setViewer($viewer)
|
||||
->setBaseURI($board_uri)
|
||||
->setIsBoardView(true);
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$saved = $engine->buildSavedQueryFromRequest($request);
|
||||
$engine->saveQuery($saved);
|
||||
$filter_form = id(new AphrontFormView())
|
||||
->setUser($viewer);
|
||||
$engine->buildSearchForm($filter_form, $saved);
|
||||
if ($engine->getErrors()) {
|
||||
return $this->newDialog()
|
||||
->setWidth(AphrontDialogView::WIDTH_FULL)
|
||||
->setTitle(pht('Advanced Filter'))
|
||||
->appendChild($filter_form->buildLayoutView())
|
||||
->setErrors($engine->getErrors())
|
||||
->setSubmitURI($board_uri)
|
||||
->addSubmitButton(pht('Apply Filter'))
|
||||
->addCancelButton($board_uri);
|
||||
}
|
||||
return id(new AphrontRedirectResponse())->setURI(
|
||||
$this->getURIWithState(
|
||||
$engine->getQueryResultsPageURI($saved->getQueryKey())));
|
||||
}
|
||||
|
||||
$query_key = $request->getURIData('queryKey');
|
||||
if (!$query_key) {
|
||||
$query_key = 'open';
|
||||
}
|
||||
$this->queryKey = $query_key;
|
||||
|
||||
$custom_query = null;
|
||||
if ($engine->isBuiltinQuery($query_key)) {
|
||||
$saved = $engine->buildSavedQueryFromBuiltin($query_key);
|
||||
} else {
|
||||
$saved = id(new PhabricatorSavedQueryQuery())
|
||||
->setViewer($viewer)
|
||||
->withQueryKeys(array($query_key))
|
||||
->executeOne();
|
||||
|
||||
if (!$saved) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$custom_query = $saved;
|
||||
}
|
||||
|
||||
if ($request->getURIData('filter')) {
|
||||
$filter_form = id(new AphrontFormView())
|
||||
->setUser($viewer);
|
||||
$engine->buildSearchForm($filter_form, $saved);
|
||||
|
||||
return $this->newDialog()
|
||||
->setWidth(AphrontDialogView::WIDTH_FULL)
|
||||
->setTitle(pht('Advanced Filter'))
|
||||
->appendChild($filter_form->buildLayoutView())
|
||||
->setSubmitURI($board_uri)
|
||||
->addSubmitButton(pht('Apply Filter'))
|
||||
->addCancelButton($board_uri);
|
||||
}
|
||||
|
||||
$task_query = $engine->buildQueryFromSavedQuery($saved);
|
||||
|
||||
$tasks = $task_query
|
||||
->withEdgeLogicPHIDs(
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
|
||||
PhabricatorQueryConstraint::OPERATOR_AND,
|
||||
array($project->getPHID()))
|
||||
->setOrder(ManiphestTaskQuery::ORDER_PRIORITY)
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
$tasks = mpull($tasks, null, 'getPHID');
|
||||
|
||||
if ($tasks) {
|
||||
$positions = id(new PhabricatorProjectColumnPositionQuery())
|
||||
->setViewer($viewer)
|
||||
->withObjectPHIDs(mpull($tasks, 'getPHID'))
|
||||
->withColumns($columns)
|
||||
->execute();
|
||||
$positions = mpull($positions, null, 'getObjectPHID');
|
||||
} else {
|
||||
$positions = array();
|
||||
}
|
||||
|
||||
$task_map = array();
|
||||
foreach ($tasks as $task) {
|
||||
$task_phid = $task->getPHID();
|
||||
if (empty($positions[$task_phid])) {
|
||||
// This shouldn't normally be possible because we create positions on
|
||||
// demand, but we might have raced as an object was removed from the
|
||||
// board. Just drop the task if we don't have a position for it.
|
||||
continue;
|
||||
}
|
||||
|
||||
$position = $positions[$task_phid];
|
||||
$task_map[$position->getColumnPHID()][] = $task_phid;
|
||||
}
|
||||
|
||||
// If we're showing the board in "natural" order, sort columns by their
|
||||
// column positions.
|
||||
if ($this->sortKey == PhabricatorProjectColumn::ORDER_NATURAL) {
|
||||
foreach ($task_map as $column_phid => $task_phids) {
|
||||
$order = array();
|
||||
foreach ($task_phids as $task_phid) {
|
||||
if (isset($positions[$task_phid])) {
|
||||
$order[$task_phid] = $positions[$task_phid]->getOrderingKey();
|
||||
} else {
|
||||
$order[$task_phid] = 0;
|
||||
}
|
||||
}
|
||||
asort($order);
|
||||
$task_map[$column_phid] = array_keys($order);
|
||||
}
|
||||
}
|
||||
|
||||
$task_can_edit_map = id(new PhabricatorPolicyFilter())
|
||||
->setViewer($viewer)
|
||||
->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT))
|
||||
|
@ -198,7 +163,10 @@ final class PhabricatorProjectBoardViewController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$batch_task_phids = idx($task_map, $batch_column->getPHID(), array());
|
||||
$batch_task_phids = $layout_engine->getColumnObjectPHIDs(
|
||||
$board_phid,
|
||||
$batch_column->getPHID());
|
||||
|
||||
foreach ($batch_task_phids as $key => $batch_task_phid) {
|
||||
if (empty($task_can_edit_map[$batch_task_phid])) {
|
||||
unset($batch_task_phids[$key]);
|
||||
|
@ -251,9 +219,24 @@ final class PhabricatorProjectBoardViewController
|
|||
$this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
|
||||
|
||||
foreach ($columns as $column) {
|
||||
$task_phids = idx($task_map, $column->getPHID(), array());
|
||||
if (!$this->showHidden) {
|
||||
if ($column->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$task_phids = $layout_engine->getColumnObjectPHIDs(
|
||||
$board_phid,
|
||||
$column->getPHID());
|
||||
|
||||
$column_tasks = array_select_keys($tasks, $task_phids);
|
||||
|
||||
// If we aren't using "natural" order, reorder the column by the original
|
||||
// query order.
|
||||
if ($this->sortKey != PhabricatorProjectColumn::ORDER_NATURAL) {
|
||||
$column_tasks = array_select_keys($column_tasks, array_keys($tasks));
|
||||
}
|
||||
|
||||
$panel = id(new PHUIWorkpanelView())
|
||||
->setHeader($column->getDisplayName())
|
||||
->setSubHeader($column->getDisplayType())
|
||||
|
@ -322,7 +305,7 @@ final class PhabricatorProjectBoardViewController
|
|||
$filter_menu = $this->buildFilterMenu(
|
||||
$viewer,
|
||||
$custom_query,
|
||||
$engine,
|
||||
$search_engine,
|
||||
$query_key);
|
||||
|
||||
$manage_menu = $this->buildManageMenu($project, $this->showHidden);
|
||||
|
@ -383,25 +366,6 @@ final class PhabricatorProjectBoardViewController
|
|||
$this->sortKey = $sort_key;
|
||||
}
|
||||
|
||||
private function loadColumns(PhabricatorProject $project) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$column_query = id(new PhabricatorProjectColumnQuery())
|
||||
->setViewer($viewer)
|
||||
->withProjectPHIDs(array($project->getPHID()));
|
||||
|
||||
if (!$this->showHidden) {
|
||||
$column_query->withStatuses(
|
||||
array(PhabricatorProjectColumn::STATUS_ACTIVE));
|
||||
}
|
||||
|
||||
$columns = $column_query->execute();
|
||||
$columns = mpull($columns, null, 'getSequence');
|
||||
ksort($columns);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
private function buildSortMenu(
|
||||
PhabricatorUser $viewer,
|
||||
$sort_key) {
|
||||
|
@ -797,6 +761,7 @@ final class PhabricatorProjectBoardViewController
|
|||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('initialize', 1)
|
||||
->appendRemarkupInstructions(
|
||||
pht('The workboard for this project has not been created yet.'))
|
||||
->appendControl($new_selector)
|
||||
|
|
|
@ -6,7 +6,7 @@ final class PhabricatorBoardLayoutEngine extends Phobject {
|
|||
private $boardPHIDs;
|
||||
private $objectPHIDs;
|
||||
private $boards;
|
||||
private $columnMap;
|
||||
private $columnMap = array();
|
||||
private $objectColumnMap = array();
|
||||
private $boardLayout = array();
|
||||
|
||||
|
@ -68,6 +68,17 @@ final class PhabricatorBoardLayoutEngine extends Phobject {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getColumns($board_phid) {
|
||||
$columns = idx($this->boardLayout, $board_phid, array());
|
||||
return array_select_keys($this->columnMap, array_keys($columns));
|
||||
}
|
||||
|
||||
public function getColumnObjectPHIDs($board_phid, $column_phid) {
|
||||
$columns = idx($this->boardLayout, $board_phid, array());
|
||||
$positions = idx($columns, $column_phid, array());
|
||||
return mpull($positions, 'getObjectPHID');
|
||||
}
|
||||
|
||||
public function getObjectColumns($board_phid, $object_phid) {
|
||||
$board_map = idx($this->objectColumnMap, $board_phid, array());
|
||||
|
||||
|
@ -342,14 +353,15 @@ final class PhabricatorBoardLayoutEngine extends Phobject {
|
|||
$board_phid = $board->getPHID();
|
||||
$position_groups = mgroup($positions, 'getObjectPHID');
|
||||
|
||||
foreach ($columns as $column) {
|
||||
if ($column->isDefaultColumn()) {
|
||||
$default_phid = $column->getPHID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$layout = array();
|
||||
foreach ($columns as $column) {
|
||||
$column_phid = $column->getPHID();
|
||||
$layout[$column_phid] = array();
|
||||
|
||||
if ($column->isDefaultColumn()) {
|
||||
$default_phid = $column_phid;
|
||||
}
|
||||
}
|
||||
|
||||
$object_phids = $this->getObjectPHIDs();
|
||||
foreach ($object_phids as $object_phid) {
|
||||
|
|
Loading…
Reference in a new issue