@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Workboards - let users delete columns

Summary: Fixes T4408. I had to add a "status" to colum. I think we'll need this once we get fancier anyway but for now we have "active" and deleted.

Test Plan: deleted a column. noted reloaded workboard with all those tasks back in the default colun. loaded a task and saw the initial transaction had a "Disabled" icon next to the deleted workboard. also saw the new transaction back to the default column worked.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: epriestley, Korvin

Maniphest Tasks: T4408

Differential Revision: https://secure.phabricator.com/D8544

+153 -1
+2
resources/sql/autopatches/20140314.projectcolumn.1.statuscol.sql
··· 1 + ALTER TABLE {$NAMESPACE}_project.project_column 2 + ADD COLUMN status INT UNSIGNED NOT NULL AFTER name;
+2
resources/sql/autopatches/20140314.projectcolumn.2.statuskey.sql
··· 1 + ALTER TABLE {$NAMESPACE}_project.project_column 2 + ADD KEY `key_status` (`projectPHID`,`status`,`sequence`);
+2
src/__phutil_library_map__.php
··· 1843 1843 'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php', 1844 1844 'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php', 1845 1845 'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php', 1846 + 'PhabricatorProjectBoardDeleteController' => 'applications/project/controller/PhabricatorProjectBoardDeleteController.php', 1846 1847 'PhabricatorProjectBoardEditController' => 'applications/project/controller/PhabricatorProjectBoardEditController.php', 1847 1848 'PhabricatorProjectColumn' => 'applications/project/storage/PhabricatorProjectColumn.php', 1848 1849 'PhabricatorProjectColumnQuery' => 'applications/project/query/PhabricatorProjectColumnQuery.php', ··· 4609 4610 ), 4610 4611 'PhabricatorProjectArchiveController' => 'PhabricatorProjectController', 4611 4612 'PhabricatorProjectBoardController' => 'PhabricatorProjectController', 4613 + 'PhabricatorProjectBoardDeleteController' => 'PhabricatorProjectController', 4612 4614 'PhabricatorProjectBoardEditController' => 'PhabricatorProjectController', 4613 4615 'PhabricatorProjectColumn' => 4614 4616 array(
+2
src/applications/project/application/PhabricatorApplicationProject.php
··· 53 53 'move/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectMoveController', 54 54 'board/(?P<projectID>[1-9]\d*)/edit/(?:(?P<id>\d+)/)?' 55 55 => 'PhabricatorProjectBoardEditController', 56 + 'board/(?P<projectID>[1-9]\d*)/delete/(?:(?P<id>\d+)/)?' 57 + => 'PhabricatorProjectBoardDeleteController', 56 58 'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/' 57 59 => 'PhabricatorProjectUpdateController', 58 60 'history/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectHistoryController',
+8
src/applications/project/controller/PhabricatorProjectBoardController.php
··· 30 30 $columns = id(new PhabricatorProjectColumnQuery()) 31 31 ->setViewer($viewer) 32 32 ->withProjectPHIDs(array($project->getPHID())) 33 + ->withStatuses(array(PhabricatorProjectColumn::STATUS_ACTIVE)) 33 34 ->execute(); 34 35 35 36 $columns = mpull($columns, null, 'getSequence'); ··· 167 168 ->setName(pht('Add Column')) 168 169 ->setHref($this->getApplicationURI('board/'.$this->id.'/edit/')) 169 170 ->setIcon('create') 171 + ->setDisabled(!$can_edit) 172 + ->setWorkflow(!$can_edit)) 173 + ->addAction( 174 + id(new PhabricatorActionView()) 175 + ->setName(pht('Delete Column')) 176 + ->setHref($this->getApplicationURI('board/'.$this->id.'/delete/')) 177 + ->setIcon('delete') 170 178 ->setDisabled(!$can_edit) 171 179 ->setWorkflow(!$can_edit)); 172 180
+116
src/applications/project/controller/PhabricatorProjectBoardDeleteController.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectBoardDeleteController 4 + extends PhabricatorProjectController { 5 + 6 + private $id; 7 + private $projectID; 8 + 9 + public function willProcessRequest(array $data) { 10 + $this->projectID = $data['projectID']; 11 + $this->id = idx($data, 'id'); 12 + } 13 + 14 + public function processRequest() { 15 + $request = $this->getRequest(); 16 + $viewer = $request->getUser(); 17 + 18 + $project = id(new PhabricatorProjectQuery()) 19 + ->setViewer($viewer) 20 + ->requireCapabilities( 21 + array( 22 + PhabricatorPolicyCapability::CAN_VIEW, 23 + PhabricatorPolicyCapability::CAN_EDIT, 24 + )) 25 + ->withIDs(array($this->projectID)) 26 + ->executeOne(); 27 + 28 + if (!$project) { 29 + return new Aphront404Response(); 30 + } 31 + 32 + $columns = id(new PhabricatorProjectColumnQuery()) 33 + ->setViewer($viewer) 34 + ->withProjectPHIDs(array($project->getPHID())) 35 + ->withStatuses(array(PhabricatorProjectColumn::STATUS_ACTIVE)) 36 + ->requireCapabilities( 37 + array( 38 + PhabricatorPolicyCapability::CAN_VIEW, 39 + PhabricatorPolicyCapability::CAN_EDIT)) 40 + ->execute(); 41 + 42 + if (!$columns) { 43 + return new Aphront404Response(); 44 + } 45 + 46 + $columns = mpull($columns, null, 'getSequence'); 47 + $columns = mfilter($columns, 'isDefaultColumn', true); 48 + ksort($columns); 49 + $options = mpull($columns, 'getName', 'getPHID'); 50 + 51 + $view_uri = $this->getApplicationURI('/board/'.$this->projectID.'/'); 52 + $error_view = null; 53 + if ($request->isFormPost()) { 54 + $columns = mpull($columns, null, 'getPHID'); 55 + $column_phid = $request->getStr('columnPHID'); 56 + $column = $columns[$column_phid]; 57 + 58 + $has_task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( 59 + $column_phid, 60 + PhabricatorEdgeConfig::TYPE_COLUMN_HAS_OBJECT); 61 + 62 + if ($has_task_phids) { 63 + $error_view = id(new AphrontErrorView()) 64 + ->setTitle(pht('Column has Tasks!')) 65 + ->setErrors(array(pht('A column can not be deleted if it has tasks '. 66 + 'in it. Please remove the tasks and try '. 67 + 'again.'))); 68 + } else { 69 + $column->setStatus(PhabricatorProjectColumn::STATUS_DELETED); 70 + $column->save(); 71 + 72 + return id(new AphrontRedirectResponse())->setURI($view_uri); 73 + } 74 + } 75 + 76 + $form = id(new AphrontFormView()) 77 + ->setUser($viewer) 78 + ->appendChild($error_view) 79 + ->appendChild(id(new AphrontFormSelectControl()) 80 + ->setName('columnPHID') 81 + ->setValue(head_key($options)) 82 + ->setOptions($options) 83 + ->setLabel(pht('Column'))); 84 + 85 + $title = pht('Delete Column'); 86 + $submit = $title; 87 + 88 + $form->appendChild( 89 + id(new AphrontFormSubmitControl()) 90 + ->setValue($submit) 91 + ->addCancelButton($view_uri)); 92 + 93 + $crumbs = $this->buildApplicationCrumbs(); 94 + $crumbs->addTextCrumb( 95 + $project->getName(), 96 + $this->getApplicationURI('view/'.$project->getID().'/')); 97 + $crumbs->addTextCrumb( 98 + pht('Board'), 99 + $this->getApplicationURI('board/'.$project->getID().'/')); 100 + $crumbs->addTextCrumb($title); 101 + 102 + $form_box = id(new PHUIObjectBoxView()) 103 + ->setHeaderText($title) 104 + ->setForm($form); 105 + 106 + return $this->buildApplicationPage( 107 + array( 108 + $crumbs, 109 + $form_box, 110 + ), 111 + array( 112 + 'title' => $title, 113 + 'device' => true, 114 + )); 115 + } 116 + }
+2
src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php
··· 34 34 35 35 $handle->setName($column->getDisplayName()); 36 36 $handle->setURI('/project/board/'.$column->getProject()->getID().'/'); 37 + $handle->setDisabled( 38 + $column->getStatus() == PhabricatorProjectColumn::STATUS_DELETED); 37 39 } 38 40 } 39 41
+13
src/applications/project/query/PhabricatorProjectColumnQuery.php
··· 6 6 private $ids; 7 7 private $phids; 8 8 private $projectPHIDs; 9 + private $statuses; 9 10 10 11 public function withIDs(array $ids) { 11 12 $this->ids = $ids; ··· 19 20 20 21 public function withProjectPHIDs(array $project_phids) { 21 22 $this->projectPHIDs = $project_phids; 23 + return $this; 24 + } 25 + 26 + public function withStatuses(array $status) { 27 + $this->statuses = $status; 22 28 return $this; 23 29 } 24 30 ··· 85 91 $conn_r, 86 92 'projectPHID IN (%Ls)', 87 93 $this->projectPHIDs); 94 + } 95 + 96 + if ($this->statuses !== null) { 97 + $where[] = qsprintf( 98 + $conn_r, 99 + 'status IN (%Ld)', 100 + $this->statuses); 88 101 } 89 102 90 103 $where[] = $this->buildPagingClause($conn_r);
+6 -1
src/applications/project/storage/PhabricatorProjectColumn.php
··· 4 4 extends PhabricatorProjectDAO 5 5 implements PhabricatorPolicyInterface { 6 6 7 + const STATUS_ACTIVE = 0; 8 + const STATUS_DELETED = 1; 9 + 7 10 protected $name; 11 + protected $status; 8 12 protected $projectPHID; 9 13 protected $sequence; 10 14 ··· 12 16 13 17 public static function initializeNewColumn(PhabricatorUser $user) { 14 18 return id(new PhabricatorProjectColumn()) 15 - ->setName(''); 19 + ->setName('') 20 + ->setStatus(self::STATUS_ACTIVE); 16 21 } 17 22 18 23 public function getConfiguration() {