diff --git a/web/app/components/app/app-publisher/index.tsx b/web/app/components/app/app-publisher/index.tsx index 3ba35a7336..5c86c0c51d 100644 --- a/web/app/components/app/app-publisher/index.tsx +++ b/web/app/components/app/app-publisher/index.tsx @@ -1,13 +1,17 @@ import { memo, useCallback, + useEffect, useState, } from 'react' import { useTranslation } from 'react-i18next' import dayjs from 'dayjs' -import { RiArrowDownSLine, RiPlanetLine } from '@remixicon/react' +import { RiArrowDownSLine, RiArrowRightSLine, RiLockLine, RiPlanetLine } from '@remixicon/react' import Toast from '../../base/toast' import type { ModelAndParameter } from '../configuration/debug/types' +import Divider from '../../base/divider' +import AccessControl from '../app-access-control' +import Loading from '../../base/loading' import SuggestedAction from './suggested-action' import PublishWithMultipleModel from './publish-with-multiple-model' import Button from '@/app/components/base/button' @@ -27,6 +31,9 @@ import { FileText } from '@/app/components/base/icons/src/vender/line/files' import WorkflowToolConfigureButton from '@/app/components/tools/workflow-tool/configure-button' import type { InputVar } from '@/app/components/workflow/types' import { appDefaultIconBackground } from '@/config' +import { useAppWhiteListSubjects, useGetAppAccessMode, useGetUserCanAccessApp } from '@/service/access-control' +import { AccessMode } from '@/models/access-control' +import { fetchAppDetail } from '@/service/apps' export type AppPublisherProps = { disabled?: boolean @@ -65,10 +72,27 @@ const AppPublisher = ({ const [published, setPublished] = useState(false) const [open, setOpen] = useState(false) const appDetail = useAppStore(state => state.appDetail) + const setAppDetail = useAppStore(s => s.setAppDetail) const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {} const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode const appURL = `${appBaseURL}/${appMode}/${accessToken}` + const { data: appAccessMode, isPending: isGettingAppAccessMode } = useGetAppAccessMode({ appId: appDetail?.id }) + const { data: useCanAccessApp, isPending: isGettingUserCanAccessApp } = useGetUserCanAccessApp({ appId: appDetail?.id }) + const { data: appAccessSubjects, isPending: isGettingAppWhiteListSubjects } = useAppWhiteListSubjects(appDetail?.id, open) + const [showAppAccessControl, setShowAppAccessControl] = useState(false) + const [isAppAccessSet, setIsAppAccessSet] = useState(false) + useEffect(() => { + if (appAccessMode && appAccessSubjects) { + if (appAccessMode.accessMode === AccessMode.SPECIFIC_GROUPS_MEMBERS && appAccessSubjects.groups?.length > 0 && appAccessSubjects.members?.length > 0) + setIsAppAccessSet(false) + else + setIsAppAccessSet(true) + } + else { + setIsAppAccessSet(false) + } + }, [appAccessSubjects, appAccessMode]) const language = useGetLanguage() const formatTimeFromNow = useCallback((time: number) => { return dayjs(time).locale(language === 'zh_Hans' ? 'zh-cn' : language.replace('_', '-')).fromNow() @@ -120,6 +144,13 @@ const AppPublisher = ({ } }, [appDetail?.id]) + const handleAccessControlUpdate = useCallback(() => { + fetchAppDetail({ url: '/apps', id: appDetail!.id }).then((res) => { + setAppDetail(res) + setShowAppAccessControl(false) + }) + }, [appDetail, setAppDetail]) + const [embeddingModalOpen, setEmbeddingModalOpen] = useState(false) return ( @@ -196,58 +227,83 @@ const AppPublisher = ({ ) } -
{t('app.publishApp.title')}
+{t('app.accessControlDialog.accessItems.organization')}
} + {appAccessMode?.accessMode === AccessMode.SPECIFIC_GROUPS_MEMBERS &&{t('app.accessControlDialog.accessItems.specific')}
} + {appAccessMode?.accessMode === AccessMode.PUBLIC &&{t('app.accessControlDialog.accessItems.anyone')}
} +{t('app.publishApp.notSet')}
} +