import { Component, computed, inject, input, signal } from '@angular/core'; import { I18nService } from '@core/i18n.service'; import { DialogsService, type ChmodRequest } from '@core/dialogs.service'; import { FocusService } from '@core/focus.service'; const ROLES = ['roleOwner', 'roleGroup', 'roleOthers'] as const; const PERMS = ['r', 'w', 'x'] as const; @Component({ selector: 'app-chmod-dialog', template: `

{{ i18n.t('dialogs.chmodTitle') }}

{{ targetLabel() }}

@for (role of roles; track role; let r = $index) { @for (perm of perms; track perm; let p = $index) { } }
{{ i18n.t('dialogs.read') }} {{ i18n.t('dialogs.write') }} {{ i18n.t('dialogs.execute') }}
{{ i18n.t('dialogs.' + role) }}
`, }) export class ChmodDialog { readonly i18n = inject(I18nService); readonly request = input.required(); readonly roles = ROLES; readonly perms = PERMS; private readonly dialogs = inject(DialogsService); private readonly focus = inject(FocusService); // mode is initialized lazily from the request on first read private readonly modeOverride = signal(null); readonly mode = computed(() => this.modeOverride() ?? this.request().initialMode & 0o777); readonly octal = computed(() => this.mode().toString(8).padStart(3, '0')); targetLabel(): string { const targets = this.request().targets; return targets.length === 1 ? targets[0] : this.i18n.t('dialogs.chmodItems', { count: targets.length }); } hasBit(role: number, perm: number): boolean { return !!(this.mode() & (0o400 >> (role * 3 + perm))); } toggleBit(role: number, perm: number): void { this.modeOverride.set(this.mode() ^ (0o400 >> (role * 3 + perm))); } setOctal(text: string): void { if (/^[0-7]{1,4}$/.test(text)) { this.modeOverride.set(parseInt(text, 8) & 0o777); } } submit(): void { const req = this.request(); const mode = this.mode(); this.close(); req.onConfirm(mode); } cancel(): void { this.close(); } private close(): void { this.dialogs.chmod.set(null); this.focus.bump(); } }