78 lines
3.7 KiB
TypeScript
78 lines
3.7 KiB
TypeScript
|
|
import { invoke } from '@tauri-apps/api/core'
|
||
|
|
import { isTauri } from '../mock-tauri'
|
||
|
|
import type { VaultEntry } from '../types'
|
||
|
|
import type { FrontmatterValue } from '../components/Inspector'
|
||
|
|
import { updateMockFrontmatter, deleteMockFrontmatterProperty } from './mockFrontmatterHelpers'
|
||
|
|
import { updateMockContent, trackMockChange } from '../mock-tauri'
|
||
|
|
|
||
|
|
const ENTRY_DELETE_MAP: Record<string, Partial<VaultEntry>> = {
|
||
|
|
type: { isA: null }, is_a: { isA: null }, status: { status: null }, color: { color: null },
|
||
|
|
icon: { icon: null }, owner: { owner: null }, cadence: { cadence: null },
|
||
|
|
aliases: { aliases: [] }, belongs_to: { belongsTo: [] }, related_to: { relatedTo: [] },
|
||
|
|
archived: { archived: false }, trashed: { trashed: false }, order: { order: null },
|
||
|
|
template: { template: null }, sort: { sort: null }, visible: { visible: null },
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Map a frontmatter key+value to the corresponding VaultEntry field(s). */
|
||
|
|
export function frontmatterToEntryPatch(
|
||
|
|
op: 'update' | 'delete', key: string, value?: FrontmatterValue,
|
||
|
|
): Partial<VaultEntry> {
|
||
|
|
const k = key.toLowerCase().replace(/\s+/g, '_')
|
||
|
|
if (op === 'delete') return ENTRY_DELETE_MAP[k] ?? {}
|
||
|
|
const str = value != null ? String(value) : null
|
||
|
|
const arr = Array.isArray(value) ? value.map(String) : []
|
||
|
|
const updates: Record<string, Partial<VaultEntry>> = {
|
||
|
|
type: { isA: str }, is_a: { isA: str }, status: { status: str }, color: { color: str },
|
||
|
|
icon: { icon: str }, owner: { owner: str }, cadence: { cadence: str },
|
||
|
|
aliases: { aliases: arr }, belongs_to: { belongsTo: arr }, related_to: { relatedTo: arr },
|
||
|
|
archived: { archived: Boolean(value) }, trashed: { trashed: Boolean(value) },
|
||
|
|
order: { order: typeof value === 'number' ? value : null },
|
||
|
|
template: { template: str },
|
||
|
|
sort: { sort: str },
|
||
|
|
view: { view: str },
|
||
|
|
visible: { visible: value === false ? false : null },
|
||
|
|
}
|
||
|
|
return updates[k] ?? {}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function invokeFrontmatter(command: string, args: Record<string, unknown>): Promise<string> {
|
||
|
|
return invoke<string>(command, args)
|
||
|
|
}
|
||
|
|
|
||
|
|
function applyMockFrontmatterUpdate(path: string, key: string, value: FrontmatterValue): string {
|
||
|
|
const content = updateMockFrontmatter(path, key, value)
|
||
|
|
updateMockContent(path, content)
|
||
|
|
trackMockChange(path)
|
||
|
|
return content
|
||
|
|
}
|
||
|
|
|
||
|
|
function applyMockFrontmatterDelete(path: string, key: string): string {
|
||
|
|
const content = deleteMockFrontmatterProperty(path, key)
|
||
|
|
updateMockContent(path, content)
|
||
|
|
trackMockChange(path)
|
||
|
|
return content
|
||
|
|
}
|
||
|
|
|
||
|
|
async function executeFrontmatterOp(op: 'update' | 'delete', path: string, key: string, value?: FrontmatterValue): Promise<string> {
|
||
|
|
if (op === 'update') {
|
||
|
|
return isTauri() ? invokeFrontmatter('update_frontmatter', { path, key, value }) : applyMockFrontmatterUpdate(path, key, value!)
|
||
|
|
}
|
||
|
|
return isTauri() ? invokeFrontmatter('delete_frontmatter_property', { path, key }) : applyMockFrontmatterDelete(path, key)
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Run a frontmatter update/delete and apply the result to state. */
|
||
|
|
export async function runFrontmatterAndApply(
|
||
|
|
op: 'update' | 'delete', path: string, key: string, value: FrontmatterValue | undefined,
|
||
|
|
callbacks: { updateTab: (p: string, c: string) => void; updateEntry: (p: string, patch: Partial<VaultEntry>) => void; toast: (m: string | null) => void },
|
||
|
|
): Promise<void> {
|
||
|
|
try {
|
||
|
|
callbacks.updateTab(path, await executeFrontmatterOp(op, path, key, value))
|
||
|
|
const patch = frontmatterToEntryPatch(op, key, value)
|
||
|
|
if (Object.keys(patch).length > 0) callbacks.updateEntry(path, patch)
|
||
|
|
callbacks.toast(op === 'update' ? 'Property updated' : 'Property deleted')
|
||
|
|
} catch (err) {
|
||
|
|
console.error(`Failed to ${op} frontmatter:`, err)
|
||
|
|
callbacks.toast(`Failed to ${op} property`)
|
||
|
|
}
|
||
|
|
}
|