diff --git a/oxlint-suppressions.json b/oxlint-suppressions.json
index cd155c48af6..eadb4e44d93 100644
--- a/oxlint-suppressions.json
+++ b/oxlint-suppressions.json
@@ -1889,22 +1889,6 @@
"count": 2
}
},
- "web/app/components/base/permission-selector/member-item.tsx": {
- "jsx_a11y/click-events-have-key-events": {
- "count": 1
- },
- "jsx_a11y/no-static-element-interactions": {
- "count": 1
- }
- },
- "web/app/components/base/permission-selector/permission-item.tsx": {
- "jsx_a11y/click-events-have-key-events": {
- "count": 1
- },
- "jsx_a11y/no-static-element-interactions": {
- "count": 1
- }
- },
"web/app/components/base/prompt-editor/index.stories.tsx": {
"jsx_a11y/label-has-associated-control": {
"count": 4
@@ -2956,22 +2940,6 @@
"count": 1
}
},
- "web/app/components/datasets/settings/permission-selector/member-item.tsx": {
- "jsx_a11y/click-events-have-key-events": {
- "count": 1
- },
- "jsx_a11y/no-static-element-interactions": {
- "count": 1
- }
- },
- "web/app/components/datasets/settings/permission-selector/permission-item.tsx": {
- "jsx_a11y/click-events-have-key-events": {
- "count": 1
- },
- "jsx_a11y/no-static-element-interactions": {
- "count": 1
- }
- },
"web/app/components/develop/code.tsx": {
"typescript/no-explicit-any": {
"count": 6
diff --git a/web/app/components/base/permission-selector/index.tsx b/web/app/components/base/permission-selector/index.tsx
deleted file mode 100644
index 39c75099a2f..00000000000
--- a/web/app/components/base/permission-selector/index.tsx
+++ /dev/null
@@ -1,295 +0,0 @@
-import type { Member } from '@/models/common'
-import { Avatar } from '@langgenius/dify-ui/avatar'
-import { cn } from '@langgenius/dify-ui/cn'
-import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover'
-import { RiArrowDownSLine, RiGroup2Line, RiLock2Line } from '@remixicon/react'
-import { useDebounceFn } from 'ahooks'
-import { useAtomValue } from 'jotai'
-import * as React from 'react'
-import { useCallback, useMemo, useState } from 'react'
-import { useTranslation } from 'react-i18next'
-// oxlint-disable-next-line no-restricted-imports -- This legacy selector still relies on showLeftIcon/showClearIcon props from the old input.
-import Input from '@/app/components/base/input'
-import { userProfileAtom } from '@/context/account-state'
-import { PermissionLevel } from '@/models/permission'
-import MemberItem from './member-item'
-import Item from './permission-item'
-
-type PermissionSelectorProps = {
- disabled?: boolean
- permission?: PermissionLevel
- value: string[]
- memberList: Member[]
- onChange: (permission?: PermissionLevel) => void
- onMemberSelect: (v: string[]) => void
- /** i18n namespace for label strings (defaults to datasetSettings for backward compat) */
- i18nNamespace?: 'datasetSettings'
- /**
- * Hide the "Partial members" option. Useful for surfaces (e.g. plugin
- * credential creation) where partial-member access is delegated to RBAC
- * and the picker should only expose only_me / all_team_members.
- */
- hidePartialMembers?: boolean
-}
-
-const PermissionSelector = ({
- disabled,
- permission,
- value,
- memberList,
- onChange,
- onMemberSelect,
- i18nNamespace = 'datasetSettings',
- hidePartialMembers = false,
-}: PermissionSelectorProps) => {
- const { t } = useTranslation()
- const userProfile = useAtomValue(userProfileAtom)
- const [open, setOpen] = useState(false)
-
- const [keywords, setKeywords] = useState('')
- const [searchKeywords, setSearchKeywords] = useState('')
- const { run: handleSearch } = useDebounceFn(
- () => {
- setSearchKeywords(keywords)
- },
- { wait: 500 },
- )
- const handleKeywordsChange = (value: string) => {
- setKeywords(value)
- handleSearch()
- }
- const selectMember = useCallback(
- (member: Member) => {
- if (value.includes(member.id)) onMemberSelect(value.filter((v) => v !== member.id))
- else onMemberSelect([...value, member.id])
- },
- [value, onMemberSelect],
- )
-
- const selectedMembers = useMemo(() => {
- return [
- userProfile,
- ...memberList
- .filter((member) => member.id !== userProfile.id)
- .filter((member) => value.includes(member.id)),
- ]
- }, [userProfile, value, memberList])
-
- const showMe = useMemo(() => {
- return (
- (userProfile.name ?? '').includes(searchKeywords) ||
- (userProfile.email ?? '').includes(searchKeywords)
- )
- }, [searchKeywords, userProfile])
-
- const filteredMemberList = useMemo(() => {
- return memberList.filter(
- (member) =>
- (member.name.includes(searchKeywords) || member.email.includes(searchKeywords)) &&
- member.id !== userProfile.id &&
- ['owner', 'admin', 'editor', 'dataset_operator'].includes(member.role),
- )
- }, [memberList, searchKeywords, userProfile])
-
- const onSelectOnlyMe = useCallback(() => {
- onChange(PermissionLevel.onlyMe)
- setOpen(false)
- }, [onChange])
-
- const onSelectAllMembers = useCallback(() => {
- onChange(PermissionLevel.allTeamMembers)
- setOpen(false)
- }, [onChange])
-
- const onSelectPartialMembers = useCallback(() => {
- onChange(PermissionLevel.partialMembers)
- onMemberSelect([userProfile.id])
- }, [onChange, onMemberSelect, userProfile])
-
- const isOnlyMe = permission === PermissionLevel.onlyMe
- const isAllTeamMembers = permission === PermissionLevel.allTeamMembers
- const isPartialMembers = permission === PermissionLevel.partialMembers
- const selectedMemberNames = selectedMembers.map((member) => member.name).join(', ')
-
- return (
-