Advertisement
Guest User

Untitled

a guest
Aug 26th, 2019
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.01 KB | None | 0 0
  1. import { TodoItemNode } from './classes';
  2. import { BehaviorSubject } from 'rxjs';
  3. import { Injectable } from '@angular/core';
  4.  
  5. /**
  6. * Checklist database, it can build a tree structured Json object.
  7. * Each node in Json object represents a to-do item or a category.
  8. * If a node is a category, it has children items and new items can be added under the category.
  9. */
  10. @Injectable()
  11. export class ChecklistDatabase {
  12. dataChange = new BehaviorSubject<TodoItemNode[]>([]);
  13.  
  14. get data(): TodoItemNode[] {
  15. return this.dataChange.value;
  16. }
  17.  
  18. constructor() {
  19. this.initialize();
  20. }
  21.  
  22. initialize() {
  23. // Build the tree nodes from Json object. The result is a list of `TodoItemNode` with nested
  24. // file node as children.
  25. // const data = this.buildFileTree(tree_data, 0);
  26.  
  27. // Notify the change.
  28. this.dataChange.next([]);
  29. }
  30.  
  31. /**
  32. * Build the file structure tree. The `value` is the Json object, or a sub-tree of a Json object.
  33. * The return value is the list of `TodoItemNode`.
  34. */
  35. buildFileTree(obj: object, level: number): TodoItemNode[] {
  36. return Object.keys(obj).reduce<TodoItemNode[]>((accumulator, key) => {
  37. const value = obj[key];
  38. const node = new TodoItemNode();
  39. node.item = key;
  40.  
  41. if (value != null) {
  42. if (typeof value === 'object') {
  43. node.children = this.buildFileTree(value, level + 1);
  44. } else {
  45. node.item = value;
  46. }
  47. }
  48.  
  49. return accumulator.concat(node);
  50. }, []);
  51. }
  52.  
  53. /** Add an item to to-do list */
  54. insertItem(parent: TodoItemNode, name: string): TodoItemNode {
  55. if (!parent.children) {
  56. parent.children = [];
  57. }
  58. const newItem = { item: name } as TodoItemNode;
  59. parent.children.push(newItem);
  60. this.dataChange.next(this.data);
  61. return newItem;
  62. }
  63.  
  64. insertItemAbove(node: TodoItemNode, name: string): TodoItemNode {
  65. const parentNode = this.getParentFromNodes(node);
  66. const newItem = { item: name } as TodoItemNode;
  67. if (parentNode != null) {
  68. parentNode.children.splice(parentNode.children.indexOf(node), 0, newItem);
  69. } else {
  70. this.data.splice(this.data.indexOf(node), 0, newItem);
  71. }
  72. this.dataChange.next(this.data);
  73. return newItem;
  74. }
  75.  
  76. insertItemBelow(node: TodoItemNode, name: string): TodoItemNode {
  77. const parentNode = this.getParentFromNodes(node);
  78. const newItem = { item: name } as TodoItemNode;
  79. if (parentNode != null) {
  80. parentNode.children.splice(
  81. parentNode.children.indexOf(node) + 1,
  82. 0,
  83. newItem
  84. );
  85. } else {
  86. this.data.splice(this.data.indexOf(node) + 1, 0, newItem);
  87. }
  88. this.dataChange.next(this.data);
  89. return newItem;
  90. }
  91.  
  92. getParentFromNodes(node: TodoItemNode): TodoItemNode {
  93. for (let i = 0; i < this.data.length; ++i) {
  94. const currentRoot = this.data[i];
  95. const parent = this.getParent(currentRoot, node);
  96. if (parent != null) {
  97. return parent;
  98. }
  99. }
  100. return null;
  101. }
  102.  
  103. getParent(currentRoot: TodoItemNode, node: TodoItemNode): TodoItemNode {
  104. if (currentRoot.children && currentRoot.children.length > 0) {
  105. for (let i = 0; i < currentRoot.children.length; ++i) {
  106. const child = currentRoot.children[i];
  107. if (child === node) {
  108. return currentRoot;
  109. } else if (child.children && child.children.length > 0) {
  110. const parent = this.getParent(child, node);
  111. if (parent != null) {
  112. return parent;
  113. }
  114. }
  115. }
  116. }
  117. return null;
  118. }
  119.  
  120. updateItem(node: TodoItemNode, name: string) {
  121. node.item = name;
  122. this.dataChange.next(this.data);
  123. }
  124.  
  125. deleteItem(node: TodoItemNode) {
  126. this.deleteNode(this.data, node);
  127. this.dataChange.next(this.data);
  128. }
  129.  
  130. copyPasteItem(from: TodoItemNode, to: TodoItemNode): TodoItemNode {
  131. const newItem = this.insertItem(to, from.item);
  132. if (from.children) {
  133. from.children.forEach(child => {
  134. this.copyPasteItem(child, newItem);
  135. });
  136. }
  137. return newItem;
  138. }
  139.  
  140. copyPasteItemAbove(from: TodoItemNode, to: TodoItemNode): TodoItemNode {
  141. const newItem = this.insertItemAbove(to, from.item);
  142. if (from.children) {
  143. from.children.forEach(child => {
  144. this.copyPasteItem(child, newItem);
  145. });
  146. }
  147. return newItem;
  148. }
  149.  
  150. copyPasteItemBelow(from: TodoItemNode, to: TodoItemNode): TodoItemNode {
  151. const newItem = this.insertItemBelow(to, from.item);
  152. if (from.children) {
  153. from.children.forEach(child => {
  154. this.copyPasteItem(child, newItem);
  155. });
  156. }
  157. return newItem;
  158. }
  159.  
  160. deleteNode(nodes: TodoItemNode[], nodeToDelete: TodoItemNode) {
  161. const index = nodes.indexOf(nodeToDelete, 0);
  162. if (index > -1) {
  163. nodes.splice(index, 1);
  164. } else {
  165. nodes.forEach(node => {
  166. if (node.children && node.children.length > 0) {
  167. this.deleteNode(node.children, nodeToDelete);
  168. }
  169. });
  170. }
  171. }
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement