import { Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { MatTable, MatTableModule } from '@angular/material/table'; import { MatIconModule } from '@angular/material/icon'; import EventService from '../shared/services/EventService'; import { Policy } from '../shared/models/policy'; import { Subscription } from 'rxjs'; import { FormsModule } from '@angular/forms'; import { HermesClientService } from '../hermes-client.service'; @Component({ selector: 'policy-table', standalone: true, imports: [FormsModule, MatTableModule, MatIconModule], templateUrl: './policy-table.component.html', styleUrl: './policy-table.component.scss' }) export class PolicyTableComponent implements OnInit, OnDestroy { @Input() policies: Policy[] = [] displayedColumns = ['path', 'group', 'usage', 'span', 'actions'] groups: { [id: string]: { id: string, name: string, priority: number } } @ViewChild(MatTable) table: MatTable; private subscription: Subscription | undefined; constructor(private events: EventService, private hermes: HermesClientService) { this.table = {} as MatTable; this.groups = {}; } ngOnInit(): void { this.subscription = this.events.listen('addPolicy', (payload) => { if (!payload) return; if (this.policies.map(p => p.path).includes(payload)) { return; } this.policies.push(new Policy("", "", payload, 1, 5000, "", true, true)); this.table.renderRows(); }); this.hermes.subscribe(4, (response: any) => { console.log('request received: ', response); if (response.request.type == "get_policies") { for (let policy of response.data) { this.policies.push(new Policy(policy.id, policy.group_id, policy.path, policy.usage, policy.span, "", false, false)); } this.table.renderRows(); } else if (response.request.type == "create_policy") { console.log("create policy", response); const policy = this.policies.find(p => this.groups[response.data.group_id].name == p.temp_group_name && p.path == response.data.path); if (policy == null) { this.policies.push(new Policy(response.data.id, response.data.group_id, response.data.path, response.data.usage, response.data.span)); } else { policy.id = response.data.id; policy.group_id = response.data.group_id; policy.editing = false; policy.isNew = false; } this.table.renderRows(); } else if (response.request.type == "update_policy") { console.log("update policy", response); const policy = this.policies.find(p => p.id == response.data.id); if (policy == null) { this.policies.push(new Policy(response.data.id, response.data.group_id, response.data.path, response.data.usage, response.data.span)); } else { policy.id = response.data.id; policy.group_id = response.data.group_id; policy.editing = false; policy.isNew = false; } this.table.renderRows(); } else if (response.request.type == "delete_policy") { console.log('delete policy', response.request.data.id); const policy = this.policies.find(p => p.id == response.request.data.id); if (!policy) { console.log('Could not find the policy by id. Already deleted.'); return; } const index = this.policies.indexOf(policy); if (index >= 0) { this.policies.splice(index, 1); this.table.renderRows(); } } else if (response.request.type == "get_permissions") { this.groups = Object.assign({}, ...response.data.groups.map((g: any) => ({ [g.id]: g }))); } }); this.hermes.fetchPolicies(); this.hermes.fetchPermissionsAndGroups(); } ngOnDestroy(): void { if (this.subscription) this.subscription.unsubscribe(); } cancel(policy: Policy) { if (!policy.editing) return; policy.path = policy.old_path ?? ''; policy.usage = policy.old_usage ?? 1; policy.span = policy.old_span ?? 5000; policy.old_path = undefined; policy.old_span = undefined; policy.old_usage = undefined; policy.editing = false; } delete(policy: Policy) { this.hermes.deletePolicy(policy.id); } edit(policy: Policy) { policy.old_path = policy.path; policy.old_span = policy.span; policy.old_usage = policy.usage; policy.temp_group_name = this.groups[policy.group_id].name policy.editing = true; } save(policy: Policy) { if (!policy.temp_group_name) { console.log('group must be valid.'); return; } const group = Object.values(this.groups).find(g => g.name); if (group == null) { console.log('group does not exist.'); return; } if (isNaN(policy.usage)) { console.log('usage must be a whole number.'); return; } if (policy.usage < 1 || policy.usage > 99) { console.error('usage must be between 1 and 99.'); return; } if (policy.usage % 1.0 != 0) { console.error('usage must be a whole number.'); return; } if (isNaN(policy.span)) { console.log('span must be a whole number.'); return; } if (policy.span < 1000 || policy.span > 1800000) { console.error('span must be between 1 and 1800000.'); return; } if (policy.span % 1.0 != 0) { console.error('span must be a whole number.'); return; } let group_id = policy?.group_id; for (let groupId in this.groups) { if (this.groups[groupId].name == policy?.temp_group_name) { group_id = groupId; break; } } if (policy?.temp_group_name != this.groups[group_id].name) { console.log('no group found.'); return; } if (policy.isNew) { this.hermes.createPolicy(group.id, policy.path, policy.usage, policy.span); } else { this.hermes.updatePolicy(policy.id, group.id, policy.path, policy.usage, policy.span); } } }