diff --git a/resources/builtin/image-200x200.png b/resources/builtin/image-200x200.png new file mode 100644 index 0000000000000000000000000000000000000000..53bc1e785c395c4c5882c1aec3bfc9eac13d4159 GIT binary patch literal 1261 zc%17D@N?(olHy`uVBq!ia0vp^CqS5k2}mkgS)K$^k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+So%F(978H@y}9l0EnO*b;NvP`ZAXzFZmwIQH=1vJekW)1 zev>-?KEC&_E>7OppL)Hy>Z@!AyLgUw=I#s5N9`4Qm6|R}{eR}w}If+ExGS@ z=H})f?G`Uy{PD-r?hPwUC$^pa^{eXewo8oPyXUE?sa-mFzi7{fsAq1=(kd!`>{2@_ zIC1G;{(Uv+>CdD2gu}GkrcU3oe}8>RiOB5Q+FEC4=b!oSC$-JlP;;jsJwj0|T3uZ| z*7T!_Tj1XpyS#lY5;<2FMhLpIgy>CA-aECZQ@y>toj+{qB%x^=-tC^V^lJIOOJ0jt z+s+*X=n{!AGf#ivszff#c7?YYufD# zJvM6{l9HBw{qm*d+D`S2lGee|A9w8BIrFNFjLebHPuHYQv-7^=lJ;NYp}sET@#Dva z>n@$!W|e<`UoZ2euZCvHvGxWA57q@l@UPz(6!Eol$={DVcJ11=cdzXBuAkHGrKP2- ztE+>9gMS+OE%r`)y!+6fG=u5yEC2til?wm4%g(Fn`@2}HW5;>b!X6iv{(q`d7p)

A!*r2F`cXrOC8Pk)l%RG%2HdoS4J>-UDQX=!P{e*aE(t&bD-PcklZ^U*ZzE*Dg}eKKkbkFz zKh86oK7D#}-qY^2KydP;=kmY^-a}p&?-aXs{{_mtoZL|{iO>7^@oe3DtyeA9NZ4G> z`ugwiqUF=|FCBPRVxNnl(00^Y2~Oy7xlpTJG2EWyjCjJP(N2-dyqP`0Ra#BG(>4J`SVZxGn>?;qc^mtdbLg4Fi(_guKoW{uRne)3>Lc^IqmD$sq^gL z3x%!L7VFlJ`(t5YabwNXsF11kZ '2290aeef', 'rsrc/js/application/policy/behavior-policy-control.js' => 'ae45872f', 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '5e9f347c', - 'rsrc/js/application/projects/behavior-project-boards.js' => 'c05fb42a', + 'rsrc/js/application/projects/behavior-project-boards.js' => '48470f95', 'rsrc/js/application/projects/behavior-project-create.js' => '065227cc', 'rsrc/js/application/projects/behavior-reorder-columns.js' => 'e1d25dfb', 'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf', @@ -653,7 +653,7 @@ 'javelin-behavior-phui-profile-menu' => '12884df9', 'javelin-behavior-policy-control' => 'ae45872f', 'javelin-behavior-policy-rule-editor' => '5e9f347c', - 'javelin-behavior-project-boards' => 'c05fb42a', + 'javelin-behavior-project-boards' => '48470f95', 'javelin-behavior-project-create' => '065227cc', 'javelin-behavior-quicksand-blacklist' => '7927a7d3', 'javelin-behavior-recurring-edit' => '5f1c4d5f', @@ -1144,6 +1144,15 @@ 'javelin-dom', 'javelin-workflow', ), + '48470f95' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'javelin-vector', + 'javelin-stratcom', + 'javelin-workflow', + 'phabricator-draggable-list', + ), '49b73b36' => array( 'javelin-behavior', 'javelin-dom', @@ -1772,15 +1781,6 @@ 'javelin-install', 'javelin-dom', ), - 'c05fb42a' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-vector', - 'javelin-stratcom', - 'javelin-workflow', - 'phabricator-draggable-list', - ), 'c1700f6f' => array( 'javelin-install', 'javelin-util', diff --git a/resources/sql/autopatches/20160202.board.1.proxy.sql b/resources/sql/autopatches/20160202.board.1.proxy.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20160202.board.1.proxy.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_project.project_column + ADD proxyPHID VARBINARY(64); 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 @@ -1885,6 +1885,7 @@ 'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php', 'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php', 'PhabricatorClusterConfigOptions' => 'applications/config/option/PhabricatorClusterConfigOptions.php', + 'PhabricatorColumnProxyInterface' => 'applications/project/interface/PhabricatorColumnProxyInterface.php', 'PhabricatorCommentEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorCommentEditEngineExtension.php', 'PhabricatorCommentEditField' => 'applications/transactions/editfield/PhabricatorCommentEditField.php', 'PhabricatorCommentEditType' => 'applications/transactions/edittype/PhabricatorCommentEditType.php', @@ -7260,6 +7261,7 @@ 'PhabricatorDestructibleInterface', 'PhabricatorFulltextInterface', 'PhabricatorConduitResultInterface', + 'PhabricatorColumnProxyInterface', ), 'PhabricatorProjectAddHeraldAction' => 'PhabricatorProjectHeraldAction', 'PhabricatorProjectApplication' => 'PhabricatorApplication', diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php --- a/src/applications/maniphest/editor/ManiphestEditEngine.php +++ b/src/applications/maniphest/editor/ManiphestEditEngine.php @@ -280,10 +280,23 @@ return new Aphront404Response(); } - // If the workboard's project has been removed from the card's project - // list, we are going to remove it from the board completely. + // If the workboard's project and all descendant projects have been removed + // from the card's project list, we are going to remove it from the board + // completely. + + // TODO: If the user did something sneaky and changed a subproject, we'll + // currently leave the card where it was but should really move it to the + // proper new column. + + $descendant_projects = id(new PhabricatorProjectQuery()) + ->setViewer($viewer) + ->withAncestorProjectPHIDs(array($column->getProjectPHID())) + ->execute(); + $board_phids = mpull($descendant_projects, 'getPHID', 'getPHID'); + $board_phids[$column->getProjectPHID()] = $column->getProjectPHID(); + $project_map = array_fuse($task->getProjectPHIDs()); - $remove_card = empty($project_map[$column->getProjectPHID()]); + $remove_card = !array_intersect_key($board_phids, $project_map); $positions = id(new PhabricatorProjectColumnPositionQuery()) ->setViewer($viewer) diff --git a/src/applications/project/controller/PhabricatorProjectBoardViewController.php b/src/applications/project/controller/PhabricatorProjectBoardViewController.php --- a/src/applications/project/controller/PhabricatorProjectBoardViewController.php +++ b/src/applications/project/controller/PhabricatorProjectBoardViewController.php @@ -130,57 +130,28 @@ $task_query = $engine->buildQueryFromSavedQuery($saved); + $select_phids = array($project->getPHID()); + if ($project->getHasSubprojects() || $project->getHasMilestones()) { + $descendants = id(new PhabricatorProjectQuery()) + ->setViewer($viewer) + ->withAncestorProjectPHIDs($select_phids) + ->execute(); + foreach ($descendants as $descendant) { + $select_phids[] = $descendant->getPHID(); + } + } + $tasks = $task_query ->withEdgeLogicPHIDs( PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, - PhabricatorQueryConstraint::OPERATOR_AND, - array($project->getPHID())) + PhabricatorQueryConstraint::OPERATOR_ANCESTOR, + array($select_phids)) ->setOrder(ManiphestTaskQuery::ORDER_PRIORITY) ->setViewer($viewer) ->execute(); $tasks = mpull($tasks, null, 'getPHID'); - if ($tasks) { - $positions = id(new PhabricatorProjectColumnPositionQuery()) - ->setViewer($viewer) - ->withObjectPHIDs(mpull($tasks, 'getPHID')) - ->withColumns($columns) - ->execute(); - $positions = mpull($positions, null, 'getObjectPHID'); - } else { - $positions = array(); - } - - $task_map = array(); - foreach ($tasks as $task) { - $task_phid = $task->getPHID(); - if (empty($positions[$task_phid])) { - // This shouldn't normally be possible because we create positions on - // demand, but we might have raced as an object was removed from the - // board. Just drop the task if we don't have a position for it. - continue; - } - - $position = $positions[$task_phid]; - $task_map[$position->getColumnPHID()][] = $task_phid; - } - - // If we're showing the board in "natural" order, sort columns by their - // column positions. - if ($this->sortKey == PhabricatorProjectColumn::ORDER_NATURAL) { - foreach ($task_map as $column_phid => $task_phids) { - $order = array(); - foreach ($task_phids as $task_phid) { - if (isset($positions[$task_phid])) { - $order[$task_phid] = $positions[$task_phid]->getOrderingKey(); - } else { - $order[$task_phid] = 0; - } - } - asort($order); - $task_map[$column_phid] = array_keys($order); - } - } + $task_map = $this->loadColumnMap($project, $tasks, $columns); $task_can_edit_map = id(new PhabricatorPolicyFilter()) ->setViewer($viewer) @@ -251,6 +222,10 @@ $this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks); foreach ($columns as $column) { + if (!$this->showHidden && $column->isHidden()) { + continue; + } + $task_phids = idx($task_map, $column->getPHID(), array()); $column_tasks = array_select_keys($tasks, $task_phids); @@ -390,14 +365,54 @@ ->setViewer($viewer) ->withProjectPHIDs(array($project->getPHID())); - if (!$this->showHidden) { - $column_query->withStatuses( - array(PhabricatorProjectColumn::STATUS_ACTIVE)); + $columns = $column_query->execute(); + $columns = msort($columns, 'getSequence'); + + // If this project has no real columns, consider the workboard empty and + // return nothing. We don't want to create proxy columns if there's no + // board at all yet. + if (!$columns) { + return array(); } - $columns = $column_query->execute(); - $columns = mpull($columns, null, 'getSequence'); - ksort($columns); + // If this project has subprojects or milestones, remove all columns + // except the backlog, then create any missing columns. + if ($project->getHasSubprojects() || $project->getHasMilestones()) { + foreach ($columns as $key => $column) { + if (!$column->getProxyPHID() && !$column->isDefaultColumn()) { + unset($columns[$key]); + } + } + + $child_projects = id(new PhabricatorProjectQuery()) + ->setViewer($viewer) + ->withParentProjectPHIDs(array($project->getPHID())) + ->withIsMilestone(true) + ->execute(); + $child_projects = mpull($child_projects, null, 'getPHID'); + + $next_sequence = last($columns)->getSequence() + 1; + + $proxy_columns = mpull($columns, null, 'getProxyPHID'); + foreach ($child_projects as $phid => $child) { + if (isset($proxy_columns[$phid])) { + continue; + } + + $new_column = PhabricatorProjectColumn::initializeNewColumn($viewer) + ->attachProject($project) + ->attachProxy($child) + ->setSequence($next_sequence++) + ->setProjectPHID($project->getPHID()) + ->setProxyPHID($phid); + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + $new_column->save(); + unset($unguarded); + + $columns[] = $new_column; + } + } return $columns; } @@ -618,6 +633,12 @@ $column_items = array(); + if ($column->getProxyPHID()) { + $default_phid = $column->getProxyPHID(); + } else { + $default_phid = $column->getProjectPHID(); + } + $column_items[] = id(new PhabricatorActionView()) ->setIcon('fa-plus') ->setName(pht('Create Task...')) @@ -626,6 +647,7 @@ ->setMetadata( array( 'columnPHID' => $column->getPHID(), + 'projectPHID' => $default_phid, )); $batch_edit_uri = $request->getRequestURI(); @@ -774,6 +796,10 @@ } } + // TODO: Tailor this UI if the project is already a parent project. We + // should not offer options for creating a parent project workboard, since + // they can't have their own columns. + $new_selector = id(new AphrontFormRadioButtonControl()) ->setLabel(pht('Columns')) ->setName('initialize-type') @@ -830,4 +856,188 @@ ->addCancelButton($profile_uri); } + private function loadColumnMap( + PhabricatorProject $board_project, + array $tasks, + array $columns) { + + if (!$tasks) { + return array(); + } + + $viewer = $this->getViewer(); + + $positions = id(new PhabricatorProjectColumnPositionQuery()) + ->setViewer($viewer) + ->withObjectPHIDs(mpull($tasks, 'getPHID')) + ->withColumns($columns) + ->execute(); + $positions = mpull($positions, null, 'getObjectPHID'); + + // First, put the tasks in the correct global order so we don't have to + // worry about it later. + if ($this->sortKey == PhabricatorProjectColumn::ORDER_NATURAL) { + $sort_map = array(); + foreach ($tasks as $phid => $task) { + $position = idx($positions, $phid); + if ($position) { + $sort_map[$phid] = $position->getOrderingKey(); + } else { + $sort_map[$phid] = 0; + } + } + asort($sort_map); + $tasks = array_select_keys($tasks, array_keys($sort_map)); + } + + // Find all the columns which are proxies for other objects. + $proxy_map = array(); + foreach ($columns as $column) { + $proxy_phid = $column->getProxyPHID(); + if ($proxy_phid) { + $proxy_map[$proxy_phid] = $column->getPHID(); + } + } + + // If we have proxies, we need to force cards into the correct proxy + // columns. + if ($proxy_map) { + $all_projects = array(); + foreach ($tasks as $task) { + foreach ($task->getProjectPHIDs() as $project_phid) { + $all_projects[$project_phid] = $project_phid; + } + } + + if ($all_projects) { + $projects = id(new PhabricatorProjectQuery()) + ->setViewer($viewer) + ->withPHIDs($all_projects) + ->execute(); + $projects = mpull($projects, null, 'getPHID'); + } else { + $projects = array(); + } + + // Build a map from every project that any task is tagged with to the + // ancestor project which has a column on this board, if one exists. + $ancestor_map = array(); + foreach ($projects as $phid => $project) { + if (isset($proxy_map[$phid])) { + $ancestor_map[$phid] = $proxy_map[$phid]; + } else { + $seen = array($phid); + foreach ($project->getAncestorProjects() as $ancestor) { + $ancestor_phid = $ancestor->getPHID(); + $seen[] = $ancestor_phid; + if (isset($proxy_map[$ancestor_phid])) { + foreach ($seen as $project_phid) { + $ancestor_map[$project_phid] = $proxy_map[$ancestor_phid]; + } + } + } + } + } + } + + $column_map = mpull($columns, null, 'getPHID'); + + foreach ($columns as $column) { + if ($column->isDefaultColumn()) { + $default_phid = $column->getPHID(); + break; + } + } + + $rem_positions = array(); + $add_positions = array(); + + $task_map = array(); + foreach ($tasks as $task_phid => $task) { + // First, check for a tags that have corresponding proxy columns, + if ($proxy_map) { + $proxy_hits = array(); + foreach ($task->getProjectPHIDs() as $project_phid) { + if (isset($ancestor_map[$project_phid])) { + $task_map[$ancestor_map[$project_phid]][] = $task_phid; + $proxy_hits[] = $ancestor_map[$project_phid]; + + // NOTE: For now, only permit tasks to appear in one column. We + // may change this soon. + break; + } + } + if ($proxy_hits) { + $proxy_hits = array_fuse($proxy_hits); + + $task_positions = array(); + + $position = idx($positions, $task_phid); + if ($position) { + $task_positions[] = $position; + } + + foreach ($task_positions as $task_position) { + $column_phid = $task_position->getColumnPHID(); + + if (isset($proxy_hits[$column_phid])) { + unset($proxy_hits[$column_phid]); + continue; + } + + $rem_positions[] = $task_position; + } + + foreach ($proxy_hits as $proxy_column_phid) { + $add_positions[] = id(new PhabricatorProjectColumnPosition()) + ->setBoardPHID($board_project->getPHID()) + ->setColumnPHID($proxy_column_phid) + ->setObjectPHID($task_phid) + ->setSequence(0); + } + + continue; + } + } + + // Next, check for existing positions on the board. + $position = idx($positions, $task_phid); + if ($position) { + $column_phid = $position->getColumnPHID(); + + // We only use an exiting position if the column is valid. For example, + // if a task was in a column but the project was converted into a + // parent project, the task gets kicked back to the backlog. + if (isset($column_map[$column_phid])) { + $task_map[$column_phid][] = $task_phid; + continue; + } else { + $rem_positions[] = $position; + } + } + + // If we made it here, we didn't find a valid position, so we're putting + // it in the backlog and writing a new position row. + + $task_map[$default_phid][] = $task_phid; + $add_positions[] = id(new PhabricatorProjectColumnPosition()) + ->setBoardPHID($board_project->getPHID()) + ->setColumnPHID($default_phid) + ->setObjectPHID($task_phid) + ->setSequence(0); + } + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + foreach ($rem_positions as $position) { + $position->delete(); + } + foreach ($add_positions as $position) { + $position->save(); + } + unset($unguarded); + + return $task_map; + } + + } diff --git a/src/applications/project/controller/PhabricatorProjectMoveController.php b/src/applications/project/controller/PhabricatorProjectMoveController.php --- a/src/applications/project/controller/PhabricatorProjectMoveController.php +++ b/src/applications/project/controller/PhabricatorProjectMoveController.php @@ -134,7 +134,33 @@ ->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY) ->setNewValue($sub); } - } + } + + $proxy = $column->getProxy(); + if ($proxy) { + // We're moving the task into a subproject or milestone column, so add + // the subproject or milestone. + $add_projects = array($proxy->getPHID()); + } else if ($project->getHasSubprojects() || $project->getHasMilestones()) { + // We're moving the task into the "Backlog" column on the parent project, + // so add the parent explicitly. This gets rid of any subproject or + // milestone tags. + $add_projects = array($project->getPHID()); + } else { + $add_projects = array(); + } + + if ($add_projects) { + $project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; + + $xactions[] = id(new ManiphestTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) + ->setMetadataValue('edge:type', $project_type) + ->setNewValue( + array( + '+' => array_fuse($add_projects), + )); + } $editor = id(new ManiphestTransactionEditor()) ->setActor($viewer) @@ -152,6 +178,18 @@ ->executeOne(); } + // Reload the object so it reflects edits which have been applied. + $object = id(new ManiphestTaskQuery()) + ->setViewer($viewer) + ->withPHIDs(array($object_phid)) + ->needProjectPHIDs(true) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + $card = id(new ProjectBoardTaskCard()) ->setViewer($viewer) ->setTask($object) @@ -164,6 +202,6 @@ return id(new AphrontAjaxResponse())->setContent( array('task' => $card)); - } + } } diff --git a/src/applications/project/interface/PhabricatorColumnProxyInterface.php b/src/applications/project/interface/PhabricatorColumnProxyInterface.php new file mode 100644 --- /dev/null +++ b/src/applications/project/interface/PhabricatorColumnProxyInterface.php @@ -0,0 +1,7 @@ +attachProject($project); } + $proxy_phids = array_filter(mpull($page, 'getProjectPHID')); + + return $page; + } + + protected function didFilterPage(array $page) { + $proxy_phids = array(); + foreach ($page as $column) { + $proxy_phid = $column->getProxyPHID(); + if ($proxy_phid !== null) { + $proxy_phids[$proxy_phid] = $proxy_phid; + } + } + + if ($proxy_phids) { + $proxies = id(new PhabricatorObjectQuery()) + ->setParentQuery($this) + ->setViewer($this->getViewer()) + ->withPHIDs($proxy_phids) + ->execute(); + $proxies = mpull($proxies, null, 'getPHID'); + } else { + $proxies = array(); + } + + foreach ($page as $key => $column) { + $proxy_phid = $column->getProxyPHID(); + + if ($proxy_phid !== null) { + $proxy = idx($proxies, $proxy_phid); + + // Only attach valid proxies, so we don't end up getting surprsied if + // an install somehow gets junk into their database. + if (!($proxy instanceof PhabricatorColumnProxyInterface)) { + $proxy = null; + } + + if (!$proxy) { + $this->didRejectResult($column); + unset($page[$key]); + continue; + } + } else { + $proxy = null; + } + + $column->attachProxy($proxy); + } + return $page; } diff --git a/src/applications/project/storage/PhabricatorProject.php b/src/applications/project/storage/PhabricatorProject.php --- a/src/applications/project/storage/PhabricatorProject.php +++ b/src/applications/project/storage/PhabricatorProject.php @@ -9,7 +9,8 @@ PhabricatorCustomFieldInterface, PhabricatorDestructibleInterface, PhabricatorFulltextInterface, - PhabricatorConduitResultInterface { + PhabricatorConduitResultInterface, + PhabricatorColumnProxyInterface { protected $name; protected $status = PhabricatorProjectStatus::STATUS_ACTIVE; @@ -663,4 +664,17 @@ ); } + +/* -( PhabricatorColumnProxyInterface )------------------------------------ */ + + + public function getProxyColumnName() { + return $this->getName(); + } + + public function getProxyColumnIcon() { + return $this->getDisplayIconIcon(); + } + + } 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 @@ -17,10 +17,12 @@ protected $name; protected $status; protected $projectPHID; + protected $proxyPHID; protected $sequence; protected $properties = array(); private $project = self::ATTACHABLE; + private $proxy = self::ATTACHABLE; public static function initializeNewColumn(PhabricatorUser $user) { return id(new PhabricatorProjectColumn()) @@ -38,6 +40,7 @@ 'name' => 'text255', 'status' => 'uint32', 'sequence' => 'uint32', + 'proxyPHID' => 'phid?', ), self::CONFIG_KEY_SCHEMA => array( 'key_status' => array( @@ -46,6 +49,10 @@ 'key_sequence' => array( 'columns' => array('projectPHID', 'sequence'), ), + 'key_proxy' => array( + 'columns' => array('projectPHID', 'proxyPHID'), + 'unique' => true, + ), ), ) + parent::getConfiguration(); } @@ -64,6 +71,15 @@ return $this->assertAttached($this->project); } + public function attachProxy($proxy) { + $this->proxy = $proxy; + return $this; + } + + public function getProxy() { + return $this->assertAttached($this->proxy); + } + public function isDefaultColumn() { return (bool)$this->getProperty('isDefault'); } @@ -73,6 +89,11 @@ } public function getDisplayName() { + $proxy = $this->getProxy(); + if ($proxy) { + return $proxy->getProxyColumnName(); + } + $name = $this->getName(); if (strlen($name)) { return $name; @@ -97,10 +118,13 @@ } public function getHeaderIcon() { - $icon = null; + $proxy = $this->getProxy(); + if ($proxy) { + return $proxy->getProxyColumnIcon(); + } if ($this->isHidden()) { - $icon = 'fa-eye-slash'; + return 'fa-eye-slash'; } return null; diff --git a/src/view/phui/PHUIWorkpanelView.php b/src/view/phui/PHUIWorkpanelView.php --- a/src/view/phui/PHUIWorkpanelView.php +++ b/src/view/phui/PHUIWorkpanelView.php @@ -10,8 +10,8 @@ private $headerTag; private $headerIcon; - public function setHeaderIcon(PHUIIconView $header_icon) { - $this->headerIcon = $header_icon; + public function setHeaderIcon($icon) { + $this->headerIcon = $icon; return $this; } diff --git a/webroot/rsrc/js/application/projects/behavior-project-boards.js b/webroot/rsrc/js/application/projects/behavior-project-boards.js --- a/webroot/rsrc/js/application/projects/behavior-project-boards.js +++ b/webroot/rsrc/js/application/projects/behavior-project-boards.js @@ -280,13 +280,16 @@ // close the dropdown, but don't want to follow the link. e.prevent(); - var column_phid = e.getNodeData('column-add-task').columnPHID; + var column_data = e.getNodeData('column-add-task'); + var column_phid = column_data.columnPHID; + var request_data = { responseType: 'card', columnPHID: column_phid, - projects: statics.projectPHID, + projects: column_data.projectPHID, order: statics.order }; + var cols = getcolumns(); var ii; var column;