Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15412708
D9031.id21452.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Referenced Files
None
Subscribers
None
D9031.id21452.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -52,6 +52,7 @@
'rsrc/css/application/conpherence/widget-pane.css' => 'bf275a6c',
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
'rsrc/css/application/countdown/timer.css' => '86b7b0a0',
+ 'rsrc/css/application/dashboard/dashboard.css' => '5b532b7b',
'rsrc/css/application/diff/inline-comment-summary.css' => '8cfd34e8',
'rsrc/css/application/differential/add-comment.css' => 'c478bcaa',
'rsrc/css/application/differential/changeset-view.css' => '1570a1ff',
@@ -696,6 +697,7 @@
'phabricator-core-css' => '40151074',
'phabricator-countdown-css' => '86b7b0a0',
'phabricator-crumbs-view-css' => '0222cbe0',
+ 'phabricator-dashboard-css' => '5b532b7b',
'phabricator-drag-and-drop-file-upload' => 'ae6abfba',
'phabricator-draggable-list' => '1681c4d4',
'phabricator-fatal-config-template-css' => '25d446d6',
diff --git a/resources/sql/autopatches/20140509.dashboardlayoutconfig.sql b/resources/sql/autopatches/20140509.dashboardlayoutconfig.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140509.dashboardlayoutconfig.sql
@@ -0,0 +1,4 @@
+ALTER TABLE {$NAMESPACE}_dashboard.dashboard
+ ADD COLUMN layoutConfig LONGTEXT NOT NULL COLLATE utf8_bin AFTER name;
+
+UPDATE {$NAMESPACE}_dashboard.dashboard SET layoutConfig = '[]';
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
@@ -1446,6 +1446,7 @@
'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php',
'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php',
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
+ 'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php',
'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php',
'PhabricatorDashboardPHIDTypeDashboard' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypeDashboard.php',
'PhabricatorDashboardPHIDTypePanel' => 'applications/dashboard/phid/PhabricatorDashboardPHIDTypePanel.php',
@@ -3159,7 +3160,11 @@
'DiffusionPathValidateController' => 'DiffusionController',
'DiffusionPushEventViewController' => 'DiffusionPushLogController',
'DiffusionPushLogController' => 'DiffusionController',
- 'DiffusionPushLogListController' => 'DiffusionPushLogController',
+ 'DiffusionPushLogListController' =>
+ array(
+ 0 => 'DiffusionPushLogController',
+ 1 => 'PhabricatorApplicationSearchResultsControllerInterface',
+ ),
'DiffusionQuery' => 'PhabricatorQuery',
'DiffusionRawDiffQuery' => 'DiffusionQuery',
'DiffusionRepositoryController' => 'DiffusionController',
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php b/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
@@ -27,6 +27,8 @@
}
$dashboard_uri = $this->getApplicationURI('view/'.$dashboard->getID().'/');
+ $layout_config = PhabricatorDashboardLayoutConfig::newFromDictionary(
+ $dashboard->getLayoutConfig());
$v_panel = $request->getStr('panel');
$e_panel = true;
@@ -61,6 +63,13 @@
),
));
+ if ($layout_config->isMultiColumnLayout()) {
+ $layout_config->setPanelLocation(
+ $request->getStr('column'),
+ $panel->getPHID());
+ $dashboard->setLayoutConfig($layout_config->toDictionary());
+ }
+
$editor = id(new PhabricatorDashboardTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
@@ -83,6 +92,17 @@
->setValue($v_panel)
->setError($e_panel));
+ if ($layout_config->isMultiColumnLayout()) {
+ $form
+ ->appendRemarkupInstructions(
+ pht('Choose which column the panel should reside in.'))
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setName('column')
+ ->setLabel(pht('Column'))
+ ->setOptions($layout_config->getColumnSelectOptions()));
+ }
+
return $this->newDialog()
->setTitle(pht('Add Panel'))
->setErrors($errors)
diff --git a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php
--- a/src/applications/dashboard/controller/PhabricatorDashboardEditController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardEditController.php
@@ -17,6 +17,7 @@
$dashboard = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withIDs(array($this->id))
+ ->needPanels(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
@@ -56,19 +57,25 @@
}
$v_name = $dashboard->getName();
+ $v_layout_mode = $dashboard->getLayoutConfigValue('layoutMode');
$e_name = true;
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
+ $v_layout_mode = $request->getStr('layout_mode');
$xactions = array();
$type_name = PhabricatorDashboardTransaction::TYPE_NAME;
+ $type_layout_mode = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
$xactions[] = id(new PhabricatorDashboardTransaction())
->setTransactionType($type_name)
->setNewValue($v_name);
+ $xactions[] = id(new PhabricatorDashboardTransaction())
+ ->setTransactionType($type_layout_mode)
+ ->setNewValue($v_layout_mode);
try {
$editor = id(new PhabricatorDashboardTransactionEditor())
@@ -86,6 +93,8 @@
}
}
+ $layout_mode_options =
+ PhabricatorDashboardLayoutConfig::getLayoutModeSelectOptions();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
@@ -95,11 +104,16 @@
->setValue($v_name)
->setError($e_name))
->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel(pht('Layout Mode'))
+ ->setName('layout_mode')
+ ->setValue($v_layout_mode)
+ ->setOptions($layout_mode_options))
+ ->appendChild(
id(new AphrontFormSubmitControl())
->setValue($button)
->addCancelButton($cancel_uri));
-
$box = id(new PHUIObjectBoxView())
->setHeaderText($header)
->setForm($form)
diff --git a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
--- a/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
+++ b/src/applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php
@@ -11,6 +11,7 @@
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorDashboardTransaction::TYPE_NAME;
+ $types[] = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
return $types;
}
@@ -24,6 +25,11 @@
return null;
}
return $object->getName();
+ case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
+ if ($this->getIsNewObject()) {
+ return null;
+ }
+ return $object->getLayoutConfigValue('layoutMode');
}
return parent::getCustomTransactionOldValue($object, $xaction);
@@ -34,6 +40,7 @@
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorDashboardTransaction::TYPE_NAME:
+ case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
return $xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
@@ -46,6 +53,23 @@
case PhabricatorDashboardTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
return;
+ case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
+ $old_layout = PhabricatorDashboardLayoutConfig::newFromDictionary(
+ $object->getLayoutConfig());
+ $object->setLayoutConfigValue('layoutMode', $xaction->getNewValue());
+ $new_layout = PhabricatorDashboardLayoutConfig::newFromDictionary(
+ $object->getLayoutConfig());
+ if ($old_layout->isMultiColumnLayout() !=
+ $new_layout->isMultiColumnLayout()) {
+ $panel_phids = $object->getPanelPHIDs();
+ $new_locations = array('left' => array());
+ foreach ($panel_phids as $panel_phid) {
+ $new_locations['left'][] = $panel_phid;
+ }
+ $new_layout->setPanelLocations($new_locations);
+ $object->setLayoutConfig($new_layout->toDictionary());
+ }
+ return;
case PhabricatorTransactions::TYPE_VIEW_POLICY:
$object->setViewPolicy($xaction->getNewValue());
return;
@@ -65,6 +89,7 @@
switch ($xaction->getTransactionType()) {
case PhabricatorDashboardTransaction::TYPE_NAME:
+ case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
return;
case PhabricatorTransactions::TYPE_EDGE:
return;
diff --git a/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
--- a/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
+++ b/src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
@@ -16,18 +16,87 @@
}
public function renderDashboard() {
+ require_celerity_resource('phabricator-dashboard-css');
$dashboard = $this->dashboard;
$viewer = $this->viewer;
- $result = array();
- foreach ($dashboard->getPanels() as $panel) {
- $result[] = id(new PhabricatorDashboardPanelRenderingEngine())
+ $layout_config =
+ PhabricatorDashboardLayoutConfig::newFromDictionary(
+ $dashboard->getLayoutConfig());
+ $panel_locations = $layout_config->getPanelLocations();
+ $panels = mpull($dashboard->getPanels(), null, 'getPHID');
+
+ switch ($layout_config->getLayoutMode()) {
+ case PhabricatorDashboardLayoutConfig::MODE_HALF_AND_HALF:
+ case PhabricatorDashboardLayoutConfig::MODE_THIRD_AND_THIRDS:
+ case PhabricatorDashboardLayoutConfig::MODE_THIRDS_AND_THIRD:
+ $panel_phids = idx($panel_locations, 'left', array_keys($panels));
+ $left_panels = array_select_keys($panels, $panel_phids);
+ break;
+ case PhabricatorDashboardLayoutConfig::MODE_FULL:
+ default:
+ $left_panels = $panels;
+ break;
+ }
+
+ $left_result = array();
+ foreach ($left_panels as $panel) {
+ $left_result[] = id(new PhabricatorDashboardPanelRenderingEngine())
->setViewer($viewer)
->setPanel($panel)
->setEnableAsyncRendering(true)
->renderPanel();
}
+ switch ($layout_config->getLayoutMode()) {
+ case PhabricatorDashboardLayoutConfig::MODE_HALF_AND_HALF:
+ case PhabricatorDashboardLayoutConfig::MODE_THIRD_AND_THIRDS:
+ case PhabricatorDashboardLayoutConfig::MODE_THIRDS_AND_THIRD:
+ $panel_phids = idx($panel_locations, 'right', array());
+ $right_panels = array_select_keys($panels, $panel_phids);
+ break;
+ case PhabricatorDashboardLayoutConfig::MODE_FULL:
+ default:
+ $right_panels = array();
+ break;
+ }
+
+ $right_result = array();
+ foreach ($right_panels as $panel) {
+ $right_result[] = id(new PhabricatorDashboardPanelRenderingEngine())
+ ->setViewer($viewer)
+ ->setPanel($panel)
+ ->setEnableAsyncRendering(true)
+ ->renderPanel();
+ }
+
+ switch ($layout_config->getLayoutMode()) {
+ case PhabricatorDashboardLayoutConfig::MODE_HALF_AND_HALF:
+ $result = id(new AphrontMultiColumnView())
+ ->setFluidlayout(true)
+ ->addColumn($left_result, 'half')
+ ->addColumn($right_result, 'half');
+ break;
+ break;
+ case PhabricatorDashboardLayoutConfig::MODE_THIRD_AND_THIRDS:
+ $result = id(new AphrontMultiColumnView())
+ ->setFluidlayout(true)
+ ->addColumn($left_result, 'third')
+ ->addColumn($right_result, 'thirds');
+ break;
+ break;
+ case PhabricatorDashboardLayoutConfig::MODE_THIRDS_AND_THIRD:
+ $result = id(new AphrontMultiColumnView())
+ ->setFluidlayout(true)
+ ->addColumn($left_result, 'thirds')
+ ->addColumn($right_result, 'third');
+ break;
+ case PhabricatorDashboardLayoutConfig::MODE_FULL:
+ default:
+ $result = $left_result;
+ break;
+ }
+
return $result;
}
diff --git a/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php b/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php
@@ -0,0 +1,85 @@
+<?php
+
+final class PhabricatorDashboardLayoutConfig {
+
+ const MODE_FULL = 'layout-mode-full';
+ const MODE_HALF_AND_HALF = 'layout-mode-half-and-half';
+ const MODE_THIRD_AND_THIRDS = 'layout-mode-third-and-thirds';
+ const MODE_THIRDS_AND_THIRD = 'layout-mode-thirds-and-third';
+
+ private $layoutMode = self::MODE_FULL;
+ private $panelLocations = array();
+
+ public function setLayoutMode($mode) {
+ $this->layoutMode = $mode;
+ return $this;
+ }
+ public function getLayoutMode() {
+ return $this->layoutMode;
+ }
+
+ public function setPanelLocation($which_column, $panel_phid) {
+ $this->panelLocations[$which_column][] = $panel_phid;
+ return $this;
+ }
+
+ public function setPanelLocations(array $locations) {
+ $this->panelLocations = $locations;
+ return $this;
+ }
+
+ public function getPanelLocations() {
+ return $this->panelLocations;
+ }
+
+ public function isMultiColumnLayout() {
+ return $this->getLayoutMode() != self::MODE_FULL;
+ }
+
+ public function getColumnSelectOptions() {
+ $options = array();
+
+ switch ($this->getLayoutMode()) {
+ case self::MODE_HALF_AND_HALF:
+ case self::MODE_THIRD_AND_THIRDS:
+ case self::MODE_THIRDS_AND_THIRD:
+ return array(
+ 'left' => pht('Left'),
+ 'right' => pht('Right'));
+ break;
+ case self::MODE_FULL:
+ throw new Exception('There is only one column in mode full.');
+ break;
+ default:
+ throw new Exception('Unknown layout mode!');
+ break;
+ }
+
+ return $options;
+ }
+
+ public static function getLayoutModeSelectOptions() {
+ return array(
+ self::MODE_FULL => pht('One full-width column'),
+ self::MODE_HALF_AND_HALF => pht('Two columns, 1/2 and 1/2'),
+ self::MODE_THIRD_AND_THIRDS => pht('Two columns, 1/3 and 2/3'),
+ self::MODE_THIRDS_AND_THIRD => pht('Two columns, 2/3 and 1/3'),
+ );
+ }
+
+ public static function newFromDictionary(array $dict) {
+ $layout_config = id(new PhabricatorDashboardLayoutConfig())
+ ->setLayoutMode(idx($dict, 'layoutMode', self::MODE_FULL))
+ ->setPanelLocations(idx($dict, 'panelLocations', array()));
+
+ return $layout_config;
+ }
+
+ public function toDictionary() {
+ return array(
+ 'layoutMode' => $this->getLayoutMode(),
+ 'panelLocations' => $this->getPanelLocations()
+ );
+ }
+
+}
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
@@ -9,6 +9,7 @@
protected $name;
protected $viewPolicy;
protected $editPolicy;
+ protected $layoutConfig = array();
private $panelPHIDs = self::ATTACHABLE;
private $panels = self::ATTACHABLE;
@@ -17,12 +18,16 @@
return id(new PhabricatorDashboard())
->setName('')
->setViewPolicy(PhabricatorPolicies::POLICY_USER)
- ->setEditPolicy($actor->getPHID());
+ ->setEditPolicy($actor->getPHID())
+ ->attachPanels(array())
+ ->attachPanelPHIDs(array());
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
+ self::CONFIG_SERIALIZATION => array(
+ 'layoutConfig' => self::SERIALIZATION_JSON),
) + parent::getConfiguration();
}
@@ -31,6 +36,20 @@
PhabricatorDashboardPHIDTypeDashboard::TYPECONST);
}
+ public function getLayoutConfigValue($key) {
+ return idx($this->layoutConfig, $key);
+ }
+
+ public function setLayoutConfigValue($key, $value) {
+ $this->layoutConfig[$key] = $value;
+ return $this;
+ }
+
+ public function setLayoutConfig(array $dict) {
+ $this->layoutConfig = $dict;
+ return $this;
+ }
+
public function attachPanelPHIDs(array $phids) {
$this->panelPHIDs = $phids;
return $this;
diff --git a/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php b/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php
--- a/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php
+++ b/src/applications/dashboard/storage/PhabricatorDashboardTransaction.php
@@ -4,6 +4,7 @@
extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'dashboard:name';
+ const TYPE_LAYOUT_MODE = 'dashboard:layoutmode';
public function getApplicationName() {
return 'dashboard';
@@ -86,4 +87,15 @@
return parent::getColor();
}
+
+ public function shouldHide() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_LAYOUT_MODE:
+ return true;
+ }
+ return parent::shouldHide();
+ }
}
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
@@ -12,8 +12,10 @@
private $gutter;
private $border;
- public function addColumn($column) {
- $this->columns[] = $column;
+ public function addColumn($column, $class = null) {
+ $this->columns[] = array(
+ 'column' => $column,
+ 'class' => $class);
return $this;
}
@@ -55,19 +57,21 @@
$classes[] = 'aphront-multi-column-'.count($this->columns).'-up';
$columns = array();
- $column_class = array();
- $column_class[] = 'aphront-multi-column-column';
- $outer_class = array();
- $outer_class[] = 'aphront-multi-column-column-outer';
- if ($this->gutter) {
- $column_class[] = $this->gutter;
- }
$i = 0;
- foreach ($this->columns as $column) {
+ foreach ($this->columns as $column_data) {
+ $column_class = array('aphront-multi-column-column');
+ if ($this->gutter) {
+ $column_class[] = $this->gutter;
+ }
+ $outer_class = array('aphront-multi-column-column-outer');
if (++$i === count($this->columns)) {
$column_class[] = 'aphront-multi-column-column-last';
$outer_class[] = 'aphront-multi-colum-column-outer-last';
}
+ $column = $column_data['column'];
+ if ($column_data['class']) {
+ $outer_class[] = $column_data['class'];
+ }
$column_inner = phutil_tag(
'div',
array(
diff --git a/webroot/rsrc/css/application/dashboard/dashboard.css b/webroot/rsrc/css/application/dashboard/dashboard.css
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/css/application/dashboard/dashboard.css
@@ -0,0 +1,19 @@
+/**
+ * @provides phabricator-dashboard-css
+ */
+
+.aphront-multi-column-fluid .aphront-multi-column-2-up
+.aphront-multi-column-column-outer.half {
+ width: 50%;
+}
+
+.aphront-multi-column-fluid .aphront-multi-column-2-up
+.aphront-multi-column-column-outer.third {
+ width: 33.34%;
+}
+
+
+.aphront-multi-column-fluid .aphront-multi-column-2-up
+.aphront-multi-column-column-outer.thirds {
+ width: 66.66%;
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 20, 2:30 PM (1 d, 10 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7707846
Default Alt Text
D9031.id21452.diff (20 KB)
Attached To
Mode
D9031: Dashboards - add layout mode to dashboards
Attached
Detach File
Event Timeline
Log In to Comment