feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -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 UnitItem } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { useEditUnitNameModal } from '@coze-data/knowledge-modal-base';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import {
|
||||
IconCozEdit,
|
||||
IconCozRefresh,
|
||||
IconCozTrashCan,
|
||||
} from '@coze-arch/coze-design/icons';
|
||||
import { IconButton, Tooltip } from '@coze-arch/coze-design';
|
||||
|
||||
import { type RenderColumnsProps } from '../types';
|
||||
import { getFrequencyMap } from '../../../utils';
|
||||
|
||||
export function getFileSizeInfo(record: UnitItem) {
|
||||
return (
|
||||
<div
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListFileSize}.${record.name}`}
|
||||
className={'coz-fg-secondary text-12px'}
|
||||
>
|
||||
{record?.size}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function getFrequencyInfo(record: UnitItem) {
|
||||
return (
|
||||
<div
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListFrequency}.${record.name}`}
|
||||
className={'coz-fg-secondary text-12px'}
|
||||
>
|
||||
{getFrequencyMap(record.updateInterval || 0)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ActionRenderByDelete(props: RenderColumnsProps) {
|
||||
const { index, record, params } = props;
|
||||
const { onChange, unitList, onDelete } = params;
|
||||
|
||||
const handleDelete = () => {
|
||||
onChange(unitList.filter((u, i) => index !== i));
|
||||
if (typeof onDelete === 'function') {
|
||||
onDelete?.(record, index);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Tooltip spacing={12} content={I18n.t('Delete')} position="top">
|
||||
<IconButton
|
||||
color="secondary"
|
||||
icon={<IconCozTrashCan className="text-14px" />}
|
||||
iconPosition="left"
|
||||
size="small"
|
||||
onClick={handleDelete}
|
||||
></IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
export function ActionRenderByEditName(props: RenderColumnsProps) {
|
||||
const { index, record, params } = props;
|
||||
const { onChange, unitList } = params;
|
||||
|
||||
const { node, open } = useEditUnitNameModal({
|
||||
name: record?.name ?? '',
|
||||
onOk: (name: string) => {
|
||||
const arr = [...unitList];
|
||||
arr[index].name = name;
|
||||
onChange(arr);
|
||||
},
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<Tooltip spacing={12} content={I18n.t('Edit')} position="top">
|
||||
<IconButton
|
||||
color="secondary"
|
||||
icon={<IconCozEdit className="text-14px" />}
|
||||
iconPosition="left"
|
||||
size="small"
|
||||
onClick={() => open()}
|
||||
/>
|
||||
</Tooltip>
|
||||
{node}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function ActionRenderByRetry(props: RenderColumnsProps) {
|
||||
const { index, record, params } = props;
|
||||
if (params.disableRetry) {
|
||||
return null;
|
||||
}
|
||||
const { onRetry } = params;
|
||||
|
||||
const handleRetry = () => {
|
||||
onRetry?.(record, index);
|
||||
};
|
||||
return (
|
||||
<Tooltip
|
||||
spacing={12}
|
||||
content={I18n.t('datasets_unit_update_retry')}
|
||||
position="top"
|
||||
>
|
||||
<IconButton
|
||||
color="secondary"
|
||||
icon={<IconCozRefresh className="text-14px" />}
|
||||
iconPosition="left"
|
||||
size="small"
|
||||
onClick={handleRetry}
|
||||
></IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
@@ -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 FC } from 'react';
|
||||
|
||||
import { UITableAction } from '@coze-arch/bot-semi';
|
||||
|
||||
import { type ActionProps } from '../../types';
|
||||
|
||||
export const Action: FC<ActionProps> = ({
|
||||
onDelete,
|
||||
showEdit,
|
||||
deleteProps,
|
||||
editProps,
|
||||
}: ActionProps) => (
|
||||
<UITableAction
|
||||
deleteProps={{
|
||||
disabled: false,
|
||||
handleClick: onDelete,
|
||||
...deleteProps,
|
||||
}}
|
||||
editProps={{
|
||||
hide: !showEdit,
|
||||
...editProps,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -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 { Action } from './action';
|
||||
@@ -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 { UploadStatusComp } from './upload-status';
|
||||
export { UnitName } from './unit-name';
|
||||
export { Action } from './action-render';
|
||||
@@ -0,0 +1,44 @@
|
||||
.unit-name-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 3px;
|
||||
|
||||
:global {
|
||||
.semi-icon {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.view-name {
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.input-suffix {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
font-size: 12px;
|
||||
color: rgb(28 29 35 / 35%);
|
||||
}
|
||||
|
||||
.unit-name-input {
|
||||
width: 100%;
|
||||
|
||||
.error {
|
||||
position: absolute;
|
||||
color: rgb(249 57 32 / 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.unit-name-error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.error {
|
||||
color: rgb(249 57 32 / 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 { useState, useEffect } from 'react';
|
||||
|
||||
import { KNOWLEDGE_UNIT_NAME_MAX_LEN } from '@coze-data/knowledge-modal-base';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { UIInput } from '@coze-arch/bot-semi';
|
||||
|
||||
import { getTypeIcon } from '../../utils';
|
||||
import { type UnitNameProps } from '../../types';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const UnitName: React.FC<UnitNameProps> = ({
|
||||
edit,
|
||||
onChange,
|
||||
disabled,
|
||||
record,
|
||||
formatType,
|
||||
}) => {
|
||||
const { type, name, validateMessage } = record;
|
||||
const [value, setValue] = useState(name); // 需要用自身state,否则出现无法输入中文的bug
|
||||
const getValidateMessage = (val: string) =>
|
||||
!val ? I18n.t('datasets_unit_exception_name_empty') : validateMessage;
|
||||
useEffect(() => {
|
||||
setValue(name);
|
||||
}, [name]);
|
||||
return (
|
||||
<div
|
||||
className={styles['unit-name-wrap']}
|
||||
data-testid={`${KnowledgeE2e.FeishuUploadListName}.${name}`}
|
||||
>
|
||||
{getTypeIcon({ type, formatType })}
|
||||
{edit ? (
|
||||
<div className="unit-name-input">
|
||||
<UIInput
|
||||
disabled={disabled}
|
||||
value={value}
|
||||
onChange={val => {
|
||||
setValue(val);
|
||||
onChange(val);
|
||||
}}
|
||||
maxLength={KNOWLEDGE_UNIT_NAME_MAX_LEN}
|
||||
validateStatus={!name ? 'error' : 'default'}
|
||||
suffix={
|
||||
<span className="input-suffix">
|
||||
{(name || '').length}/{KNOWLEDGE_UNIT_NAME_MAX_LEN}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
<div className="error">{getValidateMessage(name)}</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="unit-name-error">
|
||||
<span className="view-name">{name}</span>
|
||||
{validateMessage ? (
|
||||
<div className="error">{validateMessage}</div>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 { useState, useEffect, type FC } from 'react';
|
||||
|
||||
import { KNOWLEDGE_UNIT_NAME_MAX_LEN } from '@coze-data/knowledge-modal-base';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { UIInput } from '@coze-arch/bot-semi';
|
||||
import { FormatType } from '@coze-arch/bot-api/memory';
|
||||
|
||||
import { validateField } from '@/utils';
|
||||
|
||||
import { getTypeIcon } from '../../utils';
|
||||
import { type UnitNameProps } from '../../types';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const UnitName: FC<UnitNameProps> = ({
|
||||
edit,
|
||||
onChange,
|
||||
disabled,
|
||||
record,
|
||||
formatType,
|
||||
canValidator = true,
|
||||
inModal = false,
|
||||
}) => {
|
||||
const { type, name, validateMessage, dynamicErrorMessage } = record;
|
||||
const [value, setValue] = useState(name); // 需要用自身state,否则出现无法输入中文的bug
|
||||
const [validData, setValidData] = useState({ valid: true, errorMsg: '' });
|
||||
|
||||
const getValidateMessage = (val: string) =>
|
||||
!val ? I18n.t('datasets_unit_exception_name_empty') : validateMessage;
|
||||
|
||||
const validator = (val: string) => {
|
||||
const validObj = validateField(val, getValidateMessage(name));
|
||||
setValidData(
|
||||
formatType === FormatType.Table
|
||||
? validObj
|
||||
: {
|
||||
valid: !!name,
|
||||
errorMsg: '',
|
||||
},
|
||||
);
|
||||
};
|
||||
useEffect(() => {
|
||||
setValue(name);
|
||||
canValidator && !disabled && validator(name);
|
||||
}, [name, disabled]);
|
||||
|
||||
return (
|
||||
<div className={styles['unit-name-wrap']}>
|
||||
{getTypeIcon({ type, formatType, url: record.url, inModal })}
|
||||
{edit ? (
|
||||
<div className="unit-name-input">
|
||||
<UIInput
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListName}.${record.name}`}
|
||||
disabled={disabled}
|
||||
autoFocus={true}
|
||||
value={value}
|
||||
onChange={val => {
|
||||
setValue(val);
|
||||
onChange(val);
|
||||
}}
|
||||
onBlur={() => {
|
||||
canValidator && validator(name);
|
||||
}}
|
||||
maxLength={KNOWLEDGE_UNIT_NAME_MAX_LEN}
|
||||
validateStatus={
|
||||
!validData.valid || dynamicErrorMessage ? 'error' : 'default'
|
||||
}
|
||||
suffix={
|
||||
<span className="input-suffix">
|
||||
{(name || '').length}/{KNOWLEDGE_UNIT_NAME_MAX_LEN}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
<div className="error">
|
||||
{!disabled &&
|
||||
(validData.errorMsg ||
|
||||
getValidateMessage(name) ||
|
||||
dynamicErrorMessage)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span
|
||||
className="view-name"
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListNameView}.${record.name}`}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
.upload-status-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 22px;
|
||||
|
||||
:global {
|
||||
.semi-icon {
|
||||
float: left;
|
||||
margin: 0 5px -3px 0;
|
||||
}
|
||||
|
||||
.semi-progress-horizontal {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.retry {
|
||||
cursor: pointer;
|
||||
|
||||
:global {
|
||||
.semi-icon {
|
||||
float: left;
|
||||
margin: 3px 3px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.retry-text {
|
||||
margin-left: 3px;
|
||||
color: rgb(77 83 232 / 100%);
|
||||
}
|
||||
|
||||
|
||||
.disabled-retry {
|
||||
.retry-text {
|
||||
cursor: not-allowed;
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.no-retry-text {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 complexity */
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
UploadStatus,
|
||||
EntityStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Tooltip, Progress, Spin } from '@coze-arch/bot-semi';
|
||||
import {
|
||||
IconUploadFileSuccess,
|
||||
IconUploadFileFail,
|
||||
} from '@coze-arch/bot-icons';
|
||||
import { WebStatus } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { type UploadStateProps } from '../../types';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const UploadStatusComp: React.FC<UploadStateProps> = ({
|
||||
record,
|
||||
onRetry,
|
||||
index,
|
||||
needLoading,
|
||||
overlayClassName,
|
||||
disableRetry,
|
||||
noRetry,
|
||||
}) => {
|
||||
const { status } = record;
|
||||
if (
|
||||
status === UploadStatus.UPLOADING ||
|
||||
status === UploadStatus.VALIDATING ||
|
||||
status === UploadStatus.WAIT ||
|
||||
status === WebStatus.Handling ||
|
||||
status === EntityStatus.EntityStatusProcess
|
||||
) {
|
||||
return (
|
||||
<span
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListStatus}.${record.name}`}
|
||||
className={classNames(styles['upload-status-wrap'], overlayClassName)}
|
||||
>
|
||||
<span>{I18n.t('datasets_unit_upload_state')}</span>
|
||||
{needLoading ? (
|
||||
<Spin spinning={true} />
|
||||
) : (
|
||||
<Progress percent={record.percent} />
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (
|
||||
status === UploadStatus.SUCCESS ||
|
||||
status === WebStatus.Finish ||
|
||||
status === EntityStatus.EntityStatusSuccess
|
||||
) {
|
||||
return (
|
||||
<span
|
||||
className={styles['upload-status-wrap']}
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListStatus}.${record.name}`}
|
||||
>
|
||||
<IconUploadFileSuccess />
|
||||
<span>{I18n.t('datasets_unit_upload_success')}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (status === UploadStatus.VALIDATE_FAIL) {
|
||||
return (
|
||||
<span
|
||||
className={styles['upload-status-wrap']}
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListStatus}.${record.name}`}
|
||||
>
|
||||
<IconUploadFileFail />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (
|
||||
status === UploadStatus.UPLOAD_FAIL ||
|
||||
status === WebStatus.Failed ||
|
||||
status === EntityStatus.EntityStatusFail
|
||||
) {
|
||||
return (
|
||||
<div
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListStatus}.${record.name}`}
|
||||
className={classNames(
|
||||
`${styles['upload-status-wrap']} ${styles.retry}`,
|
||||
overlayClassName,
|
||||
disableRetry ? styles['disabled-retry'] : '',
|
||||
noRetry ? styles['no-retry-text'] : '',
|
||||
)}
|
||||
onClick={() => {
|
||||
!disableRetry && !noRetry && onRetry && onRetry(record, index);
|
||||
}}
|
||||
>
|
||||
{!record.statusDescript ? (
|
||||
<IconUploadFileFail />
|
||||
) : (
|
||||
<Tooltip content={record.statusDescript} trigger="hover">
|
||||
<IconUploadFileFail />
|
||||
</Tooltip>
|
||||
)}
|
||||
{!noRetry && (
|
||||
<div className={classNames(styles['retry-text'])}>
|
||||
{I18n.t('datasets_unit_update_retry')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
export { UploadUnitTable } from './upload-unit-table';
|
||||
export { type RenderColumnsProps } from './types';
|
||||
export {
|
||||
ActionRenderByDelete,
|
||||
ActionRenderByEditName,
|
||||
ActionRenderByRetry,
|
||||
getFrequencyInfo,
|
||||
getFileSizeInfo,
|
||||
} from './actions';
|
||||
export { getProcessStatus } from './utils';
|
||||
export { type ColumnInfo, type UploadUnitTableProps } from './types';
|
||||
@@ -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 ReactNode } from 'react';
|
||||
|
||||
import {
|
||||
type UnitType,
|
||||
type UnitItem,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { type UIActionItemProps } from '@coze-arch/bot-semi';
|
||||
import { type FormatType } from '@coze-arch/bot-api/memory';
|
||||
|
||||
export interface UploadStateProps {
|
||||
record: UnitItem;
|
||||
onRetry?: (record: UnitItem, index: number) => void;
|
||||
index: number;
|
||||
needLoading?: boolean;
|
||||
overlayClassName?: string;
|
||||
disableRetry?: boolean;
|
||||
// 不显示重试文案
|
||||
noRetry?: boolean;
|
||||
}
|
||||
|
||||
export interface UnitNameProps {
|
||||
canValidator?: boolean;
|
||||
edit?: boolean;
|
||||
disabled?: boolean;
|
||||
inModal?: boolean;
|
||||
formatType: FormatType;
|
||||
onChange: (value: string) => void;
|
||||
record: UnitItem;
|
||||
}
|
||||
|
||||
export interface ActionProps {
|
||||
showEdit?: boolean;
|
||||
onDelete: () => void;
|
||||
deleteProps?: UIActionItemProps;
|
||||
editProps?: UIActionItemProps;
|
||||
record?: UnitItem;
|
||||
}
|
||||
|
||||
export enum ActionType {
|
||||
Edit = 'edit',
|
||||
Delete = 'delete',
|
||||
}
|
||||
|
||||
export type HandleChange = (
|
||||
unitList: UnitItem[],
|
||||
action?: {
|
||||
type: ActionType;
|
||||
index: number;
|
||||
},
|
||||
) => void;
|
||||
|
||||
export interface ColumnInfo {
|
||||
subText?: ReactNode;
|
||||
actions?: ReactNode[];
|
||||
formatType?: FormatType;
|
||||
}
|
||||
|
||||
export interface UploadUnitTableProps {
|
||||
type: UnitType;
|
||||
unitList: UnitItem[];
|
||||
onChange: HandleChange;
|
||||
edit: boolean;
|
||||
canValidator?: boolean;
|
||||
onRetry?: (record: UnitItem, index: number) => void;
|
||||
disableRetry?: boolean;
|
||||
onDelete?: (record: UnitItem, index: number) => void;
|
||||
showEdit?: boolean;
|
||||
inModal?: boolean;
|
||||
getColumns?: (record: UnitItem, index: number) => ColumnInfo;
|
||||
}
|
||||
export interface GetColumnsParams extends UploadUnitTableProps {
|
||||
formatType: FormatType;
|
||||
}
|
||||
|
||||
export interface RenderColumnsProps {
|
||||
params: UploadUnitTableProps;
|
||||
record: UnitItem;
|
||||
index: number;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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, { type FC, type ReactNode } from 'react';
|
||||
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { ProcessProgressItem } from '../process-progress-item/process-progress-item';
|
||||
import { ProcessStatus } from '../../types';
|
||||
import { getProcessStatus, getTypeIcon } from './utils';
|
||||
import { type ColumnInfo, type UploadUnitTableProps } from './types';
|
||||
|
||||
const INIT_PERCENT = 10;
|
||||
|
||||
const renderSubText = (
|
||||
status: ProcessStatus,
|
||||
statusDesc: string,
|
||||
subText: ReactNode,
|
||||
) => {
|
||||
if (status === ProcessStatus.Failed) {
|
||||
return (
|
||||
<div
|
||||
data-dtestid={`${KnowledgeE2e.CreateUnitListProgressName}.${'subText'}`}
|
||||
className={'text-12px'}
|
||||
>
|
||||
{statusDesc || I18n.t('datasets_unit_upload_fail')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return subText;
|
||||
};
|
||||
|
||||
export const UploadUnitTable: FC<UploadUnitTableProps> = props => {
|
||||
const { unitList = [], getColumns } = props;
|
||||
if (unitList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className="upload-container">
|
||||
{unitList.map((item, index) => {
|
||||
const curStatus = getProcessStatus(item?.status);
|
||||
const statusDescript = item?.statusDescript || '';
|
||||
|
||||
// 使用getColumns获取每个项目的信息
|
||||
const columnInfo: ColumnInfo = getColumns
|
||||
? getColumns(item, index)
|
||||
: {};
|
||||
const { subText, actions, formatType } = columnInfo;
|
||||
|
||||
return (
|
||||
<ProcessProgressItem
|
||||
key={item.uid}
|
||||
mainText={item.name || '--'}
|
||||
subText={renderSubText(curStatus, statusDescript, subText)}
|
||||
tipText={
|
||||
<span
|
||||
data-dtestid={`${KnowledgeE2e.LocalUploadListStatus}.${item.name}`}
|
||||
>
|
||||
{curStatus === ProcessStatus.Failed
|
||||
? statusDescript || I18n.t('datasets_unit_upload_fail')
|
||||
: I18n.t('datasets_unit_upload_success')}
|
||||
</span>
|
||||
}
|
||||
status={curStatus}
|
||||
avatar={getTypeIcon({ ...item, formatType })}
|
||||
actions={actions}
|
||||
percent={item.percent || INIT_PERCENT}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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 {
|
||||
EntityStatus,
|
||||
UploadStatus,
|
||||
} from '@coze-data/knowledge-resource-processor-core';
|
||||
import { WebStatus } from '@coze-arch/idl/knowledge';
|
||||
import { Image } from '@coze-arch/bot-semi';
|
||||
import {
|
||||
IconUploadPDF,
|
||||
IconUploadCSV,
|
||||
IconUploadDoc,
|
||||
IconUploadTxt,
|
||||
IconUploadTableUrl,
|
||||
IconUploadXLS,
|
||||
IconUploadTextUrl,
|
||||
IconUploadMD,
|
||||
} from '@coze-arch/bot-icons';
|
||||
import { FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { ProcessStatus } from '../../types';
|
||||
|
||||
enum UploadType {
|
||||
PDF = 'pdf',
|
||||
DOCX = 'docx',
|
||||
TXT = 'txt',
|
||||
XLSX = 'xlsx',
|
||||
XLTX = 'xltx',
|
||||
CSV = 'csv',
|
||||
PNG = 'png',
|
||||
JPG = 'jpg',
|
||||
JPEG = 'jpeg',
|
||||
WEBP = 'webp',
|
||||
XLS = 'xls',
|
||||
MD = 'md',
|
||||
}
|
||||
export const getTypeIcon = (params: {
|
||||
type: string | undefined;
|
||||
formatType?: FormatType;
|
||||
url?: string;
|
||||
inModal?: boolean;
|
||||
}) => {
|
||||
const { type, formatType, url } = params;
|
||||
// const iconClassName = inModal ? styles['icon-size-24'] : styles.icon;
|
||||
if (
|
||||
formatType === FormatType.Image &&
|
||||
[UploadType.JPG, UploadType.JPEG, UploadType.PNG, UploadType.WEBP].includes(
|
||||
type as UploadType,
|
||||
)
|
||||
) {
|
||||
return (
|
||||
<Image
|
||||
src={url}
|
||||
width={24}
|
||||
height={24}
|
||||
style={{
|
||||
borderRadius: '4px',
|
||||
marginRight: '12px',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (type === UploadType.MD) {
|
||||
return <IconUploadMD />;
|
||||
}
|
||||
if (type === UploadType.PDF) {
|
||||
return <IconUploadPDF />;
|
||||
}
|
||||
if (type === UploadType.DOCX) {
|
||||
return <IconUploadDoc />;
|
||||
}
|
||||
if (type === UploadType.TXT) {
|
||||
return <IconUploadTxt />;
|
||||
}
|
||||
if (
|
||||
type === UploadType.XLSX ||
|
||||
type === UploadType.XLTX ||
|
||||
type === UploadType.XLS
|
||||
) {
|
||||
return <IconUploadXLS />;
|
||||
}
|
||||
if (type === UploadType.CSV) {
|
||||
return <IconUploadCSV />;
|
||||
}
|
||||
|
||||
return formatType === FormatType.Table ? (
|
||||
<IconUploadTableUrl />
|
||||
) : (
|
||||
<IconUploadTextUrl />
|
||||
);
|
||||
};
|
||||
|
||||
export const getProcessStatus = (
|
||||
status: UploadStatus | WebStatus | EntityStatus,
|
||||
) => {
|
||||
if (
|
||||
status === UploadStatus.UPLOADING ||
|
||||
status === UploadStatus.VALIDATING ||
|
||||
status === UploadStatus.WAIT ||
|
||||
status === WebStatus.Handling ||
|
||||
status === EntityStatus.EntityStatusProcess
|
||||
) {
|
||||
return ProcessStatus.Processing;
|
||||
}
|
||||
|
||||
if (
|
||||
status === UploadStatus.SUCCESS ||
|
||||
status === WebStatus.Finish ||
|
||||
status === EntityStatus.EntityStatusSuccess
|
||||
) {
|
||||
return ProcessStatus.Complete;
|
||||
}
|
||||
|
||||
if (
|
||||
status === UploadStatus.VALIDATE_FAIL ||
|
||||
status === UploadStatus.UPLOAD_FAIL ||
|
||||
status === WebStatus.Failed ||
|
||||
status === EntityStatus.EntityStatusFail
|
||||
) {
|
||||
return ProcessStatus.Failed;
|
||||
}
|
||||
return ProcessStatus.Processing;
|
||||
};
|
||||
Reference in New Issue
Block a user