| responseType_ = 'text'; | responseType_ = 'text'; | ||||
| } | } | ||||
| return this.httpClient.post<Rule>(`${this.configuration.basePath}/rules`, | |||||
| return this.httpClient.post<Rule>(`${this.configuration.basePath}/rules/admin`, | |||||
| createRuleDto, | createRuleDto, | ||||
| { | { | ||||
| responseType: <any>responseType_, | responseType: <any>responseType_, | ||||
| ); | ); | ||||
| } | } | ||||
| /** | |||||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||||
| * @param reportProgress flag to report request and response progress. | |||||
| */ | |||||
| public findAllAdmin(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<Array<Rule>>; | |||||
| public findAllAdmin(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<Array<Rule>>>; | |||||
| public findAllAdmin(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<Array<Rule>>>; | |||||
| public findAllAdmin(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> { | |||||
| let headers = this.defaultHeaders; | |||||
| let credential: string | undefined; | |||||
| // authentication (basic) required | |||||
| credential = this.configuration.lookupCredential('basic'); | |||||
| if (credential) { | |||||
| headers = headers.set('Authorization', 'Basic ' + credential); | |||||
| } | |||||
| let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||||
| if (httpHeaderAcceptSelected === undefined) { | |||||
| // to determine the Accept header | |||||
| const httpHeaderAccepts: string[] = [ | |||||
| 'application/json' | |||||
| ]; | |||||
| httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||||
| } | |||||
| if (httpHeaderAcceptSelected !== undefined) { | |||||
| headers = headers.set('Accept', httpHeaderAcceptSelected); | |||||
| } | |||||
| let responseType_: 'text' | 'json' = 'json'; | |||||
| if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) { | |||||
| responseType_ = 'text'; | |||||
| } | |||||
| return this.httpClient.get<Array<Rule>>(`${this.configuration.basePath}/rules/admin`, | |||||
| { | |||||
| responseType: <any>responseType_, | |||||
| withCredentials: this.configuration.withCredentials, | |||||
| headers: headers, | |||||
| observe: observe, | |||||
| reportProgress: reportProgress | |||||
| } | |||||
| ); | |||||
| } | |||||
| /** | /** | ||||
| * @param id | * @param id | ||||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | ||||
| responseType_ = 'text'; | responseType_ = 'text'; | ||||
| } | } | ||||
| return this.httpClient.delete<any>(`${this.configuration.basePath}/rules/${encodeURIComponent(String(id))}`, | |||||
| return this.httpClient.delete<any>(`${this.configuration.basePath}/rules/admin/${encodeURIComponent(String(id))}`, | |||||
| { | |||||
| responseType: <any>responseType_, | |||||
| withCredentials: this.configuration.withCredentials, | |||||
| headers: headers, | |||||
| observe: observe, | |||||
| reportProgress: reportProgress | |||||
| } | |||||
| ); | |||||
| } | |||||
| /** | |||||
| * @param id | |||||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||||
| * @param reportProgress flag to report request and response progress. | |||||
| */ | |||||
| public restore(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<any>; | |||||
| public restore(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<HttpResponse<any>>; | |||||
| public restore(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<HttpEvent<any>>; | |||||
| public restore(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined}): Observable<any> { | |||||
| if (id === null || id === undefined) { | |||||
| throw new Error('Required parameter id was null or undefined when calling restore.'); | |||||
| } | |||||
| let headers = this.defaultHeaders; | |||||
| let credential: string | undefined; | |||||
| // authentication (basic) required | |||||
| credential = this.configuration.lookupCredential('basic'); | |||||
| if (credential) { | |||||
| headers = headers.set('Authorization', 'Basic ' + credential); | |||||
| } | |||||
| let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||||
| if (httpHeaderAcceptSelected === undefined) { | |||||
| // to determine the Accept header | |||||
| const httpHeaderAccepts: string[] = [ | |||||
| ]; | |||||
| httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||||
| } | |||||
| if (httpHeaderAcceptSelected !== undefined) { | |||||
| headers = headers.set('Accept', httpHeaderAcceptSelected); | |||||
| } | |||||
| let responseType_: 'text' | 'json' = 'json'; | |||||
| if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) { | |||||
| responseType_ = 'text'; | |||||
| } | |||||
| return this.httpClient.post<any>(`${this.configuration.basePath}/rules/admin/restore/${encodeURIComponent(String(id))}`, | |||||
| null, | |||||
| { | { | ||||
| responseType: <any>responseType_, | responseType: <any>responseType_, | ||||
| withCredentials: this.configuration.withCredentials, | withCredentials: this.configuration.withCredentials, | ||||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | ||||
| * @param reportProgress flag to report request and response progress. | * @param reportProgress flag to report request and response progress. | ||||
| */ | */ | ||||
| public update(id: string, body: object, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<object>; | |||||
| public update(id: string, body: object, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpResponse<object>>; | |||||
| public update(id: string, body: object, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json'}): Observable<HttpEvent<object>>; | |||||
| public update(id: string, body: object, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json'}): Observable<any> { | |||||
| public update(id: string, body: object, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<any>; | |||||
| public update(id: string, body: object, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<HttpResponse<any>>; | |||||
| public update(id: string, body: object, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined}): Observable<HttpEvent<any>>; | |||||
| public update(id: string, body: object, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined}): Observable<any> { | |||||
| if (id === null || id === undefined) { | if (id === null || id === undefined) { | ||||
| throw new Error('Required parameter id was null or undefined when calling update.'); | throw new Error('Required parameter id was null or undefined when calling update.'); | ||||
| } | } | ||||
| if (httpHeaderAcceptSelected === undefined) { | if (httpHeaderAcceptSelected === undefined) { | ||||
| // to determine the Accept header | // to determine the Accept header | ||||
| const httpHeaderAccepts: string[] = [ | const httpHeaderAccepts: string[] = [ | ||||
| 'application/json' | |||||
| ]; | ]; | ||||
| httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | ||||
| } | } | ||||
| responseType_ = 'text'; | responseType_ = 'text'; | ||||
| } | } | ||||
| return this.httpClient.patch<object>(`${this.configuration.basePath}/rules/${encodeURIComponent(String(id))}`, | |||||
| return this.httpClient.patch<any>(`${this.configuration.basePath}/rules/admin/${encodeURIComponent(String(id))}`, | |||||
| body, | body, | ||||
| { | { | ||||
| responseType: <any>responseType_, | responseType: <any>responseType_, |
| */ | */ | ||||
| findAll(extraHttpRequestParams?: any): Observable<Array<Rule>>; | findAll(extraHttpRequestParams?: any): Observable<Array<Rule>>; | ||||
| /** | |||||
| * | |||||
| * | |||||
| */ | |||||
| findAllAdmin(extraHttpRequestParams?: any): Observable<Array<Rule>>; | |||||
| /** | /** | ||||
| * | * | ||||
| * | * | ||||
| */ | */ | ||||
| remove(id: string, extraHttpRequestParams?: any): Observable<{}>; | remove(id: string, extraHttpRequestParams?: any): Observable<{}>; | ||||
| /** | |||||
| * | |||||
| * | |||||
| * @param id | |||||
| */ | |||||
| restore(id: string, extraHttpRequestParams?: any): Observable<{}>; | |||||
| /** | /** | ||||
| * | * | ||||
| * | * | ||||
| * @param id | * @param id | ||||
| * @param body | * @param body | ||||
| */ | */ | ||||
| update(id: string, body: object, extraHttpRequestParams?: any): Observable<object>; | |||||
| update(id: string, body: object, extraHttpRequestParams?: any): Observable<{}>; | |||||
| } | } |
| text: string; | text: string; | ||||
| parentRule?: Rule | null; | parentRule?: Rule | null; | ||||
| subRule?: Array<Rule> | null; | subRule?: Array<Rule> | null; | ||||
| created?: string | null; | |||||
| updated?: string | null; | |||||
| deletedAt?: string | null; | |||||
| } | } | ||||
| import { map } from "rxjs/operators"; | import { map } from "rxjs/operators"; | ||||
| import { CreateRuleDto, Rule, RulesService } from "../../../../../api"; | import { CreateRuleDto, Rule, RulesService } from "../../../../../api"; | ||||
| import { environment } from "../../../../environments/environment"; | import { environment } from "../../../../environments/environment"; | ||||
| import { RuleDataService } from "../../../service/rule-data.service"; | |||||
| import { RuleFlatNode } from "./rule-flat-node"; | import { RuleFlatNode } from "./rule-flat-node"; | ||||
| get data(): Rule[] { return this.dataChange.value; } | get data(): Rule[] { return this.dataChange.value; } | ||||
| get count(): number { return this.dataChange.value.length }; | get count(): number { return this.dataChange.value.length }; | ||||
| protected removeData(rule: Rule) { | |||||
| const indexOfRule = this.dataChange.value.indexOf(rule); | |||||
| if (indexOfRule !== -1) { | |||||
| this.dataChange.value.splice(indexOfRule, 1) | |||||
| this.dataChange.next( | |||||
| this.data | |||||
| ); | |||||
| } | |||||
| } | |||||
| protected addData(rule: Rule) { this.dataChange.next([...this.dataChange.value, rule]) } | protected addData(rule: Rule) { this.dataChange.next([...this.dataChange.value, rule]) } | ||||
| constructor(protected rulesService: RulesService) { | |||||
| constructor(protected rulesService: RulesService, protected ruleHelperService: RuleDataService) { | |||||
| this.rulesService.configuration.basePath = environment.apiUrl; | this.rulesService.configuration.basePath = environment.apiUrl; | ||||
| this.rulesService.findAll() | |||||
| this.rulesService.findAllAdmin() | |||||
| .subscribe( | .subscribe( | ||||
| (rules: Rule[]) => this.dataChange.next( | (rules: Rule[]) => this.dataChange.next( | ||||
| rules | rules | ||||
| .filter(this.filterRuleWithParentFromRootLayer) | |||||
| .sort(this.compareRulesByParagraph) | |||||
| .filter(ruleHelperService.filterRuleWithParentFromRootLayer) | |||||
| .sort(ruleHelperService.compareRulesByParagraph) | |||||
| ) | ) | ||||
| ), | ), | ||||
| (err) => { | (err) => { | ||||
| //TODO add toaster | //TODO add toaster | ||||
| } | } | ||||
| } | } | ||||
| getParagraphOfNextChild = (parentRule): string => `${parentRule.paragraph}.${parentRule.subRule.length + 1}`; | |||||
| filterRuleWithParentFromRootLayer = (rootLayerRule: Rule) => typeof rootLayerRule.parentRule !== 'number'; | |||||
| compareRulesByParagraph = (ruleA: Rule, ruleB: Rule) => this.compareParahraph(ruleA.paragraph, ruleB.paragraph); | |||||
| compareParahraph(paragraphA: string, paragraphB: string): 0 | 1 | -1 { | |||||
| if (paragraphA === paragraphB) { | |||||
| return 0; | |||||
| } | |||||
| const paragrapASections = paragraphA.split('.'); | |||||
| const paragrapBSections = paragraphB.split('.'); | |||||
| if (+paragrapASections[0] > +paragrapBSections[0]) { | |||||
| return 1; | |||||
| } | |||||
| if (+paragrapASections[0] < +paragrapBSections[0]) { | |||||
| return -1; | |||||
| } | |||||
| if (+paragrapASections[0] === +paragrapBSections[0]) { | |||||
| let shiftedParagraphASections = paragrapASections; | |||||
| shiftedParagraphASections.shift(); | |||||
| let shiftedParagraphBSections = paragrapBSections; | |||||
| shiftedParagraphBSections.shift(); | |||||
| return this.compareParahraph( | |||||
| shiftedParagraphASections.join('.'), | |||||
| shiftedParagraphBSections.join('.'), | |||||
| ) | |||||
| } | |||||
| } | |||||
| getParentById = (ruleId: string) => this.data.find(rule => rule.id === ruleId) | getParentById = (ruleId: string) => this.data.find(rule => rule.id === ruleId) | ||||
| insertEmptyChild(parent: Rule) { | insertEmptyChild(parent: Rule) { | ||||
| if (!parent.subRule) { | |||||
| parent.subRule = []; | |||||
| } | |||||
| parent.subRule.push( | parent.subRule.push( | ||||
| { | { | ||||
| text: '', | text: '', | ||||
| id: '0', | id: '0', | ||||
| parentRule: parent, | parentRule: parent, | ||||
| paragraph: this.getParagraphOfNextChild(parent) | |||||
| paragraph: this.ruleHelperService.getParagraphOfNextChild(parent), | |||||
| created: 'today', | |||||
| deletedAt: null, | |||||
| updated: null, | |||||
| } | } | ||||
| ) | ) | ||||
| this.dataChange.next(this.data); | this.dataChange.next(this.data); | ||||
| text: '', | text: '', | ||||
| id: '0', | id: '0', | ||||
| parentRule: null, | parentRule: null, | ||||
| paragraph: `${this.count + 2}` | |||||
| paragraph: `${this.count + 1}`, | |||||
| created: 'today', | |||||
| deletedAt: null, | |||||
| updated: null, | |||||
| }) | }) | ||||
| } | } | ||||
| insertChild(parent: Rule, subRule: Rule) { | insertChild(parent: Rule, subRule: Rule) { | ||||
| paragraph: parent.paragraph, | paragraph: parent.paragraph, | ||||
| subRuleIds: [ | subRuleIds: [ | ||||
| ...parent.subRule | ...parent.subRule | ||||
| .filter(rule => rule.id === "0") | |||||
| .map(rule => rule.id) ?? [], | |||||
| .filter(rule => rule.id !== "0") | |||||
| .map(rule => rule.id), | |||||
| subRule.id, | subRule.id, | ||||
| ], | ], | ||||
| text: parent.text | text: parent.text | ||||
| insertParent(newRule: Rule) { | insertParent(newRule: Rule) { | ||||
| const createNewRule: CreateRuleDto = { | const createNewRule: CreateRuleDto = { | ||||
| paragraph: `${this.count + 1}`, | |||||
| paragraph: newRule.paragraph, | |||||
| text: newRule.text, | text: newRule.text, | ||||
| subRuleIds: null, | subRuleIds: null, | ||||
| parentId: null | parentId: null | ||||
| this.dataChange.next(this.data); | this.dataChange.next(this.data); | ||||
| } | } | ||||
| removeParent(parent: Rule) { | |||||
| parent.deletedAt = "deleted"; | |||||
| this.rulesService.remove(parent.id).subscribe( | |||||
| (deleted) => { | |||||
| //todo add update message | |||||
| }, | |||||
| (err) => { | |||||
| //TODO Push error message | |||||
| console.error(err); | |||||
| } | |||||
| ); | |||||
| this.dataChange.next(this.data); | |||||
| } | |||||
| restore(rule: Rule) { | |||||
| rule.deletedAt = null; | |||||
| if (rule.subRule) { | |||||
| rule.subRule.forEach((subRule) => { | |||||
| this.restore(subRule); | |||||
| }) | |||||
| } | |||||
| this.rulesService.restore(rule.id).subscribe( | |||||
| (deleted) => { | |||||
| //todo add restored message | |||||
| }, | |||||
| (err) => { | |||||
| //TODO Push error message | |||||
| console.error(err); | |||||
| } | |||||
| ); | |||||
| this.dataChange.next(this.data); | |||||
| } | |||||
| removeChild(parent: Rule, subRule: Rule) { | removeChild(parent: Rule, subRule: Rule) { | ||||
| if (parent.subRule) { | if (parent.subRule) { | ||||
| const subRuleToRemove = this.findSubRuleFromParent(parent, subRule); | |||||
| const indexIfSubRule = parent.subRule.indexOf(subRuleToRemove); | |||||
| if (indexIfSubRule > -1) { | |||||
| parent.subRule.splice(indexIfSubRule, 1); | |||||
| } | |||||
| subRule.deletedAt = "delted"; | |||||
| this.rulesService.remove(subRule.id).subscribe( | |||||
| (deleted) => { | |||||
| this.update(parent.id, { | |||||
| paragraph: parent.paragraph, | |||||
| subRuleIds: [ | |||||
| ...parent.subRule | |||||
| .filter(rule => rule.id !== "0") | |||||
| .map(rule => rule.id) | |||||
| ], | |||||
| text: parent.text | |||||
| }).subscribe( | |||||
| (updated) => { | |||||
| //todo add update message | |||||
| }, | |||||
| (err) => { | |||||
| //TODO Push error message | |||||
| console.error(err); | |||||
| } | |||||
| ); | |||||
| //todo add update message | |||||
| }, | |||||
| (err) => { | |||||
| //TODO Push error message | |||||
| console.error(err); | |||||
| } | |||||
| ); | |||||
| this.dataChange.next(this.data); | this.dataChange.next(this.data); | ||||
| } | } | ||||
| } | } |
| <button mat-icon-button disabled></button> §{{ node.item.paragraph }} {{ node.item.text }} | <button mat-icon-button disabled></button> §{{ node.item.paragraph }} {{ node.item.text }} | ||||
| <button *ngIf="node.root" mat-icon-button (click)="addEmptyRule(node)"> | <button *ngIf="node.root" mat-icon-button (click)="addEmptyRule(node)"> | ||||
| <mat-icon>add</mat-icon> | <mat-icon>add</mat-icon> | ||||
| </button> | |||||
| <button mat-icon-button (click)="remove(node)"> | |||||
| <mat-icon>remove</mat-icon> | |||||
| </button> | </button> | ||||
| </div> | </div> | ||||
| </mat-tree-node> | </mat-tree-node> | ||||
| <button *ngIf="node.root" mat-icon-button (click)="addEmptyRule(node)"> | <button *ngIf="node.root" mat-icon-button (click)="addEmptyRule(node)"> | ||||
| <mat-icon>add</mat-icon> | <mat-icon>add</mat-icon> | ||||
| </button> | </button> | ||||
| <button mat-icon-button (click)="remove(node)"> | |||||
| <mat-icon>remove</mat-icon> | |||||
| </button> | |||||
| </mat-tree-node> | </mat-tree-node> | ||||
| <mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding> | <mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding> | ||||
| <button mat-icon-button disabled></button> | <button mat-icon-button disabled></button> | ||||
| </mat-form-field> | </mat-form-field> | ||||
| <button mat-button (click)="addNode(node, itemValue.value)">Save</button> | <button mat-button (click)="addNode(node, itemValue.value)">Save</button> | ||||
| </mat-tree-node> | </mat-tree-node> | ||||
| <mat-tree-node class="disabled-node" *matTreeNodeDef="let node; when: isDeleted" matTreeNodePadding> | |||||
| <button mat-icon-button (click)="restore(node)"> | |||||
| <mat-icon>restore</mat-icon> | |||||
| </button> | |||||
| <span>§{{ node.item.paragraph }} {{node.item.text}}</span> | |||||
| </mat-tree-node> | |||||
| </mat-tree> | </mat-tree> | ||||
| <button mat-icon-button (click)="addEmptyRule()"> | <button mat-icon-button (click)="addEmptyRule()"> | ||||
| <mat-icon>add</mat-icon> | |||||
| <mat-icon>add</mat-icon> | |||||
| </button> | </button> | ||||
| </mat-card> | </mat-card> |
| .new-node-input { | .new-node-input { | ||||
| padding-left: 2vw; | padding-left: 2vw; | ||||
| } | |||||
| .disabled-node { | |||||
| text-decoration: line-through; | |||||
| } | } |
| getLevel = (node: RuleFlatNode) => node.level; | getLevel = (node: RuleFlatNode) => node.level; | ||||
| isExpandable = (node: RuleFlatNode) => node.expandable; | isExpandable = (node: RuleFlatNode) => node.expandable; | ||||
| getChildren = (node: Rule): Rule[] => node.subRule; | getChildren = (node: Rule): Rule[] => node.subRule; | ||||
| hasChild = (_: number, node: RuleFlatNode) => node.expandable; | |||||
| hasChild = (_: number, node: RuleFlatNode) => node.expandable && !this.isDeleted(_, node); | |||||
| isDeleted = (_: number, _nodeData: RuleFlatNode) => _nodeData.item.deletedAt !== null; | |||||
| hasNoContent = (_: number, _nodeData: RuleFlatNode) => _nodeData.item.text === ''; | hasNoContent = (_: number, _nodeData: RuleFlatNode) => _nodeData.item.text === ''; | ||||
| hasContent = (_nodeData: RuleFlatNode) => _nodeData.item.text !== ""; | hasContent = (_nodeData: RuleFlatNode) => _nodeData.item.text !== ""; | ||||
| if (!!newRule.parentRule) { | if (!!newRule.parentRule) { | ||||
| const parentRule = this._database.getParentById(newRule.parentRule.id) | const parentRule = this._database.getParentById(newRule.parentRule.id) | ||||
| this._database.insertChild(parentRule, newRule) | this._database.insertChild(parentRule, newRule) | ||||
| return; | |||||
| } | } | ||||
| this._database.insertParent(newRule) | this._database.insertParent(newRule) | ||||
| } | } | ||||
| async remove(nodeToRemove: RuleFlatNode) { | |||||
| const ruleToRemove = this.flatNodeMap.get(nodeToRemove); | |||||
| if (nodeToRemove.root) { | |||||
| this._database.removeParent(ruleToRemove); | |||||
| return | |||||
| } | |||||
| const parentNode = this.getParentNode(nodeToRemove); | |||||
| const parent = this.flatNodeMap.get(parentNode); | |||||
| this._database.removeChild(parent, ruleToRemove); | |||||
| } | |||||
| async restore(nodeToRestore: RuleFlatNode) { | |||||
| const ruleToRestore = this.flatNodeMap.get(nodeToRestore); | |||||
| this._database.restore(ruleToRestore); | |||||
| } | |||||
| } | } |
| <mat-sidenav-container class="all-wrap"> | <mat-sidenav-container class="all-wrap"> | ||||
| <mat-sidenav-content class="page-wrap"> | |||||
| <mat-toolbar color="primary"> | |||||
| <span class="mat-title title" > | |||||
| <mat-sidenav-content class="page-wrap"> | |||||
| <mat-toolbar color="primary"> | |||||
| <span routerLink="" class="mat-title title"> | |||||
| <mat-icon mat-list-icon class="logo">bedroom_baby</mat-icon> Hof Hoppe</span | <mat-icon mat-list-icon class="logo">bedroom_baby</mat-icon> Hof Hoppe</span | ||||
| > | > | ||||
| </mat-toolbar> | </mat-toolbar> | ||||
| <router-outlet></router-outlet> | <router-outlet></router-outlet> | ||||
| </main> | </main> | ||||
| </mat-sidenav-content> | </mat-sidenav-content> | ||||
| </mat-sidenav-container> | |||||
| </mat-sidenav-container> |
| import { Component, OnInit } from '@angular/core'; | import { Component, OnInit } from '@angular/core'; | ||||
| import { Rule } from '../../../../api/model/rule'; | import { Rule } from '../../../../api/model/rule'; | ||||
| import { RulesService } from '../../../../api/api/rules.service'; | import { RulesService } from '../../../../api/api/rules.service'; | ||||
| import { RuleDataService } from '../../service/rule-data.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-rules', | selector: 'app-rules', | ||||
| templateUrl: './rules.component.html', | templateUrl: './rules.component.html', | ||||
| }) | }) | ||||
| export class RulesComponent implements OnInit { | export class RulesComponent implements OnInit { | ||||
| rules: Rule[] = [] | rules: Rule[] = [] | ||||
| constructor(protected rulesService: RulesService) { | |||||
| constructor(protected rulesService: RulesService,protected ruleDataService: RuleDataService) { | |||||
| rulesService.configuration.basePath = 'http://localhost:3000'; | rulesService.configuration.basePath = 'http://localhost:3000'; | ||||
| } | } | ||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.rulesService.findAll('body').subscribe((rules: Rule[]) => { | this.rulesService.findAll('body').subscribe((rules: Rule[]) => { | ||||
| this.rules = rules; | |||||
| this.rules = rules | |||||
| .sort(this.ruleDataService.compareRulesByParagraph) | |||||
| }) | }) | ||||
| } | } | ||||
| import { TestBed } from '@angular/core/testing'; | |||||
| import { RuleDataService } from './rule-data.service'; | |||||
| describe('RuleDataService', () => { | |||||
| let service: RuleDataService; | |||||
| beforeEach(() => { | |||||
| TestBed.configureTestingModule({}); | |||||
| service = TestBed.inject(RuleDataService); | |||||
| }); | |||||
| it('should be created', () => { | |||||
| expect(service).toBeTruthy(); | |||||
| }); | |||||
| }); |
| import { Injectable } from '@angular/core'; | |||||
| import { Rule } from '../../../api'; | |||||
| @Injectable({ | |||||
| providedIn: 'root' | |||||
| }) | |||||
| export class RuleDataService { | |||||
| getParagraphOfNextChild = (parentRule): string => `${parentRule.paragraph}.${parentRule.subRule.length + 1}`; | |||||
| filterRuleWithParentFromRootLayer = (rootLayerRule: Rule) => typeof rootLayerRule.parentRule !== 'number'; | |||||
| compareRulesByParagraph = (ruleA: Rule, ruleB: Rule) => this.compareParahraph(ruleA.paragraph, ruleB.paragraph); | |||||
| compareParahraph(paragraphA: string, paragraphB: string): 0 | 1 | -1 { | |||||
| if (paragraphA === paragraphB) { | |||||
| return 0; | |||||
| } | |||||
| const paragrapASections = paragraphA.split('.'); | |||||
| const paragrapBSections = paragraphB.split('.'); | |||||
| if (+paragrapASections[0] > +paragrapBSections[0]) { | |||||
| return 1; | |||||
| } | |||||
| if (+paragrapASections[0] < +paragrapBSections[0]) { | |||||
| return -1; | |||||
| } | |||||
| if (+paragrapASections[0] === +paragrapBSections[0]) { | |||||
| let shiftedParagraphASections = paragrapASections; | |||||
| shiftedParagraphASections.shift(); | |||||
| let shiftedParagraphBSections = paragrapBSections; | |||||
| shiftedParagraphBSections.shift(); | |||||
| return this.compareParahraph( | |||||
| shiftedParagraphASections.join('.'), | |||||
| shiftedParagraphBSections.join('.'), | |||||
| ) | |||||
| } | |||||
| } | |||||
| constructor() { } | |||||
| } |