0.1.14 上线前更改
This commit is contained in:
@@ -103,6 +103,10 @@ export function inferPasteTargetDocId({
|
||||
const parsed = parseFileTreeRowId(focusedRowId);
|
||||
if (parsed?.kind === "doc") return parsed.docId;
|
||||
if (parsed?.kind === "index") return parsed.docId;
|
||||
if (parsed?.kind === "asset-folder") {
|
||||
const row = rowById.get(focusedRowId);
|
||||
return row?.kind === "asset-folder" ? row.docId : null;
|
||||
}
|
||||
if (parsed?.kind === "asset") {
|
||||
const row = rowById.get(focusedRowId);
|
||||
return row?.kind === "asset" ? row.docId : null;
|
||||
|
||||
@@ -27,7 +27,7 @@ export function computeFileTreeDeleteTargets(args: {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (row.kind === "asset") {
|
||||
if (row.kind === "asset" || row.kind === "asset-folder") {
|
||||
assetCandidates.push(row.asset.id);
|
||||
assetDocIdByAssetId.set(row.asset.id, row.docId);
|
||||
}
|
||||
|
||||
@@ -3,16 +3,20 @@
|
||||
import type { DocumentNode } from "@/lib/documents";
|
||||
import type { MediaAsset } from "@/types/media";
|
||||
import type { FileTreeRow } from "./types";
|
||||
import { makeAssetRowId, makeDocRowId, makeIndexRowId } from "./types";
|
||||
import { makeAssetFolderRowId, makeAssetRowId, makeDocRowId, makeIndexRowId } from "./types";
|
||||
|
||||
export function buildVisibleRows({
|
||||
nodes,
|
||||
expanded,
|
||||
assetsByDoc,
|
||||
assetChildrenByAssetId,
|
||||
expandedAssetFolderIds,
|
||||
}: {
|
||||
nodes: DocumentNode[];
|
||||
expanded: Set<string>;
|
||||
assetsByDoc: Record<string, MediaAsset[]>;
|
||||
assetChildrenByAssetId?: Record<string, MediaAsset[]>;
|
||||
expandedAssetFolderIds?: Set<string>;
|
||||
}): FileTreeRow[] {
|
||||
const rows: FileTreeRow[] = [];
|
||||
|
||||
@@ -43,6 +47,35 @@ export function buildVisibleRows({
|
||||
});
|
||||
|
||||
assets.forEach((asset) => {
|
||||
if (asset.asset_type === "mindmap") {
|
||||
const children = assetChildrenByAssetId?.[asset.id] ?? [];
|
||||
const hasChildren = children.length > 0;
|
||||
const isExpanded = expandedAssetFolderIds?.has(asset.id) ?? false;
|
||||
rows.push({
|
||||
kind: "asset-folder",
|
||||
rowId: makeAssetFolderRowId(asset.id),
|
||||
depth: depth + 1,
|
||||
docId: node.id,
|
||||
parentDocId: node.id,
|
||||
asset,
|
||||
hasChildren,
|
||||
isExpanded,
|
||||
});
|
||||
if (hasChildren && isExpanded) {
|
||||
children.forEach((child) => {
|
||||
rows.push({
|
||||
kind: "asset",
|
||||
rowId: makeAssetRowId(child.id),
|
||||
depth: depth + 2,
|
||||
docId: node.id,
|
||||
parentDocId: node.id,
|
||||
asset: child,
|
||||
});
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rows.push({
|
||||
kind: "asset",
|
||||
rowId: makeAssetRowId(asset.id),
|
||||
@@ -59,4 +92,3 @@ export function buildVisibleRows({
|
||||
nodes.forEach((node) => walk(node, 0));
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,19 @@
|
||||
import type { DocumentNode } from "@/lib/documents";
|
||||
import type { MediaAsset } from "@/types/media";
|
||||
|
||||
export type FileTreeRowKind = "doc" | "index" | "asset";
|
||||
export type FileTreeRowKind = "doc" | "index" | "asset" | "asset-folder";
|
||||
|
||||
export type FileTreeRowId = `doc:${string}` | `index:${string}` | `asset:${string}`;
|
||||
export type FileTreeRowId =
|
||||
| `doc:${string}`
|
||||
| `index:${string}`
|
||||
| `asset:${string}`
|
||||
| `asset-folder:${string}`;
|
||||
|
||||
export type ParsedFileTreeRowId =
|
||||
| { kind: "doc"; docId: string }
|
||||
| { kind: "index"; docId: string }
|
||||
| { kind: "asset"; assetId: string };
|
||||
| { kind: "asset"; assetId: string }
|
||||
| { kind: "asset-folder"; assetId: string };
|
||||
|
||||
export function makeDocRowId(docId: string): FileTreeRowId {
|
||||
return `doc:${docId}`;
|
||||
@@ -24,6 +29,10 @@ export function makeAssetRowId(assetId: string): FileTreeRowId {
|
||||
return `asset:${assetId}`;
|
||||
}
|
||||
|
||||
export function makeAssetFolderRowId(assetId: string): FileTreeRowId {
|
||||
return `asset-folder:${assetId}`;
|
||||
}
|
||||
|
||||
export function parseFileTreeRowId(rowId: string): ParsedFileTreeRowId | null {
|
||||
const idx = rowId.indexOf(":");
|
||||
if (idx <= 0) return null;
|
||||
@@ -37,6 +46,8 @@ export function parseFileTreeRowId(rowId: string): ParsedFileTreeRowId | null {
|
||||
return { kind: "index", docId: rest };
|
||||
case "asset":
|
||||
return { kind: "asset", assetId: rest };
|
||||
case "asset-folder":
|
||||
return { kind: "asset-folder", assetId: rest };
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -61,6 +72,16 @@ export type FileTreeRow =
|
||||
parentDocId: string;
|
||||
node: DocumentNode;
|
||||
}
|
||||
| {
|
||||
kind: "asset-folder";
|
||||
rowId: FileTreeRowId;
|
||||
depth: number;
|
||||
docId: string;
|
||||
parentDocId: string;
|
||||
asset: MediaAsset;
|
||||
hasChildren: boolean;
|
||||
isExpanded: boolean;
|
||||
}
|
||||
| {
|
||||
kind: "asset";
|
||||
rowId: FileTreeRowId;
|
||||
@@ -76,6 +97,11 @@ export function getFileTreeRowLabel(row: FileTreeRow): string {
|
||||
return row.node.title || "无标题";
|
||||
case "index":
|
||||
return "index.md";
|
||||
case "asset-folder": {
|
||||
const name = row.asset.file_name || "附件";
|
||||
// 思维导图展示为“文件夹”时,去掉 .json 结尾更直观
|
||||
return row.asset.asset_type === "mindmap" ? name.replace(/\.json$/i, "") : name;
|
||||
}
|
||||
case "asset":
|
||||
return row.asset.file_name || "附件";
|
||||
}
|
||||
@@ -86,8 +112,8 @@ export function getOwningDocId(row: FileTreeRow): string {
|
||||
case "doc":
|
||||
case "index":
|
||||
return row.docId;
|
||||
case "asset-folder":
|
||||
case "asset":
|
||||
return row.asset.document_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user