import { type ChangeEvent, type MouseEvent as ReactMouseEvent, type RefObject } from "react"; import Icon from "../common/Icon"; import { WorkspaceTreeGroup } from "../../features/platform/WorkspaceTree"; import type { ScriptItem, WorkspaceDirectory } from "../../services/api"; import type { AuthUser } from "../../context/AuthContext"; type ScriptExplorerProps = { scripts: ScriptItem[]; filteredScripts: ScriptItem[]; directories: WorkspaceDirectory[]; user: AuthUser | null; selectedId: string | null; loading: boolean; refreshing: boolean; uploading: boolean; keyword: string; onKeywordChange: (keyword: string) => void; onRefresh: () => void; onUpload: () => void; onOpenCreateDialog: (parentPath?: string, scriptType?: "notebook" | "python") => void; onOpenFolderDialog: (parentPath?: string) => void; onChooseUpload: (parentPath?: string) => void; onContextMenu: ( event: ReactMouseEvent, target: { kind: "root" | "directory" | "file"; path: string; script?: ScriptItem } ) => void; onSelect: (scriptId: string) => void; uploadInputRef: RefObject; onHandleUpload: (event: ChangeEvent) => void; }; export function ScriptExplorer({ scripts, filteredScripts, directories, user, selectedId, loading, refreshing, uploading, keyword, onKeywordChange, onRefresh, onUpload, onOpenCreateDialog, onOpenFolderDialog, onChooseUpload, onContextMenu, onSelect, uploadInputRef, onHandleUpload, }: ScriptExplorerProps) { const memberScriptGroups = (() => { const currentUserScripts = filteredScripts.filter( (item) => item.owner_user_id === user?.user_id, ); const inferred = inferredDirectories(currentUserScripts); return [{ user: user, scripts: currentUserScripts, directories: mergeDirectories(directories, inferred), }]; })(); return ( ); } function parentOf(path: string) { const parts = path.split("/"); parts.pop(); return parts.join("/"); } function ownedScriptPath(item: ScriptItem) { return item.relative_path.replaceAll("\\", "/").split("/").slice(2).join("/"); } function inferredDirectories(items: ScriptItem[]): WorkspaceDirectory[] { const result = new Map(); for (const item of items) { const parts = parentOf(ownedScriptPath(item)).split("/").filter(Boolean); let parentPath = ""; for (const name of parts) { const path = parentPath ? `${parentPath}/${name}` : name; result.set(path, { path, name, parent_path: parentPath }); parentPath = path; } } return [...result.values()]; } function mergeDirectories( left: WorkspaceDirectory[], right: WorkspaceDirectory[], ): WorkspaceDirectory[] { return [...new Map( [...left, ...right].map((item) => [item.path, item]), ).values()]; }