소스 검색

Merge branch '1.1.3-master_web' of http://8.130.72.63:18081/shenzhen/tjdify into 1.1.3-master

CzRger 3 달 전
부모
커밋
64cddb8bbe

+ 12 - 4
web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout-main.tsx

@@ -6,12 +6,10 @@ import useSWR from 'swr'
 import { useTranslation } from 'react-i18next'
 import { useBoolean } from 'ahooks'
 import {
-  Cog8ToothIcon,
   DocumentTextIcon,
   PaperClipIcon,
 } from '@heroicons/react/24/outline'
 import {
-  Cog8ToothIcon as Cog8ToothSolidIcon,
   // CommandLineIcon as CommandLineSolidIcon,
   DocumentTextIcon as DocumentTextSolidIcon,
 } from '@heroicons/react/24/solid'
@@ -31,6 +29,7 @@ import { getLocaleOnClient } from '@/i18n'
 import { useAppContext } from '@/context/app-context'
 import Tooltip from '@/app/components/base/tooltip'
 import LinkedAppsPanel from '@/app/components/base/linked-apps-panel'
+import { GetDatasetAuth } from '@/app/(commonLayout)/datasets/Container'
 
 export type IAppDetailLayoutProps = {
   children: React.ReactNode
@@ -156,6 +155,7 @@ const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
     url: 'fetchDatasetDetail',
     datasetId,
   }, apiParams => fetchDatasetDetail(apiParams.datasetId))
+  const { isCreate, isEdit, isOperation } = GetDatasetAuth(datasetRes)
 
   const { data: relatedApps } = useSWR({
     action: 'fetchDatasetRelatedApps',
@@ -164,11 +164,19 @@ const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
 
   const navigation = useMemo(() => {
     const baseNavigation = [
-      { name: t('common.datasetMenus.hitTesting'), href: `/datasets/${datasetId}/hitTesting`, icon: TargetIcon, selectedIcon: TargetSolidIcon },
       // { name: 'api & webhook', href: `/datasets/${datasetId}/api`, icon: CommandLineIcon, selectedIcon: CommandLineSolidIcon },
-      { name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon },
+      // { name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon },
     ]
 
+    if (isEdit) {
+      baseNavigation.unshift({
+        name: t('common.datasetMenus.hitTesting'),
+        href: `/datasets/${datasetId}/hitTesting`,
+        icon: TargetIcon,
+        selectedIcon: TargetSolidIcon,
+      })
+    }
+
     if (datasetRes?.provider !== 'external') {
       baseNavigation.unshift({
         name: t('common.datasetMenus.documents'),

+ 21 - 4
web/app/(commonLayout)/datasets/Container.tsx

@@ -78,10 +78,10 @@ const Container = () => {
     handleTagsUpdate()
   }
 
-  useEffect(() => {
-    if (currentWorkspace.role === 'normal')
-      return router.replace('/apps')
-  }, [currentWorkspace, router])
+  // useEffect(() => {
+  //   if (currentWorkspace.role === 'normal')
+  //     return router.replace('/apps')
+  // }, [currentWorkspace, router])
 
   const [type, setType] = useState<any>()
   const [searchType, setSearchType] = useState('')
@@ -207,3 +207,20 @@ const Container = () => {
 }
 
 export default Container
+
+export const GetDatasetAuth = (row: any) => {
+  const { currentWorkspace, userProfile } = useAppContext()
+  let isCreate = false
+  let isEdit = false
+  let isOperation = false
+  if (row) {
+    isCreate = currentWorkspace.role === 'owner' || row.created_by === userProfile.id
+    isEdit = isCreate || currentWorkspace.role === 'admin' || (row.edit_auth === 2 && currentWorkspace.role === 'leader' && row.dept_id === userProfile.dept_id)
+    isOperation = isEdit || row.has_edit_permission || (row.edit_auth === 2 && row.dept_id === userProfile.dept_id)
+  }
+  return {
+    isCreate,
+    isEdit,
+    isOperation,
+  }
+}

+ 3 - 7
web/app/(commonLayout)/datasets/DatasetCard.tsx

@@ -20,6 +20,7 @@ import type { Tag } from '@/app/components/base/tag-management/constant'
 import TagSelector from '@/app/components/base/tag-management/selector'
 import CornerLabel from '@/app/components/base/corner-label'
 import { useAppContext } from '@/context/app-context'
+import { GetDatasetAuth } from '@/app/(commonLayout)/datasets/Container'
 
 export type DatasetCardProps = {
   dataset: DataSet
@@ -34,6 +35,7 @@ const DatasetCard = ({
   const { notify } = useContext(ToastContext)
   const { push } = useRouter()
   const EXTERNAL_PROVIDER = 'external' as const
+  const { isCreate, isEdit, isOperation } = GetDatasetAuth(dataset)
 
   const { isCurrentWorkspaceDatasetOperator, currentWorkspace, userProfile } = useAppContext()
   const [tags, setTags] = useState<Tag[]>(dataset.tags)
@@ -194,13 +196,7 @@ const DatasetCard = ({
             </div>
           </div>
           {
-            (
-              currentWorkspace.role === 'owner' // 所有者
-              || currentWorkspace.role === 'admin' // 管理员
-              || dataset.has_edit_permission // 编辑授权
-              || dataset.created_by === userProfile.id // 创建
-              || (dataset.edit_auth === 2 && dataset.dept_id === userProfile.dept_id) // 部门领导
-            ) && (
+            isEdit && (
               <>
                 <div className='mx-1 !hidden h-[14px] w-[1px] shrink-0 bg-divider-regular group-hover:!flex' />
                 <div className='!hidden shrink-0 group-hover:!flex'>

+ 58 - 51
web/app/components/datasets/documents/index.tsx

@@ -32,6 +32,7 @@ import StatusWithAction from '../common/document-status-with-action/status-with-
 import { SimpleSelect } from '@/app/components/base/select'
 import DetailModal from './mould/index'
 import { useAppContext } from '@/context/app-context'
+import { GetDatasetAuth } from '@/app/(commonLayout)/datasets/Container'
 
 const FolderPlusIcon = ({ className }: React.SVGProps<SVGElement>) => {
   return <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
@@ -68,12 +69,13 @@ const EmptyElement: FC<{ canAdd: boolean; onClick: () => void; type?: 'upload' |
         {type === 'upload' ? <FolderPlusIcon /> : <NotionIcon />}
       </div>
       <span className={s.emptyTitle}>{t('datasetDocuments.list.empty.title')}<ThreeDotsIcon className='relative -left-1.5 -top-3 inline' /></span>
+
       <div className={s.emptyTip}>
         {t(`datasetDocuments.list.empty.${type}.tip`)}
       </div>
-      {type === 'upload' && canAdd && <Button onClick={onClick} className={s.addFileBtn}>
-        <PlusIcon className={s.plusIcon} />{t('datasetDocuments.list.addFile')}
-      </Button>}
+      {/* {type === 'upload' && canAdd && <Button onClick={onClick} className={s.addFileBtn}> */}
+      {/*  <PlusIcon className={s.plusIcon} />{t('datasetDocuments.list.addFile')} */}
+      {/* </Button>} */}
     </div>
   </div>
 }
@@ -121,6 +123,7 @@ const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
     },
     refetchInterval: (isDataSourceNotion && timerCanRun) ? 2500 : 0,
   })
+  const { isCreate, isEdit, isOperation } = GetDatasetAuth(dataset)
 
   const invalidDocumentList = useInvalidDocumentList(datasetId)
 
@@ -305,54 +308,58 @@ const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
                 placeholder="请选择审核状态"
               />
             </div>
-            <div className='flex !h-8 items-center justify-center gap-2'>
-              {
-                ['owner', 'admin'].includes(appContext.currentWorkspace.role) && (<Button variant='primary' onClick={() => {
-                  setTransfer({ mode: 'manage' })
-                  setMouldModalVisible(true)
-                }} className='shrink-0'>
-                  <BookOpenIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
-                  模板管理
-                </Button>)
-              }
-              <Button variant='primary' onClick={() => {
-                setTransfer({ mode: 'download' })
-                setMouldModalVisible(true)
-              }} className='shrink-0'>
-                <ArrowDownTrayIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
-                模板下载
-              </Button>
+            {
+              isOperation && (
+                <div className='flex !h-8 items-center justify-center gap-2'>
+                  {
+                    isEdit && (<Button variant='primary' onClick={() => {
+                      setTransfer({ mode: 'manage' })
+                      setMouldModalVisible(true)
+                    }} className='shrink-0'>
+                      <BookOpenIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
+                      模板管理
+                    </Button>)
+                  }
+                  <Button variant='primary' onClick={() => {
+                    setTransfer({ mode: 'download' })
+                    setMouldModalVisible(true)
+                  }} className='shrink-0'>
+                    <ArrowDownTrayIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
+                    模板下载
+                  </Button>
 
-              {!isFreePlan && <AutoDisabledDocument datasetId={datasetId} />}
-              <IndexFailed datasetId={datasetId} />
-              {!embeddingAvailable && <StatusWithAction type='warning' description={t('dataset.embeddingModelNotAvailable')} />}
-              {embeddingAvailable && (
-                <Button variant='secondary' className='shrink-0' onClick={showEditMetadataModal}>
-                  <RiDraftLine className='mr-1 size-4' />
-                  {t('dataset.metadata.metadata')}
-                </Button>
-              )}
-              {isShowEditMetadataModal && (
-                <DatasetMetadataDrawer
-                  userMetadata={datasetMetaData || []}
-                  onClose={hideEditMetadataModal}
-                  onAdd={handleAddMetaData}
-                  onRename={handleRename}
-                  onRemove={handleDeleteMetaData}
-                  builtInMetadata={builtInMetaData || []}
-                  isBuiltInEnabled={!!builtInEnabled}
-                  onIsBuiltInEnabledChange={setBuiltInEnabled}
-                />
-              )}
-              {embeddingAvailable && (
-                <Button variant='primary' onClick={routeToDocCreate} className='shrink-0'>
-                  <PlusIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
-                  {isDataSourceNotion && t('datasetDocuments.list.addPages')}
-                  {isDataSourceWeb && t('datasetDocuments.list.addUrl')}
-                  {(!dataset?.data_source_type || isDataSourceFile) && t('datasetDocuments.list.addFile')}
-                </Button>
-              )}
-            </div>
+                  {!isFreePlan && <AutoDisabledDocument datasetId={datasetId} />}
+                  <IndexFailed datasetId={datasetId} />
+                  {!embeddingAvailable && <StatusWithAction type='warning' description={t('dataset.embeddingModelNotAvailable')} />}
+                  {embeddingAvailable && (
+                    <Button variant='secondary' className='shrink-0' onClick={showEditMetadataModal}>
+                      <RiDraftLine className='mr-1 size-4' />
+                      {t('dataset.metadata.metadata')}
+                    </Button>
+                  )}
+                  {isShowEditMetadataModal && (
+                    <DatasetMetadataDrawer
+                      userMetadata={datasetMetaData || []}
+                      onClose={hideEditMetadataModal}
+                      onAdd={handleAddMetaData}
+                      onRename={handleRename}
+                      onRemove={handleDeleteMetaData}
+                      builtInMetadata={builtInMetaData || []}
+                      isBuiltInEnabled={!!builtInEnabled}
+                      onIsBuiltInEnabledChange={setBuiltInEnabled}
+                    />
+                  )}
+                  {embeddingAvailable && (
+                    <Button variant='primary' onClick={routeToDocCreate} className='shrink-0'>
+                      <PlusIcon className={cn('mr-2 h-4 w-4 stroke-current')} />
+                      {isDataSourceNotion && t('datasetDocuments.list.addPages')}
+                      {isDataSourceWeb && t('datasetDocuments.list.addUrl')}
+                      {(!dataset?.data_source_type || isDataSourceFile) && t('datasetDocuments.list.addFile')}
+                    </Button>
+                  )}
+                </div>
+              )
+            }
           </div>
           {isListLoading
             ? <Loading type='app' />
@@ -372,7 +379,7 @@ const Documents: FC<IDocumentsProps> = ({ datasetId }) => {
                   onChange: setCurrPage,
                 }}
                 onManageMetadata={showEditMetadataModal}
-                optionsExamineStatus={optionsExamineStatus}
+                dataset={dataset}
               />
               : <EmptyElement canAdd={embeddingAvailable} onClick={routeToDocCreate} type={isDataSourceNotion ? 'sync' : 'upload'} />
           }

+ 90 - 66
web/app/components/datasets/documents/list.tsx

@@ -56,6 +56,7 @@ import { extensionToFileType } from '@/app/components/datasets/hit-testing/utils
 import useBatchEditDocumentMetadata from '../metadata/hooks/use-batch-edit-document-metadata'
 import EditMetadataBatchModal from '@/app/components/datasets/metadata/edit-metadata-batch/modal'
 import { useAppContext } from '@/context/app-context'
+import { GetDatasetAuth } from '@/app/(commonLayout)/datasets/Container'
 
 export const useIndexStatus = () => {
   const { t } = useTranslation()
@@ -470,7 +471,7 @@ type IDocumentListProps = {
   pagination: PaginationProps
   onUpdate: () => void
   onManageMetadata: () => void,
-  optionsExamineStatus: any[]
+  dataset: any
 }
 
 /**
@@ -485,8 +486,9 @@ const DocumentList: FC<IDocumentListProps> = ({
   pagination,
   onUpdate,
   onManageMetadata,
-  optionsExamineStatus,
+  dataset,
 }) => {
+  const { isCreate, isEdit, isOperation } = GetDatasetAuth(dataset)
   const { t } = useTranslation()
   const { formatTime } = useTimestamp()
   const router = useRouter()
@@ -582,7 +584,7 @@ const DocumentList: FC<IDocumentListProps> = ({
       else { Toast.notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) }
     }
   }
-  const ExamineMap = {
+  const ExamineMap: any = {
     1: '待审核',
     2: '审核不通过',
     3: '无',
@@ -632,7 +634,7 @@ const DocumentList: FC<IDocumentListProps> = ({
             <tr>
               <td className='w-12'>
                 <div className='flex items-center' onClick={e => e.stopPropagation()}>
-                  {embeddingAvailable && (
+                  {isOperation && embeddingAvailable && (
                     <Checkbox
                       className='mr-2 shrink-0'
                       checked={isAllSelected}
@@ -659,7 +661,11 @@ const DocumentList: FC<IDocumentListProps> = ({
               </td>
               <td className='w-40'>{t('datasetDocuments.list.table.header.status')}</td>
               <td className='w-40'>审核状态</td>
-              <td className='w-20'>{t('datasetDocuments.list.table.header.action')}</td>
+              {
+                isOperation && (
+                  <td className='w-20'>{t('datasetDocuments.list.table.header.action')}</td>
+                )
+              }
             </tr>
           </thead>
           <tbody className="text-text-secondary">
@@ -668,50 +674,58 @@ const DocumentList: FC<IDocumentListProps> = ({
               const fileType = isFile ? doc.data_source_detail_dict?.upload_file?.extension : ''
               return <tr
                 key={doc.id}
-                className={'h-8 cursor-pointer border-b border-divider-subtle hover:bg-background-default-hover'}
+                className={`h-8 border-b border-divider-subtle ${isOperation && (doc.check_status === 2 || doc.check_status === 3) ? 'cursor-pointer  hover:bg-background-default-hover' : ''}`}
                 onClick={() => {
-                  (doc.check_status === 2 || doc.check_status === 3) && router.push(`/datasets/${datasetId}/documents/${doc.id}`)
+                  isOperation && (doc.check_status === 2 || doc.check_status === 3) && router.push(`/datasets/${datasetId}/documents/${doc.id}`)
                 }}>
                 <td className='text-left align-middle text-xs text-text-tertiary'>
                   <div className='flex items-center' onClick={e => e.stopPropagation()}>
-                    <Checkbox
-                      className='mr-2 shrink-0'
-                      checked={selectedIds.includes(doc.id)}
-                      onCheck={() => {
-                        onSelectedIdChange(
-                          selectedIds.includes(doc.id)
-                            ? selectedIds.filter(id => id !== doc.id)
-                            : [...selectedIds, doc.id],
-                        )
-                      }}
-                    />
+                    {
+                      isOperation && (
+                        <Checkbox
+                          className='mr-2 shrink-0'
+                          checked={selectedIds.includes(doc.id)}
+                          onCheck={() => {
+                            onSelectedIdChange(
+                              selectedIds.includes(doc.id)
+                                ? selectedIds.filter(id => id !== doc.id)
+                                : [...selectedIds, doc.id],
+                            )
+                          }}
+                        />
+                      )
+                    }
                     {/* {doc.position} */}
                     {index + 1}
                   </div>
                 </td>
                 <td>
-                  <div className={'group mr-6 flex max-w-[460px] items-center hover:mr-0'}>
+                  <div className={`group mr-6 flex max-w-[460px] items-center ${isOperation ? 'hover:mr-0' : ''}`}>
                     <div className='shrink-0'>
                       {doc?.data_source_type === DataSourceType.NOTION && <NotionIcon className='mr-1.5 mt-[-3px] inline-flex align-middle' type='page' src={doc.data_source_info.notion_page_icon} />}
                       {doc?.data_source_type === DataSourceType.FILE && <FileTypeIcon type={extensionToFileType(doc?.data_source_info?.upload_file?.extension ?? fileType)} className='mr-1.5' />}
                       {doc?.data_source_type === DataSourceType.WEB && <Globe01 className='mr-1.5 mt-[-3px] inline-flex align-middle' />}
                     </div>
                     <span className='grow-1 truncate text-sm'>{doc.name}</span>
-                    <div className='hidden shrink-0 group-hover:ml-auto group-hover:flex'>
-                      <Tooltip
-                        popupContent={t('datasetDocuments.list.table.rename')}
-                      >
-                        <div
-                          className='cursor-pointer rounded-md p-1 hover:bg-state-base-hover'
-                          onClick={(e) => {
-                            e.stopPropagation()
-                            handleShowRenameModal(doc)
-                          }}
-                        >
-                          <RiEditLine className='h-4 w-4 text-text-tertiary' />
+                    {
+                      isOperation && (
+                        <div className='hidden shrink-0 group-hover:ml-auto group-hover:flex'>
+                          <Tooltip
+                            popupContent={t('datasetDocuments.list.table.rename')}
+                          >
+                            <div
+                              className='cursor-pointer rounded-md p-1 hover:bg-state-base-hover'
+                              onClick={(e) => {
+                                e.stopPropagation()
+                                handleShowRenameModal(doc)
+                              }}
+                            >
+                              <RiEditLine className='h-4 w-4 text-text-tertiary' />
+                            </div>
+                          </Tooltip>
                         </div>
-                      </Tooltip>
-                    </div>
+                      )
+                    }
                   </div>
                 </td>
                 <td>
@@ -734,43 +748,53 @@ const DocumentList: FC<IDocumentListProps> = ({
                 </td>
                 <td>
                   {
-                    doc.check_status === 1 && (
-                      ['owner', 'admin'].includes(appContext.currentWorkspace.role)
-                        ? <div className="cursor-pointer text-[#155aef]" onClick={(e) => {
-                          e.stopPropagation()
-                          setRow(doc)
-                          setConfirmExamineHandleTitle(`${doc.enabled ? '下线' : '上线'}审核`)
-                          setConfirmExamineHandleContent(`用户“${doc.enable_application}”申请将该知识${doc.enabled ? '下线' : '上线'},请审核!`)
-                          setShowConfirmExamineHandle(true)
-                        }}>{ExamineMap[doc.check_status]}</div>
-                        : <div>{ExamineMap[doc.check_status]}</div>
-                    )
-                  }
-                  {
-                    doc.check_status === 2 && (
-                      <div className="cursor text-[#155aef]" onClick={(e) => {
-                        e.stopPropagation()
-                        setConfirmExamineResultContent(`用户“${doc.check_by}”不同意将该知识上线!`)
-                        setShowConfirmExamineResult(true)
-                      }}>{ExamineMap[doc.check_status]}</div>
-                    )
-                  }
-                  {
-                    doc.check_status === 3 && (
+                    isOperation ? (<>
+                      {
+                        doc.check_status === 1 && (
+                          ['owner', 'admin'].includes(appContext.currentWorkspace.role)
+                            ? <div className="cursor-pointer text-[#155aef]" onClick={(e) => {
+                              e.stopPropagation()
+                              setRow(doc)
+                              setConfirmExamineHandleTitle(`${doc.enabled ? '下线' : '上线'}审核`)
+                              setConfirmExamineHandleContent(`用户“${doc.enable_application}”申请将该知识${doc.enabled ? '下线' : '上线'},请审核!`)
+                              setShowConfirmExamineHandle(true)
+                            }}>{ExamineMap[doc.check_status]}</div>
+                            : <div>{ExamineMap[doc.check_status]}</div>
+                        )
+                      }
+                      {
+                        doc.check_status === 2 && (
+                          <div className="cursor text-[#155aef]" onClick={(e) => {
+                            e.stopPropagation()
+                            setConfirmExamineResultContent(`用户“${doc.check_by}”不同意将该知识上线!`)
+                            setShowConfirmExamineResult(true)
+                          }}>{ExamineMap[doc.check_status]}</div>
+                        )
+                      }
+                      {
+                        doc.check_status === 3 && (
+                          <div>{ExamineMap[doc.check_status]}</div>
+                        )
+                      }
+                    </>) : (
                       <div>{ExamineMap[doc.check_status]}</div>
                     )
                   }
                 </td>
-                <td>
-                  {
-                    (doc.check_status === 2 || doc.check_status === 3) && (<OperationAction
-                      embeddingAvailable={embeddingAvailable}
-                      datasetId={datasetId}
-                      detail={pick(doc, ['name', 'enabled', 'archived', 'id', 'data_source_type', 'doc_form', 'check_status'])}
-                      onUpdate={onUpdate}
-                    />)
-                  }
-                </td>
+                {
+                  isOperation && (
+                    <td>
+                      {
+                        (doc.check_status === 2 || doc.check_status === 3) && (<OperationAction
+                          embeddingAvailable={embeddingAvailable}
+                          datasetId={datasetId}
+                          detail={pick(doc, ['name', 'enabled', 'archived', 'id', 'data_source_type', 'doc_form', 'check_status'])}
+                          onUpdate={onUpdate}
+                        />)
+                      }
+                    </td>
+                  )
+                }
               </tr>
             })}
           </tbody>

+ 22 - 15
web/app/components/datasets/rename-modal/index.tsx

@@ -24,6 +24,7 @@ import {
   setDatasetsPermission,
 } from '@/service/common'
 import { TreeSelect as AntdTreeSelect } from 'antd'
+import { GetDatasetAuth } from '@/app/(commonLayout)/datasets/Container'
 
 type RenameDatasetModalProps = {
   show: boolean
@@ -33,6 +34,7 @@ type RenameDatasetModalProps = {
 }
 
 const RenameDatasetModal = ({ show, dataset, onSuccess, onClose }: RenameDatasetModalProps) => {
+  const { isCreate, isEdit, isOperation } = GetDatasetAuth(dataset)
   const { t } = useTranslation()
   const { notify } = useContext(ToastContext)
   const [loading, setLoading] = useState(false)
@@ -219,21 +221,26 @@ const RenameDatasetModal = ({ show, dataset, onSuccess, onClose }: RenameDataset
             />
           </div>
         </div>
-        <div className='pt-2'>
-          <div className='py-2 text-sm font-medium leading-[20px] text-text-primary'>编辑权限</div>
-          <div className="h-[32px]">
-            <SimpleSelect
-              className="h-[32px]"
-              defaultValue={editAuth}
-              onSelect={(i: any) => {
-                setEditAuth(i.value)
-              }}
-              items={optionsEditAuth}
-              allowSearch={false}
-              placeholder="请选择编辑权限"
-            />
-          </div>
-        </div>
+        {
+          isCreate && (
+            <div className='pt-2'>
+              <div className='py-2 text-sm font-medium leading-[20px] text-text-primary'>编辑权限</div>
+              <div className="h-[32px]">
+                <SimpleSelect
+                  className="h-[32px]"
+                  defaultValue={editAuth}
+                  onSelect={(i: any) => {
+                    setEditAuth(i.value)
+                  }}
+                  items={optionsEditAuth}
+                  allowSearch={false}
+                  placeholder="请选择编辑权限"
+                  notClearable={true}
+                />
+              </div>
+            </div>
+          )
+        }
         <div className='pt-2'>
           <div className='py-2 text-sm font-medium leading-[20px] text-text-primary'>编辑授权</div>
           <AntdTreeSelect

+ 10 - 11
web/app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx

@@ -4,7 +4,6 @@ import React, { useCallback, useState } from 'react'
 import { useBoolean } from 'ahooks'
 import {
   RiDeleteBinLine,
-  RiEditLine,
 } from '@remixicon/react'
 import { useTranslation } from 'react-i18next'
 import type { DataSet } from '@/models/datasets'
@@ -77,16 +76,16 @@ const DatasetItem: FC<Props> = ({
       </div>
       {!readonly && (
         <div className='ml-2 hidden shrink-0 items-center  space-x-1 group-hover/dataset-item:flex'>
-          {
-            editable && <ActionButton
-              onClick={(e) => {
-                e.stopPropagation()
-                showSettingsModal()
-              }}
-            >
-              <RiEditLine className='h-4 w-4 shrink-0 text-text-tertiary' />
-            </ActionButton>
-          }
+          {/* { */}
+          {/*  editable && <ActionButton */}
+          {/*    onClick={(e) => { */}
+          {/*      e.stopPropagation() */}
+          {/*      showSettingsModal() */}
+          {/*    }} */}
+          {/*  > */}
+          {/*    <RiEditLine className='h-4 w-4 shrink-0 text-text-tertiary' /> */}
+          {/*  </ActionButton> */}
+          {/* } */}
           <ActionButton
             onClick={handleRemove}
             state={ActionButtonState.Destructive}

+ 1 - 1
web/context/app-context.tsx

@@ -100,7 +100,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
   const [currentWorkspace, setCurrentWorkspace] = useState<ICurrentWorkspace>(initialWorkspaceInfo)
   const isCurrentWorkspaceManager = useMemo(() => ['owner', 'admin'].includes(currentWorkspace.role), [currentWorkspace.role])
   const isCurrentWorkspaceOwner = useMemo(() => currentWorkspace.role === 'owner', [currentWorkspace.role])
-  const isCurrentWorkspaceEditor = useMemo(() => ['owner', 'admin', 'editor'].includes(currentWorkspace.role), [currentWorkspace.role])
+  const isCurrentWorkspaceEditor = useMemo(() => ['owner', 'admin', 'editor', 'leader'].includes(currentWorkspace.role), [currentWorkspace.role])
   const isCurrentWorkspaceDatasetOperator = useMemo(() => currentWorkspace.role === 'dataset_operator', [currentWorkspace.role])
   const updateUserProfileAndVersion = useCallback(async () => {
     if (userProfileResponse && !userProfileResponse.bodyUsed) {