diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ea745663b1..9e11af068f 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2475,6 +2475,7 @@ phutil_register_library_map(array( 'PonderVote' => 'applications/ponder/constants/PonderVote.php', 'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php', 'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php', + 'ProjectBoardTaskCard' => 'applications/project/view/ProjectBoardTaskCard.php', 'ProjectCapabilityCreateProjects' => 'applications/project/capability/ProjectCapabilityCreateProjects.php', 'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php', 'PublishFragmentBuildStepImplementation' => 'applications/harbormaster/step/PublishFragmentBuildStepImplementation.php', diff --git a/src/applications/maniphest/controller/ManiphestController.php b/src/applications/maniphest/controller/ManiphestController.php index ecd87faed8..7bc4f99a1f 100644 --- a/src/applications/maniphest/controller/ManiphestController.php +++ b/src/applications/maniphest/controller/ManiphestController.php @@ -66,5 +66,4 @@ abstract class ManiphestController extends PhabricatorController { return $view; } - } diff --git a/src/applications/maniphest/controller/ManiphestTaskEditController.php b/src/applications/maniphest/controller/ManiphestTaskEditController.php index 31d6798f9c..a4ca313d7a 100644 --- a/src/applications/maniphest/controller/ManiphestTaskEditController.php +++ b/src/applications/maniphest/controller/ManiphestTaskEditController.php @@ -12,6 +12,7 @@ final class ManiphestTaskEditController extends ManiphestController { $request = $this->getRequest(); $user = $request->getUser(); + $response_type = $request->getStr('response_type', 'task'); $can_edit_assign = $this->hasApplicationCapability( ManiphestCapabilityEditAssign::CAPABILITY); @@ -335,9 +336,30 @@ final class ManiphestTaskEditController extends ManiphestController { } if ($request->isAjax()) { + switch ($response_type) { + case 'card': + $owner = null; + if ($task->getOwnerPHID()) { + $owner = id(new PhabricatorHandleQuery()) + ->setViewer($user) + ->withPHIDs(array($task->getOwnerPHID())) + ->executeOne(); + } + $tasks = id(new ProjectBoardTaskCard()) + ->setViewer($user) + ->setTask($task) + ->setOwner($owner) + ->setCanEdit(true) + ->getItem(); + break; + case 'task': + default: + $tasks = $this->renderSingleTask($task); + break; + } return id(new AphrontAjaxResponse())->setContent( array( - 'tasks' => $this->renderSingleTask($task), + 'tasks' => $tasks, )); } @@ -463,7 +485,8 @@ final class ManiphestTaskEditController extends ManiphestController { $form = new AphrontFormView(); $form ->setUser($user) - ->addHiddenInput('template', $template_id); + ->addHiddenInput('template', $template_id) + ->addHiddenInput('response_type', $response_type); if ($parent_task) { $form diff --git a/src/applications/project/controller/PhabricatorProjectBoardController.php b/src/applications/project/controller/PhabricatorProjectBoardController.php index f0e1591f43..9365014fe0 100644 --- a/src/applications/project/controller/PhabricatorProjectBoardController.php +++ b/src/applications/project/controller/PhabricatorProjectBoardController.php @@ -55,11 +55,12 @@ final class PhabricatorProjectBoardController ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY) ->execute(); $tasks = mpull($tasks, null, 'getPHID'); + $task_phids = array_keys($tasks); - if ($tasks) { + if ($task_phids) { $edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_COLUMN; $edge_query = id(new PhabricatorEdgeQuery()) - ->withSourcePHIDs(mpull($tasks, 'getPHID')) + ->withSourcePHIDs($task_phids) ->withEdgeTypes(array($edge_type)) ->withDestinationPHIDs(mpull($columns, 'getPHID')); $edge_query->execute(); @@ -77,6 +78,11 @@ final class PhabricatorProjectBoardController $task_map[$column_phid][] = $task_phid; } + $task_can_edit_map = id(new PhabricatorPolicyFilter()) + ->setViewer($viewer) + ->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT)) + ->apply($tasks); + $board_id = celerity_generate_unique_node_id(); $board = id(new PHUIWorkboardView()) @@ -113,7 +119,17 @@ final class PhabricatorProjectBoardController )); $task_phids = idx($task_map, $column->getPHID(), array()); foreach (array_select_keys($tasks, $task_phids) as $task) { - $cards->addItem($this->renderTaskCard($task)); + $owner = null; + if ($task->getOwnerPHID()) { + $owner = $this->handles[$task->getOwnerPHID()]; + } + $can_edit = idx($task_can_edit_map, $task->getPHID(), false); + $cards->addItem(id(new ProjectBoardTaskCard()) + ->setViewer($viewer) + ->setTask($task) + ->setOwner($owner) + ->setCanEdit($can_edit) + ->getItem()); } $panel->setCards($cards); @@ -183,44 +199,4 @@ final class PhabricatorProjectBoardController )); } - private function renderTaskCard(ManiphestTask $task) { - $request = $this->getRequest(); - $viewer = $request->getUser(); - $handles = $this->handles; - - $color_map = ManiphestTaskPriority::getColorMap(); - $bar_color = idx($color_map, $task->getPriority(), 'grey'); - - // TODO: Batch this earlier on. - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $task, - PhabricatorPolicyCapability::CAN_EDIT); - - $card = id(new PHUIObjectItemView()) - ->setObjectName('T'.$task->getID()) - ->setHeader($task->getTitle()) - ->setGrippable($can_edit) - ->setHref('/T'.$task->getID()) - ->addSigil('project-card') - ->setMetadata( - array( - 'objectPHID' => $task->getPHID(), - )) - ->addAction( - id(new PHUIListItemView()) - ->setName(pht('Edit')) - ->setIcon('edit') - ->setHref('/maniphest/task/edit/'.$task->getID().'/') - ->setWorkflow(true)) - ->setBarColor($bar_color); - - if ($task->getOwnerPHID()) { - $owner = $handles[$task->getOwnerPHID()]; - $card->addAttribute($owner->renderLink()); - } - - return $card; - } - } diff --git a/src/applications/project/view/ProjectBoardTaskCard.php b/src/applications/project/view/ProjectBoardTaskCard.php new file mode 100644 index 0000000000..3d6c7a88a5 --- /dev/null +++ b/src/applications/project/view/ProjectBoardTaskCard.php @@ -0,0 +1,75 @@ +viewer = $viewer; + return $this; + } + public function getViewer() { + return $this->viewer; + } + + public function setTask(ManiphestTask $task) { + $this->task = $task; + return $this; + } + public function getTask() { + return $this->task; + } + + public function setOwner(PhabricatorObjectHandle $owner = null) { + $this->owner = $owner; + return $this; + } + public function getOwner() { + return $this->owner; + } + + public function setCanEdit($can_edit) { + $this->canEdit = $can_edit; + return $this; + } + public function getCanEdit() { + return $this->canEdit; + } + + public function getItem() { + $task = $this->getTask(); + $owner = $this->getOwner(); + $can_edit = $this->getCanEdit(); + + $color_map = ManiphestTaskPriority::getColorMap(); + $bar_color = idx($color_map, $task->getPriority(), 'grey'); + + $card = id(new PHUIObjectItemView()) + ->setObjectName('T'.$task->getID()) + ->setHeader($task->getTitle()) + ->setGrippable($can_edit) + ->setHref('/T'.$task->getID()) + ->addSigil('project-card') + ->setMetadata( + array( + 'objectPHID' => $task->getPHID(), + )) + ->addAction( + id(new PHUIListItemView()) + ->setName(pht('Edit')) + ->setIcon('edit') + ->addSigil('edit-project-card') + ->setHref('/maniphest/task/edit/'.$task->getID().'/')) + ->setBarColor($bar_color); + + if ($owner) { + $card->addAttribute($owner->renderLink()); + } + + return $card; + } + +} diff --git a/webroot/rsrc/js/application/projects/behavior-project-boards.js b/webroot/rsrc/js/application/projects/behavior-project-boards.js index 55a1e02700..3dde45eec6 100644 --- a/webroot/rsrc/js/application/projects/behavior-project-boards.js +++ b/webroot/rsrc/js/application/projects/behavior-project-boards.js @@ -66,4 +66,21 @@ JX.behavior('project-boards', function(config) { lists[ii].setGroup(lists); } + var onedit = function(card, r) { + var nodes = JX.$H(r.tasks).getFragment().firstChild; + var new_card = JX.$H(r.tasks); + JX.DOM.replace(card, new_card); + }; + + JX.Stratcom.listen( + 'click', + ['edit-project-card'], + function(e) { + e.kill(); + var card = e.getNode('project-card'); + new JX.Workflow(e.getNode('tag:a').href, { 'response_type' : 'card' }) + .setHandler(JX.bind(null, onedit, card)) + .start(); + }); + });