import { create } from "zustand"; import type { ScriptItem, ScriptType, StableVersion, Visibility, } from "../../../services/api"; export type NewScriptForm = { name: string; scriptType: ScriptType; visibility: Visibility; parentPath: string; }; export type ContextMenuState = { x: number; y: number; kind: "root" | "directory" | "file"; path: string; script?: ScriptItem; }; export type FolderDialogState = { open: boolean; parentPath: string; name: string; busy: boolean; }; export type DataResourceDialogState = { open: boolean; file: File | null; parentPath: string; resourceName: string; visibility: Visibility; description: string; uploading: boolean; targetPath: string; }; export type PublishDialogState = { target: ScriptItem | null; releaseNote: string; visibility: Visibility; publishing: boolean; publishedVersion: StableVersion | null; }; export type UploadState = { parentPath: string; uploading: boolean; }; export const initialCreateForm: NewScriptForm = { name: "", scriptType: "notebook", visibility: "workspace", parentPath: "", }; type UiState = { createDialog: { open: boolean; creating: boolean; form: NewScriptForm; }; folderDialog: FolderDialogState; contextMenu: ContextMenuState | null; workspaceMenuOpen: boolean; upload: UploadState; publish: PublishDialogState; dataResourceDialog: DataResourceDialogState; // create dialog openCreateDialog: (parentPath?: string, scriptType?: ScriptType) => void; closeCreateDialog: () => void; setCreateForm: (form: NewScriptForm) => void; setCreating: (creating: boolean) => void; // folder dialog openFolderDialog: (parentPath?: string) => void; closeFolderDialog: () => void; setFolderName: (name: string) => void; setFolderBusy: (busy: boolean) => void; // context menu showContextMenu: ( event: { clientX: number; clientY: number; preventDefault: () => void; stopPropagation: () => void }, target: Omit, ) => void; closeContextMenu: () => void; // workspace menu (topbar) setWorkspaceMenuOpen: (open: boolean) => void; // upload chooseUpload: (parentPath?: string) => void; setUploading: (uploading: boolean) => void; setUploadParentPath: (parentPath: string) => void; // publish dialog openPublishDialog: (script: ScriptItem) => void; closePublishDialog: () => void; setReleaseNote: (note: string) => void; setPublishVisibility: (visibility: Visibility) => void; setPublishing: (publishing: boolean) => void; setPublishedVersion: (version: StableVersion) => void; clearPublishedVersion: () => void; // data resource dialog openDataResourceDialog: (file: File, parentPath?: string) => void; closeDataResourceDialog: () => void; setDataResourceName: (name: string) => void; setDataResourceVisibility: (visibility: Visibility) => void; setDataResourceDescription: (description: string) => void; setDataResourceTargetPath: (path: string) => void; setDataResourceUploading: (uploading: boolean) => void; }; export const useUiStore = create((set) => ({ createDialog: { open: false, creating: false, form: initialCreateForm, }, folderDialog: { open: false, parentPath: "", name: "", busy: false, }, contextMenu: null, workspaceMenuOpen: false, upload: { parentPath: "", uploading: false, }, publish: { target: null, releaseNote: "", visibility: "workspace", publishing: false, publishedVersion: null, }, dataResourceDialog: { open: false, file: null, parentPath: "", resourceName: "", visibility: "workspace", description: "", uploading: false, targetPath: "", }, openCreateDialog: (parentPath = "", scriptType = "notebook") => set((state) => ({ contextMenu: null, createDialog: { open: true, creating: false, form: { ...initialCreateForm, parentPath, scriptType }, }, })), closeCreateDialog: () => set((state) => ({ createDialog: { ...state.createDialog, open: false }, })), setCreateForm: (form) => set((state) => ({ createDialog: { ...state.createDialog, form } })), setCreating: (creating) => set((state) => ({ createDialog: { ...state.createDialog, creating } })), openFolderDialog: (parentPath = "") => set((state) => ({ contextMenu: null, folderDialog: { open: true, parentPath, name: "", busy: false, }, })), closeFolderDialog: () => set((state) => ({ folderDialog: { ...state.folderDialog, open: false }, })), setFolderName: (name) => set((state) => ({ folderDialog: { ...state.folderDialog, name } })), setFolderBusy: (busy) => set((state) => ({ folderDialog: { ...state.folderDialog, busy } })), showContextMenu: (event, target) => { event.preventDefault(); event.stopPropagation(); const width = 188; const height = target.kind === "file" ? 92 : 190; set({ contextMenu: { ...target, x: Math.min(event.clientX, window.innerWidth - width - 8), y: Math.min(event.clientY, window.innerHeight - height - 8), }, }); }, closeContextMenu: () => set({ contextMenu: null }), setWorkspaceMenuOpen: (open) => set({ workspaceMenuOpen: open }), chooseUpload: (parentPath = "") => set((state) => ({ contextMenu: null, upload: { ...state.upload, parentPath }, })), setUploading: (uploading) => set((state) => ({ upload: { ...state.upload, uploading } })), setUploadParentPath: (parentPath) => set((state) => ({ upload: { ...state.upload, parentPath } })), openPublishDialog: (script) => set((state) => ({ publish: { ...state.publish, target: script, releaseNote: "", visibility: script.visibility === "private" ? "private" : "workspace", }, })), closePublishDialog: () => set((state) => ({ publish: { ...state.publish, target: null } })), setReleaseNote: (note) => set((state) => ({ publish: { ...state.publish, releaseNote: note } })), setPublishVisibility: (visibility) => set((state) => ({ publish: { ...state.publish, visibility } })), setPublishing: (publishing) => set((state) => ({ publish: { ...state.publish, publishing } })), setPublishedVersion: (version) => set((state) => ({ publish: { ...state.publish, target: null, publishedVersion: version, }, })), clearPublishedVersion: () => set((state) => ({ publish: { ...state.publish, publishedVersion: null } })), openDataResourceDialog: (file, parentPath = "") => set((state) => ({ contextMenu: null, dataResourceDialog: { open: true, file, parentPath, resourceName: file.name.replace(/\.[^/.]+$/, ""), visibility: "workspace", description: "", uploading: false, // 右键"在此处上传"时,把父目录预填进子目录输入框 targetPath: parentPath, }, })), closeDataResourceDialog: () => set((state) => ({ dataResourceDialog: { ...state.dataResourceDialog, open: false, uploading: false }, })), setDataResourceName: (name) => set((state) => ({ dataResourceDialog: { ...state.dataResourceDialog, resourceName: name } })), setDataResourceVisibility: (visibility) => set((state) => ({ dataResourceDialog: { ...state.dataResourceDialog, visibility } })), setDataResourceDescription: (description) => set((state) => ({ dataResourceDialog: { ...state.dataResourceDialog, description } })), setDataResourceTargetPath: (path) => set((state) => ({ dataResourceDialog: { ...state.dataResourceDialog, targetPath: path } })), setDataResourceUploading: (uploading) => set((state) => ({ dataResourceDialog: { ...state.dataResourceDialog, uploading } })), }));