Page MenuHomePhabricator

D8131.id18392.diff
No OneTemporary

D8131.id18392.diff

diff --git a/resources/sql/autopatches/20140130.dash.3.boardxaction.sql b/resources/sql/autopatches/20140130.dash.3.boardxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140130.dash.3.boardxaction.sql
@@ -0,0 +1,21 @@
+CREATE TABLE {$NAMESPACE}_dashboard.dashboard_transaction (
+ id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ objectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ commentPHID VARCHAR(64) COLLATE utf8_bin,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) NOT NULL COLLATE utf8_bin,
+ oldValue LONGTEXT NOT NULL COLLATE utf8_bin,
+ newValue LONGTEXT NOT NULL COLLATE utf8_bin,
+ contentSource LONGTEXT NOT NULL COLLATE utf8_bin,
+ metadata LONGTEXT NOT NULL COLLATE utf8_bin,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+
+ UNIQUE KEY `key_phid` (phid),
+ KEY `key_object` (objectPHID)
+
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
diff --git a/resources/sql/autopatches/20140130.dash.4.panelxaction.sql b/resources/sql/autopatches/20140130.dash.4.panelxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140130.dash.4.panelxaction.sql
@@ -0,0 +1,21 @@
+CREATE TABLE {$NAMESPACE}_dashboard.dashboard_paneltransaction (
+ id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ objectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ commentPHID VARCHAR(64) COLLATE utf8_bin,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) NOT NULL COLLATE utf8_bin,
+ oldValue LONGTEXT NOT NULL COLLATE utf8_bin,
+ newValue LONGTEXT NOT NULL COLLATE utf8_bin,
+ contentSource LONGTEXT NOT NULL COLLATE utf8_bin,
+ metadata LONGTEXT NOT NULL COLLATE utf8_bin,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+
+ UNIQUE KEY `key_phid` (phid),
+ KEY `key_object` (objectPHID)
+
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
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
@@ -1387,15 +1387,25 @@
'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php',
'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php',
'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php',
+ 'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php',
'PhabricatorDashboardPHIDTypeDashboard' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypeDashboard.php',
'PhabricatorDashboardPHIDTypePanel' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypePanel.php',
'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php',
+ 'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditController.php',
'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/PhabricatorDashboardPanelListController.php',
'PhabricatorDashboardPanelQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelQuery.php',
'PhabricatorDashboardPanelSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php',
+ 'PhabricatorDashboardPanelTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php',
+ 'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PassphraseDashboardPanelTransactionEditor.php',
+ 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php',
+ 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
+ 'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
+ 'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PassphraseDashboardTransactionEditor.php',
+ 'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php',
+ 'PhabricatorDashboardViewController' => 'applications/dashboard/controller/PhabricatorDashboardViewController.php',
'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
'PhabricatorDebugController' => 'applications/system/PhabricatorDebugController.php',
'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorDefaultFileStorageEngineSelector.php',
@@ -4040,6 +4050,7 @@
),
'PhabricatorDashboardController' => 'PhabricatorController',
'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO',
+ 'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
'PhabricatorDashboardListController' =>
array(
0 => 'PhabricatorDashboardController',
@@ -4047,7 +4058,12 @@
),
'PhabricatorDashboardPHIDTypeDashboard' => 'PhabricatorPHIDType',
'PhabricatorDashboardPHIDTypePanel' => 'PhabricatorPHIDType',
- 'PhabricatorDashboardPanel' => 'PhabricatorDashboardDAO',
+ 'PhabricatorDashboardPanel' =>
+ array(
+ 0 => 'PhabricatorDashboardDAO',
+ 1 => 'PhabricatorPolicyInterface',
+ ),
+ 'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController',
'PhabricatorDashboardPanelListController' =>
array(
0 => 'PhabricatorDashboardController',
@@ -4055,8 +4071,16 @@
),
'PhabricatorDashboardPanelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorDashboardPanelSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PhabricatorDashboardPanelTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+ 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+ 'PhabricatorDashboardViewController' => 'PhabricatorDashboardController',
'PhabricatorDataNotAttachedException' => 'Exception',
'PhabricatorDebugController' => 'PhabricatorController',
'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector',
diff --git a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php
--- a/src/applications/dashboard/application/PhabricatorApplicationDashboard.php
+++ b/src/applications/dashboard/application/PhabricatorApplicationDashboard.php
@@ -11,7 +11,7 @@
}
public function getIconName() {
- return 'dashboard';
+ return 'fancyhome';
}
public function getRoutes() {
@@ -21,9 +21,14 @@
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhabricatorDashboardListController',
'view/(?P<id>\d+)/' => 'PhabricatorDashboardViewController',
+ 'create/' => 'PhabricatorDashboardEditController',
+ 'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
+
'panel/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhabricatorDashboardPanelListController',
+ 'create/' => 'PhabricatorDashboardPanelEditController',
+ 'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardPanelEditController',
),
),
);
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php
@@ -0,0 +1,119 @@
+<?php
+
+final class PhabricatorDashboardEditController
+ extends PhabricatorDashboardController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = idx($data, 'id');
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ if ($this->id) {
+ $dashboard = id(new PhabricatorDashboardQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$dashboard) {
+ return new Aphront404Response();
+ }
+
+ $is_new = false;
+ } else {
+ $dashboard = PhabricatorDashboard::initializeNewDashboard($viewer);
+
+ $is_new = true;
+ }
+
+ $crumbs = $this->buildApplicationCrumbs();
+
+ if ($is_new) {
+ $title = pht('Create Dashboard');
+ $header = pht('Create Dashboard');
+ $button = pht('Create Dashboard');
+ $cancel_uri = $this->getApplicationURI();
+
+ $crumbs->addTextCrumb('Create Dashboard');
+ } else {
+ $id = $dashboard->getID();
+ $cancel_uri = $this->getApplicationURI('view/'.$id.'/');
+
+ $title = pht('Edit Dashboard %d', $dashboard->getID());
+ $header = pht('Edit Dashboard "%s"', $dashboard->getName());
+ $button = pht('Save Changes');
+
+ $crumbs->addTextCrumb(pht('Dashboard %d', $id), $cancel_uri);
+ $crumbs->addTextCrumb(pht('Edit'));
+ }
+
+ $v_name = $dashboard->getName();
+ $e_name = true;
+
+ $validation_exception = null;
+ if ($request->isFormPost()) {
+ $v_name = $request->getStr('name');
+
+ $xactions = array();
+
+ $type_name = PhabricatorDashboardTransaction::TYPE_NAME;
+
+ $xactions[] = id(new PhabricatorDashboardTransaction())
+ ->setTransactionType($type_name)
+ ->setNewValue($v_name);
+
+ try {
+ $editor = id(new PhabricatorDashboardTransactionEditor())
+ ->setActor($viewer)
+ ->setContinueOnNoEffect(true)
+ ->setContentSourceFromRequest($request)
+ ->applyTransactions($dashboard, $xactions);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($this->getApplicationURI('view/'.$dashboard->getID().'/'));
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ $validation_exception = $ex;
+
+ $e_name = $validation_exception->getShortMessage($type_name);
+ }
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel(pht('Name'))
+ ->setName('name')
+ ->setValue($v_name)
+ ->setError($e_name))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue($button)
+ ->addCancelButton($cancel_uri));
+
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText($header)
+ ->setForm($form)
+ ->setValidationException($validation_exception);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $box,
+ ),
+ array(
+ 'title' => $title,
+ 'device' => true,
+ ));
+ }
+
+}
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardListController.php b/src/applications/dashboard/controller/PhabricatorDashboardListController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardListController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardListController.php
@@ -33,11 +33,38 @@
return $nav;
}
+ public function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ $crumbs->addAction(
+ id(new PHUIListItemView())
+ ->setIcon('create')
+ ->setName(pht('Create Dashboard'))
+ ->setHref($this->getApplicationURI().'create/'));
+
+ return $crumbs;
+ }
+
public function renderResultsList(
array $dashboards,
PhabricatorSavedQuery $query) {
+ $viewer = $this->getRequest()->getUser();
+
+ $list = new PHUIObjectItemListView();
+ $list->setUser($viewer);
+ foreach ($dashboards as $dashboard) {
+ $id = $dashboard->getID();
+
+ $item = id(new PHUIObjectItemView())
+ ->setObjectName(pht('Dashboard %d', $id))
+ ->setHeader($dashboard->getName())
+ ->setHref($this->getApplicationURI("view/{$id}/"))
+ ->setObject($dashboard);
+
+ $list->addItem($item);
+ }
- return 'got '.count($dashboards).' ok';
+ return $list;
}
}
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
@@ -0,0 +1,123 @@
+<?php
+
+final class PhabricatorDashboardPanelEditController
+ extends PhabricatorDashboardController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = idx($data, 'id');
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ if ($this->id) {
+ $is_create = false;
+
+ $panel = id(new PhabricatorDashboardPanelQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$panel) {
+ return new Aphront404Response();
+ }
+
+ } else {
+ $is_create = true;
+
+ $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
+ }
+
+ if ($is_create) {
+ $title = pht('New Panel');
+ $header = pht('Create New Panel');
+ $button = pht('Create Panel');
+ $cancel_uri = $this->getApplicationURI('panel/');
+ } else {
+ $title = pht('Edit %s', $panel->getMonogram());
+ $header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
+ $button = pht('Save Panel');
+ $cancel_uri = '/'.$panel->getMonogram();
+ }
+
+ $v_name = $panel->getName();
+ $e_name = true;
+
+ $validation_exception = null;
+ if ($request->isFormPost()) {
+ $v_name = $request->getStr('name');
+
+ $xactions = array();
+
+ $type_name = PhabricatorDashboardPanelTransaction::TYPE_NAME;
+
+ $xactions[] = id(new PhabricatorDashboardPanelTransaction())
+ ->setTransactionType($type_name)
+ ->setNewValue($v_name);
+
+ try {
+ $editor = id(new PhabricatorDashboardPanelTransactionEditor())
+ ->setActor($viewer)
+ ->setContinueOnNoEffect(true)
+ ->setContentSourceFromRequest($request)
+ ->applyTransactions($panel, $xactions);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI('/'.$panel->getMonogram());
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ $validation_exception = $ex;
+
+ $e_name = $validation_exception->getShortMessage($type_name);
+ }
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel(pht('Name'))
+ ->setName('name')
+ ->setValue($v_name)
+ ->setError($e_name))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue($button)
+ ->addCancelButton($cancel_uri));
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(
+ pht('Panels'),
+ $this->getApplicationURI('panel/'));
+ if ($is_create) {
+ $crumbs->addTextCrumb(pht('New Panel'));
+ } else {
+ $crumbs->addTextCrumb(
+ $panel->getMonogram(),
+ '/'.$panel->getMonogram());
+ $crumbs->addTextCrumb(pht('Edit'));
+ }
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText($header)
+ ->setValidationException($validation_exception)
+ ->setForm($form);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $box,
+ ),
+ array(
+ 'title' => $title,
+ 'device' => true,
+ ));
+ }
+
+}
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelListController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelListController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardPanelListController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelListController.php
@@ -33,11 +33,39 @@
return $nav;
}
+ public function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ $crumbs->addTextCrumb(pht('Panels'), $this->getApplicationURI().'panel/');
+
+ $crumbs->addAction(
+ id(new PHUIListItemView())
+ ->setIcon('create')
+ ->setName(pht('Create Panel'))
+ ->setHref($this->getApplicationURI().'panel/create/'));
+
+ return $crumbs;
+ }
+
public function renderResultsList(
array $panels,
PhabricatorSavedQuery $query) {
- return 'got '.count($panels).' ok';
+ $viewer = $this->getRequest()->getUser();
+
+ $list = new PHUIObjectItemListView();
+ $list->setUser($viewer);
+ foreach ($panels as $panel) {
+ $item = id(new PHUIObjectItemView())
+ ->setObjectName($panel->getMonogram())
+ ->setHeader($panel->getName())
+ ->setHref('/'.$panel->getMonogram())
+ ->setObject($panel);
+
+ $list->addItem($item);
+ }
+
+ return $list;
}
}
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/controller/PhabricatorDashboardPanelViewController.php
@@ -0,0 +1,123 @@
+<?php
+
+final class PhabricatorDashboardPanelViewController
+ extends PhabricatorDashboardController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = $data['id'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ $panel = id(new PhabricatorDashboardPanelQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->executeOne();
+ if (!$panel) {
+ return new Aphront404Response();
+ }
+
+ $title = $panel->getMonogram().' '.$panel->getName();
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(
+ pht('Panels'),
+ $this->getApplicationURI('panel/'));
+ $crumbs->addTextCrumb($panel->getMonogram());
+
+ $header = $this->buildHeaderView($panel);
+ $actions = $this->buildActionView($panel);
+ $properties = $this->buildPropertyView($panel);
+ $timeline = $this->buildTransactions($panel);
+
+ $properties->setActionList($actions);
+ $box = id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->addPropertyList($properties);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $box,
+ $timeline,
+ ),
+ array(
+ 'title' => $title,
+ 'device' => true,
+ ));
+ }
+
+ private function buildHeaderView(PhabricatorDashboardPanel $panel) {
+ $viewer = $this->getRequest()->getUser();
+
+ return id(new PHUIHeaderView())
+ ->setUser($viewer)
+ ->setHeader($panel->getName())
+ ->setPolicyObject($panel);
+ }
+
+ private function buildActionView(PhabricatorDashboardPanel $panel) {
+ $viewer = $this->getRequest()->getUser();
+ $id = $panel->getID();
+
+ $actions = id(new PhabricatorActionListView())
+ ->setObjectURI('/'.$panel->getMonogram())
+ ->setUser($viewer);
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $panel,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $actions->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Panel'))
+ ->setIcon('edit')
+ ->setHref($this->getApplicationURI("panel/edit/{$id}/"))
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit));
+
+ return $actions;
+ }
+
+ private function buildPropertyView(PhabricatorDashboardPanel $panel) {
+ $viewer = $this->getRequest()->getUser();
+
+ $properties = id(new PHUIPropertyListView())
+ ->setUser($viewer)
+ ->setObject($panel);
+
+ $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
+ $viewer,
+ $panel);
+
+ $properties->addProperty(
+ pht('Editable By'),
+ $descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
+
+ return $properties;
+ }
+
+ private function buildTransactions(PhabricatorDashboardPanel $panel) {
+ $viewer = $this->getRequest()->getUser();
+
+ $xactions = id(new PhabricatorDashboardPanelTransactionQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($panel->getPHID()))
+ ->execute();
+
+ $engine = id(new PhabricatorMarkupEngine())
+ ->setViewer($viewer);
+
+ $timeline = id(new PhabricatorApplicationTransactionView())
+ ->setUser($viewer)
+ ->setObjectPHID($panel->getPHID())
+ ->setTransactions($xactions);
+
+ return $timeline;
+ }
+
+}
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardViewController.php b/src/applications/dashboard/controller/PhabricatorDashboardViewController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/controller/PhabricatorDashboardViewController.php
@@ -0,0 +1,120 @@
+<?php
+
+final class PhabricatorDashboardViewController
+ extends PhabricatorDashboardController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = $data['id'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ $dashboard = id(new PhabricatorDashboardQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->executeOne();
+ if (!$dashboard) {
+ return new Aphront404Response();
+ }
+
+ $title = $dashboard->getName();
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(pht('Dashboard %d', $dashboard->getID()));
+
+ $header = $this->buildHeaderView($dashboard);
+ $actions = $this->buildActionView($dashboard);
+ $properties = $this->buildPropertyView($dashboard);
+ $timeline = $this->buildTransactions($dashboard);
+
+ $properties->setActionList($actions);
+ $box = id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->addPropertyList($properties);
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $box,
+ $timeline,
+ ),
+ array(
+ 'title' => $title,
+ 'device' => true,
+ ));
+ }
+
+ private function buildHeaderView(PhabricatorDashboard $dashboard) {
+ $viewer = $this->getRequest()->getUser();
+
+ return id(new PHUIHeaderView())
+ ->setUser($viewer)
+ ->setHeader($dashboard->getName())
+ ->setPolicyObject($dashboard);
+ }
+
+ private function buildActionView(PhabricatorDashboard $dashboard) {
+ $viewer = $this->getRequest()->getUser();
+ $id = $dashboard->getID();
+
+ $actions = id(new PhabricatorActionListView())
+ ->setObjectURI($this->getApplicationURI('view/'.$dashboard->getID().'/'))
+ ->setUser($viewer);
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $dashboard,
+ PhabricatorPolicyCapability::CAN_EDIT);
+
+ $actions->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Dashboard'))
+ ->setIcon('edit')
+ ->setHref($this->getApplicationURI("edit/{$id}/"))
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit));
+
+ return $actions;
+ }
+
+ private function buildPropertyView(PhabricatorDashboard $dashboard) {
+ $viewer = $this->getRequest()->getUser();
+
+ $properties = id(new PHUIPropertyListView())
+ ->setUser($viewer)
+ ->setObject($dashboard);
+
+ $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
+ $viewer,
+ $dashboard);
+
+ $properties->addProperty(
+ pht('Editable By'),
+ $descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
+
+ return $properties;
+ }
+
+ private function buildTransactions(PhabricatorDashboard $dashboard) {
+ $viewer = $this->getRequest()->getUser();
+
+ $xactions = id(new PhabricatorDashboardTransactionQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($dashboard->getPHID()))
+ ->execute();
+
+ $engine = id(new PhabricatorMarkupEngine())
+ ->setViewer($viewer);
+
+ $timeline = id(new PhabricatorApplicationTransactionView())
+ ->setUser($viewer)
+ ->setObjectPHID($dashboard->getPHID())
+ ->setTransactions($xactions);
+
+ return $timeline;
+ }
+
+}
diff --git a/src/applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php b/src/applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php
@@ -0,0 +1,101 @@
+<?php
+
+final class PhabricatorDashboardPanelTransactionEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+
+ $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+ $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+ $types[] = PhabricatorDashboardPanelTransaction::TYPE_NAME;
+
+ return $types;
+ }
+
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardPanelTransaction::TYPE_NAME:
+ if ($this->getIsNewObject()) {
+ return null;
+ }
+ return $object->getName();
+ }
+
+ return parent::getCustomTransactionOldValue($object, $xaction);
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardPanelTransaction::TYPE_NAME:
+ return $xaction->getNewValue();
+ }
+ return parent::getCustomTransactionNewValue($object, $xaction);
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardPanelTransaction::TYPE_NAME:
+ $object->setName($xaction->getNewValue());
+ return;
+ case PhabricatorTransactions::TYPE_VIEW_POLICY:
+ $object->setViewPolicy($xaction->getNewValue());
+ return;
+ case PhabricatorTransactions::TYPE_EDIT_POLICY:
+ $object->setEditPolicy($xaction->getNewValue());
+ return;
+ }
+
+ return parent::applyCustomInternalTransaction($object, $xaction);
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardPanelTransaction::TYPE_NAME:
+ return;
+ }
+
+ return parent::applyCustomExternalTransaction($object, $xaction);
+ }
+
+ protected function validateTransaction(
+ PhabricatorLiskDAO $object,
+ $type,
+ array $xactions) {
+
+ $errors = parent::validateTransaction($object, $type, $xactions);
+
+ switch ($type) {
+ case PhabricatorDashboardPanelTransaction::TYPE_NAME:
+ $missing = $this->validateIsEmptyTextField(
+ $object->getName(),
+ $xactions);
+
+ if ($missing) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Required'),
+ pht('Panel name is required.'),
+ nonempty(last($xactions), null));
+
+ $error->setIsMissingFieldError(true);
+ $errors[] = $error;
+ }
+ break;
+ }
+
+ return $errors;
+ }
+
+
+}
diff --git a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
@@ -0,0 +1,101 @@
+<?php
+
+final class PhabricatorDashboardTransactionEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getTransactionTypes() {
+ $types = parent::getTransactionTypes();
+
+ $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+ $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+ $types[] = PhabricatorDashboardTransaction::TYPE_NAME;
+
+ return $types;
+ }
+
+ protected function getCustomTransactionOldValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardTransaction::TYPE_NAME:
+ if ($this->getIsNewObject()) {
+ return null;
+ }
+ return $object->getName();
+ }
+
+ return parent::getCustomTransactionOldValue($object, $xaction);
+ }
+
+ protected function getCustomTransactionNewValue(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardTransaction::TYPE_NAME:
+ return $xaction->getNewValue();
+ }
+ return parent::getCustomTransactionNewValue($object, $xaction);
+ }
+
+ protected function applyCustomInternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardTransaction::TYPE_NAME:
+ $object->setName($xaction->getNewValue());
+ return;
+ case PhabricatorTransactions::TYPE_VIEW_POLICY:
+ $object->setViewPolicy($xaction->getNewValue());
+ return;
+ case PhabricatorTransactions::TYPE_EDIT_POLICY:
+ $object->setEditPolicy($xaction->getNewValue());
+ return;
+ }
+
+ return parent::applyCustomInternalTransaction($object, $xaction);
+ }
+
+ protected function applyCustomExternalTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorDashboardTransaction::TYPE_NAME:
+ return;
+ }
+
+ return parent::applyCustomExternalTransaction($object, $xaction);
+ }
+
+ protected function validateTransaction(
+ PhabricatorLiskDAO $object,
+ $type,
+ array $xactions) {
+
+ $errors = parent::validateTransaction($object, $type, $xactions);
+
+ switch ($type) {
+ case PhabricatorDashboardTransaction::TYPE_NAME:
+ $missing = $this->validateIsEmptyTextField(
+ $object->getName(),
+ $xactions);
+
+ if ($missing) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Required'),
+ pht('Dashboard name is required.'),
+ nonempty(last($xactions), null));
+
+ $error->setIsMissingFieldError(true);
+ $errors[] = $error;
+ }
+ break;
+ }
+
+ return $errors;
+ }
+
+
+}
diff --git a/src/applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php b/src/applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorDashboardPanelTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhabricatorDashboardPanelTransaction();
+ }
+
+}
diff --git a/src/applications/dashboard/query/PhabricatorDashboardTransactionQuery.php b/src/applications/dashboard/query/PhabricatorDashboardTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/query/PhabricatorDashboardTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class PhabricatorDashboardTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new PhabricatorDashboardTransaction();
+ }
+
+}
diff --git a/src/applications/dashboard/storage/PhabricatorDashboard.php b/src/applications/dashboard/storage/PhabricatorDashboard.php
--- a/src/applications/dashboard/storage/PhabricatorDashboard.php
+++ b/src/applications/dashboard/storage/PhabricatorDashboard.php
@@ -6,9 +6,16 @@
final class PhabricatorDashboard extends PhabricatorDashboardDAO
implements PhabricatorPolicyInterface {
- private $name;
- private $viewPolicy;
- private $editPolicy;
+ protected $name;
+ protected $viewPolicy;
+ protected $editPolicy;
+
+ public static function initializeNewDashboard(PhabricatorUser $actor) {
+ return id(new PhabricatorDashboard())
+ ->setName('')
+ ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
+ ->setEditPolicy($actor->getPHID());
+ }
public function getConfiguration() {
return array(
diff --git a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php
--- a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php
+++ b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php
@@ -3,12 +3,21 @@
/**
* An individual dashboard panel.
*/
-final class PhabricatorDashboardPanel extends PhabricatorDashboardDAO {
+final class PhabricatorDashboardPanel
+ extends PhabricatorDashboardDAO
+ implements PhabricatorPolicyInterface {
- private $name;
- private $viewPolicy;
- private $editPolicy;
- private $properties = array();
+ protected $name;
+ protected $viewPolicy;
+ protected $editPolicy;
+ protected $properties = array();
+
+ public static function initializeNewPanel(PhabricatorUser $actor) {
+ return id(new PhabricatorDashboardPanel())
+ ->setName('')
+ ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
+ ->setEditPolicy($actor->getPHID());
+ }
public function getConfiguration() {
return array(
@@ -21,7 +30,7 @@
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
- PhabricatorDashboardPHIDTypeDashboard::TYPECONST);
+ PhabricatorDashboardPHIDTypePanel::TYPECONST);
}
public function getProperty($key, $default = null) {
diff --git a/src/applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php b/src/applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php
@@ -0,0 +1,89 @@
+<?php
+
+final class PhabricatorDashboardPanelTransaction
+ extends PhabricatorApplicationTransaction {
+
+ const TYPE_NAME = 'dashpanel:name';
+
+ public function getApplicationName() {
+ return 'dashboard';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorDashboardPHIDTypePanel::TYPECONST;
+ }
+
+ public function getTitle() {
+ $author_phid = $this->getAuthorPHID();
+ $object_phid = $this->getObjectPHID();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $author_link = $this->renderHandleLink($author_phid);
+
+ $type = $this->getTransactionType();
+ switch ($type) {
+ case self::TYPE_NAME:
+ if (!strlen($old)) {
+ return pht(
+ '%s created this panel.',
+ $author_link);
+ } else {
+ return pht(
+ '%s renamed this panel from "%s" to "%s".',
+ $author_link,
+ $old,
+ $new);
+ }
+ }
+
+ return parent::getTitle();
+ }
+
+ public function getTitleForFeed(PhabricatorFeedStory $story) {
+ $author_phid = $this->getAuthorPHID();
+ $object_phid = $this->getObjectPHID();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $author_link = $this->renderHandleLink($author_phid);
+ $object_link = $this->renderHandleLink($object_phid);
+
+ $type = $this->getTransactionType();
+ switch ($type) {
+ case self::TYPE_NAME:
+ if (!strlen($old)) {
+ return pht(
+ '%s created dashboard panel %s.',
+ $author_link,
+ $object_link);
+ } else {
+ return pht(
+ '%s renamed dashboard panel %s from "%s" to "%s".',
+ $author_link,
+ $object_link,
+ $old,
+ $new);
+ }
+ }
+
+ return parent::getTitleForFeed($story);
+ }
+
+ public function getColor() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_NAME:
+ if (!strlen($old)) {
+ return PhabricatorTransactions::COLOR_GREEN;
+ }
+ break;
+ }
+
+ return parent::getColor();
+ }
+}
diff --git a/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php b/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php
@@ -0,0 +1,89 @@
+<?php
+
+final class PhabricatorDashboardTransaction
+ extends PhabricatorApplicationTransaction {
+
+ const TYPE_NAME = 'dashboard:name';
+
+ public function getApplicationName() {
+ return 'dashboard';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorDashboardPHIDTypeDashboard::TYPECONST;
+ }
+
+ public function getTitle() {
+ $author_phid = $this->getAuthorPHID();
+ $object_phid = $this->getObjectPHID();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $author_link = $this->renderHandleLink($author_phid);
+
+ $type = $this->getTransactionType();
+ switch ($type) {
+ case self::TYPE_NAME:
+ if (!strlen($old)) {
+ return pht(
+ '%s created this dashboard.',
+ $author_link);
+ } else {
+ return pht(
+ '%s renamed this dashboard from "%s" to "%s".',
+ $author_link,
+ $old,
+ $new);
+ }
+ }
+
+ return parent::getTitle();
+ }
+
+ public function getTitleForFeed(PhabricatorFeedStory $story) {
+ $author_phid = $this->getAuthorPHID();
+ $object_phid = $this->getObjectPHID();
+
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $author_link = $this->renderHandleLink($author_phid);
+ $object_link = $this->renderHandleLink($object_phid);
+
+ $type = $this->getTransactionType();
+ switch ($type) {
+ case self::TYPE_NAME:
+ if (!strlen($old)) {
+ return pht(
+ '%s created dashboard %s.',
+ $author_link,
+ $object_link);
+ } else {
+ return pht(
+ '%s renamed dashboard %s from "%s" to "%s".',
+ $author_link,
+ $object_link,
+ $old,
+ $new);
+ }
+ }
+
+ return parent::getTitleForFeed($story);
+ }
+
+ public function getColor() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_NAME:
+ if (!strlen($old)) {
+ return PhabricatorTransactions::COLOR_GREEN;
+ }
+ break;
+ }
+
+ return parent::getColor();
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 16, 1:15 AM (3 w, 2 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/pv/7e/djdimr3jyredpknl
Default Alt Text
D8131.id18392.diff (40 KB)

Event Timeline