diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4056,6 +4056,7 @@ 'PhabricatorProjectColumnHideController' => 'applications/project/controller/PhabricatorProjectColumnHideController.php', 'PhabricatorProjectColumnNaturalOrder' => 'applications/project/order/PhabricatorProjectColumnNaturalOrder.php', 'PhabricatorProjectColumnOrder' => 'applications/project/order/PhabricatorProjectColumnOrder.php', + 'PhabricatorProjectColumnOwnerOrder' => 'applications/project/order/PhabricatorProjectColumnOwnerOrder.php', 'PhabricatorProjectColumnPHIDType' => 'applications/project/phid/PhabricatorProjectColumnPHIDType.php', 'PhabricatorProjectColumnPosition' => 'applications/project/storage/PhabricatorProjectColumnPosition.php', 'PhabricatorProjectColumnPositionQuery' => 'applications/project/query/PhabricatorProjectColumnPositionQuery.php', @@ -10140,6 +10141,7 @@ 'PhabricatorProjectColumnHideController' => 'PhabricatorProjectBoardController', 'PhabricatorProjectColumnNaturalOrder' => 'PhabricatorProjectColumnOrder', 'PhabricatorProjectColumnOrder' => 'Phobject', + 'PhabricatorProjectColumnOwnerOrder' => 'PhabricatorProjectColumnOrder', 'PhabricatorProjectColumnPHIDType' => 'PhabricatorPHIDType', 'PhabricatorProjectColumnPosition' => array( 'PhabricatorProjectDAO', diff --git a/src/applications/project/order/PhabricatorProjectColumnOwnerOrder.php b/src/applications/project/order/PhabricatorProjectColumnOwnerOrder.php new file mode 100644 --- /dev/null +++ b/src/applications/project/order/PhabricatorProjectColumnOwnerOrder.php @@ -0,0 +1,163 @@ +newHeaderKeyForOwnerPHID($object->getOwnerPHID()); + } + + private function newHeaderKeyForOwnerPHID($owner_phid) { + if ($owner_phid === null) { + $owner_phid = ''; + } + + return sprintf('owner(%s)', $owner_phid); + } + + protected function newSortVectorsForObjects(array $objects) { + $owner_phids = mpull($objects, null, 'getOwnerPHID'); + $owner_phids = array_keys($owner_phids); + $owner_phids = array_filter($owner_phids); + + if ($owner_phids) { + $owner_users = id(new PhabricatorPeopleQuery()) + ->setViewer($this->getViewer()) + ->withPHIDs($owner_phids) + ->execute(); + $owner_users = mpull($owner_users, null, 'getPHID'); + } else { + $owner_users = array(); + } + + $vectors = array(); + foreach ($objects as $vector_key => $object) { + $owner_phid = $object->getOwnerPHID(); + if (!$owner_phid) { + $vector = $this->newSortVectorForUnowned(); + } else { + $owner = idx($owner_users, $owner_phid); + if ($owner) { + $vector = $this->newSortVectorForOwner($owner); + } else { + $vector = $this->newSortVectorForOwnerPHID($owner_phid); + } + } + + $vectors[$vector_key] = $vector; + } + + return $vectors; + } + + private function newSortVectorForUnowned() { + // Always put unasssigned tasks at the top. + return array( + 0, + ); + } + + private function newSortVectorForOwner(PhabricatorUser $user) { + // Put assigned tasks with a valid owner after "Unassigned", but above + // assigned tasks with an invalid owner. Sort these tasks by the owner's + // username. + return array( + 1, + $user->getUsername(), + ); + } + + private function newSortVectorForOwnerPHID($owner_phid) { + // If we have tasks with a nonempty owner but can't load the associated + // "User" object, move them to the bottom. We can only sort these by the + // PHID. + return array( + 2, + $owner_phid, + ); + } + + protected function newHeadersForObjects(array $objects) { + $owner_phids = mpull($objects, null, 'getOwnerPHID'); + $owner_phids = array_keys($owner_phids); + $owner_phids = array_filter($owner_phids); + + if ($owner_phids) { + $owner_users = id(new PhabricatorPeopleQuery()) + ->setViewer($this->getViewer()) + ->withPHIDs($owner_phids) + ->execute(); + $owner_users = mpull($owner_users, null, 'getPHID'); + } else { + $owner_users = array(); + } + + array_unshift($owner_phids, null); + + $headers = array(); + foreach ($owner_phids as $owner_phid) { + $header_key = $this->newHeaderKeyForOwnerPHID($owner_phid); + + if ($owner_phid === null) { + $owner = null; + $sort_vector = $this->newSortVectorForUnowned(); + $owner_name = pht('Not Assigned'); + } else { + $owner = idx($owner_users, $owner_phid); + if ($owner) { + $sort_vector = $this->newSortVectorForOwner($owner); + $owner_name = $owner->getUsername(); + } else { + $sort_vector = $this->newSortVectorForOwnerPHID($owner_phid); + $owner_name = pht('Unknown User ("%s")', $owner_phid); + } + } + + $owner_icon = 'fa-user'; + $owner_color = 'bluegrey'; + + $icon_view = id(new PHUIIconView()) + ->setIcon($owner_icon, $owner_color); + + $header = $this->newHeader() + ->setHeaderKey($header_key) + ->setSortVector($sort_vector) + ->setName($owner_name) + ->setIcon($icon_view) + ->setEditProperties( + array( + 'value' => $owner_phid, + )); + + $headers[] = $header; + } + + return $headers; + } + + protected function newColumnTransactions($object, array $header) { + $new_owner = idx($header, 'value'); + + if ($object->getOwnerPHID() === $new_owner) { + return null; + } + + $xactions = array(); + $xactions[] = $this->newTransaction($object) + ->setTransactionType(ManiphestTaskOwnerTransaction::TRANSACTIONTYPE) + ->setNewValue($new_owner); + + return $xactions; + } + +}