Page MenuHomePhabricator

D9031.id21452.diff
No OneTemporary

D9031.id21452.diff

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

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)

Event Timeline