Skip to content
Snippets Groups Projects
Commit a0dc664b authored by Christopher Johnson's avatar Christopher Johnson
Browse files

updates to c01f23adfb82295588e3a9536f5281f32eef2b6e 04.02.2016

Bug: T125775

Change-Id: Ic632cad2b631fdc6b1b586a21f60698bcab7dbb3
parent 062482bf
No related branches found
No related tags found
No related merge requests found
...@@ -210,7 +210,7 @@ JX.behavior('sprint-boards', function(config, statics) { ...@@ -210,7 +210,7 @@ JX.behavior('sprint-boards', function(config, statics) {
JX.DOM.setContent(column, items); JX.DOM.setContent(column, items);
onupdate(column); onupdate(column);
} };
function update_statics(update_config) { function update_statics(update_config) {
statics.boardID = update_config.boardID; statics.boardID = update_config.boardID;
...@@ -276,13 +276,16 @@ JX.behavior('sprint-boards', function(config, statics) { ...@@ -276,13 +276,16 @@ JX.behavior('sprint-boards', function(config, statics) {
// close the dropdown, but don't want to follow the link. // close the dropdown, but don't want to follow the link.
e.prevent(); e.prevent();
var column_phid = e.getNodeData('column-add-task').columnPHID; var column_data = e.getNodeData('column-add-task');
var column_phid = column_data.columnPHID;
var request_data = { var request_data = {
responseType: 'card', responseType: 'card',
columnPHID: column_phid, columnPHID: column_phid,
projects: statics.projectPHID, projects: column_data.projectPHID,
order: statics.order order: statics.order
}; };
var cols = getcolumns(); var cols = getcolumns();
var ii; var ii;
var column; var column;
...@@ -349,7 +352,8 @@ JX.behavior('sprint-boards', function(config, statics) { ...@@ -349,7 +352,8 @@ JX.behavior('sprint-boards', function(config, statics) {
var current_page_id = JX.Quicksand.getCurrentPageID(); var current_page_id = JX.Quicksand.getCurrentPageID();
statics.boardConfigCache = {}; statics.boardConfigCache = {};
statics.boardConfigCache[current_page_id] = config; statics.boardConfigCache[current_page_id] = config;
statics.setup = init_board(); init_board();
statics.setup = setup();
} }
}); });
...@@ -23,6 +23,8 @@ final class SprintBoardColumnDetailController ...@@ -23,6 +23,8 @@ final class SprintBoardColumnDetailController
} }
$this->setProject($project); $this->setProject($project);
$project_id = $project->getID();
$column = id(new PhabricatorProjectColumnQuery()) $column = id(new PhabricatorProjectColumnQuery())
->setViewer($viewer) ->setViewer($viewer)
->withIDs(array($id)) ->withIDs(array($id))
...@@ -46,6 +48,10 @@ final class SprintBoardColumnDetailController ...@@ -46,6 +48,10 @@ final class SprintBoardColumnDetailController
$actions = $this->buildActionView($column); $actions = $this->buildActionView($column);
$properties = $this->buildPropertyView($column, $actions); $properties = $this->buildPropertyView($column, $actions);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Workboard'), "/project/board/{$project_id}/");
$crumbs->addTextCrumb(pht('Column: %s', $title));
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
->addPropertyList($properties); ->addPropertyList($properties);
...@@ -55,6 +61,7 @@ final class SprintBoardColumnDetailController ...@@ -55,6 +61,7 @@ final class SprintBoardColumnDetailController
return $this->newPage() return $this->newPage()
->setTitle($title) ->setTitle($title)
->setNavigation($nav) ->setNavigation($nav)
->setCrumbs($crumbs)
->appendChild( ->appendChild(
array( array(
$box, $box,
......
...@@ -81,10 +81,12 @@ final class SprintBoardColumnEditController ...@@ -81,10 +81,12 @@ final class SprintBoardColumnEditController
$xactions = array(); $xactions = array();
if (!$column->getProxy()) {
$type_name = PhabricatorProjectColumnTransaction::TYPE_NAME; $type_name = PhabricatorProjectColumnTransaction::TYPE_NAME;
$xactions[] = id(new PhabricatorProjectColumnTransaction()) $xactions[] = id(new PhabricatorProjectColumnTransaction())
->setTransactionType($type_name) ->setTransactionType($type_name)
->setNewValue($v_name); ->setNewValue($v_name);
}
$type_limit = PhabricatorProjectColumnTransaction::TYPE_LIMIT; $type_limit = PhabricatorProjectColumnTransaction::TYPE_LIMIT;
$xactions[] = id(new PhabricatorProjectColumnTransaction()) $xactions[] = id(new PhabricatorProjectColumnTransaction())
...@@ -105,18 +107,19 @@ final class SprintBoardColumnEditController ...@@ -105,18 +107,19 @@ final class SprintBoardColumnEditController
} }
} }
$form = new AphrontFormView(); $form = id(new AphrontFormView())
$form ->setUser($request->getUser());
->setUser($request->getUser())
->appendChild( if (!$column->getProxy()) {
$form->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setValue($v_name) ->setValue($v_name)
->setLabel(pht('Name')) ->setLabel(pht('Name'))
->setName('name') ->setName('name')
->setError($e_name) ->setError($e_name));
->setCaption( }
pht('This will be displayed as the header of the column.')))
->appendChild( $form->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setValue($v_limit) ->setValue($v_limit)
->setLabel(pht('Point Limit')) ->setLabel(pht('Point Limit'))
......
...@@ -26,6 +26,7 @@ final class SprintBoardMoveController ...@@ -26,6 +26,7 @@ final class SprintBoardMoveController
return new Aphront404Response(); return new Aphront404Response();
} }
$is_sprint = $this->isSprint($project); $is_sprint = $this->isSprint($project);
$board_phid = $project->getPHID();
$object = id(new ManiphestTaskQuery()) $object = id(new ManiphestTaskQuery())
->setViewer($viewer) ->setViewer($viewer)
...@@ -55,11 +56,14 @@ final class SprintBoardMoveController ...@@ -55,11 +56,14 @@ final class SprintBoardMoveController
return new Aphront404Response(); return new Aphront404Response();
} }
$positions = id(new PhabricatorProjectColumnPositionQuery()) $engine = id(new PhabricatorBoardLayoutEngine())
->setViewer($viewer) ->setViewer($viewer)
->withColumns($columns) ->setBoardPHIDs(array($board_phid))
->withObjectPHIDs(array($object_phid)) ->setObjectPHIDs(array($object_phid))
->execute(); ->executeLayout();
$columns = $engine->getObjectColumns($board_phid, $object_phid);
$old_column_phids = mpull($columns, 'getPHID');
$xactions = array(); $xactions = array();
...@@ -81,7 +85,7 @@ final class SprintBoardMoveController ...@@ -81,7 +85,7 @@ final class SprintBoardMoveController
) + $order_params) ) + $order_params)
->setOldValue( ->setOldValue(
array( array(
'columnPHIDs' => mpull($positions, 'getColumnPHID'), 'columnPHIDs' => $old_column_phids,
'projectPHID' => $column->getProjectPHID(), 'projectPHID' => $column->getProjectPHID(),
)); ));
...@@ -137,6 +141,32 @@ final class SprintBoardMoveController ...@@ -137,6 +141,32 @@ final class SprintBoardMoveController
} }
} }
$proxy = $column->getProxy();
if ($proxy) {
// We're moving the task into a subproject or milestone column, so add
// the subproject or milestone.
$add_projects = array($proxy->getPHID());
} else if ($project->getHasSubprojects() || $project->getHasMilestones()) {
// We're moving the task into the "Backlog" column on the parent project,
// so add the parent explicitly. This gets rid of any subproject or
// milestone tags.
$add_projects = array($project->getPHID());
} else {
$add_projects = array();
}
if ($add_projects) {
$project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue('edge:type', $project_type)
->setNewValue(
array(
'+' => array_fuse($add_projects),
));
}
$editor = id(new ManiphestTransactionEditor()) $editor = id(new ManiphestTransactionEditor())
->setActor($viewer) ->setActor($viewer)
->setContinueOnMissingFields(true) ->setContinueOnMissingFields(true)
...@@ -152,9 +182,41 @@ final class SprintBoardMoveController ...@@ -152,9 +182,41 @@ final class SprintBoardMoveController
->withPHIDs(array($object->getOwnerPHID())) ->withPHIDs(array($object->getOwnerPHID()))
->executeOne(); ->executeOne();
} }
// Reload the object so it reflects edits which have been applied.
$object = id(new ManiphestTaskQuery())
->setViewer($viewer)
->withPHIDs(array($object_phid))
->needProjectPHIDs(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
$except_phids = array($board_phid);
if ($project->getHasSubprojects() || $project->getHasMilestones()) {
$descendants = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withAncestorProjectPHIDs($except_phids)
->execute();
foreach ($descendants as $descendant) {
$except_phids[] = $descendant->getPHID();
}
}
$except_phids = array_fuse($except_phids);
$handle_phids = array_fuse($object->getProjectPHIDs());
$handle_phids = array_diff_key($handle_phids, $except_phids);
$project_handles = $viewer->loadHandles($handle_phids);
$project_handles = iterator_to_array($project_handles);
if ($is_sprint == true) { if ($is_sprint == true) {
$card = id(new SprintBoardTaskCard()) $card = id(new SprintBoardTaskCard())
->setProject($project) ->setProject($project)
->setProjectHandles($project_handles)
->setViewer($viewer) ->setViewer($viewer)
->setTask($object) ->setTask($object)
->setOwner($owner) ->setOwner($owner)
...@@ -164,6 +226,7 @@ final class SprintBoardMoveController ...@@ -164,6 +226,7 @@ final class SprintBoardMoveController
$card = id(new ProjectBoardTaskCard()) $card = id(new ProjectBoardTaskCard())
->setViewer($viewer) ->setViewer($viewer)
->setTask($object) ->setTask($object)
->setProjectHandles($project_handles)
->setOwner($owner) ->setOwner($owner)
->setCanEdit(true) ->setCanEdit(true)
->setProject($project) ->setProject($project)
......
...@@ -28,68 +28,34 @@ final class SprintBoardViewController ...@@ -28,68 +28,34 @@ final class SprintBoardViewController
$project = $this->getProject(); $project = $this->getProject();
$this->readRequestState(); $this->readRequestState();
$columns = $this->loadColumns($project);
// TODO: Expand the checks here if we add the ability
// to hide the Backlog column
if (!$columns) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$project,
PhabricatorPolicyCapability::CAN_EDIT);
if (!$can_edit) {
$content = $this->buildNoAccessContent($project);
} else {
$content = $this->buildInitializeContent($project);
}
if ($content instanceof AphrontResponse) {
return $content;
}
$nav = $this->getProfileMenu();
$nav->selectFilter(PhabricatorProject::PANEL_WORKBOARD);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Workboard'));
return $this->newPage()
->setTitle(
array(
pht('Workboard'),
$project->getName(),
))
->setNavigation($nav)
->setCrumbs($crumbs)
->appendChild($content);
}
$is_sprint = $this->isSprint($project); $is_sprint = $this->isSprint($project);
$board_uri = $this->getApplicationURI('board/'.$project->getID().'/'); $board_uri = $this->getApplicationURI('board/'.$project->getID().'/');
$engine = id(new ManiphestTaskSearchEngine()) $search_engine = id(new ManiphestTaskSearchEngine())
->setViewer($viewer) ->setViewer($viewer)
->setBaseURI($board_uri) ->setBaseURI($board_uri)
->setIsBoardView(true); ->setIsBoardView(true);
if ($request->isFormPost()) { if ($request->isFormPost() && !$request->getBool('initialize')) {
$saved = $engine->buildSavedQueryFromRequest($request); $saved = $search_engine->buildSavedQueryFromRequest($request);
$engine->saveQuery($saved); $search_engine->saveQuery($saved);
$filter_form = id(new AphrontFormView()) $filter_form = id(new AphrontFormView())
->setUser($viewer); ->setUser($viewer);
$engine->buildSearchForm($filter_form, $saved); $search_engine->buildSearchForm($filter_form, $saved);
if ($engine->getErrors()) { if ($search_engine->getErrors()) {
return $this->newDialog() return $this->newDialog()
->setWidth(AphrontDialogView::WIDTH_FULL) ->setWidth(AphrontDialogView::WIDTH_FULL)
->setTitle(pht('Advanced Filter')) ->setTitle(pht('Advanced Filter'))
->appendChild($filter_form->buildLayoutView()) ->appendChild($filter_form->buildLayoutView())
->setErrors($engine->getErrors()) ->setErrors($search_engine->getErrors())
->setSubmitURI($board_uri) ->setSubmitURI($board_uri)
->addSubmitButton(pht('Apply Filter')) ->addSubmitButton(pht('Apply Filter'))
->addCancelButton($board_uri); ->addCancelButton($board_uri);
} }
return id(new AphrontRedirectResponse())->setURI( return id(new AphrontRedirectResponse())->setURI(
$this->getURIWithState( $this->getURIWithState(
$engine->getQueryResultsPageURI($saved->getQueryKey()))); $search_engine->getQueryResultsPageURI($saved->getQueryKey())));
} }
$query_key = $request->getURIData('queryKey'); $query_key = $request->getURIData('queryKey');
...@@ -103,8 +69,8 @@ final class SprintBoardViewController ...@@ -103,8 +69,8 @@ final class SprintBoardViewController
$this->queryKey = $query_key; $this->queryKey = $query_key;
$custom_query = null; $custom_query = null;
if ($engine->isBuiltinQuery($query_key)) { if ($search_engine->isBuiltinQuery($query_key)) {
$saved = $engine->buildSavedQueryFromBuiltin($query_key); $saved = $search_engine->buildSavedQueryFromBuiltin($query_key);
} else { } else {
$saved = id(new PhabricatorSavedQueryQuery()) $saved = id(new PhabricatorSavedQueryQuery())
->setViewer($viewer) ->setViewer($viewer)
...@@ -121,7 +87,7 @@ final class SprintBoardViewController ...@@ -121,7 +87,7 @@ final class SprintBoardViewController
if ($request->getURIData('filter')) { if ($request->getURIData('filter')) {
$filter_form = id(new AphrontFormView()) $filter_form = id(new AphrontFormView())
->setUser($viewer); ->setUser($viewer);
$engine->buildSearchForm($filter_form, $saved); $search_engine->buildSearchForm($filter_form, $saved);
return $this->newDialog() return $this->newDialog()
->setWidth(AphrontDialogView::WIDTH_FULL) ->setWidth(AphrontDialogView::WIDTH_FULL)
...@@ -132,58 +98,68 @@ final class SprintBoardViewController ...@@ -132,58 +98,68 @@ final class SprintBoardViewController
->addCancelButton($board_uri); ->addCancelButton($board_uri);
} }
$task_query = $engine->buildQueryFromSavedQuery($saved); $task_query = $search_engine->buildQueryFromSavedQuery($saved);
$select_phids = array($project->getPHID());
if ($project->getHasSubprojects() || $project->getHasMilestones()) {
$descendants = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withAncestorProjectPHIDs($select_phids)
->execute();
foreach ($descendants as $descendant) {
$select_phids[] = $descendant->getPHID();
}
}
$tasks = $task_query $tasks = $task_query
->withEdgeLogicPHIDs( ->withEdgeLogicPHIDs(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
PhabricatorQueryConstraint::OPERATOR_AND, PhabricatorQueryConstraint::OPERATOR_ANCESTOR,
array($project->getPHID())) array($select_phids))
->setOrder(ManiphestTaskQuery::ORDER_PRIORITY) ->setOrder(ManiphestTaskQuery::ORDER_PRIORITY)
->setViewer($viewer) ->setViewer($viewer)
->execute(); ->execute();
$tasks = mpull($tasks, null, 'getPHID'); $tasks = mpull($tasks, null, 'getPHID');
if ($tasks) { $board_phid = $project->getPHID();
$positions = id(new PhabricatorProjectColumnPositionQuery())
$layout_engine = id(new PhabricatorBoardLayoutEngine())
->setViewer($viewer) ->setViewer($viewer)
->withObjectPHIDs(mpull($tasks, 'getPHID')) ->setBoardPHIDs(array($board_phid))
->withColumns($columns) ->setObjectPHIDs(array_keys($tasks))
->execute(); ->executeLayout();
$positions = mpull($positions, null, 'getObjectPHID');
$columns = $layout_engine->getColumns($board_phid);
if (!$columns) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$project,
PhabricatorPolicyCapability::CAN_EDIT);
if (!$can_edit) {
$content = $this->buildNoAccessContent($project);
} else { } else {
$positions = array(); $content = $this->buildInitializeContent($project);
} }
$task_map = array(); if ($content instanceof AphrontResponse) {
foreach ($tasks as $task) { return $content;
$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]; $nav = $this->getProfileMenu();
$task_map[$position->getColumnPHID()][] = $task_phid; $nav->selectFilter(PhabricatorProject::PANEL_WORKBOARD);
}
// If we're showing the board in "natural" order, sort columns by their $crumbs = $this->buildApplicationCrumbs();
// column positions. $crumbs->addTextCrumb(pht('Workboard'));
if ($this->sortKey == PhabricatorProjectColumn::ORDER_NATURAL) {
foreach ($task_map as $column_phid => $task_phids) { return $this->newPage()
$order = array(); ->setTitle(
foreach ($task_phids as $task_phid) { array(
if (isset($positions[$task_phid])) { pht('Workboard'),
$order[$task_phid] = $positions[$task_phid]->getOrderingKey(); $project->getName(),
} else { ))
$order[$task_phid] = 0; ->setNavigation($nav)
} ->setCrumbs($crumbs)
} ->appendChild($content);
asort($order);
$task_map[$column_phid] = array_keys($order);
}
} }
$task_can_edit_map = id(new PhabricatorPolicyFilter()) $task_can_edit_map = id(new PhabricatorPolicyFilter())
...@@ -202,7 +178,10 @@ final class SprintBoardViewController ...@@ -202,7 +178,10 @@ final class SprintBoardViewController
return new Aphront404Response(); 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) { foreach ($batch_task_phids as $key => $batch_task_phid) {
if (empty($task_can_edit_map[$batch_task_phid])) { if (empty($task_can_edit_map[$batch_task_phid])) {
unset($batch_task_phids[$key]); unset($batch_task_phids[$key]);
...@@ -270,10 +249,46 @@ final class SprintBoardViewController ...@@ -270,10 +249,46 @@ final class SprintBoardViewController
$this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks); $this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
$all_project_phids = array();
foreach ($tasks as $task) {
foreach ($task->getProjectPHIDs() as $project_phid) {
$all_project_phids[$project_phid] = $project_phid;
}
}
foreach ($select_phids as $phid) {
unset($all_project_phids[$phid]);
}
$all_handles = $viewer->loadHandles($all_project_phids);
$all_handles = iterator_to_array($all_handles);
foreach ($columns as $column) { foreach ($columns as $column) {
$task_phids = idx($task_map, $column->getPHID(), array()); if (!$this->showHidden) {
if ($column->isHidden()) {
continue;
}
}
$proxy = $column->getProxy();
if ($proxy && !$proxy->isMilestone()) {
// TODO: For now, don't show subproject columns because we can't
// handle tasks with multiple positions yet.
continue;
}
$task_phids = $layout_engine->getColumnObjectPHIDs(
$board_phid,
$column->getPHID());
$column_tasks = array_select_keys($tasks, $task_phids); $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()) $panel = id(new PHUIWorkpanelView())
->setHeader($column->getDisplayName()) ->setHeader($column->getDisplayName())
->setSubHeader($column->getDisplayType()) ->setSubHeader($column->getDisplayType())
...@@ -284,6 +299,11 @@ final class SprintBoardViewController ...@@ -284,6 +299,11 @@ final class SprintBoardViewController
$panel->setHeaderIcon($header_icon); $panel->setHeaderIcon($header_icon);
} }
$display_class = $column->getDisplayClass();
if ($display_class) {
$panel->addClass($display_class);
}
if ($column->isHidden()) { if ($column->isHidden()) {
$panel->addClass('project-panel-hidden'); $panel->addClass('project-panel-hidden');
} }
...@@ -323,9 +343,11 @@ final class SprintBoardViewController ...@@ -323,9 +343,11 @@ final class SprintBoardViewController
$owner = $this->handles[$task->getOwnerPHID()]; $owner = $this->handles[$task->getOwnerPHID()];
} }
$can_edit = idx($task_can_edit_map, $task->getPHID(), false); $can_edit = idx($task_can_edit_map, $task->getPHID(), false);
$handles = array_select_keys($all_handles, $task->getProjectPHIDs());
if ($is_sprint == true) { if ($is_sprint == true) {
$cards->addItem(id(new SprintBoardTaskCard()) $cards->addItem(id(new SprintBoardTaskCard())
->setProject($project) ->setProject($project)
->setProjectHandles($handles)
->setViewer($viewer) ->setViewer($viewer)
->setTask($task) ->setTask($task)
->setOwner($owner) ->setOwner($owner)
...@@ -335,6 +357,7 @@ final class SprintBoardViewController ...@@ -335,6 +357,7 @@ final class SprintBoardViewController
$cards->addItem(id(new ProjectBoardTaskCard()) $cards->addItem(id(new ProjectBoardTaskCard())
->setViewer($viewer) ->setViewer($viewer)
->setProject($project) ->setProject($project)
->setProjectHandles($handles)
->setTask($task) ->setTask($task)
->setOwner($owner) ->setOwner($owner)
->setCanEdit($can_edit) ->setCanEdit($can_edit)
...@@ -352,7 +375,7 @@ final class SprintBoardViewController ...@@ -352,7 +375,7 @@ final class SprintBoardViewController
$filter_menu = $this->buildFilterMenu( $filter_menu = $this->buildFilterMenu(
$viewer, $viewer,
$custom_query, $custom_query,
$engine, $search_engine,
$query_key); $query_key);
$manage_menu = $this->buildManageMenu($project, $this->showHidden); $manage_menu = $this->buildManageMenu($project, $this->showHidden);
...@@ -413,25 +436,6 @@ final class SprintBoardViewController ...@@ -413,25 +436,6 @@ final class SprintBoardViewController
$this->sortKey = $sort_key; $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( private function buildSortMenu(
PhabricatorUser $viewer, PhabricatorUser $viewer,
$sort_key) { $sort_key) {
...@@ -562,7 +566,7 @@ final class SprintBoardViewController ...@@ -562,7 +566,7 @@ final class SprintBoardViewController
$show_hidden) { $show_hidden) {
$request = $this->getRequest(); $request = $this->getRequest();
$viewer = $request->getViewer(); $viewer = $request->getUser();
$can_edit = PhabricatorPolicyFilter::hasCapability( $can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer, $viewer,
...@@ -648,6 +652,12 @@ final class SprintBoardViewController ...@@ -648,6 +652,12 @@ final class SprintBoardViewController
$column_items = array(); $column_items = array();
if ($column->getProxyPHID()) {
$default_phid = $column->getProxyPHID();
} else {
$default_phid = $column->getProjectPHID();
}
$column_items[] = id(new PhabricatorActionView()) $column_items[] = id(new PhabricatorActionView())
->setIcon('fa-plus') ->setIcon('fa-plus')
->setName(pht('Create Task...')) ->setName(pht('Create Task...'))
...@@ -656,6 +666,7 @@ final class SprintBoardViewController ...@@ -656,6 +666,7 @@ final class SprintBoardViewController
->setMetadata( ->setMetadata(
array( array(
'columnPHID' => $column->getPHID(), 'columnPHID' => $column->getPHID(),
'projectPHID' => $default_phid,
)); ));
$batch_edit_uri = $request->getRequestURI(); $batch_edit_uri = $request->getRequestURI();
...@@ -718,6 +729,7 @@ final class SprintBoardViewController ...@@ -718,6 +729,7 @@ final class SprintBoardViewController
return $column_button; return $column_button;
} }
/** /**
* Add current state parameters (like order and the visibility of hidden * Add current state parameters (like order and the visibility of hidden
* columns) to a URI. * columns) to a URI.
...@@ -833,6 +845,7 @@ final class SprintBoardViewController ...@@ -833,6 +845,7 @@ final class SprintBoardViewController
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($viewer) ->setUser($viewer)
->addHiddenInput('initialize', 1)
->appendRemarkupInstructions( ->appendRemarkupInstructions(
pht('The workboard for this project has not been created yet.')) pht('The workboard for this project has not been created yet.'))
->appendControl($new_selector) ->appendControl($new_selector)
......
...@@ -280,20 +280,35 @@ final class SprintManiphestEditEngine ...@@ -280,20 +280,35 @@ final class SprintManiphestEditEngine
return new Aphront404Response(); return new Aphront404Response();
} }
// If the workboard's project has been removed from the card's project // If the workboard's project and all descendant projects have been removed
// list, we are going to remove it from the board completely. // from the card's project list, we are going to remove it from the board
// completely.
// TODO: If the user did something sneaky and changed a subproject, we'll
// currently leave the card where it was but should really move it to the
// proper new column.
$descendant_projects = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->withAncestorProjectPHIDs(array($column->getProjectPHID()))
->execute();
$board_phids = mpull($descendant_projects, 'getPHID', 'getPHID');
$board_phids[$column->getProjectPHID()] = $column->getProjectPHID();
$project_map = array_fuse($task->getProjectPHIDs()); $project_map = array_fuse($task->getProjectPHIDs());
$remove_card = empty($project_map[$column->getProjectPHID()]); $remove_card = !array_intersect_key($board_phids, $project_map);
$positions = id(new PhabricatorProjectColumnPositionQuery()) $positions = id(new PhabricatorProjectColumnPositionQuery())
->setViewer($viewer) ->setViewer($viewer)
->withColumns(array($column)) ->withBoardPHIDs(array($column->getProjectPHID()))
->withColumnPHIDs(array($column->getPHID()))
->execute(); ->execute();
$task_phids = mpull($positions, 'getObjectPHID'); $task_phids = mpull($positions, 'getObjectPHID');
$column_tasks = id(new ManiphestTaskQuery()) $column_tasks = id(new ManiphestTaskQuery())
->setViewer($viewer) ->setViewer($viewer)
->withPHIDs($task_phids) ->withPHIDs($task_phids)
->needProjectPHIDs(true)
->execute(); ->execute();
if ($order == PhabricatorProjectColumn::ORDER_NATURAL) { if ($order == PhabricatorProjectColumn::ORDER_NATURAL) {
...@@ -329,17 +344,27 @@ final class SprintManiphestEditEngine ...@@ -329,17 +344,27 @@ final class SprintManiphestEditEngine
->executeOne(); ->executeOne();
} }
$handle_phids = $task->getProjectPHIDs();
$handle_phids = array_fuse($handle_phids);
$handle_phids = array_diff_key($handle_phids, $board_phids);
$project_handles = $viewer->loadHandles($handle_phids);
$project_handles = iterator_to_array($project_handles);
$projects = $request->getArr('projectPHIDs'); $projects = $request->getArr('projectPHIDs');
$project = $this->getSprintProjectforTask($viewer, $projects); $project = $this->getSprintProjectforTask($viewer, $projects);
$tasks = id(new SprintBoardTaskCard()) $tasks = id(new SprintBoardTaskCard())
->setViewer($viewer) ->setViewer($viewer)
->setProject($project) ->setProject($project)
->setProjectHandles($project_handles)
->setTask($task) ->setTask($task)
->setOwner($owner) ->setOwner($owner)
->setCanEdit(true) ->setCanEdit(true)
->getItem(); ->getItem();
$tasks->addClass('phui-workcard');
$payload = array( $payload = array(
'tasks' => $tasks, 'tasks' => $tasks,
'data' => $data, 'data' => $data,
......
...@@ -304,8 +304,7 @@ final class SprintQuery extends SprintDAO { ...@@ -304,8 +304,7 @@ final class SprintQuery extends SprintDAO {
->setViewer($this->viewer) ->setViewer($this->viewer)
->withBoardPHIDs(array($this->projectPHID)) ->withBoardPHIDs(array($this->projectPHID))
->withObjectPHIDs(mpull($tasks, 'getPHID')) ->withObjectPHIDs(mpull($tasks, 'getPHID'))
->withColumns($columns) ->withColumnPHIDs(mpull($columns, 'getPHID'))
->needColumns(true)
->execute(); ->execute();
$positions = mpull($positions, null, 'getObjectPHID'); $positions = mpull($positions, null, 'getObjectPHID');
} else { } else {
......
...@@ -4,6 +4,7 @@ final class SprintBoardTaskCard extends Phobject { ...@@ -4,6 +4,7 @@ final class SprintBoardTaskCard extends Phobject {
private $project; private $project;
private $viewer; private $viewer;
private $projectHandles;
private $task; private $task;
private $owner; private $owner;
private $canEdit; private $canEdit;
...@@ -28,6 +29,15 @@ final class SprintBoardTaskCard extends Phobject { ...@@ -28,6 +29,15 @@ final class SprintBoardTaskCard extends Phobject {
return $this->viewer; return $this->viewer;
} }
public function setProjectHandles(array $handles) {
$this->projectHandles = $handles;
return $this;
}
public function getProjectHandles() {
return $this->projectHandles;
}
public function setTask(ManiphestTask $task) { public function setTask(ManiphestTask $task) {
$this->task = $task; $this->task = $task;
return $this; return $this;
...@@ -128,14 +138,12 @@ final class SprintBoardTaskCard extends Phobject { ...@@ -128,14 +138,12 @@ final class SprintBoardTaskCard extends Phobject {
$card->addHandleIcon($owner, $owner->getName()); $card->addHandleIcon($owner, $owner->getName());
} }
$card->addAttribute($this->getCardAttributes()); $card->addAttribute($this->getCardAttributes());
$project_phids = array_fuse($task->getProjectPHIDs());
unset($project_phids[$this->project->getPHID()]);
if ($project_phids) { $project_handles = $this->getProjectHandles();
$handle_list = $viewer->loadHandles($project_phids); if ($project_handles) {
$tag_list = id(new PHUIHandleTagListView()) $tag_list = id(new PHUIHandleTagListView())
->setSlim(true) ->setSlim(true)
->setHandles($handle_list); ->setHandles($project_handles);
$card->addAttribute($tag_list); $card->addAttribute($tag_list);
} }
return $card; return $card;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment