1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

Generate file trees from changesets in the new flank UI

Summary: Ref T13516. Generate a tree structure based on the page changesets. Still missing styles and a whole lot of behavior.

Test Plan: {F7373967}

Maniphest Tasks: T13516

Differential Revision: https://secure.phabricator.com/D21152
This commit is contained in:
epriestley 2020-04-21 09:56:30 -07:00
parent 646280972b
commit 8cd1f9a309
6 changed files with 352 additions and 31 deletions

View file

@ -12,7 +12,7 @@ return array(
'core.pkg.css' => 'a4a2417c', 'core.pkg.css' => 'a4a2417c',
'core.pkg.js' => '4355a8d3', 'core.pkg.js' => '4355a8d3',
'differential.pkg.css' => '607c84be', 'differential.pkg.css' => '607c84be',
'differential.pkg.js' => 'e40c5192', 'differential.pkg.js' => '688775a9',
'diffusion.pkg.css' => '42c75c37', 'diffusion.pkg.css' => '42c75c37',
'diffusion.pkg.js' => 'a98c0bf7', 'diffusion.pkg.js' => 'a98c0bf7',
'maniphest.pkg.css' => '35995d6d', 'maniphest.pkg.css' => '35995d6d',
@ -378,9 +378,11 @@ return array(
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be', 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be',
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9', 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9',
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8',
'rsrc/js/application/diff/DiffChangeset.js' => '5a4e4a3b', 'rsrc/js/application/diff/DiffChangeset.js' => 'd1eda7b4',
'rsrc/js/application/diff/DiffChangesetList.js' => '3ac694dd', 'rsrc/js/application/diff/DiffChangesetList.js' => '469beba0',
'rsrc/js/application/diff/DiffInline.js' => '16e97ebc', 'rsrc/js/application/diff/DiffInline.js' => '16e97ebc',
'rsrc/js/application/diff/DiffPathView.js' => 'e5166692',
'rsrc/js/application/diff/DiffTreeView.js' => '4055adeb',
'rsrc/js/application/diff/behavior-preview-link.js' => 'f51e9c17', 'rsrc/js/application/diff/behavior-preview-link.js' => 'f51e9c17',
'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd', 'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd',
'rsrc/js/application/differential/behavior-populate.js' => 'b86ef6c2', 'rsrc/js/application/differential/behavior-populate.js' => 'b86ef6c2',
@ -778,9 +780,11 @@ return array(
'phabricator-darklog' => '3b869402', 'phabricator-darklog' => '3b869402',
'phabricator-darkmessage' => '26cd4b73', 'phabricator-darkmessage' => '26cd4b73',
'phabricator-dashboard-css' => '5a205b9d', 'phabricator-dashboard-css' => '5a205b9d',
'phabricator-diff-changeset' => '5a4e4a3b', 'phabricator-diff-changeset' => 'd1eda7b4',
'phabricator-diff-changeset-list' => '3ac694dd', 'phabricator-diff-changeset-list' => '469beba0',
'phabricator-diff-inline' => '16e97ebc', 'phabricator-diff-inline' => '16e97ebc',
'phabricator-diff-path-view' => 'e5166692',
'phabricator-diff-tree-view' => '4055adeb',
'phabricator-drag-and-drop-file-upload' => '4370900d', 'phabricator-drag-and-drop-file-upload' => '4370900d',
'phabricator-draggable-list' => '0169e425', 'phabricator-draggable-list' => '0169e425',
'phabricator-fatal-config-template-css' => '20babf50', 'phabricator-fatal-config-template-css' => '20babf50',
@ -1240,10 +1244,6 @@ return array(
'trigger-rule', 'trigger-rule',
'trigger-rule-type', 'trigger-rule-type',
), ),
'3ac694dd' => array(
'javelin-install',
'phuix-button-view',
),
'3ae89b20' => array( '3ae89b20' => array(
'phui-workcard-view-css', 'phui-workcard-view-css',
), ),
@ -1267,6 +1267,9 @@ return array(
'phabricator-drag-and-drop-file-upload', 'phabricator-drag-and-drop-file-upload',
'phabricator-draggable-list', 'phabricator-draggable-list',
), ),
'4055adeb' => array(
'javelin-dom',
),
'407ee861' => array( '407ee861' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-uri', 'javelin-uri',
@ -1316,6 +1319,11 @@ return array(
'javelin-util', 'javelin-util',
'phabricator-busy', 'phabricator-busy',
), ),
'469beba0' => array(
'javelin-install',
'phuix-button-view',
'phabricator-diff-tree-view',
),
'47a0728b' => array( '47a0728b' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
@ -1466,17 +1474,6 @@ return array(
'javelin-dom', 'javelin-dom',
'javelin-history', 'javelin-history',
), ),
'5a4e4a3b' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-workflow',
'javelin-router',
'javelin-behavior-device',
'javelin-vector',
'phabricator-diff-inline',
),
'5a6f6a06' => array( '5a6f6a06' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-quicksand', 'javelin-quicksand',
@ -2099,6 +2096,18 @@ return array(
'javelin-workflow', 'javelin-workflow',
'javelin-util', 'javelin-util',
), ),
'd1eda7b4' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'javelin-workflow',
'javelin-router',
'javelin-behavior-device',
'javelin-vector',
'phabricator-diff-inline',
'phabricator-diff-path-view',
),
'd3799cb4' => array( 'd3799cb4' => array(
'javelin-install', 'javelin-install',
), ),
@ -2125,6 +2134,9 @@ return array(
'javelin-dom', 'javelin-dom',
'phuix-dropdown-menu', 'phuix-dropdown-menu',
), ),
'e5166692' => array(
'javelin-dom',
),
'e5bdb730' => array( 'e5bdb730' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-stratcom', 'javelin-stratcom',

View file

@ -178,6 +178,9 @@ final class DifferentialChangesetDetailView extends AphrontView {
$changeset_state = null; $changeset_state = null;
} }
$path_parts = trim($display_filename, '/');
$path_parts = explode('/', $path_parts);
return javelin_tag( return javelin_tag(
'div', 'div',
array( array(
@ -189,9 +192,9 @@ final class DifferentialChangesetDetailView extends AphrontView {
'ref' => $this->getRenderingRef(), 'ref' => $this->getRenderingRef(),
'autoload' => $this->getAutoload(), 'autoload' => $this->getAutoload(),
'displayPath' => hsprintf('%s', $display_parts), 'displayPath' => hsprintf('%s', $display_parts),
'path' => $display_filename,
'icon' => $display_icon, 'icon' => $display_icon,
'treeNodeID' => 'tree-node-'.$changeset->getAnchorName(), 'treeNodeID' => 'tree-node-'.$changeset->getAnchorName(),
'pathParts' => $path_parts,
'editorURI' => $this->getEditorURI(), 'editorURI' => $this->getEditorURI(),
'editorConfigureURI' => $this->getEditorConfigureURI(), 'editorConfigureURI' => $this->getEditorConfigureURI(),

View file

@ -9,10 +9,10 @@
* javelin-behavior-device * javelin-behavior-device
* javelin-vector * javelin-vector
* phabricator-diff-inline * phabricator-diff-inline
* phabricator-diff-path-view
* @javelin * @javelin
*/ */
JX.install('DiffChangeset', { JX.install('DiffChangeset', {
construct : function(node) { construct : function(node) {
@ -29,6 +29,7 @@ JX.install('DiffChangeset', {
this._rightID = data.right; this._rightID = data.right;
this._displayPath = JX.$H(data.displayPath); this._displayPath = JX.$H(data.displayPath);
this._pathParts = data.pathParts;
this._icon = data.icon; this._icon = data.icon;
this._editorURI = data.editorURI; this._editorURI = data.editorURI;
@ -70,6 +71,7 @@ JX.install('DiffChangeset', {
_editorURI: null, _editorURI: null,
_editorConfigureURI: null, _editorConfigureURI: null,
_pathView: null,
getEditorURI: function() { getEditorURI: function() {
return this._editorURI; return this._editorURI;
@ -891,6 +893,21 @@ JX.install('DiffChangeset', {
_onundo: function(e) { _onundo: function(e) {
e.kill(); e.kill();
this.toggleVisibility(); this.toggleVisibility();
},
getPathView: function() {
if (!this._pathView) {
this._pathView = new JX.DiffPathView()
.setChangeset(this)
.setPath(this._pathParts);
}
return this._pathView;
},
select: function(scroll) {
this.getChangesetList().selectChangeset(this, scroll);
return this;
} }
}, },

View file

@ -2,6 +2,7 @@
* @provides phabricator-diff-changeset-list * @provides phabricator-diff-changeset-list
* @requires javelin-install * @requires javelin-install
* phuix-button-view * phuix-button-view
* phabricator-diff-tree-view
* @javelin * @javelin
*/ */
@ -640,6 +641,25 @@ JX.install('DiffChangesetList', {
}; };
}, },
selectChangeset: function(changeset, scroll) {
var items = this._getSelectableItems();
var cursor = null;
for (var ii = 0; ii < items.length; ii++) {
var item = items[ii];
if (changeset === item.target) {
cursor = ii;
break;
}
}
if (cursor !== null) {
this._setSelectionState(items[cursor], true);
}
return this;
},
_setSelectionState: function(item, scroll) { _setSelectionState: function(item, scroll) {
this._cursorItem = item; this._cursorItem = item;
this._redrawSelection(scroll); this._redrawSelection(scroll);
@ -1467,10 +1487,18 @@ JX.install('DiffChangesetList', {
var node = this._getBannerNode(); var node = this._getBannerNode();
var changeset = this._getVisibleChangeset(); var changeset = this._getVisibleChangeset();
var tree = this._getTreeView();
var formation = this.getFormationView();
if (!changeset) { if (!changeset) {
this._bannerChangeset = null; this._bannerChangeset = null;
JX.DOM.remove(node); JX.DOM.remove(node);
tree.setSelectedPath(null);
if (formation) {
formation.repaint();
}
return; return;
} }
@ -1481,6 +1509,14 @@ JX.install('DiffChangesetList', {
} }
this._bannerChangeset = changeset; this._bannerChangeset = changeset;
var paths = tree.getPaths();
for (var ii = 0; ii < paths.length; ii++) {
var path = paths[ii];
if (path.getChangeset() === changeset) {
tree.setSelectedPath(path);
}
}
var inlines = this._getInlinesByType(); var inlines = this._getInlinesByType();
var unsaved = inlines.unsaved; var unsaved = inlines.unsaved;
@ -1586,6 +1622,10 @@ JX.install('DiffChangesetList', {
JX.DOM.setContent(node, [buttons_view, path_view]); JX.DOM.setContent(node, [buttons_view, path_view]);
document.body.appendChild(node); document.body.appendChild(node);
if (formation) {
formation.repaint();
}
}, },
_getInlinesByType: function() { _getInlinesByType: function() {
@ -1958,6 +1998,20 @@ JX.install('DiffChangesetList', {
return null; return null;
}, },
_getTreeView: function() {
if (!this._treeView) {
var tree = new JX.DiffTreeView();
for (var ii = 0; ii < this._changesets.length; ii++) {
var changeset = this._changesets[ii];
tree.addPath(changeset.getPathView());
}
this._treeView = tree;
}
return this._treeView;
},
_redrawFiletree : function() { _redrawFiletree : function() {
var formation = this.getFormationView(); var formation = this.getFormationView();
@ -1970,15 +2024,8 @@ JX.install('DiffChangesetList', {
var flank_body = flank.getBodyNode(); var flank_body = flank.getBodyNode();
var items = []; var tree = this._getTreeView();
for (var ii = 0; ii < this._changesets.length; ii++) { JX.DOM.setContent(flank_body, tree.getNode());
var changeset = this._changesets[ii];
var node = JX.$N('div', {}, changeset.getDisplayPath());
items.push(node);
}
JX.DOM.setContent(flank_body, items);
} }
} }

View file

@ -0,0 +1,83 @@
/**
* @provides phabricator-diff-path-view
* @requires javelin-dom
* @javelin
*/
JX.install('DiffPathView', {
construct: function() {
},
properties: {
changeset: null
},
members: {
_node: null,
_path: null,
_depth: 0,
_selected: false,
getNode: function() {
if (!this._node) {
this._node = JX.$N('li');
var onclick = JX.bind(this, this._onclick);
JX.DOM.listen(this._node, 'click', null, onclick);
}
return this._node;
},
setPath: function(path) {
this._path = path;
this._redraw();
return this;
},
getPath: function() {
return this._path;
},
setDepth: function(depth) {
this._depth = depth;
this._redraw();
return this;
},
setIsSelected: function(selected) {
this._selected = selected;
this._redraw();
return this;
},
_onclick: function(e) {
if (!e.isNormalClick()) {
return;
}
var changeset = this.getChangeset();
if (changeset) {
changeset.select(true);
}
e.kill();
},
_redraw: function() {
var node = this.getNode();
node.style.paddingLeft = (8 * this._depth) + 'px';
var display = this._path[this._path.length - 1];
if (this._selected) {
display = ['*', display];
}
JX.DOM.setContent(node, display);
}
}
});

View file

@ -0,0 +1,159 @@
/**
* @provides phabricator-diff-tree-view
* @requires javelin-dom
* @javelin
*/
JX.install('DiffTreeView', {
construct: function() {
this._keys = [];
this._tree = this._newTreeNode(null, [], 0);
this._nodes = {};
this._paths = [];
},
members: {
_node: null,
_keys: null,
_tree: null,
_nodes: null,
_dirty: false,
_paths: null,
_selectedPath: null,
getNode: function() {
if (!this._node) {
this._node = JX.$N('ul');
}
if (this._dirty) {
this.redraw();
}
return this._node;
},
addPath: function(path) {
this._paths.push(path);
var tree = this._getTree(this._tree, path.getPath(), 0);
tree.pathObject = path;
this._dirty = true;
return this;
},
getPaths: function() {
return this._paths;
},
setSelectedPath: function(path) {
if (this._selectedPath) {
this._selectedPath.setIsSelected(false);
this._selectedPath = null;
}
if (path) {
path.setIsSelected(true);
}
this._selectedPath = path;
return this;
},
redraw: function() {
if (!this._dirty) {
return;
}
this._dirty = false;
var ii;
// For nodes which don't have a path object yet, build one.
var tree;
var trees = [];
for (ii = 0; ii < this._keys.length; ii++) {
var key = this._keys[ii];
tree = this._nodes[key];
var path = tree.pathObject;
if (!path) {
path = new JX.DiffPathView()
.setPath(tree.parts);
tree.pathObject = path;
}
trees.push(tree);
}
for (ii = 0; ii < trees.length; ii++) {
tree = trees[ii];
if (!tree.parent) {
tree.depth = 0;
} else {
tree.depth = tree.parent.depth + 1;
}
tree.pathObject.setDepth((tree.depth - 1));
}
var nodes = [];
for (ii = 0; ii < trees.length; ii++) {
tree = trees[ii];
nodes.push(tree.pathObject.getNode());
}
JX.DOM.setContent(this.getNode(), nodes);
},
_getTree: function(root, path, ii) {
if (ii >= path.length) {
return root;
}
var part = path[ii];
if (!root.children.hasOwnProperty(part)) {
root.children[part] = this._newTreeNode(root, path, ii);
root.childCount++;
}
return this._getTree(root.children[part], path, ii + 1);
},
_newTreeNode: function(parent, path, ii) {
var key;
var parts;
if (path.length) {
parts = path.slice(0, ii + 1);
key = parts.join('/');
this._keys.push(key);
} else {
parts = [];
key = null;
}
var node = {
parent: parent,
nodeKey: key,
parts: parts,
children: {},
pathObject: null,
childCount: 0,
depth: 0
};
if (key !== null) {
this._nodes[key] = node;
}
return node;
}
}
});