277 lines
7.8 KiB
TypeScript
277 lines
7.8 KiB
TypeScript
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<ContextMenuState, "x" | "y">,
|
|
) => 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<UiState>((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 } })),
|
|
}));
|