'use client' import type { AccessChannels, AccessEndpoint } from '@dify/contracts/enterprise/types.gen' import type { ReactNode } from 'react' import { Switch, SwitchSkeleton } from '@langgenius/dify-ui/switch' import { useMutation } from '@tanstack/react-query' import { useAtomValue } from 'jotai' import { useTranslation } from 'react-i18next' import { SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton' import { consoleQuery } from '@/service/client' import { deploymentRouteAppInstanceIdAtom } from '../../../route-state' import { DeploymentEmptyState, DeploymentNoticeState, DeploymentStateMessage, } from '../../../shared/components/empty-state' import { CopyPill, EndpointRow } from '../../../shared/components/endpoint' import { Section } from '../../../shared/components/section' import { accessSettingsAtom, accessSettingsIsErrorAtom, accessSettingsIsLoadingAtom, } from '../state' import { getUrlOrigin } from './url' const ACCESS_CHANNEL_SKELETON_SECTIONS = [{ key: 'webapp' }, { key: 'cli' }] function AccessChannelsSwitch({ checked, accessChannels, disabled, }: { checked: boolean accessChannels?: AccessChannels disabled?: boolean }) { const { t } = useTranslation('deployments') const appInstanceId = useAtomValue(deploymentRouteAppInstanceIdAtom) const toggleAccessChannel = useMutation( consoleQuery.enterprise.accessService.updateAccessChannels.mutationOptions(), ) return ( $['access.channels.title'])} checked={checked} disabled={disabled || !appInstanceId} loading={toggleAccessChannel.isPending} onCheckedChange={(enabled) => { if (!appInstanceId) return toggleAccessChannel.mutate({ params: { appInstanceId }, body: { appInstanceId, webAppEnabled: enabled, developerApiEnabled: accessChannels?.developerApiEnabled ?? false, }, }) }} /> ) } function AccessChannelsSkeleton() { return (
{ACCESS_CHANNEL_SKELETON_SECTIONS.map((section) => (
))}
) } function ChannelInfo({ icon, title, description, }: { icon: ReactNode title: string description?: string }) { return (
{icon}
{title}
{description &&
{description}
}
) } function ChannelRow({ info, children }: { info: ReactNode; children: ReactNode }) { return (
{info}
{children}
) } export function AccessChannelsSection() { const { t } = useTranslation('deployments') const appInstanceId = useAtomValue(deploymentRouteAppInstanceIdAtom) const accessSettings = useAtomValue(accessSettingsAtom) const isLoading = useAtomValue(accessSettingsIsLoadingAtom) const isError = useAtomValue(accessSettingsIsErrorAtom) const accessChannels = accessSettings?.accessChannels const webAppEndpoints: AccessEndpoint[] | undefined = accessSettings?.webAppEndpoints const cliEndpoint: AccessEndpoint | undefined = accessSettings?.cliEndpoint const runEnabled = accessChannels?.webAppEnabled ?? false const webappRows = webAppEndpoints?.flatMap((endpoint) => { const endpointUrl = endpoint.endpointUrl if (!endpointUrl) return [] return [ { endpoint, endpointUrl, }, ] }) ?? [] const cliDomain = getUrlOrigin(cliEndpoint?.endpointUrl) const cliDocsUrl = cliDomain ? `${cliDomain}/cli` : undefined return (
$['access.channels.title'])} action={ isLoading ? ( ) : (
{runEnabled ? t(($) => $['overview.enabled']) : t(($) => $['overview.disabled'])}
) } > {isLoading ? ( ) : isError || !appInstanceId ? ( {t(($) => $['common.loadFailed'])} ) : runEnabled ? (
) : ( $['access.channels.disabled'])} description={t(($) => $['access.channels.disabledHint'])} /> )}
) }