feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type FooterControlsProps,
|
||||
type UploadConfig,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useImageDisplayAnnotationStepCheck } from '@/hooks/common';
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import { ImageFileAddStep } from './types';
|
||||
import { createImageFileAddStore, type ImageFileAddStore } from './store';
|
||||
import { ImageUpload } from './steps/upload';
|
||||
import { ImageProcess } from './steps/process';
|
||||
import { ImageAnnotation } from './steps/annotation';
|
||||
|
||||
export const ImageFileAddConfig: UploadConfig<
|
||||
ImageFileAddStep,
|
||||
ImageFileAddStore
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
title: I18n.t('knowledge_photo_006'),
|
||||
step: ImageFileAddStep.Upload,
|
||||
content: props => (
|
||||
<ImageUpload
|
||||
{...props}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: I18n.t('knowledge_photo_007'),
|
||||
step: ImageFileAddStep.Annotation,
|
||||
content: props => (
|
||||
<ImageAnnotation
|
||||
{...props}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: I18n.t('db_table_0126_015'),
|
||||
step: ImageFileAddStep.Process,
|
||||
content: props => (
|
||||
<ImageProcess
|
||||
{...props}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
createStore: createImageFileAddStore,
|
||||
useUploadMount: store => useImageDisplayAnnotationStepCheck(),
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { ImageFileAddConfig } from './config';
|
||||
@@ -0,0 +1,125 @@
|
||||
/* stylelint-disable max-nesting-depth */
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
.segment-radio-wrapper {
|
||||
.displayNone {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.custom-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.form-segment {
|
||||
margin-top: 33px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
|
||||
margin-bottom: 8px;
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: var(--coz-fg-primary);
|
||||
}
|
||||
|
||||
.label-red::after {
|
||||
content: "*";
|
||||
margin-left: 4px;
|
||||
font-weight: 600;
|
||||
color: var(--coz-fg-hglt-red);
|
||||
}
|
||||
|
||||
.custom-input {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
&::before {
|
||||
content: '';
|
||||
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin-top: 26px;
|
||||
|
||||
background: var(--light-usage-border-color-border,
|
||||
rgb(28 31 35 / 8%));
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-radioGroup.semi-radioGroup-vertical {
|
||||
row-gap: 16px;
|
||||
}
|
||||
|
||||
.semi-radioGroup {
|
||||
.semi-radio-content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.custom-wrapper {
|
||||
padding-bottom: 0;
|
||||
|
||||
.semi-input-default,
|
||||
.semi-input-wrapper-focus {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup {
|
||||
padding: 16px 16px 16px 19px;
|
||||
border: 1px solid var(--coz-stroke-plus);
|
||||
border-radius: 8px;
|
||||
|
||||
&:hover {
|
||||
background: var(--coz-mg-secondary-hovered);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--coz-mg-secondary-pressed);
|
||||
}
|
||||
|
||||
.semi-radio-extra {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup_checked {
|
||||
background: var(--coz-mg-hglt);
|
||||
border: 1px solid var(--coz-stroke-hglt);
|
||||
|
||||
&:hover {
|
||||
background: var(--coz-mg-hglt-hovered);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--coz-mg-hglt-pressed);
|
||||
}
|
||||
}
|
||||
|
||||
.semi-radio-addon {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.semi-form-field-label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.semi-checkboxGroup-vertical {
|
||||
row-gap: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useMemo, type FC } from 'react';
|
||||
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Radio, RadioGroup } from '@coze-arch/coze-design';
|
||||
|
||||
import { ImageAnnotationType, ImageFileAddStep } from '../../types';
|
||||
import { type ImageFileAddStore } from '../../store';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const ImageAnnotation: FC<ContentProps<ImageFileAddStore>> = props => {
|
||||
const { useStore, footer } = props;
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
const annotationType = useStore(state => state.annotationType);
|
||||
const setAnnotationType = useStore(state => state.setAnnotationType);
|
||||
|
||||
const buttonStatus = useMemo(() => {
|
||||
if (!annotationType) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}, [annotationType]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles['segment-radio-wrapper']}>
|
||||
<RadioGroup
|
||||
type="pureCard"
|
||||
onChange={e => {
|
||||
setAnnotationType(e.target.value as ImageAnnotationType);
|
||||
}}
|
||||
direction="vertical"
|
||||
value={annotationType}
|
||||
>
|
||||
<Radio
|
||||
data-testid={KnowledgeE2e.ImageAnnotationAiRadio}
|
||||
value={ImageAnnotationType.Auto}
|
||||
extra={I18n.t('knowledge_photo_009')}
|
||||
>
|
||||
{I18n.t('knowledge_photo_008')}
|
||||
</Radio>
|
||||
<Radio
|
||||
data-testid={KnowledgeE2e.ImageAnnotationManualRadio}
|
||||
value={ImageAnnotationType.Manual}
|
||||
extra={I18n.t('knowledge_photo_011')}
|
||||
>
|
||||
{I18n.t('knowledge_photo_010')}
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
{footer?.([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
onClick: () => setCurrentStep(ImageFileAddStep.Upload),
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
status: buttonStatus,
|
||||
onClick: () => {
|
||||
setCurrentStep(ImageFileAddStep.Process);
|
||||
},
|
||||
},
|
||||
])}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
.footer-sub-tip {
|
||||
font-size: 12px;
|
||||
color: var(--light-usage-text-color-text-2, rgb(28 31 35 / 60%));
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, type FC } from 'react';
|
||||
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import { type ContentProps } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { getKnowledgeIDEQuery } from '@coze-data/knowledge-common-services';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import {
|
||||
CaptionType,
|
||||
DocumentSource,
|
||||
FormatType,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { reportProcessDocumentFail } from '@/utils/common';
|
||||
import { getProcessingDescMsg } from '@/utils';
|
||||
import { useCreateDocument } from '@/hooks';
|
||||
import { UnitProgress } from '@/components';
|
||||
|
||||
import { ImageAnnotationType } from '../../types';
|
||||
import { type ImageFileAddStore } from '../../store';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const ImageProcess: FC<ContentProps<ImageFileAddStore>> = props => {
|
||||
const { useStore, footer } = props;
|
||||
|
||||
const resourceNavigate = useDataNavigate();
|
||||
|
||||
const params = useKnowledgeParams();
|
||||
|
||||
const unitList = useStore(state => state.unitList);
|
||||
const annotationType = useStore(state => state.annotationType);
|
||||
const progressList = useStore(state => state.progressList);
|
||||
const createStatus = useStore(state => state.createStatus);
|
||||
|
||||
const createDocument = useCreateDocument(useStore, {
|
||||
onSuccess: docRes => {
|
||||
const documentInfos = docRes.document_infos ?? [];
|
||||
reportProcessDocumentFail(
|
||||
documentInfos,
|
||||
REPORT_EVENTS.KnowledgeProcessDocument,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
createDocument({
|
||||
format_type: FormatType.Image,
|
||||
chunk_strategy: {
|
||||
caption_type:
|
||||
annotationType === ImageAnnotationType.Manual
|
||||
? CaptionType.Manual
|
||||
: CaptionType.Auto,
|
||||
},
|
||||
document_bases: unitList.map(item => ({
|
||||
name: item.name,
|
||||
source_info: {
|
||||
tos_uri: item.uri,
|
||||
document_source: DocumentSource.Document,
|
||||
},
|
||||
})),
|
||||
});
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<UnitProgress progressList={progressList} createStatus={createStatus} />
|
||||
{footer?.({
|
||||
btns: [
|
||||
{
|
||||
e2e: KnowledgeE2e.CreateUnitConfirmBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('variable_reset_yes'),
|
||||
onClick: () => {
|
||||
const query = getKnowledgeIDEQuery() as Record<string, string>;
|
||||
resourceNavigate.toResource?.(
|
||||
'knowledge',
|
||||
params.datasetID,
|
||||
query,
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
prefix: (
|
||||
<span className={styles['footer-sub-tip']}>
|
||||
{getProcessingDescMsg(createStatus)}
|
||||
</span>
|
||||
),
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useMemo, type FC } from 'react';
|
||||
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
UploadStatus,
|
||||
type UnitItem,
|
||||
UnitType,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Toast } from '@coze-arch/coze-design';
|
||||
|
||||
import { UploadUnitFile, UploadUnitTable } from '@/components';
|
||||
|
||||
import { ImageFileAddStep } from '../../types';
|
||||
import { type ImageFileAddStore } from '../../store';
|
||||
import { useRetry } from './use-retry';
|
||||
|
||||
export const ImageUpload: FC<ContentProps<ImageFileAddStore>> = props => {
|
||||
const { useStore, footer } = props;
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
const unitList = useStore(state => state.unitList);
|
||||
const setUnitList = useStore(state => state.setUnitList);
|
||||
|
||||
const onRetry = useRetry({ unitList, setUnitList });
|
||||
|
||||
const buttonStatus = useMemo(() => {
|
||||
if (
|
||||
unitList.length === 0 ||
|
||||
unitList.some(
|
||||
unitItem =>
|
||||
unitItem.name.length === 0 ||
|
||||
unitItem.status !== UploadStatus.SUCCESS,
|
||||
)
|
||||
) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}, [unitList]);
|
||||
|
||||
const hideUploadFile = false;
|
||||
const AddUnitMaxLimit = 300;
|
||||
|
||||
const handleClickNext = () => {
|
||||
setCurrentStep(ImageFileAddStep.Annotation);
|
||||
};
|
||||
|
||||
const handleUnitListUpdate = (data: UnitItem[]) => {
|
||||
const result = data;
|
||||
setUnitList(result);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<UploadUnitFile
|
||||
action=""
|
||||
accept={'.png,.jpg,.jpeg,.webp'}
|
||||
dragMainText={I18n.t('knowledge_photo_004')}
|
||||
dragSubText={I18n.t('knowledge_photo_005')}
|
||||
limit={AddUnitMaxLimit}
|
||||
unitList={unitList}
|
||||
multiple={AddUnitMaxLimit > 1}
|
||||
style={hideUploadFile ? { visibility: 'hidden', height: 0 } : undefined}
|
||||
setUnitList={handleUnitListUpdate}
|
||||
onFinish={handleUnitListUpdate}
|
||||
maxSizeMB={20}
|
||||
onSizeError={file =>
|
||||
Toast.error(
|
||||
I18n.t('photo-size-limit', {
|
||||
fileName: file.name,
|
||||
}),
|
||||
)
|
||||
}
|
||||
/>
|
||||
{unitList.length > 0 ? (
|
||||
<div className="mt-[25px] mb-[25px] overflow-y-auto">
|
||||
<UploadUnitTable
|
||||
type={UnitType.IMAGE_FILE}
|
||||
edit={true}
|
||||
unitList={unitList}
|
||||
onChange={setUnitList}
|
||||
onRetry={onRetry}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{footer?.([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
status: buttonStatus,
|
||||
onClick: handleClickNext,
|
||||
},
|
||||
])}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import { type UnitItem } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { FileBizType } from '@coze-arch/bot-api/developer_api';
|
||||
import { DeveloperApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { transformUnitList, getFileExtension, getBase64 } from '@/utils';
|
||||
|
||||
export const useRetry = (params: {
|
||||
unitList: UnitItem[];
|
||||
setUnitList: (unitList: UnitItem[]) => void;
|
||||
}) => {
|
||||
const { unitList, setUnitList } = params;
|
||||
|
||||
const onRetry = async (record: UnitItem, index: number) => {
|
||||
try {
|
||||
const { fileInstance } = record;
|
||||
if (fileInstance) {
|
||||
const { name } = fileInstance;
|
||||
const extension = getFileExtension(name);
|
||||
const base64 = await getBase64(fileInstance);
|
||||
const result = await DeveloperApi.UploadFile({
|
||||
file_head: {
|
||||
file_type: extension,
|
||||
biz_type: FileBizType.BIZ_BOT_DATASET,
|
||||
},
|
||||
data: base64,
|
||||
});
|
||||
|
||||
setUnitList(
|
||||
transformUnitList({
|
||||
unitList,
|
||||
data: result?.data,
|
||||
fileInstance,
|
||||
index,
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
const error = e as Error;
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeUploadFile,
|
||||
error,
|
||||
});
|
||||
}
|
||||
};
|
||||
return onRetry;
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
import {
|
||||
CreateUnitStatus,
|
||||
type UploadBaseAction,
|
||||
type UploadBaseState,
|
||||
type ProgressItem,
|
||||
type UnitItem,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
import { ImageAnnotationType, ImageFileAddStep } from '../types';
|
||||
|
||||
export type ImageFileAddStore = UploadBaseState<ImageFileAddStep> &
|
||||
UploadBaseAction<ImageFileAddStep> & {
|
||||
annotationType: ImageAnnotationType;
|
||||
setAnnotationType: (annotationType: ImageAnnotationType) => void;
|
||||
};
|
||||
|
||||
const storeStaticValues: Pick<
|
||||
ImageFileAddStore,
|
||||
| 'unitList'
|
||||
| 'currentStep'
|
||||
| 'annotationType'
|
||||
| 'createStatus'
|
||||
| 'progressList'
|
||||
> = {
|
||||
currentStep: ImageFileAddStep.Upload,
|
||||
unitList: [],
|
||||
annotationType: ImageAnnotationType.Auto,
|
||||
createStatus: CreateUnitStatus.UPLOAD_UNIT,
|
||||
progressList: [],
|
||||
};
|
||||
|
||||
export const createImageFileAddStore = () =>
|
||||
create<ImageFileAddStore>()(
|
||||
devtools((set, get, store) => ({
|
||||
...storeStaticValues,
|
||||
setCurrentStep: (currentStep: ImageFileAddStep) => {
|
||||
set({ currentStep });
|
||||
},
|
||||
setUnitList: (unitList: UnitItem[]) => {
|
||||
set({ unitList });
|
||||
},
|
||||
setAnnotationType: (annotationType: ImageAnnotationType) => {
|
||||
set({ annotationType });
|
||||
},
|
||||
setCreateStatus: (createStatus: CreateUnitStatus) => {
|
||||
set({ createStatus });
|
||||
},
|
||||
setProgressList: (progressList: ProgressItem[]) => {
|
||||
set({ progressList });
|
||||
},
|
||||
reset: () => {
|
||||
set(storeStaticValues);
|
||||
},
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export enum ImageFileAddStep {
|
||||
Upload = 0,
|
||||
Annotation,
|
||||
Process,
|
||||
}
|
||||
|
||||
export enum ImageAnnotationType {
|
||||
Auto = 'auto',
|
||||
Manual = 'manual',
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadConfig,
|
||||
type FooterControlsProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import { useTableCheck } from '../../hooks';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
import { type TableLocalContentProps } from './types';
|
||||
import { createTableCustomAddStore } from './store';
|
||||
import { TableCustomCreate } from './steps';
|
||||
import { TableCustomStep, TABLE_CUSTOM_WRAPPER_CLASS_NAME } from './constant';
|
||||
|
||||
export const TableCustomAddConfig: UploadConfig<
|
||||
TableCustomStep,
|
||||
UploadTableAction<TableCustomStep> & UploadTableState<TableCustomStep>
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableCustomCreate
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step2'),
|
||||
step: TableCustomStep.CREATE,
|
||||
},
|
||||
],
|
||||
createStore: createTableCustomAddStore,
|
||||
showStep: false,
|
||||
className: TABLE_CUSTOM_WRAPPER_CLASS_NAME,
|
||||
useUploadMount: store => useTableCheck(store),
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** table-custom add steps */
|
||||
export enum TableCustomStep {
|
||||
CREATE,
|
||||
}
|
||||
|
||||
export const TABLE_CUSTOM_WRAPPER_CLASS_NAME = 'table-custom-wrapper';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableCustomAddConfig } from './config';
|
||||
@@ -0,0 +1,12 @@
|
||||
.create-table-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.add-column-button {
|
||||
width: 114px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import {
|
||||
FooterBtnStatus,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Tooltip } from '@coze-arch/bot-semi';
|
||||
import { type DocTableColumn } from '@coze-arch/bot-api/memory';
|
||||
import { DocumentSource, FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
import { IconCozPlus } from '@coze-arch/coze-design/icons';
|
||||
import { Button } from '@coze-arch/coze-design';
|
||||
|
||||
import { type AddCustomTableMeta } from '@/types';
|
||||
import { useCreateDocumentReq } from '@/services';
|
||||
import { getCustomStatus } from '@/features/knowledge-type/table/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import { MAX_TABLE_META_COLUMN_LEN } from '@/constants';
|
||||
import { TableStructure, TableStructureTitle } from '@/components';
|
||||
|
||||
import styles from './create-v2.module.less';
|
||||
|
||||
function getCreateDocumentParams(
|
||||
metaData: AddCustomTableMeta & { key?: string; id?: string },
|
||||
isAppend: boolean,
|
||||
) {
|
||||
return {
|
||||
document_bases: [
|
||||
{
|
||||
name: '', // table custom传控
|
||||
source_info: {
|
||||
document_source: DocumentSource.Custom,
|
||||
},
|
||||
table_meta: metaData.map((meta, index) => ({
|
||||
column_name: meta.column_name,
|
||||
is_semantic: meta.is_semantic,
|
||||
column_type: meta.column_type,
|
||||
desc: meta.desc,
|
||||
sequence: index.toString(),
|
||||
})),
|
||||
},
|
||||
],
|
||||
format_type: FormatType.Table,
|
||||
is_append: isAppend,
|
||||
};
|
||||
}
|
||||
export const TableCustomCreate = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { footer, useStore } = props;
|
||||
const params = useKnowledgeParams();
|
||||
|
||||
const resourceNavigate = useDataNavigate();
|
||||
|
||||
const { datasetID: knowledgeId } = params;
|
||||
const [footerStatus, setFooterStatus] = useState(FooterBtnStatus.ENABLE);
|
||||
const currentUuid = nanoid();
|
||||
const [metaData, setMetaData] = useState<AddCustomTableMeta>([
|
||||
{
|
||||
id: currentUuid,
|
||||
key: currentUuid,
|
||||
column_name: '',
|
||||
is_semantic: false,
|
||||
},
|
||||
]);
|
||||
const documentList = useStore(state => state.documentList) ?? [];
|
||||
const isAppend = documentList.length !== 0;
|
||||
|
||||
const createDocument = useCreateDocumentReq({
|
||||
onSuccess: () => {
|
||||
setFooterStatus(FooterBtnStatus.ENABLE);
|
||||
resourceNavigate.toResource?.('knowledge', knowledgeId);
|
||||
},
|
||||
onFail: () => {
|
||||
setFooterStatus(FooterBtnStatus.DISABLE);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (footerStatus !== FooterBtnStatus.LOADING) {
|
||||
setFooterStatus(getCustomStatus(metaData, 'toBeDelete')); // toBeDelete 待删
|
||||
}
|
||||
}, [metaData]);
|
||||
|
||||
const TooltipWrapper = ({ children }: { children: JSX.Element }) => {
|
||||
if (metaData.length >= MAX_TABLE_META_COLUMN_LEN) {
|
||||
return (
|
||||
<Tooltip trigger="hover" content={I18n.t('knowledge_1222_01')}>
|
||||
{children}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return <>{children}</>;
|
||||
};
|
||||
return (
|
||||
<div className={styles['create-table-wrapper']}>
|
||||
<TableStructureTitle />
|
||||
<TableStructure
|
||||
initValid
|
||||
isDragTable
|
||||
data={metaData}
|
||||
setData={setMetaData as (v: Array<DocTableColumn>) => void}
|
||||
/>
|
||||
<TooltipWrapper>
|
||||
<Button
|
||||
data-testid={KnowledgeE2e.TableCustomUAddFieldBtn}
|
||||
className={styles['add-column-button']}
|
||||
type="tertiary"
|
||||
disabled={metaData.length >= MAX_TABLE_META_COLUMN_LEN}
|
||||
onClick={() => {
|
||||
const curUuid = nanoid();
|
||||
setMetaData(
|
||||
metaData.concat({
|
||||
id: curUuid,
|
||||
key: curUuid,
|
||||
column_name: '',
|
||||
is_semantic: false,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
block={false}
|
||||
icon={<IconCozPlus />}
|
||||
>
|
||||
{I18n.t('datasets_segment_tableStructure_add_field')}
|
||||
</Button>
|
||||
</TooltipWrapper>
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.CreateUnitConfirmBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('variable_reset_yes'),
|
||||
onClick: () => {
|
||||
setFooterStatus(FooterBtnStatus.LOADING);
|
||||
createDocument(getCreateDocumentParams(metaData, isAppend));
|
||||
},
|
||||
status: footerStatus,
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type TableLocalContentProps } from '../../types';
|
||||
import { TableCustomCreate as TableCustomCreateV2 } from './create-v2';
|
||||
|
||||
/** 到时候要删掉 TableCustomCreateV1*/
|
||||
export const TableCustomCreate = (props: TableLocalContentProps) => (
|
||||
<TableCustomCreateV2 {...props} />
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableCustomCreate } from './create';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableCustomCreate } from './create';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { createTableCustomAddStore } from './store';
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type StateCreator } from 'zustand';
|
||||
|
||||
import {
|
||||
createTableSlice,
|
||||
getDefaultState,
|
||||
} from '@/features/knowledge-type/table/slice';
|
||||
import type {
|
||||
UploadTableAction,
|
||||
UploadTableState,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import { DEFAULT_TABLE_SETTINGS_FROM_ZERO } from '@/constants';
|
||||
|
||||
export const createTableCustomSlice: StateCreator<
|
||||
UploadTableState<number> & UploadTableAction<number>
|
||||
> = (set, get, store) => ({
|
||||
...createTableSlice(set, get, store),
|
||||
tableSettings: DEFAULT_TABLE_SETTINGS_FROM_ZERO,
|
||||
reset: () => {
|
||||
set({
|
||||
...getDefaultState(),
|
||||
tableSettings: DEFAULT_TABLE_SETTINGS_FROM_ZERO,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
|
||||
import { type TableCustomStep } from '../constant';
|
||||
import { createTableCustomSlice } from './slice';
|
||||
|
||||
export const createTableCustomAddStore = () =>
|
||||
create<
|
||||
UploadTableState<TableCustomStep> & UploadTableAction<TableCustomStep>
|
||||
>()(
|
||||
devtools((set, get, store) => ({
|
||||
...createTableCustomSlice(set, get, store),
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type ContentProps } from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
import { type TableCustomStep } from './constant';
|
||||
|
||||
export type TableLocalContentProps = ContentProps<
|
||||
UploadTableAction<TableCustomStep> & UploadTableState<TableCustomStep>
|
||||
>;
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadConfig,
|
||||
type FooterControlsProps,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
import { createTableCustomIncrementalStore } from './store';
|
||||
import { TableUpload } from './steps';
|
||||
import { TableCustomIncrementalStep } from './constants';
|
||||
|
||||
type TableCustomContentProps = ContentProps<
|
||||
UploadTableAction<TableCustomIncrementalStep> &
|
||||
UploadTableState<TableCustomIncrementalStep>
|
||||
>;
|
||||
|
||||
export const TableCustomIncrementalConfig: UploadConfig<
|
||||
TableCustomIncrementalStep,
|
||||
UploadTableAction<TableCustomIncrementalStep> &
|
||||
UploadTableState<TableCustomIncrementalStep>
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
content: (props: TableCustomContentProps) => (
|
||||
<TableUpload
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step2'),
|
||||
step: TableCustomIncrementalStep.UPLOAD,
|
||||
},
|
||||
],
|
||||
createStore: createTableCustomIncrementalStore,
|
||||
className: 'table-custom-increment-wrapper',
|
||||
showStep: false,
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export enum TableCustomIncrementalStep {
|
||||
UPLOAD,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableCustomIncrementalConfig } from './config';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableUpload } from './upload';
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useCallback, useRef, useState, useEffect } from 'react';
|
||||
|
||||
import { type TableDataItem } from '@coze-data/knowledge-modal-base';
|
||||
import { type TableViewRecord } from '@coze-common/table-view';
|
||||
import { type DocTableColumn } from '@coze-arch/bot-api/memory';
|
||||
|
||||
import { transformTableData } from './utils';
|
||||
|
||||
interface UseTableOperationsParams {
|
||||
initialData?: TableViewRecord[];
|
||||
createTableSegment?: () => void;
|
||||
editTableSegment?: (data: string | TableDataItem[]) => void;
|
||||
}
|
||||
function useTableOperations({
|
||||
initialData = [],
|
||||
editTableSegment,
|
||||
}: UseTableOperationsParams) {
|
||||
const [tableData, setTableData] = useState<TableViewRecord[]>(initialData);
|
||||
const tableDataRef = useRef<TableViewRecord[]>(initialData);
|
||||
const sheetStructureRef = useRef<DocTableColumn[]>([]);
|
||||
const [editItemIndex, setEditItemIndex] = useState<number>(-1);
|
||||
|
||||
const handleCellUpdate = useCallback(
|
||||
(_record: TableViewRecord, index: number) => {
|
||||
setTableData(prevData =>
|
||||
prevData.map((item, i) => {
|
||||
if (i === index) {
|
||||
return { ...item, ..._record };
|
||||
}
|
||||
return item;
|
||||
}),
|
||||
);
|
||||
},
|
||||
[tableData],
|
||||
);
|
||||
const handleDel = useCallback(
|
||||
(indexList: (string | number)[]) => {
|
||||
const currentTableData = tableDataRef.current;
|
||||
const newTableData = [...currentTableData];
|
||||
indexList.forEach(index => {
|
||||
newTableData.splice(Number(index), 1);
|
||||
});
|
||||
setTableData(newTableData);
|
||||
},
|
||||
[tableDataRef.current],
|
||||
);
|
||||
|
||||
const handleEdit = useCallback(
|
||||
(record: TableViewRecord, index: string | number) => {
|
||||
const currentTableData = tableDataRef.current;
|
||||
setEditItemIndex(Number(index));
|
||||
const curTableItem = currentTableData[Number(index)];
|
||||
const curTableItemKeys = Object.keys(curTableItem);
|
||||
const editTableData = curTableItemKeys.map(key => {
|
||||
const sItem = sheetStructureRef.current.find(
|
||||
item => item.column_name === key,
|
||||
);
|
||||
return {
|
||||
column_name: sItem?.column_name || '',
|
||||
column_id: sItem?.id || '',
|
||||
is_semantic: Boolean(sItem?.is_semantic),
|
||||
value: curTableItem[key] as string,
|
||||
};
|
||||
});
|
||||
editTableSegment?.(editTableData);
|
||||
},
|
||||
[sheetStructureRef.current, tableDataRef.current],
|
||||
);
|
||||
const handleAdd = useCallback(() => {
|
||||
const tableDataItem = transformTableData<DocTableColumn>(
|
||||
sheetStructureRef.current,
|
||||
'column_name',
|
||||
);
|
||||
const currentTableData = tableDataRef.current;
|
||||
setTableData([...currentTableData, ...tableDataItem]);
|
||||
}, [tableDataRef.current]);
|
||||
|
||||
useEffect(() => {
|
||||
tableDataRef.current = tableData;
|
||||
}, [tableData]);
|
||||
|
||||
return {
|
||||
editItemIndex,
|
||||
tableData,
|
||||
setTableData,
|
||||
handleCellUpdate,
|
||||
handleAdd,
|
||||
handleDel,
|
||||
handleEdit,
|
||||
tableDataRef,
|
||||
sheetStructureRef,
|
||||
};
|
||||
}
|
||||
|
||||
export default useTableOperations;
|
||||
@@ -0,0 +1,121 @@
|
||||
/* stylelint-disable no-duplicate-selectors */
|
||||
/* stylelint-disable declaration-no-important */
|
||||
/* stylelint-disable max-nesting-depth */
|
||||
.structure-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
margin-bottom: 10px;
|
||||
|
||||
&-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
line-height: 20px;
|
||||
color: var(--coz-fg-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-table-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.unit-table-container {
|
||||
border: 1px solid var(--coz-stroke-primary);
|
||||
border-radius: 8px;
|
||||
|
||||
.unit-table-view {
|
||||
min-height: 90px;
|
||||
max-height: 540px;
|
||||
|
||||
:global {
|
||||
.semi-table-wrapper {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.coz-tag.coz-tag-primary {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.semi-table-thead>.semi-table-row>.semi-table-row-head {
|
||||
border-bottom: 1px solid var(--coz-stroke-primary);
|
||||
}
|
||||
|
||||
.semi-table-header {
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
.semi-table-row {
|
||||
&:last-child {
|
||||
.semi-table-row-cell {
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.semi-table-row:hover>.semi-table-row-cell:first-child {
|
||||
border-top-left-radius: 0 !important;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
}
|
||||
|
||||
.semi-table-row:hover>.semi-table-row-cell:last-child {
|
||||
border-top-right-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
.semi-table-body {
|
||||
max-height: 499px !important;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-view-title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.semantic-tag {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.unit-table-empty {
|
||||
height: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-toolbar {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.spin {
|
||||
:global {
|
||||
.semi-spin-wrapper {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.semi-tabs-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.semi-spin-children {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-sub-tip {
|
||||
font-size: 12px;
|
||||
color: var(--coz-fg-primary);
|
||||
}
|
||||
|
||||
.column-type {
|
||||
margin-left: 6px;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableUpload } from './upload';
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable @coze-arch/max-line-per-function */
|
||||
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import { type ContentProps } from '@coze-data/knowledge-resource-processor-core';
|
||||
import {
|
||||
type TableDataItem,
|
||||
useTableSegmentModal,
|
||||
ModalActionType,
|
||||
transSliceContentOutput,
|
||||
} from '@coze-data/knowledge-modal-base';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import {
|
||||
TableView,
|
||||
type TableViewColumns,
|
||||
type TableViewRecord,
|
||||
} from '@coze-common/table-view';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Spin } from '@coze-arch/bot-semi';
|
||||
import { type DocTableColumn } from '@coze-arch/bot-api/memory';
|
||||
import { ColumnType } from '@coze-arch/bot-api/memory';
|
||||
import {
|
||||
DocumentSource,
|
||||
type DocumentInfo,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
import { IconCozPlus } from '@coze-arch/coze-design/icons';
|
||||
import { Button } from '@coze-arch/coze-design';
|
||||
|
||||
import { getAddSegmentParams } from '@/features/knowledge-type/table/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import {
|
||||
useFetchAddSegmentReq,
|
||||
useFetchListDocumentReq,
|
||||
useFetchTableInfoReq,
|
||||
} from '@/features/knowledge-type/table/hooks';
|
||||
import { TableStatus } from '@/constants';
|
||||
|
||||
import {
|
||||
getSubmitBtnStatus,
|
||||
tableDataCleaning,
|
||||
transformTableData,
|
||||
} from './utils';
|
||||
import useTableOperations from './hooks';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
interface StructureBarProps {
|
||||
docTitle: string;
|
||||
}
|
||||
|
||||
const StructureBar = ({ docTitle }: StructureBarProps) => (
|
||||
<div
|
||||
className={styles['structure-bar']}
|
||||
data-testid={KnowledgeE2e.IncrementTableUploadStructureTitle}
|
||||
>
|
||||
<div className={styles['structure-bar-title']}>{docTitle}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
interface TableContainerProps {
|
||||
loading: boolean;
|
||||
tableData: TableViewRecord[];
|
||||
columns: TableViewColumns[];
|
||||
handleAdd: () => void;
|
||||
handleDel: (indexList: (string | number)[]) => void;
|
||||
handleEdit: (record: TableViewRecord, index: string | number) => void;
|
||||
}
|
||||
const TableContainer = ({
|
||||
loading,
|
||||
tableData,
|
||||
columns,
|
||||
handleAdd,
|
||||
handleDel,
|
||||
handleEdit,
|
||||
}: TableContainerProps) => (
|
||||
<>
|
||||
<div className={`${styles['unit-table-container']} `}>
|
||||
<Spin
|
||||
spinning={loading}
|
||||
wrapperClassName={styles.spin}
|
||||
size="large"
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
>
|
||||
{tableData.length ? (
|
||||
<TableView
|
||||
className={`${styles['unit-table-view']} `}
|
||||
dataSource={tableData}
|
||||
columns={columns}
|
||||
rowOperation
|
||||
editProps={{
|
||||
onDelete: handleDel,
|
||||
onEdit: handleEdit,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className={styles['unit-table-empty']}></div>
|
||||
)}
|
||||
</Spin>
|
||||
</div>
|
||||
<div className={`${styles['footer-toolbar']} `}>
|
||||
<Button
|
||||
data-testid={KnowledgeE2e.IncrementTableUploadStructureAddBtn}
|
||||
className={styles['structure-bar-button']}
|
||||
type="tertiary"
|
||||
onClick={() => {
|
||||
handleAdd();
|
||||
}}
|
||||
icon={<IconCozPlus />}
|
||||
>
|
||||
{I18n.t('knowledge_custom_add_content')}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
export const TableUpload = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>({
|
||||
useStore,
|
||||
footer,
|
||||
}: ContentProps<T>) => {
|
||||
const params = useKnowledgeParams();
|
||||
const { docID, spaceID, datasetID } = params;
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
const tableStatus = useStore(state => state.status);
|
||||
|
||||
const [columns, setColumns] = useState<TableViewColumns[]>([]);
|
||||
const [docInfo, setDocInfo] = useState<DocumentInfo>({});
|
||||
const tableContainerRef = useRef<HTMLDivElement | null>(null);
|
||||
const tableMetaRef = useRef<DocTableColumn[]>([]);
|
||||
|
||||
const docTitle = useMemo(() => docInfo?.name || '', [docInfo]);
|
||||
const { node: TableSegmentModalNode, edit: editTableSegment } =
|
||||
useTableSegmentModal({
|
||||
title: I18n.t('knowledg_table_segments_content'),
|
||||
meta: tableMetaRef.current || [],
|
||||
onFinish: (actionType, data) => {
|
||||
const curTableItem = transformTableData<TableDataItem>(
|
||||
data,
|
||||
'column_name',
|
||||
'value',
|
||||
);
|
||||
const hasEdit = actionType === ModalActionType.Edit;
|
||||
if (hasEdit) {
|
||||
handleCellUpdate(curTableItem[0], editItemIndex);
|
||||
} else {
|
||||
const newTableData = [...tableData, ...curTableItem];
|
||||
setTableData(newTableData);
|
||||
}
|
||||
},
|
||||
});
|
||||
const {
|
||||
editItemIndex,
|
||||
tableData,
|
||||
setTableData,
|
||||
sheetStructureRef,
|
||||
handleCellUpdate,
|
||||
handleDel,
|
||||
handleEdit,
|
||||
handleAdd,
|
||||
} = useTableOperations({
|
||||
editTableSegment,
|
||||
});
|
||||
|
||||
const fetchTableInfo = useFetchTableInfoReq(
|
||||
res => {
|
||||
const {
|
||||
tableColumns,
|
||||
tableData: sTableData,
|
||||
sheetStructure: tableSchema,
|
||||
} = tableDataCleaning({
|
||||
data: res,
|
||||
tableContainerRef,
|
||||
handleCellUpdate,
|
||||
handleEdit,
|
||||
handleDel,
|
||||
});
|
||||
if (tableColumns.length > 0) {
|
||||
setColumns(tableColumns);
|
||||
}
|
||||
if (sTableData.length > 0) {
|
||||
setTableData(sTableData);
|
||||
}
|
||||
|
||||
if (tableSchema.length > 0) {
|
||||
tableMetaRef.current = tableSchema;
|
||||
sheetStructureRef.current = tableSchema;
|
||||
}
|
||||
setStatus(TableStatus.NORMAL);
|
||||
},
|
||||
() => {
|
||||
setStatus(TableStatus.NORMAL);
|
||||
},
|
||||
);
|
||||
|
||||
const resourceNavigate = useDataNavigate();
|
||||
const { fetchAddSegment, addSegmentLoading } = useFetchAddSegmentReq(res => {
|
||||
resourceNavigate.toResource?.('knowledge', datasetID);
|
||||
});
|
||||
|
||||
const fetchDocumentInfo = useFetchListDocumentReq(setDocInfo);
|
||||
useEffect(() => {
|
||||
if (docID) {
|
||||
setStatus(TableStatus.LOADING);
|
||||
fetchDocumentInfo();
|
||||
fetchTableInfo({
|
||||
document_id: docID,
|
||||
});
|
||||
}
|
||||
}, [docID]);
|
||||
|
||||
function handleSaveTableData() {
|
||||
if (!spaceID || !datasetID || !docID) {
|
||||
return;
|
||||
}
|
||||
const imageKeys: string[] = [];
|
||||
columns.forEach(col => {
|
||||
if (col.columnType === ColumnType.Image) {
|
||||
imageKeys.push(col.id as string);
|
||||
}
|
||||
});
|
||||
const formatData = tableData.map(data =>
|
||||
Object.fromEntries(
|
||||
Object.entries(data).map(([key, value]) => {
|
||||
if (imageKeys.includes(key)) {
|
||||
return [key, transSliceContentOutput(value as string)];
|
||||
}
|
||||
return [key, value];
|
||||
}),
|
||||
),
|
||||
);
|
||||
const documentInfo = [
|
||||
{
|
||||
source_info: {
|
||||
document_source: DocumentSource.Custom,
|
||||
custom_content: JSON.stringify(formatData),
|
||||
},
|
||||
table_sheet: {
|
||||
sheet_id: '0',
|
||||
header_line_idx: '0',
|
||||
start_line_idx: '0',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const payload = getAddSegmentParams({
|
||||
spaceId: spaceID,
|
||||
docId: docID,
|
||||
datasetId: datasetID,
|
||||
documentInfo,
|
||||
});
|
||||
fetchAddSegment(payload);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={tableContainerRef}
|
||||
className={classNames(
|
||||
'custom-table-container',
|
||||
styles['custom-table-container'],
|
||||
)}
|
||||
>
|
||||
<StructureBar docTitle={docTitle} />
|
||||
<TableContainer
|
||||
loading={tableStatus === TableStatus.LOADING}
|
||||
columns={columns}
|
||||
tableData={tableData}
|
||||
handleAdd={handleAdd}
|
||||
handleDel={handleDel}
|
||||
handleEdit={handleEdit}
|
||||
/>
|
||||
{TableSegmentModalNode}
|
||||
|
||||
{footer
|
||||
? footer({
|
||||
prefix: (
|
||||
<span className={styles['footer-sub-tip']}>
|
||||
{I18n.t('knowledge_table_custom_submit_tips')}
|
||||
</span>
|
||||
),
|
||||
btns: [
|
||||
{
|
||||
e2e: KnowledgeE2e.CreateUnitConfirmBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('variable_reset_yes'),
|
||||
onClick: () => {
|
||||
handleSaveTableData();
|
||||
},
|
||||
status: getSubmitBtnStatus(
|
||||
sheetStructureRef.current,
|
||||
tableData,
|
||||
addSegmentLoading,
|
||||
),
|
||||
},
|
||||
],
|
||||
})
|
||||
: null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { getDataTypeText } from '@coze-data/utils';
|
||||
import { FooterBtnStatus } from '@coze-data/knowledge-resource-processor-core';
|
||||
import {
|
||||
TextRender,
|
||||
type TableViewRecord,
|
||||
ImageRender,
|
||||
ActionsRender,
|
||||
} from '@coze-common/table-view';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { type ColumnProps } from '@coze-arch/bot-semi/Table';
|
||||
import { Typography } from '@coze-arch/bot-semi';
|
||||
import {
|
||||
type DocTableColumn,
|
||||
type GetDocumentTableInfoResponse,
|
||||
ColumnType,
|
||||
} from '@coze-arch/bot-api/memory';
|
||||
import { Tag } from '@coze-arch/coze-design';
|
||||
|
||||
import { getSrcFromImg } from '@/utils/table';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
const MAX_WIDTH = 1400;
|
||||
const MIN_WIDTH = 200;
|
||||
const DIFF_WIDTH = 397;
|
||||
|
||||
export function transformTableData<T>(
|
||||
tableColumns: T[],
|
||||
indexName: string,
|
||||
valueName?: string,
|
||||
) {
|
||||
const tableDataItem: Record<string, string> = {};
|
||||
tableColumns.forEach(column => {
|
||||
const key = column[indexName as keyof T] as string;
|
||||
const value = valueName ? (column[valueName as keyof T] as string) : '';
|
||||
tableDataItem[key] = value;
|
||||
});
|
||||
|
||||
return [tableDataItem];
|
||||
}
|
||||
|
||||
export interface TableDataCleaningParams {
|
||||
data: GetDocumentTableInfoResponse;
|
||||
handleEdit: (record: TableViewRecord, index: number) => void;
|
||||
handleDel: (indexList: number[]) => void;
|
||||
handleCellUpdate: (record: TableViewRecord, index: number) => void;
|
||||
tableContainerRef: React.RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
const ColumnTypeComp = (props: { columnType: ColumnType }) => (
|
||||
<Tag color="primary" className={styles['column-type']}>
|
||||
{getDataTypeText(props.columnType)}
|
||||
</Tag>
|
||||
);
|
||||
|
||||
export function tableDataCleaning({
|
||||
data,
|
||||
handleEdit,
|
||||
handleDel,
|
||||
handleCellUpdate,
|
||||
tableContainerRef,
|
||||
}: TableDataCleaningParams) {
|
||||
const defaultData = {
|
||||
sheetStructure: [],
|
||||
tableColumns: [],
|
||||
tableData: [],
|
||||
};
|
||||
|
||||
if (!data) {
|
||||
return defaultData;
|
||||
}
|
||||
const { table_meta, sheet_list } = data;
|
||||
|
||||
if (!table_meta || !Object.keys(table_meta).length || !sheet_list?.length) {
|
||||
return defaultData;
|
||||
}
|
||||
|
||||
const curSubSheet = sheet_list[0];
|
||||
const curSheetStructure = table_meta[curSubSheet?.id ?? ''] || [];
|
||||
const dom = tableContainerRef.current;
|
||||
const maxWidth = dom ? dom.offsetWidth - DIFF_WIDTH : MAX_WIDTH;
|
||||
|
||||
const dataWidth =
|
||||
maxWidth / curSheetStructure.length > MIN_WIDTH
|
||||
? maxWidth / curSheetStructure.length
|
||||
: MIN_WIDTH;
|
||||
const tableColumns: ColumnProps[] = curSheetStructure.map(column => ({
|
||||
id: column.column_name,
|
||||
dataIndex: column.column_name,
|
||||
columnType: column.column_type,
|
||||
title: (
|
||||
<div className={styles['table-view-title']}>
|
||||
<Typography.Text
|
||||
className={styles['table-view-title-content']}
|
||||
ellipsis={{
|
||||
showTooltip: {
|
||||
opts: { content: column.column_name },
|
||||
},
|
||||
}}
|
||||
>
|
||||
{column.column_name}
|
||||
</Typography.Text>
|
||||
{column.is_semantic ? (
|
||||
<Tag color="green" className={styles['semantic-tag']}>
|
||||
{I18n.t('knowledge_1226_001')}
|
||||
</Tag>
|
||||
) : null}
|
||||
{column.column_type ? (
|
||||
<ColumnTypeComp columnType={column.column_type}></ColumnTypeComp>
|
||||
) : null}
|
||||
</div>
|
||||
),
|
||||
width: dataWidth,
|
||||
render: (text: string, record: TableViewRecord, index: number) => {
|
||||
if (column.column_type === ColumnType.Image) {
|
||||
const srcList = getSrcFromImg(
|
||||
record?.[column?.column_name as string] as string,
|
||||
);
|
||||
return (
|
||||
<ImageRender
|
||||
srcList={srcList}
|
||||
onChange={(src, tosKey) => {
|
||||
let val = '';
|
||||
if (src || tosKey) {
|
||||
val = `<img src="${src ?? ''}" ${
|
||||
tosKey ? `data-tos-key="${tosKey}"` : ''
|
||||
}>`;
|
||||
}
|
||||
const newRecord = {
|
||||
...record,
|
||||
[column?.column_name as string]: val,
|
||||
};
|
||||
handleCellUpdate(newRecord, index);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TextRender
|
||||
dataIndex={column.column_name}
|
||||
value={text}
|
||||
record={record}
|
||||
index={index}
|
||||
editable
|
||||
validator={{
|
||||
validate: value => {
|
||||
if (column.is_semantic) {
|
||||
return !value || value === '';
|
||||
}
|
||||
return false;
|
||||
},
|
||||
errorMsg: I18n.t('datasets_url_empty'),
|
||||
}}
|
||||
onBlur={async (_text, updateRecord) =>
|
||||
await handleCellUpdate(updateRecord, index)
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}));
|
||||
|
||||
// 增加操作列
|
||||
tableColumns.push({
|
||||
title: <></>,
|
||||
width: 100,
|
||||
dataIndex: 'actions',
|
||||
className: styles['unit-actions-column'],
|
||||
fixed: 'right',
|
||||
render: (_text, record, index) => (
|
||||
<ActionsRender
|
||||
record={record}
|
||||
index={index}
|
||||
editProps={{
|
||||
disabled: false,
|
||||
onEdit: () => {
|
||||
handleEdit?.(record, index);
|
||||
},
|
||||
}}
|
||||
deleteProps={{
|
||||
disabled: false,
|
||||
onDelete: () => {
|
||||
handleDel?.([index]);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
||||
const tableDataItem = transformTableData<DocTableColumn>(
|
||||
curSheetStructure,
|
||||
'column_name',
|
||||
);
|
||||
|
||||
return {
|
||||
sheetStructure: curSheetStructure,
|
||||
tableColumns,
|
||||
tableData: tableDataItem,
|
||||
};
|
||||
}
|
||||
|
||||
export function getSubmitBtnStatus(
|
||||
sheetStructure: DocTableColumn[],
|
||||
tableData: TableViewRecord[],
|
||||
loading?: boolean,
|
||||
) {
|
||||
if (loading) {
|
||||
return FooterBtnStatus.LOADING;
|
||||
}
|
||||
const semanticItem = sheetStructure.find(item => item.is_semantic);
|
||||
if (!semanticItem) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
|
||||
const semanticItemName = semanticItem?.column_name;
|
||||
if (!semanticItemName) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
|
||||
if (!tableData.length) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
|
||||
const hasSemanticItemNull = tableData.some(
|
||||
item => item && item[semanticItemName] === '',
|
||||
);
|
||||
|
||||
if (hasSemanticItemNull) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
|
||||
import { createTableSlice } from '../../../slice';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
import { type TableCustomIncrementalStep } from './constants';
|
||||
|
||||
export const createTableCustomIncrementalStore = () =>
|
||||
create<
|
||||
UploadTableState<TableCustomIncrementalStep> &
|
||||
UploadTableAction<TableCustomIncrementalStep>
|
||||
>()(
|
||||
devtools((set, get, store) => ({
|
||||
...createTableSlice(set, get, store),
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableCustomAddConfig } from './add/config';
|
||||
export { TableCustomIncrementalConfig } from './incremental/config';
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { type StoreApi, type UseBoundStore } from 'zustand';
|
||||
import { useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
|
||||
import { useListDocumentReq } from '@/services';
|
||||
|
||||
import { type UploadTableAction, type UploadTableState } from '../interface';
|
||||
|
||||
export const useTableCheck = (
|
||||
store: UseBoundStore<
|
||||
StoreApi<UploadTableState<number> & UploadTableAction<number>>
|
||||
>,
|
||||
) => {
|
||||
const params = useKnowledgeParams();
|
||||
const setDocumentList = store(state => state.setDocumentList);
|
||||
|
||||
const listDocument = useListDocumentReq(res => {
|
||||
const { document_infos = [] } = res;
|
||||
setDocumentList && setDocumentList(document_infos);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
listDocument({
|
||||
dataset_id: params.datasetID ?? '',
|
||||
document_ids: params.docID ? [params.docID] : undefined,
|
||||
});
|
||||
}, []);
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { useTableCheck } from './hooks';
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadConfig,
|
||||
type FooterControlsProps,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import { TableLocalStep } from '../constants';
|
||||
import { useTableCheck } from '../../hooks';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
import { createTableLocalAddStore } from './store';
|
||||
import {
|
||||
TableUpload,
|
||||
TableConfiguration,
|
||||
TablePreview,
|
||||
TableProcessing,
|
||||
} from './steps';
|
||||
|
||||
type TableLocalContentProps = ContentProps<
|
||||
UploadTableAction<TableLocalStep> & UploadTableState<TableLocalStep>
|
||||
>;
|
||||
|
||||
export const TableLocalAddConfig: UploadConfig<
|
||||
TableLocalStep,
|
||||
UploadTableAction<TableLocalStep> & UploadTableState<TableLocalStep>
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableUpload
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step2'),
|
||||
step: TableLocalStep.UPLOAD,
|
||||
},
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableConfiguration
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_tab_step2'),
|
||||
step: TableLocalStep.CONFIGURATION,
|
||||
},
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TablePreview
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_tab_step3'),
|
||||
step: TableLocalStep.PREVIEW,
|
||||
},
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableProcessing
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step4'),
|
||||
step: TableLocalStep.PROCESSING,
|
||||
},
|
||||
],
|
||||
createStore: createTableLocalAddStore,
|
||||
className: 'table-local-wrapper',
|
||||
useUploadMount: store => useTableCheck(store),
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableLocalAddConfig } from './config';
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { IllustrationNoResult } from '@douyinfe/semi-illustrations';
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { UIEmpty } from '@coze-arch/bot-semi';
|
||||
import { TableDataType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { useOptFromQuery, tableSettingsToString } from '@/utils';
|
||||
import {
|
||||
isConfigurationLoading as isLoadingFunc,
|
||||
isConfigurationError as isErrorFunc,
|
||||
isConfigurationShowBanner as isShowBannerFunc,
|
||||
getConfigurationMeta,
|
||||
getConfigurationNextStatus,
|
||||
semanticValidator,
|
||||
} from '@/features/knowledge-type/table/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import {
|
||||
useChangeTableSettingsNl2ql,
|
||||
useFetchTableSchemaInfo,
|
||||
} from '@/features/knowledge-type/table/hooks';
|
||||
import { TableSettingFormFields } from '@/constants';
|
||||
import {
|
||||
TableStructure as TableStructureInternal,
|
||||
TableSettingBar,
|
||||
ConfigurationLoading,
|
||||
ConfigurationError,
|
||||
ConfigurationBanner,
|
||||
} from '@/components';
|
||||
|
||||
import { useUploadFetchTableParams } from '../services';
|
||||
import { TableLocalStep } from '../../../constants';
|
||||
|
||||
export const TableConfiguration = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
/** common action */
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
|
||||
/** table store*/
|
||||
const status = useStore(state => state.status);
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const originTableData = useStore(state => state.originTableData);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
const semanticValidate = useStore(state => state.semanticValidate);
|
||||
/** table action*/
|
||||
const setTableData = useStore(state => state.setTableData);
|
||||
const setSemanticValidate = useStore(state => state.setSemanticValidate);
|
||||
|
||||
/** compute action */
|
||||
const opt = useOptFromQuery();
|
||||
const isLoading = isLoadingFunc(status);
|
||||
const isError = isErrorFunc(status);
|
||||
const isShowBanner = isShowBannerFunc(opt, tableData, tableSettings);
|
||||
const currentMeta = getConfigurationMeta(tableData, tableSettings);
|
||||
const meta = currentMeta.map((item, index) => ({
|
||||
...item,
|
||||
key: index + item.column_name,
|
||||
}));
|
||||
|
||||
/** events action */
|
||||
const onChangeTableSettings = useChangeTableSettingsNl2ql(useStore);
|
||||
/** network action */
|
||||
const fetchTableParams = useUploadFetchTableParams(useStore);
|
||||
const fetchTableInfo = useFetchTableSchemaInfo<T>(useStore);
|
||||
const getContent = () => {
|
||||
if (isLoading) {
|
||||
return <ConfigurationLoading />;
|
||||
}
|
||||
if (isError) {
|
||||
return (
|
||||
<ConfigurationError
|
||||
fetchTableInfo={() => {
|
||||
fetchTableInfo({
|
||||
source_file: fetchTableParams,
|
||||
table_data_type: TableDataType.AllData,
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<TableStructureInternal
|
||||
tipsNode={
|
||||
<>
|
||||
{isShowBanner ? <ConfigurationBanner /> : null}
|
||||
{!meta.length || isEmpty(originTableData) ? (
|
||||
<UIEmpty
|
||||
empty={{
|
||||
title: I18n.t('knowledge_1221_02'),
|
||||
icon: <IllustrationNoResult></IllustrationNoResult>,
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
}
|
||||
showTitle
|
||||
initValid
|
||||
isDragTable
|
||||
baseKey={`${tableSettings[TableSettingFormFields.SHEET]}.${
|
||||
tableSettings[TableSettingFormFields.KEY_START_ROW]
|
||||
}.`}
|
||||
data={meta}
|
||||
verifyMap={
|
||||
semanticValidate[tableSettings[TableSettingFormFields.SHEET]] || {}
|
||||
}
|
||||
setData={v => {
|
||||
const curSheet = tableSettings[TableSettingFormFields.SHEET];
|
||||
const newData = {
|
||||
...tableData,
|
||||
table_meta: {
|
||||
...tableData.table_meta,
|
||||
[curSheet]: v,
|
||||
},
|
||||
};
|
||||
setTableData(newData);
|
||||
setSemanticValidate(semanticValidator(newData));
|
||||
}}
|
||||
loading={isLoading}
|
||||
/>
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.UPLOAD);
|
||||
},
|
||||
status: FooterBtnStatus.ENABLE,
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.PREVIEW);
|
||||
fetchTableInfo({
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
table_data_type: TableDataType.OnlyPreview,
|
||||
source_file: fetchTableParams,
|
||||
origin_table_meta:
|
||||
originTableData?.table_meta?.[tableSettings.sheet_id],
|
||||
preview_table_meta:
|
||||
tableData?.table_meta?.[tableSettings.sheet_id],
|
||||
});
|
||||
},
|
||||
status: getConfigurationNextStatus(tableData, tableSettings),
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableSettingBar
|
||||
data={tableData}
|
||||
tableSettings={tableSettings}
|
||||
setTableSettings={onChangeTableSettings}
|
||||
/>
|
||||
{getContent()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableConfiguration } from './configuration';
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableUpload } from './upload';
|
||||
export { TableConfiguration } from './configuration';
|
||||
export { TablePreview } from './preview';
|
||||
export { TableProcessing } from './processing';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TablePreview } from './preview';
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import { TablePreview as TablePreviewInternal } from '@/components';
|
||||
|
||||
import { TableLocalStep } from '../../../constants';
|
||||
|
||||
export const TablePreview = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
|
||||
/** store */
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TablePreviewInternal data={tableData} settings={tableSettings} />
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.CONFIGURATION);
|
||||
},
|
||||
status: FooterBtnStatus.ENABLE,
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.PROCESSING);
|
||||
},
|
||||
status: FooterBtnStatus.ENABLE,
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableProcessing } from './processing';
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useMemo, useEffect } from 'react';
|
||||
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useCreateDocument } from '@/hooks';
|
||||
import {
|
||||
getDocIdFromProgressList,
|
||||
getConfigurationMeta,
|
||||
getCreateDocumentParams,
|
||||
} from '@/features/knowledge-type/table/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import { UnitProgress } from '@/components';
|
||||
|
||||
export const TableProcessing = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
/** store */
|
||||
const progressList = useStore(state => state.progressList);
|
||||
const unitList = useStore(state => state.unitList);
|
||||
const createStatus = useStore(state => state.createStatus);
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
const meta = getConfigurationMeta(tableData, tableSettings);
|
||||
/** config */
|
||||
const params = useKnowledgeParams();
|
||||
const resourceNavigate = useDataNavigate();
|
||||
const docId = useMemo(
|
||||
() => getDocIdFromProgressList(progressList),
|
||||
[progressList],
|
||||
);
|
||||
const createDocument = useCreateDocument(useStore);
|
||||
useEffect(() => {
|
||||
createDocument(
|
||||
getCreateDocumentParams({
|
||||
isAppend: false,
|
||||
unitList,
|
||||
metaData: meta,
|
||||
tableSettings,
|
||||
}),
|
||||
);
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<UnitProgress progressList={progressList} createStatus={createStatus} />
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.CreateUnitConfirmBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('variable_reset_yes'),
|
||||
onClick: () => {
|
||||
resourceNavigate.toResource?.('knowledge', params.datasetID);
|
||||
},
|
||||
status: docId ? FooterBtnStatus.ENABLE : FooterBtnStatus.DISABLE,
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* service定义:包含业务处理 & 事件
|
||||
*/
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { type StoreApi, type UseBoundStore } from 'zustand';
|
||||
import { get } from 'lodash-es';
|
||||
import { type UnitItem } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { DocumentSource } from '@coze-arch/bot-api/knowledge';
|
||||
import { FileBizType } from '@coze-arch/bot-api/developer_api';
|
||||
import { DeveloperApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { transformUnitList, getFileExtension, getBase64 } from '@/utils';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
|
||||
/** table-local upload 时要用tos_uri 去取table_info */
|
||||
export const useUploadFetchTableParams = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const unitList = useStore(state => state.unitList);
|
||||
return useMemo(
|
||||
() => ({
|
||||
tos_uri: get(unitList, '0.uri', ''),
|
||||
document_source: DocumentSource.Document,
|
||||
}),
|
||||
[unitList],
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* table-local add upload onRetry
|
||||
*/
|
||||
export const useRetry = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const setUnitList = useStore(state => state.setUnitList);
|
||||
const unitList = useStore(state => state.unitList);
|
||||
|
||||
const onRetry = async (record: UnitItem, index: number) => {
|
||||
try {
|
||||
const { fileInstance } = record;
|
||||
if (fileInstance) {
|
||||
const { name } = fileInstance;
|
||||
const extension = getFileExtension(name);
|
||||
const base64 = await getBase64(fileInstance);
|
||||
const result = await DeveloperApi.UploadFile({
|
||||
file_head: {
|
||||
file_type: extension,
|
||||
biz_type: FileBizType.BIZ_BOT_DATASET,
|
||||
},
|
||||
data: base64,
|
||||
});
|
||||
|
||||
setUnitList(
|
||||
transformUnitList({
|
||||
unitList,
|
||||
data: result?.data,
|
||||
fileInstance,
|
||||
index,
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO 加上报
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
return onRetry;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableUpload } from './upload';
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import {
|
||||
UnitType,
|
||||
type UnitItem,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { TableDataType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { tableSettingsToString } from '@/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import {
|
||||
useAcceptFiles,
|
||||
useFetchTableSchemaInfo,
|
||||
} from '@/features/knowledge-type/table/hooks';
|
||||
import { DEFAULT_TABLE_SETTINGS_FROM_ONE, TableStatus } from '@/constants';
|
||||
import { UploadUnitTable, UploadUnitFile } from '@/components';
|
||||
|
||||
import { useRetry, useUploadFetchTableParams } from '../services';
|
||||
import { TableLocalStep } from '../../../constants';
|
||||
import { getNextBtnStatus } from './utils';
|
||||
|
||||
export const TableUpload = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
/** common store */
|
||||
const unitList = useStore(state => state.unitList);
|
||||
/** common action */
|
||||
const setUnitList = useStore(state => state.setUnitList);
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
/** table store */
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
/** table action */
|
||||
const setOriginTableData = useStore(state => state.setOriginTableData);
|
||||
const setTableData = useStore(state => state.setTableData);
|
||||
const setTableSettings = useStore(state => state.setTableSettings);
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
|
||||
/** event action */
|
||||
const onRetry = useRetry(useStore);
|
||||
const params = useUploadFetchTableParams(useStore);
|
||||
const fetchTableInfo = useFetchTableSchemaInfo<T>(useStore);
|
||||
|
||||
useEffect(() => {
|
||||
// 删除上传文件时,同步删除表格源数据
|
||||
if (!unitList.length) {
|
||||
setOriginTableData({});
|
||||
setTableData({});
|
||||
setTableSettings(DEFAULT_TABLE_SETTINGS_FROM_ONE);
|
||||
}
|
||||
}, [unitList.length]);
|
||||
|
||||
const accept = useAcceptFiles();
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
<UploadUnitFile
|
||||
setUnitList={setUnitList}
|
||||
unitList={unitList}
|
||||
onFinish={(list: UnitItem[]) => {
|
||||
setUnitList(list);
|
||||
}}
|
||||
limit={1}
|
||||
accept={accept}
|
||||
dragMainText={I18n.t('datasets_createFileModel_step2_UploadDoc')}
|
||||
dragSubText={I18n.t('datasets_unit_update_exception_tips3')}
|
||||
action={''}
|
||||
style={
|
||||
!unitList.length
|
||||
? {}
|
||||
: {
|
||||
display: 'none',
|
||||
}
|
||||
}
|
||||
showIllustration={false}
|
||||
/>
|
||||
}
|
||||
<div className="upload-unit-table">
|
||||
<UploadUnitTable
|
||||
edit={false}
|
||||
type={UnitType.TABLE_DOC}
|
||||
unitList={unitList}
|
||||
onChange={(list: UnitItem[]) => {
|
||||
setUnitList(list);
|
||||
}}
|
||||
onRetry={onRetry}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.CONFIGURATION);
|
||||
setStatus(TableStatus.LOADING);
|
||||
fetchTableInfo({
|
||||
source_file: params,
|
||||
table_data_type: TableDataType.AllData,
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
});
|
||||
},
|
||||
status: getNextBtnStatus(unitList),
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UnitItem,
|
||||
FooterBtnStatus,
|
||||
UploadStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
export function getNextBtnStatus(unitList: UnitItem[]) {
|
||||
if (
|
||||
unitList.length === 0 ||
|
||||
unitList.some(
|
||||
unitItem =>
|
||||
unitItem.name.length === 0 || unitItem.status !== UploadStatus.SUCCESS,
|
||||
)
|
||||
) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
|
||||
import { type TableLocalStep } from '../constants';
|
||||
import { createTableSlice } from '../../../slice';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
|
||||
export const createTableLocalAddStore = () =>
|
||||
create<
|
||||
UploadTableState<TableLocalStep> & UploadTableAction<TableLocalStep>
|
||||
>()(
|
||||
devtools((set, get, store) => ({
|
||||
...createTableSlice(set, get, store),
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** table-local add and resegment unit steps */
|
||||
export enum TableLocalStep {
|
||||
UPLOAD,
|
||||
CONFIGURATION,
|
||||
PREVIEW,
|
||||
PROCESSING,
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadConfig,
|
||||
type FooterControlsProps,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import { TableLocalStep } from '../constants';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
import { createTableLocalIncrementalStore } from './store';
|
||||
import {
|
||||
TableUpload,
|
||||
TableConfiguration,
|
||||
TablePreview,
|
||||
TableProcessing,
|
||||
} from './steps';
|
||||
|
||||
type TableLocalContentProps = ContentProps<
|
||||
UploadTableAction<TableLocalStep> & UploadTableState<TableLocalStep>
|
||||
>;
|
||||
|
||||
export const TableLocalIncrementalConfig: UploadConfig<
|
||||
TableLocalStep,
|
||||
UploadTableAction<TableLocalStep> & UploadTableState<TableLocalStep>
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableUpload
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step2'),
|
||||
step: TableLocalStep.UPLOAD,
|
||||
},
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableConfiguration
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_tab_step2'),
|
||||
step: TableLocalStep.CONFIGURATION,
|
||||
},
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TablePreview
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_tab_step3'),
|
||||
step: TableLocalStep.PREVIEW,
|
||||
},
|
||||
{
|
||||
content: (props: TableLocalContentProps) => (
|
||||
<TableProcessing
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step4'),
|
||||
step: TableLocalStep.PROCESSING,
|
||||
},
|
||||
],
|
||||
createStore: createTableLocalIncrementalStore,
|
||||
className: 'table-local-wrapper',
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableLocalIncrementalConfig } from './config';
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { IllustrationNoResult } from '@douyinfe/semi-illustrations';
|
||||
import { useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { UIEmpty } from '@coze-arch/bot-semi';
|
||||
import { isApiError } from '@coze-arch/bot-http';
|
||||
import { DocumentSource, TableDataType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { tableSettingsToString } from '@/utils';
|
||||
import {
|
||||
isConfigurationLoading as isLoadingFunc,
|
||||
isConfigurationError as isErrorFunc,
|
||||
getExpandConfigurationMeta,
|
||||
semanticValidator,
|
||||
} from '@/features/knowledge-type/table/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import {
|
||||
useChangeTableSettingsNl2ql,
|
||||
useFetchTableSchemaInfo,
|
||||
useTableSchemaValid,
|
||||
} from '@/features/knowledge-type/table/hooks';
|
||||
import { TableSettingFormFields } from '@/constants';
|
||||
import {
|
||||
TableStructure as TableStructureInternal,
|
||||
TableSettingBar,
|
||||
ConfigurationLoading,
|
||||
ConfigurationError,
|
||||
} from '@/components';
|
||||
|
||||
import { useUploadFetchTableParams } from '../services';
|
||||
import styles from '../index.module.less';
|
||||
import { TableLocalStep } from '../../../constants';
|
||||
|
||||
interface TableHeaderProps {
|
||||
isTableStructureError: boolean;
|
||||
}
|
||||
|
||||
const validErrorCode = '708024073';
|
||||
|
||||
const TableHeader = ({ isTableStructureError }: TableHeaderProps) => (
|
||||
<>
|
||||
<div className={styles['validation-results']}>
|
||||
<div className={styles['validation-item']}></div>
|
||||
<div className={styles['validation-item']}>
|
||||
{isTableStructureError ? (
|
||||
<p className={styles['error-msg']}>
|
||||
{I18n.t('knowledg_table_structure_err_msg')}
|
||||
</p>
|
||||
) : null}
|
||||
<p className={styles.tips}>{I18n.t('knowledg_table_structure_tips')}</p>
|
||||
</div>
|
||||
<div className={styles['validation-item']}></div>
|
||||
</div>
|
||||
<div
|
||||
className={styles['table-structure-title']}
|
||||
data-testid={KnowledgeE2e.TableLocalTableStructureTitle}
|
||||
>
|
||||
{I18n.t('datasets_segment_tableStructure_title')}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @coze-arch/max-line-per-function
|
||||
export const TableConfiguration = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
|
||||
const status = useStore(state => state.status);
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const originTableData = useStore(state => state.originTableData);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
const semanticValidate = useStore(state => state.semanticValidate);
|
||||
const setTableData = useStore(state => state.setTableData);
|
||||
const setSemanticValidate = useStore(state => state.setSemanticValidate);
|
||||
|
||||
const isLoading = isLoadingFunc(status);
|
||||
const [validate, setValidate] = useState(false);
|
||||
const isConfigurationError = isErrorFunc(status);
|
||||
const [isTableStructureError, setIsTableStructureError] = useState(false);
|
||||
const validResultRef = useRef<Record<string, string>>({});
|
||||
const meta = getExpandConfigurationMeta(
|
||||
tableData,
|
||||
tableSettings,
|
||||
validResultRef.current,
|
||||
);
|
||||
const onChangeTableSettings = useChangeTableSettingsNl2ql(useStore);
|
||||
const uploadParams = useUploadFetchTableParams(useStore);
|
||||
const params = useKnowledgeParams();
|
||||
const fetchTableInfo = useFetchTableSchemaInfo<T>(useStore);
|
||||
const tableSchemaValid = useTableSchemaValid(
|
||||
(state, result) => {
|
||||
setIsTableStructureError(!state);
|
||||
setValidate(state);
|
||||
validResultRef.current = result;
|
||||
},
|
||||
err => {
|
||||
if (isApiError(err) && err?.code === validErrorCode) {
|
||||
setIsTableStructureError(true);
|
||||
}
|
||||
setValidate(false);
|
||||
validResultRef.current = {};
|
||||
},
|
||||
);
|
||||
useEffect(() => {
|
||||
if (tableSettings) {
|
||||
setValidate(false);
|
||||
tableSchemaValid({
|
||||
space_id: params.spaceID || '',
|
||||
document_id: params.docID || '',
|
||||
source_file: {
|
||||
tos_uri: uploadParams.tos_uri || '',
|
||||
document_source: DocumentSource.Document,
|
||||
},
|
||||
table_sheet: {
|
||||
sheet_id: tableSettings.sheet_id.toString(),
|
||||
header_line_idx: tableSettings.header_line_idx.toString(),
|
||||
start_line_idx: tableSettings.start_line_idx.toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [tableSettings]);
|
||||
if (isLoading) {
|
||||
return <ConfigurationLoading />;
|
||||
}
|
||||
|
||||
if (isConfigurationError) {
|
||||
return (
|
||||
<ConfigurationError
|
||||
fetchTableInfo={() => {
|
||||
fetchTableInfo({
|
||||
...uploadParams,
|
||||
document_id: params.docID,
|
||||
table_data_type: TableDataType.AllData,
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableSettingBar
|
||||
className={`${styles['table-setting-bar-container']} ${
|
||||
isTableStructureError ? styles['is-error'] : ''
|
||||
}`}
|
||||
data={tableData}
|
||||
tableSettings={tableSettings}
|
||||
setTableSettings={onChangeTableSettings}
|
||||
/>
|
||||
<TableHeader isTableStructureError={isTableStructureError} />
|
||||
{!meta.length || isEmpty(originTableData) ? (
|
||||
<UIEmpty
|
||||
empty={{
|
||||
title: I18n.t('knowledge_1221_02'),
|
||||
icon: <IllustrationNoResult></IllustrationNoResult>,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<TableStructureInternal
|
||||
initValid={false}
|
||||
baseKey={`${tableSettings[TableSettingFormFields.SHEET]}.${
|
||||
tableSettings[TableSettingFormFields.KEY_START_ROW]
|
||||
}.`}
|
||||
data={meta}
|
||||
verifyMap={
|
||||
semanticValidate[tableSettings[TableSettingFormFields.SHEET]] || {}
|
||||
}
|
||||
setData={v => {
|
||||
const curSheet = tableSettings[TableSettingFormFields.SHEET];
|
||||
const newData = {
|
||||
...tableData,
|
||||
table_meta: {
|
||||
...tableData.table_meta,
|
||||
[curSheet]: v,
|
||||
},
|
||||
};
|
||||
setTableData(newData);
|
||||
setSemanticValidate(semanticValidator(newData));
|
||||
}}
|
||||
loading={isLoading}
|
||||
isPreview={true}
|
||||
/>
|
||||
)}
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.UPLOAD);
|
||||
},
|
||||
status: FooterBtnStatus.ENABLE,
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.PREVIEW);
|
||||
fetchTableInfo({
|
||||
table_data_type: TableDataType.OnlyPreview,
|
||||
source_file: uploadParams,
|
||||
document_id: params.docID,
|
||||
origin_table_meta:
|
||||
originTableData?.table_meta?.[tableSettings.sheet_id],
|
||||
preview_table_meta:
|
||||
tableData?.table_meta?.[tableSettings.sheet_id],
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
});
|
||||
},
|
||||
status: validate
|
||||
? FooterBtnStatus.ENABLE
|
||||
: FooterBtnStatus.DISABLE,
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableConfiguration } from './configuration';
|
||||
@@ -0,0 +1,170 @@
|
||||
/* stylelint-disable no-duplicate-selectors */
|
||||
/* stylelint-disable declaration-no-important */
|
||||
/* stylelint-disable max-nesting-depth */
|
||||
/* stylelint-disable font-family-no-missing-generic-family-keyword */
|
||||
.table-structure-title {
|
||||
margin: 12px 0 6px;
|
||||
|
||||
font-family: "PingFang SC";
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
line-height: 20px;
|
||||
color: var(--coz-fg-primary);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.no-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
height: 448px;
|
||||
|
||||
&-tips {
|
||||
margin-top: 16px;
|
||||
|
||||
font-family: "SF Pro Display";
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
line-height: 22px;
|
||||
color: var(--coz-fg-primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line plugin/disallow-first-level-global */
|
||||
:global {
|
||||
.table-local-wrapper {
|
||||
:global {
|
||||
.semi-banner-full .semi-banner-content-wrapper .semi-banner-content {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.select-page-content {
|
||||
.semi-tree-option-expand-icon {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
.expand-placeholder {
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
line-height: 0 !important;
|
||||
}
|
||||
|
||||
.file-selector {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.no-real-expand {
|
||||
margin: 0 8px 0 0 !important;
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 4px;
|
||||
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.file-selector {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 8px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.semi-tree-option-list {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.file-node-row-content {
|
||||
.action-placeholder {
|
||||
width: 0;
|
||||
margin: 0 0 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.footer-sub-tip {
|
||||
font-size: 12px;
|
||||
color: var(--light-usage-text-color-text-2, rgb(28 31 35 / 60%));
|
||||
}
|
||||
|
||||
.table-doc-footer {
|
||||
float: right;
|
||||
margin-top: 40px;
|
||||
|
||||
:global {
|
||||
.semi-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-setting-bar-container {
|
||||
margin-bottom: 0;
|
||||
|
||||
|
||||
&.is-error {
|
||||
:global {
|
||||
[x-field-id="header_line_idx"] {
|
||||
.semi-select {
|
||||
border: 1px solid var(--coz-stroke-hglt-red);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.validation-results {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
.validation-item {
|
||||
flex: 1 1;
|
||||
padding: 0 8px;
|
||||
|
||||
.tips {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: var(--coz-fg-secondary);
|
||||
}
|
||||
|
||||
.error-msg {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: var(--coz-stroke-hglt-red);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableUpload } from './upload';
|
||||
export { TableConfiguration } from './configuration';
|
||||
export { TablePreview } from './preview';
|
||||
export { TableProcessing } from './processing';
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TablePreview } from './preview';
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import { TablePreview as TablePreviewInternal } from '@/components';
|
||||
|
||||
import { TableLocalStep } from '../../../constants';
|
||||
|
||||
export const TablePreview = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
|
||||
/** store */
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
return (
|
||||
<>
|
||||
<TablePreviewInternal data={tableData} settings={tableSettings} />
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.CONFIGURATION);
|
||||
},
|
||||
status: FooterBtnStatus.ENABLE,
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.PROCESSING);
|
||||
},
|
||||
status: FooterBtnStatus.ENABLE,
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableProcessing } from './processing';
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useMemo, useEffect } from 'react';
|
||||
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { DocumentSource } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import {
|
||||
getAddSegmentParams,
|
||||
getDocIdFromProgressList,
|
||||
} from '@/features/knowledge-type/table/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import { useAddSegment } from '@/features/knowledge-type/table/hooks';
|
||||
import { UnitProgress } from '@/components';
|
||||
|
||||
export const TableProcessing = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
/** store */
|
||||
const unitList = useStore(state => state.unitList);
|
||||
const progressList = useStore(state => state.progressList);
|
||||
const createStatus = useStore(state => state.createStatus);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
|
||||
/** config */
|
||||
const params = useKnowledgeParams();
|
||||
const { docID: docIdByQuery, spaceID, datasetID } = params;
|
||||
const resourceNavigate = useDataNavigate();
|
||||
const docId = useMemo(
|
||||
() => getDocIdFromProgressList(progressList),
|
||||
[progressList],
|
||||
);
|
||||
|
||||
const handleAddSegment = useAddSegment(useStore);
|
||||
useEffect(() => {
|
||||
if (
|
||||
!docIdByQuery ||
|
||||
!datasetID ||
|
||||
!spaceID ||
|
||||
!tableSettings ||
|
||||
!unitList
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const payload = getAddSegmentParams({
|
||||
spaceId: spaceID,
|
||||
docId: docIdByQuery,
|
||||
datasetId: datasetID,
|
||||
documentInfo: unitList.map(item => ({
|
||||
name: '', // item.name,
|
||||
source_info: {
|
||||
document_source: DocumentSource.Document,
|
||||
tos_uri: item.uri,
|
||||
},
|
||||
table_sheet: {
|
||||
sheet_id: tableSettings.sheet_id.toString(),
|
||||
header_line_idx: tableSettings.header_line_idx.toString(),
|
||||
start_line_idx: tableSettings.start_line_idx.toString(),
|
||||
},
|
||||
})),
|
||||
});
|
||||
handleAddSegment(payload);
|
||||
}, [tableSettings, unitList]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<UnitProgress progressList={progressList} createStatus={createStatus} />
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.CreateUnitConfirmBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('variable_reset_yes'),
|
||||
onClick: () => {
|
||||
resourceNavigate.toResource?.('knowledge', params.datasetID);
|
||||
},
|
||||
status: docId ? FooterBtnStatus.ENABLE : FooterBtnStatus.DISABLE,
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* service定义:包含业务处理 & 事件
|
||||
*/
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { type StoreApi, type UseBoundStore } from 'zustand';
|
||||
import { get } from 'lodash-es';
|
||||
import { type UnitItem } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { DocumentSource } from '@coze-arch/bot-api/knowledge';
|
||||
import { FileBizType } from '@coze-arch/bot-api/developer_api';
|
||||
import { DeveloperApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { transformUnitList, getFileExtension, getBase64 } from '@/utils';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
|
||||
/** table-local upload 时要用tos_uri 去取table_info */
|
||||
export const useUploadFetchTableParams = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const unitList = useStore(state => state.unitList);
|
||||
return useMemo(
|
||||
() => ({
|
||||
tos_uri: get(unitList, '0.uri', ''),
|
||||
document_source: DocumentSource.Document,
|
||||
}),
|
||||
[unitList],
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* table-local add upload onRetry
|
||||
*/
|
||||
export const useRetry = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const setUnitList = useStore(state => state.setUnitList);
|
||||
const unitList = useStore(state => state.unitList);
|
||||
|
||||
const onRetry = async (record: UnitItem, index: number) => {
|
||||
try {
|
||||
const { fileInstance } = record;
|
||||
if (fileInstance) {
|
||||
const { name } = fileInstance;
|
||||
const extension = getFileExtension(name);
|
||||
const base64 = await getBase64(fileInstance);
|
||||
const result = await DeveloperApi.UploadFile({
|
||||
file_head: {
|
||||
file_type: extension,
|
||||
biz_type: FileBizType.BIZ_BOT_DATASET,
|
||||
},
|
||||
data: base64,
|
||||
});
|
||||
|
||||
setUnitList(
|
||||
transformUnitList({
|
||||
unitList,
|
||||
data: result?.data,
|
||||
fileInstance,
|
||||
index,
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO 加上报
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
return onRetry;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableUpload } from './upload';
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import {
|
||||
UnitType,
|
||||
type UnitItem,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { TableDataType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { useDocIdFromQuery, tableSettingsToString } from '@/utils';
|
||||
import type {
|
||||
UploadTableState,
|
||||
UploadTableAction,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
import {
|
||||
useAcceptFiles,
|
||||
useFetchTableSchemaInfo,
|
||||
} from '@/features/knowledge-type/table/hooks';
|
||||
import { DEFAULT_TABLE_SETTINGS_FROM_ONE, TableStatus } from '@/constants';
|
||||
import { UploadUnitTable, UploadUnitFile } from '@/components';
|
||||
|
||||
import { useRetry, useUploadFetchTableParams } from '../services';
|
||||
import { TableLocalStep } from '../../../constants';
|
||||
import { getButtonStatus } from './utils';
|
||||
|
||||
export const TableUpload = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
|
||||
/** common store */
|
||||
const docId = useDocIdFromQuery();
|
||||
const unitList = useStore(state => state.unitList);
|
||||
/** common action */
|
||||
const setUnitList = useStore(state => state.setUnitList);
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
|
||||
/** table store */
|
||||
const originTableData = useStore(state => state.originTableData);
|
||||
const tableSettings = useStore(state => state.tableSettings);
|
||||
/** table action */
|
||||
const setOriginTableData = useStore(state => state.setOriginTableData);
|
||||
const setTableData = useStore(state => state.setTableData);
|
||||
const setTableSettings = useStore(state => state.setTableSettings);
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
|
||||
/** event action */
|
||||
const onRetry = useRetry(useStore);
|
||||
const params = useUploadFetchTableParams(useStore);
|
||||
const fetchTableInfo = useFetchTableSchemaInfo<T>(useStore);
|
||||
|
||||
useEffect(() => {
|
||||
// 删除上传文件时,同步删除表格源数据
|
||||
if (!unitList.length) {
|
||||
setOriginTableData({});
|
||||
setTableData({});
|
||||
setTableSettings(DEFAULT_TABLE_SETTINGS_FROM_ONE);
|
||||
}
|
||||
}, [unitList.length]);
|
||||
|
||||
const accept = useAcceptFiles();
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
<UploadUnitFile
|
||||
setUnitList={setUnitList}
|
||||
unitList={unitList}
|
||||
onFinish={(list: UnitItem[]) => {
|
||||
setUnitList(list);
|
||||
}}
|
||||
limit={1}
|
||||
accept={accept}
|
||||
dragMainText={I18n.t('datasets_createFileModel_step2_UploadDoc')}
|
||||
dragSubText={
|
||||
<div>
|
||||
<p>{I18n.t('datasets_unit_update_exception_tips3')}</p>
|
||||
<p>{I18n.t('knowledg_table_increment_tips')}</p>
|
||||
</div>
|
||||
}
|
||||
action={''}
|
||||
style={
|
||||
!unitList.length
|
||||
? {}
|
||||
: {
|
||||
display: 'none',
|
||||
}
|
||||
}
|
||||
showIllustration={false}
|
||||
/>
|
||||
}
|
||||
<div className="upload-unit-table">
|
||||
<UploadUnitTable
|
||||
edit={false}
|
||||
type={UnitType.TABLE_DOC}
|
||||
unitList={unitList}
|
||||
onChange={(list: UnitItem[]) => {
|
||||
setUnitList(list);
|
||||
}}
|
||||
canValidator={false}
|
||||
onRetry={onRetry}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{footer
|
||||
? footer([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
onClick: () => {
|
||||
setCurrentStep(TableLocalStep.CONFIGURATION);
|
||||
if (!isEmpty(originTableData)) {
|
||||
return;
|
||||
}
|
||||
setStatus(TableStatus.LOADING);
|
||||
fetchTableInfo({
|
||||
source_file: params,
|
||||
document_id: docId,
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
table_data_type: TableDataType.AllData,
|
||||
});
|
||||
},
|
||||
status: getButtonStatus(unitList),
|
||||
},
|
||||
])
|
||||
: null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UnitItem,
|
||||
FooterBtnStatus,
|
||||
UploadStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
export function getButtonStatus(unitList: UnitItem[]) {
|
||||
if (
|
||||
unitList.length === 0 ||
|
||||
unitList.some(
|
||||
unitItem =>
|
||||
unitItem.name.length === 0 || unitItem.status !== UploadStatus.SUCCESS,
|
||||
)
|
||||
) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
|
||||
import { type TableLocalStep } from '../constants';
|
||||
import { createTableSlice } from '../../../slice';
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../../../interface';
|
||||
|
||||
export const createTableLocalIncrementalStore = () =>
|
||||
create<
|
||||
UploadTableState<TableLocalStep> & UploadTableAction<TableLocalStep>
|
||||
>()(
|
||||
devtools((set, get, store) => ({
|
||||
...createTableSlice(set, get, store),
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TableLocalAddConfig } from './add/config';
|
||||
export { TableLocalIncrementalConfig } from './incremental/config';
|
||||
@@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* pure network request & common services
|
||||
*/
|
||||
// TODO 待解
|
||||
|
||||
import { type StoreApi, type UseBoundStore } from 'zustand';
|
||||
import { debounce, get } from 'lodash-es';
|
||||
import { useRequest } from 'ahooks';
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import {
|
||||
type ProgressItem,
|
||||
CreateUnitStatus,
|
||||
FooterBtnStatus,
|
||||
OptType,
|
||||
UnitType,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { type FormApi } from '@coze-arch/bot-semi/Form';
|
||||
import { useFlags } from '@coze-arch/bot-flags';
|
||||
import { CustomError } from '@coze-arch/bot-error';
|
||||
import { DocumentSourceType, FormatType } from '@coze-arch/bot-api/memory';
|
||||
import type {
|
||||
AssociateFileResponse,
|
||||
DocTableColumn,
|
||||
DocTableSheet,
|
||||
// DocumentTableTaskInfo,
|
||||
FileNode,
|
||||
GetDocumentTableInfoRequest,
|
||||
GetDocumentTableInfoResponse,
|
||||
// GetTableSchemaInfoRequest,
|
||||
} from '@coze-arch/bot-api/memory';
|
||||
import {
|
||||
type GetTableSchemaRequest,
|
||||
TableDataType,
|
||||
DocumentSource,
|
||||
type DocumentInfo,
|
||||
type CreateDocumentRequest,
|
||||
type CreateDocumentResponse,
|
||||
type ValidateTableSchemaRequest,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
import { MemoryApi, KnowledgeApi } from '@coze-arch/bot-api';
|
||||
|
||||
import {
|
||||
isThirdResegment as isThirdResegmentFunc,
|
||||
isIncremental as isIncrementalFunc,
|
||||
} from '@/utils';
|
||||
import { type CustomFormFields } from '@/types/table';
|
||||
import { type TableSettings } from '@/types';
|
||||
import { usePollingTaskProgress } from '@/hooks';
|
||||
import { TABLE_ACCEPT_LOCAL_FILE } from '@/constants/common';
|
||||
import { TableStatus } from '@/constants';
|
||||
|
||||
import {
|
||||
type UploadTableAction,
|
||||
type UploadTableState,
|
||||
} from '../table/interface';
|
||||
import { useUploadFetchTableParams } from '../table/first-party/local/add/steps/services';
|
||||
import { semanticValidator, getCustomStatus } from './utils';
|
||||
|
||||
export interface TableSchemaInfoResponse {
|
||||
code?: number;
|
||||
msg?: string;
|
||||
sheet_list?: DocTableSheet[];
|
||||
table_meta?: Record<string, DocTableColumn[]>;
|
||||
preview_data?: Record<string, Record<number, string>[]>;
|
||||
}
|
||||
|
||||
export interface ThirdTableState {
|
||||
tosUrlRef?: string;
|
||||
fileTreeNodesMap?: Record<string, FileNode[]>;
|
||||
docInfo?: DocumentInfo;
|
||||
fileIdsMap?: AssociateFileResponse['file_mapping'];
|
||||
}
|
||||
export const useFetchTableInfoReq = (
|
||||
onSuccess: (res: TableSchemaInfoResponse) => void,
|
||||
onError: () => void,
|
||||
) => {
|
||||
const { run: fetchTableInfo } = useRequest(
|
||||
async (params: GetDocumentTableInfoRequest) => {
|
||||
const res = await MemoryApi.GetDocumentTableInfo(params);
|
||||
onSuccess(res);
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeGetTableInfo,
|
||||
error: error as Error,
|
||||
});
|
||||
onError();
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
|
||||
return fetchTableInfo;
|
||||
};
|
||||
|
||||
export const useFetchTableSchemaInfoReq = (
|
||||
onSuccess: (res: GetDocumentTableInfoResponse) => void,
|
||||
onError: () => void,
|
||||
) => {
|
||||
const { run: fetchTableInfo } = useRequest(
|
||||
async (params: GetTableSchemaRequest) => {
|
||||
try {
|
||||
const { table_meta, preview_data, ...rest } =
|
||||
await KnowledgeApi.GetTableSchema(params);
|
||||
const updateParams =
|
||||
params?.table_data_type === TableDataType.OnlyPreview
|
||||
? {
|
||||
preview_data: {
|
||||
[`${params.table_sheet?.sheet_id || '0'}`]:
|
||||
preview_data ?? [],
|
||||
},
|
||||
}
|
||||
: {
|
||||
...rest,
|
||||
table_meta: {
|
||||
[`${params.table_sheet?.sheet_id || '0'}`]: table_meta ?? [],
|
||||
},
|
||||
preview_data: {
|
||||
[`${params.table_sheet?.sheet_id || '0'}`]:
|
||||
preview_data ?? [],
|
||||
},
|
||||
};
|
||||
onSuccess(updateParams);
|
||||
} catch (error) {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeGetTableInfo,
|
||||
error: error as Error,
|
||||
});
|
||||
onError();
|
||||
}
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeGetTableInfo,
|
||||
error: error as Error,
|
||||
});
|
||||
onError();
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
return fetchTableInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* 这个方法 所有的table链路都会用到
|
||||
* impure,会改store,因为所有table链路类似,所以放到这里
|
||||
*/
|
||||
export const useFetchTableSchemaInfo = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const setSemanticValidate = useStore(state => state.setSemanticValidate);
|
||||
const setOriginTableData = useStore(state => state.setOriginTableData);
|
||||
const setTableData = useStore(state => state.setTableData);
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
|
||||
return useFetchTableSchemaInfoReq(
|
||||
res => {
|
||||
const isOnlyPreview = !get(res, 'table_meta');
|
||||
const newData = isOnlyPreview
|
||||
? {
|
||||
...tableData,
|
||||
preview_data: get(res, 'preview_data'),
|
||||
}
|
||||
: res;
|
||||
if (!isOnlyPreview) {
|
||||
// 为什么有这个if,因为第一次请求全量,第二次请求isOnlyPreview
|
||||
setOriginTableData(newData);
|
||||
}
|
||||
const validateRes = semanticValidator(newData);
|
||||
setSemanticValidate(validateRes);
|
||||
setTableData(newData);
|
||||
setStatus(TableStatus.NORMAL);
|
||||
},
|
||||
() => {
|
||||
console.log('setStatus(TableStatus.ERROR)');
|
||||
setStatus(TableStatus.ERROR);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
// TODO 待优化,这个函数包含了太多逻辑,非常乱
|
||||
// events action nl2ql链路
|
||||
export const useChangeTableSettingsNl2ql = <
|
||||
T extends UploadTableState<number> &
|
||||
UploadTableAction<number> &
|
||||
ThirdTableState,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const { type, docID, opt } = useKnowledgeParams();
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
const setTableSettings = useStore(state => state.setTableSettings);
|
||||
const fileIdsMap = useStore(state => state.fileIdsMap ?? {});
|
||||
const docInfo = useStore(state => state.docInfo);
|
||||
const tosUrlRef = useStore(state => state.tosUrlRef);
|
||||
const sourceFileId =
|
||||
fileIdsMap[Object.keys(fileIdsMap)?.[0]]?.[0].source_file_id ??
|
||||
docInfo?.source_file_id;
|
||||
const fetchTableInfo = useFetchTableSchemaInfo(useStore);
|
||||
const AWAIT = 500;
|
||||
const params = useUploadFetchTableParams(useStore);
|
||||
|
||||
const isThirdResegment = isThirdResegmentFunc(opt ?? OptType.ADD, type); // 判断是否为三方的resegment
|
||||
const isIncremental = isIncrementalFunc(opt ?? OptType.ADD);
|
||||
|
||||
const onChangeTableSettings = debounce((v: TableSettings) => {
|
||||
setStatus(TableStatus.LOADING);
|
||||
const sourceFile =
|
||||
type &&
|
||||
[UnitType.TABLE_GOOGLE_DRIVE, UnitType.TABLE_FEISHU].includes(type)
|
||||
? {
|
||||
// 飞书需要传 tos_uri
|
||||
tos_uri: type === UnitType.TABLE_FEISHU ? tosUrlRef : undefined,
|
||||
source_file_id: sourceFileId ?? undefined,
|
||||
document_source:
|
||||
type === UnitType.TABLE_GOOGLE_DRIVE
|
||||
? DocumentSource.GoogleDrive
|
||||
: DocumentSource.FeishuWeb,
|
||||
}
|
||||
: params;
|
||||
fetchTableInfo({
|
||||
// 如果为三方的resegment就不传 source_file
|
||||
source_file: isThirdResegment ? undefined : sourceFile,
|
||||
table_sheet:
|
||||
!isIncremental &&
|
||||
get(sourceFile, 'document_source') === DocumentSource.Web
|
||||
? undefined
|
||||
: {
|
||||
sheet_id: String(v.sheet_id),
|
||||
header_line_idx: String(v.header_line_idx),
|
||||
start_line_idx: String(v.start_line_idx),
|
||||
},
|
||||
// 如果为三方的resegment和增量导入,就传 document_id 其他情况不传
|
||||
document_id: isThirdResegment || isIncremental ? docID : undefined,
|
||||
table_data_type: TableDataType.AllData,
|
||||
});
|
||||
setTableSettings(v);
|
||||
}, AWAIT);
|
||||
return onChangeTableSettings;
|
||||
};
|
||||
export const useUpdateDocument = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const tableData = useStore(state => state.tableData);
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
const setCreateStatus = useStore(state => state.setCreateStatus);
|
||||
const setProgressList = useStore(state => state.setProgressList);
|
||||
const pollingTaskProgress = usePollingTaskProgress();
|
||||
const { docID: docIdFromQuery } = useKnowledgeParams();
|
||||
|
||||
const { run: handleUpdateDocument } = useRequest(
|
||||
async () => {
|
||||
try {
|
||||
setStatus(TableStatus.LOADING);
|
||||
await KnowledgeApi.UpdateDocument({
|
||||
document_id: docIdFromQuery,
|
||||
table_meta: tableData.table_meta?.[0],
|
||||
});
|
||||
await pollingTaskProgress(
|
||||
[
|
||||
{
|
||||
document_id: docIdFromQuery,
|
||||
},
|
||||
],
|
||||
{
|
||||
onProgressing: (progressList: ProgressItem[]) => {
|
||||
setProgressList(progressList);
|
||||
},
|
||||
onFinish: () => {
|
||||
setCreateStatus(CreateUnitStatus.TASK_FINISH);
|
||||
},
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeUpdateDocument,
|
||||
error: error as Error,
|
||||
});
|
||||
} finally {
|
||||
setStatus(TableStatus.NORMAL);
|
||||
}
|
||||
},
|
||||
{
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
return handleUpdateDocument;
|
||||
};
|
||||
|
||||
/**
|
||||
* table custom createDocument
|
||||
* TODO 即将废弃,切到新的knowledge信息架构后要删掉
|
||||
* @deprecated
|
||||
* @param setStatus
|
||||
* @param formApi
|
||||
* @returns
|
||||
*/
|
||||
export const useCreateDocument = (
|
||||
setStatus: (v: FooterBtnStatus) => void,
|
||||
formApi: React.MutableRefObject<FormApi<CustomFormFields> | undefined>,
|
||||
) => {
|
||||
const params = useKnowledgeParams();
|
||||
const resourceNavigate = useDataNavigate();
|
||||
const { run: createDocument } = useRequest(
|
||||
async () => {
|
||||
setStatus(FooterBtnStatus.LOADING);
|
||||
const data = formApi?.current?.getValues();
|
||||
const payload = {
|
||||
space_id: params.spaceID,
|
||||
dataset_id: params.datasetID,
|
||||
document: {
|
||||
source_type: DocumentSourceType.Custom,
|
||||
name: data?.unitName,
|
||||
format_type: FormatType.Table,
|
||||
table_meta: (data?.metaData ?? []).map(meta => ({
|
||||
column_name: meta.column_name,
|
||||
is_semantic: meta.is_semantic,
|
||||
column_type: meta.column_type,
|
||||
desc: meta.desc,
|
||||
})),
|
||||
},
|
||||
};
|
||||
const { id } = await MemoryApi.CreateDocument(payload);
|
||||
console.log('doc-id', id);
|
||||
resourceNavigate.toResource?.('knowledge', params.datasetID);
|
||||
setStatus(getCustomStatus(data?.metaData ?? [], data?.unitName ?? ''));
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
const data = formApi?.current?.getValues();
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeCreateDocument,
|
||||
error,
|
||||
});
|
||||
setStatus(getCustomStatus(data?.metaData ?? [], data?.unitName ?? ''));
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
return createDocument;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* table unit name校验
|
||||
* TODO 待删,新链路已经不用,只直接用新的,因为产品功能是新的
|
||||
*/
|
||||
export const useValidateUnitName = () => {
|
||||
const { docID: docIdFromQuery, spaceID, datasetID } = useKnowledgeParams();
|
||||
return async (params: { unit_name: string | string[] }) => {
|
||||
const { unit_name: unitName, ...rest } = params;
|
||||
const unitNameList = unitName instanceof Array ? unitName : [unitName];
|
||||
return Promise.all(
|
||||
unitNameList.map(
|
||||
async (name: string) =>
|
||||
await MemoryApi.ValidateUnitName({
|
||||
space_id: spaceID ?? '',
|
||||
dataset_id: datasetID ?? '',
|
||||
document_id: docIdFromQuery ? docIdFromQuery : undefined,
|
||||
unit_name: name,
|
||||
format_type: FormatType.Table,
|
||||
...rest,
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const useTableSchemaValid = (
|
||||
onSuccess: (res: boolean, validResult: Record<string, string>) => void,
|
||||
onError?: (error: Error) => void,
|
||||
) => {
|
||||
const { run: tableSchemaValid } = useRequest(
|
||||
async (params: ValidateTableSchemaRequest) => {
|
||||
const res = await KnowledgeApi.ValidateTableSchema(params);
|
||||
const validResult = res?.column_valid_result || {};
|
||||
const validResultKeys = Object.keys(validResult);
|
||||
const state = validResultKeys.length === 0 ? res?.code === 0 : false;
|
||||
onSuccess(state, validResult);
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeTableSchemaValid,
|
||||
error: error as Error,
|
||||
});
|
||||
onError?.(error);
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
|
||||
return tableSchemaValid;
|
||||
};
|
||||
|
||||
export const useFetchAddSegmentReq = (
|
||||
onSuccess: (res: CreateDocumentResponse) => void,
|
||||
onError?: () => void,
|
||||
) => {
|
||||
const { run: fetchAddSegment, loading: addSegmentLoading } = useRequest(
|
||||
async (params: CreateDocumentRequest) => {
|
||||
const res = await KnowledgeApi.CreateDocument(params);
|
||||
onSuccess(res);
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeTableAddSegment,
|
||||
error: error as Error,
|
||||
});
|
||||
onError?.();
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
fetchAddSegment,
|
||||
addSegmentLoading,
|
||||
};
|
||||
};
|
||||
|
||||
export const useAddSegment = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
useStore: UseBoundStore<StoreApi<T>>,
|
||||
) => {
|
||||
const setStatus = useStore(state => state.setStatus);
|
||||
const setCreateStatus = useStore(state => state.setCreateStatus);
|
||||
const setProgressList = useStore(state => state.setProgressList);
|
||||
const pollingTaskProgress = usePollingTaskProgress();
|
||||
const { docID: docIdFromQuery } = useKnowledgeParams();
|
||||
|
||||
const { fetchAddSegment } = useFetchAddSegmentReq(
|
||||
async res => {
|
||||
await pollingTaskProgress(
|
||||
[
|
||||
{
|
||||
document_id: docIdFromQuery,
|
||||
},
|
||||
],
|
||||
{
|
||||
onProgressing: (progressList: ProgressItem[]) => {
|
||||
setProgressList(progressList);
|
||||
},
|
||||
onFinish: () => {
|
||||
setCreateStatus(CreateUnitStatus.TASK_FINISH);
|
||||
},
|
||||
},
|
||||
);
|
||||
setStatus(TableStatus.NORMAL);
|
||||
},
|
||||
() => {
|
||||
setStatus(TableStatus.ERROR);
|
||||
},
|
||||
);
|
||||
|
||||
return fetchAddSegment;
|
||||
};
|
||||
|
||||
export const useFetchListDocumentReq = (
|
||||
onSuccess: (res: DocumentInfo) => void,
|
||||
onError?: () => void,
|
||||
) => {
|
||||
const params = useKnowledgeParams();
|
||||
|
||||
const { run: fetchListDocument } = useRequest(
|
||||
async () => {
|
||||
if (!params.datasetID) {
|
||||
throw new CustomError(
|
||||
REPORT_EVENTS.KnowledgeListDocument,
|
||||
`${REPORT_EVENTS.KnowledgeListDocument}: no datasetID`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!params.docID) {
|
||||
throw new CustomError(
|
||||
REPORT_EVENTS.KnowledgeListDocument,
|
||||
`${REPORT_EVENTS.KnowledgeListDocument}: no docId`,
|
||||
);
|
||||
}
|
||||
|
||||
const listDocumentRes = await KnowledgeApi.ListDocument({
|
||||
dataset_id: params.datasetID,
|
||||
document_ids: [params.docID],
|
||||
});
|
||||
|
||||
const docInfo: DocumentInfo =
|
||||
listDocumentRes?.document_infos?.find(
|
||||
i => i.document_id === params.docID,
|
||||
) || {};
|
||||
onSuccess(docInfo);
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeListDocument,
|
||||
error: error as Error,
|
||||
});
|
||||
onError?.();
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
|
||||
return fetchListDocument;
|
||||
};
|
||||
|
||||
export const useAcceptFiles = (): string => {
|
||||
const [FLAGS] = useFlags();
|
||||
|
||||
const accept = TABLE_ACCEPT_LOCAL_FILE.filter(i => {
|
||||
if (!FLAGS['bot.data.knowledge_md_xls']) {
|
||||
return i !== '.xls';
|
||||
}
|
||||
return !!i;
|
||||
}).join(',');
|
||||
|
||||
return accept;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { type UploadTableAction, type UploadTableState } from './interface';
|
||||
export {
|
||||
useFetchTableSchemaInfo,
|
||||
useTableSchemaValid,
|
||||
useAddSegment,
|
||||
useChangeTableSettingsNl2ql,
|
||||
} from './hooks';
|
||||
export {
|
||||
isConfigurationLoading,
|
||||
isConfigurationError,
|
||||
isConfigurationShowBanner,
|
||||
getConfigurationMeta,
|
||||
getConfigurationNextStatus,
|
||||
semanticValidator,
|
||||
getDocIdFromProgressList,
|
||||
getCreateDocumentParams,
|
||||
getExpandConfigurationMeta,
|
||||
getAddSegmentParams,
|
||||
useResegmentFetchTableParams,
|
||||
} from './utils';
|
||||
export { createTableSlice, getDefaultState } from './slice';
|
||||
export { useValidateUnitName } from './hooks';
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadBaseAction,
|
||||
type UploadBaseState,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { type DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import type { SemanticValidate, TableSettings, TableInfo } from '@/types';
|
||||
import { type TableStatus } from '@/constants';
|
||||
|
||||
export interface UploadTableAction<T extends number>
|
||||
extends UploadBaseAction<T> {
|
||||
/** store action */
|
||||
setStatus: (status: TableStatus) => void;
|
||||
setSemanticValidate: (semanticValidate: SemanticValidate) => void;
|
||||
setTableData: (tableData: TableInfo) => void;
|
||||
setOriginTableData: (originTableData: TableInfo) => void;
|
||||
setTableSettings: (tableSettings: TableSettings) => void;
|
||||
setDocumentList?: (documentList: Array<DocumentInfo>) => void;
|
||||
}
|
||||
|
||||
export interface UploadTableState<T extends number> extends UploadBaseState<T> {
|
||||
status: TableStatus;
|
||||
semanticValidate: SemanticValidate;
|
||||
tableData: TableInfo;
|
||||
originTableData: TableInfo;
|
||||
tableSettings: TableSettings;
|
||||
documentList?: Array<DocumentInfo>;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type StateCreator } from 'zustand';
|
||||
import {
|
||||
CreateUnitStatus,
|
||||
type ProgressItem,
|
||||
type UnitItem,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { type DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import type { SemanticValidate, TableInfo, TableSettings } from '@/types';
|
||||
import { TableStatus, DEFAULT_TABLE_SETTINGS_FROM_ONE } from '@/constants';
|
||||
|
||||
import type { UploadTableAction, UploadTableState } from './interface';
|
||||
|
||||
export const getDefaultState = () => ({
|
||||
/** base store */
|
||||
createStatus: CreateUnitStatus.UPLOAD_UNIT,
|
||||
progressList: [],
|
||||
unitList: [],
|
||||
currentStep: 0,
|
||||
/** table store */
|
||||
status: TableStatus.NORMAL,
|
||||
semanticValidate: {},
|
||||
tableData: {},
|
||||
originTableData: {},
|
||||
tableSettings: DEFAULT_TABLE_SETTINGS_FROM_ONE,
|
||||
documentList: [],
|
||||
});
|
||||
|
||||
export const createTableSlice: StateCreator<
|
||||
UploadTableState<number> & UploadTableAction<number>
|
||||
> = (set, get) => ({
|
||||
/** defaultState */
|
||||
...getDefaultState(),
|
||||
|
||||
/** base store action */
|
||||
setCurrentStep: (currentStep: number) => {
|
||||
set({ currentStep });
|
||||
},
|
||||
setCreateStatus: (createStatus: CreateUnitStatus) => {
|
||||
set({ createStatus });
|
||||
},
|
||||
setProgressList: (progressList: ProgressItem[]) => {
|
||||
set({ progressList });
|
||||
},
|
||||
setUnitList: (unitList: UnitItem[]) => {
|
||||
set({ unitList });
|
||||
},
|
||||
|
||||
/** table store action */
|
||||
setStatus: (status: TableStatus) => {
|
||||
set({ status });
|
||||
},
|
||||
setSemanticValidate: (semanticValidate: SemanticValidate) => {
|
||||
set({ semanticValidate });
|
||||
},
|
||||
setTableData: (tableData: TableInfo) => {
|
||||
set({ tableData });
|
||||
},
|
||||
setOriginTableData: (originTableData: TableInfo) => {
|
||||
set({ originTableData });
|
||||
},
|
||||
setTableSettings: (tableSettings: TableSettings) => {
|
||||
set({ tableSettings });
|
||||
},
|
||||
setDocumentList: (documentList: Array<DocumentInfo>) => {
|
||||
set({ documentList });
|
||||
},
|
||||
|
||||
/** reset state */
|
||||
reset: () => {
|
||||
set(getDefaultState());
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { get } from 'lodash-es';
|
||||
import { isFeishuOrLarkDocumentSource } from '@coze-data/utils';
|
||||
import {
|
||||
FooterBtnStatus,
|
||||
UploadStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import type {
|
||||
UnitItem,
|
||||
OptType,
|
||||
ProgressItem,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import {
|
||||
type GetDocumentTableInfoResponse,
|
||||
type DocumentTaskInfo,
|
||||
type DocTableColumn,
|
||||
ColumnType,
|
||||
} from '@coze-arch/bot-api/memory';
|
||||
import {
|
||||
TableDataType,
|
||||
DocumentSource,
|
||||
type DocumentBase,
|
||||
type TableColumn,
|
||||
type UpdateRule,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
import { FormatType } from '@coze-arch/bot-api/developer_api';
|
||||
|
||||
import {
|
||||
useDocIdFromQuery,
|
||||
tableSettingsToString,
|
||||
validateField,
|
||||
} from '@/utils';
|
||||
import {
|
||||
type TableSettings,
|
||||
type TableInfo,
|
||||
type SemanticValidate,
|
||||
type AddCustomTableMeta,
|
||||
} from '@/types';
|
||||
import {
|
||||
TableStatus,
|
||||
MAX_TABLE_META_COLUMN_LEN,
|
||||
MAX_TABLE_META_STR_LEN,
|
||||
TableSettingFormFields,
|
||||
} from '@/constants';
|
||||
|
||||
/**
|
||||
* 校验key是否能作为语义匹配项
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
export const semanticValidator = (
|
||||
data?: GetDocumentTableInfoResponse,
|
||||
startRow = 0,
|
||||
): SemanticValidate => {
|
||||
if (!data) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const { table_meta, preview_data } = data;
|
||||
|
||||
if (
|
||||
!table_meta ||
|
||||
!preview_data ||
|
||||
!Object.keys(table_meta).length ||
|
||||
!Object.keys(preview_data).length
|
||||
) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO 下面forEach写的不好,待优化
|
||||
const res: SemanticValidate = {};
|
||||
Object.keys(table_meta).forEach(sheetId => {
|
||||
res[sheetId] = {};
|
||||
const curTableMeta = table_meta[sheetId];
|
||||
if (!Array.isArray(curTableMeta)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
curTableMeta.forEach(meta => {
|
||||
const { column_type, sequence } = meta;
|
||||
if (sequence === undefined) {
|
||||
return;
|
||||
}
|
||||
res[sheetId][sequence] = {
|
||||
valid: true,
|
||||
msg: '',
|
||||
};
|
||||
preview_data[sheetId].slice(startRow).forEach(dataMap => {
|
||||
if (column_type === ColumnType.Image) {
|
||||
res[sheetId][sequence] = {
|
||||
valid: false,
|
||||
msg: I18n.t('knowledge_insert_img_011'),
|
||||
};
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export function filterDocumentList({
|
||||
unitList,
|
||||
tableData,
|
||||
tableSettings,
|
||||
docIdFromQuery,
|
||||
}: {
|
||||
unitList: UnitItem[];
|
||||
tableData: TableInfo;
|
||||
tableSettings: TableSettings;
|
||||
docIdFromQuery: string;
|
||||
}): DocumentTaskInfo[] {
|
||||
const meta = tableData.table_meta?.[tableSettings.sheet_id];
|
||||
const { sheet_id, header_line_idx, start_line_idx } = tableSettings;
|
||||
const settings = {
|
||||
sheet_id: sheet_id.toString(),
|
||||
header_line_idx: header_line_idx.toString(),
|
||||
start_line_idx: start_line_idx.toString(),
|
||||
};
|
||||
return unitList.map(item => {
|
||||
if (item.docId) {
|
||||
return {
|
||||
name: item.name,
|
||||
uri: item.uri,
|
||||
document_id: item.docId,
|
||||
format_type: FormatType.Table,
|
||||
doc_table_meta: meta,
|
||||
doc_table_info: settings,
|
||||
};
|
||||
}
|
||||
return {
|
||||
name: item.name,
|
||||
uri: item.uri,
|
||||
document_id: docIdFromQuery === '' ? undefined : docIdFromQuery,
|
||||
format_type: FormatType.Table,
|
||||
doc_table_meta: meta,
|
||||
doc_table_info: settings,
|
||||
};
|
||||
}) as DocumentTaskInfo[];
|
||||
}
|
||||
|
||||
export const useResegmentFetchTableParams = () => ({
|
||||
document_id: useDocIdFromQuery(),
|
||||
// source_file: {
|
||||
// document_source: DocumentSource.Document,
|
||||
// },
|
||||
table_data_type: TableDataType.AllData,
|
||||
});
|
||||
|
||||
export function isConfigurationLoading(status: TableStatus) {
|
||||
return status === TableStatus.LOADING;
|
||||
}
|
||||
|
||||
export function isConfigurationError(status: TableStatus) {
|
||||
return status === TableStatus.ERROR;
|
||||
}
|
||||
|
||||
export function isConfigurationShowBanner(
|
||||
opt: OptType,
|
||||
originTableData: TableInfo,
|
||||
tableSettings: TableSettings,
|
||||
): boolean {
|
||||
return opt
|
||||
? (
|
||||
get(
|
||||
originTableData,
|
||||
`table_meta.${tableSettings[TableSettingFormFields.SHEET]}`,
|
||||
) || []
|
||||
).length > MAX_TABLE_META_COLUMN_LEN
|
||||
: Object.keys(
|
||||
get(
|
||||
originTableData,
|
||||
`preview_data.${tableSettings[TableSettingFormFields.SHEET]}.${
|
||||
tableSettings[TableSettingFormFields.KEY_START_ROW]
|
||||
}`,
|
||||
) || {},
|
||||
).length > MAX_TABLE_META_COLUMN_LEN;
|
||||
}
|
||||
|
||||
export function getConfigurationMeta(
|
||||
tableData: TableInfo,
|
||||
tableSettings: TableSettings,
|
||||
) {
|
||||
return tableData
|
||||
? (
|
||||
(tableData.table_meta || {})[
|
||||
tableSettings[TableSettingFormFields.SHEET] || 0
|
||||
] || []
|
||||
).map(_meta => ({
|
||||
..._meta,
|
||||
key: _meta.id,
|
||||
column_name: (_meta.column_name ?? '').substring(
|
||||
0,
|
||||
MAX_TABLE_META_STR_LEN,
|
||||
),
|
||||
}))
|
||||
: [];
|
||||
}
|
||||
|
||||
export function getExpandConfigurationMeta(
|
||||
tableData: TableInfo,
|
||||
tableSettings: TableSettings,
|
||||
validResult: Record<string, string>,
|
||||
): Array<
|
||||
DocTableColumn & {
|
||||
autofocus?: boolean;
|
||||
errMsg?: string;
|
||||
}
|
||||
> {
|
||||
const tableColumn = getConfigurationMeta(tableData, tableSettings);
|
||||
const validResultKeys = Object.keys(validResult);
|
||||
return tableColumn.map(item => {
|
||||
const newItem: DocTableColumn & {
|
||||
autofocus?: boolean;
|
||||
errMsg?: string;
|
||||
} = {
|
||||
...item,
|
||||
};
|
||||
const hasHit = validResultKeys.includes(item?.column_name || '');
|
||||
if (hasHit) {
|
||||
newItem.errMsg = validResult[item?.column_name || ''];
|
||||
}
|
||||
return newItem;
|
||||
});
|
||||
}
|
||||
|
||||
export function getConfigurationNextStatus(
|
||||
tableData: TableInfo,
|
||||
tableSettings: TableSettings,
|
||||
): FooterBtnStatus {
|
||||
if (!tableData) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
const { table_meta } = tableData;
|
||||
const meta =
|
||||
get(table_meta, tableSettings[TableSettingFormFields.SHEET]) || [];
|
||||
const hasEmptyMeta = meta.some(v => (v.column_name ?? '') === '');
|
||||
const hasEmptyType = meta.some(v => !(v.column_type ?? ''));
|
||||
const hasSystemField = meta.some(
|
||||
v => validateField(v?.column_name ?? '')?.valid === false,
|
||||
);
|
||||
const hasSemantic = meta.some(v => v.is_semantic === true);
|
||||
const hasDuplicateColumnName = meta.some(
|
||||
v => meta.filter(i => i.column_name === v.column_name).length >= 2,
|
||||
);
|
||||
// 没有表结构数据禁止下一步
|
||||
if (
|
||||
!Object.keys(meta).length ||
|
||||
hasEmptyMeta ||
|
||||
hasEmptyType ||
|
||||
!hasSemantic ||
|
||||
hasSystemField ||
|
||||
meta.length > MAX_TABLE_META_COLUMN_LEN ||
|
||||
hasDuplicateColumnName
|
||||
) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}
|
||||
|
||||
export function getDocIdFromProgressList(progressList: ProgressItem[]) {
|
||||
return Array.isArray(progressList) && progressList.length > 0
|
||||
? get(progressList, '0.documentId')
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取footer状态,不包括loading状态,仅判断启/禁用
|
||||
* 满足以下任一情况时,禁用footer按钮
|
||||
* 1.存在列名为空
|
||||
* 2.unitName为空
|
||||
* 3.没有选择语义匹配项
|
||||
* @param metaData
|
||||
* @param unitName // TODO unitName的判断待删
|
||||
* @returns
|
||||
*/
|
||||
export const getCustomStatus = (
|
||||
metaData: AddCustomTableMeta,
|
||||
unitName: string,
|
||||
): FooterBtnStatus => {
|
||||
const isDisabled =
|
||||
metaData.some(meta => !meta.column_type) ||
|
||||
!validateField(unitName)?.valid || // TODO 这一行待删
|
||||
!metaData.some(meta => meta.is_semantic === true) ||
|
||||
metaData.some(v => validateField(v.column_name ?? '')?.valid === false);
|
||||
return isDisabled ? FooterBtnStatus.DISABLE : FooterBtnStatus.ENABLE;
|
||||
};
|
||||
|
||||
// table上传第一步footer状态判断
|
||||
export function getButtonStatus(unitList: UnitItem[]) {
|
||||
const valid = unitList.some(v => validateField(v.name)?.valid === false);
|
||||
if (
|
||||
unitList.length === 0 ||
|
||||
valid ||
|
||||
unitList.some(
|
||||
unitItem =>
|
||||
unitItem.name.length === 0 || unitItem.status !== UploadStatus.SUCCESS,
|
||||
)
|
||||
) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}
|
||||
|
||||
export function getAddSegmentParams({
|
||||
spaceId,
|
||||
docId,
|
||||
datasetId,
|
||||
documentInfo,
|
||||
}: {
|
||||
spaceId?: string;
|
||||
docId?: string;
|
||||
datasetId: string;
|
||||
documentInfo: DocumentBase[];
|
||||
}) {
|
||||
const payload = {
|
||||
space_id: spaceId, // 兼容旧接口
|
||||
document_id: docId, // 兼容旧接口
|
||||
dataset_id: datasetId,
|
||||
format_type: FormatType.Table,
|
||||
document_bases: documentInfo,
|
||||
is_append: true,
|
||||
};
|
||||
return payload;
|
||||
}
|
||||
|
||||
export function getCreateDocumentParams({
|
||||
isAppend,
|
||||
unitList,
|
||||
metaData,
|
||||
tableSettings,
|
||||
sourceType,
|
||||
updateRule,
|
||||
}: {
|
||||
isAppend: boolean;
|
||||
unitList: UnitItem[];
|
||||
metaData: TableColumn[];
|
||||
tableSettings: TableSettings;
|
||||
sourceType?: DocumentSource;
|
||||
updateRule?: UpdateRule;
|
||||
}) {
|
||||
const documentSource = sourceType ?? DocumentSource.Document;
|
||||
const getSourceFileId = (unit: UnitItem) =>
|
||||
[DocumentSource.GoogleDrive, DocumentSource.Notion].includes(documentSource)
|
||||
? unit.file_id
|
||||
: unit.entity_id;
|
||||
|
||||
const getUpdateRule = () => {
|
||||
if (updateRule) {
|
||||
return updateRule;
|
||||
}
|
||||
|
||||
if (
|
||||
!isAppend &&
|
||||
(documentSource === DocumentSource.Web ||
|
||||
isFeishuOrLarkDocumentSource(documentSource))
|
||||
) {
|
||||
return {
|
||||
update_interval: get(unitList, '0.updateInterval'),
|
||||
update_type: get(unitList, '0.updateType'),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
source_type: documentSource,
|
||||
format_type: FormatType.Table,
|
||||
document_bases: unitList.map(unit => ({
|
||||
name: '',
|
||||
source_info: {
|
||||
tos_uri: unit.uri,
|
||||
document_source: documentSource,
|
||||
source_file_id: getSourceFileId(unit),
|
||||
web_id: unit.webID as string,
|
||||
},
|
||||
update_rule: getUpdateRule(),
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
table_meta: metaData.map(meta => ({
|
||||
id: isAppend ? meta.id : '0', // 不是追加,默认是新建(为'0')
|
||||
column_name: meta.column_name,
|
||||
is_semantic: meta.is_semantic,
|
||||
column_type: meta.column_type,
|
||||
desc: meta.desc,
|
||||
sequence: meta.sequence,
|
||||
})),
|
||||
})),
|
||||
|
||||
is_append: isAppend,
|
||||
// document_id: useDocIdFromQuery() ?? undefined, // TODO 待删除,这里是为了兼容原来的MemoryApi.ProcessDocumentsTask更新逻辑
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
enum PreProcessRule {
|
||||
REMOVE_SPACES = 'remove_extra_spaces',
|
||||
REMOVE_EMAILS = 'remove_urls_emails',
|
||||
}
|
||||
|
||||
export enum SeparatorType {
|
||||
LINE_BREAK = '\n',
|
||||
LINE_BREAK2 = '\n\n',
|
||||
CN_PERIOD = '。',
|
||||
CN_EXCLAMATION = '!',
|
||||
EN_PERIOD = '.',
|
||||
EN_EXCLAMATION = '!',
|
||||
CN_QUESTION = '?',
|
||||
EN_QUESTION = '?',
|
||||
CUSTOM = 'custom',
|
||||
}
|
||||
|
||||
export interface SegmentRule {
|
||||
separator: string;
|
||||
maxTokens: number;
|
||||
preProcessRules: PreProcessRule[];
|
||||
}
|
||||
|
||||
export enum SegmentCleaner {
|
||||
AUTO = 0,
|
||||
CUSTOM = 1,
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadConfig,
|
||||
type FooterControlsProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useTextDisplaySegmentStepCheck } from '@/hooks/common';
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import {
|
||||
createTextCustomAddUpdateStore,
|
||||
type UploadTextCustomAddUpdateStore,
|
||||
} from './store';
|
||||
import { TextUpload, TextSegment, TextProcessing } from './steps';
|
||||
import { TextCustomAddUpdateStep } from './constants';
|
||||
|
||||
export const TextCustomAddUpdateConfig: UploadConfig<
|
||||
TextCustomAddUpdateStep,
|
||||
UploadTextCustomAddUpdateStore
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
content: props => (
|
||||
<TextUpload
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('knowledge_upload_text_custom_add_title'),
|
||||
step: TextCustomAddUpdateStep.UPLOAD_CONTENT,
|
||||
},
|
||||
{
|
||||
content: props => (
|
||||
<TextSegment
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('kl_write_107'),
|
||||
step: TextCustomAddUpdateStep.SEGMENT_CLEANER,
|
||||
},
|
||||
{
|
||||
content: props => (
|
||||
<TextProcessing
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step4'),
|
||||
step: TextCustomAddUpdateStep.EMBED_PROGRESS,
|
||||
},
|
||||
],
|
||||
createStore: createTextCustomAddUpdateStore,
|
||||
useUploadMount: store => useTextDisplaySegmentStepCheck(),
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export enum TextCustomAddUpdateStep {
|
||||
UPLOAD_CONTENT = 0,
|
||||
SEGMENT_CLEANER = 1,
|
||||
EMBED_PROGRESS = 2,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextCustomAddUpdateConfig } from './config';
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextUpload } from './upload';
|
||||
export { TextSegment } from './segment';
|
||||
export { TextProcessing } from './processing';
|
||||
@@ -0,0 +1,4 @@
|
||||
.footer-sub-tip {
|
||||
font-size: 12px;
|
||||
color: var(--light-usage-text-color-text-2, rgb(28 31 35 / 60%));
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextProcessing } from './processing';
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FC, useEffect } from 'react';
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useDataNavigate, useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import { type ContentProps } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { getKnowledgeIDEQuery } from '@coze-data/knowledge-common-services';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import {
|
||||
DocumentSource,
|
||||
FormatType,
|
||||
StorageLocation,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { getProcessingDescMsg } from '@/utils';
|
||||
import { useCreateDocument } from '@/hooks';
|
||||
import { getCustomValues } from '@/features/knowledge-type/text/utils';
|
||||
import { UnitProgress } from '@/components';
|
||||
|
||||
import type { UploadTextCustomAddUpdateStore } from '../../store';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const TextProcessing: FC<
|
||||
ContentProps<UploadTextCustomAddUpdateStore>
|
||||
> = props => {
|
||||
const { useStore, footer } = props;
|
||||
|
||||
const resourceNavigate = useDataNavigate();
|
||||
const params = useKnowledgeParams();
|
||||
|
||||
const {
|
||||
progressList,
|
||||
createStatus,
|
||||
docName,
|
||||
docContent,
|
||||
segmentMode,
|
||||
segmentRule,
|
||||
enableStorageStrategy,
|
||||
storageLocation,
|
||||
openSearchConfig,
|
||||
} = useStore(
|
||||
useShallow(state => ({
|
||||
progressList: state.progressList,
|
||||
createStatus: state.createStatus,
|
||||
docName: state.docName,
|
||||
docContent: state.docContent,
|
||||
segmentMode: state.segmentMode,
|
||||
segmentRule: state.segmentRule,
|
||||
enableStorageStrategy: state.enableStorageStrategy,
|
||||
storageLocation: state.storageLocation,
|
||||
openSearchConfig: state.openSearchConfig,
|
||||
})),
|
||||
);
|
||||
|
||||
const createDocument = useCreateDocument(useStore);
|
||||
|
||||
useEffect(() => {
|
||||
createDocument({
|
||||
format_type: FormatType.Text,
|
||||
document_bases: [
|
||||
{
|
||||
name: docName,
|
||||
source_info: {
|
||||
custom_content: docContent,
|
||||
document_source: DocumentSource.Custom,
|
||||
},
|
||||
},
|
||||
],
|
||||
// 非首次添加时,不需要传分段规则
|
||||
chunk_strategy: getCustomValues(segmentMode, segmentRule),
|
||||
storage_strategy:
|
||||
IS_CN_REGION && enableStorageStrategy
|
||||
? {
|
||||
storage_location: storageLocation,
|
||||
open_search_config:
|
||||
storageLocation === StorageLocation.OpenSearch
|
||||
? openSearchConfig
|
||||
: undefined,
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<UnitProgress progressList={progressList} createStatus={createStatus} />
|
||||
{footer?.({
|
||||
btns: [
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('variable_reset_yes'),
|
||||
onClick: () => {
|
||||
const query = getKnowledgeIDEQuery() as Record<string, string>;
|
||||
resourceNavigate.toResource?.(
|
||||
'knowledge',
|
||||
params.datasetID,
|
||||
query,
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
prefix: (
|
||||
<span className={styles['footer-sub-tip']}>
|
||||
{getProcessingDescMsg(createStatus)}
|
||||
</span>
|
||||
),
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
.radio-wrapper {
|
||||
.displayNone {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-line-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.line {
|
||||
&::before {
|
||||
content: '';
|
||||
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: -15px;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
width: 690px;
|
||||
height: 1px;
|
||||
margin-top: 26px;
|
||||
|
||||
background: var(--light-usage-border-color-border,
|
||||
rgb(28 31 35 / 8%));
|
||||
}
|
||||
}
|
||||
|
||||
.form-line {
|
||||
margin-top: 27px;
|
||||
}
|
||||
|
||||
.pt6 {
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-radioGroup {
|
||||
&.semi-radioGroup-vertical {
|
||||
row-gap: 16px;
|
||||
}
|
||||
|
||||
.custom-wrapper {
|
||||
padding-bottom: 0;
|
||||
|
||||
.semi-input-default,
|
||||
.semi-input-wrapper-focus {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup {
|
||||
padding: 16px 16px 16px 19px;
|
||||
border: 1px solid var(--light-usage-border-color-border, rgb(28 31 35 / 8%));
|
||||
border-radius: 8px;
|
||||
|
||||
.semi-radio-addon {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.semi-form-field-label {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.semi-checkboxGroup-vertical {
|
||||
row-gap: 8px;
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup_checked {
|
||||
background: transparent;
|
||||
border: 1px solid var(--semi-color-primary);
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup_checked:active {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup .semi-radio-extra {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.separator-div {
|
||||
margin-top: 33px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.separator-not-custom {
|
||||
margin-bottom: 11px;
|
||||
}
|
||||
|
||||
.separator-input {
|
||||
padding-top: 0;
|
||||
padding-bottom: 8px !important;
|
||||
|
||||
|
||||
:global {
|
||||
.semi-form-field-label {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// :global {
|
||||
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextSegment } from './segment';
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type FC, useEffect } from 'react';
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { get } from 'lodash-es';
|
||||
import { useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import { type ContentProps } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { getSegmentCleanerParams, getStorageStrategyEnabled } from '@/utils';
|
||||
import { SegmentMode } from '@/types';
|
||||
import { useListDocumentReq } from '@/services';
|
||||
import {
|
||||
SegmentConfig,
|
||||
type OnChangeProps,
|
||||
} from '@/features/segment-config/base';
|
||||
|
||||
import type { UploadTextCustomAddUpdateStore } from '../../store';
|
||||
import { TextCustomAddUpdateStep } from '../../constants';
|
||||
import { getButtonNextStatus } from './utils';
|
||||
|
||||
export const TextSegment: FC<
|
||||
ContentProps<UploadTextCustomAddUpdateStore>
|
||||
> = props => {
|
||||
const { useStore, footer } = props;
|
||||
const {
|
||||
// common store
|
||||
setCurrentStep,
|
||||
// text store
|
||||
segmentRule,
|
||||
setSegmentRule,
|
||||
segmentMode,
|
||||
setSegmentMode,
|
||||
setEnableStorageStrategy,
|
||||
storageLocation,
|
||||
testConnectionSuccess,
|
||||
} = useStore(
|
||||
useShallow(state => ({
|
||||
setCurrentStep: state.setCurrentStep,
|
||||
segmentRule: state.segmentRule,
|
||||
setSegmentRule: state.setSegmentRule,
|
||||
segmentMode: state.segmentMode || SegmentMode.AUTO,
|
||||
setSegmentMode: state.setSegmentMode,
|
||||
setEnableStorageStrategy: state.setEnableStorageStrategy,
|
||||
storageLocation: state.storageLocation,
|
||||
testConnectionSuccess: state.testConnectionSuccess,
|
||||
})),
|
||||
);
|
||||
|
||||
const { datasetID, docID } = useKnowledgeParams();
|
||||
|
||||
const listDocumentReq = useListDocumentReq(res => {
|
||||
const segment = getSegmentCleanerParams(get(res, 'document_infos[0]', {}));
|
||||
if (segment) {
|
||||
setSegmentRule(segment.segmentRule);
|
||||
setSegmentMode(segment.segmentMode);
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (docID) {
|
||||
listDocumentReq({
|
||||
dataset_id: datasetID || '',
|
||||
document_ids: [docID || ''],
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (datasetID) {
|
||||
KnowledgeApi.DatasetDetail({ dataset_ids: [datasetID] }).then(res => {
|
||||
const dataset = res.dataset_details?.[datasetID];
|
||||
setEnableStorageStrategy(getStorageStrategyEnabled(dataset));
|
||||
});
|
||||
}
|
||||
}, [datasetID]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SegmentConfig
|
||||
segmentRule={segmentRule}
|
||||
segmentMode={segmentMode}
|
||||
onChange={({ segmentRule: rule, segmentMode: mode }: OnChangeProps) => {
|
||||
rule !== undefined && setSegmentRule(rule);
|
||||
mode !== undefined && setSegmentMode(mode);
|
||||
}}
|
||||
/>
|
||||
{footer?.([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
onClick: () => setCurrentStep(TextCustomAddUpdateStep.UPLOAD_CONTENT),
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
onClick: () => setCurrentStep(TextCustomAddUpdateStep.EMBED_PROGRESS),
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
status: getButtonNextStatus({
|
||||
segmentMode,
|
||||
segmentRule,
|
||||
storageLocation,
|
||||
testConnectionSuccess,
|
||||
}),
|
||||
},
|
||||
])}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FooterBtnStatus } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { type StorageLocation } from '@coze-arch/idl/knowledge';
|
||||
|
||||
import { type CustomSegmentRule, type SegmentMode } from '@/types';
|
||||
import { validateSegmentRules } from '@/features/knowledge-type/text/utils';
|
||||
|
||||
export function getButtonNextStatus(params: {
|
||||
segmentMode: SegmentMode;
|
||||
segmentRule: CustomSegmentRule;
|
||||
storageLocation: StorageLocation;
|
||||
testConnectionSuccess: boolean;
|
||||
}): FooterBtnStatus {
|
||||
const segmentValid = validateSegmentRules(
|
||||
params.segmentMode,
|
||||
params.segmentRule,
|
||||
);
|
||||
return segmentValid ? FooterBtnStatus.ENABLE : FooterBtnStatus.DISABLE;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UploadImageMenu } from '@coze-data/knowledge-common-components/text-knowledge-editor/features/editor-actions/upload-image';
|
||||
import {
|
||||
createEditorActionFeatureRegistry,
|
||||
type EditorActionRegistry,
|
||||
} from '@coze-data/knowledge-common-components/text-knowledge-editor/features/editor-actions';
|
||||
export const editorContextActionRegistry: EditorActionRegistry = (() => {
|
||||
const editorContextActionFeatureRegistry = createEditorActionFeatureRegistry(
|
||||
'editor-context-actions',
|
||||
);
|
||||
editorContextActionFeatureRegistry.registerSome([
|
||||
{
|
||||
type: 'upload-image',
|
||||
module: {
|
||||
Component: UploadImageMenu,
|
||||
},
|
||||
},
|
||||
]);
|
||||
return editorContextActionFeatureRegistry;
|
||||
})();
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UploadImageButton } from '@coze-data/knowledge-common-components/text-knowledge-editor/features/editor-actions/upload-image';
|
||||
import {
|
||||
createEditorActionFeatureRegistry,
|
||||
type EditorActionRegistry,
|
||||
} from '@coze-data/knowledge-common-components/text-knowledge-editor/features/editor-actions';
|
||||
export const editorToolbarActionRegistry: EditorActionRegistry = (() => {
|
||||
const editorToolbarActionFeatureRegistry = createEditorActionFeatureRegistry(
|
||||
'editor-toolbar-actions',
|
||||
);
|
||||
editorToolbarActionFeatureRegistry.registerSome([
|
||||
{
|
||||
type: 'upload-image',
|
||||
module: {
|
||||
Component: UploadImageButton,
|
||||
},
|
||||
},
|
||||
]);
|
||||
return editorToolbarActionFeatureRegistry;
|
||||
})();
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import { type UnitItem } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { FileBizType } from '@coze-arch/bot-api/developer_api';
|
||||
import { DeveloperApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { transformUnitList, getFileExtension, getBase64 } from '@/utils';
|
||||
|
||||
export const useRetry = (params: {
|
||||
unitList: UnitItem[];
|
||||
setUnitList: (unitList: UnitItem[]) => void;
|
||||
}) => {
|
||||
const { unitList, setUnitList } = params;
|
||||
|
||||
const onRetry = async (record: UnitItem, index: number) => {
|
||||
try {
|
||||
const { fileInstance } = record;
|
||||
if (fileInstance) {
|
||||
const { name } = fileInstance;
|
||||
const extension = getFileExtension(name);
|
||||
const base64 = await getBase64(fileInstance);
|
||||
const result = await DeveloperApi.UploadFile({
|
||||
file_head: {
|
||||
file_type: extension,
|
||||
biz_type: FileBizType.BIZ_BOT_DATASET,
|
||||
},
|
||||
data: base64,
|
||||
});
|
||||
|
||||
setUnitList(
|
||||
transformUnitList({
|
||||
unitList,
|
||||
data: result?.data,
|
||||
fileInstance,
|
||||
index,
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
const error = e as Error;
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeUploadFile,
|
||||
error,
|
||||
});
|
||||
}
|
||||
};
|
||||
return onRetry;
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
.custom-text-form {
|
||||
:global {
|
||||
.semi-form-field-error-message, .semi-form-field-label-required .semi-form-field-label-text::after {
|
||||
color: var(--coz-fg-hglt-red);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextUpload } from './upload';
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useContext, useMemo } from 'react';
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import { CozeInputWithCountField } from '@coze-data/utils';
|
||||
import { KnowledgeParamsStoreContext } from '@coze-data/knowledge-stores';
|
||||
import {
|
||||
type ContentProps,
|
||||
FooterBtnStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import {
|
||||
DocumentEditor,
|
||||
useInitEditor,
|
||||
EditorToolbar,
|
||||
type Chunk,
|
||||
} from '@coze-data/knowledge-common-components/text-knowledge-editor';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Form } from '@coze-arch/bot-semi';
|
||||
|
||||
import type { UploadTextCustomAddUpdateStore } from '../../store';
|
||||
import { TextCustomAddUpdateStep } from '../../constants';
|
||||
import { editorToolbarActionRegistry } from './editor-toolbar-actions-contributes';
|
||||
import { editorContextActionRegistry } from './editor-context-actions-contributes';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
const MAX_DOC_NAME_LEN = 100;
|
||||
|
||||
export const TextUpload = <T extends UploadTextCustomAddUpdateStore>(
|
||||
props: ContentProps<T>,
|
||||
) => {
|
||||
const { useStore, footer } = props;
|
||||
/** common store */
|
||||
const docName = useStore(state => state.docName);
|
||||
const docContent = useStore(state => state.docContent);
|
||||
const isDouyin = useContext(KnowledgeParamsStoreContext)?.paramsStore?.(
|
||||
s => s.params?.isDouyinBot,
|
||||
);
|
||||
/** common action */
|
||||
const setDocName = useStore(state => state.setDocName);
|
||||
const setDocContent = useStore(state => state.setDocContent);
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
|
||||
const buttonStatus = useMemo(() => {
|
||||
if (!docName || !docContent) {
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
return FooterBtnStatus.ENABLE;
|
||||
}, [docName, docContent]);
|
||||
|
||||
const handleClickNext = () => {
|
||||
setCurrentStep(TextCustomAddUpdateStep.SEGMENT_CLEANER);
|
||||
};
|
||||
|
||||
const initChunk = useMemo<Chunk>(
|
||||
() => ({
|
||||
text_knowledge_editor_chunk_uuid: nanoid(),
|
||||
content: '',
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
const { editor } = useInitEditor({
|
||||
chunk: initChunk,
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: 'h-[360px] overflow-y-auto',
|
||||
},
|
||||
},
|
||||
onChange: v => {
|
||||
setDocContent(v.content ?? '');
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form<Record<string, unknown>>
|
||||
layout="vertical"
|
||||
showValidateIcon={false}
|
||||
className={styles['custom-text-form']}
|
||||
>
|
||||
<CozeInputWithCountField
|
||||
data-testid={KnowledgeE2e.CustomUploadNameInput}
|
||||
className={styles['doc-name-input']}
|
||||
field="docName"
|
||||
autoFocus
|
||||
trigger="blur"
|
||||
onChange={(v: string) => setDocName(v)}
|
||||
maxLength={MAX_DOC_NAME_LEN}
|
||||
placeholder={I18n.t('knowledge_upload_text_custom_doc_name_tips')}
|
||||
label={I18n.t('knowledge_upload_text_custom_doc_name')}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: I18n.t('knowledge_upload_text_custom_doc_name_tips'),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Form.Slot
|
||||
className={styles['form-segment-content']}
|
||||
label={{ text: I18n.t('knowledge_upload_text_custom_doc_content') }}
|
||||
// error={I18n.t('knowledge_upload_text_custom_doc_content_tips')}
|
||||
>
|
||||
<DocumentEditor
|
||||
editor={editor}
|
||||
placeholder={I18n.t(
|
||||
'knowledge_upload_text_custom_doc_content_tips',
|
||||
)}
|
||||
editorContextMenuItemsRegistry={
|
||||
!isDouyin ? editorContextActionRegistry : undefined
|
||||
}
|
||||
editorBottomSlot={
|
||||
!isDouyin ? (
|
||||
<EditorToolbar
|
||||
editor={editor}
|
||||
actionRegistry={editorToolbarActionRegistry}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
</Form.Slot>
|
||||
</Form>
|
||||
|
||||
{footer?.([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
status: buttonStatus,
|
||||
onClick: handleClickNext,
|
||||
},
|
||||
])}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { createTextCustomAddUpdateStore } from './store';
|
||||
export { UploadTextCustomAddUpdateStore } from './types';
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type StateCreator } from 'zustand';
|
||||
|
||||
import {
|
||||
createTextSlice,
|
||||
getDefaultTextState,
|
||||
} from '@/features/knowledge-type/text/slice';
|
||||
|
||||
import { TextCustomAddUpdateStep } from '../constants';
|
||||
import {
|
||||
type UploadTextCustomAddUpdateStore,
|
||||
type UploadTextCustomAddUpdateState,
|
||||
} from './types';
|
||||
|
||||
export const getDefaultTextCustomAddState: () => UploadTextCustomAddUpdateState =
|
||||
() => ({
|
||||
...getDefaultTextState(),
|
||||
currentStep: TextCustomAddUpdateStep.UPLOAD_CONTENT,
|
||||
docName: '',
|
||||
docContent: '',
|
||||
});
|
||||
|
||||
export const createTextCustomAddUpdateSlice: StateCreator<
|
||||
UploadTextCustomAddUpdateStore
|
||||
> = (set, ...arg) => ({
|
||||
...createTextSlice(set, ...arg),
|
||||
// overwrite
|
||||
...getDefaultTextCustomAddState(),
|
||||
// /** reset state */
|
||||
reset: () => {
|
||||
set(getDefaultTextCustomAddState());
|
||||
},
|
||||
setDocContent: (content: string) => {
|
||||
set({
|
||||
docContent: content,
|
||||
});
|
||||
},
|
||||
setDocName: (name: string) => {
|
||||
set({
|
||||
docName: name,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { create } from 'zustand';
|
||||
|
||||
import { type UploadTextCustomAddUpdateStore } from './types';
|
||||
import { createTextCustomAddUpdateSlice } from './slice';
|
||||
|
||||
export const createTextCustomAddUpdateStore = () =>
|
||||
create<UploadTextCustomAddUpdateStore>()(
|
||||
devtools((set, get, store) => ({
|
||||
...createTextCustomAddUpdateSlice(set, get, store),
|
||||
})),
|
||||
);
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadTextState,
|
||||
type UploadTextAction,
|
||||
} from '@/features/knowledge-type/text/interface';
|
||||
|
||||
import { type TextCustomAddUpdateStep } from '../constants';
|
||||
|
||||
export type UploadTextCustomAddUpdateState =
|
||||
UploadTextState<TextCustomAddUpdateStep> & {
|
||||
docName: string;
|
||||
docContent: string;
|
||||
};
|
||||
export type UploadTextCustomAddUpdateAction =
|
||||
UploadTextAction<TextCustomAddUpdateStep> & {
|
||||
setDocName: (unitName: string) => void;
|
||||
setDocContent: (content: string) => void;
|
||||
};
|
||||
|
||||
export type UploadTextCustomAddUpdateStore = UploadTextCustomAddUpdateState &
|
||||
UploadTextCustomAddUpdateAction;
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextCustomAddUpdateConfig } from './add/config';
|
||||
export { UploadTextCustomAddUpdateStore } from './add/store';
|
||||
export { TextCustomAddUpdateStep } from './add/constants';
|
||||
export { getButtonNextStatus } from './add/steps/segment/utils';
|
||||
export { createTextCustomAddUpdateStore } from './add/store';
|
||||
export { TextUpload, TextSegment, TextProcessing } from './add/steps';
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type UploadConfig,
|
||||
type FooterControlsProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { useTextDisplaySegmentStepCheck } from '@/hooks/common';
|
||||
import { UploadFooter } from '@/components';
|
||||
|
||||
import {
|
||||
createTextLocalAddUpdateStore,
|
||||
type UploadTextLocalAddUpdateStore,
|
||||
} from './store';
|
||||
import { SegmentPreviewStep } from './steps/preview';
|
||||
import { TextUpload, TextSegment, TextProcessing } from './steps';
|
||||
import { TextLocalAddUpdateStep } from './constants';
|
||||
|
||||
export const TextLocalAddUpdateConfig: UploadConfig<
|
||||
TextLocalAddUpdateStep,
|
||||
UploadTextLocalAddUpdateStore
|
||||
> = {
|
||||
steps: [
|
||||
{
|
||||
content: props => (
|
||||
<TextUpload
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={props.checkStatus}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step2'),
|
||||
step: TextLocalAddUpdateStep.UPLOAD_FILE,
|
||||
},
|
||||
{
|
||||
content: props => (
|
||||
<TextSegment
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('kl_write_107'),
|
||||
step: TextLocalAddUpdateStep.SEGMENT_CLEANER,
|
||||
},
|
||||
{
|
||||
content: props => (
|
||||
<SegmentPreviewStep
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('knowlege_qqq_001'),
|
||||
step: TextLocalAddUpdateStep.SEGMENT_PREVIEW,
|
||||
showThisStep: () => true,
|
||||
},
|
||||
{
|
||||
content: props => (
|
||||
<TextProcessing
|
||||
useStore={props.useStore}
|
||||
footer={(controls: FooterControlsProps) => (
|
||||
<UploadFooter controls={controls} />
|
||||
)}
|
||||
checkStatus={undefined}
|
||||
/>
|
||||
),
|
||||
title: I18n.t('datasets_createFileModel_step4'),
|
||||
step: TextLocalAddUpdateStep.EMBED_PROGRESS,
|
||||
},
|
||||
],
|
||||
createStore: createTextLocalAddUpdateStore,
|
||||
useUploadMount: store => useTextDisplaySegmentStepCheck(),
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export enum TextLocalAddUpdateStep {
|
||||
UPLOAD_FILE,
|
||||
SEGMENT_CLEANER,
|
||||
SEGMENT_PREVIEW,
|
||||
EMBED_PROGRESS,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextLocalAddUpdateConfig } from './config';
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { TextUpload } from './upload';
|
||||
export { TextSegment } from './segment';
|
||||
export { TextProcessing } from './processing';
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable @coze-arch/max-line-per-function */
|
||||
import { useEffect, useMemo, type FC } from 'react';
|
||||
|
||||
import { isEqual } from 'lodash-es';
|
||||
import classNames from 'classnames';
|
||||
import { useRequest } from 'ahooks';
|
||||
import { useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import {
|
||||
FooterBtnStatus,
|
||||
type ContentProps,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { ReviewStatus } from '@coze-arch/idl/knowledge';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
import { Toast } from '@coze-arch/coze-design';
|
||||
|
||||
import { PreProcessRule, SegmentMode, SeperatorType } from '@/types';
|
||||
import { SegmentPreview } from '@/features/segment-preview';
|
||||
import { getCustomValues } from '@/features/knowledge-type/text/utils';
|
||||
import { getSeperatorOptionList } from '@/constants';
|
||||
|
||||
import type { UploadTextLocalAddUpdateStore } from '../../store';
|
||||
import { TextLocalAddUpdateStep } from '../../constants';
|
||||
|
||||
export const SegmentPreviewStep: FC<
|
||||
ContentProps<UploadTextLocalAddUpdateStore>
|
||||
> = props => {
|
||||
const { useStore, footer } = props;
|
||||
const params = useKnowledgeParams();
|
||||
/** common store */
|
||||
const setCurrentStep = useStore(state => state.setCurrentStep);
|
||||
const unitList = useStore(state => state.unitList);
|
||||
const segmentMode = useStore(state => state.segmentMode);
|
||||
const docReviewList = useStore(state => state.docReviewList);
|
||||
const setDocReviewList = useStore(state => state.setDocReviewList);
|
||||
const currentReviewID = useStore(state => state.currentReviewID);
|
||||
const setCurrentReviewID = useStore(state => state.setCurrentReviewID);
|
||||
const selectionIDs = useStore(state => state.selectionIDs);
|
||||
const setSelectionIDs = useStore(state => state.setSelectionIDs);
|
||||
const levelSegments = useStore(state => state.levelSegments);
|
||||
const setLevelSegments = useStore(state => state.setLevelSegments);
|
||||
const parsingStrategy = useStore(state => state.parsingStrategy);
|
||||
const levelChunkStrategy = useStore(state => state.levelChunkStrategy);
|
||||
const segmentRule = useStore(state => state.segmentRule);
|
||||
|
||||
const docReviewCreated = useMemo(
|
||||
() =>
|
||||
isEqual(
|
||||
docReviewList.map(item => item.document_name),
|
||||
unitList.map(item => item.name),
|
||||
),
|
||||
[docReviewList, unitList],
|
||||
);
|
||||
|
||||
/** 创建 doc review */
|
||||
useEffect(() => {
|
||||
const createDocReview = async () => {
|
||||
const { unitList: inputUnitList } = useStore.getState();
|
||||
const res = await KnowledgeApi.CreateDocumentReview({
|
||||
dataset_id: params.datasetID,
|
||||
reviews: inputUnitList.map(item => ({
|
||||
tos_uri: item.uri,
|
||||
document_name: item.name,
|
||||
document_type: item.type,
|
||||
})),
|
||||
parsing_strategy: parsingStrategy,
|
||||
chunk_strategy: getCustomValues(
|
||||
segmentMode,
|
||||
segmentRule,
|
||||
levelChunkStrategy,
|
||||
),
|
||||
});
|
||||
if (res.code === 0 && res.reviews?.length) {
|
||||
setDocReviewList(res.reviews);
|
||||
setCurrentReviewID(res.reviews[0].review_id ?? '');
|
||||
}
|
||||
};
|
||||
if (!docReviewCreated) {
|
||||
createDocReview();
|
||||
}
|
||||
// TODO: segmentMode 切换时需要重新创建 doc review
|
||||
}, [
|
||||
docReviewCreated,
|
||||
parsingStrategy,
|
||||
segmentMode,
|
||||
segmentRule,
|
||||
levelChunkStrategy,
|
||||
]);
|
||||
|
||||
/** 轮询 doc review 状态 */
|
||||
const { run: pollDocReviewStatus, cancel: cancelPollDocReviewStatus } =
|
||||
useRequest(
|
||||
async () => {
|
||||
const res = await KnowledgeApi.MGetDocumentReview({
|
||||
dataset_id: params.datasetID,
|
||||
review_ids: docReviewList.map(item => item.review_id ?? ''),
|
||||
});
|
||||
if (res.code === 0) {
|
||||
setDocReviewList(res.reviews ?? []);
|
||||
}
|
||||
},
|
||||
{
|
||||
manual: true,
|
||||
pollingInterval: 2000,
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (docReviewCreated) {
|
||||
pollDocReviewStatus();
|
||||
}
|
||||
return () => {
|
||||
cancelPollDocReviewStatus();
|
||||
};
|
||||
}, [docReviewCreated]);
|
||||
|
||||
/** 结束轮询 */
|
||||
const docReviewProcessFinished =
|
||||
docReviewList.length > 0 &&
|
||||
docReviewList.every(
|
||||
item =>
|
||||
// docReview 刚创建时没有 status, 其他情况下校验 status 是否为 Processing
|
||||
typeof item.status !== 'undefined' &&
|
||||
item.status !== ReviewStatus.Processing,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (docReviewProcessFinished) {
|
||||
cancelPollDocReviewStatus();
|
||||
}
|
||||
}, [docReviewProcessFinished]);
|
||||
|
||||
const { loading: saveLoading, run: saveDocumentReview } = useRequest(
|
||||
async () => {
|
||||
const res = await KnowledgeApi.SaveDocumentReview({
|
||||
review_id: currentReviewID,
|
||||
dataset_id: params.datasetID,
|
||||
doc_tree_json: JSON.stringify({ chunks: levelSegments }),
|
||||
});
|
||||
return res.code === 0;
|
||||
},
|
||||
{
|
||||
manual: true,
|
||||
onSuccess: data => {
|
||||
if (data) {
|
||||
setCurrentStep(TextLocalAddUpdateStep.EMBED_PROGRESS);
|
||||
}
|
||||
},
|
||||
onError: () => {
|
||||
Toast.error('变更保存失败');
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SegmentPreview
|
||||
docReviewList={docReviewList}
|
||||
setDocReviewList={setDocReviewList}
|
||||
segmentMode={segmentMode}
|
||||
currentReviewID={currentReviewID}
|
||||
setCurrentReviewID={setCurrentReviewID}
|
||||
selectionIDs={selectionIDs}
|
||||
setSelectionIDs={setSelectionIDs}
|
||||
levelSegments={levelSegments}
|
||||
setLevelSegments={setLevelSegments}
|
||||
datasetID={params.datasetID}
|
||||
segmentInfo={
|
||||
segmentMode !== SegmentMode.AUTO ? (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-col',
|
||||
'text-[14px] font-[400] leading-[20px] coz-fg-primary',
|
||||
)}
|
||||
>
|
||||
{segmentMode === SegmentMode.LEVEL ? (
|
||||
<>
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('knowledge_level_004')}:
|
||||
{levelChunkStrategy.maxLevel}
|
||||
</span>
|
||||
{levelChunkStrategy.isSaveTitle ? (
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('knowledge_level_005')}
|
||||
</span>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
{segmentMode === SegmentMode.CUSTOM ? (
|
||||
<>
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('datasets_Custom_segmentID')}:
|
||||
{segmentRule.separator.type !== SeperatorType.CUSTOM
|
||||
? getSeperatorOptionList().find(
|
||||
item => item.value === segmentRule.separator.type,
|
||||
)?.label
|
||||
: segmentRule.separator.customValue}
|
||||
</span>
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('datasets_Custom_maxLength')}:
|
||||
{segmentRule.maxTokens}
|
||||
</span>
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('kl_write_014')}: {segmentRule.overlap}
|
||||
</span>
|
||||
{segmentRule.preProcessRules.includes(
|
||||
PreProcessRule.REMOVE_SPACES,
|
||||
) ? (
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('datasets_Custom_rule_replace')}
|
||||
</span>
|
||||
) : null}
|
||||
{segmentRule.preProcessRules.includes(
|
||||
PreProcessRule.REMOVE_EMAILS,
|
||||
) ? (
|
||||
<span>
|
||||
{'\u2022'} {I18n.t('datasets_Custom_rule_delete')}
|
||||
</span>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
{footer?.([
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitUpBtn,
|
||||
type: 'primary',
|
||||
theme: 'light',
|
||||
onClick: () => {
|
||||
setDocReviewList([]);
|
||||
setCurrentStep(TextLocalAddUpdateStep.SEGMENT_CLEANER);
|
||||
},
|
||||
text: I18n.t('datasets_createFileModel_previousBtn'),
|
||||
},
|
||||
{
|
||||
e2e: KnowledgeE2e.UploadUnitNextBtn,
|
||||
type: 'hgltplus',
|
||||
theme: 'solid',
|
||||
status: saveLoading
|
||||
? FooterBtnStatus.LOADING
|
||||
: FooterBtnStatus.ENABLE,
|
||||
onClick: async () => {
|
||||
await saveDocumentReview();
|
||||
},
|
||||
text: I18n.t('datasets_createFileModel_NextBtn'),
|
||||
},
|
||||
])}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
.footer-sub-tip {
|
||||
font-size: 12px;
|
||||
color: var(--light-usage-text-color-text-2, rgb(28 31 35 / 60%));
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user