Tidy up editor, file tree, get list field working, allow creating new items
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
import { FlatTreeControl } from '@angular/cdk/tree';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, computed, input, output } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
computed,
|
||||
output,
|
||||
signal,
|
||||
} from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import {
|
||||
@@ -8,6 +15,10 @@ import {
|
||||
MatTreeFlattener,
|
||||
MatTreeModule,
|
||||
} from '@angular/material/tree';
|
||||
import { message, open } from '@tauri-apps/api/dialog';
|
||||
import { UnlistenFn, listen } from '@tauri-apps/api/event';
|
||||
import { FileEntry, readDir } from '@tauri-apps/api/fs';
|
||||
import { OpenFolderMessage } from '../messages/openfolder.message';
|
||||
|
||||
export interface FileOrFolder {
|
||||
isDirectory: boolean;
|
||||
@@ -29,12 +40,10 @@ interface FileNode {
|
||||
templateUrl: './file-tree.component.html',
|
||||
styleUrl: './file-tree.component.scss',
|
||||
})
|
||||
export class FileTreeComponent {
|
||||
workspaceName = input<string | null>();
|
||||
files = input<FileOrFolder[]>([]);
|
||||
|
||||
export class FileTreeComponent implements OnInit, OnDestroy {
|
||||
fileSelected = output<FileOrFolder>();
|
||||
|
||||
// File tree
|
||||
protected hasChild = (_: number, node: FileNode) => node.expandable;
|
||||
|
||||
private _transformer = (node: FileOrFolder, level: number) => ({
|
||||
@@ -64,4 +73,71 @@ export class FileTreeComponent {
|
||||
dataSource.data = this.files();
|
||||
return dataSource;
|
||||
});
|
||||
|
||||
// Folder selection
|
||||
protected selectedDirectory = signal<string | null>(null);
|
||||
protected files = signal<FileOrFolder[]>([]);
|
||||
protected workspaceName = computed(() => {
|
||||
const directory = this.selectedDirectory();
|
||||
if (directory) {
|
||||
const directorySplit = directory.split('/');
|
||||
return directorySplit[directorySplit.length - 1];
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
private unlisten?: UnlistenFn;
|
||||
|
||||
async ngOnInit() {
|
||||
this.unlisten = await listen(
|
||||
'openfolder',
|
||||
async (event: OpenFolderMessage) => {
|
||||
await this.selectDirectory();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async ngOnDestroy() {
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
}
|
||||
}
|
||||
|
||||
async selectDirectory() {
|
||||
const selectedDirectory = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
});
|
||||
if (Array.isArray(selectedDirectory)) {
|
||||
message('Only a single folder can be selected at a time');
|
||||
return;
|
||||
} else {
|
||||
this.selectedDirectory.set(selectedDirectory);
|
||||
}
|
||||
if (selectedDirectory) {
|
||||
const entries = await readDir(selectedDirectory, {
|
||||
recursive: true,
|
||||
});
|
||||
const splitNumbers = /(\d)+|(\D)+/;
|
||||
this.files.set(
|
||||
entries
|
||||
.sort(this.sortFiles(splitNumbers))
|
||||
.map((entry) => this.mapEntry(entry, splitNumbers))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private mapEntry(entry: FileEntry, splitNumbers: RegExp): FileOrFolder {
|
||||
return {
|
||||
isDirectory: entry.children != null,
|
||||
name: entry.name || '',
|
||||
children: entry.children
|
||||
?.sort(this.sortFiles(splitNumbers))
|
||||
.map((entry) => this.mapEntry(entry, splitNumbers)),
|
||||
path: entry.path,
|
||||
};
|
||||
}
|
||||
|
||||
private sortFiles = (splitNumbers: RegExp) => (a: FileEntry, b: FileEntry) =>
|
||||
a.name?.localeCompare(b.name ?? '') ?? 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user