Configurable list columns via header right-click
Native checkable menu on the column headers toggles Size, Modified, Kind, Rights, Owner and Group (persisted, both panels). Owner/group come from the ls-style SFTP longname remotely and cached uid/gid lookups locally (POSIX; undefined on Windows). All columns sort. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,16 +9,27 @@ import {
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import { NgIcon } from '@ng-icons/core';
|
||||
import type { FileEntry, SavedConnection, SshConfigHost } from '@shared/types';
|
||||
import type { ColumnKey, FileEntry, SavedConnection, SshConfigHost } from '@shared/types';
|
||||
import { ConnectionsService } from '../connections.service';
|
||||
import { DialogsService } from '../dialogs.service';
|
||||
import { FileActionsService } from '../file-actions.service';
|
||||
import { fileGlyph, fileIconClass } from '../file-icons';
|
||||
import { formatDate, formatSize } from '../format';
|
||||
import { fileGlyph, fileIconClass, fileKind } from '../file-icons';
|
||||
import { formatDate, formatMode, formatSize } from '../format';
|
||||
import { PanelsService, type Side, type SortKey } from '../panels.service';
|
||||
import { RpcService } from '../rpc.service';
|
||||
import { SettingsService } from '../settings.service';
|
||||
import { TransfersService } from '../transfers.service';
|
||||
|
||||
/** Optional columns in fixed display order, with their track widths. */
|
||||
const COLUMN_DEFS: { key: ColumnKey; label: string; width: string }[] = [
|
||||
{ key: 'size', label: 'Size', width: '5.5rem' },
|
||||
{ key: 'mtime', label: 'Modified', width: '8.5rem' },
|
||||
{ key: 'kind', label: 'Kind', width: '5.5rem' },
|
||||
{ key: 'rights', label: 'Rights', width: '6.5rem' },
|
||||
{ key: 'owner', label: 'Owner', width: '6rem' },
|
||||
{ key: 'group', label: 'Group', width: '6rem' },
|
||||
];
|
||||
|
||||
@Component({
|
||||
selector: 'app-file-panel',
|
||||
imports: [NgIcon],
|
||||
@@ -34,6 +45,7 @@ export class FilePanel {
|
||||
readonly connections = inject(ConnectionsService);
|
||||
readonly dialogs = inject(DialogsService);
|
||||
private readonly settings = inject(SettingsService);
|
||||
private readonly rpc = inject(RpcService);
|
||||
readonly panel = computed(() => this.panels.get(this.side()));
|
||||
readonly isActive = computed(() => this.panels.activeSide() === this.side());
|
||||
readonly isRemote = computed(() => this.panel().sessionId() !== 'local');
|
||||
@@ -50,6 +62,22 @@ export class FilePanel {
|
||||
|
||||
readonly formatSize = formatSize;
|
||||
readonly formatDate = formatDate;
|
||||
readonly formatMode = formatMode;
|
||||
readonly fileKind = fileKind;
|
||||
|
||||
/** The optional columns currently shown, in canonical order. */
|
||||
readonly visibleColumns = computed(() => {
|
||||
const visible = this.settings.columns();
|
||||
return COLUMN_DEFS.filter((c) => visible.includes(c.key));
|
||||
});
|
||||
readonly gridTemplate = computed(() =>
|
||||
['minmax(0,1fr)', ...this.visibleColumns().map((c) => c.width)].join(' '),
|
||||
);
|
||||
|
||||
headerContextMenu(event: MouseEvent): void {
|
||||
event.preventDefault();
|
||||
void this.rpc.request.showColumnsMenu({ visible: this.settings.columns() });
|
||||
}
|
||||
|
||||
constructor() {
|
||||
// keep the editable path bar in sync with the actual cwd
|
||||
|
||||
Reference in New Issue
Block a user