Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F73213
D7374.diff
All Users
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
D7374.diff
View Options
diff --git a/resources/sql/patches/20131020.col1.sql b/resources/sql/patches/20131020.col1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/patches/20131020.col1.sql
@@ -0,0 +1,9 @@
+CREATE TABLE {$NAMESPACE}_project.project_column (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ name VARCHAR(255) NOT NULL,
+ sequence INT UNSIGNED NOT NULL,
+ projectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ UNIQUE KEY `key_sequence` (projectPHID, sequence),
+ UNIQUE KEY `key_phid` (phid)
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -3966,7 +3966,7 @@
),
'phui-workboard-view-css' =>
array(
- 'uri' => '/res/628679e5/rsrc/css/phui/phui-workboard-view.css',
+ 'uri' => '/res/445c7c7e/rsrc/css/phui/phui-workboard-view.css',
'type' => 'css',
'requires' =>
array(
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
@@ -1515,15 +1515,22 @@
'PhabricatorPolicyTestObject' => 'applications/policy/__tests__/PhabricatorPolicyTestObject.php',
'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
+ 'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php',
+ 'PhabricatorProjectColumn' => 'applications/project/storage/PhabricatorProjectColumn.php',
+ 'PhabricatorProjectColumnQuery' => 'applications/project/query/PhabricatorProjectColumnQuery.php',
'PhabricatorProjectConstants' => 'applications/project/constants/PhabricatorProjectConstants.php',
'PhabricatorProjectController' => 'applications/project/controller/PhabricatorProjectController.php',
'PhabricatorProjectCreateController' => 'applications/project/controller/PhabricatorProjectCreateController.php',
+ 'PhabricatorProjectCustomFieldNumericIndex' => 'applications/project/storage/PhabricatorProjectCustomFieldNumericIndex.php',
+ 'PhabricatorProjectCustomFieldStorage' => 'applications/project/storage/PhabricatorProjectCustomFieldStorage.php',
+ 'PhabricatorProjectCustomFieldStringIndex' => 'applications/project/storage/PhabricatorProjectCustomFieldStringIndex.php',
'PhabricatorProjectDAO' => 'applications/project/storage/PhabricatorProjectDAO.php',
'PhabricatorProjectEditor' => 'applications/project/editor/PhabricatorProjectEditor.php',
'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php',
'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
'PhabricatorProjectMembersEditController' => 'applications/project/controller/PhabricatorProjectMembersEditController.php',
'PhabricatorProjectNameCollisionException' => 'applications/project/exception/PhabricatorProjectNameCollisionException.php',
+ 'PhabricatorProjectPHIDTypeColumn' => 'applications/project/phid/PhabricatorProjectPHIDTypeColumn.php',
'PhabricatorProjectPHIDTypeProject' => 'applications/project/phid/PhabricatorProjectPHIDTypeProject.php',
'PhabricatorProjectProfile' => 'applications/project/storage/PhabricatorProjectProfile.php',
'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
@@ -3733,8 +3740,18 @@
0 => 'PhabricatorProjectDAO',
1 => 'PhabricatorPolicyInterface',
),
+ 'PhabricatorProjectBoardController' => 'PhabricatorProjectController',
+ 'PhabricatorProjectColumn' =>
+ array(
+ 0 => 'PhabricatorProjectDAO',
+ 1 => 'PhabricatorPolicyInterface',
+ ),
+ 'PhabricatorProjectColumnQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
+ 'PhabricatorProjectCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
+ 'PhabricatorProjectCustomFieldStorage' => 'PhabricatorCustomFieldStorage',
+ 'PhabricatorProjectCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectEditor' => 'PhabricatorEditor',
'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
@@ -3745,6 +3762,7 @@
),
'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController',
'PhabricatorProjectNameCollisionException' => 'Exception',
+ 'PhabricatorProjectPHIDTypeColumn' => 'PhabricatorPHIDType',
'PhabricatorProjectPHIDTypeProject' => 'PhabricatorPHIDType',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
diff --git a/src/applications/maniphest/controller/ManiphestTaskEditController.php b/src/applications/maniphest/controller/ManiphestTaskEditController.php
--- a/src/applications/maniphest/controller/ManiphestTaskEditController.php
+++ b/src/applications/maniphest/controller/ManiphestTaskEditController.php
@@ -609,7 +609,7 @@
->setPreviewURI($this->getApplicationURI('task/descriptionpreview/'));
if ($task->getID()) {
- $page_objects = array( $task->getPHID() );
+ $page_objects = array($task->getPHID());
} else {
$page_objects = array();
}
diff --git a/src/applications/project/application/PhabricatorApplicationProject.php b/src/applications/project/application/PhabricatorApplicationProject.php
--- a/src/applications/project/application/PhabricatorApplicationProject.php
+++ b/src/applications/project/application/PhabricatorApplicationProject.php
@@ -45,6 +45,7 @@
'picture/(?P<id>[1-9]\d*)/' =>
'PhabricatorProjectProfilePictureController',
'create/' => 'PhabricatorProjectCreateController',
+ 'board/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectBoardController',
'update/(?P<id>[1-9]\d*)/(?P<action>[^/]+)/'
=> 'PhabricatorProjectUpdateController',
),
diff --git a/src/applications/project/controller/PhabricatorProjectBoardController.php b/src/applications/project/controller/PhabricatorProjectBoardController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/controller/PhabricatorProjectBoardController.php
@@ -0,0 +1,152 @@
+<?php
+
+final class PhabricatorProjectBoardController
+ extends PhabricatorProjectController {
+
+ private $id;
+
+ public function shouldAllowPublic() {
+ return true;
+ }
+
+ public function willProcessRequest(array $data) {
+ $this->id = $data['id'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ $project = id(new PhabricatorProjectQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->executeOne();
+ if (!$project) {
+ return new Aphront404Response();
+ }
+
+ $columns = id(new PhabricatorProjectColumnQuery())
+ ->setViewer($viewer)
+ ->withProjectPHIDs(array($project->getPHID()))
+ ->execute();
+
+ // TODO: Completely making this part up.
+ $columns[] = id(new PhabricatorProjectColumn())
+ ->setName('Backlog')
+ ->setPHID(0)
+ ->setSequence(0);
+
+ $columns[] = id(new PhabricatorProjectColumn())
+ ->setName('Assigned')
+ ->setPHID(1)
+ ->setSequence(1);
+
+ $columns[] = id(new PhabricatorProjectColumn())
+ ->setName('In Progress')
+ ->setPHID(2)
+ ->setSequence(2);
+
+ $columns[] = id(new PhabricatorProjectColumn())
+ ->setName('Completed')
+ ->setPHID(3)
+ ->setSequence(3);
+
+ msort($columns, 'getSequence');
+
+ $tasks = id(new ManiphestTaskQuery())
+ ->setViewer($viewer)
+ ->withAllProjects(array($project->getPHID()))
+ ->withStatus(ManiphestTaskQuery::STATUS_OPEN)
+ ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY)
+ ->execute();
+ $tasks = mpull($tasks, null, 'getPHID');
+
+ // TODO: This is also made up.
+ $task_map = array();
+ foreach ($tasks as $task) {
+ $task_map[mt_rand(0, 3)][] = $task->getPHID();
+ }
+
+ $board = id(new PHUIWorkboardView())
+ ->setUser($viewer);
+
+ foreach ($columns as $column) {
+ $panel = id(new PHUIWorkpanelView())
+ ->setHeader($column->getName());
+
+ $cards = id(new PHUIObjectItemListView())
+ ->setUser($viewer)
+ ->setCards(true)
+ ->setFlush(true);
+ $task_phids = idx($task_map, $column->getPHID(), array());
+ foreach (array_select_keys($tasks, $task_phids) as $task) {
+ $cards->addItem($this->renderTaskCard($task));
+ }
+ $panel->setCards($cards);
+
+ $board->addPanel($panel);
+ }
+
+ $crumbs = $this->buildApplicationCrumbs();
+
+ $actions = id(new PhabricatorActionListView())
+ ->setUser($viewer)
+ ->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Add Column/Milestone/Sprint'))
+ ->setHref($this->getApplicationURI('board/'.$this->id.'/edit/'))
+ ->setIcon('create'));
+
+ $plist = id(new PHUIPropertyListView());
+ // TODO: Need this to get actions to render.
+ $plist->addProperty(pht('Ignore'), pht('This Property'));
+ $plist->setActionList($actions);
+
+ $header = id(new PHUIObjectBoxView())
+ ->setHeaderText($project->getName())
+ ->addPropertyList($plist);
+
+ $board_box = id(new PHUIBoxView())
+ ->appendChild($board)
+ ->addMargin(PHUI::MARGIN_LARGE);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $header,
+ $board_box,
+ ),
+ array(
+ 'title' => pht('Board'),
+ 'device' => true,
+ ));
+ }
+
+ private function renderTaskCard(ManiphestTask $task) {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ $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);
+
+ return id(new PHUIObjectItemView())
+ ->setObjectName('T'.$task->getID())
+ ->setHeader($task->getTitle())
+ ->setGrippable($can_edit)
+ ->setHref('/T'.$task->getID())
+ ->addAction(
+ id(new PHUIListItemView())
+ ->setName(pht('Edit'))
+ ->setIcon('edit')
+ ->setHref('/maniphest/task/edit/'.$task->getID().'/')
+ ->setWorkflow(true))
+ ->setBarColor($bar_color);
+ }
+
+}
diff --git a/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php b/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/phid/PhabricatorProjectPHIDTypeColumn.php
@@ -0,0 +1,39 @@
+<?php
+
+final class PhabricatorProjectPHIDTypeColumn extends PhabricatorPHIDType {
+
+ const TYPECONST = 'PCOL';
+
+ public function getTypeConstant() {
+ return self::TYPECONST;
+ }
+
+ public function getTypeName() {
+ return pht('Project Column');
+ }
+
+ public function newObject() {
+ return new PhabricatorProjectColumn();
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new PhabricatorProjectColumnQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $column = $objects[$phid];
+
+ $handle->setName($column->getName());
+ }
+ }
+
+}
diff --git a/src/applications/project/query/PhabricatorProjectColumnQuery.php b/src/applications/project/query/PhabricatorProjectColumnQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/query/PhabricatorProjectColumnQuery.php
@@ -0,0 +1,99 @@
+<?php
+
+final class PhabricatorProjectColumnQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $projectPHIDs;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withProjectPHIDs(array $project_phids) {
+ $this->projectPHIDs = $project_phids;
+ return $this;
+ }
+
+ protected function loadPage() {
+ $table = new PhabricatorProjectColumn();
+ $conn_r = $table->establishConnection('r');
+
+ $data = queryfx_all(
+ $conn_r,
+ 'SELECT * FROM %T %Q %Q %Q',
+ $table->getTableName(),
+ $this->buildWhereClause($conn_r),
+ $this->buildOrderClause($conn_r),
+ $this->buildLimitClause($conn_r));
+
+ return $table->loadAllFromArray($data);
+ }
+
+ protected function willFilterPage(array $page) {
+ $projects = array();
+
+ $project_phids = array_filter(mpull($page, 'getProjectPHID'));
+ if ($project_phids) {
+ $projects = id(new PhabricatorProjectQuery())
+ ->setParentQuery($this)
+ ->setViewer($this->getViewer())
+ ->withPHIDs($project_phids)
+ ->execute();
+ $projects = mpull($projects, null, 'getPHID');
+ }
+
+ foreach ($page as $key => $column) {
+ $phid = $column->getProjectPHID();
+ $project = idx($projects, $phid);
+ if (!$project) {
+ unset($page[$key]);
+ continue;
+ }
+ $column->attachProject($project);
+ }
+
+ return $page;
+ }
+
+ private function buildWhereClause($conn_r) {
+ $where = array();
+
+ if ($this->ids) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->projectPHIDs) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'projectPHID IN (%Ls)',
+ $this->projectPHIDs);
+ }
+
+ $where[] = $this->buildPagingClause($conn_r);
+
+ return $this->formatWhereClause($where);
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorApplicationProject';
+ }
+
+}
diff --git a/src/applications/project/storage/PhabricatorProjectColumn.php b/src/applications/project/storage/PhabricatorProjectColumn.php
new file mode 100644
--- /dev/null
+++ b/src/applications/project/storage/PhabricatorProjectColumn.php
@@ -0,0 +1,58 @@
+<?php
+
+final class PhabricatorProjectColumn
+ extends PhabricatorProjectDAO
+ implements PhabricatorPolicyInterface {
+
+ protected $name;
+ protected $projectPHID;
+ protected $sequence;
+
+ private $project = self::ATTACHABLE;
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorProjectPHIDTypeColumn::TYPECONST);
+ }
+
+ public function attachProject(PhabricatorProject $project) {
+ $this->project = $project;
+ return $this;
+ }
+
+ public function getProject() {
+ return $this->assertAttached($this->project);
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return $this->getProject()->getPolicy($capability);
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return $this->getProject()->hasAutomaticCapability(
+ $capability,
+ $viewer);
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return pht('Users must be able to see a project to see its board.');
+ }
+
+}
diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
--- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1688,6 +1688,10 @@
'type' => 'sql',
'name' => $this->getPatchPath('20131020.pcustom.sql'),
),
+ '20131020.col1.sql' => array(
+ 'type' => 'sql',
+ 'name' => $this->getPatchPath('20131020.col1.sql'),
+ ),
);
}
}
diff --git a/src/view/layout/AphrontMultiColumnView.php b/src/view/layout/AphrontMultiColumnView.php
--- a/src/view/layout/AphrontMultiColumnView.php
+++ b/src/view/layout/AphrontMultiColumnView.php
@@ -6,7 +6,7 @@
const GUTTER_MEDIUM = 'mmr';
const GUTTER_LARGE = 'mlr';
- private $column = array();
+ private $columns = array();
private $fluidLayout = false;
private $gutter;
private $shadow;
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
@@ -18,6 +18,7 @@
}
public function setHeaderAction($header_action) {
+ // TODO: This doesn't do anything?
$this->headerAction = $header_action;
return $this;
}
diff --git a/webroot/rsrc/css/phui/phui-workboard-view.css b/webroot/rsrc/css/phui/phui-workboard-view.css
--- a/webroot/rsrc/css/phui/phui-workboard-view.css
+++ b/webroot/rsrc/css/phui/phui-workboard-view.css
@@ -9,7 +9,7 @@
.phui-workboard-view-shadow {
padding: 8px;
min-height: 120px;
- overflow-x: scroll;
+ overflow-x: auto;
border-radius: 5px;
background: rgba(150,150,150,.1);
box-shadow: inset 0 0 5px rgba(0,0,0,.5);
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/6s/3x/3qqnx2ki5ew7zaf6
Default Alt Text
D7374.diff (17 KB)
Attached To
Mode
D7374: Add a secret board view to Projects
Attached
Detach File
Event Timeline
Log In to Comment