[ARVADOS-WORKBENCH2] updated: 1.1.4-471-g540d41f
Git user
git at public.curoverse.com
Thu Aug 2 04:49:42 EDT 2018
Summary of changes:
src/models/tree.test.ts | 26 +++------
src/models/tree.ts | 66 +++++++++++++---------
.../collections-panel-files-reducer.ts | 55 +++++++++---------
3 files changed, 74 insertions(+), 73 deletions(-)
via 540d41f964c7ad3495cead777d6d175ff8f76b53 (commit)
from 772cf27f6c086cc59a71211ca9df74c33414a859 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 540d41f964c7ad3495cead777d6d175ff8f76b53
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date: Thu Aug 2 10:49:17 2018 +0200
Add function for tree nodes value manipulation
Feature #13855
Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
diff --git a/src/models/tree.test.ts b/src/models/tree.test.ts
index 1ddb083..708cf40 100644
--- a/src/models/tree.test.ts
+++ b/src/models/tree.test.ts
@@ -43,7 +43,7 @@ describe('Tree', () => {
].reduce((tree, node) => Tree.setNode(node)(tree), tree);
expect(Tree.getNodeDescendants('Node 1')(newTree)).toEqual(['Node 2', 'Node 3', 'Node 2.1', 'Node 3.1']);
});
-
+
it('gets root descendants', () => {
const newTree = [
{ children: [], id: 'Node 1', parent: '', value: 'Value 1' },
@@ -52,9 +52,9 @@ describe('Tree', () => {
{ children: [], id: 'Node 3', parent: 'Node 1', value: 'Value 1' },
{ children: [], id: 'Node 3.1', parent: 'Node 3', value: 'Value 1' }
].reduce((tree, node) => Tree.setNode(node)(tree), tree);
- expect(Tree.getNodeDescendants('')(newTree)).toEqual(['Node 1','Node 2', 'Node 3', 'Node 2.1', 'Node 3.1']);
+ expect(Tree.getNodeDescendants('')(newTree)).toEqual(['Node 1', 'Node 2', 'Node 3', 'Node 2.1', 'Node 3.1']);
});
-
+
it('gets node children', () => {
const newTree = [
{ children: [], id: 'Node 1', parent: '', value: 'Value 1' },
@@ -65,7 +65,7 @@ describe('Tree', () => {
].reduce((tree, node) => Tree.setNode(node)(tree), tree);
expect(Tree.getNodeChildren('Node 1')(newTree)).toEqual(['Node 2', 'Node 3']);
});
-
+
it('gets root children', () => {
const newTree = [
{ children: [], id: 'Node 1', parent: '', value: 'Value 1' },
@@ -76,25 +76,13 @@ describe('Tree', () => {
].reduce((tree, node) => Tree.setNode(node)(tree), tree);
expect(Tree.getNodeChildren('')(newTree)).toEqual(['Node 1', 'Node 3']);
});
-
- it('maps nodes', () => {
- const newTree = [
- { children: [], id: 'Node 1', parent: '', value: 'Value 1' },
- { children: [], id: 'Node 2', parent: 'Node 1', value: 'Value 1' },
- { children: [], id: 'Node 2.1', parent: 'Node 2', value: 'Value 1' },
- { children: [], id: 'Node 3', parent: 'Node 1', value: 'Value 1' },
- { children: [], id: 'Node 3.1', parent: 'Node 3', value: 'Value 1' }
- ].reduce((tree, node) => Tree.setNode(node)(tree), tree);
- const updatedTree = Tree.mapNodes(['Node 2.1', 'Node 3.1'])(node => ({...node, value: `Updated ${node.value}`}))(newTree);
- expect(Tree.getNode('Node 2.1')(updatedTree)).toEqual({ children: [], id: 'Node 2.1', parent: 'Node 2', value: 'Updated Value 1' },);
- });
-
+
it('maps tree', () => {
const newTree = [
{ children: [], id: 'Node 1', parent: '', value: 'Value 1' },
{ children: [], id: 'Node 2', parent: 'Node 1', value: 'Value 2' },
].reduce((tree, node) => Tree.setNode(node)(tree), tree);
- const mappedTree = Tree.mapTree<string, number>(node => ({...node, value: parseInt(node.value.split(' ')[1], 10)}))(newTree);
- expect(Tree.getNode('Node 2')(mappedTree)).toEqual({ children: [], id: 'Node 2', parent: 'Node 1', value: 2 },);
+ const mappedTree = Tree.mapTreeValues<string, number>(value => parseInt(value.split(' ')[1], 10))(newTree);
+ expect(Tree.getNode('Node 2')(mappedTree)).toEqual({ children: [], id: 'Node 2', parent: 'Node 1', value: 2 }, );
});
});
\ No newline at end of file
diff --git a/src/models/tree.ts b/src/models/tree.ts
index 1f1e308..61e7d86 100644
--- a/src/models/tree.ts
+++ b/src/models/tree.ts
@@ -28,22 +28,36 @@ export const setNode = <T>(node: TreeNode<T>) => (tree: Tree<T>): Tree<T> => {
return newTree;
};
-export const addChild = (parentId: string, childId: string) => <T>(tree: Tree<T>): Tree<T> => {
- const node = getNode(parentId)(tree);
- if (node) {
- const children = node.children.some(id => id === childId)
- ? node.children
- : [...node.children, childId];
+export const getNodeValue = (id: string) => <T>(tree: Tree<T>) => {
+ const node = getNode(id)(tree);
+ return node ? node.value : undefined;
+};
- const newNode = children === node.children
- ? node
- : { ...node, children };
+export const setNodeValue = (id: string) => <T>(value: T) => (tree: Tree<T>) => {
+ const node = getNode(id)(tree);
+ return node
+ ? setNode(mapNodeValue(() => value)(node))(tree)
+ : tree;
+};
- return setNode(newNode)(tree);
- }
- return tree;
+export const setNodeValueWith = <T>(mapFn: (value: T) => T) => (id: string) => (tree: Tree<T>) => {
+ const node = getNode(id)(tree);
+ return node
+ ? setNode(mapNodeValue(mapFn)(node))(tree)
+ : tree;
};
+export const mapTreeValues = <T, R>(mapFn: (value: T) => R) => (tree: Tree<T>): Tree<R> =>
+ getNodeDescendants('')(tree)
+ .map(id => getNode(id)(tree))
+ .map(mapNodeValue(mapFn))
+ .reduce((newTree, node) => setNode(node)(newTree), createTree<R>());
+
+export const mapTree = <T, R>(mapFn: (node: TreeNode<T>) => TreeNode<R>) => (tree: Tree<T>): Tree<R> =>
+ getNodeDescendants('')(tree)
+ .map(id => getNode(id)(tree))
+ .map(mapFn)
+ .reduce((newTree, node) => setNode(node)(newTree), createTree<R>());
export const getNodeAncestors = (id: string) => <T>(tree: Tree<T>): string[] => {
const node = getNode(id)(tree);
@@ -70,20 +84,7 @@ export const getNodeDescendants = (id: string, limit = Infinity) => <T>(tree: Tr
export const getNodeChildren = (id: string) => <T>(tree: Tree<T>): string[] =>
getNodeDescendants(id, 0)(tree);
-export const mapNodes = (ids: string[]) => <T>(mapFn: (node: TreeNode<T>) => TreeNode<T>) => (tree: Tree<T>): Tree<T> =>
- ids
- .map(id => getNode(id)(tree))
- .map(mapFn)
- .map(setNode)
- .reduce((tree, update) => update(tree), tree);
-
-export const mapTree = <T, R>(mapFn: (node: TreeNode<T>) => TreeNode<R>) => (tree: Tree<T>): Tree<R> =>
- getNodeDescendants('')(tree)
- .map(id => getNode(id)(tree))
- .map(mapFn)
- .reduce((newTree, node) => setNode(node)(newTree), createTree<R>());
-
-export const mapNodeValue = <T>(mapFn: (value: T) => T) => (node: TreeNode<T>) =>
+const mapNodeValue = <T, R>(mapFn: (value: T) => R) => (node: TreeNode<T>): TreeNode<R> =>
({ ...node, value: mapFn(node.value) });
const getRootNodeChildren = <T>(tree: Tree<T>) =>
@@ -91,5 +92,18 @@ const getRootNodeChildren = <T>(tree: Tree<T>) =>
.keys(tree)
.filter(id => getNode(id)(tree)!.parent === TREE_ROOT_ID);
+const addChild = (parentId: string, childId: string) => <T>(tree: Tree<T>): Tree<T> => {
+ const node = getNode(parentId)(tree);
+ if (node) {
+ const children = node.children.some(id => id === childId)
+ ? node.children
+ : [...node.children, childId];
+ const newNode = children === node.children
+ ? node
+ : { ...node, children };
+ return setNode(newNode)(tree);
+ }
+ return tree;
+};
diff --git a/src/store/collection-panel/collection-panel-files/collections-panel-files-reducer.ts b/src/store/collection-panel/collection-panel-files/collections-panel-files-reducer.ts
index c31f6c6..f6503cc 100644
--- a/src/store/collection-panel/collection-panel-files/collections-panel-files-reducer.ts
+++ b/src/store/collection-panel/collection-panel-files/collections-panel-files-reducer.ts
@@ -4,7 +4,7 @@
import { CollectionPanelFilesState, CollectionPanelFile, CollectionPanelDirectory, mapCollectionFileToCollectionPanelFile } from "./collection-panel-files-state";
import { CollectionPanelFilesAction, collectionPanelFilesAction } from "./collection-panel-files-actions";
-import { createTree, mapTree, TreeNode, mapNodes, getNode, setNode, getNodeAncestors, getNodeDescendants, mapNodeValue } from "../../../models/tree";
+import { createTree, mapTreeValues, getNode, setNode, getNodeAncestors, getNodeDescendants, setNodeValueWith, mapTree } from "../../../models/tree";
import { CollectionFileType } from "../../../models/collection-file";
export const collectionPanelFilesReducer = (state: CollectionPanelFilesState = createTree(), action: CollectionPanelFilesAction) => {
@@ -21,55 +21,54 @@ export const collectionPanelFilesReducer = (state: CollectionPanelFilesState = c
.map(toggleDescendants(data.id))[0],
SELECT_ALL_COLLECTION_FILES: () =>
- mapTree(mapNodeValue(v => ({ ...v, selected: true })))(state),
+ mapTreeValues(v => ({ ...v, selected: true }))(state),
UNSELECT_ALL_COLLECTION_FILES: () =>
- mapTree(mapNodeValue(v => ({ ...v, selected: false })))(state),
-
+ mapTreeValues(v => ({ ...v, selected: false }))(state),
+
default: () => state
});
};
const toggleCollapse = (id: string) => (tree: CollectionPanelFilesState) =>
- mapNodes
- ([id])
- (mapNodeValue((v: CollectionPanelDirectory | CollectionPanelFile) =>
- v.type === CollectionFileType.DIRECTORY
- ? { ...v, collapsed: !v.collapsed }
- : v))
- (tree);
+ setNodeValueWith((v: CollectionPanelDirectory | CollectionPanelFile) =>
+ v.type === CollectionFileType.DIRECTORY
+ ? { ...v, collapsed: !v.collapsed }
+ : v)(id)(tree);
+
const toggleSelected = (id: string) => (tree: CollectionPanelFilesState) =>
- mapNodes
- ([id])
- (mapNodeValue((v: CollectionPanelDirectory | CollectionPanelFile) => ({ ...v, selected: !v.selected })))
- (tree);
+ setNodeValueWith((v: CollectionPanelDirectory | CollectionPanelFile) => ({ ...v, selected: !v.selected }))(id)(tree);
const toggleDescendants = (id: string) => (tree: CollectionPanelFilesState) => {
const node = getNode(id)(tree);
if (node && node.value.type === CollectionFileType.DIRECTORY) {
- return mapNodes(getNodeDescendants(id)(tree))(mapNodeValue(v => ({ ...v, selected: node.value.selected })))(tree);
+ return getNodeDescendants(id)(tree)
+ .reduce((newTree, id) =>
+ setNodeValueWith(v => ({ ...v, selected: node.value.selected }))(id)(newTree), tree);
}
return tree;
};
const toggleAncestors = (id: string) => (tree: CollectionPanelFilesState) => {
- const ancestors = getNodeAncestors(id)(tree)
- .map(id => getNode(id)(tree))
- .reverse();
- return ancestors.reduce((newTree, parent) => parent !== undefined ? toggleParentNode(parent)(newTree) : newTree, tree);
+ const ancestors = getNodeAncestors(id)(tree).reverse();
+ return ancestors.reduce((newTree, parent) => parent ? toggleParentNode(parent)(newTree) : newTree, tree);
};
-const toggleParentNode = (node: TreeNode<CollectionPanelDirectory | CollectionPanelFile>) => (tree: CollectionPanelFilesState) => {
- const parentNode = getNode(node.id)(tree);
- if (parentNode) {
- const selected = parentNode.children
- .map(id => getNode(id)(tree))
- .every(node => node !== undefined && node.value.selected);
- return setNode(mapNodeValue(v => ({ ...v, selected }))(parentNode))(tree);
+const toggleParentNode = (id: string) => (tree: CollectionPanelFilesState) => {
+ const node = getNode(id)(tree);
+ if (node) {
+ const parentNode = getNode(node.id)(tree);
+ if (parentNode) {
+ const selected = parentNode.children
+ .map(id => getNode(id)(tree))
+ .every(node => node !== undefined && node.value.selected);
+ return setNodeValueWith(v => ({ ...v, selected }))(parentNode.id)(tree);
+ }
+ return setNode(node)(tree);
}
- return setNode(node)(tree);
+ return tree;
};
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list