'use client' import type { TriggerParams } from '@/app/components/base/date-and-time-picker/types' import type { AutoUpdateConfig } from '@/app/components/plugins/reference-setting-modal/auto-update-setting/types' import type { PluginCategoryEnum } from '@/app/components/plugins/types' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' import { Dialog, DialogCloseButton, DialogContent, DialogTitle, DialogTrigger } from '@langgenius/dify-ui/dialog' import { toast } from '@langgenius/dify-ui/toast' import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { convertTimezoneToOffsetStr } from '@/app/components/base/date-and-time-picker/utils/dayjs' import { AUTO_UPDATE_MODE, AUTO_UPDATE_STRATEGY } from '@/app/components/plugins/reference-setting-modal/auto-update-setting/types' import { convertLocalSecondsToUTCDaySeconds, convertUTCDaySecondsToLocalSeconds, dayjsToTimeOfDay, timeOfDayToDayjs } from '@/app/components/plugins/reference-setting-modal/auto-update-setting/utils' import { useAppContext } from '@/context/app-context' import { useMutationPluginAutoUpgradeSettings, usePluginAutoUpgradeSettings } from '@/service/use-plugins' import UpdateSettingDialogForm from './update-setting-dialog-form' type Props = { category: PluginCategoryEnum disabled?: boolean } const UpdateSettingDialog = ({ category, disabled = false, }: Props) => { const { t } = useTranslation() const { userProfile } = useAppContext() const timezone = userProfile.timezone || 'UTC' const { data: autoUpgradeSetting, error, isFetching, isLoading, } = usePluginAutoUpgradeSettings(category) const { mutate: saveAutoUpgrade, isPending: isSavePending } = useMutationPluginAutoUpgradeSettings({ category, onSuccess: () => { toast.success(t('api.actionSuccess', { ns: 'common' })) }, }) const savedAutoUpgrade = autoUpgradeSetting?.auto_upgrade const [isOpen, setIsOpen] = useState(false) const [draftAutoUpgrade, setDraftAutoUpgrade] = useState() const isSettingsLoading = !savedAutoUpgrade && !error && (isLoading || isFetching) const autoUpgrade = draftAutoUpgrade ?? savedAutoUpgrade const hasSettings = !!autoUpgrade const getStrategyLabel = useCallback((strategy: AUTO_UPDATE_STRATEGY) => { switch (strategy) { case AUTO_UPDATE_STRATEGY.disabled: return t('autoUpdate.strategy.disabled.name', { ns: 'plugin' }) case AUTO_UPDATE_STRATEGY.fixOnly: return t('autoUpdate.strategy.fixOnly.name', { ns: 'plugin' }) case AUTO_UPDATE_STRATEGY.latest: return t('autoUpdate.strategy.latest.name', { ns: 'plugin' }) default: return '' } }, [t]) const selectedStrategyLabel = autoUpgrade ? getStrategyLabel(autoUpgrade.strategy_setting) : '' const plugins = useMemo(() => { if (!autoUpgrade) return [] switch (autoUpgrade.upgrade_mode) { case AUTO_UPDATE_MODE.partial: return autoUpgrade.include_plugins case AUTO_UPDATE_MODE.exclude: return autoUpgrade.exclude_plugins default: return [] } }, [autoUpgrade]) const updateTimeValue = useMemo(() => { if (!autoUpgrade) return '' const localSeconds = convertUTCDaySecondsToLocalSeconds(autoUpgrade.upgrade_time_of_day, timezone) return timeOfDayToDayjs(localSeconds).format('HH:mm') }, [autoUpgrade, timezone]) const strategyOptions = useMemo(() => [ { value: AUTO_UPDATE_STRATEGY.disabled, label: getStrategyLabel(AUTO_UPDATE_STRATEGY.disabled), }, { value: AUTO_UPDATE_STRATEGY.fixOnly, label: getStrategyLabel(AUTO_UPDATE_STRATEGY.fixOnly), }, { value: AUTO_UPDATE_STRATEGY.latest, label: getStrategyLabel(AUTO_UPDATE_STRATEGY.latest), }, ], [getStrategyLabel]) const scopeOptions = useMemo(() => [ { value: AUTO_UPDATE_MODE.update_all, label: t('autoUpdate.scopeMode.all', { ns: 'plugin' }), }, { value: AUTO_UPDATE_MODE.exclude, label: t('autoUpdate.scopeMode.exclude', { ns: 'plugin' }), }, { value: AUTO_UPDATE_MODE.partial, label: t('autoUpdate.upgradeMode.partial', { ns: 'plugin' }), }, ], [t]) const updateAutoUpgrade = useCallback((payload: Partial) => { setDraftAutoUpgrade((currentAutoUpgrade) => { const baseAutoUpgrade = currentAutoUpgrade ?? savedAutoUpgrade if (!baseAutoUpgrade) return undefined return { ...baseAutoUpgrade, ...payload, } }) }, [savedAutoUpgrade]) const handlePluginsChange = useCallback((newPlugins: string[]) => { if (!autoUpgrade) return if (autoUpgrade.upgrade_mode === AUTO_UPDATE_MODE.partial) { updateAutoUpgrade({ include_plugins: newPlugins, }) } else if (autoUpgrade.upgrade_mode === AUTO_UPDATE_MODE.exclude) { updateAutoUpgrade({ exclude_plugins: newPlugins, }) } }, [autoUpgrade, updateAutoUpgrade]) const minuteFilter = useCallback((minutes: string[]) => { return minutes.filter((m) => { const time = Number.parseInt(m, 10) return time % 15 === 0 }) }, []) const handleUpdateTimeChange = useCallback((value: Parameters[0]) => { updateAutoUpgrade({ upgrade_time_of_day: convertLocalSecondsToUTCDaySeconds(dayjsToTimeOfDay(value), timezone), }) }, [timezone, updateAutoUpgrade]) const handleOpenChange = useCallback((open: boolean) => { if (disabled) { setIsOpen(false) return } setIsOpen(open) if (open) setDraftAutoUpgrade(savedAutoUpgrade) else setDraftAutoUpgrade(undefined) }, [disabled, savedAutoUpgrade]) const handleCancel = useCallback(() => { setDraftAutoUpgrade(undefined) setIsOpen(false) }, []) const handleSave = useCallback(() => { if (!autoUpgrade) return saveAutoUpgrade(autoUpgrade) setDraftAutoUpgrade(undefined) setIsOpen(false) }, [autoUpgrade, saveAutoUpgrade]) const renderTimePickerTrigger = useCallback(({ inputElem, onClick, isOpen }: TriggerParams) => { return ( ) }, [timezone]) return ( {t('autoUpdate.autoUpdate', { ns: 'plugin' })} {selectedStrategyLabel && ( {selectedStrategyLabel} )} )} /> {!disabled && (
{t('autoUpdate.autoUpdateSettings', { ns: 'plugin' })}
{isSettingsLoading && (
{t('loading', { ns: 'common' })}
)} {!isSettingsLoading && !hasSettings && (
{t('api.actionFailed', { ns: 'common' })}
)} {!isSettingsLoading && hasSettings && autoUpgrade && ( <>
)}
)}
) } export default UpdateSettingDialog