feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { mergeConfig } from 'vite';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
|
||||
/** @type { import('@storybook/react-vite').StorybookConfig } */
|
||||
const config = {
|
||||
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.tsx'],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-onboarding',
|
||||
'@storybook/addon-interactions',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: 'tag',
|
||||
},
|
||||
viteFinal: config =>
|
||||
mergeConfig(config, {
|
||||
plugins: [
|
||||
svgr({
|
||||
svgrOptions: {
|
||||
native: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,14 @@
|
||||
/** @type { import('@storybook/react').Preview } */
|
||||
const preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
@@ -0,0 +1,5 @@
|
||||
const { defineConfig } = require('@coze-arch/stylelint-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
extends: [],
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
# @coze-data/knowledge-ide-base
|
||||
## 知识库首页ide
|
||||
### 地址:/space/{space_id}/knowledge/{knowledge_id}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"operationSettings": [
|
||||
{
|
||||
"operationName": "test:cov",
|
||||
"outputFolderNames": ["coverage"]
|
||||
},
|
||||
{
|
||||
"operationName": "ts-check",
|
||||
"outputFolderNames": ["dist"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const { defineConfig } = require('@coze-arch/eslint-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
packageRoot: __dirname,
|
||||
preset: 'web',
|
||||
rules: {
|
||||
'@typescript-eslint/naming-convention': 'off',
|
||||
},
|
||||
});
|
||||
127
frontend/packages/data/knowledge/knowledge-ide-base/package.json
Normal file
127
frontend/packages/data/knowledge/knowledge-ide-base/package.json
Normal file
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"name": "@coze-data/knowledge-ide-base",
|
||||
"version": "0.0.1",
|
||||
"description": "Knowledge IDE text base components",
|
||||
"license": "Apache-2.0",
|
||||
"author": "haozhenfei@bytedance.com",
|
||||
"maintainers": [],
|
||||
"exports": {
|
||||
".": "./src/index.tsx",
|
||||
"./types": "./src/types/index.ts",
|
||||
"./utils": "./src/utils/index.ts",
|
||||
"./components/*": "./src/components/*/index.tsx",
|
||||
"./features/*": "./src/features/*/index.tsx",
|
||||
"./hooks/*": "./src/hooks/*/index.ts",
|
||||
"./layout": "./src/layout/index.tsx",
|
||||
"./layout/*": "./src/layout/*/index.tsx",
|
||||
"./context/*": "./src/context/*/index.tsx"
|
||||
},
|
||||
"main": "src/index.tsx",
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"types": [
|
||||
"./src/types/index.ts"
|
||||
],
|
||||
"components/*": [
|
||||
"./src/components/*/index.tsx"
|
||||
],
|
||||
"features/*": [
|
||||
"./src/features/*/index.tsx"
|
||||
],
|
||||
"utils": [
|
||||
"./src/utils/index.ts"
|
||||
],
|
||||
"hooks/*": [
|
||||
"./src/hooks/*/index.ts"
|
||||
],
|
||||
"layout": [
|
||||
"./src/layout/index.tsx"
|
||||
],
|
||||
"layout/*": [
|
||||
"./src/layout/*/index.tsx"
|
||||
],
|
||||
"context/*": [
|
||||
"./src/context/*/index.tsx"
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "exit 0",
|
||||
"lint": "eslint ./ --cache",
|
||||
"test": "vitest --run --passWithNoTests",
|
||||
"test:cov": "npm run test -- --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coze-arch/bot-api": "workspace:*",
|
||||
"@coze-arch/bot-error": "workspace:*",
|
||||
"@coze-arch/bot-flags": "workspace:*",
|
||||
"@coze-arch/bot-hooks": "workspace:*",
|
||||
"@coze-arch/bot-icons": "workspace:*",
|
||||
"@coze-arch/bot-monaco-editor": "workspace:*",
|
||||
"@coze-arch/bot-semi": "workspace:*",
|
||||
"@coze-arch/bot-studio-store": "workspace:*",
|
||||
"@coze-arch/bot-tea": "workspace:*",
|
||||
"@coze-arch/bot-utils": "workspace:*",
|
||||
"@coze-arch/coze-design": "0.0.6-alpha.346d77",
|
||||
"@coze-arch/i18n": "workspace:*",
|
||||
"@coze-arch/logger": "workspace:*",
|
||||
"@coze-arch/report-events": "workspace:*",
|
||||
"@coze-arch/report-tti": "workspace:*",
|
||||
"@coze-common/chat-area-utils": "workspace:*",
|
||||
"@coze-data/e2e": "workspace:*",
|
||||
"@coze-data/feature-register": "workspace:*",
|
||||
"@coze-data/knowledge-common-components": "workspace:*",
|
||||
"@coze-data/knowledge-common-hooks": "workspace:*",
|
||||
"@coze-data/knowledge-common-services": "workspace:*",
|
||||
"@coze-data/knowledge-modal-adapter": "workspace:*",
|
||||
"@coze-data/knowledge-modal-base": "workspace:*",
|
||||
"@coze-data/knowledge-resource-processor-adapter": "workspace:*",
|
||||
"@coze-data/knowledge-resource-processor-base": "workspace:*",
|
||||
"@coze-data/knowledge-resource-processor-core": "workspace:*",
|
||||
"@coze-data/knowledge-stores": "workspace:*",
|
||||
"@coze-data/reporter": "workspace:*",
|
||||
"@coze-data/utils": "workspace:*",
|
||||
"@coze-foundation/local-storage": "workspace:*",
|
||||
"@coze-studio/components": "workspace:*",
|
||||
"@coze-studio/premium-components-adapter": "workspace:*",
|
||||
"@coze-studio/premium-store-adapter": "workspace:*",
|
||||
"@douyinfe/semi-illustrations": "^2.36.0",
|
||||
"ahooks": "^3.7.8",
|
||||
"classnames": "^2.3.2",
|
||||
"dayjs": "^1.11.7",
|
||||
"dompurify": "3.0.8",
|
||||
"immer": "^10.0.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoid": "^4.0.2",
|
||||
"qs": "^6.11.2",
|
||||
"react-router-dom": "^6.22.0",
|
||||
"zustand": "^4.4.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@coze-arch/bot-typings": "workspace:*",
|
||||
"@coze-arch/eslint-config": "workspace:*",
|
||||
"@coze-arch/stylelint-config": "workspace:*",
|
||||
"@coze-arch/ts-config": "workspace:*",
|
||||
"@coze-arch/vitest-config": "workspace:*",
|
||||
"@coze-common/table-view": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@types/dompurify": "3.0.5",
|
||||
"@types/lodash-es": "^4.17.10",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/react": "18.2.37",
|
||||
"@types/react-dom": "18.2.15",
|
||||
"@vitest/coverage-v8": "~3.0.5",
|
||||
"react": "~18.2.0",
|
||||
"react-dom": "~18.2.0",
|
||||
"stylelint": "^15.11.0",
|
||||
"vite-plugin-svgr": "~3.3.0",
|
||||
"vitest": "~3.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.2.0",
|
||||
"react-dom": ">=18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
@common-box-shadow: 0px 2px 8px 0px rgba(31, 35, 41, 0.02),
|
||||
0px 2px 4px 0px rgba(31, 35, 41, 0.02), 0px 2px 2px 0px rgba(31, 35, 41, 0.02);
|
||||
|
||||
.common-svg-icon(@size: 14px, @color: #3370ff) {
|
||||
>svg {
|
||||
width: @size;
|
||||
height: @size;
|
||||
|
||||
>path {
|
||||
fill: @color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M10.8619 1.52827C11.1223 1.78862 11.1223 2.21073 10.8619 2.47108L5.33333 7.99968L10.8619 13.5283C11.1223 13.7886 11.1223 14.2107 10.8619 14.4711C10.6016 14.7314 10.1795 14.7314 9.91912 14.4711L4.39052 8.94248C3.86983 8.42179 3.86982 7.57757 4.39052 7.05687L9.91912 1.52827C10.1795 1.26792 10.6016 1.26792 10.8619 1.52827Z"
|
||||
fill="currentColor" style="fill-opacity:1;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 500 B |
@@ -0,0 +1,11 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.437 6.33333H13.4176C12.7059 4.01711 10.5496 2.33333 8.00001 2.33333C5.45043 2.33333 3.29412 4.01711 2.5824 6.33333H1.19964C1.94734 3.27199 4.70835 1 8.00001 1C11.2917 1 14.0527 3.27199 14.8004 6.33333H15.8963C15.9536 6.33333 16 6.38181 16 6.44161C16 6.47033 15.9891 6.49787 15.9696 6.51818L14.2767 8.28576C14.2159 8.34919 14.1174 8.34919 14.0567 8.28576L12.3637 6.51818C12.3232 6.47589 12.3232 6.40733 12.3637 6.36505C12.3832 6.34474 12.4095 6.33333 12.437 6.33333Z"
|
||||
fill="currentColor" style="fill:currentColor;fill-opacity:1;" />
|
||||
<path
|
||||
d="M3.56296 9.66667H2.5824C3.29411 11.9829 5.45042 13.6667 8 13.6667C10.5496 13.6667 12.7059 11.9829 13.4176 9.66667H14.8004C14.0527 12.728 11.2917 15 8 15C4.70834 15 1.94734 12.728 1.19963 9.66667H0.103709C0.076204 9.66667 0.0498254 9.65526 0.0303755 9.63495C-0.0101252 9.59267 -0.0101252 9.52411 0.0303755 9.48182L1.72333 7.71424C1.78408 7.65081 1.88258 7.65081 1.94333 7.71424L3.63629 9.48182C3.65574 9.50213 3.66667 9.52967 3.66667 9.55839C3.66667 9.61819 3.62024 9.66667 3.56296 9.66667Z"
|
||||
fill="currentColor" style="fill:currentColor;fill-opacity:1;" />
|
||||
<path
|
||||
d="M8.67672 5H7.34015L5.00001 11H6.34407L7.02746 9.34409H8.93271L9.67654 11H11L8.67672 5ZM8.6202 8.00001H7.37163L8.00991 6.31981L8.6202 8.00001Z"
|
||||
fill="currentColor" style="fill:currentColor;fill-opacity:1;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,12 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1930_159006)">
|
||||
<path d="M7.9974 13.9998C4.68369 13.9998 1.9974 11.3135 1.9974 7.99984C1.9974 4.68613 4.68369 1.99984 7.9974 1.99984C11.3111 1.99984 13.9974 4.68613 13.9974 7.99984C13.9974 11.3135 11.3111 13.9998 7.9974 13.9998ZM7.9974 15.3332C12.0475 15.3332 15.3307 12.0499 15.3307 7.99984C15.3307 3.94975 12.0475 0.666504 7.9974 0.666504C3.94731 0.666504 0.664062 3.94975 0.664062 7.99984C0.664062 12.0499 3.94731 15.3332 7.9974 15.3332Z" fill="#DB2E13" style="fill:#DB2E13;fill:color(display-p3 0.8588 0.1804 0.0745);fill-opacity:1;"/>
|
||||
<path d="M7.9974 4.6665C7.62921 4.6665 7.33073 4.96498 7.33073 5.33317V8.6665C7.33073 9.03469 7.62921 9.33317 7.9974 9.33317C8.36559 9.33317 8.66406 9.03469 8.66406 8.6665V5.33317C8.66406 4.96498 8.36559 4.6665 7.9974 4.6665Z" fill="#DB2E13" style="fill:#DB2E13;fill:color(display-p3 0.8588 0.1804 0.0745);fill-opacity:1;"/>
|
||||
<path d="M7.9974 9.99984C7.62921 9.99984 7.33073 10.2983 7.33073 10.6665C7.33073 11.0347 7.62921 11.3332 7.9974 11.3332C8.36559 11.3332 8.66406 11.0347 8.66406 10.6665C8.66406 10.2983 8.36559 9.99984 7.9974 9.99984Z" fill="#DB2E13" style="fill:#DB2E13;fill:color(display-p3 0.8588 0.1804 0.0745);fill-opacity:1;"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1930_159006">
|
||||
<rect width="16" height="16" fill="white" style="fill:white;fill-opacity:1;"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,36 @@
|
||||
.icon-with-suffix {
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
|
||||
:global {
|
||||
.icon-with-suffix-common {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.suffix {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
|
||||
border-radius: 2.667px;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { FormatType } from '@coze-arch/bot-api/memory';
|
||||
import {
|
||||
IconSvgFile,
|
||||
IconSvgSheet,
|
||||
IconSvgUnbound,
|
||||
} from '@coze-arch/bot-icons';
|
||||
|
||||
import style from './index.module.less';
|
||||
|
||||
interface Props {
|
||||
hasSuffix: boolean;
|
||||
formatType?: FormatType;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const IconMap = {
|
||||
[FormatType.Table]: {
|
||||
icon: <IconSvgSheet />,
|
||||
bgColor: '#35C566',
|
||||
suffixIcon: <IconSvgUnbound />,
|
||||
suffixBgColor: 'rgba(255,150,0,1)',
|
||||
},
|
||||
[FormatType.Text]: {
|
||||
icon: <IconSvgFile />,
|
||||
bgColor: 'rgba(34, 136, 255, 1)',
|
||||
suffixIcon: <IconSvgUnbound />,
|
||||
suffixBgColor: 'rgba(255,150,0,1)',
|
||||
},
|
||||
};
|
||||
|
||||
export const IconWithSuffix = (props: Props) => {
|
||||
const { formatType = FormatType.Text, hasSuffix, className } = props;
|
||||
|
||||
return (
|
||||
<div className={classNames(style['icon-with-suffix'], className)}>
|
||||
<div
|
||||
className={classNames('icon-with-suffix-common', 'icon')}
|
||||
style={{
|
||||
backgroundColor: `${IconMap?.[formatType]?.bgColor}`,
|
||||
}}
|
||||
>
|
||||
{IconMap?.[formatType]?.icon}
|
||||
</div>
|
||||
{hasSuffix ? (
|
||||
<div
|
||||
className={classNames('icon-with-suffix-common', 'suffix')}
|
||||
style={{
|
||||
backgroundColor: `${IconMap?.[formatType]?.suffixBgColor}`,
|
||||
}}
|
||||
>
|
||||
{IconMap?.[formatType]?.suffixIcon}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
// UI稿的 confirm modal 和 semi 默认的不一样,需要手动调整样式
|
||||
.confirm-modal {
|
||||
:global {
|
||||
.semi-modal-header {
|
||||
margin-bottom: 16px;
|
||||
|
||||
// icon 和 title 的间距
|
||||
.semi-modal-icon-wrapper {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
// title 颜色
|
||||
.semi-modal-confirm-title-text {
|
||||
color: rgba(29, 28, 35, 100%);
|
||||
}
|
||||
|
||||
// 关闭 icon 的 hover 颜色
|
||||
.semi-button:hover {
|
||||
background-color: rgba(46, 46, 56, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.semi-modal-body {
|
||||
margin: 0;
|
||||
padding: 16px 0;
|
||||
|
||||
.semi-modal-confirm-content {
|
||||
color: rgba(29, 28, 35, 100%)
|
||||
}
|
||||
}
|
||||
|
||||
.semi-modal-footer button {
|
||||
min-width: 96px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 React from 'react';
|
||||
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { UIIconButton, Icon, Tooltip, UIModal } from '@coze-arch/bot-semi';
|
||||
import { IconCloseKnowledge, IconWarningSize24 } from '@coze-arch/bot-icons';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { ReactComponent as SvgTranslate } from '@/assets/icon_translate.svg';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface AutoGenerateButtonProps {
|
||||
currentValue: string;
|
||||
document_id: string;
|
||||
disable: boolean;
|
||||
onChange: (value: string) => void;
|
||||
onProgress: (loading: boolean) => void;
|
||||
}
|
||||
|
||||
export const AutoGenerateButton: React.FC<AutoGenerateButtonProps> = ({
|
||||
currentValue,
|
||||
document_id,
|
||||
disable,
|
||||
onChange,
|
||||
onProgress,
|
||||
}) => {
|
||||
const handleGenerate = async () => {
|
||||
const generateCaption = async () => {
|
||||
onProgress(true);
|
||||
try {
|
||||
const res = await KnowledgeApi.ExtractPhotoCaption({
|
||||
document_id,
|
||||
});
|
||||
if (res.caption) {
|
||||
onChange(res.caption);
|
||||
}
|
||||
} catch (error) {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeGeneratePhotoCaption,
|
||||
error: error as Error,
|
||||
});
|
||||
} finally {
|
||||
onProgress(false);
|
||||
}
|
||||
};
|
||||
// 如果没有 caption,则不用confirm
|
||||
if (!currentValue) {
|
||||
await generateCaption();
|
||||
return;
|
||||
}
|
||||
UIModal.warning({
|
||||
// 必填参数,统一 confirm modal 的样式
|
||||
className: styles['confirm-modal'],
|
||||
closeIcon: <IconCloseKnowledge />,
|
||||
|
||||
// 自定义参数
|
||||
title: I18n.t('knowledge_photo_021'),
|
||||
content: I18n.t('knowledge_photo_022'),
|
||||
icon: <IconWarningSize24 />,
|
||||
cancelText: I18n.t('Cancel'),
|
||||
okText: I18n.t('Confirm'),
|
||||
okButtonProps: { theme: 'solid', type: 'warning' },
|
||||
onOk: () => {
|
||||
generateCaption();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip content={I18n.t('knowledge_photo_020')}>
|
||||
<UIIconButton
|
||||
icon={
|
||||
<Icon
|
||||
svg={
|
||||
<SvgTranslate
|
||||
color={disable ? 'rgba(28, 31, 35, 0.35)' : '#4D53E8'}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
className="absolute !bottom-[8px] !left-[12px]"
|
||||
onClick={handleGenerate}
|
||||
disabled={disable}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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 } from 'react';
|
||||
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { formatBytes } from '@coze-arch/bot-utils';
|
||||
import {
|
||||
FormatType,
|
||||
type Dataset,
|
||||
type DocumentInfo,
|
||||
DocumentSource,
|
||||
DocumentStatus,
|
||||
StorageLocation,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
import { Space, Tag } from '@coze-arch/coze-design';
|
||||
|
||||
import { type ProgressMap } from '@/types';
|
||||
import { DOCUMENT_UPDATE_TYPE_MAP } from '@/constant';
|
||||
|
||||
import { getSourceName } from '../../utils';
|
||||
|
||||
export interface HeaderTagProps {
|
||||
dataSetDetail: Dataset;
|
||||
docInfo?: DocumentInfo;
|
||||
progressMap?: ProgressMap;
|
||||
}
|
||||
// eslint-disable-next-line complexity
|
||||
export const HeaderTags = ({
|
||||
dataSetDetail,
|
||||
docInfo,
|
||||
progressMap = {},
|
||||
}: HeaderTagProps) => {
|
||||
const formatType = dataSetDetail?.format_type;
|
||||
const updateFrequencyStr = useMemo(() => {
|
||||
if (!docInfo) {
|
||||
return '';
|
||||
}
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
let str: string = DOCUMENT_UPDATE_TYPE_MAP[docInfo?.update_type];
|
||||
if (docInfo.update_interval) {
|
||||
str = `${I18n.t('datasets_segment_tag_updateFrequency', {
|
||||
num: docInfo.update_interval,
|
||||
})}`;
|
||||
}
|
||||
return str;
|
||||
}, [docInfo]);
|
||||
return (
|
||||
<div className="flex pb-[4px]" data-testid={KnowledgeE2e.UnitDetailTags}>
|
||||
<Space spacing={4} className="[&_.semi-tag-content]:font-medium">
|
||||
{/* file size */}
|
||||
{dataSetDetail?.all_file_size ? (
|
||||
<Tag size="mini" color="primary">
|
||||
{formatBytes(parseInt(String(dataSetDetail.all_file_size)))}
|
||||
</Tag>
|
||||
) : null}
|
||||
|
||||
{/* table source type */}
|
||||
{formatType === FormatType.Table && !!docInfo && (
|
||||
<Tag size="mini" color="primary">
|
||||
{getSourceName(docInfo)}
|
||||
</Tag>
|
||||
)}
|
||||
|
||||
{/* table api update type */}
|
||||
{formatType === FormatType.Table &&
|
||||
docInfo &&
|
||||
docInfo?.source_type === DocumentSource.Web ? (
|
||||
<Tag size="mini" color="primary">
|
||||
{updateFrequencyStr}
|
||||
</Tag>
|
||||
) : null}
|
||||
|
||||
{/* doc count */}
|
||||
{formatType === FormatType.Text && !!dataSetDetail?.doc_count && (
|
||||
<Tag size="mini" color="primary">
|
||||
{I18n.t('kl2_009', {
|
||||
num: dataSetDetail?.doc_count ?? 0,
|
||||
})}
|
||||
</Tag>
|
||||
)}
|
||||
|
||||
{/* 图片来源 */}
|
||||
{formatType === FormatType.Image && (
|
||||
<Tag size="mini" color="primary">
|
||||
{I18n.t('dataset_detail_source_local')}
|
||||
</Tag>
|
||||
)}
|
||||
|
||||
{/* 图片数量 */}
|
||||
{formatType === FormatType.Image && !!dataSetDetail?.doc_count && (
|
||||
<Tag size="mini" color="primary">
|
||||
{I18n.t('knowledge_photo_015', {
|
||||
num: dataSetDetail?.doc_count || 0,
|
||||
})}
|
||||
</Tag>
|
||||
)}
|
||||
|
||||
{/* 未添加文档时不展示 */}
|
||||
{formatType !== FormatType.Image && !!dataSetDetail?.doc_count && (
|
||||
<>
|
||||
{/* slice count */}
|
||||
<Tag size="mini" color="primary">
|
||||
{I18n.t('datasets_segment_tag_segments', {
|
||||
num: dataSetDetail?.slice_count ?? 0,
|
||||
})}
|
||||
</Tag>
|
||||
{/* hit count */}
|
||||
<Tag size="mini" color="primary">
|
||||
{I18n.t('datasets_segment_card_hit', {
|
||||
num: dataSetDetail?.hit_count,
|
||||
})}
|
||||
</Tag>
|
||||
</>
|
||||
)}
|
||||
|
||||
{dataSetDetail?.storage_location === StorageLocation.OpenSearch ? (
|
||||
<Tag size="mini" color="cyan">
|
||||
{I18n.t('knowledge_es_001')}
|
||||
</Tag>
|
||||
) : null}
|
||||
|
||||
{/* loading */}
|
||||
{Boolean(dataSetDetail?.processing_file_id_list) &&
|
||||
Boolean(dataSetDetail?.processing_file_id_list?.length) && (
|
||||
<Tag
|
||||
size="mini"
|
||||
color="blue"
|
||||
data-testid={KnowledgeE2e.UnitDetailTagsProcessing}
|
||||
>
|
||||
{I18n.t('datasets_segment_tag_processing')}
|
||||
{docInfo?.format_type === FormatType.Table &&
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
progressMap?.[docInfo?.document_id]
|
||||
? // @ts-expect-error -- linter-disable-autofix
|
||||
`${progressMap?.[docInfo?.document_id]?.progress}%`
|
||||
: ''}
|
||||
</Tag>
|
||||
)}
|
||||
|
||||
{/** Table error */}
|
||||
{formatType === FormatType.Table &&
|
||||
docInfo?.status === DocumentStatus.Failed && (
|
||||
<Tag
|
||||
size="mini"
|
||||
color="red"
|
||||
data-testid={KnowledgeE2e.UnitDetailTagsFailed}
|
||||
>
|
||||
{docInfo?.status_descript || I18n.t('dataset_process_fail')}
|
||||
</Tag>
|
||||
)}
|
||||
</Space>
|
||||
</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.
|
||||
*/
|
||||
|
||||
export { HeaderTags } from './header-tags';
|
||||
export { RelatedBotsList } from './related-bots-list';
|
||||
export { FailedTag } from './tag';
|
||||
export { IconWithSuffix } from './Icon-with-suffix';
|
||||
export { KnowledgePreviewNavigation } from './preview-navigation';
|
||||
export { KnowledgeModalNavBar } from './knowledge-modal-nav-bar';
|
||||
export { KnowledgeIDENavBar } from './knowledge-nav-bar';
|
||||
@@ -0,0 +1,61 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
.table-config-menu-down {
|
||||
padding: 4px;
|
||||
font-size: 12px;
|
||||
|
||||
.dropdown-item-line {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-dropdown-menu {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.semi-dropdown-item {
|
||||
min-width: 126px;
|
||||
height: 32px !important;
|
||||
padding: 8px 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item-link {
|
||||
font-size: 12px;
|
||||
color: var(--coz-fg-hglt) !important;
|
||||
|
||||
:global {
|
||||
.semi-dropdown-item-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item-link-icon {
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-dropdown-item-icon {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
&-right {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-button-content-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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, type ReactNode } from 'react';
|
||||
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import {
|
||||
IconCozSetting,
|
||||
IconCozArrowUp,
|
||||
IconCozArrowDown,
|
||||
} from '@coze-arch/coze-design/icons';
|
||||
import { Button, Menu } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface KnowledgeConfigMenuProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const KnowledgeConfigMenu = (props: KnowledgeConfigMenuProps) => {
|
||||
const { children } = props;
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<Menu
|
||||
clickToHide
|
||||
keepDOM
|
||||
trigger="click"
|
||||
position="bottomRight"
|
||||
onVisibleChange={setVisible}
|
||||
render={
|
||||
<Menu.SubMenu mode="menu" className={styles['table-config-menu-down']}>
|
||||
{children}
|
||||
</Menu.SubMenu>
|
||||
}
|
||||
>
|
||||
<Button
|
||||
className={styles['action-btn']}
|
||||
data-testid={KnowledgeE2e.SegmentDetailSystemBtn}
|
||||
icon={
|
||||
visible ? (
|
||||
<IconCozArrowUp className={'text-[12px]'} />
|
||||
) : (
|
||||
<IconCozArrowDown className={'text-[12px]'} />
|
||||
)
|
||||
}
|
||||
iconPosition="right"
|
||||
color="primary"
|
||||
style={{
|
||||
minWidth: '45px',
|
||||
padding: '6px 6px 6px 8px',
|
||||
}}
|
||||
>
|
||||
<IconCozSetting />
|
||||
</Button>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
export interface TableConfigButtonProps {
|
||||
documentInfo: DocumentInfo;
|
||||
onChangeDocList?: (docList: DocumentInfo[]) => void;
|
||||
reload: () => void;
|
||||
canEdit?: boolean;
|
||||
}
|
||||
@@ -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 interface TextConfigButtonProps {
|
||||
reload: () => void;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
@import '../../assets/common.less';
|
||||
|
||||
.navbar {
|
||||
.brief {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--coz-fg-primary);
|
||||
|
||||
:global {
|
||||
.semi-avatar {
|
||||
margin-right: 8px;
|
||||
background: transparent;
|
||||
border: 0.5px solid var(--coz-stroke-primary);
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
padding: 8px!important;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
.doc-icon-note {
|
||||
.common-svg-icon(36px, null);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 classNames from 'classnames';
|
||||
import {
|
||||
useKnowledgeParams,
|
||||
useKnowledgeStore,
|
||||
} from '@coze-data/knowledge-stores';
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import {
|
||||
FormatType,
|
||||
type Dataset,
|
||||
type DocumentInfo,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
import { IconCozCross } from '@coze-arch/coze-design/icons';
|
||||
import { IconButton, Avatar, Space } from '@coze-arch/coze-design';
|
||||
|
||||
import { getFormatTypeFromUnitType } from '@/utils';
|
||||
import { RenderDocumentIcon } from '@/components/render-document-icon';
|
||||
import { PhotoFilter } from '@/components/photo-filter';
|
||||
import { HeaderTags } from '@/components/header-tags';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface KnowledgeModalNavBarProps {
|
||||
title: string;
|
||||
datasetDetail?: Dataset;
|
||||
docInfo?: DocumentInfo;
|
||||
importKnowledgeSourceButton?: React.ReactNode;
|
||||
actionButtons?: React.ReactNode;
|
||||
onBack?: () => void;
|
||||
beforeBack?: () => void;
|
||||
}
|
||||
|
||||
export const KnowledgeModalNavBar: React.FC<KnowledgeModalNavBarProps> = ({
|
||||
title,
|
||||
actionButtons,
|
||||
datasetDetail,
|
||||
docInfo,
|
||||
onBack,
|
||||
beforeBack,
|
||||
importKnowledgeSourceButton,
|
||||
}) => {
|
||||
const setSearchValue = useKnowledgeStore(state => state.setSearchValue);
|
||||
const dataSetDetail = useKnowledgeStore(state => state.dataSetDetail);
|
||||
const canEdit = useKnowledgeStore(state => state.canEdit);
|
||||
|
||||
const params = useKnowledgeParams();
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
setSearchValue('');
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const isImageFormat = dataSetDetail?.format_type === FormatType.Image;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex items-center justify-between shrink-0 h-[56px]',
|
||||
styles.navbar,
|
||||
)}
|
||||
data-testid={KnowledgeE2e.KnowledgeAddContentNavBar}
|
||||
>
|
||||
<div className={styles.brief}>
|
||||
<IconButton
|
||||
color="secondary"
|
||||
icon={<IconCozCross className="text-[16px]" />}
|
||||
iconPosition="left"
|
||||
className={`${styles['back-icon']} mr-[8px]`}
|
||||
onClick={() => {
|
||||
beforeBack?.();
|
||||
onBack?.();
|
||||
}}
|
||||
></IconButton>
|
||||
{datasetDetail?.icon_url ? (
|
||||
<Avatar src={datasetDetail?.icon_url} shape="square" />
|
||||
) : (
|
||||
<RenderDocumentIcon
|
||||
formatType={getFormatTypeFromUnitType(params.type ?? UnitType.TEXT)}
|
||||
className={styles['doc-icon-note']}
|
||||
iconSuffixClassName="icon-with-suffix-overlay"
|
||||
/>
|
||||
)}
|
||||
<div className="ml-[12px]">
|
||||
<p className="text-[18px] font-medium">{title}</p>
|
||||
{!!datasetDetail && (
|
||||
<HeaderTags dataSetDetail={datasetDetail} docInfo={docInfo} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.toolbar}>
|
||||
<Space spacing={12}>
|
||||
{isImageFormat ? <PhotoFilter /> : null}
|
||||
{/* 导入按钮 */}
|
||||
{canEdit ? importKnowledgeSourceButton : null}
|
||||
{actionButtons}
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,142 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
@import '../../assets/common.less';
|
||||
|
||||
.brief {
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
:global {
|
||||
.semi-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
background: transparent;
|
||||
border: 0.5px solid var(--coz-stroke-primary);
|
||||
border-radius: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.bot-count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
width: 220px;
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: rgba(29, 28, 36, 35%);
|
||||
|
||||
&-text {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
cursor: pointer;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-top: 1px;
|
||||
|
||||
path {
|
||||
fill: #C6CACD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.action-right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.tags {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.title {
|
||||
max-width: 800px;
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
color: var(--coz-fg-plus);
|
||||
}
|
||||
|
||||
.description {
|
||||
overflow: hidden;
|
||||
|
||||
margin-top: 6px;
|
||||
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
line-height: 22px;
|
||||
color: var(--light-usage-text-color-text-1, rgb(28 29 35 / 80%));
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-tag-blue-light {
|
||||
color: var(--light-color-brand-brand-6, #304cdb);
|
||||
background: var(--light-color-brand-brand-1, #d9e2ff);
|
||||
}
|
||||
|
||||
.semi-button {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.icon-with-suffix-overlay {
|
||||
.icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
[role="img"] {
|
||||
.common-svg-icon(24px, null);
|
||||
}
|
||||
}
|
||||
|
||||
.suffix {
|
||||
top: 27px;
|
||||
left: 27px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
[role="img"] {
|
||||
.common-svg-icon(12px, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.doc-icon-note {
|
||||
border-radius: 8px;
|
||||
.common-svg-icon(36px, null);
|
||||
}
|
||||
|
||||
.bot-used-count {
|
||||
display: flex;
|
||||
|
||||
:global {
|
||||
.related-bots-circle {
|
||||
margin-top: -5px;
|
||||
margin-right: 4px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* 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 */
|
||||
/* eslint-disable complexity */
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { useKnowledgeParams, useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { useEditKnowledgeModal } from '@coze-data/knowledge-modal-adapter';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { useFlags } from '@coze-arch/bot-flags';
|
||||
import { FormatType, type Dataset } from '@coze-arch/bot-api/knowledge';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
import {
|
||||
IconCozArrowLeft,
|
||||
IconCozEdit,
|
||||
IconCozInfoCircle,
|
||||
} from '@coze-arch/coze-design/icons';
|
||||
import {
|
||||
Space,
|
||||
IconButton,
|
||||
Avatar,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from '@coze-arch/coze-design';
|
||||
|
||||
import { getUnitType } from '@/utils';
|
||||
import { type ProgressMap } from '@/types';
|
||||
import { RenderDocumentIcon } from '@/components/render-document-icon';
|
||||
import { PhotoFilter } from '@/components/photo-filter';
|
||||
import { HeaderTags, RelatedBotsList } from '@/components';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface KnowledgeIDENavBarProps {
|
||||
progressMap: ProgressMap;
|
||||
hideBackButton?: boolean;
|
||||
textConfigButton?: React.ReactNode;
|
||||
tableConfigButton?: React.ReactNode;
|
||||
importKnowledgeSourceButton?: React.ReactNode;
|
||||
onChangeDataset: (dataset: Dataset) => void;
|
||||
onBack?: () => void;
|
||||
}
|
||||
|
||||
export const KnowledgeIDENavBar = ({
|
||||
onChangeDataset,
|
||||
progressMap,
|
||||
hideBackButton,
|
||||
textConfigButton,
|
||||
tableConfigButton,
|
||||
importKnowledgeSourceButton,
|
||||
onBack,
|
||||
}: KnowledgeIDENavBarProps) => {
|
||||
const dataSetDetail = useKnowledgeStore(state => state.dataSetDetail);
|
||||
const canEdit = useKnowledgeStore(state => state.canEdit);
|
||||
const documentList = useKnowledgeStore(state => state.documentList);
|
||||
const navigate = useNavigate();
|
||||
const params = useKnowledgeParams();
|
||||
|
||||
const [FLAGS] = useFlags();
|
||||
|
||||
const { node: editKnowledgeModal, edit } = useEditKnowledgeModal({
|
||||
onOk: async formValue => {
|
||||
await KnowledgeApi.UpdateDataset({
|
||||
dataset_id: formValue.id,
|
||||
name: formValue.name,
|
||||
icon_uri: formValue.icon_uri?.[0].uid,
|
||||
description: formValue.description,
|
||||
});
|
||||
onChangeDataset({
|
||||
...dataSetDetail,
|
||||
name: formValue?.name || dataSetDetail?.name,
|
||||
description: formValue?.description || dataSetDetail?.description,
|
||||
icon_uri: formValue.icon_uri?.at(0)?.uid || dataSetDetail?.icon_uri,
|
||||
icon_url: formValue.icon_uri?.at(0)?.url || dataSetDetail?.icon_url,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const isTableFormat = dataSetDetail?.format_type === FormatType.Table;
|
||||
const isImageFormat = dataSetDetail?.format_type === FormatType.Image;
|
||||
const isShowResegmentBtn =
|
||||
canEdit &&
|
||||
!isTableFormat &&
|
||||
!!dataSetDetail?.doc_count &&
|
||||
!dataSetDetail?.processing_file_id_list?.length &&
|
||||
!isImageFormat;
|
||||
|
||||
const documentInfo = documentList?.[0];
|
||||
const unitType = useMemo(() => {
|
||||
if (documentInfo) {
|
||||
return getUnitType({
|
||||
format_type: FormatType.Table,
|
||||
source_type: documentInfo?.source_type,
|
||||
});
|
||||
}
|
||||
return UnitType.TABLE_API;
|
||||
}, [documentInfo]);
|
||||
const isShowLinkUrl = useMemo(
|
||||
() =>
|
||||
unitType &&
|
||||
[
|
||||
UnitType.TABLE_API,
|
||||
UnitType.TABLE_GOOGLE_DRIVE,
|
||||
UnitType.TABLE_FEISHU,
|
||||
UnitType.TABLE_LARK,
|
||||
].includes(unitType),
|
||||
[unitType],
|
||||
);
|
||||
// link 或者 action 二选一存在时才展示
|
||||
const showTableConfigButton =
|
||||
(isShowLinkUrl || canEdit) && isTableFormat && documentList?.length;
|
||||
|
||||
const handleBack = () => {
|
||||
onBack?.();
|
||||
navigate(`/space/${params.spaceID}/library`);
|
||||
};
|
||||
|
||||
const fromProject = params.biz === 'project';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex items-center justify-between shrink-0',
|
||||
fromProject ? 'px-[16px] py-[12px]' : 'h-[56px]',
|
||||
styles.brief,
|
||||
)}
|
||||
>
|
||||
<div className={styles.info}>
|
||||
{hideBackButton ? null : (
|
||||
<IconButton
|
||||
color="secondary"
|
||||
icon={<IconCozArrowLeft className="text-[16px]" />}
|
||||
iconPosition="left"
|
||||
onClick={handleBack}
|
||||
className="mr-[4px]"
|
||||
></IconButton>
|
||||
)}
|
||||
{/* icon */}
|
||||
<div className={styles.icon}>
|
||||
{dataSetDetail?.icon_url ? (
|
||||
<Avatar
|
||||
src={dataSetDetail?.icon_url}
|
||||
shape="square"
|
||||
size="default"
|
||||
/>
|
||||
) : (
|
||||
<RenderDocumentIcon
|
||||
formatType={dataSetDetail?.format_type || FormatType.Text}
|
||||
className={styles['doc-icon-note']}
|
||||
iconSuffixClassName="icon-with-suffix-overlay"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<Typography.Text
|
||||
data-testid={KnowledgeE2e.SegmentDetailTitle}
|
||||
className={styles.title}
|
||||
weight={500}
|
||||
ellipsis={{
|
||||
showTooltip: {
|
||||
opts: { content: dataSetDetail?.name },
|
||||
},
|
||||
}}
|
||||
>
|
||||
{dataSetDetail?.name}
|
||||
</Typography.Text>
|
||||
{canEdit ? (
|
||||
<Tooltip content={I18n.t('datasets_segment_edit')}>
|
||||
<IconButton
|
||||
data-testid={KnowledgeE2e.SegmentDetailTitleEditIcon}
|
||||
size="mini"
|
||||
color="secondary"
|
||||
icon={<IconCozEdit className="text-[14px]" />}
|
||||
iconPosition="left"
|
||||
wrapperClass="text-[0] leading-none"
|
||||
className="coz-fg-secondary"
|
||||
onClick={() => {
|
||||
edit({
|
||||
id: dataSetDetail.dataset_id || '',
|
||||
name: dataSetDetail?.name,
|
||||
description: dataSetDetail?.description,
|
||||
icon_uri: [
|
||||
{
|
||||
url: dataSetDetail?.icon_url || '',
|
||||
uid: dataSetDetail?.icon_uri || '',
|
||||
},
|
||||
],
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
{FLAGS['bot.data.knowledge_bots_count'] ? (
|
||||
<div className={styles['bot-count']}>
|
||||
<div className={styles['bot-count-text']}>
|
||||
{I18n.t('knowledge_optimize_019', {
|
||||
n: dataSetDetail?.bot_used_count ?? 0,
|
||||
})}
|
||||
</div>
|
||||
{!!dataSetDetail?.bot_used_count && (
|
||||
<Tooltip
|
||||
autoAdjustOverflow={true}
|
||||
position={
|
||||
dataSetDetail?.bot_used_count > 2 ? 'bottom' : 'top'
|
||||
}
|
||||
content={
|
||||
<RelatedBotsList
|
||||
datasetId={dataSetDetail?.dataset_id ?? ''}
|
||||
classNameItem={styles['bot-used-count']}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<IconCozInfoCircle className={styles['bot-count-icon']} />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<HeaderTags
|
||||
dataSetDetail={dataSetDetail}
|
||||
docInfo={documentList?.[0]}
|
||||
progressMap={progressMap}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Space spacing={10}>
|
||||
{isImageFormat ? <PhotoFilter /> : null}
|
||||
{isShowResegmentBtn ? textConfigButton : null}
|
||||
{showTableConfigButton ? tableConfigButton : null}
|
||||
{canEdit ? importKnowledgeSourceButton : null}
|
||||
</Space>
|
||||
</div>
|
||||
{editKnowledgeModal}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 { Menu } from '@coze-arch/coze-design';
|
||||
|
||||
interface KnowledgeSourceMenuItemProps {
|
||||
value?: string;
|
||||
onClick?: (value: string) => void;
|
||||
title: string;
|
||||
icon?: React.ReactNode;
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
export const KnowledgeSourceMenuItem = (
|
||||
props: KnowledgeSourceMenuItemProps,
|
||||
) => {
|
||||
const { title, icon, testId, value, onClick } = props;
|
||||
return (
|
||||
<Menu.Item
|
||||
key={value}
|
||||
icon={icon ?? null}
|
||||
onClick={() => {
|
||||
if (value && onClick) {
|
||||
onClick.call(this, value);
|
||||
}
|
||||
}}
|
||||
data-testid={testId}
|
||||
>
|
||||
{title}
|
||||
</Menu.Item>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
.hidden-tooltip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.create-opt-select-down {
|
||||
:global {
|
||||
.semi-dropdown-item {
|
||||
min-width: 126px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 { Menu } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface KnowledgeSourceMenuProps {
|
||||
triggerComponent: ReactNode;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const KnowledgeSourceMenu = (props: KnowledgeSourceMenuProps) => {
|
||||
const { triggerComponent, onVisibleChange, children } = props;
|
||||
|
||||
return (
|
||||
<Menu
|
||||
clickToHide
|
||||
trigger="click"
|
||||
position="bottomRight"
|
||||
onVisibleChange={onVisibleChange}
|
||||
render={
|
||||
<Menu.SubMenu mode="menu" className={styles['create-opt-select-down']}>
|
||||
{children}
|
||||
</Menu.SubMenu>
|
||||
}
|
||||
>
|
||||
{triggerComponent}
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
.common-svg-icon(@size: 14px, @color: #3370ff) {
|
||||
>svg {
|
||||
width: @size;
|
||||
height: @size;
|
||||
|
||||
>path {
|
||||
fill: @color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.radio-wrapper {
|
||||
.radio-group {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.radio-item {
|
||||
flex: 0 0 49%;
|
||||
}
|
||||
|
||||
.displayNone {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.form-line-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-line {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.pt6 {
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-radioGroup-vertical {
|
||||
row-gap: 8px;
|
||||
}
|
||||
|
||||
.semi-radio-cardRadioGroup {
|
||||
column-gap: 16px;
|
||||
border: 1px solid var(--coz-stroke-plus);
|
||||
|
||||
&:hover {
|
||||
background: var(--coz-mg-secondary-hovered);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--coz-mg-secondary-pressed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.radio-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-size-16 {
|
||||
.common-svg-icon(16px, null);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 { RadioGroup } from '@coze-arch/coze-design';
|
||||
import type { RadioGroupProps } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface KnowledgeSourceRadioGroupProps {
|
||||
value: RadioGroupProps['value'];
|
||||
onChange: RadioGroupProps['onChange'];
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const KnowledgeSourceRadioGroup = (
|
||||
props: KnowledgeSourceRadioGroupProps,
|
||||
) => {
|
||||
const { value, onChange, children } = props;
|
||||
|
||||
return (
|
||||
<div className={styles['radio-wrapper']}>
|
||||
<RadioGroup
|
||||
type="pureCard"
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
direction="horizontal"
|
||||
name="format-type"
|
||||
className={styles['radio-group']}
|
||||
>
|
||||
{children}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 { Radio, Typography } from '@coze-arch/coze-design';
|
||||
|
||||
interface KnowledgeSourceRadioProps {
|
||||
title: string;
|
||||
description: string;
|
||||
icon?: React.ReactNode;
|
||||
e2e?: string;
|
||||
key?: string;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export const KnowledgeSourceRadio = (props: KnowledgeSourceRadioProps) => {
|
||||
const { title, description, icon, e2e, key, value } = props;
|
||||
return (
|
||||
<Radio
|
||||
key={key}
|
||||
value={value}
|
||||
extra={
|
||||
<Typography.Text
|
||||
type="tertiary"
|
||||
ellipsis={{
|
||||
showTooltip: {
|
||||
opts: { content: description },
|
||||
},
|
||||
}}
|
||||
style={{ lineHeight: '20px', width: 180 }}
|
||||
>
|
||||
{description}
|
||||
</Typography.Text>
|
||||
}
|
||||
className="flex-[0_0_49%]"
|
||||
data-testid={e2e}
|
||||
>
|
||||
{icon ? <div className="flex items-center mr-2">{icon}</div> : null}
|
||||
{title}
|
||||
</Radio>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,243 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
.photo-list {
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
height: calc(100vh - 170px);
|
||||
padding: 0 24px;
|
||||
|
||||
.photo-list-spin {
|
||||
flex: 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
|
||||
.spin {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-group {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
|
||||
// Card 整体
|
||||
.card {
|
||||
cursor: auto;
|
||||
width: 222px;
|
||||
height: 258px;
|
||||
border-radius: 8px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 14px 0 rgba(0, 0, 0, 8%);
|
||||
}
|
||||
|
||||
:global {
|
||||
// 固定高度142,超出高度的图片,截取居中部分展示
|
||||
.semi-card-cover {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 142px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-disabled {
|
||||
:global {
|
||||
.semi-card-cover {
|
||||
background: var(--Light-usage-fill---color-fill-0, rgba(46, 46, 57, 4%));
|
||||
border-radius: var(--default, 8px) var(--default, 8px) 0 0;
|
||||
|
||||
svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Card 封面
|
||||
.card-cover {
|
||||
cursor: pointer;
|
||||
border-radius: 8px 8px 0 0;
|
||||
|
||||
// 设置最小高度142,保证填满封面
|
||||
img {
|
||||
min-height: 142px;
|
||||
}
|
||||
}
|
||||
|
||||
.prohibit-cover {
|
||||
overflow: hidden;
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 16px; /* 133.333% */
|
||||
color: var(--Light-usage-text---color-text-3, rgba(29, 28, 36, 35%));
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Card 内容区 (title + description)
|
||||
.card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
.photo-name {
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: rgba(29, 28, 35, 100%);
|
||||
}
|
||||
|
||||
.photo-description {
|
||||
height: 32px;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
|
||||
.failed-tag {
|
||||
padding: 0 6px;
|
||||
color: rgba(219, 46, 19, 100%);
|
||||
background-color: rgba(255, 224, 210, 100%);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.processing-tag {
|
||||
padding: 0 6px;
|
||||
color: #304cdb;
|
||||
background-color: #d9e2ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Card 底部栏(时间 + 操作按钮)
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 24px;
|
||||
|
||||
.create-time {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: rgba(28, 29, 35, 35%)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// UI稿的 confirm modal 和 semi 默认的不一样,需要手动调整样式
|
||||
.confirm-modal {
|
||||
:global {
|
||||
.semi-modal-header {
|
||||
margin-bottom: 16px;
|
||||
|
||||
// icon 和 title 的间距
|
||||
.semi-modal-icon-wrapper {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
// title 颜色
|
||||
.semi-modal-confirm-title-text {
|
||||
color: rgba(29, 28, 35, 100%);
|
||||
}
|
||||
|
||||
// 关闭 icon 的 hover 颜色
|
||||
.semi-button:hover {
|
||||
background-color: rgba(46, 46, 56, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.semi-modal-body {
|
||||
margin: 0;
|
||||
padding: 16px 0;
|
||||
|
||||
.semi-modal-confirm-content {
|
||||
color: rgba(29, 28, 35, 100%)
|
||||
}
|
||||
}
|
||||
|
||||
.semi-modal-footer button {
|
||||
min-width: 96px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 编辑 photo 信息的弹窗
|
||||
.modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
|
||||
// photo 大图展示
|
||||
// 用 flex 解决宽高和内部 image 不一致的问题
|
||||
.photo-large {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
.arrow-button {
|
||||
position: absolute;
|
||||
top: 126px;
|
||||
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 12px;
|
||||
|
||||
color: #1D1C23;
|
||||
|
||||
background-color: rgba(255, 255, 255, 50%);
|
||||
border: none;
|
||||
border-radius: 26px;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 20%), 0 0 1px 0 rgba(0, 0, 0, 20%);
|
||||
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #4D53E8;
|
||||
background-color: rgba(255, 255, 255, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// photo 描述输入框
|
||||
.photo-caption-textarea {
|
||||
position: relative;
|
||||
|
||||
:global {
|
||||
.semi-input-textarea-counter {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.ai-generate-button {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
// 解决 disabled button 样式错位的问题
|
||||
>span {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* 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 */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import {
|
||||
UIModal,
|
||||
Image,
|
||||
TextArea,
|
||||
Spin,
|
||||
IconButton,
|
||||
Icon,
|
||||
} from '@coze-arch/bot-semi';
|
||||
import { DocumentStatus, type PhotoInfo } from '@coze-arch/bot-api/knowledge';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { type ProgressMap } from '@/types';
|
||||
import { ReactComponent as SvgArrowLeft } from '@/assets/icon_arrow_left.svg';
|
||||
|
||||
import { AutoGenerateButton } from '../auto-generate-photo-detail-button';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface UsePhotoDetailModalParams {
|
||||
photo: PhotoInfo | undefined;
|
||||
photoList: PhotoInfo[] | undefined;
|
||||
progressMap: ProgressMap;
|
||||
canEdit: boolean;
|
||||
setCurrentPhotoId: (v: string) => void;
|
||||
reload: () => void;
|
||||
onCancel?: () => void;
|
||||
onSubmit?: () => void;
|
||||
}
|
||||
|
||||
export const usePhotoDetailModal = (params: UsePhotoDetailModalParams) => {
|
||||
const {
|
||||
photo = {},
|
||||
photoList = [],
|
||||
canEdit = false,
|
||||
setCurrentPhotoId,
|
||||
reload,
|
||||
progressMap,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
} = params;
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [textAreaLoading, setTextAreaLoading] = useState(false);
|
||||
const [saveButtonLoading, setSaveButtonLoading] = useState(false);
|
||||
const [textAreaValue, setTextAreaValue] = useState('');
|
||||
|
||||
const { document_id, status: originStatus } = photo;
|
||||
|
||||
const currentIndex = photoList.findIndex(i => i.document_id === document_id);
|
||||
|
||||
const status = progressMap[document_id || '']?.status || originStatus;
|
||||
|
||||
// 处理中获处理失败的photo,不允许更新 caption
|
||||
const disableUpdate =
|
||||
status === DocumentStatus.Processing ||
|
||||
status === DocumentStatus.Failed ||
|
||||
!canEdit;
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
setTextAreaValue(photo.caption);
|
||||
}
|
||||
}, [
|
||||
visible,
|
||||
// 切换图片时需要更新初始状态
|
||||
document_id,
|
||||
]);
|
||||
|
||||
const handleSave = async () => {
|
||||
if (disableUpdate) {
|
||||
setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
onSubmit?.();
|
||||
setSaveButtonLoading(true);
|
||||
try {
|
||||
await KnowledgeApi.UpdatePhotoCaption({
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
document_id,
|
||||
caption: textAreaValue,
|
||||
});
|
||||
reload();
|
||||
setSaveButtonLoading(false);
|
||||
setVisible(false);
|
||||
} catch (error) {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeUpdatePhotoCaption,
|
||||
error: error as Error,
|
||||
});
|
||||
setSaveButtonLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
node: (
|
||||
<UIModal
|
||||
visible={visible}
|
||||
onCancel={() => {
|
||||
setVisible(false);
|
||||
onCancel?.();
|
||||
}}
|
||||
centered
|
||||
title={I18n.t('knowledge_photo_019')}
|
||||
width={792}
|
||||
onOk={handleSave}
|
||||
okButtonProps={{
|
||||
disabled: disableUpdate,
|
||||
loading: saveButtonLoading,
|
||||
}}
|
||||
>
|
||||
<div className={styles['modal-content']}>
|
||||
<div className={styles['photo-large']}>
|
||||
<Image
|
||||
// 仅设置高度,宽度会按图片原比例自动缩放
|
||||
height={300}
|
||||
src={photo.url}
|
||||
/>
|
||||
{
|
||||
// 未找到,或者为第一个,不展示 pre 按钮
|
||||
currentIndex < 1 ? null : (
|
||||
<IconButton
|
||||
icon={<Icon svg={<SvgArrowLeft />} />}
|
||||
className={styles['arrow-button']}
|
||||
style={{
|
||||
left: '24px',
|
||||
}}
|
||||
onClick={() => {
|
||||
const { document_id: preId } = photoList[currentIndex - 1];
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
setCurrentPhotoId(preId);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
// 未找到,或者为最后一个,不展示 pre 按钮
|
||||
currentIndex === -1 ||
|
||||
currentIndex === photoList.length - 1 ? null : (
|
||||
<IconButton
|
||||
icon={<Icon rotate={180} svg={<SvgArrowLeft />} />}
|
||||
className={styles['arrow-button']}
|
||||
style={{
|
||||
right: '24px',
|
||||
}}
|
||||
onClick={() => {
|
||||
const { document_id: nextId } = photoList[currentIndex + 1];
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
setCurrentPhotoId(nextId);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className={styles['photo-caption-textarea']}>
|
||||
<Spin spinning={textAreaLoading}>
|
||||
<TextArea
|
||||
maxCount={2000}
|
||||
maxLength={2000}
|
||||
placeholder={I18n.t('knowledge_photo_026')}
|
||||
value={textAreaValue}
|
||||
onChange={v => setTextAreaValue(v)}
|
||||
disabled={disableUpdate}
|
||||
/>
|
||||
</Spin>
|
||||
<AutoGenerateButton
|
||||
currentValue={textAreaValue}
|
||||
document_id={document_id || ''}
|
||||
disable={disableUpdate}
|
||||
onChange={setTextAreaValue}
|
||||
onProgress={setTextAreaLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</UIModal>
|
||||
),
|
||||
open: () => {
|
||||
setVisible(true);
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
// photo 类型的 Filter
|
||||
.photo-filter-tab {
|
||||
display: flex;
|
||||
|
||||
&-item {
|
||||
cursor: pointer;
|
||||
|
||||
height: 14px;
|
||||
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: #1D1C2399;
|
||||
|
||||
&-active {
|
||||
cursor: pointer;
|
||||
|
||||
height: 14px;
|
||||
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: #4D53E8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 FC } from 'react';
|
||||
|
||||
import { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Divider } from '@coze-arch/coze-design';
|
||||
|
||||
import { FilterPhotoType } from '@/types';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const PhotoFilter: FC = () => {
|
||||
const photoFilterValue = useKnowledgeStore(state => state.photoFilterValue);
|
||||
const setPhotoFilterValue = useKnowledgeStore(
|
||||
state => state.setPhotoFilterValue,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles['photo-filter-tab']}>
|
||||
<div
|
||||
data-testid={KnowledgeE2e.ImageAnnotationAllTab}
|
||||
key={FilterPhotoType.All}
|
||||
onClick={() => setPhotoFilterValue(FilterPhotoType.All)}
|
||||
className={
|
||||
photoFilterValue === FilterPhotoType.All
|
||||
? styles['photo-filter-tab-item-active']
|
||||
: styles['photo-filter-tab-item']
|
||||
}
|
||||
>
|
||||
{I18n.t('knowledge-dataset-type-all')}
|
||||
</div>
|
||||
<Divider layout="vertical" margin="12px" />
|
||||
<div
|
||||
data-testid={KnowledgeE2e.ImageAnnotationAnnotationedTab}
|
||||
key={FilterPhotoType.HasCaption}
|
||||
onClick={() => setPhotoFilterValue(FilterPhotoType.HasCaption)}
|
||||
className={
|
||||
photoFilterValue === FilterPhotoType.HasCaption
|
||||
? styles['photo-filter-tab-item-active']
|
||||
: styles['photo-filter-tab-item']
|
||||
}
|
||||
>
|
||||
{I18n.t('knowledge_photo_013')}
|
||||
</div>
|
||||
<Divider layout="vertical" margin="12px" />
|
||||
<div
|
||||
data-testid={KnowledgeE2e.ImageAnnotationUnAnnotationTab}
|
||||
key={FilterPhotoType.NoCaption}
|
||||
onClick={() => setPhotoFilterValue(FilterPhotoType.NoCaption)}
|
||||
className={
|
||||
photoFilterValue === FilterPhotoType.NoCaption
|
||||
? styles['photo-filter-tab-item-active']
|
||||
: styles['photo-filter-tab-item']
|
||||
}
|
||||
>
|
||||
{I18n.t('knowledge_photo_014')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
.header {
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 DataSetInfo } from '@coze-arch/bot-api/memory';
|
||||
import { type Dataset } from '@coze-arch/bot-api/knowledge';
|
||||
import { UIBreadcrumb } from '@coze-studio/components';
|
||||
import { Layout } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface KnowledgePreviewNavigationProps {
|
||||
datasetInfo: Dataset;
|
||||
}
|
||||
export const KnowledgePreviewNavigation = ({
|
||||
datasetInfo,
|
||||
}: KnowledgePreviewNavigationProps) => (
|
||||
<Layout.Header
|
||||
className={styles.header}
|
||||
breadcrumb={
|
||||
<UIBreadcrumb
|
||||
showTooltip={{ width: '160px' }}
|
||||
className={styles.breadcrumb}
|
||||
datasetInfo={datasetInfo as unknown as DataSetInfo}
|
||||
compact={false}
|
||||
/>
|
||||
}
|
||||
></Layout.Header>
|
||||
);
|
||||
@@ -0,0 +1,22 @@
|
||||
.related-bots-list {
|
||||
overflow: scroll;
|
||||
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
max-height: 396px;
|
||||
// color: var(--Fg-COZ-fg-primary, rgba(6, 7, 9, 0.80));
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
:global {
|
||||
.related-bots-circle {
|
||||
margin-top: -4px;
|
||||
margin-right: 4px;
|
||||
font-size: 18px
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 { useRequest } from 'ahooks';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import { Loading } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
interface RelatedBotsListProps {
|
||||
datasetId: string;
|
||||
classNameItem?: string;
|
||||
style?: Record<string, string>;
|
||||
}
|
||||
|
||||
export const RelatedBotsList = (props: RelatedBotsListProps) => {
|
||||
const { datasetId, style, classNameItem } = props;
|
||||
|
||||
const {
|
||||
loading,
|
||||
data,
|
||||
run,
|
||||
error: requestError,
|
||||
} = useRequest(
|
||||
async () => {
|
||||
const resq = await KnowledgeApi.GetDatasetRefBots({
|
||||
dataset_id: datasetId,
|
||||
});
|
||||
return resq.ref_bots;
|
||||
},
|
||||
{
|
||||
onError: error => {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeGetDatasetRefDetail,
|
||||
error,
|
||||
});
|
||||
},
|
||||
manual: true,
|
||||
},
|
||||
);
|
||||
useEffect(() => {
|
||||
run();
|
||||
}, [datasetId]);
|
||||
if (requestError) {
|
||||
return <div>{I18n.t('knowledge_optimize_020')}</div>;
|
||||
}
|
||||
if (loading) {
|
||||
return <Loading loading={loading}></Loading>;
|
||||
}
|
||||
return (
|
||||
<div className={styles['related-bots-list']}>
|
||||
{data?.map(item => (
|
||||
<div
|
||||
className={
|
||||
classNameItem ? classNameItem : styles['related-bots-list-item']
|
||||
}
|
||||
style={style}
|
||||
key={item.name}
|
||||
>
|
||||
<div className="related-bots-circle">.</div>
|
||||
|
||||
<div>{item.name}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
.icon-with-suffix {
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
|
||||
:global {
|
||||
.icon-with-suffix-common {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon {
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.suffix {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 16px;
|
||||
left: 16px;
|
||||
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
|
||||
border-radius: 2.667px;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 { DocumentSource, FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
import { isFeishuOrLarkDocumentSource } from '@coze-data/utils';
|
||||
import { IconUnitsTable, IconUnitsFile } from '@coze-arch/bot-icons';
|
||||
|
||||
import { IconWithSuffix } from './suffix';
|
||||
|
||||
// 获取 icon
|
||||
export const RenderDocumentIcon = ({
|
||||
formatType,
|
||||
sourceType,
|
||||
isDisconnect,
|
||||
className,
|
||||
iconSuffixClassName,
|
||||
}: {
|
||||
formatType?: FormatType;
|
||||
sourceType?: DocumentSource;
|
||||
isDisconnect?: boolean;
|
||||
className?: string;
|
||||
iconSuffixClassName?: string;
|
||||
}) => {
|
||||
if (
|
||||
sourceType &&
|
||||
([DocumentSource.Notion, DocumentSource.GoogleDrive].includes(sourceType) ||
|
||||
isFeishuOrLarkDocumentSource(sourceType))
|
||||
) {
|
||||
return (
|
||||
<IconWithSuffix
|
||||
hasSuffix={!!isDisconnect}
|
||||
formatType={formatType}
|
||||
className={iconSuffixClassName}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return formatType === FormatType.Table ? (
|
||||
<IconUnitsTable className={className} />
|
||||
) : (
|
||||
<IconUnitsFile className={className} />
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
import {
|
||||
IconSvgFile,
|
||||
IconSvgSheet,
|
||||
IconSvgUnbound,
|
||||
} from '@coze-arch/bot-icons';
|
||||
|
||||
import style from './index.module.less';
|
||||
|
||||
interface Props {
|
||||
hasSuffix: boolean;
|
||||
formatType?: FormatType;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const IconMap = {
|
||||
[FormatType.Table]: {
|
||||
icon: <IconSvgSheet />,
|
||||
bgColor: '#35C566',
|
||||
suffixIcon: <IconSvgUnbound />,
|
||||
suffixBgColor: 'rgba(255,150,0,1)',
|
||||
},
|
||||
[FormatType.Text]: {
|
||||
icon: <IconSvgFile />,
|
||||
bgColor: 'rgba(34, 136, 255, 1)',
|
||||
suffixIcon: <IconSvgUnbound />,
|
||||
suffixBgColor: 'rgba(255,150,0,1)',
|
||||
},
|
||||
};
|
||||
|
||||
export const IconWithSuffix = (props: Props) => {
|
||||
const { formatType = FormatType.Text, hasSuffix, className } = props;
|
||||
|
||||
return (
|
||||
<div className={classNames(style['icon-with-suffix'], className)}>
|
||||
<div
|
||||
className={classNames('icon-with-suffix-common', 'icon')}
|
||||
style={{
|
||||
backgroundColor: `${IconMap?.[formatType]?.bgColor}`,
|
||||
}}
|
||||
>
|
||||
{IconMap?.[formatType]?.icon}
|
||||
</div>
|
||||
{hasSuffix ? (
|
||||
<div
|
||||
className={classNames('icon-with-suffix-common', 'suffix')}
|
||||
style={{
|
||||
backgroundColor: `${IconMap?.[formatType]?.suffixBgColor}`,
|
||||
}}
|
||||
>
|
||||
{IconMap?.[formatType]?.suffixIcon}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -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 { FailedTag } from './tag';
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 { I18n } from '@coze-arch/i18n';
|
||||
import { Tag, Tooltip } from '@coze-arch/coze-design';
|
||||
|
||||
interface FailedTagProps {
|
||||
statusDescription: string | undefined;
|
||||
}
|
||||
export const FailedTag: FC<FailedTagProps> = ({ statusDescription }) => (
|
||||
<Tooltip content={statusDescription}>
|
||||
<span>
|
||||
<Tag color="red" size="small">
|
||||
{I18n.t('bot_publish_columns_status_failed')}
|
||||
</Tag>
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 { I18n } from '@coze-arch/i18n';
|
||||
import { DocumentUpdateType, FormatType } from '@coze-arch/bot-api/memory';
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
export const MAX_SEGMENT_TOTAL = 10000;
|
||||
export const CREATE_UNIT_DISABLE_UNIT_TYPES = [
|
||||
UnitType.TABLE_GOOGLE_DRIVE,
|
||||
UnitType.TABLE_FEISHU,
|
||||
UnitType.TEXT_FEISHU,
|
||||
UnitType.TEXT_LARK,
|
||||
UnitType.TABLE_LARK,
|
||||
UnitType.TEXT_GOOGLE_DRIVE,
|
||||
UnitType.TEXT_DOC,
|
||||
UnitType.TEXT_URL,
|
||||
UnitType.TEXT_NOTION,
|
||||
UnitType.TEXT_CUSTOM,
|
||||
];
|
||||
export const CREATE_UNIT_DISABLE_FORMAT_TYPES = [FormatType.Text];
|
||||
export enum ViewMode {
|
||||
ContentView,
|
||||
SegmentView,
|
||||
}
|
||||
|
||||
export const VIEW_MODE_OPTIONS = [
|
||||
{
|
||||
value: ViewMode.ContentView,
|
||||
label: I18n.t('content_view_001'),
|
||||
},
|
||||
{
|
||||
value: ViewMode.SegmentView,
|
||||
label: I18n.t('content_view_002'),
|
||||
},
|
||||
];
|
||||
export enum SegmentOptSelect {
|
||||
RENAME = 0,
|
||||
UPDATE_CONTENT = 1,
|
||||
UPDATE_FREQUENCY = 2,
|
||||
DELETE = 4,
|
||||
CONFIGURATION_TABLE_STRUCTURE = 5,
|
||||
FETCH_SLICE = 6,
|
||||
UPDATE_FREQUENCY_BATCH = 7,
|
||||
APPEND_FREQUENCY = 8,
|
||||
OPEN_SEARCH_CONFIG = 9,
|
||||
}
|
||||
|
||||
export const DOCUMENT_UPDATE_TYPE_MAP = {
|
||||
[DocumentUpdateType.NoUpdate]: I18n.t('datasets_segment_tag_updateNo'),
|
||||
[DocumentUpdateType.Cover]: I18n.t('datasets_segment_tag_overwrite'),
|
||||
[DocumentUpdateType.Append]: I18n.t('datasets_segment_tag_overwriteNo'),
|
||||
} as const;
|
||||
|
||||
export { POLLING_TIME } from './polling';
|
||||
@@ -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 const POLLING_TIME = 5000; //ms
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 { createContext, useContext } from 'react';
|
||||
|
||||
import { type ImportKnowledgeMenuSourceRegistry } from '@/features/import-knowledge-sources/menu/registry';
|
||||
|
||||
export interface KnowledgeIDERegistry {
|
||||
importKnowledgeMenuSourceFeatureRegistry?: ImportKnowledgeMenuSourceRegistry;
|
||||
}
|
||||
|
||||
export const KnowledgeIDERegistryContext = createContext<KnowledgeIDERegistry>({
|
||||
importKnowledgeMenuSourceFeatureRegistry: undefined,
|
||||
});
|
||||
|
||||
export const useKnowledgeIDERegistry = () =>
|
||||
useContext(KnowledgeIDERegistryContext);
|
||||
@@ -0,0 +1,243 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
.photo-list {
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
height: calc(100vh - 170px);
|
||||
padding: 0 24px;
|
||||
|
||||
.photo-list-spin {
|
||||
flex: 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
|
||||
.spin {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-group {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
|
||||
// Card 整体
|
||||
.card {
|
||||
cursor: auto;
|
||||
width: 222px;
|
||||
height: 258px;
|
||||
border-radius: 8px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 14px 0 rgba(0, 0, 0, 8%);
|
||||
}
|
||||
|
||||
:global {
|
||||
// 固定高度142,超出高度的图片,截取居中部分展示
|
||||
.semi-card-cover {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 142px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-disabled {
|
||||
:global {
|
||||
.semi-card-cover {
|
||||
background: var(--Light-usage-fill---color-fill-0, rgba(46, 46, 57, 4%));
|
||||
border-radius: var(--default, 8px) var(--default, 8px) 0 0;
|
||||
|
||||
svg {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Card 封面
|
||||
.card-cover {
|
||||
cursor: pointer;
|
||||
border-radius: 8px 8px 0 0;
|
||||
|
||||
// 设置最小高度142,保证填满封面
|
||||
img {
|
||||
min-height: 142px;
|
||||
}
|
||||
}
|
||||
|
||||
.prohibit-cover {
|
||||
overflow: hidden;
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 16px; /* 133.333% */
|
||||
color: var(--Light-usage-text---color-text-3, rgba(29, 28, 36, 35%));
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Card 内容区 (title + description)
|
||||
.card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
.photo-name {
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: rgba(29, 28, 35, 100%);
|
||||
}
|
||||
|
||||
.photo-description {
|
||||
height: 32px;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
|
||||
.failed-tag {
|
||||
padding: 0 6px;
|
||||
color: rgba(219, 46, 19, 100%);
|
||||
background-color: rgba(255, 224, 210, 100%);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.processing-tag {
|
||||
padding: 0 6px;
|
||||
color: #304cdb;
|
||||
background-color: #d9e2ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Card 底部栏(时间 + 操作按钮)
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 24px;
|
||||
|
||||
.create-time {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: rgba(28, 29, 35, 35%)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// UI稿的 confirm modal 和 semi 默认的不一样,需要手动调整样式
|
||||
.confirm-modal {
|
||||
:global {
|
||||
.semi-modal-header {
|
||||
margin-bottom: 16px;
|
||||
|
||||
// icon 和 title 的间距
|
||||
.semi-modal-icon-wrapper {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
// title 颜色
|
||||
.semi-modal-confirm-title-text {
|
||||
color: rgba(29, 28, 35, 100%);
|
||||
}
|
||||
|
||||
// 关闭 icon 的 hover 颜色
|
||||
.semi-button:hover {
|
||||
background-color: rgba(46, 46, 56, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.semi-modal-body {
|
||||
margin: 0;
|
||||
padding: 16px 0;
|
||||
|
||||
.semi-modal-confirm-content {
|
||||
color: rgba(29, 28, 35, 100%)
|
||||
}
|
||||
}
|
||||
|
||||
.semi-modal-footer button {
|
||||
min-width: 96px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 编辑 photo 信息的弹窗
|
||||
.modal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
|
||||
// photo 大图展示
|
||||
// 用 flex 解决宽高和内部 image 不一致的问题
|
||||
.photo-large {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
.arrow-button {
|
||||
position: absolute;
|
||||
top: 126px;
|
||||
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 12px;
|
||||
|
||||
color: #1D1C23;
|
||||
|
||||
background-color: rgba(255, 255, 255, 50%);
|
||||
border: none;
|
||||
border-radius: 26px;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 20%), 0 0 1px 0 rgba(0, 0, 0, 20%);
|
||||
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #4D53E8;
|
||||
background-color: rgba(255, 255, 255, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// photo 描述输入框
|
||||
.photo-caption-textarea {
|
||||
position: relative;
|
||||
|
||||
:global {
|
||||
.semi-input-textarea-counter {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.ai-generate-button {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
// 解决 disabled button 样式错位的问题
|
||||
>span {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* 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 */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable max-lines-per-function */
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useEffect, useState, type FC, useRef } from 'react';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import classNames from 'classnames';
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import {
|
||||
useKnowledgeParams,
|
||||
useKnowledgeStore,
|
||||
} from '@coze-data/knowledge-stores';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import {
|
||||
Card,
|
||||
CardGroup,
|
||||
Image,
|
||||
Space,
|
||||
Spin,
|
||||
Tooltip,
|
||||
Typography,
|
||||
UIIconButton,
|
||||
UIModal,
|
||||
UIEmpty,
|
||||
} from '@coze-arch/bot-semi';
|
||||
import {
|
||||
IconCloseKnowledge,
|
||||
IconDeleteOutline,
|
||||
IconEdit,
|
||||
IconWaringRed,
|
||||
IconSegmentEmpty,
|
||||
IconImageFailOutlined,
|
||||
} from '@coze-arch/bot-icons';
|
||||
import { DocumentStatus, type PhotoInfo } from '@coze-arch/bot-api/knowledge';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { type ProgressItem, type ProgressMap } from '@/types';
|
||||
import { usePhotoDetailModal } from '@/components/photo-detail-modal';
|
||||
|
||||
import { usePhotoList } from './use-photo-list';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface ImageKnowledgeWorkspaceProps {
|
||||
progressMap: ProgressMap;
|
||||
}
|
||||
|
||||
export const ImageKnowledgeWorkspace: FC<
|
||||
ImageKnowledgeWorkspaceProps
|
||||
> = props => {
|
||||
const { progressMap } = props;
|
||||
const [_, setSearchParams] = useSearchParams();
|
||||
const params = useKnowledgeParams();
|
||||
const firstAutoOpenEditDocumentId = params.first_auto_open_edit_document_id;
|
||||
const [currentPhotoId, setCurrentPhotoId] = useState<string>('');
|
||||
const [currentHoverCardId, setCurrentHoverCardId] = useState<string>('');
|
||||
|
||||
const dataSetDetail = useKnowledgeStore(state => state.dataSetDetail);
|
||||
const canEdit = useKnowledgeStore(state => state.canEdit);
|
||||
const searchValue = useKnowledgeStore(state => state.searchValue);
|
||||
const photoFilterValue = useKnowledgeStore(state => state.photoFilterValue);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { data, loading, loadingMore, reloadAsync, noMore } = usePhotoList(
|
||||
{
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
datasetID: dataSetDetail?.dataset_id,
|
||||
filterPhotoType: photoFilterValue,
|
||||
searchValue,
|
||||
},
|
||||
{
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
isNoMore: d => d?.list.length >= d?.total,
|
||||
target: ref,
|
||||
},
|
||||
);
|
||||
|
||||
const photoList = data?.list;
|
||||
|
||||
const shouldAutoOpenDetailModal = photoList?.find(
|
||||
i => i.document_id === firstAutoOpenEditDocumentId,
|
||||
);
|
||||
|
||||
const previewPhotoList = photoList?.filter(
|
||||
photo => photo.status !== DocumentStatus.AuditFailed,
|
||||
);
|
||||
const curPhoto = previewPhotoList?.find(
|
||||
i => i.document_id === currentPhotoId,
|
||||
);
|
||||
|
||||
const resetUrlQueryParams = () => {
|
||||
setSearchParams((state: URLSearchParams) => {
|
||||
state.delete('action_type');
|
||||
return state;
|
||||
});
|
||||
};
|
||||
|
||||
const { node, open } = usePhotoDetailModal({
|
||||
photo: curPhoto,
|
||||
progressMap,
|
||||
photoList: previewPhotoList,
|
||||
canEdit: !!canEdit,
|
||||
setCurrentPhotoId,
|
||||
reload: reloadAsync,
|
||||
onCancel: () => {
|
||||
// 重置url参数
|
||||
resetUrlQueryParams();
|
||||
},
|
||||
onSubmit: () => {
|
||||
resetUrlQueryParams();
|
||||
},
|
||||
});
|
||||
|
||||
// 手动控制 data 加载时机
|
||||
useEffect(() => {
|
||||
if (dataSetDetail?.dataset_id) {
|
||||
reloadAsync();
|
||||
|
||||
// 重新加载时,回到最顶部
|
||||
ref.current?.scrollTo?.({
|
||||
top: 0,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
}
|
||||
}, [searchValue, photoFilterValue, dataSetDetail?.dataset_id]);
|
||||
|
||||
// 自动打开编辑弹窗
|
||||
useEffect(() => {
|
||||
if (shouldAutoOpenDetailModal) {
|
||||
if (firstAutoOpenEditDocumentId) {
|
||||
setCurrentPhotoId(firstAutoOpenEditDocumentId);
|
||||
}
|
||||
open();
|
||||
}
|
||||
}, [firstAutoOpenEditDocumentId, shouldAutoOpenDetailModal]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles['photo-list']} ref={ref}>
|
||||
<Spin
|
||||
spinning={loading}
|
||||
wrapperClassName={styles['photo-list-spin']}
|
||||
childStyle={{
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{/* @ts-expect-error -- linter-disable-autofix */}
|
||||
{photoList?.length <= 0 ? (
|
||||
<UIEmpty
|
||||
empty={{
|
||||
icon: <IconSegmentEmpty />,
|
||||
title: I18n.t('query_data_empty'),
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<CardGroup spacing={12} className={styles['card-group']}>
|
||||
{photoList?.map(item => {
|
||||
const {
|
||||
url,
|
||||
document_id,
|
||||
name,
|
||||
update_time,
|
||||
caption: originCaption,
|
||||
status: originStatus,
|
||||
} = item;
|
||||
// 此处使用 progressMap 可以保持不断刷新直至完成
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
const status = progressMap[document_id]?.status || originStatus;
|
||||
// 使用 progressMap 获取最新的caption
|
||||
const caption =
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
(progressMap[document_id] as ProgressItem & PhotoInfo)
|
||||
?.caption || originCaption;
|
||||
|
||||
const hasCaption =
|
||||
typeof caption === 'string' && Boolean(caption);
|
||||
|
||||
const handleEdit = () => {
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
setCurrentPhotoId(document_id);
|
||||
open();
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
UIModal.error({
|
||||
// 必填参数,统一 confirm modal 的样式
|
||||
className: styles['confirm-modal'],
|
||||
closeIcon: <IconCloseKnowledge />,
|
||||
|
||||
// 自定义参数
|
||||
title: I18n.t('kl2_007'),
|
||||
content: I18n.t(
|
||||
'dataset_detail_table_deleteModel_description',
|
||||
),
|
||||
icon: <IconWaringRed />,
|
||||
cancelText: I18n.t('Cancel'),
|
||||
okText: I18n.t('Delete'),
|
||||
okButtonProps: {
|
||||
type: 'danger',
|
||||
},
|
||||
onOk: async () => {
|
||||
try {
|
||||
await KnowledgeApi.DeleteDocument({
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
document_ids: [document_id],
|
||||
});
|
||||
await reloadAsync();
|
||||
} catch (error) {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgeDeleteDocument,
|
||||
error: error as Error,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const onMouseEnter = () => {
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
setCurrentHoverCardId(document_id);
|
||||
};
|
||||
|
||||
const onMouseLeave = () => {
|
||||
setCurrentHoverCardId('');
|
||||
};
|
||||
|
||||
const isHover = currentHoverCardId === document_id;
|
||||
const isAudiFailed =
|
||||
originStatus === DocumentStatus.AuditFailed;
|
||||
const getCaption = () => {
|
||||
// 违规图片
|
||||
if (isAudiFailed) {
|
||||
return (
|
||||
<span>
|
||||
{I18n.t('knowledge_content_illegal_error_msg')}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// 处理失败
|
||||
if (status === DocumentStatus.Failed) {
|
||||
return (
|
||||
<span className={styles['failed-tag']}>
|
||||
{I18n.t('dataset_process_fail')}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// 处理中
|
||||
if (status === DocumentStatus.Processing) {
|
||||
return (
|
||||
<span className={styles['processing-tag']}>
|
||||
{I18n.t('datasets_segment_tag_processing')}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// 已标注
|
||||
if (hasCaption) {
|
||||
return caption;
|
||||
}
|
||||
|
||||
// 未标注
|
||||
return I18n.t('knowledge_photo_016');
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={document_id}
|
||||
cover={
|
||||
isAudiFailed ? (
|
||||
<div className={styles['prohibit-cover']}>
|
||||
<IconImageFailOutlined size={'extra-small'} />
|
||||
<p>{I18n.t('knowledge_photo_illegal_error_msg')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<Image
|
||||
src={url}
|
||||
// 仅设置宽度,高度会按图片原比例自动缩放
|
||||
width={222}
|
||||
preview={false}
|
||||
onClick={handleEdit}
|
||||
className={styles['card-cover']}
|
||||
/>
|
||||
)
|
||||
}
|
||||
headerLine={false}
|
||||
bodyStyle={{
|
||||
padding: '12px 16px',
|
||||
}}
|
||||
className={classNames(
|
||||
styles.card,
|
||||
isAudiFailed ? styles['card-disabled'] : '',
|
||||
)}
|
||||
>
|
||||
<div
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
className={styles['card-content']}
|
||||
>
|
||||
<Typography.Text
|
||||
className={styles['photo-name']}
|
||||
ellipsis={{
|
||||
showTooltip: true,
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</Typography.Text>
|
||||
<Typography.Paragraph
|
||||
className={styles['photo-description']}
|
||||
ellipsis={{
|
||||
showTooltip: true,
|
||||
rows: 2,
|
||||
}}
|
||||
style={{
|
||||
color: hasCaption
|
||||
? 'rgba(29, 28, 35, 0.6)'
|
||||
: 'rgba(255, 178, 51, 1)',
|
||||
}}
|
||||
>
|
||||
{getCaption()}
|
||||
</Typography.Paragraph>
|
||||
|
||||
<div className={styles['card-footer']}>
|
||||
<Typography.Text className={styles['create-time']}>
|
||||
{/* @ts-expect-error -- linter-disable-autofix */}
|
||||
{dayjs.unix(update_time).format('YYYY-MM-DD HH:mm')}
|
||||
</Typography.Text>
|
||||
{isHover && canEdit ? (
|
||||
<Space spacing={12}>
|
||||
<Tooltip content={I18n.t('Edit')}>
|
||||
<UIIconButton
|
||||
icon={<IconEdit />}
|
||||
disabled={isAudiFailed}
|
||||
onClick={handleEdit}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip content={I18n.t('Delete')}>
|
||||
<UIIconButton
|
||||
icon={<IconDeleteOutline />}
|
||||
onClick={handleDelete}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Space>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</CardGroup>
|
||||
)}
|
||||
</Spin>
|
||||
<div className={styles.footer}>
|
||||
{!noMore && (
|
||||
<Spin
|
||||
spinning={loadingMore}
|
||||
tip={I18n.t('loading')}
|
||||
wrapperClassName={styles.spin}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{node}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -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 InfiniteScrollOptions } from 'ahooks/lib/useInfiniteScroll/types';
|
||||
import { useInfiniteScroll } from 'ahooks';
|
||||
import { DataNamespace, dataReporter } from '@coze-data/reporter';
|
||||
import { KNOWLEDGE_MAX_DOC_SIZE } from '@coze-data/knowledge-modal-base';
|
||||
import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { type PhotoInfo } from '@coze-arch/bot-api/knowledge';
|
||||
import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
|
||||
import { FilterPhotoType } from '@/types';
|
||||
|
||||
export interface UsePhotoListParams {
|
||||
datasetID: string;
|
||||
searchValue?: string;
|
||||
filterPhotoType?: FilterPhotoType;
|
||||
}
|
||||
|
||||
interface Result {
|
||||
list: PhotoInfo[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
export const usePhotoList = (
|
||||
params: UsePhotoListParams,
|
||||
options: InfiniteScrollOptions<Result>,
|
||||
) => {
|
||||
const { datasetID, searchValue, filterPhotoType } = params;
|
||||
|
||||
const fetchPhotoList = async (
|
||||
page: number,
|
||||
pageSize: number,
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
): Promise<Result> => {
|
||||
try {
|
||||
const res = await KnowledgeApi.ListPhoto({
|
||||
page: page ?? 1,
|
||||
size: pageSize ?? KNOWLEDGE_MAX_DOC_SIZE,
|
||||
dataset_id: datasetID,
|
||||
filter: {
|
||||
keyword: searchValue,
|
||||
has_caption:
|
||||
filterPhotoType === FilterPhotoType.HasCaption
|
||||
? true
|
||||
: filterPhotoType === FilterPhotoType.NoCaption
|
||||
? false
|
||||
: // 传 undefined 代表返回全部
|
||||
undefined,
|
||||
},
|
||||
});
|
||||
return {
|
||||
list: res.photo_infos || [],
|
||||
total: res.total || 0,
|
||||
};
|
||||
} catch (error) {
|
||||
dataReporter.errorEvent(DataNamespace.KNOWLEDGE, {
|
||||
eventName: REPORT_EVENTS.KnowledgePhotoList,
|
||||
error: error as Error,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return useInfiniteScroll<Result>(
|
||||
async d => {
|
||||
const p = d ? Math.ceil(d.list.length / PAGE_SIZE) + 1 : 1;
|
||||
return fetchPhotoList(p, PAGE_SIZE);
|
||||
},
|
||||
{
|
||||
manual: true,
|
||||
...options,
|
||||
},
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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 } from 'react';
|
||||
|
||||
import {
|
||||
useDataNavigate,
|
||||
useKnowledgeStore,
|
||||
} from '@coze-data/knowledge-stores';
|
||||
import { OptType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { getKnowledgeIDEQuery } from '@coze-data/knowledge-common-services/use-case';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozArrowDown } from '@coze-arch/bot-icons';
|
||||
import { FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
import { IconCozArrowUp } from '@coze-arch/coze-design/icons';
|
||||
import { Button, Tooltip } from '@coze-arch/coze-design';
|
||||
|
||||
import { ImportKnowledgeSourceMenu } from '@/features/import-knowledge-source-menu';
|
||||
|
||||
import { type ImportKnowledgeSourceButtonProps } from '../module';
|
||||
import {
|
||||
createBtnDisableToolTip,
|
||||
getTableFormatTooltip,
|
||||
getDefaultFormatTooltip,
|
||||
} from './services/use-case/disabled-tooltip';
|
||||
|
||||
export const ImportKnowledgeSourceButton = ({
|
||||
disabledTooltip: disabledTooltipProp,
|
||||
onSourceChange,
|
||||
}: ImportKnowledgeSourceButtonProps) => {
|
||||
const documentList = useKnowledgeStore(state => state.documentList);
|
||||
const dataSetDetail = useKnowledgeStore(state => state.dataSetDetail);
|
||||
const [visible, setVisible] = useState<boolean>(false);
|
||||
const resourceNavigate = useDataNavigate();
|
||||
const disabledTooltip =
|
||||
disabledTooltipProp ?? createBtnDisableToolTip(dataSetDetail, documentList);
|
||||
const query = getKnowledgeIDEQuery() as Record<string, string>;
|
||||
if (disabledTooltip) {
|
||||
return (
|
||||
<Tooltip
|
||||
content={disabledTooltip}
|
||||
arrowPointAtCenter={false}
|
||||
position="top"
|
||||
>
|
||||
<Button
|
||||
data-testid={KnowledgeE2e.SegmentDetailAddBtn}
|
||||
color="hgltplus"
|
||||
disabled
|
||||
iconPosition="right"
|
||||
icon={<IconCozArrowDown className={'text-[12px]'} />}
|
||||
>
|
||||
{I18n.t('knowledg_unit_add_segments')}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ImportKnowledgeSourceMenu
|
||||
onVisibleChange={dropVisible => {
|
||||
setVisible(dropVisible);
|
||||
}}
|
||||
onChange={unitType => {
|
||||
if (onSourceChange) {
|
||||
onSourceChange(unitType);
|
||||
return;
|
||||
}
|
||||
/** 默认跳转到upload */
|
||||
const formatType = dataSetDetail?.format_type;
|
||||
const docID = documentList?.[0]?.document_id;
|
||||
const params: Record<string, string> = {
|
||||
type: unitType,
|
||||
...query,
|
||||
};
|
||||
if (formatType === FormatType.Table && docID) {
|
||||
params.opt = OptType.INCREMENTAL;
|
||||
params.doc_id = docID;
|
||||
}
|
||||
resourceNavigate.upload?.(params);
|
||||
}}
|
||||
triggerComponent={
|
||||
<Button
|
||||
data-testid={KnowledgeE2e.SegmentDetailAddBtn}
|
||||
iconPosition="right"
|
||||
icon={
|
||||
visible ? (
|
||||
<IconCozArrowUp className={'text-[12px]'} />
|
||||
) : (
|
||||
<IconCozArrowDown className={'text-[12px]'} />
|
||||
)
|
||||
}
|
||||
>
|
||||
{I18n.t('knowledg_unit_add_segments')}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export {
|
||||
getTableFormatTooltip,
|
||||
getDefaultFormatTooltip,
|
||||
createBtnDisableToolTip,
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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 {
|
||||
KNOWLEDGE_MAX_DOC_SIZE,
|
||||
KNOWLEDGE_MAX_SLICE_COUNT,
|
||||
} from '@coze-data/knowledge-modal-base';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { type Dataset, type DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
import { DocumentStatus, FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
/**
|
||||
* 处理表格类型数据集的禁用提示
|
||||
*/
|
||||
export const getTableFormatTooltip = (documentList: DocumentInfo[]): string => {
|
||||
const docInfo = documentList?.[0];
|
||||
if (!docInfo) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (docInfo.status === DocumentStatus.Processing) {
|
||||
return I18n.t('knowledge_add_content_processing_tips');
|
||||
}
|
||||
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
if (docInfo?.slice_count >= KNOWLEDGE_MAX_SLICE_COUNT) {
|
||||
return I18n.t('kl2_002');
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理默认类型数据集的禁用提示
|
||||
*/
|
||||
export const getDefaultFormatTooltip = (dataSetDetail: Dataset): string => {
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
if (dataSetDetail?.doc_count >= KNOWLEDGE_MAX_DOC_SIZE) {
|
||||
return I18n.t('kl2_003');
|
||||
}
|
||||
|
||||
if (dataSetDetail?.processing_file_id_list?.length) {
|
||||
return I18n.t('knowledge_add_content_processing_tips');
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建按钮禁用时的提示文本
|
||||
* @param dataSetDetail - 数据集详情
|
||||
* @param documentList - 文档列表
|
||||
* @returns 提示文本
|
||||
*/
|
||||
export const createBtnDisableToolTip = (
|
||||
dataSetDetail: Dataset,
|
||||
documentList: DocumentInfo[],
|
||||
): string => {
|
||||
const formatType = dataSetDetail?.format_type;
|
||||
|
||||
const tooltipHandlers: Record<string, () => string> = {
|
||||
[FormatType.Table]: () => getTableFormatTooltip(documentList),
|
||||
default: () => getDefaultFormatTooltip(dataSetDetail),
|
||||
};
|
||||
|
||||
if (!formatType) {
|
||||
return tooltipHandlers.default();
|
||||
}
|
||||
|
||||
const handler = tooltipHandlers[formatType] || tooltipHandlers.default;
|
||||
return handler();
|
||||
};
|
||||
@@ -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 {
|
||||
getTableFormatTooltip,
|
||||
getDefaultFormatTooltip,
|
||||
createBtnDisableToolTip,
|
||||
} from './disabled-tooltip';
|
||||
@@ -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 { useShallow } from 'zustand/react/shallow';
|
||||
import { useKnowledgeParams, useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { type UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { useKnowledgeNavigate } from '@coze-data/knowledge-common-hooks/use-case';
|
||||
import { useSpaceStore } from '@coze-arch/bot-studio-store';
|
||||
import { type FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { getAddContentUrl } from '@/utils';
|
||||
import { ActionType } from '@/types';
|
||||
|
||||
import { type ImportKnowledgeSourceButtonProps } from '../module';
|
||||
import { ImportKnowledgeSourceButton } from '../base';
|
||||
|
||||
export type BizAgentIdeImportKnowledgeSourceButtonProps =
|
||||
ImportKnowledgeSourceButtonProps;
|
||||
|
||||
export const BizAgentIdeImportKnowledgeSourceButton = ({
|
||||
disabledTooltip,
|
||||
}: BizAgentIdeImportKnowledgeSourceButtonProps) => {
|
||||
const navigate = useKnowledgeNavigate();
|
||||
const { documentList, dataSetDetail } = useKnowledgeStore(
|
||||
useShallow(state => ({
|
||||
documentList: state.documentList,
|
||||
dataSetDetail: state.dataSetDetail,
|
||||
})),
|
||||
);
|
||||
const params = useKnowledgeParams();
|
||||
const spaceId = useSpaceStore(item => item.space.id);
|
||||
return (
|
||||
<ImportKnowledgeSourceButton
|
||||
disabledTooltip={disabledTooltip}
|
||||
onSourceChange={unitType => {
|
||||
navigate(
|
||||
getAddContentUrl({
|
||||
spaceID: spaceId as string,
|
||||
datasetID: dataSetDetail?.dataset_id as string,
|
||||
docID: documentList?.[0]?.document_id,
|
||||
formatType: dataSetDetail?.format_type as FormatType,
|
||||
type: unitType as UnitType,
|
||||
pageMode: 'modal',
|
||||
botId: params.botID,
|
||||
actionType: ActionType.ADD,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -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 interface ImportKnowledgeSourceButtonProps {
|
||||
disabledTooltip?: string;
|
||||
onSourceChange?: (source: string) => void;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 } from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
import { useKnowledgeIDERegistry } from '../../context/knowledge-ide-registry-context';
|
||||
import { KnowledgeSourceMenu as KnowledgeSourceMenuComponent } from '../../components/knowledge-source-menu';
|
||||
|
||||
export interface ImportKnowledgeSourceMenuProps {
|
||||
triggerComponent?: ReactNode;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
onChange?: (val: UnitType) => void;
|
||||
}
|
||||
|
||||
export const ImportKnowledgeSourceMenu = (
|
||||
props: ImportKnowledgeSourceMenuProps,
|
||||
) => {
|
||||
const { triggerComponent, onVisibleChange, onChange } = props;
|
||||
const { importKnowledgeMenuSourceFeatureRegistry } =
|
||||
useKnowledgeIDERegistry();
|
||||
|
||||
return (
|
||||
<KnowledgeSourceMenuComponent
|
||||
triggerComponent={triggerComponent}
|
||||
onVisibleChange={onVisibleChange}
|
||||
>
|
||||
{importKnowledgeMenuSourceFeatureRegistry
|
||||
?.entries()
|
||||
.map(([key, { Component }]) => (
|
||||
<Component key={key} onClick={value => onChange?.(value)} />
|
||||
))}
|
||||
</KnowledgeSourceMenuComponent>
|
||||
);
|
||||
};
|
||||
@@ -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 { ImageLocalModule } from '@/features/import-knowledge-sources/radio/image-local';
|
||||
import {
|
||||
createImportKnowledgeSourceRadioFeatureRegistry,
|
||||
type ImportKnowledgeRadioSourceFeatureRegistry,
|
||||
} from '@/features/import-knowledge-sources/radio';
|
||||
|
||||
export const importImageKnowledgeSourceRadioGroupContributes: ImportKnowledgeRadioSourceFeatureRegistry =
|
||||
(() => {
|
||||
const importKnowledgeRadioSourceFeatureRegistry =
|
||||
createImportKnowledgeSourceRadioFeatureRegistry(
|
||||
'import-knowledge-source-image-radio-group',
|
||||
);
|
||||
importKnowledgeRadioSourceFeatureRegistry.registerSome([
|
||||
{
|
||||
type: 'image-local',
|
||||
module: ImageLocalModule,
|
||||
},
|
||||
]);
|
||||
return importKnowledgeRadioSourceFeatureRegistry;
|
||||
})();
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 { TableLocalModule } from '@coze-data/knowledge-ide-base/features/import-knowledge-sources/radio/table-local';
|
||||
import {
|
||||
createImportKnowledgeSourceRadioFeatureRegistry,
|
||||
type ImportKnowledgeRadioSourceFeatureRegistry,
|
||||
} from '@coze-data/knowledge-ide-base/features/import-knowledge-sources/radio';
|
||||
import { TableCustomModule } from '@coze-data/knowledge-ide-base/features/import-knowledge-sources/radio';
|
||||
|
||||
export const importTableKnowledgeSourceRadioGroupContributes: ImportKnowledgeRadioSourceFeatureRegistry =
|
||||
(() => {
|
||||
const importKnowledgeRadioSourceFeatureRegistry =
|
||||
createImportKnowledgeSourceRadioFeatureRegistry(
|
||||
'import-knowledge-source-table-radio-group',
|
||||
);
|
||||
importKnowledgeRadioSourceFeatureRegistry.registerSome([
|
||||
{
|
||||
type: 'table-local',
|
||||
module: TableLocalModule,
|
||||
},
|
||||
{
|
||||
type: 'table-custom',
|
||||
module: TableCustomModule,
|
||||
},
|
||||
]);
|
||||
return importKnowledgeRadioSourceFeatureRegistry;
|
||||
})();
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import {
|
||||
createImportKnowledgeSourceRadioFeatureRegistry,
|
||||
type ImportKnowledgeRadioSourceFeatureRegistry,
|
||||
} from '@coze-data/knowledge-ide-base/features/import-knowledge-sources/radio';
|
||||
import {
|
||||
TextCustomModule,
|
||||
TextLocalModule,
|
||||
} from '@coze-data/knowledge-ide-base/features/import-knowledge-sources/radio';
|
||||
|
||||
export const importTextKnowledgeSourceRadioGroupContributes: ImportKnowledgeRadioSourceFeatureRegistry =
|
||||
(() => {
|
||||
const importKnowledgeRadioSourceFeatureRegistry =
|
||||
createImportKnowledgeSourceRadioFeatureRegistry(
|
||||
'import-knowledge-source-text-radio-group',
|
||||
);
|
||||
importKnowledgeRadioSourceFeatureRegistry.registerSome([
|
||||
{
|
||||
type: 'text-local',
|
||||
module: TextLocalModule,
|
||||
},
|
||||
{
|
||||
type: 'text-custom',
|
||||
module: TextCustomModule,
|
||||
},
|
||||
]);
|
||||
return importKnowledgeRadioSourceFeatureRegistry;
|
||||
})();
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 } from 'react';
|
||||
|
||||
import { type UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { type ImportKnowledgeRadioSourceFeatureRegistry } from '../import-knowledge-sources/radio/registry';
|
||||
import { KnowledgeSourceRadioGroup as KnowledgeSourceRadioGroupComponent } from '../../components/knowledge-source-radio-group';
|
||||
import { importTextKnowledgeSourceRadioGroupContributes } from './import-text-knowledge-source-contributes';
|
||||
import { importTableKnowledgeSourceRadioGroupContributes } from './import-table-knowledge-source-contributes';
|
||||
import { importImageKnowledgeSourceRadioGroupContributes } from './import-image-knowledge-source-contributes';
|
||||
|
||||
export interface ImportKnowledgeSourceRadioGroupProps {
|
||||
formatType: FormatType;
|
||||
value?: UnitType;
|
||||
importKnowledgeSourceRegistry: ImportKnowledgeRadioSourceFeatureRegistry;
|
||||
onChange?: (val: UnitType) => void;
|
||||
}
|
||||
|
||||
export const ImportKnowledgeSourceRadioGroup = (
|
||||
props: ImportKnowledgeSourceRadioGroupProps,
|
||||
) => {
|
||||
const { value, onChange, formatType } = props;
|
||||
const importKnowledgeSourceRegistry = useMemo(() => {
|
||||
if (formatType === FormatType.Text) {
|
||||
return importTextKnowledgeSourceRadioGroupContributes;
|
||||
}
|
||||
if (formatType === FormatType.Table) {
|
||||
return importTableKnowledgeSourceRadioGroupContributes;
|
||||
}
|
||||
if (formatType === FormatType.Image) {
|
||||
return importImageKnowledgeSourceRadioGroupContributes;
|
||||
}
|
||||
}, [formatType]);
|
||||
if (!importKnowledgeSourceRegistry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<KnowledgeSourceRadioGroupComponent
|
||||
value={value}
|
||||
onChange={e => {
|
||||
onChange?.(e.target.value);
|
||||
}}
|
||||
>
|
||||
{importKnowledgeSourceRegistry.entries().map(([key, { Component }]) => (
|
||||
<Component key={key} />
|
||||
))}
|
||||
</KnowledgeSourceRadioGroupComponent>
|
||||
);
|
||||
};
|
||||
@@ -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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozDocument } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceMenuItem } from '@/components/knowledge-source-menu-item';
|
||||
|
||||
import {
|
||||
type ImportKnowledgeMenuSourceModule,
|
||||
type ImportKnowledgeMenuSourceModuleProps,
|
||||
} from '../module';
|
||||
|
||||
export const ImageLocal = (props: ImportKnowledgeMenuSourceModuleProps) => {
|
||||
const { onClick } = props;
|
||||
return (
|
||||
<KnowledgeSourceMenuItem
|
||||
title={I18n.t('knowledge_photo_002')}
|
||||
icon={<IconCozDocument className="w-4 h-4" />}
|
||||
testId={`${KnowledgeE2e.SegmentDetailDropdownItem}.${UnitType.IMAGE_FILE}`}
|
||||
value={UnitType.IMAGE_FILE}
|
||||
onClick={() => onClick(UnitType.IMAGE_FILE)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const ImageLocalModule: ImportKnowledgeMenuSourceModule = {
|
||||
Component: ImageLocal,
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 { TableCustomModule } from './table-custom';
|
||||
export { TableLocalModule } from './table-local';
|
||||
export { TextCustomModule } from './text-custom';
|
||||
export { TextLocalModule } from './text-local';
|
||||
export { ImageLocalModule } from './image-local';
|
||||
export type {
|
||||
ImportKnowledgeMenuSourceModuleProps,
|
||||
ImportKnowledgeMenuSourceModule,
|
||||
} from './module';
|
||||
export {
|
||||
createImportKnowledgeMenuSourceFeatureRegistry,
|
||||
type ImportKnowledgeMenuSourceFeatureType,
|
||||
type ImportKnowledgeMenuSourceRegistry,
|
||||
} from './registry';
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
|
||||
export interface ImportKnowledgeMenuSourceModuleProps {
|
||||
onClick: (item: UnitType) => void;
|
||||
}
|
||||
|
||||
export interface ImportKnowledgeMenuSourceModule {
|
||||
Component: React.ComponentType<ImportKnowledgeMenuSourceModuleProps>;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 { FeatureRegistry } from '@coze-data/feature-register';
|
||||
|
||||
import { type ImportKnowledgeMenuSourceModule } from './module';
|
||||
|
||||
export type ImportKnowledgeMenuSourceFeatureType =
|
||||
| 'text-local'
|
||||
| 'text-custom'
|
||||
| 'table-custom'
|
||||
| 'table-local'
|
||||
| 'image-local'
|
||||
| 'image-custom';
|
||||
|
||||
export type ImportKnowledgeMenuSourceRegistry = FeatureRegistry<
|
||||
ImportKnowledgeMenuSourceFeatureType,
|
||||
ImportKnowledgeMenuSourceModule
|
||||
>;
|
||||
|
||||
export const createImportKnowledgeMenuSourceFeatureRegistry = (
|
||||
name: string,
|
||||
): ImportKnowledgeMenuSourceRegistry =>
|
||||
new FeatureRegistry<
|
||||
ImportKnowledgeMenuSourceFeatureType,
|
||||
ImportKnowledgeMenuSourceModule
|
||||
>({
|
||||
name,
|
||||
});
|
||||
@@ -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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozPencilPaper } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceMenuItem } from '@/components/knowledge-source-menu-item';
|
||||
|
||||
import {
|
||||
type ImportKnowledgeMenuSourceModule,
|
||||
type ImportKnowledgeMenuSourceModuleProps,
|
||||
} from '../module';
|
||||
|
||||
export const TableCustom = (props: ImportKnowledgeMenuSourceModuleProps) => {
|
||||
const { onClick } = props;
|
||||
return (
|
||||
<KnowledgeSourceMenuItem
|
||||
title={I18n.t('datasets_createFileModel_step1_TabCustomTitle')}
|
||||
icon={<IconCozPencilPaper className="w-4 h-4" />}
|
||||
testId={`${KnowledgeE2e.SegmentDetailDropdownItem}.${UnitType.TABLE_CUSTOM}`}
|
||||
value={UnitType.TABLE_CUSTOM}
|
||||
onClick={() => onClick(UnitType.TABLE_CUSTOM)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const TableCustomModule: ImportKnowledgeMenuSourceModule = {
|
||||
Component: TableCustom,
|
||||
};
|
||||
@@ -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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozDocument } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceMenuItem } from '@/components/knowledge-source-menu-item';
|
||||
|
||||
import {
|
||||
type ImportKnowledgeMenuSourceModule,
|
||||
type ImportKnowledgeMenuSourceModuleProps,
|
||||
} from '../module';
|
||||
|
||||
export const TableLocal = (props: ImportKnowledgeMenuSourceModuleProps) => {
|
||||
const { onClick } = props;
|
||||
return (
|
||||
<KnowledgeSourceMenuItem
|
||||
title={I18n.t('datasets_createFileModel_step1_TabLocalTitle')}
|
||||
icon={<IconCozDocument className="w-4 h-4" />}
|
||||
testId={`${KnowledgeE2e.SegmentDetailDropdownItem}.${UnitType.TABLE_DOC}`}
|
||||
value={UnitType.TABLE_DOC}
|
||||
onClick={() => onClick(UnitType.TABLE_DOC)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const TableLocalModule: ImportKnowledgeMenuSourceModule = {
|
||||
Component: TableLocal,
|
||||
};
|
||||
@@ -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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozPencilPaper } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceMenuItem } from '@/components/knowledge-source-menu-item';
|
||||
|
||||
import {
|
||||
type ImportKnowledgeMenuSourceModule,
|
||||
type ImportKnowledgeMenuSourceModuleProps,
|
||||
} from '../module';
|
||||
|
||||
export const TextCustom = (props: ImportKnowledgeMenuSourceModuleProps) => {
|
||||
const { onClick } = props;
|
||||
return (
|
||||
<KnowledgeSourceMenuItem
|
||||
title={I18n.t('datasets_createFileModel_step1_CustomTitle')}
|
||||
icon={<IconCozPencilPaper className="w-4 h-4" />}
|
||||
testId={`${KnowledgeE2e.SegmentDetailDropdownItem}.${UnitType.TEXT_CUSTOM}`}
|
||||
value={UnitType.TEXT_CUSTOM}
|
||||
onClick={() => onClick(UnitType.TEXT_CUSTOM)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const TextCustomModule: ImportKnowledgeMenuSourceModule = {
|
||||
Component: TextCustom,
|
||||
};
|
||||
@@ -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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozDocument } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceMenuItem } from '@/components/knowledge-source-menu-item';
|
||||
|
||||
import {
|
||||
type ImportKnowledgeMenuSourceModule,
|
||||
type ImportKnowledgeMenuSourceModuleProps,
|
||||
} from '../module';
|
||||
|
||||
export const TextLocal = (props: ImportKnowledgeMenuSourceModuleProps) => {
|
||||
const { onClick } = props;
|
||||
return (
|
||||
<KnowledgeSourceMenuItem
|
||||
title={I18n.t('datasets_createFileModel_step1_LocalTitle')}
|
||||
icon={<IconCozDocument className="w-4 h-4" />}
|
||||
testId={`${KnowledgeE2e.SegmentDetailDropdownItem}.${UnitType.TEXT_DOC}`}
|
||||
value={UnitType.TEXT_DOC}
|
||||
onClick={() => onClick(UnitType.TEXT_DOC)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const TextLocalModule: ImportKnowledgeMenuSourceModule = {
|
||||
Component: TextLocal,
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozDocument } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceRadio } from '@/components/knowledge-source-radio';
|
||||
|
||||
import { type ImportKnowledgeRadioSourceModule } from '../module';
|
||||
|
||||
export const ImageLocal: ImportKnowledgeRadioSourceModule['Component'] = () => (
|
||||
<KnowledgeSourceRadio
|
||||
title={I18n.t('knowledge_photo_002')}
|
||||
description={I18n.t('knowledge_photo_003')}
|
||||
icon={<IconCozDocument className="w-4 h-4" />}
|
||||
e2e={KnowledgeE2e.CreateKnowledgeModalPhotoImgRadio}
|
||||
key={UnitType.IMAGE_FILE}
|
||||
value={UnitType.IMAGE_FILE}
|
||||
/>
|
||||
);
|
||||
|
||||
export const ImageLocalModule: ImportKnowledgeRadioSourceModule = {
|
||||
Component: ImageLocal,
|
||||
};
|
||||
@@ -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 { TableCustomModule } from './table-custom';
|
||||
export { TableLocalModule } from './table-local';
|
||||
export { TextCustomModule } from './text-custom';
|
||||
export { TextLocalModule } from './text-local';
|
||||
export { ImageLocalModule } from './image-local';
|
||||
export type { ImportKnowledgeRadioSourceModule } from './module';
|
||||
export {
|
||||
createImportKnowledgeSourceRadioFeatureRegistry,
|
||||
type ImportKnowledgeRadioSourceFeatureType,
|
||||
ImportKnowledgeRadioSourceFeatureRegistry,
|
||||
} from './registry';
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 { ComponentProps, ReactElement } from 'react';
|
||||
|
||||
import type { KnowledgeSourceRadio } from '@/components/knowledge-source-radio';
|
||||
|
||||
export interface ImportKnowledgeRadioSourceModule {
|
||||
Component: () => ReactElement<
|
||||
ComponentProps<typeof KnowledgeSourceRadio>
|
||||
> | null;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 { FeatureRegistry } from '@coze-data/feature-register';
|
||||
|
||||
import { TextLocalModule } from './text-local';
|
||||
import { type ImportKnowledgeRadioSourceModule } from './module';
|
||||
|
||||
export type ImportKnowledgeRadioSourceFeatureType =
|
||||
| 'text-local'
|
||||
| 'text-custom'
|
||||
| 'table-custom'
|
||||
| 'table-local'
|
||||
| 'image-local'
|
||||
| 'image-custom';
|
||||
|
||||
export type ImportKnowledgeRadioSourceFeatureRegistry = FeatureRegistry<
|
||||
ImportKnowledgeRadioSourceFeatureType,
|
||||
ImportKnowledgeRadioSourceModule
|
||||
>;
|
||||
|
||||
export const createImportKnowledgeSourceRadioFeatureRegistry = (
|
||||
name: string,
|
||||
): ImportKnowledgeRadioSourceFeatureRegistry =>
|
||||
new FeatureRegistry<
|
||||
ImportKnowledgeRadioSourceFeatureType,
|
||||
ImportKnowledgeRadioSourceModule
|
||||
>({
|
||||
name,
|
||||
defaultFeature: {
|
||||
type: 'text-local',
|
||||
module: TextLocalModule,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozPencilPaper } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceRadio } from '@/components/knowledge-source-radio';
|
||||
|
||||
import { type ImportKnowledgeRadioSourceModule } from '../module';
|
||||
|
||||
export const TableCustom: ImportKnowledgeRadioSourceModule['Component'] =
|
||||
() => (
|
||||
<KnowledgeSourceRadio
|
||||
title={I18n.t('datasets_createFileModel_step1_TabCustomTitle')}
|
||||
description={I18n.t(
|
||||
'datasets_createFileModel_step1_TabCustomDescription',
|
||||
)}
|
||||
icon={<IconCozPencilPaper className="w-4 h-4" />}
|
||||
e2e={KnowledgeE2e.CreateKnowledgeModalTableCustomRadio}
|
||||
key={UnitType.TABLE_CUSTOM}
|
||||
value={UnitType.TABLE_CUSTOM}
|
||||
/>
|
||||
);
|
||||
|
||||
export const TableCustomModule: ImportKnowledgeRadioSourceModule = {
|
||||
Component: TableCustom,
|
||||
};
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozDocument } from '@coze-arch/coze-design/icons';
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
|
||||
import { KnowledgeSourceRadio } from '@/components/knowledge-source-radio';
|
||||
import { type ImportKnowledgeRadioSourceModule } from '../module';
|
||||
|
||||
export const TableLocal: ImportKnowledgeRadioSourceModule['Component'] = () => (
|
||||
<KnowledgeSourceRadio
|
||||
title={I18n.t('datasets_createFileModel_step1_TabLocalTitle')}
|
||||
description={I18n.t('datasets_createFileModel_step1_TabLocalDescription')}
|
||||
icon={<IconCozDocument className="w-4 h-4" />}
|
||||
e2e={KnowledgeE2e.CreateKnowledgeModalTableLocalRadio}
|
||||
key={UnitType.TABLE_DOC}
|
||||
value={UnitType.TABLE_DOC}
|
||||
/>
|
||||
);
|
||||
|
||||
export const TableLocalModule: ImportKnowledgeRadioSourceModule = {
|
||||
Component: TableLocal,
|
||||
};
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozPencilPaper } from '@coze-arch/coze-design/icons';
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
|
||||
import { type ImportKnowledgeRadioSourceModule } from '../module';
|
||||
import { KnowledgeSourceRadio } from '@/components/knowledge-source-radio';
|
||||
|
||||
export const TextCustom: ImportKnowledgeRadioSourceModule['Component'] = () => (
|
||||
<KnowledgeSourceRadio
|
||||
title={I18n.t('datasets_createFileModel_step1_CustomTitle')}
|
||||
description={I18n.t('datasets_createFileModel_step1_CustomDescription')}
|
||||
icon={<IconCozPencilPaper className="w-4 h-4" />}
|
||||
e2e={KnowledgeE2e.CreateKnowledgeModalTextCustomRadio}
|
||||
key={UnitType.TEXT_CUSTOM}
|
||||
value={UnitType.TEXT_CUSTOM}
|
||||
/>
|
||||
);
|
||||
|
||||
export const TextCustomModule: ImportKnowledgeRadioSourceModule = {
|
||||
Component: TextCustom,
|
||||
};
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozDocument } from '@coze-arch/coze-design/icons';
|
||||
|
||||
import { KnowledgeSourceRadio } from '@/components/knowledge-source-radio';
|
||||
import { type ImportKnowledgeRadioSourceModule } from '../module';
|
||||
|
||||
export const TextLocal: ImportKnowledgeRadioSourceModule['Component'] = () => (
|
||||
<KnowledgeSourceRadio
|
||||
title={I18n.t('datasets_createFileModel_step1_LocalTitle')}
|
||||
description={I18n.t('datasets_createFileModel_step1_LocalDescription')}
|
||||
icon={<IconCozDocument className="w-4 h-4" />}
|
||||
e2e={KnowledgeE2e.CreateKnowledgeModalTextLocalRadio}
|
||||
key={UnitType.TEXT_DOC}
|
||||
value={UnitType.TEXT_DOC}
|
||||
/>
|
||||
);
|
||||
|
||||
export const TextLocalModule: ImportKnowledgeRadioSourceModule = {
|
||||
Component: TextLocal,
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 { useDataNavigate } from '@coze-data/knowledge-stores';
|
||||
import { OptType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { UpdateType } from '@coze-arch/bot-api/knowledge';
|
||||
import { Menu } from '@coze-arch/coze-design';
|
||||
|
||||
import {
|
||||
type TableConfigMenuModule,
|
||||
type TableConfigMenuModuleProps,
|
||||
} from '../module';
|
||||
|
||||
export const ConfigurationTableStructure = (
|
||||
props: TableConfigMenuModuleProps,
|
||||
) => {
|
||||
const { documentInfo } = props;
|
||||
const resourceNavigate = useDataNavigate();
|
||||
|
||||
if (
|
||||
documentInfo.update_type !== undefined &&
|
||||
documentInfo.update_type !== UpdateType.NoUpdate
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleClick = () => {
|
||||
resourceNavigate.upload?.({
|
||||
type: 'table',
|
||||
opt: OptType.RESEGMENT,
|
||||
doc_id: documentInfo?.document_id ?? '',
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu.Item onClick={handleClick}>
|
||||
{I18n.t('knowledge_segment_config_table')}
|
||||
</Menu.Item>
|
||||
);
|
||||
};
|
||||
export const ConfigurationTableStructureModule: TableConfigMenuModule = {
|
||||
Component: ConfigurationTableStructure,
|
||||
};
|
||||
@@ -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 {
|
||||
createTableConfigMenuRegistry,
|
||||
type TableConfigMenuRegistry,
|
||||
type TableConfigMenuFeatureType,
|
||||
} from './registry';
|
||||
export {
|
||||
type TableConfigMenuModule,
|
||||
type TableConfigMenuModuleProps,
|
||||
} from './module';
|
||||
export { ConfigurationTableStructureModule } from './configuration-table-structure';
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import type { DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
export interface TableConfigMenuModuleProps {
|
||||
documentInfo: DocumentInfo;
|
||||
reload?: () => void;
|
||||
onChangeDocList?: (docList: DocumentInfo[]) => void;
|
||||
}
|
||||
|
||||
export interface TableConfigMenuModule {
|
||||
Component: React.ComponentType<TableConfigMenuModuleProps>;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 { FeatureRegistry } from '@coze-data/feature-register';
|
||||
|
||||
import { type TableConfigMenuModule } from './module';
|
||||
|
||||
export type TableConfigMenuFeatureType =
|
||||
| 'configuration-table-structure'
|
||||
| 'update-frequency'
|
||||
| 'fetch-slice'
|
||||
| 'view-source';
|
||||
|
||||
export type TableConfigMenuRegistry = FeatureRegistry<
|
||||
TableConfigMenuFeatureType,
|
||||
TableConfigMenuModule
|
||||
>;
|
||||
|
||||
export const createTableConfigMenuRegistry = (
|
||||
name: string,
|
||||
): TableConfigMenuRegistry =>
|
||||
new FeatureRegistry<TableConfigMenuFeatureType, TableConfigMenuModule>({
|
||||
name,
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { type DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { useReloadKnowledgeIDE } from '@/hooks/use-case/use-reload-knowledge-ide';
|
||||
|
||||
import { type TableConfigMenuRegistry } from '../../knowledge-ide-table-config-menus';
|
||||
import { KnowledgeConfigMenu as KnowledgeConfigMenuComponent } from '../../../components/knowledge-config-menu';
|
||||
|
||||
export interface TableConfigButtonProps {
|
||||
knowledgeTableConfigMenuContributes?: TableConfigMenuRegistry;
|
||||
onChangeDocList?: (docList: DocumentInfo[]) => void;
|
||||
}
|
||||
|
||||
export const TableConfigButton = (props: TableConfigButtonProps) => {
|
||||
const { knowledgeTableConfigMenuContributes, onChangeDocList } = props;
|
||||
const documentList = useKnowledgeStore(state => state.documentList);
|
||||
const documentInfo = documentList?.[0];
|
||||
const canEdit = useKnowledgeStore(state => state.canEdit);
|
||||
const { reload } = useReloadKnowledgeIDE();
|
||||
|
||||
if (!knowledgeTableConfigMenuContributes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<KnowledgeConfigMenuComponent>
|
||||
{canEdit
|
||||
? knowledgeTableConfigMenuContributes
|
||||
?.entries()
|
||||
.map(([key, { Component }]) => (
|
||||
<Component
|
||||
key={key}
|
||||
documentInfo={documentInfo}
|
||||
onChangeDocList={onChangeDocList}
|
||||
reload={reload}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
</KnowledgeConfigMenuComponent>
|
||||
);
|
||||
};
|
||||
@@ -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 { useMemo } from 'react';
|
||||
|
||||
import { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { UnitType } from '@coze-data/knowledge-resource-processor-core';
|
||||
import { FormatType } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import { getUnitType } from '@/utils';
|
||||
|
||||
import { TableLocalTableConfigButton } from './table-local';
|
||||
import { TableCustomTableConfigButton } from './table-custom';
|
||||
import { type TableConfigButtonProps } from './base';
|
||||
export const KnowledgeIDETableConfig = (props: TableConfigButtonProps) => {
|
||||
const documentInfo = useKnowledgeStore(state => state.documentList?.[0]);
|
||||
const unitType = useMemo(() => {
|
||||
if (documentInfo) {
|
||||
return getUnitType({
|
||||
format_type: FormatType.Table,
|
||||
source_type: documentInfo?.source_type,
|
||||
});
|
||||
}
|
||||
return UnitType.TABLE_API;
|
||||
}, [documentInfo]);
|
||||
if (unitType === UnitType.TABLE_CUSTOM) {
|
||||
return <TableCustomTableConfigButton {...props} />;
|
||||
}
|
||||
if (unitType === UnitType.TABLE_DOC) {
|
||||
return <TableLocalTableConfigButton {...props} />;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 { TableConfigButton, type TableConfigButtonProps } from '../base';
|
||||
import { knowledgeTableConfigMenuContributes } from './knowledge-ide-table-config-menu-contributes';
|
||||
export const TableCustomTableConfigButton = (props: TableConfigButtonProps) => (
|
||||
<TableConfigButton
|
||||
{...props}
|
||||
knowledgeTableConfigMenuContributes={knowledgeTableConfigMenuContributes}
|
||||
/>
|
||||
);
|
||||
@@ -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 {
|
||||
ConfigurationTableStructureModule,
|
||||
createTableConfigMenuRegistry,
|
||||
type TableConfigMenuRegistry,
|
||||
} from '@/features/knowledge-ide-table-config-menus';
|
||||
|
||||
export const knowledgeTableConfigMenuContributes: TableConfigMenuRegistry =
|
||||
(() => {
|
||||
const knowledgeTableConfigMenuRegistry = createTableConfigMenuRegistry(
|
||||
'knowledge-ide-table-custom-config-menu',
|
||||
);
|
||||
knowledgeTableConfigMenuRegistry.registerSome([
|
||||
{
|
||||
type: 'configuration-table-structure',
|
||||
module: ConfigurationTableStructureModule,
|
||||
},
|
||||
]);
|
||||
return knowledgeTableConfigMenuRegistry;
|
||||
})();
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { TableConfigButton, type TableConfigButtonProps } from '../base';
|
||||
import { knowledgeTableLocalConfigMenuContributes } from './knowledge-ide-table-config-menu-contributes';
|
||||
export const TableLocalTableConfigButton = (props: TableConfigButtonProps) => (
|
||||
<TableConfigButton
|
||||
{...props}
|
||||
knowledgeTableConfigMenuContributes={
|
||||
knowledgeTableLocalConfigMenuContributes
|
||||
}
|
||||
/>
|
||||
);
|
||||
@@ -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 {
|
||||
ConfigurationTableStructureModule,
|
||||
createTableConfigMenuRegistry,
|
||||
type TableConfigMenuRegistry,
|
||||
} from '@/features/knowledge-ide-table-config-menus';
|
||||
|
||||
export const knowledgeTableLocalConfigMenuContributes: TableConfigMenuRegistry =
|
||||
(() => {
|
||||
const knowledgeTableConfigMenuRegistry = createTableConfigMenuRegistry(
|
||||
'knowledge-ide-table-local-config-menu',
|
||||
);
|
||||
knowledgeTableConfigMenuRegistry.registerSome([
|
||||
{
|
||||
type: 'configuration-table-structure',
|
||||
module: ConfigurationTableStructureModule,
|
||||
},
|
||||
]);
|
||||
return knowledgeTableConfigMenuRegistry;
|
||||
})();
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* 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, useState } from 'react';
|
||||
|
||||
import { useKnowledgeParams } from '@coze-data/knowledge-stores';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { SceneType, usePageJumpService } from '@coze-arch/bot-hooks';
|
||||
import {
|
||||
type Knowledge,
|
||||
type GetDraftBotInfoAgwData,
|
||||
type KnowledgeInfo,
|
||||
ReferenceUpdateType,
|
||||
BotMode,
|
||||
} from '@coze-arch/bot-api/playground_api';
|
||||
import {
|
||||
type Dataset,
|
||||
DatasetStatus,
|
||||
StorageLocation,
|
||||
} from '@coze-arch/bot-api/knowledge';
|
||||
import { PlaygroundApi } from '@coze-arch/bot-api';
|
||||
import { Toast, Button } from '@coze-arch/coze-design';
|
||||
|
||||
import { ActionType } from '@/types';
|
||||
|
||||
type BotDataset =
|
||||
| Knowledge
|
||||
| {
|
||||
dataset: KnowledgeInfo[];
|
||||
};
|
||||
|
||||
interface UpdateDatasetForBot {
|
||||
botId: string;
|
||||
agentId: string;
|
||||
dataset: BotDataset;
|
||||
updatedDatasetList?: KnowledgeInfo[];
|
||||
spaceId: string;
|
||||
|
||||
dataSetDetail?: Dataset;
|
||||
}
|
||||
export const useFetchBotInfo = (spaceId, botId) => {
|
||||
const [botInfo, setBotInfo] = useState<GetDraftBotInfoAgwData>();
|
||||
const fetchBotInfo = async () => {
|
||||
try {
|
||||
const { data } = await PlaygroundApi.GetDraftBotInfoAgw({
|
||||
bot_id: botId,
|
||||
});
|
||||
setBotInfo(data ?? {});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (spaceId && botId) {
|
||||
fetchBotInfo();
|
||||
}
|
||||
}, [spaceId, botId]);
|
||||
|
||||
return botInfo;
|
||||
};
|
||||
|
||||
const updateDatasetForBot = async ({
|
||||
botId,
|
||||
agentId,
|
||||
dataset,
|
||||
botInfo,
|
||||
updatedDatasetList,
|
||||
spaceId,
|
||||
}: UpdateDatasetForBot & {
|
||||
botInfo?: GetDraftBotInfoAgwData;
|
||||
}) => {
|
||||
if (botInfo?.bot_info.bot_mode === BotMode.SingleMode) {
|
||||
await PlaygroundApi.UpdateDraftBotInfoAgw({
|
||||
bot_info: {
|
||||
bot_id: botId,
|
||||
knowledge: {
|
||||
...dataset,
|
||||
knowledge_info: updatedDatasetList,
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const currentAgent = botInfo?.bot_info?.agents?.find(
|
||||
agent => agent.agent_id === agentId,
|
||||
);
|
||||
if (currentAgent?.agent_id) {
|
||||
await PlaygroundApi.UpdateAgentV2({
|
||||
...currentAgent,
|
||||
current_version:
|
||||
currentAgent.update_type === ReferenceUpdateType.AutoUpdate
|
||||
? '0'
|
||||
: currentAgent.current_version,
|
||||
id: currentAgent?.agent_id,
|
||||
space_id: spaceId,
|
||||
bot_id: botId,
|
||||
knowledge: {
|
||||
...dataset,
|
||||
knowledge_info: updatedDatasetList,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const getUpdatedDataset = (
|
||||
dataset: BotDataset,
|
||||
actionType: ActionType,
|
||||
dataSetDetail: Dataset,
|
||||
): KnowledgeInfo[] => {
|
||||
// 更新后的bot知识库
|
||||
let updatedDatasetList: KnowledgeInfo[] = [];
|
||||
// 原本的bot知识库内容
|
||||
let originDataset: KnowledgeInfo[] = [];
|
||||
|
||||
// 兼容json版本的dataset,FG全量后删除
|
||||
if ('dataset' in dataset) {
|
||||
originDataset = dataset?.dataset ?? [];
|
||||
} else {
|
||||
originDataset = dataset?.knowledge_info ?? [];
|
||||
}
|
||||
|
||||
if (actionType === ActionType.REMOVE) {
|
||||
updatedDatasetList = originDataset?.filter(
|
||||
item => item.id !== dataSetDetail.dataset_id,
|
||||
);
|
||||
} else {
|
||||
updatedDatasetList = [
|
||||
...originDataset,
|
||||
{ name: dataSetDetail.name, id: dataSetDetail.dataset_id },
|
||||
];
|
||||
}
|
||||
|
||||
return updatedDatasetList;
|
||||
};
|
||||
|
||||
// 更新bot知识库逻辑
|
||||
export const handleDatasetUpdate = async ({
|
||||
botInfo,
|
||||
botId,
|
||||
agentId,
|
||||
dataSetDetail = {},
|
||||
dataset,
|
||||
actionType,
|
||||
spaceId,
|
||||
updateSuccess,
|
||||
}: UpdateDatasetForBot & {
|
||||
botInfo?: GetDraftBotInfoAgwData;
|
||||
updateSuccess: () => void;
|
||||
actionType: ActionType;
|
||||
}) => {
|
||||
const updatedDatasetList = getUpdatedDataset(
|
||||
dataset,
|
||||
actionType,
|
||||
dataSetDetail,
|
||||
);
|
||||
|
||||
const updateBotParams = {
|
||||
spaceId,
|
||||
botId,
|
||||
agentId,
|
||||
updatedDatasetList,
|
||||
dataset,
|
||||
};
|
||||
|
||||
await updateDatasetForBot({ ...updateBotParams, botInfo });
|
||||
|
||||
updateSuccess();
|
||||
};
|
||||
|
||||
// 根据不同botInfo信息 获取不同的bot原有的dataset
|
||||
export const getDatasetInfo = (
|
||||
botInfo: GetDraftBotInfoAgwData | undefined,
|
||||
agentId: string,
|
||||
): BotDataset => {
|
||||
if (agentId) {
|
||||
return (
|
||||
botInfo?.bot_info?.agents?.find(item => item.agent_id === agentId)
|
||||
?.knowledge ?? {}
|
||||
);
|
||||
}
|
||||
|
||||
return botInfo?.bot_info?.knowledge ?? {};
|
||||
};
|
||||
|
||||
export const NavBarActionButton = ({
|
||||
dataSetDetail,
|
||||
}: {
|
||||
dataSetDetail: Dataset;
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { jump } = usePageJumpService();
|
||||
const params = useKnowledgeParams();
|
||||
const { spaceID, botID, agentID, actionType } = params;
|
||||
|
||||
const botInfo = useFetchBotInfo(spaceID, botID);
|
||||
|
||||
const dataset = getDatasetInfo(botInfo, agentID ?? '');
|
||||
|
||||
const updateSuccess = () => {
|
||||
Toast.success(
|
||||
I18n.t(
|
||||
actionType === ActionType.REMOVE
|
||||
? 'bot_edit_dataset_removed_toast'
|
||||
: 'bot_edit_dataset_added_toast',
|
||||
{ dataset_name: dataSetDetail.name },
|
||||
),
|
||||
);
|
||||
jump(SceneType.KNOWLEDGE__BACK__BOT, {
|
||||
spaceID,
|
||||
botID,
|
||||
mode:
|
||||
dataSetDetail.storage_location === StorageLocation.Douyin
|
||||
? 'douyin'
|
||||
: 'bot',
|
||||
});
|
||||
};
|
||||
const handleActionClick = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await handleDatasetUpdate({
|
||||
botInfo,
|
||||
botId: botID ?? '',
|
||||
agentId: agentID ?? '',
|
||||
dataSetDetail,
|
||||
dataset,
|
||||
actionType: actionType ?? ActionType.ADD,
|
||||
spaceId: spaceID ?? '',
|
||||
updateSuccess,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={dataSetDetail?.status === DatasetStatus.DatasetForbid}
|
||||
onClick={handleActionClick}
|
||||
>
|
||||
{actionType === ActionType.REMOVE &&
|
||||
dataSetDetail?.storage_location === StorageLocation.Douyin
|
||||
? I18n.t('dy_avatar_resource_delete')
|
||||
: null}
|
||||
{actionType === ActionType.REMOVE &&
|
||||
dataSetDetail?.storage_location !== StorageLocation.Douyin
|
||||
? I18n.t('kl2_014')
|
||||
: null}
|
||||
{actionType !== ActionType.REMOVE &&
|
||||
dataSetDetail?.storage_location === StorageLocation.Douyin
|
||||
? I18n.t('dy_avatar_resource_add')
|
||||
: null}
|
||||
{actionType !== ActionType.REMOVE &&
|
||||
dataSetDetail?.storage_location !== StorageLocation.Douyin
|
||||
? I18n.t('kl2_013')
|
||||
: null}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
|
||||
import { ImportKnowledgeSourceButton } from '@/features/import-knowledge-source-button/base';
|
||||
import { KnowledgeIDENavBar as KnowledgeIDENavBarComponent } from '@/components/knowledge-nav-bar';
|
||||
|
||||
import { type KnowledgeIDENavBarProps } from '../module';
|
||||
|
||||
export const BaseKnowledgeIDENavBar = (props: KnowledgeIDENavBarProps) => {
|
||||
const { progressMap, hideBackButton, importKnowledgeSourceButton } = props;
|
||||
const { setDataSetDetail } = useKnowledgeStore(
|
||||
useShallow(state => ({
|
||||
setDataSetDetail: state.setDataSetDetail,
|
||||
})),
|
||||
);
|
||||
return (
|
||||
<KnowledgeIDENavBarComponent
|
||||
{...props}
|
||||
importKnowledgeSourceButton={
|
||||
importKnowledgeSourceButton ?? <ImportKnowledgeSourceButton />
|
||||
}
|
||||
onChangeDataset={setDataSetDetail}
|
||||
progressMap={progressMap}
|
||||
hideBackButton={hideBackButton}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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, useState } from 'react';
|
||||
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useKnowledgeParams, useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { SceneType, usePageJumpService } from '@coze-arch/bot-hooks';
|
||||
import { StorageLocation } from '@coze-arch/bot-api/knowledge';
|
||||
import { Modal, Toast } from '@coze-arch/coze-design';
|
||||
|
||||
import { ActionType } from '@/types';
|
||||
import {
|
||||
useFetchBotInfo,
|
||||
getDatasetInfo,
|
||||
handleDatasetUpdate,
|
||||
} from '@/features/nav-bar-action-button';
|
||||
|
||||
export const useBeforeKnowledgeIDEClose = ({
|
||||
onBack,
|
||||
}: {
|
||||
onBack?: () => void;
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const {
|
||||
spaceID: spaceId,
|
||||
agentID: agentId,
|
||||
botID: botId,
|
||||
actionType,
|
||||
} = useKnowledgeParams();
|
||||
const { dataSetDetail } = useKnowledgeStore(
|
||||
useShallow(state => ({
|
||||
dataSetDetail: state.dataSetDetail,
|
||||
})),
|
||||
);
|
||||
|
||||
const { jump } = usePageJumpService();
|
||||
|
||||
const botInfo = useFetchBotInfo(spaceId, botId);
|
||||
|
||||
const dataset = getDatasetInfo(botInfo, agentId ?? '');
|
||||
|
||||
const hasAddDataset = useMemo(() => {
|
||||
let datasetIds: string[] = [];
|
||||
if ('dataset' in dataset) {
|
||||
datasetIds = (dataset?.dataset || []).map(item => item.id ?? '');
|
||||
}
|
||||
if ('knowledge_info' in dataset) {
|
||||
datasetIds = (dataset?.knowledge_info || []).map(item => item.id ?? '');
|
||||
}
|
||||
return !datasetIds.includes(dataSetDetail?.dataset_id || '');
|
||||
}, [dataset, dataSetDetail?.dataset_id]);
|
||||
|
||||
const updateSuccessJump = () => {
|
||||
jump(SceneType.KNOWLEDGE__BACK__BOT, {
|
||||
spaceID: spaceId,
|
||||
botID: botId,
|
||||
mode:
|
||||
dataSetDetail?.storage_location === StorageLocation.Douyin
|
||||
? 'douyin'
|
||||
: 'bot',
|
||||
});
|
||||
};
|
||||
const handleFullModalBack = () => {
|
||||
if (onBack) {
|
||||
onBack?.();
|
||||
} else {
|
||||
updateSuccessJump();
|
||||
}
|
||||
};
|
||||
|
||||
const updateSuccess = () => {
|
||||
Toast.success(
|
||||
I18n.t(
|
||||
actionType === ActionType.REMOVE
|
||||
? 'bot_edit_dataset_removed_toast'
|
||||
: 'bot_edit_dataset_added_toast',
|
||||
{ dataset_name: dataSetDetail?.name },
|
||||
),
|
||||
);
|
||||
updateSuccessJump();
|
||||
};
|
||||
|
||||
const handleBotIdeBack = () => {
|
||||
// Bot IDE检查是否有绑定knowledge,如果有绑定知识库正常关闭,没有绑定确认提示处理
|
||||
if (hasAddDataset) {
|
||||
Modal.confirm({
|
||||
title: I18n.t('bot_ide_knowledge_confirm_title'),
|
||||
content:
|
||||
dataSetDetail?.storage_location === StorageLocation.Douyin
|
||||
? I18n.t('dy_avatar_resource_add_tip')
|
||||
: I18n.t('bot_ide_knowledge_confirm_content'),
|
||||
okText: I18n.t('bot_ide_knowledge_confirm_ok'),
|
||||
cancelText: I18n.t('bot_ide_knowledge_confirm_cancel'),
|
||||
confirmLoading: loading,
|
||||
onOk: async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await handleDatasetUpdate({
|
||||
botInfo,
|
||||
botId: botId ?? '',
|
||||
agentId: agentId ?? '',
|
||||
dataSetDetail,
|
||||
dataset,
|
||||
actionType: actionType ?? ActionType.ADD,
|
||||
spaceId: spaceId ?? '',
|
||||
updateSuccess,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
// 无论成功无论都跳转一次
|
||||
handleFullModalBack();
|
||||
}
|
||||
},
|
||||
onCancel: () => {
|
||||
// 取消,正常跳转
|
||||
handleFullModalBack();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// 正常绑定不做弹窗拦截
|
||||
handleFullModalBack();
|
||||
}
|
||||
};
|
||||
|
||||
return handleBotIdeBack;
|
||||
};
|
||||
@@ -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 { useShallow } from 'zustand/react/shallow';
|
||||
import { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
|
||||
import { NavBarActionButton } from '@/features/nav-bar-action-button';
|
||||
import { BizAgentIdeImportKnowledgeSourceButton } from '@/features/import-knowledge-source-button/biz-agent-ide';
|
||||
import { KnowledgeModalNavBar as KnowledgeModalNavBarComponent } from '@/components/knowledge-modal-nav-bar';
|
||||
|
||||
import { type KnowledgeIDENavBarProps } from '../module';
|
||||
import { useBeforeKnowledgeIDEClose } from './hooks/use-case/use-before-knowledgeide-close';
|
||||
|
||||
export type BizAgentIdeKnowledgeIDENavBarProps = KnowledgeIDENavBarProps;
|
||||
|
||||
export const BizAgentIdeKnowledgeIDENavBar = (
|
||||
props: BizAgentIdeKnowledgeIDENavBarProps,
|
||||
) => {
|
||||
const { onBack, importKnowledgeSourceButton } = props;
|
||||
const { dataSetDetail, documentList } = useKnowledgeStore(
|
||||
useShallow(state => ({
|
||||
dataSetDetail: state.dataSetDetail,
|
||||
documentList: state.documentList,
|
||||
})),
|
||||
);
|
||||
const handleBotIdeBack = useBeforeKnowledgeIDEClose({
|
||||
onBack,
|
||||
});
|
||||
return (
|
||||
<KnowledgeModalNavBarComponent
|
||||
title={dataSetDetail?.name as string}
|
||||
onBack={onBack}
|
||||
datasetDetail={dataSetDetail}
|
||||
docInfo={documentList?.[0]}
|
||||
actionButtons={
|
||||
<NavBarActionButton
|
||||
key={dataSetDetail?.dataset_id}
|
||||
dataSetDetail={dataSetDetail}
|
||||
/>
|
||||
}
|
||||
importKnowledgeSourceButton={
|
||||
importKnowledgeSourceButton ?? (
|
||||
<BizAgentIdeImportKnowledgeSourceButton />
|
||||
)
|
||||
}
|
||||
beforeBack={handleBotIdeBack}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 KnowledgeIDENavBarProps } from '../module';
|
||||
import { BaseKnowledgeIDENavBar } from '../base';
|
||||
|
||||
export type BizLibraryKnowledgeIDENavBarProps = KnowledgeIDENavBarProps;
|
||||
|
||||
export const BizLibraryKnowledgeIDENavBar = (
|
||||
props: BizLibraryKnowledgeIDENavBarProps,
|
||||
) => <BaseKnowledgeIDENavBar {...props} />;
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 KnowledgeIDENavBarProps } from '../module';
|
||||
import { BaseKnowledgeIDENavBar } from '../base';
|
||||
|
||||
export type BizProjectKnowledgeIDENavBarProps = KnowledgeIDENavBarProps;
|
||||
|
||||
export const BizProjectKnowledgeIDENavBar = (
|
||||
props: BizProjectKnowledgeIDENavBarProps,
|
||||
) => <BaseKnowledgeIDENavBar {...props} hideBackButton />;
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 { useShallow } from 'zustand/react/shallow';
|
||||
import { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
|
||||
import { KnowledgeModalNavBar as KnowledgeModalNavBarComponent } from '@/components/knowledge-modal-nav-bar';
|
||||
|
||||
import { type KnowledgeIDENavBarProps } from '../module';
|
||||
|
||||
export type BizWorkflowKnowledgeIDENavBarProps = KnowledgeIDENavBarProps;
|
||||
|
||||
export const BizWorkflowKnowledgeIDENavBar = (
|
||||
props: BizWorkflowKnowledgeIDENavBarProps,
|
||||
) => {
|
||||
const { onBack, actionButtons } = props;
|
||||
const { dataSetDetail, documentList } = useKnowledgeStore(
|
||||
useShallow(state => ({
|
||||
dataSetDetail: state.dataSetDetail,
|
||||
documentList: state.documentList,
|
||||
})),
|
||||
);
|
||||
return (
|
||||
<KnowledgeModalNavBarComponent
|
||||
title={dataSetDetail?.name as string}
|
||||
onBack={onBack}
|
||||
datasetDetail={dataSetDetail}
|
||||
docInfo={documentList?.[0]}
|
||||
actionButtons={actionButtons}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -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 ProgressMap } from '@/types';
|
||||
|
||||
export interface KnowledgeIDENavBarProps {
|
||||
progressMap: ProgressMap;
|
||||
hideBackButton?: boolean;
|
||||
textConfigButton?: React.ReactNode;
|
||||
tableConfigButton?: React.ReactNode;
|
||||
importKnowledgeSourceButton?: React.ReactNode;
|
||||
actionButtons?: React.ReactNode;
|
||||
onBack?: () => void;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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, useRef, useState } from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
import { useKnowledgeStore } from '@coze-data/knowledge-stores';
|
||||
import { type TableViewMethods } from '@coze-common/table-view';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { EmptyState, Spin, Layout } from '@coze-arch/coze-design';
|
||||
import { IconSegmentEmpty } from '@coze-arch/bot-icons';
|
||||
import { type DocumentInfo } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import styles from '../styles/index.module.less';
|
||||
import { useGetSliceListData } from '../hooks/inner/use-get-slice-list-data';
|
||||
import { TableUIContext } from '../context/table-ui-context';
|
||||
import { TableDataContext } from '../context/table-data-context';
|
||||
import { TableActionsContext } from '../context/table-actions-context';
|
||||
import { TableDataView } from './table-data-view';
|
||||
|
||||
const MAX_TOTAL = 1000;
|
||||
|
||||
export interface TableKnowledgeWorkspaceProps {
|
||||
onChangeDocList?: (docList: DocumentInfo[]) => void;
|
||||
reload?: () => void;
|
||||
isReloading: boolean;
|
||||
}
|
||||
|
||||
export const TableKnowledgeWorkspace = ({
|
||||
isReloading,
|
||||
}: TableKnowledgeWorkspaceProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const contentWrapperRef = useRef<HTMLDivElement>(null);
|
||||
const tableViewRef = useRef<TableViewMethods>(null);
|
||||
const canEdit = useKnowledgeStore(state => state.canEdit);
|
||||
const documentList = useKnowledgeStore(state => state.documentList)?.filter(
|
||||
doc => doc.document_id,
|
||||
) as { document_id: string }[];
|
||||
const [curIndex, setCurIndex] = useState(0);
|
||||
const [curSliceId, setCurSliceId] = useState('');
|
||||
const [delSliceIds, setDelSliceIds] = useState<string[]>([]);
|
||||
|
||||
const {
|
||||
sliceListData,
|
||||
mutateSliceListData,
|
||||
loadMoreSliceList,
|
||||
isLoadingSliceList,
|
||||
isLoadingMoreSliceList,
|
||||
} = useGetSliceListData();
|
||||
|
||||
const slices = sliceListData?.list;
|
||||
|
||||
const isShowAddBtn = useMemo(
|
||||
() =>
|
||||
Boolean(
|
||||
canEdit &&
|
||||
!sliceListData?.hasMore &&
|
||||
sliceListData?.total &&
|
||||
sliceListData?.total < MAX_TOTAL,
|
||||
),
|
||||
[canEdit, sliceListData],
|
||||
);
|
||||
|
||||
const hasShowEmptyContent = useMemo(() => {
|
||||
if (!documentList?.length && !isReloading) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
sliceListData?.ready &&
|
||||
!slices?.length &&
|
||||
!(isLoadingMoreSliceList || isLoadingSliceList)
|
||||
);
|
||||
}, [
|
||||
sliceListData,
|
||||
documentList,
|
||||
isReloading,
|
||||
isLoadingMoreSliceList,
|
||||
isLoadingSliceList,
|
||||
slices,
|
||||
]);
|
||||
|
||||
// 创建 UI Context 值
|
||||
const uiContextValue = {
|
||||
tableViewRef,
|
||||
isLoadingMoreSliceList,
|
||||
isLoadingSliceList,
|
||||
isShowAddBtn,
|
||||
};
|
||||
|
||||
// 创建数据 Context 值
|
||||
const dataContextValue = {
|
||||
sliceListData: sliceListData || { list: [], total: 0 },
|
||||
curIndex,
|
||||
curSliceId,
|
||||
delSliceIds,
|
||||
};
|
||||
|
||||
// 创建操作 Context 值
|
||||
const actionsContextValue = {
|
||||
setCurIndex,
|
||||
setCurSliceId,
|
||||
setDelSliceIds,
|
||||
loadMoreSliceList,
|
||||
mutateSliceListData,
|
||||
};
|
||||
|
||||
return (
|
||||
<TableUIContext.Provider value={uiContextValue}>
|
||||
<TableDataContext.Provider value={dataContextValue}>
|
||||
<TableActionsContext.Provider value={actionsContextValue}>
|
||||
<Layout.Content
|
||||
ref={containerRef}
|
||||
className={classnames(
|
||||
styles['slice-list-ui-content'],
|
||||
'knowledge-ide-base-slice-list-ui-content',
|
||||
)}
|
||||
>
|
||||
<Spin
|
||||
spinning={isLoadingSliceList}
|
||||
wrapperClassName={styles.spin}
|
||||
size="large"
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
>
|
||||
{slices?.length ? (
|
||||
<div
|
||||
ref={contentWrapperRef}
|
||||
className={styles['slice-list-table']}
|
||||
>
|
||||
<TableDataView />
|
||||
</div>
|
||||
) : null}
|
||||
{hasShowEmptyContent && !isLoadingSliceList ? (
|
||||
<div className={styles['empty-content']}>
|
||||
<EmptyState
|
||||
size="large"
|
||||
icon={
|
||||
<IconSegmentEmpty
|
||||
style={{ width: 150, height: '100%' }}
|
||||
/>
|
||||
}
|
||||
title={I18n.t('dataset_segment_empty_desc')}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</Spin>
|
||||
</Layout.Content>
|
||||
</TableActionsContext.Provider>
|
||||
</TableDataContext.Provider>
|
||||
</TableUIContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 classnames from 'classnames';
|
||||
import {
|
||||
useKnowledgeParamsStore,
|
||||
useKnowledgeStore,
|
||||
} from '@coze-data/knowledge-stores';
|
||||
import { KnowledgeE2e } from '@coze-data/e2e';
|
||||
import { TableView } from '@coze-common/table-view';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { IconCozPlus } from '@coze-arch/coze-design/icons';
|
||||
import { Button } from '@coze-arch/coze-design';
|
||||
import { DocumentStatus } from '@coze-arch/bot-api/knowledge';
|
||||
|
||||
import styles from '../styles/index.module.less';
|
||||
import { getTableRenderColumnsData } from '../service/use-case/get-table-render-columns-data';
|
||||
import { useTableSliceOperations } from '../hooks/use-case/use-table-slice-operations';
|
||||
import { useTableSegmentModal } from '../hooks/use-case/use-table-segment-modal';
|
||||
import { useDeleteSliceModal } from '../hooks/use-case/use-delete-slice-modal';
|
||||
import { useAddRow } from '../hooks/use-case/use-add-row';
|
||||
import { useTableHeight } from '../hooks/inner/use-table-height';
|
||||
import { useScroll } from '../hooks/inner/use-scroll';
|
||||
import { useTableUI } from '../context/table-ui-context';
|
||||
import { useTableData } from '../context/table-data-context';
|
||||
import { useTableActions } from '../context/table-actions-context';
|
||||
|
||||
// 表格内容组件
|
||||
const TableContent = () => {
|
||||
const knowledgeIDEBiz = useKnowledgeParamsStore(state => state.params.biz);
|
||||
const documentList = useKnowledgeStore(state => state.documentList);
|
||||
const curDoc = documentList?.[0];
|
||||
|
||||
const { tableViewRef, isLoadingMoreSliceList, isLoadingSliceList } =
|
||||
useTableUI();
|
||||
|
||||
const { sliceListData } = useTableData();
|
||||
|
||||
const slices = sliceListData?.list;
|
||||
|
||||
const { loadMoreSliceList } = useTableActions();
|
||||
|
||||
const canEdit = Boolean(useKnowledgeStore(state => state.canEdit));
|
||||
|
||||
// 删除切片弹窗
|
||||
const { deleteSliceModalNode, openDeleteSliceModal } = useDeleteSliceModal();
|
||||
|
||||
// 编辑slice弹窗
|
||||
const { tableSegmentModalNode, openTableSegmentModal } =
|
||||
useTableSegmentModal();
|
||||
|
||||
// 获取表格操作方法
|
||||
const { deleteSlice, rowUpdateSliceData, modalEditSlice } =
|
||||
useTableSliceOperations({
|
||||
openDeleteSliceModal,
|
||||
openTableSegmentModal,
|
||||
});
|
||||
|
||||
const { tableH } = useTableHeight();
|
||||
|
||||
// 如果没有数据,直接返回空
|
||||
if (!slices?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tableKey = curDoc?.document_id;
|
||||
|
||||
const { data: dataSource, columns } = getTableRenderColumnsData({
|
||||
sliceList: slices,
|
||||
metaData: curDoc?.table_meta,
|
||||
onEdit: modalEditSlice,
|
||||
onDelete: deleteSlice,
|
||||
onUpdate: rowUpdateSliceData,
|
||||
canEdit,
|
||||
tableKey: tableKey || '',
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(
|
||||
styles['table-view-container-box'],
|
||||
'table-view-box',
|
||||
)}
|
||||
style={{ height: tableH }}
|
||||
>
|
||||
<TableView
|
||||
tableKey={tableKey}
|
||||
ref={tableViewRef}
|
||||
className={classnames(
|
||||
`${styles['unit-table-view']} ${
|
||||
isLoadingMoreSliceList ? styles['table-view-loading'] : ''
|
||||
}`,
|
||||
knowledgeIDEBiz === 'project'
|
||||
? styles['table-preview-max']
|
||||
: styles['table-preview-secondary'],
|
||||
)}
|
||||
resizable
|
||||
dataSource={dataSource}
|
||||
loading={isLoadingSliceList}
|
||||
columns={columns}
|
||||
rowSelect={canEdit}
|
||||
isVirtualized
|
||||
rowOperation={canEdit}
|
||||
scrollToBottom={() => {
|
||||
if (!isLoadingSliceList && !isLoadingMoreSliceList) {
|
||||
loadMoreSliceList();
|
||||
}
|
||||
}}
|
||||
editProps={{
|
||||
onDelete: indexs => deleteSlice(indexs as number[]),
|
||||
onEdit: (record, index) => {
|
||||
modalEditSlice(record, index as number);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
{deleteSliceModalNode}
|
||||
{tableSegmentModalNode}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 添加行按钮组件
|
||||
const AddRowButton = () => {
|
||||
const { isShowAddBtn } = useTableUI();
|
||||
const documentList = useKnowledgeStore(state => state.documentList);
|
||||
const curDoc = documentList?.[0];
|
||||
const { increaseTableHeight } = useTableHeight();
|
||||
const { scrollTableBodyToBottom } = useScroll();
|
||||
const { handleAddRow } = useAddRow({
|
||||
increaseTableHeight,
|
||||
scrollTableBodyToBottom,
|
||||
});
|
||||
|
||||
if (!isShowAddBtn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['add-row-btn']}>
|
||||
<Button
|
||||
disabled={curDoc?.status === DocumentStatus.Processing}
|
||||
data-testid={KnowledgeE2e.SegmentDetailContentAddRowBtn}
|
||||
color="primary"
|
||||
size="default"
|
||||
icon={<IconCozPlus />}
|
||||
onClick={handleAddRow}
|
||||
>
|
||||
{I18n.t('knowledge_optimize_0010')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 主组件
|
||||
export const TableDataView = () => {
|
||||
const { sliceListData } = useTableData();
|
||||
const slices = sliceListData?.list;
|
||||
|
||||
// 如果没有数据,只显示添加按钮
|
||||
if (!slices?.length) {
|
||||
return <AddRowButton />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableContent />
|
||||
<AddRowButton />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 { createContext, useContext } from 'react';
|
||||
|
||||
import { type DatasetDataScrollList } from '@/service';
|
||||
|
||||
// 表格操作相关的 Context
|
||||
interface TableActionsContextType {
|
||||
setCurIndex: (index: number | ((prev: number) => number)) => void;
|
||||
setCurSliceId: (id: string | ((prev: string) => string)) => void;
|
||||
setDelSliceIds: (ids: string[] | ((prev: string[]) => string[])) => void;
|
||||
loadMoreSliceList: () => void;
|
||||
mutateSliceListData: (data: DatasetDataScrollList) => void;
|
||||
}
|
||||
|
||||
export const TableActionsContext =
|
||||
createContext<TableActionsContextType | null>(null);
|
||||
|
||||
export const useTableActions = () => {
|
||||
const context = useContext(TableActionsContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
'useTableActions must be used within a TableActionsProvider',
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 { createContext, useContext } from 'react';
|
||||
|
||||
import { type DatasetDataScrollList } from '@/service';
|
||||
|
||||
// 表格数据相关的 Context
|
||||
interface TableDataContextType {
|
||||
sliceListData: DatasetDataScrollList;
|
||||
curIndex: number;
|
||||
curSliceId: string;
|
||||
delSliceIds: string[];
|
||||
}
|
||||
|
||||
export const TableDataContext = createContext<TableDataContextType | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
export const useTableData = () => {
|
||||
const context = useContext(TableDataContext);
|
||||
if (!context) {
|
||||
throw new Error('useTableData must be used within a TableDataProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
import { createContext, useContext } from 'react';
|
||||
import { type MutableRefObject } from 'react';
|
||||
|
||||
import { type TableViewMethods } from '@coze-common/table-view';
|
||||
|
||||
// 表格 UI 相关的 Context
|
||||
interface TableUIContextType {
|
||||
tableViewRef: MutableRefObject<TableViewMethods | null>;
|
||||
isLoadingMoreSliceList: boolean;
|
||||
isLoadingSliceList: boolean;
|
||||
isShowAddBtn: boolean;
|
||||
}
|
||||
|
||||
export const TableUIContext = createContext<TableUIContextType | null>(null);
|
||||
|
||||
export const useTableUI = () => {
|
||||
const context = useContext(TableUIContext);
|
||||
if (!context) {
|
||||
throw new Error('useTableUI must be used within a TableUIProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user