refactor: replace Toast with Sonner

This commit is contained in:
tao.chen
2026-08-26 14:06:12 +08:00
parent f99b543100
commit d7f3db1cc4
18 changed files with 126 additions and 320 deletions
@@ -8,7 +8,7 @@ import {
} from "../../../services/api";
import { useScriptWorkspaceStore } from "../../platform/state/scriptWorkspaceStore";
import { useUiStore } from "../../platform/state/uiStore";
import { toast } from "sonner";
type Notice = {
tone: "success" | "error" | "info";
@@ -65,7 +65,9 @@ function requireApi(): WorkspaceBoundApi {
}
function pushToast(notice: Notice) {
useUiStore.getState().pushToast(notice);
if (notice.tone === "error") toast.error(notice.message);
else if (notice.tone === "info") toast.info(notice.message);
else toast.success(notice.message);
}
function setApiOnline(online: boolean) {
@@ -42,7 +42,7 @@ const saveBtnClass =
// 模块级变量存储刷新版本号,用于检测只读内容刷新
let _lastRefreshVersion = 0;
type ToastState = {
type Notice = {
tone: "success" | "error" | "info";
message: string;
};
@@ -71,7 +71,7 @@ type ScriptWorkspaceProps = {
onSwitchTab: (scriptId: string) => void;
onNewTab: () => void;
onPublish: () => void;
onInfo: (toast: ToastState) => void;
onInfo: (toast: Notice) => void;
pythonEditorBuffers: Record<string, PythonEditorBuffer>;
onOpenPythonEditor: () => void;
@@ -13,6 +13,7 @@ import { VersionReceiptModal } from "./VersionReceiptModal";
import { getSessionCache, useScriptWorkspaceStore } from "./state/scriptWorkspaceStore";
import { useUiStore } from "./state/uiStore";
import { toast } from "sonner";
import { ScriptWorkspace } from "./ScriptWorkspace";
import { copyToClipboard } from "../../lib/clipboard";
@@ -68,7 +69,11 @@ export default function ScriptsPage() {
const refreshReadOnlyContent = useScriptWorkspaceStore((s) => s.refreshReadOnlyContent);
// ui store
const pushToast = useUiStore((s) => s.pushToast);
const pushToast = (notice: { tone: "success" | "error" | "info"; message: string }) => {
if (notice.tone === "error") toast.error(notice.message);
else if (notice.tone === "info") toast.info(notice.message);
else toast.success(notice.message);
};
const createDialog = useUiStore((s) => s.createDialog);
const setCreateForm = useUiStore((s) => s.setCreateForm);
const closeCreateDialog = useUiStore((s) => s.closeCreateDialog);
@@ -8,7 +8,7 @@ import type {
WorkspaceBoundApi,
} from "~/services/api";
import { useUiStore } from "./uiStore";
import { toast } from "sonner";
// 缓存的会话类型(多 iframe 共存方案)
type CachedSession = {
@@ -173,7 +173,9 @@ export function pushToast(
tone: "success" | "error" | "info",
message: string,
): void {
useUiStore.getState().pushToast({ tone, message });
if (tone === "error") toast.error(message);
else if (tone === "info") toast.info(message);
else toast.success(message);
}
export async function sha256Hex(
@@ -7,12 +7,6 @@ import type {
Visibility,
} from "../../../services/api";
export type ToastTone = "success" | "error" | "info";
export type ToastState = {
tone: ToastTone;
message: string;
};
export type NewScriptForm = {
name: string;
scriptType: ScriptType;
@@ -66,7 +60,6 @@ export const initialCreateForm: NewScriptForm = {
};
type UiState = {
toast: ToastState | null;
createDialog: {
open: boolean;
creating: boolean;
@@ -79,10 +72,6 @@ type UiState = {
publish: PublishDialogState;
dataResourceDialog: DataResourceDialogState;
// toast
pushToast: (toast: ToastState) => void;
dismissToast: () => void;
// create dialog
openCreateDialog: (parentPath?: string, scriptType?: ScriptType) => void;
closeCreateDialog: () => void;
@@ -129,7 +118,6 @@ type UiState = {
};
export const useUiStore = create<UiState>((set) => ({
toast: null,
createDialog: {
open: false,
creating: false,
@@ -165,9 +153,6 @@ export const useUiStore = create<UiState>((set) => ({
targetPath: "",
},
pushToast: (toast) => set({ toast }),
dismissToast: () => set({ toast: null }),
openCreateDialog: (parentPath = "", scriptType = "notebook") =>
set((state) => ({
contextMenu: null,
@@ -1,10 +1,14 @@
import { useScriptWorkspaceStore } from "../platform/state/scriptWorkspaceStore";
import { useUiStore } from "../platform/state/uiStore";
import { toast } from "sonner";
import SchedulePage from "./SchedulePage";
export default function SchedulesPageRoute() {
const setApiOnline = useScriptWorkspaceStore((s) => s.setApiOnline);
const pushToast = useUiStore((s) => s.pushToast);
const pushToast = (notice: { tone: "success" | "error" | "info"; message: string }) => {
if (notice.tone === "error") toast.error(notice.message);
else if (notice.tone === "info") toast.info(notice.message);
else toast.success(notice.message);
};
return (
<SchedulePage
@@ -3,7 +3,7 @@
import { ApiRequestError, type Schedule, type ScheduleNode, type WorkspaceBoundApi } from "../../../services/api";
import { useScriptWorkspaceStore } from "../../platform/state/scriptWorkspaceStore";
import { useUiStore } from "../../platform/state/uiStore";
import { toast } from "sonner";
import type { NodeForm, NodePositionDraft, Notice, ScheduleForm } from "./types";
import type { SchedulesStore } from "./useSchedulesStore";
@@ -22,7 +22,9 @@ export function requireApi(): WorkspaceBoundApi {
}
export function notify(notice: Notice): void {
useUiStore.getState().pushToast(notice);
if (notice.tone === "error") toast.error(notice.message);
else if (notice.tone === "info") toast.info(notice.message);
else toast.success(notice.message);
}
export function setApiOnline(online: boolean): void {