diff --git a/src/app/groups/group-page/group-page.component.html b/src/app/groups/group-page/group-page.component.html index f4c7e23..777217e 100644 --- a/src/app/groups/group-page/group-page.component.html +++ b/src/app/groups/group-page/group-page.component.html @@ -37,7 +37,8 @@ [groups]="groups" [policies]="policies" [group]="group?.id" /> - + diff --git a/src/app/policies/policy-add-button/policy-add-button.component.ts b/src/app/policies/policy-add-button/policy-add-button.component.ts index afc68f0..6d1ff2d 100644 --- a/src/app/policies/policy-add-button/policy-add-button.component.ts +++ b/src/app/policies/policy-add-button/policy-add-button.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { Component, inject, input } from '@angular/core'; import { Policy } from '../../shared/models/policy'; import { PolicyItemEditComponent } from '../policy-item-edit/policy-item-edit.component'; import { MatDialog } from '@angular/material/dialog'; @@ -17,28 +17,21 @@ import { Group } from '../../shared/models/group'; }) export class PolicyAddButtonComponent { private readonly dialog = inject(MatDialog); - @Input({ required: true }) policies: Policy[] = []; - @Input({ required: true }) groups: Group[] = []; - @Input() group: string | undefined = undefined; - @Output() policy = new EventEmitter(); + + policies = input.required(); + groups = input.required(); + group = input(); openDialog(): void { - const dialogRef = this.dialog.open(PolicyItemEditComponent, { + this.dialog.open(PolicyItemEditComponent, { data: { - policies: this.policies, - groups: this.groups, - group_id: this.group, - groupDisabled: !!this.group, + policies: this.policies(), + groups: this.groups(), + group_id: this.group(), + groupDisabled: !!this.group(), isNew: true, } }); - - dialogRef.afterClosed().subscribe((result: Policy) => { - if (!result) - return; - - this.policy.emit(result); - }); } } \ No newline at end of file diff --git a/src/app/policies/policy-dropdown/policy-dropdown.component.html b/src/app/policies/policy-dropdown/policy-dropdown.component.html index 45cdf56..7fdca45 100644 --- a/src/app/policies/policy-dropdown/policy-dropdown.component.html +++ b/src/app/policies/policy-dropdown/policy-dropdown.component.html @@ -7,8 +7,11 @@ [formControl]="policyControl" [matAutocomplete]="auto" /> - @for (option of filteredPolicies | async; track option) { - {{option}} + @for (option of filteredPolicies | async; track option.path) { + +

{{option.path}}

+

{{option.description}}

+
}
@if (policyControl.invalid && (policyControl.dirty || policyControl.touched)) { diff --git a/src/app/policies/policy-dropdown/policy-dropdown.component.scss b/src/app/policies/policy-dropdown/policy-dropdown.component.scss index e69de29..982878b 100644 --- a/src/app/policies/policy-dropdown/policy-dropdown.component.scss +++ b/src/app/policies/policy-dropdown/policy-dropdown.component.scss @@ -0,0 +1,12 @@ +p { + margin: 0; + padding: 0; +} + +.description { + font-size: smaller; +} + +.muted { + color: #999999 +} \ No newline at end of file diff --git a/src/app/policies/policy-dropdown/policy-dropdown.component.ts b/src/app/policies/policy-dropdown/policy-dropdown.component.ts index 318e737..63852fe 100644 --- a/src/app/policies/policy-dropdown/policy-dropdown.component.ts +++ b/src/app/policies/policy-dropdown/policy-dropdown.component.ts @@ -4,9 +4,14 @@ import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angu import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatInputModule } from '@angular/material/input'; -import { map, Observable, startWith } from 'rxjs'; +import { EMPTY, map, Observable, startWith } from 'rxjs'; -const Policies = [ +interface PolicyData { + path: string; + description: string; +} + +const Policies: PolicyData[] = [ { path: "tts", description: "Anything to do with TTS" }, { path: "tts.chat", description: "Anything to do with chat" }, { path: "tts.chat.bits.read", description: "To read chat messages with bits via TTS" }, @@ -43,14 +48,7 @@ const Policies = [ export class PolicyDropdownComponent { @Input() policy: string | null = ''; @Input({ alias: 'control' }) policyControl = new FormControl('', [Validators.required]); - filteredPolicies: Observable; - - constructor() { - this.filteredPolicies = this.policyControl.valueChanges.pipe( - startWith(''), - map(value => this._filter(value || '')), - ); - } + filteredPolicies: Observable = EMPTY; ngOnInit() { this.policyControl.setValue(this.policy); @@ -60,13 +58,12 @@ export class PolicyDropdownComponent { ); } - private _filter(value: string): string[] { + private _filter(value: string): PolicyData[] { const filterValue = value.toLowerCase(); - const names = Policies.map(p => p.path); - if (names.includes(filterValue)) { - return names; + if (Policies.map(p => p.path).includes(filterValue)) { + return Policies; } - return names.filter(option => option.toLowerCase().includes(filterValue)); + return Policies.filter(option => option.path.toLowerCase().includes(filterValue)); } } diff --git a/src/app/policies/policy-table/policy-table.component.html b/src/app/policies/policy-table/policy-table.component.html index 06239a3..e55121a 100644 --- a/src/app/policies/policy-table/policy-table.component.html +++ b/src/app/policies/policy-table/policy-table.component.html @@ -1,5 +1,5 @@
(); + groups = input.required(); + @ViewChild(MatTable) table: MatTable; readonly displayedColumns = ['path', 'group', 'usage', 'span', 'actions']; private readonly _subscriptions: any[] = []; - groups: Group[] = []; - constructor() { this.table = {} as MatTable; } ngOnInit(): void { - this.route.data.subscribe(r => { - this.groups = [...r['groups']]; - }); - - this._subscriptions.push(this.events.listen('addPolicy', (payload) => { - if (!payload || this.policies.map(p => p.path).includes(payload)) - return; - - this.policies.push(payload); - this.table.renderRows(); - })); - - this._subscriptions.push(this.hermes.subscribeToRequests('create_policy', response => { - const policy = this.policies.find(p => p.path == response.data.path); - if (policy == null) { - this.policies.push(response.data); - } - this.table.renderRows(); - })); - - this._subscriptions.push(this.hermes.subscribeToRequests('update_policy', response => { - const policy = this.policies.find(p => p.id == response.data.id); - if (policy != null) { - policy.id = response.data.id; - policy.group_id = response.data.group_id; - } - this.table.renderRows(); - })); - - this._subscriptions.push(this.hermes.subscribeToRequests('delete_policy', response => { - this.policies = this.policies.filter(p => p.id != response.request.data.id); - this.table.renderRows(); - })); - } - - ngAfterViewInit(): void { - this.table.renderRows(); + this._subscriptions.push(this.policyService.create$?.subscribe(_ => this.table.renderRows())); + this._subscriptions.push(this.policyService.update$?.subscribe(_ => this.table.renderRows())); + this._subscriptions.push(this.policyService.delete$?.subscribe(_ => this.table.renderRows())); } ngOnDestroy(): void { @@ -81,33 +50,23 @@ export class PolicyTableComponent implements OnInit, OnDestroy, AfterViewInit { } delete(policy: Policy) { - this.hermes.deletePolicy(policy.id); + this.client.deletePolicy(policy.id); } edit(policy: Policy) { - const dialogRef = this.dialog.open(PolicyItemEditComponent, { + this.dialog.open(PolicyItemEditComponent, { data: { - policies: this.policies, - groups: this.groups, + policies: this.policies(), + groups: this.groups(), policy_id: policy.id, group_id: policy.group_id, groupDisabled: true, isNew: false, } }); - - dialogRef.afterClosed().subscribe((result: Policy) => { - if (!result) - return; - - policy.group_id = result.group_id; - policy.path = result.path; - policy.usage = result.usage; - policy.span = result.span; - }); } getGroupById(group_id: string) { - return this.groups.find((g: Group) => g.id == group_id); + return this.groups().find((g: Group) => g.id == group_id); } } \ No newline at end of file diff --git a/src/app/policies/policy/policy.component.html b/src/app/policies/policy/policy.component.html index c3b61cf..fa9783c 100644 --- a/src/app/policies/policy/policy.component.html +++ b/src/app/policies/policy/policy.component.html @@ -1,10 +1,10 @@

Policies

+ [groups]="groups" />
- +
\ No newline at end of file diff --git a/src/app/policies/policy/policy.component.ts b/src/app/policies/policy/policy.component.ts index 1279010..db77674 100644 --- a/src/app/policies/policy/policy.component.ts +++ b/src/app/policies/policy/policy.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, OnDestroy } from '@angular/core'; import { PolicyTableComponent } from "../policy-table/policy-table.component"; import { Policy } from '../../shared/models/policy'; import { ActivatedRoute, RouterModule } from '@angular/router'; @@ -6,43 +6,55 @@ import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { PolicyAddButtonComponent } from "../policy-add-button/policy-add-button.component"; import { Group } from '../../shared/models/group'; +import PolicyService from '../../shared/services/policy.service'; +import GroupService from '../../shared/services/group.service'; @Component({ selector: 'policy', - imports: [MatButtonModule, MatIconModule, PolicyTableComponent, RouterModule, PolicyAddButtonComponent], + imports: [ + MatButtonModule, + MatIconModule, + PolicyTableComponent, + RouterModule, + PolicyAddButtonComponent, + ], templateUrl: './policy.component.html', styleUrl: './policy.component.scss' }) -export class PolicyComponent { +export class PolicyComponent implements OnDestroy { private readonly route = inject(ActivatedRoute); + + private readonly policyService = inject(PolicyService); + private readonly groupService = inject(GroupService); + + private readonly _subscriptions: any[] = []; private _policies: Policy[] = []; - groups: Group[] = []; + private _groups: Group[] = []; constructor() { this.route.data.subscribe((data) => { - const policies = [...data['policies']]; - policies.sort(this.compare); - this._policies = policies; - - this.groups = [...data['groups']]; + this._policies = data['policies']; + this._groups = data['groups']; }); + + this._subscriptions.push(this.policyService.delete$?.subscribe(_ => + this.policyService.fetch().subscribe(p => this._policies = p))); + + this._subscriptions.push(this.groupService.deleteGroup$?.subscribe(_ => + this.groupService.fetch().subscribe(g => this._groups = g.groups))); + } + + ngOnDestroy(): void { + this._subscriptions.filter(s => !!s).forEach(s => s.unsubscribe()); } get policies() { return this._policies; } - addPolicy(policy: Policy) { - let index = -1; - for (let i = 0; i < this._policies.length; i++) { - const comp = this.compare(policy, this._policies[i]); - if (comp < 0) { - index = i; - break; - } - } - this._policies.splice(index >= 0 ? index : this._policies.length, 0, policy); + get groups() { + return this._groups; } compare(a: Policy, b: Policy) {