Skip to content

Commit 46ef322

Browse files
refactor: move TaskGroupingTreeStorage to TaskGroups (#1957)
* refactor: rename storage var * refactor: declare root in the TaskGroupingTree * refactor: setGroupsHeadings() accepts TaskGroupingTreeStorage as parameter * refactor: rename generateAllPaths() * test: rename tree to root * refactor: extract generateTaskTreeStorage() * refactor: addTaskGroups() accepts groupingTreeStorage * refactor: extract const groupingTreeStorage * refactor: remove groupingTreeStorage from TaskGroupingTreeNode * refactor: modify comment * refactor: inline buildGroupingTree() * refactor: comment & jsdoc in TaskGroupingTree * refactor: move TaskGroupingTreeStorage to TaskGroups * refactor: fix totalTasksCount() jsdoc * refactor: rename vars in generateNodePath() * refactor: extract TaskGroupingTreeStorage to a separate file * refactor: revert changes in GroupingTreeNode * refactor: rollback some comments * refactor: Re-extract buildGroupingTree(), and reinstate its comments. --------- Co-authored-by: Clare Macrae <[email protected]>
1 parent adace93 commit 46ef322

File tree

5 files changed

+47
-35
lines changed

5 files changed

+47
-35
lines changed

src/Query/GroupDisplayHeadingSelector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { GroupDisplayHeading } from './GroupDisplayHeading';
2-
import type { TaskGroupingTreeStorage } from './TaskGroupingTree';
32
import type { Grouper } from './Grouper';
3+
import type { TaskGroupingTreeStorage } from './TaskGroupingTreeStorage';
44

55
/*
66
* This file contains implementation details of Group.ts

src/Query/TaskGroupingTree.ts

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
import type { Task } from '../Task';
22
import type { Grouper } from './Grouper';
33
import { GroupingTreeNode } from './GroupingTreeNode';
4-
5-
/**
6-
* Storage used for the initial grouping together of tasks.
7-
*
8-
* The keys of the map are the names of the groups.
9-
* For example, one set of keys might be ['Folder Name/', 'File Name']
10-
* and the values would be all the matching Tasks from that file.
11-
*/
12-
export class TaskGroupingTreeStorage extends Map<string[], Task[]> {}
4+
import type { TaskGroupingTreeStorage } from './TaskGroupingTreeStorage';
135

146
/*
157
* A tree of tasks where every level in the tree corresponds to a grouping property.
@@ -48,30 +40,26 @@ class TaskGroupingTreeNode extends GroupingTreeNode<Task> {}
4840
* Ideally, this code would be simplified and moved in to TaskGroups.
4941
*/
5042
export class TaskGroupingTree {
51-
public groups = new TaskGroupingTreeStorage();
43+
private root: TaskGroupingTreeNode;
5244

5345
/**
54-
* Group a list of tasks, according to one or more task properties
46+
* Group a list of tasks, according to one or more task properties.
5547
* @param groupers 0 or more Grouping values, one per 'group by' line
5648
* @param tasks The tasks that match the task block's Query
5749
*/
5850
constructor(groupers: Grouper[], tasks: Task[]) {
59-
const tree = this.buildGroupingTree(groupers, tasks);
60-
this.groups = tree.generateAllPaths();
51+
// The root of the tree contains all the tasks.
52+
this.root = new TaskGroupingTreeNode(tasks);
53+
54+
this.buildGroupingTree(groupers);
6155
}
6256

63-
/**
64-
* Returns a grouping tree that groups the passed @tasks by the passed @groupers.
65-
*/
66-
private buildGroupingTree(groupers: Grouper[], tasks: Task[]): TaskGroupingTreeNode {
57+
private buildGroupingTree(groupers: Grouper[]) {
6758
// The tree is build layer by layer, starting from the root.
6859
// At every level, we iterate on the nodes of that level to generate
6960
// the next one using the next grouping.
7061

71-
// The root of the tree contains all the tasks.
72-
const root = new TaskGroupingTreeNode(tasks);
73-
74-
let currentTreeLevel = [root];
62+
let currentTreeLevel = [this.root];
7563
for (const grouper of groupers) {
7664
const nextTreeLevel = [];
7765
for (const currentTreeNode of currentTreeLevel) {
@@ -92,7 +80,14 @@ export class TaskGroupingTree {
9280
}
9381
currentTreeLevel = nextTreeLevel;
9482
}
83+
}
9584

96-
return root;
85+
/** Generates an intermediate storage for the initial grouping together of tasks.
86+
*
87+
* @returns a map where the keys are the names of the groups
88+
* and the values are the tasks.
89+
*/
90+
public generateTaskTreeStorage(): TaskGroupingTreeStorage {
91+
return this.root.generateAllPaths();
9792
}
9893
}

src/Query/TaskGroupingTreeStorage.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { Task } from '../Task';
2+
3+
/**
4+
* Storage used for the initial grouping together of tasks.
5+
*
6+
* The keys of the map are the names of the groups.
7+
* For example, one set of keys might be ['Folder Name/', 'File Name']
8+
* and the values would be all the matching Tasks from that file.
9+
*
10+
* This is an implementation detail of the task-grouping code, and does not need to
11+
* be understood in order to group tasks.
12+
*/
13+
14+
export class TaskGroupingTreeStorage extends Map<string[], Task[]> {}

src/Query/TaskGroups.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Grouper } from './Grouper';
33
import { GroupDisplayHeadingSelector } from './GroupDisplayHeadingSelector';
44
import { TaskGroupingTree } from './TaskGroupingTree';
55
import { TaskGroup } from './TaskGroup';
6+
import type { TaskGroupingTreeStorage } from './TaskGroupingTreeStorage';
67

78
/**
89
* Store all the groups of tasks generated by any 'group by'
@@ -30,11 +31,13 @@ export class TaskGroups {
3031
this._groupers = groups;
3132

3233
const taskGroupingTree = new TaskGroupingTree(groups, tasks);
33-
this.addTaskGroups(taskGroupingTree);
34+
const groupingTreeStorage = taskGroupingTree.generateTaskTreeStorage();
35+
36+
this.addTaskGroups(groupingTreeStorage);
3437

3538
this.sortTaskGroups();
3639

37-
this.setGroupsHeadings(taskGroupingTree);
40+
this.setGroupsHeadings(groupingTreeStorage);
3841
}
3942

4043
/**
@@ -89,8 +92,8 @@ export class TaskGroups {
8992
return output;
9093
}
9194

92-
private addTaskGroups(taskGroupingTree: TaskGroupingTree) {
93-
for (const [groups, tasks] of taskGroupingTree.groups) {
95+
private addTaskGroups(groupingTreeStorage: TaskGroupingTreeStorage) {
96+
for (const [groups, tasks] of groupingTreeStorage) {
9497
const taskGroup = new TaskGroup(groups, tasks);
9598
this.addTaskGroup(taskGroup);
9699
}
@@ -124,8 +127,8 @@ export class TaskGroups {
124127
this._groups.sort(compareFn);
125128
}
126129

127-
private setGroupsHeadings(taskGroupingTree: TaskGroupingTree) {
128-
const displayHeadingSelector = new GroupDisplayHeadingSelector(taskGroupingTree.groups, this._groupers);
130+
private setGroupsHeadings(groupingTreeStorage: TaskGroupingTreeStorage) {
131+
const displayHeadingSelector = new GroupDisplayHeadingSelector(groupingTreeStorage, this._groupers);
129132
for (const group of this._groups) {
130133
group.setGroupHeadings(displayHeadingSelector.getHeadingsForTaskGroup(group.groups));
131134
}

tests/GroupingTreeNode.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,24 @@ describe('Grouping Tree', () => {
1515
// D[1] E[3, 4] F[4, 5, 6]
1616
// / \
1717
// G[4] H[5, 6]
18-
const tree = new GroupingTreeNode<number>([1, 2, 3, 4, 5, 6]);
18+
const root = new GroupingTreeNode<number>([1, 2, 3, 4, 5, 6]);
1919
const b = new GroupingTreeNode<number>([1, 5, 6]);
2020
const c = new GroupingTreeNode<number>([3, 4, 5, 6]);
2121
const d = new GroupingTreeNode<number>([1]);
2222
const e = new GroupingTreeNode<number>([3, 4]);
2323
const f = new GroupingTreeNode<number>([4, 5, 6]);
2424
const g = new GroupingTreeNode<number>([4]);
2525
const h = new GroupingTreeNode<number>([5, 6]);
26-
tree.children.set('B', b);
27-
tree.children.set('C', c);
26+
root.children.set('B', b);
27+
root.children.set('C', c);
2828
b.children.set('D', d);
2929
c.children.set('E', e);
3030
c.children.set('F', f);
3131
f.children.set('G', g);
3232
f.children.set('H', h);
3333

3434
// Act
35-
const allLeafs = tree.generateAllPaths();
35+
const allLeafs = root.generateAllPaths();
3636

3737
// Assert
3838
const expected = new Map<string[], number[]>();
@@ -45,10 +45,10 @@ describe('Grouping Tree', () => {
4545

4646
it("generates correct map when the node doesn't have children", () => {
4747
// Arrange
48-
const tree = new GroupingTreeNode<number>([1, 2, 3, 4, 5, 6]);
48+
const root = new GroupingTreeNode<number>([1, 2, 3, 4, 5, 6]);
4949

5050
// Act
51-
const allLeafs = tree.generateAllPaths();
51+
const allLeafs = root.generateAllPaths();
5252

5353
// Assert
5454
const expected = new Map<string[], number[]>();

0 commit comments

Comments
 (0)