You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
5.5KB

  1. import { Injectable } from "@angular/core"
  2. import { RippleRef } from "@angular/material/core";
  3. import { BehaviorSubject, Subject } from "rxjs";
  4. import { map } from "rxjs/operators";
  5. import { CreateRuleDto, Rule, RulesService } from "../../../../../api";
  6. import { environment } from "../../../../environments/environment";
  7. import { RuleFlatNode } from "./rule-flat-node";
  8. @Injectable({ providedIn: 'root' })
  9. export class DynamicDatabase {
  10. dataChange = new BehaviorSubject<Rule[]>([]);
  11. childAdded = new Subject<Rule>();
  12. get data(): Rule[] { return this.dataChange.value; }
  13. get count(): number { return this.dataChange.value.length };
  14. protected addData(rule: Rule) { this.dataChange.next([...this.dataChange.value, rule]) }
  15. constructor(protected rulesService: RulesService) {
  16. this.rulesService.configuration.basePath = environment.apiUrl;
  17. this.rulesService.findAll()
  18. .subscribe(
  19. (rules: Rule[]) => this.dataChange.next(
  20. rules
  21. .filter(this.filterRuleWithParentFromRootLayer)
  22. .sort(this.compareRulesByParagraph)
  23. )
  24. ),
  25. (err) => {
  26. //TODO add toaster
  27. }
  28. }
  29. getParagraphOfNextChild = (parentRule): string => `${parentRule.paragraph}.${parentRule.subRule.length + 1}`;
  30. filterRuleWithParentFromRootLayer = (rootLayerRule: Rule) => typeof rootLayerRule.parentRule !== 'number';
  31. compareRulesByParagraph = (ruleA: Rule, ruleB: Rule) => this.compareParahraph(ruleA.paragraph, ruleB.paragraph);
  32. compareParahraph(paragraphA: string, paragraphB: string): 0 | 1 | -1 {
  33. if (paragraphA === paragraphB) {
  34. return 0;
  35. }
  36. const paragrapASections = paragraphA.split('.');
  37. const paragrapBSections = paragraphB.split('.');
  38. if (+paragrapASections[0] > +paragrapBSections[0]) {
  39. return 1;
  40. }
  41. if (+paragrapASections[0] < +paragrapBSections[0]) {
  42. return -1;
  43. }
  44. if (+paragrapASections[0] === +paragrapBSections[0]) {
  45. let shiftedParagraphASections = paragrapASections;
  46. shiftedParagraphASections.shift();
  47. let shiftedParagraphBSections = paragrapBSections;
  48. shiftedParagraphBSections.shift();
  49. return this.compareParahraph(
  50. shiftedParagraphASections.join('.'),
  51. shiftedParagraphBSections.join('.'),
  52. )
  53. }
  54. }
  55. getParentById = (ruleId: string) => this.data.find(rule => rule.id === ruleId)
  56. insertEmptyChild(parent: Rule) {
  57. parent.subRule.push(
  58. {
  59. text: '',
  60. id: '0',
  61. parentRule: parent,
  62. paragraph: this.getParagraphOfNextChild(parent)
  63. }
  64. )
  65. this.dataChange.next(this.data);
  66. this.childAdded.next(parent);
  67. }
  68. insertEmptyParent() {
  69. this.addData({
  70. text: '',
  71. id: '0',
  72. parentRule: null,
  73. paragraph: `${this.count + 2}`
  74. })
  75. }
  76. insertChild(parent: Rule, subRule: Rule) {
  77. const createSubRule: CreateRuleDto = {
  78. paragraph: subRule.paragraph,
  79. text: subRule.text,
  80. subRuleIds: null,
  81. parentId: parent.id
  82. }
  83. this.rulesService.create(createSubRule).subscribe(
  84. newSubRule => {
  85. if (typeof newSubRule.id !== 'undefined' && typeof newSubRule.parentRule?.id !== 'undefined') {
  86. const updateParentRule: CreateRuleDto = {
  87. paragraph: parent.paragraph,
  88. text: parent.text,
  89. subRuleIds: [...parent.subRule ? parent.subRule.map(rule => rule.id) : [], newSubRule.id]
  90. } as CreateRuleDto;
  91. this.rulesService.update(parent.id, updateParentRule).subscribe((updated) => {
  92. //TODO Push updated message
  93. this.update(parent.id, {
  94. paragraph: parent.paragraph,
  95. subRuleIds: [
  96. ...parent.subRule
  97. .filter(rule => rule.id === "0")
  98. .map(rule => rule.id) ?? [],
  99. subRule.id,
  100. ],
  101. text: parent.text
  102. }).subscribe(
  103. (updated) => {
  104. //todo add update message
  105. },
  106. (err) => {
  107. //TODO Push error message
  108. console.error(err);
  109. }
  110. )
  111. },
  112. (err) => {
  113. //TODO Push error message
  114. console.error(err);
  115. }
  116. )
  117. return;
  118. }
  119. //TODO Push error message
  120. }
  121. )
  122. if (!parent.subRule) {
  123. parent.subRule = [];
  124. }
  125. const lastIndex = parent.subRule.indexOf(subRule);
  126. parent.subRule[lastIndex] = subRule;
  127. this.dataChange.next(this.data);
  128. this.childAdded.next(parent);
  129. }
  130. update(id: string, changedData: Partial<CreateRuleDto>) {
  131. return this.rulesService.update(id, changedData);
  132. }
  133. insertParent(newRule: Rule) {
  134. const createNewRule: CreateRuleDto = {
  135. paragraph: `${this.count + 1}`,
  136. text: newRule.text,
  137. subRuleIds: null,
  138. parentId: null
  139. }
  140. this.rulesService.create(createNewRule).subscribe(
  141. () => {
  142. //TODO created message
  143. },
  144. (err) => {
  145. //TODO Error message
  146. }
  147. )
  148. this.dataChange.next(this.data);
  149. }
  150. removeChild(parent: Rule, subRule: Rule) {
  151. if (parent.subRule) {
  152. const subRuleToRemove = this.findSubRuleFromParent(parent, subRule);
  153. const indexIfSubRule = parent.subRule.indexOf(subRuleToRemove);
  154. if (indexIfSubRule > -1) {
  155. parent.subRule.splice(indexIfSubRule, 1);
  156. }
  157. this.dataChange.next(this.data);
  158. }
  159. }
  160. findSubRuleFromParent = (parent: Rule, subRule: Rule): Rule | null =>
  161. parent.subRule.find(rules => rules.paragraph === subRule.paragraph && rules.id === subRule.id);
  162. }