'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 { useAtomValue } from 'jotai' 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 { userProfileAtom } from '@/context/account-state' 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 = useAtomValue(userProfileAtom) 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