@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at recaptime-dev/main 145 lines 4.3 kB view raw
1<?php 2 3final class PhabricatorProjectBoardReorderController 4 extends PhabricatorProjectBoardController { 5 6 public function handleRequest(AphrontRequest $request) { 7 $viewer = $request->getViewer(); 8 $projectid = $request->getURIData('projectID'); 9 10 $project = id(new PhabricatorProjectQuery()) 11 ->setViewer($viewer) 12 ->requireCapabilities( 13 array( 14 PhabricatorPolicyCapability::CAN_VIEW, 15 PhabricatorPolicyCapability::CAN_EDIT, 16 )) 17 ->withIDs(array($projectid)) 18 ->executeOne(); 19 if (!$project) { 20 return new Aphront404Response(); 21 } 22 23 $this->setProject($project); 24 $project_id = $project->getID(); 25 26 $view_uri = $this->getApplicationURI("board/{$project_id}/"); 27 $reorder_uri = $this->getApplicationURI("board/{$project_id}/reorder/"); 28 29 if ($request->isFormPost()) { 30 // User clicked "Done", make sure the page reloads to show the new 31 // column order. 32 return id(new AphrontRedirectResponse())->setURI($view_uri); 33 } 34 35 $columns = id(new PhabricatorProjectColumnQuery()) 36 ->setViewer($viewer) 37 ->withProjectPHIDs(array($project->getPHID())) 38 ->execute(); 39 $columns = msort($columns, 'getSequence'); 40 41 $column_phid = $request->getStr('columnPHID'); 42 if ($column_phid && $request->validateCSRF()) { 43 44 $columns = mpull($columns, null, 'getPHID'); 45 if (empty($columns[$column_phid])) { 46 return new Aphront404Response(); 47 } 48 49 $target_column = $columns[$column_phid]; 50 $new_sequence = $request->getInt('sequence'); 51 if ($new_sequence < 0) { 52 return new Aphront404Response(); 53 } 54 55 // TODO: For now, we're not recording any transactions here. We probably 56 // should, but this sort of edit is extremely trivial. 57 58 // Resequence the columns so that the moved column has the correct 59 // sequence number. Move columns after it up one place in the sequence. 60 $new_map = array(); 61 foreach ($columns as $phid => $column) { 62 $value = $column->getSequence(); 63 if ($column->getPHID() == $column_phid) { 64 $value = $new_sequence; 65 } else if ($column->getSequence() >= $new_sequence) { 66 $value = $value + 1; 67 } 68 $new_map[$phid] = $value; 69 } 70 71 // Sort the columns into their new ordering. 72 asort($new_map); 73 74 // Now, compact the ordering and adjust any columns that need changes. 75 $project->openTransaction(); 76 $sequence = 0; 77 foreach ($new_map as $phid => $ignored) { 78 $new_value = $sequence++; 79 $cur_value = $columns[$phid]->getSequence(); 80 if ($new_value != $cur_value) { 81 $columns[$phid]->setSequence($new_value)->save(); 82 } 83 } 84 $project->saveTransaction(); 85 86 return id(new AphrontAjaxResponse())->setContent( 87 array( 88 'sequenceMap' => mpull($columns, 'getSequence', 'getPHID'), 89 )); 90 } 91 92 $list_id = celerity_generate_unique_node_id(); 93 94 $list = id(new PHUIObjectItemListView()) 95 ->setUser($viewer) 96 ->setID($list_id) 97 ->setFlush(true) 98 ->setDrag(true); 99 100 foreach ($columns as $column) { 101 // Don't allow milestone columns to be reordered. 102 $proxy = $column->getProxy(); 103 if ($proxy && $proxy->isMilestone()) { 104 continue; 105 } 106 107 // At least for now, don't show subproject column. 108 if ($proxy) { 109 continue; 110 } 111 112 $item = id(new PHUIObjectItemView()) 113 ->setHeader($column->getDisplayName()) 114 ->addIcon($column->getHeaderIcon(), $column->getDisplayType()); 115 116 if ($column->isHidden()) { 117 $item->setDisabled(true); 118 } 119 120 $item->setGrippable(true); 121 $item->addSigil('board-column'); 122 $item->setMetadata( 123 array( 124 'columnPHID' => $column->getPHID(), 125 'columnSequence' => $column->getSequence(), 126 )); 127 128 $list->addItem($item); 129 } 130 131 Javelin::initBehavior( 132 'reorder-columns', 133 array( 134 'listID' => $list_id, 135 'reorderURI' => $reorder_uri, 136 )); 137 138 return $this->newDialog() 139 ->setTitle(pht('Reorder Columns')) 140 ->setWidth(AphrontDialogView::WIDTH_FORM) 141 ->appendChild($list) 142 ->addSubmitButton(pht('Done')); 143 } 144 145}