78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
// Dialog slice: create-schedule dialog state + cron preview.
|
|
// Pure setters + small mutations that read/write only dialog-owned fields.
|
|
|
|
import type { CronPreview } from "../../../services/api";
|
|
import type { StateCreator } from "zustand";
|
|
|
|
import { handleError, notify, requireApi } from "./helpers";
|
|
import type { SchedulesStore } from "./useSchedulesStore";
|
|
|
|
// ---- State ----
|
|
|
|
export type DialogSliceState = {
|
|
createDialogOpen: boolean;
|
|
newScheduleName: string;
|
|
cronResult: CronPreview | null;
|
|
};
|
|
|
|
// ---- Actions ----
|
|
|
|
export type DialogSliceActions = {
|
|
// pure setters
|
|
setCreateDialogOpen: (open: boolean) => void;
|
|
setNewScheduleName: (name: string) => void;
|
|
setCronResult: (result: CronPreview | null) => void;
|
|
|
|
// mutations
|
|
openCreateDialog: () => void;
|
|
runCronPreview: () => Promise<void>;
|
|
};
|
|
|
|
// `SchedulesStore` is the combined state+actions of all slices, so `get()`
|
|
// returns a fully typed snapshot — no `any` propagation.
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export const createDialogSlice: StateCreator<SchedulesStore, [], [], DialogSliceState & DialogSliceActions> = (set, get) => ({
|
|
// ---- initial state ----
|
|
createDialogOpen: false,
|
|
newScheduleName: "",
|
|
cronResult: null,
|
|
|
|
// ---- pure setters ----
|
|
|
|
setCreateDialogOpen: (open) => set({ createDialogOpen: open }),
|
|
setNewScheduleName: (name) => set({ newScheduleName: name }),
|
|
setCronResult: (result) => set({ cronResult: result }),
|
|
|
|
// ---- mutations ----
|
|
|
|
openCreateDialog: () => {
|
|
if (get().busy) return;
|
|
set((s: any) => ({
|
|
contextMenu: null,
|
|
newScheduleName: `新建调度 ${s.schedules.length + 1}`,
|
|
createDialogOpen: true,
|
|
}));
|
|
},
|
|
|
|
runCronPreview: async () => {
|
|
const api = requireApi();
|
|
const { scheduleForm } = get();
|
|
if (scheduleForm.triggerType !== "cron") return;
|
|
if (get().busy) return;
|
|
set({ busy: "cron-preview" });
|
|
try {
|
|
const result = await api.previewCron({
|
|
cron_expression: scheduleForm.cronExpression.trim(),
|
|
timezone: scheduleForm.timezone.trim(),
|
|
count: 5,
|
|
});
|
|
set({ cronResult: result });
|
|
notify({ tone: "success", message: "Cron 表达式校验通过" });
|
|
} catch (error) {
|
|
set({ cronResult: null });
|
|
await handleError(get, error, "Cron 预览失败");
|
|
} finally {
|
|
set({ busy: null });
|
|
}
|
|
},
|
|
}); |