Differential D20635 Diff 49220 src/applications/project/controller/PhabricatorProjectBoardViewController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/controller/PhabricatorProjectBoardViewController.php
| Show First 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | public function handleRequest(AphrontRequest $request) { | ||||
| $tasks = $state->getObjects(); | $tasks = $state->getObjects(); | ||||
| $task_can_edit_map = id(new PhabricatorPolicyFilter()) | $task_can_edit_map = id(new PhabricatorPolicyFilter()) | ||||
| ->setViewer($viewer) | ->setViewer($viewer) | ||||
| ->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT)) | ->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT)) | ||||
| ->apply($tasks); | ->apply($tasks); | ||||
| $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 = $state->newWorkboardURI(); | |||||
| 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->isFormOrHiSecPost()) { | |||||
| $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'); | |||||
| foreach ($columns as $key => $column) { | |||||
| if ($column->isHidden()) { | |||||
| unset($columns[$key]); | |||||
| } | |||||
| } | |||||
| $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) | |||||
| ->setCancelURI($cancel_uri); | |||||
| $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 = celerity_generate_unique_node_id(); | ||||
| $board = id(new PHUIWorkboardView()) | $board = id(new PHUIWorkboardView()) | ||||
| ->setUser($viewer) | ->setUser($viewer) | ||||
| ->setID($board_id) | ->setID($board_id) | ||||
| ->addSigil('jx-workboard') | ->addSigil('jx-workboard') | ||||
| ->setMetadata( | ->setMetadata( | ||||
| array( | array( | ||||
| ▲ Show 20 Lines • Show All 614 Lines • ▼ Show 20 Lines | $can_bulk_edit = PhabricatorPolicyFilter::hasCapability( | ||||
| ManiphestBulkEditCapability::CAPABILITY); | ManiphestBulkEditCapability::CAPABILITY); | ||||
| $column_items[] = id(new PhabricatorActionView()) | $column_items[] = id(new PhabricatorActionView()) | ||||
| ->setIcon('fa-list-ul') | ->setIcon('fa-list-ul') | ||||
| ->setName(pht('Bulk Edit Tasks...')) | ->setName(pht('Bulk Edit Tasks...')) | ||||
| ->setHref($bulk_edit_uri) | ->setHref($bulk_edit_uri) | ||||
| ->setDisabled(!$can_bulk_edit); | ->setDisabled(!$can_bulk_edit); | ||||
| $batch_move_uri = $request->getRequestURI(); | $project_move_uri = $state->newWorkboardURI( | ||||
| $batch_move_uri->replaceQueryParam('move', $column->getID()); | urisprintf( | ||||
| 'bulkmove/%d/project/', | |||||
| $column->getID())); | |||||
| $column_items[] = id(new PhabricatorActionView()) | $column_items[] = id(new PhabricatorActionView()) | ||||
| ->setIcon('fa-arrow-right') | ->setIcon('fa-arrow-right') | ||||
| ->setName(pht('Move Tasks to Column...')) | ->setName(pht('Move Tasks to Column...')) | ||||
| ->setHref($batch_move_uri) | ->setHref($project_move_uri) | ||||
| ->setWorkflow(true); | ->setWorkflow(true); | ||||
| $query_uri = urisprintf('viewquery/%d/', $column->getID()); | $query_uri = urisprintf('viewquery/%d/', $column->getID()); | ||||
| $query_uri = $state->newWorkboardURI($query_uri); | $query_uri = $state->newWorkboardURI($query_uri); | ||||
| $column_items[] = id(new PhabricatorActionView()) | $column_items[] = id(new PhabricatorActionView()) | ||||
| ->setName(pht('View as Query')) | ->setName(pht('View as Query')) | ||||
| ->setIcon('fa-search') | ->setIcon('fa-search') | ||||
| ▲ Show 20 Lines • Show All 305 Lines • Show Last 20 Lines | |||||