feat: implement create dataset pipeline forms and modals
parent
cfb6d59513
commit
de0cb06f8c
@ -0,0 +1,75 @@
|
|||||||
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
import type { CreateDatasetReq } from '@/models/datasets'
|
||||||
|
import { ChunkingMode, DatasetPermission } from '@/models/datasets'
|
||||||
|
import { useMembers } from '@/service/use-common'
|
||||||
|
import { useCreatePipelineDataset } from '@/service/knowledge/use-create-dataset'
|
||||||
|
import type { Member } from '@/models/common'
|
||||||
|
import CreateForm from '../create-form'
|
||||||
|
import type { CreateFormData } from '@/models/pipeline'
|
||||||
|
import Modal from '@/app/components/base/modal'
|
||||||
|
|
||||||
|
type CreateFromScratchModalProps = {
|
||||||
|
show: boolean
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateFromScratchModal = ({
|
||||||
|
show,
|
||||||
|
onClose,
|
||||||
|
}: CreateFromScratchModalProps) => {
|
||||||
|
const [memberList, setMemberList] = useState<Member[]>([])
|
||||||
|
const { data: members } = useMembers()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (members?.accounts)
|
||||||
|
setMemberList(members.accounts)
|
||||||
|
}, [members])
|
||||||
|
|
||||||
|
const { mutateAsync: createEmptyDataset } = useCreatePipelineDataset()
|
||||||
|
|
||||||
|
const handleCreate = useCallback(async (payload: CreateFormData) => {
|
||||||
|
const { name, appIcon, description, permission, selectedMemberIDs } = payload
|
||||||
|
const request: CreateDatasetReq = {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
icon_info: {
|
||||||
|
icon_type: appIcon.type,
|
||||||
|
icon: appIcon.type === 'image' ? appIcon.fileId : appIcon.icon,
|
||||||
|
icon_background: appIcon.type === 'image' ? undefined : appIcon.background,
|
||||||
|
icon_url: appIcon.type === 'image' ? appIcon.url : undefined,
|
||||||
|
},
|
||||||
|
doc_form: ChunkingMode.text,
|
||||||
|
permission,
|
||||||
|
}
|
||||||
|
// Handle permission
|
||||||
|
if (request.permission === DatasetPermission.partialMembers) {
|
||||||
|
const selectedMemberList = selectedMemberIDs.map((id) => {
|
||||||
|
return {
|
||||||
|
user_id: id,
|
||||||
|
role: memberList.find(member => member.id === id)?.role,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
request.partial_member_list = selectedMemberList
|
||||||
|
}
|
||||||
|
await createEmptyDataset(request, {
|
||||||
|
onSettled: () => {
|
||||||
|
onClose?.()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [createEmptyDataset, memberList, onClose])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isShow={show}
|
||||||
|
onClose={onClose}
|
||||||
|
className='max-w-[520px] p-0'
|
||||||
|
>
|
||||||
|
<CreateForm
|
||||||
|
onCreate={handleCreate}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreateFromScratchModal
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
import Button from '@/app/components/base/button'
|
||||||
|
import { RiAddLine, RiArrowRightUpLine, RiMoreFill } from '@remixicon/react'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Operations from './operations'
|
||||||
|
import CustomPopover from '@/app/components/base/popover'
|
||||||
|
|
||||||
|
type ActionsProps = {
|
||||||
|
handleApplyTemplate: () => void
|
||||||
|
handleShowTemplateDetails: () => void
|
||||||
|
showMoreOperations: boolean
|
||||||
|
openEditModal: () => void
|
||||||
|
handleExportDSL: () => void
|
||||||
|
handleDelete: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Actions = ({
|
||||||
|
handleApplyTemplate,
|
||||||
|
handleShowTemplateDetails,
|
||||||
|
showMoreOperations,
|
||||||
|
openEditModal,
|
||||||
|
handleExportDSL,
|
||||||
|
handleDelete,
|
||||||
|
}: ActionsProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='absolute bottom-0 left-0 z-10 hidden w-full items-center gap-x-1 bg-pipeline-template-card-hover-bg p-4 pt-8 group-hover:flex'>
|
||||||
|
<Button
|
||||||
|
variant='primary'
|
||||||
|
onClick={handleApplyTemplate}
|
||||||
|
className='grow gap-x-0.5'
|
||||||
|
>
|
||||||
|
<RiAddLine className='size-4' />
|
||||||
|
<span className='px-0.5'>{t('datasetPipeline.operations.choose')}</span>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant='secondary'
|
||||||
|
onClick={handleShowTemplateDetails}
|
||||||
|
className='grow gap-x-0.5'
|
||||||
|
>
|
||||||
|
<RiArrowRightUpLine className='size-4' />
|
||||||
|
<span className='px-0.5'>{t('datasetPipeline.operations.details')}</span>
|
||||||
|
</Button>
|
||||||
|
{
|
||||||
|
showMoreOperations && (
|
||||||
|
<CustomPopover
|
||||||
|
htmlContent={
|
||||||
|
<Operations
|
||||||
|
openEditModal={openEditModal}
|
||||||
|
onExport={handleExportDSL}
|
||||||
|
onDelete={handleDelete}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
className={'z-20 min-w-[160px]'}
|
||||||
|
popupClassName={'rounded-xl bg-none shadow-none ring-0 min-w-[160px]'}
|
||||||
|
position='br'
|
||||||
|
trigger='click'
|
||||||
|
btnElement={
|
||||||
|
<RiMoreFill className='size-4 text-text-tertiary' />
|
||||||
|
}
|
||||||
|
btnClassName='size-8 cursor-pointer justify-center rounded-lg p-0 shadow-xs shadow-shadow-shadow-3'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Actions)
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
import Modal from '@/app/components/base/modal'
|
||||||
|
import CreateForm from '../../create-form'
|
||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
import type { CreateFormData } from '@/models/pipeline'
|
||||||
|
import { ChunkingMode, type CreateDatasetReq, DatasetPermission } from '@/models/datasets'
|
||||||
|
import { useCreatePipelineDataset } from '@/service/knowledge/use-create-dataset'
|
||||||
|
import type { Member } from '@/models/common'
|
||||||
|
import { useMembers } from '@/service/use-common'
|
||||||
|
|
||||||
|
type ApplyTemplateModalProps = {
|
||||||
|
show: boolean
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const ApplyTemplateModal = ({
|
||||||
|
show,
|
||||||
|
onClose,
|
||||||
|
}: ApplyTemplateModalProps) => {
|
||||||
|
const [memberList, setMemberList] = useState<Member[]>([])
|
||||||
|
const { data: members } = useMembers()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (members?.accounts)
|
||||||
|
setMemberList(members.accounts)
|
||||||
|
}, [members])
|
||||||
|
|
||||||
|
const { mutateAsync: createEmptyDataset } = useCreatePipelineDataset() // todo: yaml content
|
||||||
|
|
||||||
|
const handleCreate = useCallback(async (payload: CreateFormData) => {
|
||||||
|
const { name, appIcon, description, permission, selectedMemberIDs } = payload
|
||||||
|
const request: CreateDatasetReq = {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
icon_info: {
|
||||||
|
icon_type: appIcon.type,
|
||||||
|
icon: appIcon.type === 'image' ? appIcon.fileId : appIcon.icon,
|
||||||
|
icon_background: appIcon.type === 'image' ? undefined : appIcon.background,
|
||||||
|
icon_url: appIcon.type === 'image' ? appIcon.url : undefined,
|
||||||
|
},
|
||||||
|
doc_form: ChunkingMode.text,
|
||||||
|
permission,
|
||||||
|
}
|
||||||
|
// Handle permission
|
||||||
|
if (request.permission === DatasetPermission.partialMembers) {
|
||||||
|
const selectedMemberList = selectedMemberIDs.map((id) => {
|
||||||
|
return {
|
||||||
|
user_id: id,
|
||||||
|
role: memberList.find(member => member.id === id)?.role,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
request.partial_member_list = selectedMemberList
|
||||||
|
}
|
||||||
|
await createEmptyDataset(request, {
|
||||||
|
onSettled: () => {
|
||||||
|
onClose?.()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [createEmptyDataset, memberList, onClose])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isShow={show}
|
||||||
|
onClose={onClose}
|
||||||
|
className='max-w-[520px] p-0'
|
||||||
|
>
|
||||||
|
<CreateForm
|
||||||
|
onCreate={handleCreate}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ApplyTemplateModal
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import AppIcon from '@/app/components/base/app-icon'
|
||||||
|
import { General } from '@/app/components/base/icons/src/public/knowledge/dataset-card'
|
||||||
|
import type { ChunkingMode, IconInfo } from '@/models/datasets'
|
||||||
|
import { DOC_FORM_ICON_WITH_BG, DOC_FORM_TEXT } from '@/models/datasets'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
type ContentProps = {
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
iconInfo: IconInfo
|
||||||
|
docForm: ChunkingMode
|
||||||
|
}
|
||||||
|
|
||||||
|
const Content = ({
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
iconInfo,
|
||||||
|
docForm,
|
||||||
|
}: ContentProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const Icon = DOC_FORM_ICON_WITH_BG[docForm] || General
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className='flex items-center gap-x-3 p-4 pb-2'>
|
||||||
|
<div className='relative shrink-0'>
|
||||||
|
<AppIcon
|
||||||
|
size='large'
|
||||||
|
iconType={iconInfo.icon_type}
|
||||||
|
icon={iconInfo.icon}
|
||||||
|
background={iconInfo.icon_type === 'image' ? undefined : iconInfo.icon_background}
|
||||||
|
imageUrl={iconInfo.icon_type === 'image' ? iconInfo.icon_url : undefined}
|
||||||
|
/>
|
||||||
|
<div className='absolute -bottom-1 -right-1 z-10'>
|
||||||
|
<Icon className='size-4' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex grow flex-col gap-y-1 py-px'>
|
||||||
|
<div
|
||||||
|
className='system-md-semibold truncate text-text-secondary'
|
||||||
|
title={name}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</div>
|
||||||
|
<div className='system-2xs-medium-uppercase text-text-tertiary'>
|
||||||
|
{t(`dataset.chunkingMode.${DOC_FORM_TEXT[docForm]}`)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
className='system-xs-regular line-clamp-3 grow px-4 py-1 text-text-tertiary'
|
||||||
|
title={description}
|
||||||
|
>
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Content)
|
||||||
Loading…
Reference in New Issue