refactor: extract components
This commit is contained in:
@@ -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)}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user