Browse Source

add edit function

master
Christian Ziermann 3 years ago
parent
commit
af8c7a4d43
22 changed files with 464 additions and 120 deletions
  1. +7
    -1
      src/app/admin/admin.module.ts
  2. +142
    -46
      src/app/admin/create-rule/class/dynamic-database.ts
  3. +1
    -0
      src/app/admin/create-rule/class/event-message.ts
  4. +8
    -2
      src/app/admin/create-rule/class/rule-flat-node.ts
  5. +70
    -43
      src/app/admin/create-rule/create-rule.component.html
  6. +79
    -4
      src/app/admin/create-rule/create-rule.component.ts
  7. +11
    -0
      src/app/admin/options-shet/options-shet.component.html
  8. +0
    -0
      src/app/admin/options-shet/options-shet.component.scss
  9. +25
    -0
      src/app/admin/options-shet/options-shet.component.spec.ts
  10. +23
    -0
      src/app/admin/options-shet/options-shet.component.ts
  11. +2
    -0
      src/app/app.module.ts
  12. +2
    -2
      src/app/auth/interceptor/error.interceptor.ts
  13. +3
    -0
      src/app/event-dialog/event-dialog.component.html
  14. +6
    -0
      src/app/event-dialog/event-dialog.component.scss
  15. +25
    -0
      src/app/event-dialog/event-dialog.component.spec.ts
  16. +16
    -0
      src/app/event-dialog/event-dialog.component.ts
  17. +6
    -4
      src/app/footer/footer.component.html
  18. +8
    -1
      src/app/footer/footer.component.scss
  19. +5
    -1
      src/app/footer/footer.module.ts
  20. +7
    -6
      src/app/main/main.component.html
  21. +9
    -9
      src/app/rules/rules/rules.component.html
  22. +9
    -1
      src/app/rules/rules/rules.component.ts

+ 7
- 1
src/app/admin/admin.module.ts View File

import { MatCommonModule } from '@angular/material/core'; import { MatCommonModule } from '@angular/material/core';
import { MatInputModule } from '@angular/material/input'; import { MatInputModule } from '@angular/material/input';
import { DynamicDatabase } from './create-rule/class/dynamic-database'; import { DynamicDatabase } from './create-rule/class/dynamic-database';
import {MatSnackBarModule} from '@angular/material/snack-bar';
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
import { OptionsShetComponent } from './options-shet/options-shet.component';




@NgModule({ @NgModule({
declarations: [ declarations: [
CreateRuleComponent
CreateRuleComponent,
OptionsShetComponent
], ],
imports: [ imports: [
MatBottomSheetModule,
MatSnackBarModule,
CommonModule, CommonModule,
MatCardModule, MatCardModule,
MatFormFieldModule, MatFormFieldModule,

+ 142
- 46
src/app/admin/create-rule/class/dynamic-database.ts View File

import { Injectable } from "@angular/core"
import { RippleRef } from "@angular/material/core";
import { Injectable } from "@angular/core";
import { BehaviorSubject, Subject } from "rxjs"; import { BehaviorSubject, Subject } from "rxjs";
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 { RuleDataService } from "../../../service/rule-data.service";
import { RuleFlatNode } from "./rule-flat-node";
import { EventMessage } from "./event-message";




@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })


dataChange = new BehaviorSubject<Rule[]>([]); dataChange = new BehaviorSubject<Rule[]>([]);
childAdded = new Subject<Rule>(); childAdded = new Subject<Rule>();
onEvent = new Subject<EventMessage>()


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 };
) )
), ),
(err) => { (err) => {
//TODO add toaster
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim abrufen der Regeln`
}
);
} }
} }


getById = (ruleId: string) => {
const parentNode = this.getParentById(ruleId);
if (parentNode) {
return parentNode;
}
for (const rootRule of this.data) {
const found = this.findChildById(rootRule, ruleId);
if (found) {
return found;
}
}
return null;
}

findChildById = (parent: Rule, ruleId: string) => {
if (!parent.subRule) {
return null;
}
return parent.subRule.find((
rule => rule.id === ruleId
))
}
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) { if (!parent.subRule) {
parent.subRule = []; parent.subRule = [];
} }
{ {
text: '', text: '',
id: '0', id: '0',
parentRule: parent,
parentRule: {
id: parent.id
},
paragraph: this.ruleHelperService.getParagraphOfNextChild(parent), paragraph: this.ruleHelperService.getParagraphOfNextChild(parent),
created: 'today', created: 'today',
deletedAt: null, deletedAt: null,
updated: null, updated: null,
}
} as Rule
) )
this.dataChange.next(this.data); this.dataChange.next(this.data);
this.childAdded.next(parent); this.childAdded.next(parent);
} }
this.rulesService.create(createSubRule).subscribe( this.rulesService.create(createSubRule).subscribe(
newSubRule => { newSubRule => {
subRule.id = newSubRule.id;
this.dataChange.next(this.data);
if (typeof newSubRule.id !== 'undefined' && typeof newSubRule.parentRule?.id !== 'undefined') { if (typeof newSubRule.id !== 'undefined' && typeof newSubRule.parentRule?.id !== 'undefined') {
const updateParentRule: CreateRuleDto = { const updateParentRule: CreateRuleDto = {
paragraph: parent.paragraph, paragraph: parent.paragraph,
//TODO Push updated message //TODO Push updated message
this.update(parent.id, { this.update(parent.id, {
paragraph: parent.paragraph, paragraph: parent.paragraph,
subRuleIds: [
subRule: [
...parent.subRule ...parent.subRule
.filter(rule => rule.id !== "0")
.map(rule => rule.id),
subRule.id,
.filter(rule => rule.id !== "0"),
subRule,
], ],
text: parent.text text: parent.text
}).subscribe(
(updated) => {
//todo add update message
},
(err) => {
//TODO Push error message
console.error(err);
}
)
});
}, },
(err) => { (err) => {
//TODO Push error message
console.error(err);
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim aktualisieren von Regel ${parent.paragraph}`
}
);
} }
) )
return; return;
} }
//TODO Push error message
} }
) )
if (!parent.subRule) { if (!parent.subRule) {
this.childAdded.next(parent); this.childAdded.next(parent);
} }


update(id: string, changedData: Partial<CreateRuleDto>) {
return this.rulesService.update(id, changedData);
reload() {
this.dataChange.next(this.data);
}

update(id: string, changedData: Partial<Rule>) {
let ruleToUpdate = this.getById(id);
const updateDto = {
paragraph: !!changedData.paragraph ? changedData.paragraph : ruleToUpdate.paragraph,
text: !!changedData.text ? changedData.text : ruleToUpdate.text,
parentId: !!changedData.parentRule ? changedData.parentRule.id : null,
subRuleIds: [
...!!changedData.subRule ?
changedData.subRule
.map(rule => rule.id)
: []
]
} as CreateRuleDto
this.rulesService.update(id, updateDto).subscribe(
() => {
this.onEvent.next(
{
event: 'Update',
message: `Regel ${ruleToUpdate.paragraph} wurde erfolgreich aktualisiert`
}
);
},
(err) => {
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim aktualisieren der Regel ${ruleToUpdate.paragraph}`
}
);
}
)
this.dataChange.next(this.data);
} }


insertParent(newRule: Rule) { insertParent(newRule: Rule) {
parentId: null parentId: null
} }
this.rulesService.create(createNewRule).subscribe( this.rulesService.create(createNewRule).subscribe(
() => {
//TODO created message
(created) => {
newRule.id = created.id;
this.dataChange.next(this.data);
this.onEvent.next(
{
event: 'Create',
message: `Regel ${createNewRule.paragraph} wurde erfolgreich erstellt`
}
);
}, },
(err) => { (err) => {
//TODO Error message
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim anlegen der Regel ${createNewRule.paragraph}`
}
);
} }
) )
this.dataChange.next(this.data); this.dataChange.next(this.data);
parent.deletedAt = "deleted"; parent.deletedAt = "deleted";
this.rulesService.remove(parent.id).subscribe( this.rulesService.remove(parent.id).subscribe(
(deleted) => { (deleted) => {
//todo add update message
this.onEvent.next(
{
event: 'Restore',
message: `Regel ${parent.paragraph} wurde erfolgreich deaktiviert`
}
);
}, },
(err) => { (err) => {
//TODO Push error message
console.error(err);
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim aktivieren von Regel ${parent.paragraph}`
}
);
} }
); );
this.dataChange.next(this.data); this.dataChange.next(this.data);
} }
this.rulesService.restore(rule.id).subscribe( this.rulesService.restore(rule.id).subscribe(
(deleted) => { (deleted) => {
//todo add restored message
this.onEvent.next(
{
event: 'Restore',
message: `Regel ${rule.paragraph} wurde erfolgreich reaktiviert`
}
);
}, },
(err) => { (err) => {
//TODO Push error message
console.error(err);
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim aktivieren der Regel ${rule.paragraph}`
}
);
} }
); );
this.dataChange.next(this.data); this.dataChange.next(this.data);
(deleted) => { (deleted) => {
this.update(parent.id, { this.update(parent.id, {
paragraph: parent.paragraph, paragraph: parent.paragraph,
subRuleIds: [
subRule: [
...parent.subRule ...parent.subRule
.filter(rule => rule.id !== "0") .filter(rule => rule.id !== "0")
.map(rule => rule.id)
], ],
text: parent.text text: parent.text
}).subscribe(
(updated) => {
//todo add update message
},
(err) => {
//TODO Push error message
console.error(err);
});
this.onEvent.next(
{
event: 'Remove',
message: `Regel ${subRule.paragraph} wurde erfolgreich deaktiviert`
} }
); );
//todo add update message
}, },
(err) => { (err) => {
//TODO Push error message
console.error(err);
this.onEvent.next(
{
event: 'Error',
error: err,
message: `Fehler beim deaktivieren von Regel ${subRule.paragraph}`
}
);
} }
); );
this.dataChange.next(this.data); this.dataChange.next(this.data);

+ 1
- 0
src/app/admin/create-rule/class/event-message.ts View File

export class EventMessage { event: 'Error' | 'Create' | 'Update' | 'Restore' | 'Remove'; message: string; error?: Error }

+ 8
- 2
src/app/admin/create-rule/class/rule-flat-node.ts View File

import { Rule } from "../../../../../api"; import { Rule } from "../../../../../api";


export class RuleFlatNode { export class RuleFlatNode {
constructor(public item: Rule, public level = 1, public expandable = false,
public isLoading = false,public root = true) { }
constructor(
public item: Rule,
public level = 1,
public expandable = false,
public isLoading = false,
public root = true,
public editMode = false,
) { }
} }



+ 70
- 43
src/app/admin/create-rule/create-rule.component.html View File

<mat-card class="wood-card"> <mat-card class="wood-card">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<div>
<button mat-icon-button disabled></button> §{{ node.item.paragraph }} {{ node.item.text }}
<button *ngIf="node.root" mat-icon-button (click)="addEmptyRule(node)">
<mat-icon>add</mat-icon>
</button>
<button mat-icon-button (click)="remove(node)">
<mat-icon>remove</mat-icon>
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<div>
<button mat-icon-button disabled></button>
<span *ngIf="!node.editMode">
§{{ node.item.paragraph }} {{ node.item.text }}
</span>
<span *ngIf="node.editMode">
§{{ node.item.paragraph }}
<mat-form-field class="new-node-input">
<mat-label>Updated Rule</mat-label>
<input [formControl]="text" [value]="node.item.text" matInput #itemValue placeholder="text" />
</mat-form-field>
<button [disabled]="itemValue.value === ''" mat-button (click)="updateNode(node, itemValue.value)">Update</button>

</span>

<button mat-icon-button (click)="openOptions(node)">
<mat-icon>more_vert</mat-icon>
</button> </button>
</div>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.text">
<mat-icon class="mat-icon-rtl-mirror">
{{ treeControl.isExpanded(node) ? "expand_more" : "chevron_right" }}
</mat-icon>
</button> §{{ node.item.paragraph }} {{ node.item.text }}
<button *ngIf="node.root" mat-icon-button (click)="addEmptyRule(node)">
<mat-icon>add</mat-icon>
</button>
<button mat-icon-button (click)="remove(node)">
<mat-icon>remove</mat-icon>
</button>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding>
<button mat-icon-button disabled></button>
<span>§{{ node.item.paragraph }}</span>
<mat-form-field class="new-node-input">
<mat-label>New Rule</mat-label>
<input [formControl]="text" matInput #itemValue placeholder="text" />
</mat-form-field>
<button mat-button (click)="addNode(node, itemValue.value)">Save</button>
</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>
<button mat-icon-button (click)="addEmptyRule()">
<mat-icon>add</mat-icon>
</div>
</mat-tree-node>

<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
<button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.text">
<mat-icon class="mat-icon-rtl-mirror">
{{ treeControl.isExpanded(node) ? "expand_more" : "chevron_right" }}
</mat-icon>
</button>
<span *ngIf="!node.editMode">
§{{ node.item.paragraph }} {{ node.item.text }}
</span>
<span *ngIf="node.editMode">
§{{ node.item.paragraph }}
<mat-form-field class="new-node-input">
<mat-label>Updated Rule</mat-label>
<input [formControl]="text" [value]="node.item.text" matInput #itemValue placeholder="text" />
</mat-form-field>
<button [disabled]="itemValue.value === ''" mat-button (click)="updateNode(node, itemValue.value)">Update</button>

</span>

<button mat-icon-button (click)="openOptions(node)">
<mat-icon>more_vert</mat-icon>
</button>
</mat-tree-node>

<mat-tree-node *matTreeNodeDef="let node; when: hasNoContent" matTreeNodePadding>
<button mat-icon-button disabled></button>
<span>§{{ node.item.paragraph }}</span>
<mat-form-field class="new-node-input">
<mat-label>New Rule</mat-label>
<input [formControl]="text" matInput #itemValue placeholder="text" />
</mat-form-field>
<button [disabled]="itemValue.value === ''" mat-button (click)="addNode(node, itemValue.value)">Save</button>
</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>
<button mat-icon-button (click)="openOptions(node)">
<mat-icon>more_vert</mat-icon>
</button>
</mat-tree-node>
</mat-tree>
<button mat-icon-button (click)="addEmptyRule()">
<mat-icon>add</mat-icon>
</button> </button>
</mat-card> </mat-card>

+ 79
- 4
src/app/admin/create-rule/create-rule.component.ts View File

import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { MatBottomSheet, MatBottomSheetConfig } from '@angular/material/bottom-sheet';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
import { Subject } from 'rxjs';
import { Rule } from '../../../../api/model/rule'; import { Rule } from '../../../../api/model/rule';
import { EventDialogComponent } from '../../event-dialog/event-dialog.component';
import { OptionsShetComponent } from '../options-shet/options-shet.component';
import { DynamicDatabase } from './class/dynamic-database'; import { DynamicDatabase } from './class/dynamic-database';
import { EventMessage } from './class/event-message';
import { RuleFlatNode } from './class/rule-flat-node'; import { RuleFlatNode } from './class/rule-flat-node';




flatNodeMap = new Map<RuleFlatNode, Rule>(); flatNodeMap = new Map<RuleFlatNode, Rule>();
nestedNodeMap = new Map<Rule, RuleFlatNode>(); nestedNodeMap = new Map<Rule, RuleFlatNode>();
text = new FormControl(''); text = new FormControl('');
@ViewChild(TemplateRef) template: TemplateRef<any>;




private _transformer = (rule: Rule, level: number) => { private _transformer = (rule: Rule, level: number) => {
;
const existingNode = this.nestedNodeMap.get(rule); const existingNode = this.nestedNodeMap.get(rule);
const flatNode = existingNode && existingNode.item.id === rule.id const flatNode = existingNode && existingNode.item.id === rule.id
? existingNode ? existingNode
dataSource: MatTreeFlatDataSource<Rule, RuleFlatNode>; dataSource: MatTreeFlatDataSource<Rule, RuleFlatNode>;
_database: DynamicDatabase; _database: DynamicDatabase;


constructor(database: DynamicDatabase) {
constructor(database: DynamicDatabase, private _snackBar: MatSnackBar, readonly bottomSheet: MatBottomSheet) {
this._database = database; this._database = database;
this.treeControl = new FlatTreeControl<RuleFlatNode>(this.getLevel, this.isExpandable); this.treeControl = new FlatTreeControl<RuleFlatNode>(this.getLevel, this.isExpandable);
this.treeFlattener = new MatTreeFlattener<Rule, RuleFlatNode, RuleFlatNode>( this.treeFlattener = new MatTreeFlattener<Rule, RuleFlatNode, RuleFlatNode>(
this._database.dataChange.subscribe(data => { this._database.dataChange.subscribe(data => {
this.dataSource.data = data; this.dataSource.data = data;
}); });
this._database.onEvent.subscribe(
(event) => {
if (event.error) {
console.error(event.error);
}
this.openSnackBar(event)
}
)
this._database.childAdded.subscribe(parent => this.treeControl.expand(this.nestedNodeMap.get(parent))) this._database.childAdded.subscribe(parent => this.treeControl.expand(this.nestedNodeMap.get(parent)))
} }


ngOnInit(): void { ngOnInit(): void {
} }


openOptions(node: RuleFlatNode) {
const onRemove = new Subject<RuleFlatNode>();
const onAdd = new Subject<RuleFlatNode>();
const onEdit = new Subject<RuleFlatNode>();
this.bottomSheet.open(OptionsShetComponent, {
data: {
remove: onRemove,
add: onAdd,
edit: onEdit,
node: node
}
});
onRemove.subscribe(
(node) => {
this.remove(node);
this.bottomSheet.dismiss();
}
)
onAdd.subscribe(
(node) => {
this.addEmptyRule(node);
this.bottomSheet.dismiss();
}
)
onEdit.subscribe(
(node) => {
this.openEdit(node);
this.bottomSheet.dismiss();
}
)
}

openSnackBar(event: EventMessage) {
this._snackBar.openFromComponent(EventDialogComponent, {
data: event,
duration: 1000,
});
}

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 && !this.isDeleted(_, node);
hasChild = (_: number, node: RuleFlatNode) => node.expandable && !this.isDeleted(_, node) && !this.inEditMode(_, node);
inEditMode = (_: number, node: RuleFlatNode) => node.editMode;
isDeleted = (_: number, _nodeData: RuleFlatNode) => _nodeData.item.deletedAt !== null; 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 !== "";
} }


async addNode(newNode: RuleFlatNode, text: string) { async addNode(newNode: RuleFlatNode, text: string) {
;
const newRule = this.flatNodeMap.get(newNode); const newRule = this.flatNodeMap.get(newNode);
newRule.text = text; newRule.text = 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; return;
this._database.removeChild(parent, ruleToRemove); this._database.removeChild(parent, ruleToRemove);
} }


async openEdit(nodeToEdit: RuleFlatNode) {
nodeToEdit.editMode = true;
this._database.reload;
}



async restore(nodeToRestore: RuleFlatNode) { async restore(nodeToRestore: RuleFlatNode) {
const ruleToRestore = this.flatNodeMap.get(nodeToRestore); const ruleToRestore = this.flatNodeMap.get(nodeToRestore);
this._database.restore(ruleToRestore); this._database.restore(ruleToRestore);
} }

async updateNode(updatedNode: RuleFlatNode, updatedText: string) {
const parentNode = this.getParentNode(updatedNode);
if (parentNode) {
updatedNode.item.parentRule = {
id: parentNode.item.id,
text: parentNode.item.text,
paragraph: parentNode.item.text
}
}
const updatedRule = this.flatNodeMap.get(updatedNode);
updatedRule.text = updatedText;
this._database.update(updatedRule.id, updatedRule)
}




} }

+ 11
- 0
src/app/admin/options-shet/options-shet.component.html View File

<span>
<button *ngIf="config.node.root" mat-icon-button (click)="config.add.next(config.node)">
<mat-icon>add</mat-icon>
</button>
<button mat-icon-button (click)="config.remove.next(config.node)">
<mat-icon>remove</mat-icon>
</button>
<button mat-icon-button (click)="config.edit.next(config.node)">
<mat-icon>edit</mat-icon>
</button>
</span>

+ 0
- 0
src/app/admin/options-shet/options-shet.component.scss View File


+ 25
- 0
src/app/admin/options-shet/options-shet.component.spec.ts View File

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { OptionsShetComponent } from './options-shet.component';

describe('OptionsShetComponent', () => {
let component: OptionsShetComponent;
let fixture: ComponentFixture<OptionsShetComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ OptionsShetComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(OptionsShetComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 23
- 0
src/app/admin/options-shet/options-shet.component.ts View File

import { Component, Inject, OnInit } from '@angular/core';
import { MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';
import { Subject } from 'rxjs';
import { RuleFlatNode } from '../create-rule/class/rule-flat-node';

@Component({
selector: 'app-options-shet',
templateUrl: './options-shet.component.html',
styleUrls: ['./options-shet.component.scss']
})
export class OptionsShetComponent implements OnInit {

constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public config: {
add: Subject<RuleFlatNode>,
remove: Subject<RuleFlatNode>,
edit: Subject<RuleFlatNode>,
node: RuleFlatNode
}) { }

ngOnInit(): void {
}

}

+ 2
- 0
src/app/app.module.ts View File

import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth/interceptor/auth.interceptor'; import { AuthInterceptor } from './auth/interceptor/auth.interceptor';
import { ErrorInterceptor } from './auth/interceptor/error.interceptor'; import { ErrorInterceptor } from './auth/interceptor/error.interceptor';
import { EventDialogComponent } from './event-dialog/event-dialog.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
DashboardComponent, DashboardComponent,
GridComponent, GridComponent,
MainComponent, MainComponent,
EventDialogComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

+ 2
- 2
src/app/auth/interceptor/error.interceptor.ts View File

// auto logout if 401 response returned from api // auto logout if 401 response returned from api
this.authenticationService.logout(); this.authenticationService.logout();
} }
const error = err.error.message || err.statusText;
;
const error = err.error?.message || err.statusText;
return throwError(error); return throwError(error);
})) }))
} }

+ 3
- 0
src/app/event-dialog/event-dialog.component.html View File

<span [ngClass]="{primary: event.event !== 'Error', warn: event.event === 'Error'}">
{{event.message}}
</span>

+ 6
- 0
src/app/event-dialog/event-dialog.component.scss View File

@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
.primary {}

.warn {
background-color: red;
}

+ 25
- 0
src/app/event-dialog/event-dialog.component.spec.ts View File

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { EventDialogComponent } from './event-dialog.component';

describe('EventDialogComponent', () => {
let component: EventDialogComponent;
let fixture: ComponentFixture<EventDialogComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ EventDialogComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(EventDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 16
- 0
src/app/event-dialog/event-dialog.component.ts View File

import { Component, Inject, Input, OnInit } from '@angular/core';
import { MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar';
import { EventMessage } from '../admin/create-rule/class/event-message';

@Component({
selector: 'app-event-dialog',
templateUrl: './event-dialog.component.html',
styleUrls: ['./event-dialog.component.scss']
})
export class EventDialogComponent implements OnInit {
constructor(@Inject(MAT_SNACK_BAR_DATA) public event: EventMessage) { }

ngOnInit(): void {
}

}

+ 6
- 4
src/app/footer/footer.component.html View File

<mat-toolbar> <mat-toolbar>
<span >
<span>
<a href="https://ziermach.de/legal">legal</a> <a href="https://ziermach.de/legal">legal</a>
</span
>
</mat-toolbar>
</span>
<span [routerLink]="['/admin/create']">
<mat-icon>add</mat-icon>
</span>
</mat-toolbar>

+ 8
- 1
src/app/footer/footer.component.scss View File

.mat-toolbar { .mat-toolbar {
height: 3%;
height: 3%;
background: transparent;
color: white;
font-size: small;
} }

a {
color: white
}

+ 5
- 1
src/app/footer/footer.module.ts View File

import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { FooterComponent } from './footer.component'; import { FooterComponent } from './footer.component';
import { MatToolbarModule } from '@angular/material/toolbar'; import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { RouterModule } from '@angular/router';






], ],
imports: [ imports: [
CommonModule, CommonModule,
MatToolbarModule
MatToolbarModule,
MatIconModule,
RouterModule,
], ],
exports: [ exports: [
FooterComponent FooterComponent

+ 7
- 6
src/app/main/main.component.html View File

<mat-sidenav-content class="page-wrap"> <mat-sidenav-content class="page-wrap">
<mat-toolbar color="primary"> <mat-toolbar color="primary">
<span routerLink="" class="mat-title title"> <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>
<main class="content">
<router-outlet></router-outlet>
</main>
</mat-sidenav-content>
</mat-toolbar>
<main class="content">
<router-outlet></router-outlet>
</main>
<app-footer></app-footer>
</mat-sidenav-content>
</mat-sidenav-container> </mat-sidenav-container>

+ 9
- 9
src/app/rules/rules/rules.component.html View File

<mat-card class="dashboard-card wood-card"> <mat-card class="dashboard-card wood-card">
<mat-card-header>
<mat-card-title class="title mat-title">
<mat-icon mat-list-icon class="logo">gavel</mat-icon> Regeln
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<app-rule-list [rules]="rules"></app-rule-list>
</mat-card-content>
</mat-card>
<mat-card-header>
<mat-card-title class="title mat-title">
<mat-icon mat-list-icon class="logo">gavel</mat-icon> Regeln
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<app-rule-list [rules]="rules"></app-rule-list>
</mat-card-content>
</mat-card>

+ 9
- 1
src/app/rules/rules/rules.component.ts View File

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'; import { RuleDataService } from '../../service/rule-data.service';
import { Router } from '@angular/router';
@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,protected ruleDataService: RuleDataService) {
constructor(
protected rulesService: RulesService,
protected ruleDataService: RuleDataService,
protected router: Router,
) {
rulesService.configuration.basePath = 'http://localhost:3000'; rulesService.configuration.basePath = 'http://localhost:3000';
} }




}) })
} }
openAdminArea() {
this.router.navigate(['/admin/create']);
}


} }

Loading…
Cancel
Save