From 646280972b8803a66b405eeb73d55aa6bb3178f9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 21 Apr 2020 07:33:27 -0700 Subject: [PATCH] Glue the new FormationView on top of the older Filetree view in Differential Summary: Ref T13516. This glues "FormationView" to "ChangesetList". The actual tree is not functional in any meaningful way yet. Test Plan: {F7373838} Maniphest Tasks: T13516 Differential Revision: https://secure.phabricator.com/D21151 --- resources/celerity/map.php | 73 ++++----- src/__phutil_library_map__.php | 4 +- .../DifferentialRevisionViewController.php | 45 +++-- .../engine/DifferentialFileTreeEngine.php | 155 ++++++++++++++++++ .../view/DifferentialChangesetListView.php | 17 ++ .../PHUIFormationColumnDynamicView.php | 40 +++++ .../formation/PHUIFormationColumnItem.php | 14 +- .../formation/PHUIFormationColumnView.php | 16 ++ src/view/formation/PHUIFormationFlankView.php | 11 +- src/view/formation/PHUIFormationView.php | 27 ++- webroot/rsrc/css/phui/phui-formation-view.css | 6 + .../js/application/diff/DiffChangesetList.js | 29 +++- .../differential/behavior-populate.js | 18 +- .../js/phui/behavior-phuix-formation-view.js | 54 ------ .../rsrc/js/phuix/PHUIXFormationColumnView.js | 49 ++++-- webroot/rsrc/js/phuix/PHUIXFormationView.js | 61 ++++++- 16 files changed, 452 insertions(+), 167 deletions(-) create mode 100644 src/applications/differential/engine/DifferentialFileTreeEngine.php delete mode 100644 webroot/rsrc/js/phui/behavior-phuix-formation-view.js diff --git a/resources/celerity/map.php b/resources/celerity/map.php index debb915232..e37513ba1a 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -12,7 +12,7 @@ return array( 'core.pkg.css' => 'a4a2417c', 'core.pkg.js' => '4355a8d3', 'differential.pkg.css' => '607c84be', - 'differential.pkg.js' => '1a72918e', + 'differential.pkg.js' => 'e40c5192', 'diffusion.pkg.css' => '42c75c37', 'diffusion.pkg.js' => 'a98c0bf7', 'maniphest.pkg.css' => '35995d6d', @@ -155,7 +155,7 @@ return array( 'rsrc/css/phui/phui-fontkit.css' => '1ec937e5', 'rsrc/css/phui/phui-form-view.css' => '01b796c0', 'rsrc/css/phui/phui-form.css' => '1f177cb7', - 'rsrc/css/phui/phui-formation-view.css' => 'aec68a01', + 'rsrc/css/phui/phui-formation-view.css' => 'e87a0801', 'rsrc/css/phui/phui-head-thing.css' => 'd7f293df', 'rsrc/css/phui/phui-header-view.css' => '36c86a58', 'rsrc/css/phui/phui-hovercard.css' => '6ca90fa0', @@ -379,11 +379,11 @@ return array( 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9', 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', 'rsrc/js/application/diff/DiffChangeset.js' => '5a4e4a3b', - 'rsrc/js/application/diff/DiffChangesetList.js' => '139299d7', + 'rsrc/js/application/diff/DiffChangesetList.js' => '3ac694dd', 'rsrc/js/application/diff/DiffInline.js' => '16e97ebc', 'rsrc/js/application/diff/behavior-preview-link.js' => 'f51e9c17', 'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd', - 'rsrc/js/application/differential/behavior-populate.js' => 'dfa1d313', + 'rsrc/js/application/differential/behavior-populate.js' => 'b86ef6c2', 'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => '94243d89', 'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'b7b73831', 'rsrc/js/application/diffusion/behavior-commit-branches.js' => '4b671572', @@ -520,7 +520,6 @@ return array( 'rsrc/js/phui/behavior-phui-submenu.js' => 'b5e9bff9', 'rsrc/js/phui/behavior-phui-tab-group.js' => '242aa08b', 'rsrc/js/phui/behavior-phui-timer-control.js' => 'f84bcbf4', - 'rsrc/js/phui/behavior-phuix-formation-view.js' => '1a12beef', 'rsrc/js/phuix/PHUIXActionListView.js' => 'c68f183f', 'rsrc/js/phuix/PHUIXActionView.js' => 'aaa08f3b', 'rsrc/js/phuix/PHUIXAutocomplete.js' => '2fbe234d', @@ -528,9 +527,9 @@ return array( 'rsrc/js/phuix/PHUIXDropdownMenu.js' => '7acfd98b', 'rsrc/js/phuix/PHUIXExample.js' => 'c2c500a7', 'rsrc/js/phuix/PHUIXFormControl.js' => '38c1f3fb', - 'rsrc/js/phuix/PHUIXFormationColumnView.js' => '08fc09e9', + 'rsrc/js/phuix/PHUIXFormationColumnView.js' => '8afd2cb1', 'rsrc/js/phuix/PHUIXFormationFlankView.js' => '6648270a', - 'rsrc/js/phuix/PHUIXFormationView.js' => '0113c54c', + 'rsrc/js/phuix/PHUIXFormationView.js' => 'cef53b3e', 'rsrc/js/phuix/PHUIXIconView.js' => 'a5257c4e', ), 'symbols' => array( @@ -614,7 +613,7 @@ return array( 'javelin-behavior-device' => '0cf79f45', 'javelin-behavior-diff-preview-link' => 'f51e9c17', 'javelin-behavior-differential-diff-radios' => '925fe8cd', - 'javelin-behavior-differential-populate' => 'dfa1d313', + 'javelin-behavior-differential-populate' => 'b86ef6c2', 'javelin-behavior-diffusion-commit-branches' => '4b671572', 'javelin-behavior-diffusion-commit-graph' => 'ef836bf2', 'javelin-behavior-diffusion-locate-file' => '87428eb2', @@ -672,7 +671,6 @@ return array( 'javelin-behavior-phui-tab-group' => '242aa08b', 'javelin-behavior-phui-timer-control' => 'f84bcbf4', 'javelin-behavior-phuix-example' => 'c2c500a7', - 'javelin-behavior-phuix-formation-view' => '1a12beef', 'javelin-behavior-policy-control' => '0eaa33a9', 'javelin-behavior-policy-rule-editor' => '9347f172', 'javelin-behavior-project-boards' => '58cb6a88', @@ -781,7 +779,7 @@ return array( 'phabricator-darkmessage' => '26cd4b73', 'phabricator-dashboard-css' => '5a205b9d', 'phabricator-diff-changeset' => '5a4e4a3b', - 'phabricator-diff-changeset-list' => '139299d7', + 'phabricator-diff-changeset-list' => '3ac694dd', 'phabricator-diff-inline' => '16e97ebc', 'phabricator-drag-and-drop-file-upload' => '4370900d', 'phabricator-draggable-list' => '0169e425', @@ -850,7 +848,7 @@ return array( 'phui-fontkit-css' => '1ec937e5', 'phui-form-css' => '1f177cb7', 'phui-form-view-css' => '01b796c0', - 'phui-formation-view-css' => 'aec68a01', + 'phui-formation-view-css' => 'e87a0801', 'phui-head-thing-view-css' => 'd7f293df', 'phui-header-view-css' => '36c86a58', 'phui-hovercard' => '074f0783', @@ -893,9 +891,9 @@ return array( 'phuix-button-view' => '55a24e84', 'phuix-dropdown-menu' => '7acfd98b', 'phuix-form-control-view' => '38c1f3fb', - 'phuix-formation-column-view' => '08fc09e9', + 'phuix-formation-column-view' => '8afd2cb1', 'phuix-formation-flank-view' => '6648270a', - 'phuix-formation-view' => '0113c54c', + 'phuix-formation-view' => 'cef53b3e', 'phuix-icon-view' => 'a5257c4e', 'policy-css' => 'ceb56a08', 'policy-edit-css' => '8794e2ed', @@ -922,10 +920,6 @@ return array( 'unhandled-exception-css' => '9ecfc00d', ), 'requires' => array( - '0113c54c' => array( - 'javelin-install', - 'javelin-dom', - ), '0116d3e8' => array( 'javelin-behavior', 'javelin-dom', @@ -998,10 +992,6 @@ return array( 'javelin-util', 'javelin-magical-init', ), - '08fc09e9' => array( - 'javelin-install', - 'javelin-dom', - ), '0922e81d' => array( 'herald-rule-editor', 'javelin-behavior', @@ -1041,10 +1031,6 @@ return array( 'javelin-uri', 'phabricator-keyboard-shortcut', ), - '139299d7' => array( - 'javelin-install', - 'phuix-button-view', - ), '139ef688' => array( 'javelin-behavior', 'javelin-dom', @@ -1054,12 +1040,6 @@ return array( '16e97ebc' => array( 'javelin-dom', ), - '1a12beef' => array( - 'javelin-behavior', - 'phuix-formation-view', - 'phuix-formation-column-view', - 'phuix-formation-flank-view', - ), '1a844c06' => array( 'javelin-install', 'javelin-util', @@ -1260,6 +1240,10 @@ return array( 'trigger-rule', 'trigger-rule-type', ), + '3ac694dd' => array( + 'javelin-install', + 'phuix-button-view', + ), '3ae89b20' => array( 'phui-workcard-view-css', ), @@ -1710,6 +1694,10 @@ return array( 'javelin-dom', 'phabricator-draggable-list', ), + '8afd2cb1' => array( + 'javelin-install', + 'javelin-dom', + ), '8b5c7d65' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2012,6 +2000,15 @@ return array( 'javelin-util', 'phabricator-shaped-request', ), + 'b86ef6c2' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'phabricator-tooltip', + 'phabricator-diff-changeset-list', + 'phabricator-diff-changeset', + 'phuix-formation-view', + ), 'b86f297f' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2084,6 +2081,12 @@ return array( 'phuix-icon-view', 'phabricator-busy', ), + 'cef53b3e' => array( + 'javelin-install', + 'javelin-dom', + 'phuix-formation-column-view', + 'phuix-formation-flank-view', + ), 'cf32921f' => array( 'javelin-behavior', 'javelin-dom', @@ -2116,14 +2119,6 @@ return array( 'javelin-uri', 'phabricator-notification', ), - 'dfa1d313' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'phabricator-tooltip', - 'phabricator-diff-changeset-list', - 'phabricator-diff-changeset', - ), 'e150bd50' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ecf0010678..421f678326 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -539,6 +539,7 @@ phutil_register_library_map(array( 'DifferentialExactUserFunctionDatasource' => 'applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php', 'DifferentialFieldParseException' => 'applications/differential/exception/DifferentialFieldParseException.php', 'DifferentialFieldValidationException' => 'applications/differential/exception/DifferentialFieldValidationException.php', + 'DifferentialFileTreeEngine' => 'applications/differential/engine/DifferentialFileTreeEngine.php', 'DifferentialGetAllDiffsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetAllDiffsConduitAPIMethod.php', 'DifferentialGetCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php', 'DifferentialGetCommitPathsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetCommitPathsConduitAPIMethod.php', @@ -6599,6 +6600,7 @@ phutil_register_library_map(array( 'DifferentialExactUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'DifferentialFieldParseException' => 'Exception', 'DifferentialFieldValidationException' => 'Exception', + 'DifferentialFileTreeEngine' => 'Phobject', 'DifferentialGetAllDiffsConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialGetCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod', 'DifferentialGetCommitPathsConduitAPIMethod' => 'DifferentialConduitAPIMethod', @@ -8332,7 +8334,7 @@ phutil_register_library_map(array( 'PHUIFormationExpanderView' => 'AphrontAutoIDView', 'PHUIFormationFlankView' => 'PHUIFormationColumnDynamicView', 'PHUIFormationResizerView' => 'PHUIFormationColumnView', - 'PHUIFormationView' => 'AphrontView', + 'PHUIFormationView' => 'AphrontAutoIDView', 'PHUIHandleListView' => 'AphrontTagView', 'PHUIHandleTagListView' => 'AphrontTagView', 'PHUIHandleView' => 'AphrontView', diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php index b0471e7c5f..a004bcebab 100644 --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -474,16 +474,14 @@ final class DifferentialRevisionViewController ->setKey('history') ->appendChild($history)); - $filetree_on = $viewer->compareUserSetting( - PhabricatorShowFiletreeSetting::SETTINGKEY, - PhabricatorShowFiletreeSetting::VALUE_ENABLE_FILETREE); + $filetree = id(new DifferentialFileTreeEngine()) + ->setViewer($viewer); - $collapsed_key = PhabricatorFiletreeVisibleSetting::SETTINGKEY; - $filetree_collapsed = (bool)$viewer->getUserSetting($collapsed_key); + $filetree_collapsed = !$filetree->getIsVisible(); // See PHI811. If the viewer has the file tree on, the files tab with the // table of contents is redundant, so default to the "History" tab instead. - if ($filetree_on && !$filetree_collapsed) { + if (!$filetree_collapsed) { $tab_group->selectTab('history'); } @@ -609,18 +607,9 @@ final class DifferentialRevisionViewController $crumbs->addTextCrumb($monogram); $crumbs->setBorder(true); - $nav = null; - if ($filetree_on && !$this->isVeryLargeDiff()) { - $width_key = PhabricatorFiletreeWidthSetting::SETTINGKEY; - $width_value = $viewer->getUserSetting($width_key); - - $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) - ->setTitle($monogram) - ->setBaseURI(new PhutilURI($revision->getURI())) - ->setCollapsed($filetree_collapsed) - ->setWidth((int)$width_value) - ->build($changesets); - } + $filetree + ->setChangesets($changesets) + ->setDisabled($this->isVeryLargeDiff()); $view = id(new PHUITwoColumnView()) ->setHeader($header) @@ -638,16 +627,22 @@ final class DifferentialRevisionViewController )) ->setFooter($footer); - $page = $this->newPage() - ->setTitle($monogram.' '.$revision->getTitle()) - ->setCrumbs($crumbs) - ->setPageObjectPHIDs(array($revision->getPHID())) - ->appendChild($view); + $main_content = array( + $crumbs, + $view, + ); - if ($nav) { - $page->setNavigation($nav); + $main_content = $filetree->newView($main_content); + + if (!$filetree->getDisabled()) { + $changeset_view->setFormationView($main_content); } + $page = $this->newPage() + ->setTitle($monogram.' '.$revision->getTitle()) + ->setPageObjectPHIDs(array($revision->getPHID())) + ->appendChild($main_content); + return $page; } diff --git a/src/applications/differential/engine/DifferentialFileTreeEngine.php b/src/applications/differential/engine/DifferentialFileTreeEngine.php new file mode 100644 index 0000000000..a07e620678 --- /dev/null +++ b/src/applications/differential/engine/DifferentialFileTreeEngine.php @@ -0,0 +1,155 @@ +viewer = $viewer; + return $this; + } + + public function getViewer() { + return $this->viewer; + } + + public function getIsVisible() { + return (bool)$this->getSetting($this->getVisibleSettingKey()); + } + + public function setDisabled($disabled) { + $this->disabled = $disabled; + return $this; + } + + public function getDisabled() { + return $this->disabled; + } + + public function setChangesets(array $changesets) { + $this->changesets = $changesets; + return $this; + } + + public function getChangesets() { + return $this->changesets; + } + + public function newView($content) { + if ($this->getDisabled()) { + return $content; + } + + $width = $this->getWidth(); + $is_visible = $this->getIsVisible(); + + $formation_view = new PHUIFormationView(); + + $flank_view = $formation_view->newFlankColumn() + ->setHeaderText(pht('Affected Paths')) + ->setIsResizable(true) + ->setIsFixed(true) + ->setIsVisible($is_visible) + ->setWidth($width) + ->setMinimumWidth($this->getMinimumWidth()) + ->setMaximumWidth($this->getMaximumWidth()); + + $viewer = $this->getViewer(); + if ($viewer->isLoggedIn()) { + $flank_view + ->setVisibleSettingKey($this->getVisibleSettingKey()) + ->setWidthSettingKey($this->getWidthSettingKey()); + } + + $flank_view->setHead( + array( + phutil_tag('div', array(), + array( + id(new PHUIIconView())->setIcon('fa-list'), + pht('Table of Contents'), + '[t]', + )), + )); + + $flank_view->setBody( + phutil_tag( + 'div', + array( + 'class' => 'phui-flank-loading', + ), + pht('Loading...'))); + + $flank_view->setTail( + array( + phutil_tag('div', array(), + array( + id(new PHUIIconView())->setIcon('fa-chevron-left'), + pht('Hide Panel'), + '[f]', + )), + phutil_tag( + 'div', + array(), + array( + id(new PHUIIconView())->setIcon('fa-keyboard-o'), + pht('Keyboard Reference'), + '[?]', + )), + )); + + $main_column = $formation_view->newContentColumn() + ->appendChild($content); + + return $formation_view; + } + + private function getVisibleSettingKey() { + return PhabricatorFiletreeVisibleSetting::SETTINGKEY; + } + + private function getWidthSettingKey() { + return PhabricatorFiletreeWidthSetting::SETTINGKEY; + } + + private function getWidth() { + $width = (int)$this->getSetting($this->getWidthSettingKey()); + + if (!$width) { + $width = $this->getDefaultWidth(); + } + + $min = $this->getMinimumWidth(); + if ($width < $min) { + $width = $min; + } + + $max = $this->getMaximumWidth(); + if ($width > $max) { + $width = $max; + } + + return $width; + } + + private function getDefaultWidth() { + return 240; + } + + private function getMinimumWidth() { + return 150; + } + + private function getMaximumWidth() { + return 512; + } + + private function getSetting($key) { + $viewer = $this->getViewer(); + return $viewer->getUserSetting($key); + } + + +} diff --git a/src/applications/differential/view/DifferentialChangesetListView.php b/src/applications/differential/view/DifferentialChangesetListView.php index 1783e7d8ad..02af0047a4 100644 --- a/src/applications/differential/view/DifferentialChangesetListView.php +++ b/src/applications/differential/view/DifferentialChangesetListView.php @@ -24,6 +24,7 @@ final class DifferentialChangesetListView extends AphrontView { private $title; private $parser; + private $formationView; public function setParser(DifferentialChangesetParser $parser) { $this->parser = $parser; @@ -146,6 +147,15 @@ final class DifferentialChangesetListView extends AphrontView { return $this; } + public function setFormationView(PHUIFormationView $formation_view) { + $this->formationView = $formation_view; + return $this; + } + + public function getFormationView() { + return $this->formationView; + } + public function render() { $viewer = $this->getViewer(); @@ -232,10 +242,17 @@ final class DifferentialChangesetListView extends AphrontView { $this->requireResource('aphront-tooltip-css'); + $formation_id = null; + $formation_view = $this->getFormationView(); + if ($formation_view) { + $formation_id = $formation_view->getID(); + } + $this->initBehavior( 'differential-populate', array( 'changesetViewIDs' => $ids, + 'formationViewID' => $formation_id, 'inlineURI' => $this->inlineURI, 'inlineListURI' => $this->inlineListURI, 'isStandalone' => $this->getIsStandalone(), diff --git a/src/view/formation/PHUIFormationColumnDynamicView.php b/src/view/formation/PHUIFormationColumnDynamicView.php index 1c0853fd2b..c967ee72e8 100644 --- a/src/view/formation/PHUIFormationColumnDynamicView.php +++ b/src/view/formation/PHUIFormationColumnDynamicView.php @@ -6,6 +6,10 @@ abstract class PHUIFormationColumnDynamicView private $isVisible = true; private $isResizable; private $width; + private $widthSettingKey; + private $visibleSettingKey; + private $minimumWidth; + private $maximumWidth; public function setIsVisible($is_visible) { $this->isVisible = $is_visible; @@ -34,4 +38,40 @@ abstract class PHUIFormationColumnDynamicView return $this->width; } + public function setWidthSettingKey($width_setting_key) { + $this->widthSettingKey = $width_setting_key; + return $this; + } + + public function getWidthSettingKey() { + return $this->widthSettingKey; + } + + public function setVisibleSettingKey($visible_setting_key) { + $this->visibleSettingKey = $visible_setting_key; + return $this; + } + + public function getVisibleSettingKey() { + return $this->visibleSettingKey; + } + + public function setMinimumWidth($minimum_width) { + $this->minimumWidth = $minimum_width; + return $this; + } + + public function getMinimumWidth() { + return $this->minimumWidth; + } + + public function setMaximumWidth($maximum_width) { + $this->maximumWidth = $maximum_width; + return $this; + } + + public function getMaximumWidth() { + return $this->maximumWidth; + } + } diff --git a/src/view/formation/PHUIFormationColumnItem.php b/src/view/formation/PHUIFormationColumnItem.php index 0897afd4e9..b2607127a1 100644 --- a/src/view/formation/PHUIFormationColumnItem.php +++ b/src/view/formation/PHUIFormationColumnItem.php @@ -73,6 +73,8 @@ final class PHUIFormationColumnItem } public function newClientProperties() { + $column = $this->getColumn(); + $expander_id = null; $expander = $this->getExpander(); @@ -80,18 +82,24 @@ final class PHUIFormationColumnItem $expander_id = $expander->getID(); } - $resizer_details = null; $resizer_item = $this->getResizerItem(); if ($resizer_item) { + $visible_key = $column->getVisibleSettingKey(); + $width_key = $column->getWidthSettingKey(); + $min_width = $column->getMinimumWidth(); + $max_width = $column->getMaximumWidth(); + $resizer_details = array( 'itemID' => $resizer_item->getID(), 'controlID' => $resizer_item->getColumn()->getID(), + 'widthKey' => $width_key, + 'visibleKey' => $visible_key, + 'minimumWidth' => $min_width, + 'maximumWidth' => $max_width, ); } - $column = $this->getColumn(); - $width = $column->getWidth(); if ($width !== null) { $width = (int)$width; diff --git a/src/view/formation/PHUIFormationColumnView.php b/src/view/formation/PHUIFormationColumnView.php index d15da9cc56..0d76756540 100644 --- a/src/view/formation/PHUIFormationColumnView.php +++ b/src/view/formation/PHUIFormationColumnView.php @@ -30,6 +30,22 @@ abstract class PHUIFormationColumnView return false; } + public function getVisibleSettingKey() { + return null; + } + + public function getWidthSettingKey() { + return null; + } + + public function getMinimumWidth() { + return null; + } + + public function getMaximumWidth() { + return null; + } + public function newClientProperties() { return null; } diff --git a/src/view/formation/PHUIFormationFlankView.php b/src/view/formation/PHUIFormationFlankView.php index 35eca5fbc7..1a633a4c29 100644 --- a/src/view/formation/PHUIFormationFlankView.php +++ b/src/view/formation/PHUIFormationFlankView.php @@ -99,7 +99,7 @@ final class PHUIFormationFlankView $body_id = $this->getBodyID(); $tail_id = $this->getTailID(); - $head_content = phutil_tag( + $header = phutil_tag( 'div', array( 'class' => 'phui-flank-header', @@ -128,21 +128,24 @@ final class PHUIFormationFlankView 'id' => $head_id, 'class' => 'phui-flank-view-head', ), - $head_content), + array( + $header, + $this->head, + )), phutil_tag( 'div', array( 'id' => $body_id, 'class' => 'phui-flank-view-body', ), - $this->getBody()), + $this->body), phutil_tag( 'div', array( 'id' => $tail_id, 'class' => 'phui-flank-view-tail', ), - $this->getTail()), + $this->tail), )); return $content; diff --git a/src/view/formation/PHUIFormationView.php b/src/view/formation/PHUIFormationView.php index 6dbb23fac0..72d699486b 100644 --- a/src/view/formation/PHUIFormationView.php +++ b/src/view/formation/PHUIFormationView.php @@ -1,7 +1,7 @@ newClientProperties(); + } $table_row = phutil_tag('tr', array(), $cells); $table_body = phutil_tag('tbody', array(), $table_row); - $table = phutil_tag( + $table = javelin_tag( 'table', array( + 'id' => $this->getID(), 'class' => 'phui-formation-view', - 'id' => $formation_id, + 'sigil' => 'phuix-formation-view', + 'meta' => array( + 'items' => $phuix_items, + ), ), $table_body); - $phuix_columns = array(); - foreach ($items as $item) { - $phuix_columns[] = $item->newClientProperties(); - } - - Javelin::initBehavior( - 'phuix-formation-view', - array( - 'nodeID' => $formation_id, - 'columns' => $phuix_columns, - )); - return $table; } diff --git a/webroot/rsrc/css/phui/phui-formation-view.css b/webroot/rsrc/css/phui/phui-formation-view.css index 60c6317c18..180d017c70 100644 --- a/webroot/rsrc/css/phui/phui-formation-view.css +++ b/webroot/rsrc/css/phui/phui-formation-view.css @@ -143,3 +143,9 @@ bottom: 0; width: 100%; } + +.phui-flank-loading { + color: {$lightgreytext}; + text-align: center; + margin: 16px; +} diff --git a/webroot/rsrc/js/application/diff/DiffChangesetList.js b/webroot/rsrc/js/application/diff/DiffChangesetList.js index 2208c60d18..ace4d8ccbd 100644 --- a/webroot/rsrc/js/application/diff/DiffChangesetList.js +++ b/webroot/rsrc/js/application/diff/DiffChangesetList.js @@ -90,7 +90,8 @@ JX.install('DiffChangesetList', { translations: null, inlineURI: null, inlineListURI: null, - isStandalone: false + isStandalone: false, + formationView: null }, members: { @@ -143,6 +144,8 @@ JX.install('DiffChangesetList', { this._bannerChangeset = null; this._redrawBanner(); + this._redrawFiletree(); + if (this._initialized) { return; } @@ -1953,7 +1956,31 @@ JX.install('DiffChangesetList', { } return null; + }, + + _redrawFiletree : function() { + var formation = this.getFormationView(); + + if (!formation) { + return; + } + + var filetree = formation.getColumn(0); + var flank = filetree.getFlank(); + + var flank_body = flank.getBodyNode(); + + var items = []; + for (var ii = 0; ii < this._changesets.length; ii++) { + var changeset = this._changesets[ii]; + + var node = JX.$N('div', {}, changeset.getDisplayPath()); + items.push(node); + } + + JX.DOM.setContent(flank_body, items); } + } }); diff --git a/webroot/rsrc/js/application/differential/behavior-populate.js b/webroot/rsrc/js/application/differential/behavior-populate.js index 5b415fd131..9581ef26e5 100644 --- a/webroot/rsrc/js/application/differential/behavior-populate.js +++ b/webroot/rsrc/js/application/differential/behavior-populate.js @@ -6,6 +6,7 @@ * phabricator-tooltip * phabricator-diff-changeset-list * phabricator-diff-changeset + * phuix-formation-view * @javelin */ @@ -64,12 +65,12 @@ JX.behavior('differential-populate', function(config, statics) { .setInlineListURI(config.inlineListURI) .setIsStandalone(config.isStandalone); - // Install and activate the current page. - var page_id = JX.Quicksand.getCurrentPageID(); - statics.pages[page_id] = [changeset_list]; - onredraw(page_id); - - + if (config.formationViewID) { + var formation_node = JX.$(config.formationViewID); + var formation_view = new JX.PHUIXFormationView(formation_node); + changeset_list.setFormationView(formation_view); + formation_view.start(); + } for (var ii = 0; ii < config.changesetViewIDs.length; ii++) { var id = config.changesetViewIDs[ii]; @@ -80,6 +81,11 @@ JX.behavior('differential-populate', function(config, statics) { } } + // Install and activate the current page. + var page_id = JX.Quicksand.getCurrentPageID(); + statics.pages[page_id] = [changeset_list]; + onredraw(page_id); + var highlighted = null; var highlight_class = null; diff --git a/webroot/rsrc/js/phui/behavior-phuix-formation-view.js b/webroot/rsrc/js/phui/behavior-phuix-formation-view.js deleted file mode 100644 index 0e2d12f2ef..0000000000 --- a/webroot/rsrc/js/phui/behavior-phuix-formation-view.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @provides javelin-behavior-phuix-formation-view - * @requires javelin-behavior - * phuix-formation-view - * phuix-formation-column-view - * phuix-formation-flank-view - */ - -JX.behavior('phuix-formation-view', function(config) { - - var formation_node = JX.$(config.nodeID); - var formation = new JX.PHUIXFormationView(formation_node); - - var count = config.columns.length; - for (var ii = 0; ii < count; ii++) { - var spec = config.columns[ii]; - var node = JX.$(spec.itemID); - - var column = new JX.PHUIXFormationColumnView(node) - .setIsRightAligned(spec.isRightAligned) - .setWidth(spec.width) - .setIsVisible(spec.isVisible); - - if (spec.expanderID) { - column.setExpanderNode(JX.$(spec.expanderID)); - } - - if (spec.resizer) { - column - .setResizerItem(JX.$(spec.resizer.itemID)) - .setResizerControl(JX.$(spec.resizer.controlID)); - } - - var colspec = spec.column; - if (colspec) { - if (colspec.type === 'flank') { - var flank_node = JX.$(colspec.nodeID); - - var head = JX.$(colspec.headID); - var body = JX.$(colspec.bodyID); - var tail = JX.$(colspec.tailID); - - var flank = new JX.PHUIXFormationFlankView(flank_node, head, body, tail) - .setIsFixed(colspec.isFixed); - - column.setFlank(flank); - } - } - - formation.addColumn(column); - } - - formation.start(); -}); diff --git a/webroot/rsrc/js/phuix/PHUIXFormationColumnView.js b/webroot/rsrc/js/phuix/PHUIXFormationColumnView.js index 993fe7b016..2adc462a8d 100644 --- a/webroot/rsrc/js/phuix/PHUIXFormationColumnView.js +++ b/webroot/rsrc/js/phuix/PHUIXFormationColumnView.js @@ -17,6 +17,10 @@ JX.install('PHUIXFormationColumnView', { resizerItem: null, resizerControl: null, width: null, + widthSettingKey: null, + visibleSettingKey: null, + minimumWidth: null, + maximumWidth: null, flank: null }, @@ -83,9 +87,15 @@ JX.install('PHUIXFormationColumnView', { width = this.getWidth() + dx; } - // TODO: Make these configurable? - width = Math.max(width, 150); - width = Math.min(width, 512); + var min_width = this.getMinimumWidth(); + if (min_width) { + width = Math.max(width, min_width); + } + + var max_width = this.getMaximumWidth(); + if (max_width) { + width = Math.min(width, max_width); + } this._resizingWidth = width; @@ -114,30 +124,35 @@ JX.install('PHUIXFormationColumnView', { this.setWidth(this._resizingWidth); - JX.log('new width is ' + this.getWidth()); - JX.DOM.alterClass(document.body, 'jx-drag-col', false); this._dragging = null; - // TODO: Save new width setting. - - // new JX.Request('/settings/adjust/', JX.bag) - // .setData( - // { - // key: 'filetree.width', - // value: get_width() - // }) - // .send(); - + var width_key = this.getWidthSettingKey(); + if (width_key) { + this._adjustSetting(width_key, this.getWidth()); + } }, _setVisibility: function(visible, e) { e.kill(); - // TODO: Save the visibility setting. - this.setIsVisible(visible); this.repaint(); + + var visible_key = this.getVisibleSettingKey(); + if (visible_key) { + this._adjustSetting(visible_key, visible ? 1 : 0); + } + }, + + _adjustSetting: function(key, value) { + new JX.Request('/settings/adjust/', JX.bag) + .setData( + { + key: key, + value: value + }) + .send(); }, repaint: function() { diff --git a/webroot/rsrc/js/phuix/PHUIXFormationView.js b/webroot/rsrc/js/phuix/PHUIXFormationView.js index 9ab9ad2019..b31e7878da 100644 --- a/webroot/rsrc/js/phuix/PHUIXFormationView.js +++ b/webroot/rsrc/js/phuix/PHUIXFormationView.js @@ -2,21 +2,80 @@ * @provides phuix-formation-view * @requires javelin-install * javelin-dom + * phuix-formation-column-view + * phuix-formation-flank-view */ JX.install('PHUIXFormationView', { - construct: function() { + construct: function(node) { + this._node = node; this._columns = []; + + var config = JX.Stratcom.getData(this._node); + + var items = config.items; + var count = items.length; + for (var ii = 0; ii < count; ii++) { + var item = items[ii]; + var item_node = JX.$(item.itemID); + + var column = new JX.PHUIXFormationColumnView(item_node) + .setIsRightAligned(item.isRightAligned) + .setWidth(item.width) + .setIsVisible(item.isVisible); + + if (item.expanderID) { + column.setExpanderNode(JX.$(item.expanderID)); + } + + if (item.resizer) { + column + .setWidthSettingKey(item.resizer.widthKey) + .setVisibleSettingKey(item.resizer.visibleKey) + .setMinimumWidth(item.resizer.minimumWidth) + .setMaximumWidth(item.resizer.maximumWidth) + .setResizerItem(JX.$(item.resizer.itemID)) + .setResizerControl(JX.$(item.resizer.controlID)); + } + + var spec = item.column; + if (spec) { + if (spec.type === 'flank') { + var flank_node = JX.$(spec.nodeID); + + var head = JX.$(spec.headID); + var body = JX.$(spec.bodyID); + var tail = JX.$(spec.tailID); + + var flank = new JX.PHUIXFormationFlankView( + flank_node, + head, + body, + tail); + + flank.setIsFixed(spec.isFixed); + + column.setFlank(flank); + } + } + + this.addColumn(column); + } }, members: { + _node: null, _columns: null, addColumn: function(column) { this._columns.push(column); }, + getColumn: function(idx) { + return this._columns[idx]; + }, + start: function() { JX.enableDispatch(document.body, 'mousemove');