import { Component, computed, effect, inject } from '@angular/core'; import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component'; import { AlertComponent } from '@shared/ui/alert/alert.component'; import { ButtonComponent } from '@shared/ui/button/button.component'; import { ASYNC } from '@shared/ui/async/async.component'; import { AccessStore } from '@shared/application/access.store'; import { OrgTemplateStore } from '@brief/application/org-template.store'; import { OrgTemplateEditorComponent } from '@brief/ui/org-template-editor/org-template-editor.component'; /** Page: thin container for the admin org-template editor. Deny-by-default capability gate (`orgtemplate:edit`) — a denial alert for non-admins, the editor for admins. Loads once the capability resolves; wires store commands to the organism. */ @Component({ selector: 'app-org-template-page', imports: [ PageShellComponent, AlertComponent, ButtonComponent, ...ASYNC, OrgTemplateEditorComponent, ], styles: [ ` .save { color: var(--rhc-color-foreground-subtle); font-size: 0.9em; } `, ], template: ` @if (store.lastError(); as err) { {{ err }} } @if (!access.ready()) { } @else if (!canEdit()) { {{ deniedText }} } @else { {{ failedText }} {{ retryText }} @if (store.draft(); as draft) { } } `, }) export class OrgTemplatePage { protected store = inject(OrgTemplateStore); protected access = inject(AccessStore); protected canEdit = computed(() => this.access.can('orgtemplate:edit')); protected previewUrlFor = this.store.previewUrlFor; protected heading = $localize`:@@orgTemplate.page.heading:Huisstijl beheren`; protected intro = $localize`:@@orgTemplate.page.intro:Beheer per organisatieonderdeel het uiterlijk van de brief: logo, afzender, ondertekening, voettekst en marges.`; protected deniedText = $localize`:@@orgTemplate.page.denied:U hebt geen rechten om organisatiesjablonen te beheren.`; protected failedText = $localize`:@@orgTemplate.page.failed:Het sjabloon kon niet worden geladen.`; protected retryText = $localize`:@@orgTemplate.page.retry:Opnieuw proberen`; private savingText = $localize`:@@orgTemplate.page.saving:Concept opslaan…`; private savedText = $localize`:@@orgTemplate.page.saved:Concept opgeslagen`; private saveErrorText = $localize`:@@orgTemplate.page.saveError:Opslaan mislukt`; protected saveText = computed(() => { switch (this.store.saveState().tag) { case 'Saving': return this.savingText; case 'Saved': return this.savedText; case 'Error': return this.saveErrorText; default: return ''; } }); private loadRequested = false; constructor() { // Load once the capability resolves to `allowed` (a 403 GET would be wasted // otherwise). Depends only on `canEdit()` + a plain flag — never on the store // model, so dispatching `Loading` inside `load()` can't retrigger this effect. effect(() => { if (this.canEdit() && !this.loadRequested) { this.loadRequested = true; void this.store.load(); } }); } protected reload() { void this.store.load(); } }