Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 4 - Implementation of cosmoz-tree logic #8

Merged
merged 15 commits into from
Aug 17, 2017

Conversation

JaySunSyn
Copy link
Contributor

Needs to be synced with Neovici/cosmoz-tree#1

bower.json Outdated
@@ -20,7 +20,8 @@
"iron-flex-layout": "^1.0.0",
"cosmoz-i18next": "neovici/cosmoz-i18next#master",
"cosmoz-dialog": "neovici/cosmoz-dialog#master",
"iron-list": "PolymerElements/iron-list#^2.0.4"
"iron-list": "PolymerElements/iron-list#^2.0.4",
"cosmoz-treenode": "Neovici/cosmoz-treenode"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was this added?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No response to this.
I think this is an unnecessary dep/import.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nomego Ok, not sure I get this and I think its related with the behavior I created.

Do I understand correctly, cosmoz-treenode-navigator gets a tree from outside the element? If so, how can I be sure that certain methods of Cosmoz.DefaultTree are implemented in the tree data the navigator gets from outside in order to work with them inside of the navigator? Do we define, the data (tree object) we get from outside needs do be a Cosmoz.DefaultTree (or derived from) object?

My understanding was, we get "node-like" data from outside and use the Cosmoz.Tree or DefaultTree methods inside the navigator. => wrong?

Copy link
Contributor Author

@JaySunSyn JaySunSyn Jul 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I see the mistake now, cosmoz-tree (or nothing) instead of cosmoz-treenode. Sorry for that, but above question still valid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the navigator gets a Cosmoz.Tree from outside the element.
It can be a Cosmoz.DefaultTree or some other implementation.
Cosmoz.Tree acts as an "abstract class" and defines methods that the implementations need to implement.

Yes the last part is wrong, we expect the tree to be created for us.

Also, it's a weird place to comment about this. This change is to import the "cosmoz-treenode" element which we haven't really touched during this PR, so I don't see why the dependency was added.
Ah, now I realize! :) It's just a typo, it should depend on Neovici/cosmoz-tree#master rather than Neovici/cosmoz-treenode :)

}
}, this)
var nodes = {};
nodeList.forEach(function (n) { nodes[n.id] = n; });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be a reduce()

var nodes = {};
nodeList.forEach(function (n) { nodes[n.id] = n; });

var tree = new Cosmoz.DefaultTree(nodes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.tree should be supplied instead of this.data


var tree = new Cosmoz.DefaultTree(nodes);

tree.getPath = function (node) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this method created?

bower.json Outdated
@@ -20,7 +20,8 @@
"iron-flex-layout": "^1.0.0",
"cosmoz-i18next": "neovici/cosmoz-i18next#master",
"cosmoz-dialog": "neovici/cosmoz-dialog#master",
"iron-list": "PolymerElements/iron-list#^2.0.4"
"iron-list": "PolymerElements/iron-list#^2.0.4",
"cosmoz-treenode": "Neovici/cosmoz-treenode"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No response to this.
I think this is an unnecessary dep/import.

@@ -62,7 +64,7 @@ <h3 class="layout horizontal center wrap">
<div class="section" hidden$="[[ !_renderSection(_searching, index, dataPlane, node) ]]">[[ node.sectionName ]]</div>
<paper-item on-tap="_nodeSelected" class="nodeItem">
<span class="flex">[[ node.name ]]</span>
<iron-icon hidden$="[[ !hasChildren(node) ]]" icon="icons:arrow-forward" on-click="openNode" data-path$="[[ node.path ]]"></iron-icon>
<iron-icon hidden$="[[ !hasChildren(node) ]]" data-path$="[[ node.path ]]" icon="icons:arrow-forward" on-click="openNode" data-path$="[[ node.path ]]"></iron-icon>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data-path was already bound

@@ -15,24 +16,26 @@
that component is given
*/
data: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think data should be kept but rather just expect a

tree: {
  type: Cosmoz.Tree
}

like https://github.com/Neovici/cosmoz-treenode/blob/master/cosmoz-treenode.html#L45

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that answers a big part of my above question.

@@ -15,24 +16,26 @@
that component is given
*/
data: {
type: Object
type: Object,
value: function () { return {} },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return on separate line, missing semicolon

level = Object.keys(nodes).map(function (key) {
var node = nodes[key];
_renderLevel: function (pathLocator, tree) {
if (!tree) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use curly braces

}, this);

return node;
_getNode: function (pathLocator, nodes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

second argument should be dropped if not used (also from computed property)


return node;
_getNode: function (pathLocator, nodes) {
if (!pathLocator) return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use curly braces


return parts;
_getTreePathParts: function (pathLocator, tree) {
if (!tree) return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use curly braces (x2), why different return values depending on missing argument?

}
}, this);

this._openNodeLevelPath = event.currentTarget.getAttribute('data-path');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not event.currentTarget.dataset.path ?

* of Cosmoz.TreeBehavior
*/
_getTreeClass: function (treeClass) {
treeClass.prototype.afterFound = function (node, propertyName) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why we can't just do the equivalent in the map() of _renderLevel ?
This code both updates an unknown tree implementation (once data is replaced with tree) and it writes to the nodes in the tree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can. (just a tiny little bit less efficient but no big deal)
I'm just used to such hook methods I know from js-data.

bower.json Outdated
"iron-ajax": "^2.0.2"
},
"resolutions": {
"iron-ajax": "^1.0.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not be needed if the dep is on iron-ajax#^1.0.0

bower.json Outdated
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"cosmoz-tree": "Neovici/cosmoz-tree",
"iron-ajax": "^2.0.2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^1.0.0

@@ -5,7 +5,7 @@
Polymer({

behaviors: [
Cosmoz.TranslatableBehavior
Cosmoz.TranslatableBehavior,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop comma

pathSegment = children;
}
return node;
_normalizeNode: function (nodeObj) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method actually doesn't return a formatted node as described and expected by the name but rather an array based on the object keys. It is designed to work on node.children input, but is not used that way.
Keep only the object remapping (1:1, return statement) in this method.
Create a new method for _normalizeNodes() that takes an array as input (and maps it by calling _normalizeNode() for each item). Probably needed when doing searches?
Finally, use _normalizeNodes(tree.getChildren(node)) or even a _normalizeChildren() for cases where you want this code to run as it is now.

if (!tree || !pathLocator) {
return [];
};
return this._normalizeNode(tree.getPath(pathLocator));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getPath() returns an array, need _normalizeNodes()
But I don't think we need to normalize these, do we ?

data: {
type: Object
tree: {
type: Cosmoz.tree,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop comma

if (searching) {
return this.searchAllBranches(inputValue, openNodeLevelPathParts, renderedLevel, data);
var results = tree.getNodeByProperty(this.comparisonProperty, inputValue, false, true, renderedLevel);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be searchNodes() ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird.. I have this on my local copy..


return this._sortItOut(level);
var n = tree.getNodeByPathLocator(pathLocator),
level = tree.getChildren(n) ? _objectValues(tree.getChildren(n)) : n;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could call _objectValues() twice?
Rather just do:

var node = tree.getNodeByPathLocator(pathLocator),
	children = tree.getChildren(node),
	level = children || node;
return this._sortNodes(this._normalizeNodes(level));

With the changes from the comments in the cosmoz-tree PR.

pathSegment = children;
}
return node;
_normalizeNodes: function (nodes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We never needed to normalize a single node?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dropped the key property (which is getting lost when converting to object values) as it wasn't needed and now we can just call it on a resulting array.

if (!tree || !pathLocator) {
return [];
};
return this._normalizeNodes(tree.getPath(pathLocator));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do the nodes in the path need to be normalized?
Can't we refactor away _getTreePathParts() completely?

Copy link
Contributor Author

@JaySunSyn JaySunSyn Jul 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need node.pathin the path in order to open the node when clicked on a path part.

@nomego We could of course use node.pathLocator but it's nicer to have the same node structure in the view everywhere.

<span class="slash">/</span><a href="#" data-path$="[[ node.path ]]" on-click="openNode">[[ getNodeName(node) ]]</a>

But if you prefer I can do data-path$="[[ node.pathLocator ]]"? instead of returning normalized nodes at _getTreePathParts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, ok, then I see.
Nah, keep it as it is now, it's better.

demo/index.html Outdated
</div>
<script>
window.addEventListener('WebComponentsReady', function(e) {
document.querySelector('#demo').handleResponse = function(response) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could actually be further simplified..

<iron-ajax ... last-response="{{ treeData }}">
<cosmoz-treenode-button-view ... tree="[[ getTree(treeData) ]]">
document.querySelector('#demo').getTree = function (data) {
  return new Cosmoz.DefaultTree(data);
};

Still, I don't think you need window.addEventListener('WebComponentsReady', function(e) { either?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sweet!

Copy link
Contributor

@nomego nomego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really good now, but I think that comparisonProperty (searchProperty), childProperty and hasChildren() should move to the cosmoz-tree implementation.

return this._sortItOut(level);
var node = tree.getNodeByPathLocator(pathLocator),
children = tree.getChildren(node),
level = children || _objectValues(node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need _objectValues() on the node here?
Seems like it would render a weird result?

Copy link
Contributor

@nomego nomego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost done! :)

return nodes.map(function (node) {
var path = node.pathLocator || node.path;
return {
name: node[this.comparisonProperty],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.comparisonProperty should be replaced with this.tree.searchProperty wherever possible.
Same goes for this.childProperty -> this.tree.childProperty.

value="{{ value }}" value-path-parts="{{ valuePathParts }}">
on-data-plane-changed="refit"
highlighted-node-path="{{ highlightedNodePath }}"
comparison-property="[[ comparisonProperty ]]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop comparisonProperty here as well

Copy link
Contributor

@nomego nomego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Will merge when cosmoz-tree is ready.

Copy link
Contributor

@plequang plequang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor changes required for _getNode, so that it does not throws exception when the tree property is set asynchronously

@@ -67,7 +63,7 @@

chosenNode: {
type: Object,
computed: '_getNode(value, data)',
computed: '_getNode(value)',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _getNode function needs to be bound to the tree, so that it will be called only when the tree is available.

*/
_getNode: function (pl, nodes) {
if (!pl) {
_getNode: function (pathLocator) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be _getNode: function (pathLocator, tree) and ensure tree is defined.

@plequang plequang merged commit 06851ce into Neovici:master Aug 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants