diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -20,6 +20,8 @@ private $anyProjectPHIDs = array(); private $anyUserProjectPHIDs = array(); private $includeNoProject = null; + private $allColumnPHIDs = array(); + private $anyColumnPHIDs = array(); private $dateCreatedAfter; private $dateCreatedBefore; private $dateModifiedAfter; @@ -156,6 +158,16 @@ return $this; } + public function withAllColumns(array $columns) { + $this->allColumnPHIDs = $columns; + return $this; + } + + public function withAnyColumns(array $columns) { + $this->anyColumnPHIDs = $columns; + return $this; + } + public function withAnyUserProjects(array $users) { $this->anyUserProjectPHIDs = $users; return $this; @@ -204,6 +216,8 @@ $where[] = $this->buildProjectWhereClause($conn); $where[] = $this->buildAnyProjectWhereClause($conn); $where[] = $this->buildAnyUserProjectWhereClause($conn); + $where[] = $this->buildColumnWhereClause($conn); + $where[] = $this->buildAnyColumnWhereClause($conn); $where[] = $this->buildXProjectWhereClause($conn); $where[] = $this->buildFullTextWhereClause($conn); @@ -525,6 +539,30 @@ $this->anyProjectPHIDs); } + private function buildColumnWhereClause(AphrontDatabaseConnection $conn) { + if (!$this->allColumnPHIDs) { + return null; + } + + $parts[] = qsprintf( + $conn, + 'boardcolumn.dst in (%Ls)', + $this->allColumnPHIDs); + + return '('.implode(') AND (', $parts).')'; + } + + private function buildAnyColumnWhereClause(AphrontDatabaseConnection $conn) { + if (!$this->anyColumnPHIDs) { + return null; + } + + return qsprintf( + $conn, + 'boardcolumn.dst IN (%Ls)', + $this->anyColumnPHIDs); + } + private function buildAnyUserProjectWhereClause( AphrontDatabaseConnection $conn) { if (!$this->anyUserProjectPHIDs) { @@ -661,6 +699,15 @@ $project_dao->getTableName()); } + if ($this->allColumnPHIDs || $this->anyColumnPHIDs) { + $joins[] = qsprintf( + $conn_r, + 'JOIN edge boardcolumn ON boardcolumn.src = task.phid + AND boardcolumn.type = %d', + PhabricatorEdgeConfig::TYPE_OBJECT_HAS_COLUMN + ); + } + if ($this->xprojectPHIDs) { $joins[] = qsprintf( $conn_r, diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php --- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php +++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php @@ -96,6 +96,14 @@ $this->readPHIDsFromRequest($request, 'anyProjects')); $saved->setParameter( + 'allColumnPHIDs', + $this->readPHIDsFromRequest($request, 'allColumns')); + + $saved->setParameter( + 'anyColumnPHIDs', + $this->readPHIDsFromRequest($request, 'anyColumns')); + + $saved->setParameter( 'excludeProjectPHIDs', $this->readPHIDsFromRequest($request, 'excludeProjects')); @@ -202,6 +210,16 @@ $query->withAnyUserProjects($user_project_phids); } + $all_column_phids = $saved->getParameter('allColumnPHIDs'); + if ($all_column_phids) { + $query->withAllColumns($all_column_phids); + } + + $any_column_phids = $saved->getParameter('anyColumnPHIDs'); + if ($any_column_phids) { + $query->withAnyColumns($any_column_phids); + } + $start = $this->parseDateTime($saved->getParameter('createdStart')); $end = $this->parseDateTime($saved->getParameter('createdEnd')); @@ -244,6 +262,8 @@ $exclude_project_phids = $saved->getParameter( 'excludeProjectPHIDs', array()); + $all_column_phids = $saved->getParameter('allColumnPHIDs', array()); + $any_column_phids = $saved->getParameter('anyColumnPHIDs', array()); $user_project_phids = $saved->getParameter( 'userProjectPHIDs', array()); @@ -255,6 +275,8 @@ $all_project_phids, $any_project_phids, $exclude_project_phids, + $all_column_phids, + $any_column_phids, $user_project_phids, $subscriber_phids); @@ -274,6 +296,10 @@ $exclude_project_handles = array_select_keys( $handles, $exclude_project_phids); + + $all_column_handles = array_select_keys($handles, $all_column_phids); + $any_column_handles = array_select_keys($handles, $any_column_phids); + $user_project_handles = array_select_keys($handles, $user_project_phids); $subscriber_handles = array_select_keys($handles, $subscriber_phids); @@ -359,6 +385,18 @@ ->setValue($user_project_handles)) ->appendChild( id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/workboardcolumns/') + ->setName('allColumns') + ->setLabel(pht('In All Columns')) + ->setValue($all_column_handles)) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/workboardcolumns/') + ->setName('anyColumns') + ->setLabel(pht('In Any Columns')) + ->setValue($any_column_handles)) + ->appendChild( + id(new AphrontFormTokenizerControl()) ->setDatasource('/typeahead/common/accounts/') ->setName('authors') ->setLabel(pht('Authors')) diff --git a/src/applications/project/query/PhabricatorProjectColumnQuery.php b/src/applications/project/query/PhabricatorProjectColumnQuery.php --- a/src/applications/project/query/PhabricatorProjectColumnQuery.php +++ b/src/applications/project/query/PhabricatorProjectColumnQuery.php @@ -7,6 +7,7 @@ private $phids; private $projectPHIDs; private $statuses; + private $names; public function withIDs(array $ids) { $this->ids = $ids; @@ -28,6 +29,11 @@ return $this; } + public function withNames(array $names) { + $this->names = $names; + return $this; + } + protected function loadPage() { $table = new PhabricatorProjectColumn(); $conn_r = $table->establishConnection('r'); @@ -100,6 +106,13 @@ $this->statuses); } + if ($this->names) { + $where[] = qsprintf( + $conn_r, + 'name IN (%Ls)', + $this->names); + } + $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); diff --git a/src/applications/project/storage/PhabricatorProjectColumn.php b/src/applications/project/storage/PhabricatorProjectColumn.php --- a/src/applications/project/storage/PhabricatorProjectColumn.php +++ b/src/applications/project/storage/PhabricatorProjectColumn.php @@ -51,9 +51,16 @@ public function getDisplayName() { if ($this->isDefaultColumn()) { - return pht('Backlog'); + $name = pht('Backlog'); } - return $this->getName(); + else { + $name = $this->getName(); + } + + return sprintf('%s (%s %s)', + $name, + pht('on board'), + $this->getProject()->getName()); } public function getHeaderColor() { diff --git a/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php b/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php --- a/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php +++ b/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php @@ -37,6 +37,7 @@ $need_task_priority = false; $need_macros = false; $need_legalpad_documents = false; + $need_workboard_columns = false; switch ($this->type) { case 'mainsearch': $need_users = true; @@ -99,6 +100,8 @@ case 'legalpaddocuments': $need_legalpad_documents = true; break; + case 'workboardcolumns': + $need_workboard_columns = true; } $results = array(); @@ -399,6 +402,22 @@ } } + if ($need_workboard_columns) { + $columns = id(new PhabricatorProjectColumnQuery()) + ->setViewer($viewer) + ->execute(); + if ($columns) { + foreach ($columns as $column) { + $results[] = id(new PhabricatorTypeaheadResult()) + ->setName($column->getDisplayName()) + ->setURI('/project/board/'.$column->getProject()->getID().'/') + ->setPHID($column->getPHID()) + ->setIcon('fa-columns bluegrey') + ->setPriorityString($column->getProjectPHID()); + } + } + } + $content = mpull($results, 'getWireFormat'); if ($request->isAjax()) { diff --git a/src/view/form/control/AphrontFormTokenizerControl.php b/src/view/form/control/AphrontFormTokenizerControl.php --- a/src/view/form/control/AphrontFormTokenizerControl.php +++ b/src/view/form/control/AphrontFormTokenizerControl.php @@ -92,6 +92,7 @@ 'allmailable' => pht('Type a user, project, or mailing list...'), 'searchproject' => pht('Type a project name...'), 'projects' => pht('Type a project name...'), + 'workboardcolumns'=> pht('Type a column or project name...'), 'repositories' => pht('Type a repository name...'), 'packages' => pht('Type a package name...'), 'macros' => pht('Type a macro name...'),