From 8de12ef1d73b874afc54b4c71194af8a03224205 Mon Sep 17 00:00:00 2001 From: nite-knite Date: Fri, 13 Dec 2024 14:37:22 +0800 Subject: [PATCH] feat: update dataset creation UI --- web/app/components/base/app-icon/index.tsx | 2 +- .../components/base/app-icon/style.module.css | 6 +- .../base/simple-pie-chart/index.tsx | 7 +- .../billing/priority-label/index.tsx | 8 +- .../create/embedding-process/index.module.css | 52 +++------ .../create/embedding-process/index.tsx | 109 +++++++++--------- .../create/file-uploader/index.module.css | 55 --------- .../datasets/create/file-uploader/index.tsx | 82 ++++++++----- .../datasets/create/step-one/index.module.css | 17 --- .../datasets/create/step-one/index.tsx | 16 ++- .../datasets/create/step-three/index.tsx | 30 ++--- .../documents/detail/metadata/index.tsx | 7 +- .../detail/metadata/style.module.css | 13 +-- web/i18n/en-US/dataset-creation.ts | 1 + web/i18n/zh-Hans/dataset-creation.ts | 1 + web/i18n/zh-Hant/dataset-creation.ts | 1 + web/tailwind.config.js | 4 +- 17 files changed, 170 insertions(+), 241 deletions(-) diff --git a/web/app/components/base/app-icon/index.tsx b/web/app/components/base/app-icon/index.tsx index 5e7378c087..832ae64c1b 100644 --- a/web/app/components/base/app-icon/index.tsx +++ b/web/app/components/base/app-icon/index.tsx @@ -33,7 +33,7 @@ const AppIcon: FC = ({ onClick, }) => { const wrapperClassName = classNames( - style.appIcon, + 'flex items-center justify-center relative w-9 h-9 text-lg rounded-lg grow-0 shrink-0', size !== 'medium' && style[size], rounded && style.rounded, className ?? '', diff --git a/web/app/components/base/app-icon/style.module.css b/web/app/components/base/app-icon/style.module.css index 06a2478d41..8554058ffb 100644 --- a/web/app/components/base/app-icon/style.module.css +++ b/web/app/components/base/app-icon/style.module.css @@ -1,7 +1,3 @@ -.appIcon { - @apply flex items-center justify-center relative w-9 h-9 text-lg rounded-lg grow-0 shrink-0; -} - .appIcon.large { @apply w-10 h-10; } @@ -20,4 +16,4 @@ .appIcon.rounded { @apply rounded-full; -} \ No newline at end of file +} diff --git a/web/app/components/base/simple-pie-chart/index.tsx b/web/app/components/base/simple-pie-chart/index.tsx index 7de539cbb1..4b987ab42d 100644 --- a/web/app/components/base/simple-pie-chart/index.tsx +++ b/web/app/components/base/simple-pie-chart/index.tsx @@ -10,10 +10,11 @@ export type SimplePieChartProps = { fill?: string stroke?: string size?: number + animationDuration?: number className?: string } -const SimplePieChart = ({ percentage = 80, fill = '#fdb022', stroke = '#f79009', size = 12, className }: SimplePieChartProps) => { +const SimplePieChart = ({ percentage = 80, fill = '#fdb022', stroke = '#f79009', size = 12, animationDuration, className }: SimplePieChartProps) => { const option: EChartsOption = useMemo(() => ({ series: [ { @@ -34,7 +35,7 @@ const SimplePieChart = ({ percentage = 80, fill = '#fdb022', stroke = '#f79009', { type: 'pie', radius: '83%', - animationDuration: 600, + animationDuration: animationDuration ?? 600, data: [ { value: percentage, itemStyle: { color: fill } }, { value: 100 - percentage, itemStyle: { color: '#fff' } }, @@ -48,7 +49,7 @@ const SimplePieChart = ({ percentage = 80, fill = '#fdb022', stroke = '#f79009', cursor: 'default', }, ], - }), [stroke, fill, percentage]) + }), [stroke, fill, percentage, animationDuration]) return ( { }> { plan.type === Plan.professional && ( - + ) } { (plan.type === Plan.team || plan.type === Plan.enterprise) && ( - + ) } {t(`billing.plansCommon.priority.${priority}`)} diff --git a/web/app/components/datasets/create/embedding-process/index.module.css b/web/app/components/datasets/create/embedding-process/index.module.css index 1ebb006b54..f2ab4d85a2 100644 --- a/web/app/components/datasets/create/embedding-process/index.module.css +++ b/web/app/components/datasets/create/embedding-process/index.module.css @@ -14,24 +14,7 @@ border-radius: 6px; overflow: hidden; } -.sourceItem.error { - background: #FEE4E2; -} -.sourceItem.success { - background: #D1FADF; -} -.progressbar { - position: absolute; - top: 0; - left: 0; - height: 100%; - background-color: #B2CCFF; -} -.sourceItem .info { - display: flex; - align-items: center; - z-index: 1; -} + .sourceItem .info .name { font-weight: 500; font-size: 12px; @@ -55,13 +38,6 @@ color: #05603A; } - -.cost { - @apply flex justify-between items-center text-xs text-gray-700; -} -.embeddingStatus { - @apply flex items-center justify-between text-gray-900 font-medium text-sm mr-2; -} .commonIcon { @apply w-3 h-3 mr-1 inline-block align-middle; } @@ -81,35 +57,33 @@ @apply text-xs font-medium; } -.fileIcon { - @apply w-4 h-4 mr-1 bg-center bg-no-repeat; +.unknownFileIcon { background-image: url(../assets/unknown.svg); - background-size: 16px; } -.fileIcon.csv { +.csv { background-image: url(../assets/csv.svg); } -.fileIcon.docx { +.docx { background-image: url(../assets/docx.svg); } -.fileIcon.xlsx, -.fileIcon.xls { +.xlsx, +.xls { background-image: url(../assets/xlsx.svg); } -.fileIcon.pdf { +.pdf { background-image: url(../assets/pdf.svg); } -.fileIcon.html, -.fileIcon.htm { +.html, +.htm { background-image: url(../assets/html.svg); } -.fileIcon.md, -.fileIcon.markdown { +.md, +.markdown { background-image: url(../assets/md.svg); } -.fileIcon.txt { +.txt { background-image: url(../assets/txt.svg); } -.fileIcon.json { +.json { background-image: url(../assets/json.svg); } diff --git a/web/app/components/datasets/create/embedding-process/index.tsx b/web/app/components/datasets/create/embedding-process/index.tsx index f6d500ef15..64f2570b4a 100644 --- a/web/app/components/datasets/create/embedding-process/index.tsx +++ b/web/app/components/datasets/create/embedding-process/index.tsx @@ -6,13 +6,15 @@ import { useTranslation } from 'react-i18next' import { omit } from 'lodash-es' import { ArrowRightIcon } from '@heroicons/react/24/solid' import { + RiCheckboxCircleFill, RiErrorWarningFill, RiLoader2Fill, RiTerminalBoxLine, } from '@remixicon/react' import Image from 'next/image' import { indexMethodIcon, retrievalIcon } from '../icons' -import s from './index.module.css' +import { IndexingType } from '../step-two' +import DocumentFileIcon from '../../common/document-file-icon' import cn from '@/utils/classnames' import { FieldInfo } from '@/app/components/datasets/documents/detail/metadata' import Button from '@/app/components/base/button' @@ -25,7 +27,6 @@ import { Plan } from '@/app/components/billing/type' import { ZapFast } from '@/app/components/base/icons/src/vender/solid/general' import UpgradeBtn from '@/app/components/billing/upgrade-btn' import { useProviderContext } from '@/context/provider-context' -import Tooltip from '@/app/components/base/tooltip' import { sleep } from '@/utils' import { RETRIEVE_METHOD } from '@/types/app' @@ -83,7 +84,7 @@ const RuleDetail: FC<{ return value }, [sourceData]) - return
+ return
{Object.keys(segmentationRuleMap).map((field) => { return @@ -167,6 +171,7 @@ const EmbeddingProcess: FC = ({ datasetId, batchId, documents = [], index } useEffect(() => { + setIsStopQuery(false) startQueryStatus() return () => { stopQueryStatus() @@ -225,8 +230,8 @@ const EmbeddingProcess: FC = ({ datasetId, batchId, documents = [], index return ( <> -
-
+
+
{isEmbedding &&
{t('datasetDocuments.embedding.processing')} @@ -247,68 +252,68 @@ const EmbeddingProcess: FC = ({ datasetId, batchId, documents = [], index
) } -
+
{indexingStatusBatchDetail.map(indexingStatusDetail => (
{isSourceEmbedding(indexingStatusDetail) && ( -
+
)} -
+
{getSourceType(indexingStatusDetail.id) === DataSourceType.FILE && ( -
+ //
+ )} {getSourceType(indexingStatusDetail.id) === DataSourceType.NOTION && ( )} -
{getSourceName(indexingStatusDetail.id)}
- { - enableBilling && ( - - ) - } -
-
- {isSourceEmbedding(indexingStatusDetail) && ( -
{`${getSourcePercent(indexingStatusDetail)}%`}
- )} - {indexingStatusDetail.indexing_status === 'error' && indexingStatusDetail.error && ( - - {indexingStatusDetail.error} -
- )} - > -
- Error - -
- - )} - {indexingStatusDetail.indexing_status === 'error' && !indexingStatusDetail.error && ( -
- Error +
+
+ {getSourceName(indexingStatusDetail.id)}
+ { + enableBilling && ( + + ) + } +
+ {isSourceEmbedding(indexingStatusDetail) && ( +
{`${getSourcePercent(indexingStatusDetail)}%`}
+ )} + {indexingStatusDetail.indexing_status === 'error' && ( + <> + + {indexingStatusDetail.error || 'Error'} + + + )} {indexingStatusDetail.indexing_status === 'completed' && ( -
100%
+ )}
))}
- +
+
+ {/* */} + +
)} {dataSourceType === DataSourceType.NOTION && ( @@ -249,7 +258,10 @@ const StepOne = ({ {!datasetId && ( <>
-
{t('datasetCreation.stepOne.emptyDatasetCreation')}
+ + + {t('datasetCreation.stepOne.emptyDatasetCreation')} + )}
diff --git a/web/app/components/datasets/create/step-three/index.tsx b/web/app/components/datasets/create/step-three/index.tsx index 1e7c49ac37..e2bc7f5881 100644 --- a/web/app/components/datasets/create/step-three/index.tsx +++ b/web/app/components/datasets/create/step-three/index.tsx @@ -24,29 +24,29 @@ const StepThree = ({ datasetId, datasetName, indexingType, creationCache, retrie const isMobile = media === MediaType.mobile return ( -
-
-
+
+
+
{!datasetId && ( <> -
-
{t('datasetCreation.stepThree.creationTitle')}
-
{t('datasetCreation.stepThree.creationContent')}
-
- -
-
{t('datasetCreation.stepThree.label')}
-
{datasetName || creationCache?.dataset?.name}
+
+
{t('datasetCreation.stepThree.creationTitle')}
+
{t('datasetCreation.stepThree.creationContent')}
+
+ +
+
{t('datasetCreation.stepThree.label')}
+
{datasetName || creationCache?.dataset?.name}
-
+
)} {datasetId && ( -
-
{t('datasetCreation.stepThree.additionTitle')}
-
{`${t('datasetCreation.stepThree.additionP1')} ${datasetName || creationCache?.dataset?.name} ${t('datasetCreation.stepThree.additionP2')}`}
+
+
{t('datasetCreation.stepThree.additionTitle')}
+
{`${t('datasetCreation.stepThree.additionP1')} ${datasetName || creationCache?.dataset?.name} ${t('datasetCreation.stepThree.additionP2')}`}
)} { return Object.keys(map).map(key => ({ value: key, name: map[key] })) @@ -59,9 +58,9 @@ export const FieldInfo: FC = ({ const readAlignTop = !showEdit && textNeedWrap return ( -
-
{label}
-
+
+
{label}
+
{valueIcon} {!showEdit ? displayedValue diff --git a/web/app/components/datasets/documents/detail/metadata/style.module.css b/web/app/components/datasets/documents/detail/metadata/style.module.css index 60420c196e..37796d38dc 100644 --- a/web/app/components/datasets/documents/detail/metadata/style.module.css +++ b/web/app/components/datasets/documents/detail/metadata/style.module.css @@ -53,18 +53,7 @@ .desc { @apply text-gray-500 text-xs; } -.fieldInfo { - /* height: 1.75rem; */ - min-height: 1.75rem; - @apply flex flex-row items-center gap-4; -} -.fieldInfo > .label { - @apply w-2/5 max-w-[128px] text-gray-500 text-xs font-medium overflow-hidden text-ellipsis whitespace-nowrap; -} -.fieldInfo > .value { - overflow-wrap: anywhere; - @apply w-3/5 text-gray-700 font-normal text-xs; -} + .changeTip { @apply text-[#D92D20] text-xs text-center; } diff --git a/web/i18n/en-US/dataset-creation.ts b/web/i18n/en-US/dataset-creation.ts index 514738e9da..a05a683d0f 100644 --- a/web/i18n/en-US/dataset-creation.ts +++ b/web/i18n/en-US/dataset-creation.ts @@ -47,6 +47,7 @@ const translation = { notionSyncTitle: 'Notion is not connected', notionSyncTip: 'To sync with Notion, connection to Notion must be established first.', connect: 'Go to connect', + cancel: 'Cancel', button: 'Next', emptyDatasetCreation: 'I want to create an empty Knowledge', modal: { diff --git a/web/i18n/zh-Hans/dataset-creation.ts b/web/i18n/zh-Hans/dataset-creation.ts index 48e1b4e7f2..30e32023f7 100644 --- a/web/i18n/zh-Hans/dataset-creation.ts +++ b/web/i18n/zh-Hans/dataset-creation.ts @@ -47,6 +47,7 @@ const translation = { notionSyncTitle: 'Notion 未绑定', notionSyncTip: '同步 Notion 内容前,须先绑定 Notion 空间', connect: '去绑定', + cancel: '取消', button: '下一步', emptyDatasetCreation: '创建一个空知识库', modal: { diff --git a/web/i18n/zh-Hant/dataset-creation.ts b/web/i18n/zh-Hant/dataset-creation.ts index 8c5673cb3f..e4f5011859 100644 --- a/web/i18n/zh-Hant/dataset-creation.ts +++ b/web/i18n/zh-Hant/dataset-creation.ts @@ -37,6 +37,7 @@ const translation = { notionSyncTitle: 'Notion 未繫結', notionSyncTip: '同步 Notion 內容前,須先繫結 Notion 空間', connect: '去繫結', + cancel: '取消', button: '下一步', emptyDatasetCreation: '建立一個空知識庫', modal: { diff --git a/web/tailwind.config.js b/web/tailwind.config.js index 4759c2fa80..0188d071fd 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ import tailwindThemeVarDefine from './themes/tailwind-theme-var-define' -module.exports = { +const config = { content: [ './app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', @@ -115,3 +115,5 @@ module.exports = { preflight: false, }, } + +export default config