P2: file operations with dialogs (mkdir, new file, rename, delete, chmod)

- prompt/confirm/chmod dialogs (signals-driven via DialogsService)
- FileActionsService: acts on selection or cursor row of the active panel
- function bar + F2/F7/F8/Delete keys; delete confirms and recurses
- verified provider ops + walkTree + removeRecursive on a scratch tree

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jokin
2026-07-11 13:38:40 +02:00
co-authored by Claude Fable 5
parent a150c5ee2e
commit b907e0a4ce
10 changed files with 519 additions and 2 deletions
+14 -1
View File
@@ -10,6 +10,7 @@ import {
} from '@angular/core';
import { NgIcon } from '@ng-icons/core';
import type { FileEntry } from '@shared/types';
import { FileActionsService } from '../file-actions.service';
import { formatDate, formatSize } from '../format';
import { PanelsService, type Side, type SortKey } from '../panels.service';
@@ -23,6 +24,7 @@ export class FilePanel {
readonly side = input.required<Side>();
readonly panels = inject(PanelsService);
readonly actions = inject(FileActionsService);
readonly panel = computed(() => this.panels.get(this.side()));
readonly isActive = computed(() => this.panels.activeSide() === this.side());
@@ -37,8 +39,9 @@ export class FilePanel {
constructor() {
// keep the editable path bar in sync with the actual cwd
effect(() => this.pathDraft.set(this.panel().cwd()));
// focus follows the active side (Tab switches panels)
// focus follows the active side (Tab switches panels, dialogs refocus on close)
effect(() => {
this.panels.focusTick();
if (this.isActive()) this.listEl().nativeElement.focus();
});
}
@@ -138,6 +141,16 @@ export class FilePanel {
case 'Backspace':
panel.up();
break;
case 'F2':
this.actions.rename();
break;
case 'F7':
this.actions.mkdir();
break;
case 'F8':
case 'Delete':
this.actions.delete();
break;
default:
return; // let unhandled keys through
}