refactor: extract components

This commit is contained in:
tao.chen
2026-08-07 17:38:28 +08:00
parent 873a464629
commit e2615be2e8
4 changed files with 529 additions and 112 deletions
@@ -47,14 +47,17 @@ export type NodePositionDraft = {
position_y: number;
};
export type ScheduleContextMenu = {
x: number;
y: number;
kind: "schedule" | "node" | "edge";
schedule_id: string;
node_id?: string;
edge_id?: string;
};
export type ScheduleContextMenu =
| { x: number; y: number; kind: "schedule-list" }
| { x: number; y: number; kind: "schedule"; schedule: Schedule }
| {
x: number;
y: number;
kind: "artifact";
artifact: ScheduleArtifact;
}
| { x: number; y: number; kind: "node"; node: ScheduleNode }
| { x: number; y: number; kind: "edge"; edge: ScheduleEdge };
export const EMPTY_SCHEDULE_FORM: ScheduleForm = {
scheduleName: "",
@@ -219,11 +222,18 @@ type Actions = {
) => void;
setLoading: (loading: boolean) => void;
setBusy: (busy: string | null) => void;
setRuns: (updater: (current: ScheduleRunSummary[]) => ScheduleRunSummary[]) => void;
setRuns: (
value: ScheduleRunSummary[]
| ((current: ScheduleRunSummary[]) => ScheduleRunSummary[]),
) => void;
setRunsLoading: (loading: boolean) => void;
setPositionDraftCount: (count: number) => void;
setRunDetails: (
updater: (current: Record<string, ScheduleRunDetail>) => Record<string, ScheduleRunDetail>,
) => void;
setOpenLogNodeRunIds: (updater: (current: Set<string>) => Set<string>) => void;
setOpenLogNodeRunIds: (
value: Set<string> | ((current: Set<string>) => Set<string>),
) => void;
setLogStates: (
updater: (current: Record<string, {
loading: boolean;
@@ -289,11 +299,15 @@ type Actions = {
toggleLog: (runId: string, nodeRunId: string) => Promise<void>;
downloadResult: (runId: string, nodeRunId: string) => Promise<void>;
downloadLog: (runId: string, nodeRunId: string) => Promise<void>;
setExpandedRunId: (id: string | null) => void;
setExpandedRunId: (
id: string | null | ((current: string | null) => string | null),
) => void;
// drag helpers
setPositionDraft: (nodeId: string, draft: NodePositionDraft) => void;
getPositionDrafts: () => Map<string, NodePositionDraft>;
clearAllPositionDrafts: () => void;
prunePositionDrafts: (validNodeIds: Set<string>) => void;
};
const initial: State = {
@@ -391,10 +405,10 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
bindApi: bindSchedulesApi,
reset: () => {
clearPositionDrafts();
set({ ...initial, loading: true });
},
// ---- pure setters ----
setSchedule: (value) =>
@@ -422,12 +436,27 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
})),
setLoading: (loading) => set({ loading }),
setBusy: (busy) => set({ busy }),
setRuns: (updater) =>
set((state) => ({ runs: updater(state.runs) })),
setRuns: (value) =>
set((state) => ({
runs:
typeof value === "function"
? (value as (current: ScheduleRunSummary[]) => ScheduleRunSummary[])(
state.runs,
)
: value,
})),
setRunsLoading: (loading) => set({ runsLoading: loading }),
setRunDetails: (updater) =>
set((state) => ({ runDetails: updater(state.runDetails) })),
setOpenLogNodeRunIds: (updater) =>
set((state) => ({ openLogNodeRunIds: updater(state.openLogNodeRunIds) })),
setOpenLogNodeRunIds: (value) =>
set((state) => ({
openLogNodeRunIds:
typeof value === "function"
? (value as (current: Set<string>) => Set<string>)(
state.openLogNodeRunIds,
)
: value,
})),
setLogStates: (updater) =>
set((state) => ({ logStates: updater(state.logStates) })),
setArtifactBusyKey: (key) => set({ artifactBusyKey: key }),
@@ -522,13 +551,14 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
const current = get().schedule;
if (scheduleId === current?.schedule_id || get().busy) return;
set({ busy: "load-schedule" });
clearPositionDrafts();
get().clearAllPositionDrafts();
set({
selectedNodeId: null,
selectedEdgeId: null,
linkSourceId: null,
cronResult: null,
positionDraftCount: 0,
runs: [],
runsLoading: false,
});
try {
set({ schedule: await api.getSchedule(scheduleId) });
@@ -570,8 +600,8 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
createDialogOpen: false,
newScheduleName: "",
}));
clearPositionDrafts();
set({ positionDraftCount: 0, selectedNodeId: null, selectedEdgeId: null });
get().clearAllPositionDrafts();
set({ selectedNodeId: null, selectedEdgeId: null });
notify({ tone: "success", message: "调度方案已创建" });
} catch (error) {
await handleError(error, "创建调度失败");
@@ -594,12 +624,11 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
);
set({ schedules: remaining });
if (get().schedule?.schedule_id === target_.schedule_id) {
clearPositionDrafts();
get().clearAllPositionDrafts();
set({
schedule: null,
selectedNodeId: null,
selectedEdgeId: null,
positionDraftCount: 0,
});
if (remaining[0]) {
const detail = await api.getSchedule(remaining[0].schedule_id);
@@ -714,7 +743,7 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
max_concurrency: maxConcurrency,
failure_policy: scheduleForm.failurePolicy,
});
clearPositionDrafts();
get().clearAllPositionDrafts();
set((s) => ({
schedule: updated,
schedules: s.schedules.map((item) =>
@@ -722,8 +751,8 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
? { ...updated, nodes: [], edges: [] }
: item
),
positionDraftCount: 0,
}));
notify({ tone: "success", message: "调度配置已保存" });
} catch (error) {
const localDraft = applyPositionDrafts(updated);
@@ -994,7 +1023,15 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
set({ expandedRunId: runId });
}
},
setExpandedRunId: (id) => set({ expandedRunId: id }),
setExpandedRunId: (id) =>
set((state) => ({
expandedRunId:
typeof id === "function"
? (id as (current: string | null) => string | null)(
state.expandedRunId,
)
: id,
})),
toggleLog: async (runId, nodeRunId) => {
const api = requireApi();
@@ -1138,7 +1175,18 @@ export const useSchedulesStore = create<State & Actions>((set, get) => {
positionDrafts.set(nodeId, draft);
set({ positionDraftCount: positionDrafts.size });
},
setPositionDraftCount: (count) => set({ positionDraftCount: count }),
getPositionDrafts: () => positionDrafts,
clearAllPositionDrafts: () => {
clearPositionDrafts();
set({ positionDraftCount: 0 });
},
prunePositionDrafts: (validNodeIds) => {
for (const nodeId of [...positionDrafts.keys()]) {
if (!validNodeIds.has(nodeId)) positionDrafts.delete(nodeId);
}
set({ positionDraftCount: positionDrafts.size });
},
};
});
@@ -1157,4 +1205,4 @@ function artifactNodeKey(artifact: ScheduleArtifact, schedule: Schedule): string
if (!existing.has(candidate)) return candidate;
}
return `${base}_${Date.now().toString(36)}`;
}
}