'use client' import type { ResourceOpenScope } from '@/models/access-control' import { ScrollArea } from '@langgenius/dify-ui/scroll-area' import { useAtomValue } from 'jotai' import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import AccessRulesEditor from '@/app/components/access-rules-editor' import Loading from '@/app/components/base/loading' import { userProfileIdAtom } from '@/context/account-state' import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail' import { useLocale } from '@/context/i18n' import { workspacePermissionKeysAtom } from '@/context/permission-state' import { datasetRbacEnabledAtom } from '@/context/system-features-state' import { getAccessControlTemplateLanguage } from '@/i18n-config/language' import { useDatasetAccessRules, useDatasetUserAccessSettings, useRemoveDatasetAccessPolicyMemberBindings, useUpdateDatasetOpenScope, useUpdateDatasetUserAccessSettings, } from '@/service/access-control/use-dataset-access-config' import { getDatasetACLCapabilities } from '@/utils/permission' type DatasetAccessConfigPageProps = { datasetId: string } const DatasetAccessConfigPage = ({ datasetId }: DatasetAccessConfigPageProps) => { const { t } = useTranslation() const locale = useLocale() const language = useMemo(() => getAccessControlTemplateLanguage(locale), [locale]) const dataset = useDatasetDetailContextWithSelector((state) => state.dataset) const currentUserId = useAtomValue(userProfileIdAtom) const workspacePermissionKeys = useAtomValue(workspacePermissionKeysAtom) const isRbacEnabled = useAtomValue(datasetRbacEnabledAtom) const canAccessConfig = getDatasetACLCapabilities(dataset?.permission_keys, { currentUserId, resourceMaintainer: dataset?.maintainer, workspacePermissionKeys, isRbacEnabled, }).canAccessConfig const { data: datasetAccessRulesResponse, isLoading: isLoadingDatasetAccessRules } = useDatasetAccessRules(datasetId, language, { enabled: canAccessConfig }) const { data: datasetUserAccessSettingsResponse, isLoading: isLoadingDatasetUserAccessSettings } = useDatasetUserAccessSettings(datasetId, language, { enabled: canAccessConfig }) const { mutate: updateDatasetOpenScope, isPending: isUpdatingDatasetOpenScope } = useUpdateDatasetOpenScope(datasetId) const { mutate: updateDatasetUserAccessSettings } = useUpdateDatasetUserAccessSettings(datasetId) const { mutate: removeDatasetAccessPolicyMemberBindings } = useRemoveDatasetAccessPolicyMemberBindings(datasetId) const [optimisticOpenScope, setOptimisticOpenScope] = useState(null) const [updatingAccountId, setUpdatingAccountId] = useState(null) const datasetAccessRules = datasetAccessRulesResponse?.items || [] const datasetUserAccessSettings = datasetUserAccessSettingsResponse?.data || [] const openScope = optimisticOpenScope || datasetUserAccessSettingsResponse?.scope const handleOpenScopeChange = useCallback( (nextOpenScope: ResourceOpenScope) => { if (!canAccessConfig) return if (nextOpenScope === openScope) return const previousOptimisticOpenScope = optimisticOpenScope setOptimisticOpenScope(nextOpenScope) updateDatasetOpenScope(nextOpenScope, { onError: () => setOptimisticOpenScope(previousOptimisticOpenScope), }) }, [canAccessConfig, openScope, optimisticOpenScope, updateDatasetOpenScope], ) const handleUserAccessPoliciesChange = useCallback( (accountId: string, accessPolicyIds: string[]) => { if (!canAccessConfig) return setUpdatingAccountId(accountId) updateDatasetUserAccessSettings( { accountId, accessPolicyIds }, { onSettled: () => setUpdatingAccountId(null) }, ) }, [canAccessConfig, updateDatasetUserAccessSettings], ) const handleRemoveAccessPolicyMemberBinding = useCallback( (accountId: string, accessPolicyId: string) => { if (!canAccessConfig) return setUpdatingAccountId(accountId) removeDatasetAccessPolicyMemberBindings( { accessPolicyId, accountIds: [accountId] }, { onSettled: () => setUpdatingAccountId(null) }, ) }, [canAccessConfig, removeDatasetAccessPolicyMemberBindings], ) if (!canAccessConfig) return return (

{t(($) => $['settings.resourceAccess'], { ns: 'common' })}

{t(($) => $['accessRule.datasetDescription'], { ns: 'permission' })}

) } export default DatasetAccessConfigPage