merging
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
import { reactive, computed } from 'vue'
|
||||
|
||||
export interface FileNode {
|
||||
path: string
|
||||
path: string // composite: "<collectionId>/<relpath>"
|
||||
collection?: string
|
||||
name: string
|
||||
ext: string
|
||||
family: string
|
||||
@@ -22,6 +23,13 @@ export interface FileNode {
|
||||
warnings?: string[]
|
||||
}
|
||||
|
||||
export interface CollectionInfo {
|
||||
id: string
|
||||
name: string
|
||||
available: boolean
|
||||
count: number
|
||||
}
|
||||
|
||||
export interface Detail {
|
||||
node: FileNode
|
||||
content: string | null // extracted search text (heavy formats), markdown
|
||||
@@ -53,7 +61,8 @@ export const TARGETS: Target[] = [
|
||||
]
|
||||
|
||||
interface State {
|
||||
root: string
|
||||
collections: CollectionInfo[]
|
||||
activeCollections: Set<string>
|
||||
files: FileNode[]
|
||||
tree: TreeItem[]
|
||||
counts: Record<string, number>
|
||||
@@ -74,7 +83,8 @@ interface State {
|
||||
}
|
||||
|
||||
export const store = reactive<State>({
|
||||
root: '',
|
||||
collections: [],
|
||||
activeCollections: new Set<string>(),
|
||||
files: [],
|
||||
tree: [],
|
||||
counts: {},
|
||||
@@ -110,7 +120,7 @@ export function runSearch(q: string): void {
|
||||
store.searching = true
|
||||
searchTimer = setTimeout(async () => {
|
||||
try {
|
||||
const res = await fetch(`/api/search?q=${encodeURIComponent(q)}`)
|
||||
const res = await fetch(`/api/search?q=${encodeURIComponent(q)}&collections=${encodeURIComponent(activeCsv())}`)
|
||||
if (!res.ok) return
|
||||
const d = await res.json()
|
||||
if (store.query !== q) return // a newer query superseded this one
|
||||
@@ -163,14 +173,31 @@ function buildTree(files: FileNode[]): TreeItem[] {
|
||||
return sort(root.children!)
|
||||
}
|
||||
|
||||
function activeCsv(): string {
|
||||
return [...store.activeCollections].join(',')
|
||||
}
|
||||
|
||||
/** Load available collections; default every available one to active. */
|
||||
export async function loadCollections(): Promise<void> {
|
||||
try {
|
||||
const res = await fetch('/api/collections')
|
||||
const data = await res.json()
|
||||
store.collections = data.collections ?? []
|
||||
// Default: all available collections on.
|
||||
store.activeCollections = new Set(store.collections.filter((c) => c.available).map((c) => c.id))
|
||||
} catch (e) {
|
||||
store.error = String(e)
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadTree(): Promise<void> {
|
||||
store.loading = true
|
||||
store.error = ''
|
||||
try {
|
||||
const res = await fetch('/api/tree')
|
||||
if (!store.collections.length) await loadCollections()
|
||||
const res = await fetch(`/api/tree?collections=${encodeURIComponent(activeCsv())}`)
|
||||
if (!res.ok) { store.error = (await res.json()).error ?? `HTTP ${res.status}`; return }
|
||||
const index = await res.json()
|
||||
store.root = index.root
|
||||
store.files = index.files
|
||||
store.counts = index.counts
|
||||
store.tree = buildTree(index.files)
|
||||
@@ -181,6 +208,14 @@ export async function loadTree(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Toggle a collection on/off and re-merge the tree (and re-run any search). */
|
||||
export async function toggleCollection(id: string): Promise<void> {
|
||||
if (store.activeCollections.has(id)) store.activeCollections.delete(id)
|
||||
else store.activeCollections.add(id)
|
||||
await loadTree()
|
||||
if (store.query) runSearch(store.query)
|
||||
}
|
||||
|
||||
export async function select(path: string): Promise<void> {
|
||||
store.selectedPath = path
|
||||
store.detailCollapsed = false // opening a file expands the viewer
|
||||
|
||||
Reference in New Issue
Block a user