diff --git a/web/app/components/workflow-app/index.tsx b/web/app/components/workflow-app/index.tsx index 6a4385f732..4beeed4238 100644 --- a/web/app/components/workflow-app/index.tsx +++ b/web/app/components/workflow-app/index.tsx @@ -50,6 +50,7 @@ import { } from './hooks/use-workflow-init' import { parseAsViewType, WORKFLOW_VIEW_PARAM_KEY } from './search-params' import { createWorkflowSlice } from './store/workflow/workflow-slice' +import { getSandboxMigrationDismissed, setSandboxMigrationDismissed } from './utils/sandbox-migration-storage' const SkillMain = dynamic(() => import('@/app/components/workflow/skill/main'), { ssr: false, @@ -180,6 +181,10 @@ const WorkflowAppWithAdditionalContext = () => { const { setTriggerStatuses } = useTriggerStatusStore() const appDetail = useAppStore(s => s.appDetail) const appId = appDetail?.id + const handleCloseMigrationModal = useCallback(() => { + setSandboxMigrationDismissed(appId) + setShowMigrationModal(false) + }, [appId]) const isWorkflowMode = appDetail?.mode === AppModeEnum.WORKFLOW const { data: triggersResponse } = useAppTriggers(isWorkflowMode ? appId : undefined, { staleTime: 5 * 60 * 1000, // 5 minutes cache @@ -303,8 +308,9 @@ const WorkflowAppWithAdditionalContext = () => { return if (lastCheckedAppIdRef.current !== appId) { lastCheckedAppIdRef.current = appId + const dismissed = getSandboxMigrationDismissed(appId) // eslint-disable-next-line react-hooks-extra/no-direct-set-state-in-use-effect - setShowMigrationModal(!sandboxEnabled) + setShowMigrationModal(!sandboxEnabled && !dismissed) } }, [appId, isDataReady, sandboxEnabled]) const renderGraph = useCallback((headerLeftSlot: ReactNode) => { @@ -362,7 +368,7 @@ const WorkflowAppWithAdditionalContext = () => { setShowMigrationModal(false)} + onClose={handleCloseMigrationModal} title={t('sandboxMigrationModal.title', { ns: 'workflow' })} description={t('sandboxMigrationModal.description', { ns: 'workflow' })} /> diff --git a/web/app/components/workflow-app/utils/sandbox-migration-storage.ts b/web/app/components/workflow-app/utils/sandbox-migration-storage.ts new file mode 100644 index 0000000000..93d32ca55d --- /dev/null +++ b/web/app/components/workflow-app/utils/sandbox-migration-storage.ts @@ -0,0 +1,31 @@ +const SANDBOX_MIGRATION_DISMISSED_KEY = 'workflow:sandbox-migration-dismissed-app-ids' + +export const getSandboxMigrationDismissed = (appId?: string) => { + if (!appId || typeof window === 'undefined') + return false + try { + const raw = window.localStorage.getItem(SANDBOX_MIGRATION_DISMISSED_KEY) + if (!raw) + return false + const parsed = JSON.parse(raw) as unknown + return Array.isArray(parsed) && parsed.includes(appId) + } + catch { + return false + } +} + +export const setSandboxMigrationDismissed = (appId?: string) => { + if (!appId || typeof window === 'undefined') + return + try { + const raw = window.localStorage.getItem(SANDBOX_MIGRATION_DISMISSED_KEY) + const parsed = raw ? JSON.parse(raw) as unknown : [] + const ids = new Set(Array.isArray(parsed) ? (parsed as string[]) : []) + ids.add(appId) + window.localStorage.setItem(SANDBOX_MIGRATION_DISMISSED_KEY, JSON.stringify(Array.from(ids))) + } + catch { + window.localStorage.setItem(SANDBOX_MIGRATION_DISMISSED_KEY, JSON.stringify([appId])) + } +}