diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx index 91f4ac7543..8568c7d7b6 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx @@ -39,10 +39,10 @@ const AppDetailLayout: FC = (props) => { const navigation = useMemo(() => { const navs = [ { name: t('common.appMenus.overview'), href: `/app/${appId}/overview`, icon: ChartBarSquareIcon, selectedIcon: ChartBarSquareSolidIcon }, - isCurrentWorkspaceManager ? { name: t('common.appMenus.promptEng'), href: `/app/${appId}/configuration`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon } : false, + ...(isCurrentWorkspaceManager ? [{ name: t('common.appMenus.promptEng'), href: `/app/${appId}/configuration`, icon: Cog8ToothIcon, selectedIcon: Cog8ToothSolidIcon }] : []), { name: t('common.appMenus.apiAccess'), href: `/app/${appId}/develop`, icon: CommandLineIcon, selectedIcon: CommandLineSolidIcon }, { name: t('common.appMenus.logAndAnn'), href: `/app/${appId}/logs`, icon: DocumentTextIcon, selectedIcon: DocumentTextSolidIcon }, - ].filter(nav => !!nav) + ] return navs }, [appId, isCurrentWorkspaceManager, t]) @@ -56,7 +56,7 @@ const AppDetailLayout: FC = (props) => { return (
-
{children}
+
{children}
) } diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView.tsx index eb72675d02..b376ffeb97 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView.tsx @@ -93,7 +93,7 @@ const CardView: FC = ({ appId }) => { } return ( -
+
+
{t('overview.title')} diff --git a/web/app/(commonLayout)/apps/NewAppDialog.tsx b/web/app/(commonLayout)/apps/NewAppDialog.tsx index ffac6d9de3..ba9cde0e0d 100644 --- a/web/app/(commonLayout)/apps/NewAppDialog.tsx +++ b/web/app/(commonLayout)/apps/NewAppDialog.tsx @@ -122,7 +122,7 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => {
-
+

{t('app.newApp.captionAppType')}

{isWithTemplate && ( @@ -139,7 +139,7 @@ const NewAppDialog = ({ show, onSuccess, onClose }: NewAppDialogProps) => {
{isWithTemplate ? ( -
    +
      {templates?.data?.map((template, index) => (
    • { ) : ( <> -
        +
        • setNewAppMode('chat')} diff --git a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx index 3458b14a62..bd93da43e7 100644 --- a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx +++ b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx @@ -4,6 +4,8 @@ import React, { useEffect } from 'react' import { usePathname } from 'next/navigation' import useSWR from 'swr' import { useTranslation } from 'react-i18next' +import classNames from 'classnames' +import { useBoolean } from 'ahooks' import { Cog8ToothIcon, // CommandLineIcon, @@ -11,6 +13,8 @@ import { // eslint-disable-next-line sort-imports PuzzlePieceIcon, DocumentTextIcon, + PaperClipIcon, + QuestionMarkCircleIcon, } from '@heroicons/react/24/outline' import { Cog8ToothIcon as Cog8ToothSolidIcon, @@ -20,29 +24,39 @@ import { import Link from 'next/link' import s from './style.module.css' import { fetchDatasetDetail, fetchDatasetRelatedApps } from '@/service/datasets' -import type { RelatedApp } from '@/models/datasets' +import type { RelatedApp, RelatedAppResponse } from '@/models/datasets' import { getLocaleOnClient } from '@/i18n/client' import AppSideBar from '@/app/components/app-sidebar' import Divider from '@/app/components/base/divider' import Indicator from '@/app/components/header/indicator' import AppIcon from '@/app/components/base/app-icon' import Loading from '@/app/components/base/loading' +import FloatPopoverContainer from '@/app/components/base/float-popover-container' import DatasetDetailContext from '@/context/dataset-detail' import { DataSourceType } from '@/models/datasets' +import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' export type IAppDetailLayoutProps = { children: React.ReactNode params: { datasetId: string } } -const LikedItem: FC<{ type?: 'plugin' | 'app'; appStatus?: boolean; detail: RelatedApp }> = ({ +type ILikedItemProps = { + type?: 'plugin' | 'app' + appStatus?: boolean + detail: RelatedApp + isMobile: boolean +} + +const LikedItem = ({ type = 'app', appStatus = true, detail, -}) => { + isMobile, +}: ILikedItemProps) => { return ( - -
          + +
          {type === 'app' && (
          @@ -50,7 +64,7 @@ const LikedItem: FC<{ type?: 'plugin' | 'app'; appStatus?: boolean; detail: Rela
          )}
          -
          {detail?.name || '--'}
          + {!isMobile &&
          {detail?.name || '--'}
          } ) } @@ -83,6 +97,68 @@ const BookOpenIcon = ({ className }: SVGProps) => { } +type IExtraInfoProps = { + isMobile: boolean + relatedApps?: RelatedAppResponse +} + +const ExtraInfo = ({ isMobile, relatedApps }: IExtraInfoProps) => { + const locale = getLocaleOnClient() + const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile) + const { t } = useTranslation() + + useEffect(() => { + setShowTips(!isMobile) + }, [isMobile, setShowTips]) + + return
          + + {(relatedApps?.data && relatedApps?.data?.length > 0) && ( + <> + {!isMobile &&
          {relatedApps?.total || '--'} {t('common.datasetMenus.relatedApp')}
          } + {isMobile &&
          + {relatedApps?.total || '--'} + +
          } + {relatedApps?.data?.map((item, index) => ())} + + )} + {!relatedApps?.data?.length && ( + + +
          + } + > +
          +
          +
          + +
          +
          + +
          +
          +
          {t('common.datasetMenus.emptyTip')}
          + + + {t('common.datasetMenus.viewDoc')} + +
          + + )} +
          +} + const DatasetDetailLayout: FC = (props) => { const { children, @@ -91,6 +167,10 @@ const DatasetDetailLayout: FC = (props) => { const pathname = usePathname() const hideSideBar = /documents\/create$/.test(pathname) const { t } = useTranslation() + + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const { data: datasetRes, error, mutate: mutateDatasetRes } = useSWR({ url: 'fetchDatasetDetail', datasetId, @@ -113,54 +193,18 @@ const DatasetDetailLayout: FC = (props) => { document.title = `${datasetRes.name || 'Dataset'} - Dify` }, [datasetRes]) - const ExtraInfo: FC = () => { - const locale = getLocaleOnClient() - - return
          - - {relatedApps?.data?.length - ? ( - <> -
          {relatedApps?.total || '--'} {t('common.datasetMenus.relatedApp')}
          - {relatedApps?.data?.map((item, index) => ())} - - ) - : ( -
          -
          -
          - -
          -
          - -
          -
          -
          {t('common.datasetMenus.emptyTip')}
          - - - {t('common.datasetMenus.viewDoc')} - -
          - )} -
          - } - if (!datasetRes && !error) return return ( -
          +
          {!hideSideBar && } + extraInfo={} iconType={datasetRes?.data_source_type === DataSourceType.NOTION ? 'notion' : 'dataset'} />} = (props) => { dataset: datasetRes, mutateDatasetRes: () => mutateDatasetRes(), }}> -
          {children}
          +
          {children}
          ) diff --git a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/settings/page.tsx b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/settings/page.tsx index 9a2eb8e62b..f52679bd83 100644 --- a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/settings/page.tsx +++ b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/settings/page.tsx @@ -14,14 +14,12 @@ const Settings = async ({ const { t } = await useTranslation(locale, 'dataset-settings') return ( -
          +
          {t('title')}
          {t('desc')}
          -
          -
          -
          +
          ) } diff --git a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/style.module.css b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/style.module.css index 786726703f..1cce1a16d4 100644 --- a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/style.module.css +++ b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/style.module.css @@ -1,11 +1,11 @@ .itemWrapper { - @apply flex items-center w-full h-10 px-3 rounded-lg hover:bg-gray-50 cursor-pointer; + @apply flex items-center w-full h-10 rounded-lg hover:bg-gray-50 cursor-pointer; } .appInfo { @apply truncate text-gray-700 text-sm font-normal; } .iconWrapper { - @apply relative w-6 h-6 mr-2 bg-[#D5F5F6] rounded-md; + @apply relative w-6 h-6 bg-[#D5F5F6] rounded-md; } .statusPoint { @apply flex justify-center items-center absolute -right-0.5 -bottom-0.5 w-2.5 h-2.5 bg-white rounded; diff --git a/web/app/(commonLayout)/datasets/ApiServer.tsx b/web/app/(commonLayout)/datasets/ApiServer.tsx index 675dda354e..7baa342a62 100644 --- a/web/app/(commonLayout)/datasets/ApiServer.tsx +++ b/web/app/(commonLayout)/datasets/ApiServer.tsx @@ -15,10 +15,10 @@ const ApiServer: FC = ({ const { t } = useTranslation() return ( -
          -
          -
          {t('appApi.apiServer')}
          -
          {apiBaseUrl}
          +
          +
          +
          {t('appApi.apiServer')}
          +
          {apiBaseUrl}
          { return (
          -
          +
          setActiveTab(newActiveTab)} @@ -38,16 +38,14 @@ const Container = () => { {activeTab === 'api' && data && }
          - {activeTab === 'dataset' - ? ( - <> - - - - ) - : ( - activeTab === 'api' && data && - )} + {activeTab === 'dataset' && ( + <> + + + + )} + + {activeTab === 'api' && data && }
          ) diff --git a/web/app/(commonLayout)/datasets/Doc.tsx b/web/app/(commonLayout)/datasets/Doc.tsx index a66da56ae1..f12c97b248 100644 --- a/web/app/(commonLayout)/datasets/Doc.tsx +++ b/web/app/(commonLayout)/datasets/Doc.tsx @@ -15,7 +15,7 @@ const Doc: FC = ({ const { locale } = useContext(I18n) return ( -
          +
          { locale === 'en' ? diff --git a/web/app/components/app-sidebar/basic.tsx b/web/app/components/app-sidebar/basic.tsx index 5015676871..610e770133 100644 --- a/web/app/components/app-sidebar/basic.tsx +++ b/web/app/components/app-sidebar/basic.tsx @@ -15,6 +15,7 @@ export type IAppBasicProps = { hoverTip?: string textStyle?: { main?: string; extra?: string } isExtraInLine?: boolean + mode?: 'expand' | 'collapse' } const ApiSvg = @@ -31,18 +32,18 @@ const DatasetSvg = const WebappSvg = - + const NotionSvg = - - - + + + - + @@ -55,7 +56,7 @@ const ICON_MAP = { notion: , } -export default function AppBasic({ icon, icon_background, name, type, hoverTip, textStyle, iconType = 'app', isExtraInLine }: IAppBasicProps) { +export default function AppBasic({ icon, icon_background, name, type, hoverTip, textStyle, mode = 'expand', iconType = 'app', isExtraInLine }: IAppBasicProps) { return (
          {icon && icon_background && iconType === 'app' && ( @@ -69,7 +70,7 @@ export default function AppBasic({ icon, icon_background, name, type, hoverTip,
          } -
          + {mode === 'expand' &&
          {name} {hoverTip @@ -78,7 +79,7 @@ export default function AppBasic({ icon, icon_background, name, type, hoverTip, }
          {type}
          -
          +
          }
          ) } diff --git a/web/app/components/app-sidebar/index.tsx b/web/app/components/app-sidebar/index.tsx index 73579acd66..2ad50c4055 100644 --- a/web/app/components/app-sidebar/index.tsx +++ b/web/app/components/app-sidebar/index.tsx @@ -1,8 +1,8 @@ import React from 'react' import NavLink from './navLink' -import AppBasic from './basic' - import type { NavIcon } from './navLink' +import AppBasic from './basic' +import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' export type IAppDetailNavProps = { iconType?: 'app' | 'dataset' | 'notion' @@ -20,15 +20,19 @@ export type IAppDetailNavProps = { } const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInfo, iconType = 'app' }: IAppDetailNavProps) => { + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const mode = isMobile ? 'collapse' : 'expand' + return ( -
          +
          - +
          {isShowConfig && ( @@ -340,7 +345,7 @@ const ConfigModel: FC = ({
          = ({ > <> {getToneIcon(tone.id)} -
          {t(`common.model.tone.${tone.name}`) as string}
          + {!isMobile &&
          {t(`common.model.tone.${tone.name}`) as string}
          }
          @@ -361,12 +366,12 @@ const ConfigModel: FC = ({ <> {getToneIcon(TONE_LIST[3].id)} -
          {t(`common.model.tone.${TONE_LIST[3].name}`) as string}
          + {!isMobile &&
          {t(`common.model.tone.${TONE_LIST[3].name}`) as string}
          }
          diff --git a/web/app/components/app/configuration/config-model/model-mode-type-label.tsx b/web/app/components/app/configuration/config-model/model-mode-type-label.tsx index efc3af1e23..8f4791541d 100644 --- a/web/app/components/app/configuration/config-model/model-mode-type-label.tsx +++ b/web/app/components/app/configuration/config-model/model-mode-type-label.tsx @@ -20,7 +20,7 @@ const ModelModeTypeLabel: FC = ({ return (
          {t(`appDebug.modelConfig.modeType.${type}`)}
          diff --git a/web/app/components/app/configuration/config-model/model-name.tsx b/web/app/components/app/configuration/config-model/model-name.tsx index 123960edb9..789aea537f 100644 --- a/web/app/components/app/configuration/config-model/model-name.tsx +++ b/web/app/components/app/configuration/config-model/model-name.tsx @@ -18,7 +18,7 @@ const ModelName: FC = ({ modelDisplayName, }) => { return ( - + {modelDisplayName} ) diff --git a/web/app/components/app/configuration/config-model/param-item.tsx b/web/app/components/app/configuration/config-model/param-item.tsx index c94244bbde..9f2863b232 100644 --- a/web/app/components/app/configuration/config-model/param-item.tsx +++ b/web/app/components/app/configuration/config-model/param-item.tsx @@ -49,7 +49,7 @@ const ParamItem: FC = ({ id, name, tip, step = 0.1, min = 0, max onChange(id, getFitPrecisionValue(value, precision)) }, [value, precision]) return ( -
          +
          {name} diff --git a/web/app/components/app/configuration/config-var/index.tsx b/web/app/components/app/configuration/config-var/index.tsx index 31594e5616..8ac94d626e 100644 --- a/web/app/components/app/configuration/config-var/index.tsx +++ b/web/app/components/app/configuration/config-var/index.tsx @@ -185,8 +185,8 @@ const ConfigVar: FC = ({ promptVariables, readonly, onPromptVar
          {t('appDebug.notSetVar')}
          )} {hasVar && ( -
          - +
          +
          diff --git a/web/app/components/app/configuration/config-vision/param-config.tsx b/web/app/components/app/configuration/config-vision/param-config.tsx index eec816d7ed..f12565abfe 100644 --- a/web/app/components/app/configuration/config-vision/param-config.tsx +++ b/web/app/components/app/configuration/config-vision/param-config.tsx @@ -31,7 +31,7 @@ const ParamsConfig: FC = () => { -
          +
          diff --git a/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx b/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx index 32c3910295..c1aa603f0b 100644 --- a/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx +++ b/web/app/components/app/configuration/config/automatic/get-automatic-res.tsx @@ -16,6 +16,7 @@ import Loading from '@/app/components/base/loading' import Confirm from '@/app/components/base/confirm' // type import type { AutomaticRes } from '@/service/debug' +import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' const noDataIcon = ( @@ -47,6 +48,9 @@ const GetAutomaticRes: FC = ({ }) => { const { t } = useTranslation() + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const [audiences, setAudiences] = React.useState('') const [hopingToSolve, setHopingToSolve] = React.useState('') const isValid = () => { @@ -103,15 +107,36 @@ const GetAutomaticRes: FC = ({ const [showConfirmOverwrite, setShowConfirmOverwrite] = React.useState(false) + const isShowAutoPromptInput = () => { + if (isMobile) { + // hide prompt panel on mobile if it is loading or has had result + if (isLoading || res) + return false + return true + } + + // alway display prompt panel on desktop mode + return true + } + + const isShowAutoPromptResPlaceholder = () => { + if (isMobile) { + // hide placeholder panel on mobile + return false + } + + return !isLoading && !res + } + return ( -
          -
          +
          + {isShowAutoPromptInput() &&
          {t('appDebug.automatic.title')}
          {t('appDebug.automatic.description')}
          @@ -139,7 +164,7 @@ const GetAutomaticRes: FC = ({
          -
          +
          } {(!isLoading && res) && (
          @@ -180,7 +205,7 @@ const GetAutomaticRes: FC = ({
          )} {isLoading && renderLoading} - {(!isLoading && !res) && renderNoData} + {isShowAutoPromptResPlaceholder() && renderNoData} {showConfirmOverwrite && ( = ({ onRemove, }) => { const { t } = useTranslation() + + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const [showSettingsModal, setShowSettingsModal] = useState(false) const handleSave = (newDataset: DataSet) => { @@ -74,15 +80,13 @@ const Item: FC = ({
          - { - showSettingsModal && ( - setShowSettingsModal(false)} - onSave={handleSave} - /> - ) - } + setShowSettingsModal(false)} footer={null} mask={isMobile} panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'> + setShowSettingsModal(false)} + onSave={handleSave} + /> + ) } diff --git a/web/app/components/app/configuration/dataset-config/params-config/index.tsx b/web/app/components/app/configuration/dataset-config/params-config/index.tsx index d166a5b457..f9954c2e67 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/index.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/index.tsx @@ -137,7 +137,7 @@ const ParamsConfig: FC = () => { onClose={() => { setOpen(false) }} - className='min-w-[528px]' + className='sm:min-w-[528px]' wrapperClassName='z-50' title={t('appDebug.datasetConfig.settingTitle')} > diff --git a/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx b/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx index 8019011f7e..1c6d25c4a7 100644 --- a/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx +++ b/web/app/components/app/configuration/dataset-config/settings-modal/index.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react' import { useRef, useState } from 'react' -import { useClickAway } from 'ahooks' import { useTranslation } from 'react-i18next' import { isEqual } from 'lodash-es' import cn from 'classnames' @@ -30,7 +29,7 @@ type SettingsModalProps = { } const rowClass = ` - flex justify-between py-4 + flex justify-between py-4 flex-wrap gap-y-2 ` const labelClass = ` @@ -45,10 +44,6 @@ const SettingsModal: FC = ({ const { t } = useTranslation() const { notify } = useToastContext() const ref = useRef(null) - useClickAway(() => { - if (ref) - onCancel() - }, ref) const { setShowAccountSettingModal } = useModalContext() const [loading, setLoading] = useState(false) @@ -122,10 +117,8 @@ const SettingsModal: FC = ({ return (
          = ({
          {t('datasetSettings.form.permissions')}
          -
          +
          handleValueChange('permission', v!)} - itemClassName='!w-[227px]' + itemClassName='sm:!w-[227px]' />
          @@ -198,7 +191,7 @@ const SettingsModal: FC = ({ disable={!localeCurrentDataset?.embedding_available} value={indexMethod} onChange={v => setIndexMethod(v!)} - itemClassName='!w-[227px]' + itemClassName='sm:!w-[227px]' />
          @@ -272,7 +265,7 @@ const SettingsModal: FC = ({ )}
          { const [conversationId, setConversationId] = useState('') + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const [isShowDebugPanel, { setTrue: showDebugPanel, setFalse: hideDebugPanel }] = useBoolean(false) + const [introduction, setIntroduction] = useState('') const [controlClearChatMessage, setControlClearChatMessage] = useState(0) const [prevPromptConfig, setPrevPromptConfig] = useState({ @@ -600,7 +607,7 @@ const Configuration: FC = () => { > <>
          -
          +
          @@ -630,7 +637,7 @@ const Configuration: FC = () => {
          -
          +
          {/* Model and Parameters */} { }} disabled={!hasSetAPIKEY} /> -
          +
          + {isMobile && ( + + )}
          -
          +
          -
          + {!isMobile &&
          setShowAccountSettingModal({ payload: 'provider' })} inputs={inputs} /> -
          +
          }
          {showConfirm && ( @@ -707,6 +720,15 @@ const Configuration: FC = () => { }} /> )} + {isMobile && ( + + setShowAccountSettingModal({ payload: 'provider' })} + inputs={inputs} + /> + + )} ) diff --git a/web/app/components/app/log/filter.tsx b/web/app/components/app/log/filter.tsx index 45c70b5c4d..10439d0681 100644 --- a/web/app/components/app/log/filter.tsx +++ b/web/app/components/app/log/filter.tsx @@ -39,7 +39,7 @@ const Filter: FC = ({ appId, queryParams, setQueryParams }: IFilte if (!data) return null return ( -
          +
          ({ value: item.value, name: t(`appLog.filter.period.${item.name}`) }))} className='mt-0 !w-40' @@ -47,7 +47,7 @@ const Filter: FC = ({ appId, queryParams, setQueryParams }: IFilte setQueryParams({ ...queryParams, period: item.value }) }} defaultValue={queryParams.period} /> -
          +
          {isChatMode ? t('appLog.detail.conversationId') : t('appLog.detail.time')}
          {isChatMode ? detail.id?.split('-').slice(-1)[0] : dayjs.unix(detail.created_at).format(t('appLog.dateTimeFormat') as string)}
          -
          +
          @@ -412,6 +413,10 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string } */ const ConversationList: FC = ({ logs, appDetail, onRefresh }) => { const { t } = useTranslation() + + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const [showDrawer, setShowDrawer] = useState(false) // Whether to display the chat details drawer const [currentConversation, setCurrentConversation] = useState() // Currently selected conversation const isChatMode = appDetail?.mode === 'chat' // Whether the app is a chat app @@ -445,17 +450,17 @@ const ConversationList: FC = ({ logs, appDetail, onRefresh }) return return ( - <> -
          {t('appDebug.variableTable.key')}
          - +
          +
          + - - - - - - - + + + + + + + @@ -504,9 +509,9 @@ const ConversationList: FC = ({ logs, appDetail, onRefresh }) = ({ logs, appDetail, onRefresh }) } - + ) } diff --git a/web/app/components/app/overview/appCard.tsx b/web/app/components/app/overview/appCard.tsx index 2c6d2d7733..28c16e1bef 100644 --- a/web/app/components/app/overview/appCard.tsx +++ b/web/app/components/app/overview/appCard.tsx @@ -129,7 +129,7 @@ function AppCard({ return (
          @@ -163,8 +163,8 @@ function AppCard({ : t('appOverview.overview.apiInfo.accessibleAddress')}
          -
          -
          +
          +
          {isApp ? appUrl : apiUrl}
          @@ -196,7 +196,7 @@ function AppCard({
          -
          +
          {!isApp && } {OPERATIONS_MAP[cardType].map((op) => { const disabled diff --git a/web/app/components/app/overview/customize/index.tsx b/web/app/components/app/overview/customize/index.tsx index 7ed9ce942a..9feb3a35d7 100644 --- a/web/app/components/app/overview/customize/index.tsx +++ b/web/app/components/app/overview/customize/index.tsx @@ -81,10 +81,10 @@ const CustomizeModal: FC = ({
          3 -
          +
          {t(`${prefixCustomize}.way1.step3`)}
          {t(`${prefixCustomize}.way1.step3Tip`)}
          -
          +          
                       NEXT_PUBLIC_APP_ID={`'${appId}'`} 
          NEXT_PUBLIC_APP_KEY={'\'\''}
          NEXT_PUBLIC_API_URL={`'${api_base_url}'`} diff --git a/web/app/components/app/overview/embedded/index.tsx b/web/app/components/app/overview/embedded/index.tsx index c326854f08..f53e6efee3 100644 --- a/web/app/components/app/overview/embedded/index.tsx +++ b/web/app/components/app/overview/embedded/index.tsx @@ -106,7 +106,7 @@ const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
          {t(`${prefixEmbedded}.explanation`)}
          -
          +
          {Object.keys(OPTION_MAP).map((v, index) => { return (
          {
          -
          +
          {OPTION_MAP[option].getContent(appBaseUrl, accessToken, isTestEnv)}
          diff --git a/web/app/components/base/drawer/index.tsx b/web/app/components/base/drawer/index.tsx index 7518b4d4f0..1911350831 100644 --- a/web/app/components/base/drawer/index.tsx +++ b/web/app/components/base/drawer/index.tsx @@ -1,9 +1,10 @@ 'use client' import { Dialog } from '@headlessui/react' import { useTranslation } from 'react-i18next' +import { XMarkIcon } from '@heroicons/react/24/outline' import Button from '../button' -type DrawerProps = { +export type IDrawerProps = { title?: string description?: string panelClassname?: string @@ -12,6 +13,7 @@ type DrawerProps = { mask?: boolean isOpen: boolean // closable: boolean + showClose?: boolean onClose: () => void onCancel?: () => void onOk?: () => void @@ -24,11 +26,12 @@ export default function Drawer({ children, footer, mask = true, + showClose = false, isOpen, onClose, onCancel, onOk, -}: DrawerProps) { +}: IDrawerProps) { const { t } = useTranslation() return ( {title} } + {showClose && + + } {description && {description}} {children} diff --git a/web/app/components/base/float-popover-container/index.tsx b/web/app/components/base/float-popover-container/index.tsx new file mode 100644 index 0000000000..be5db82420 --- /dev/null +++ b/web/app/components/base/float-popover-container/index.tsx @@ -0,0 +1,37 @@ +'use client' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import type { PortalToFollowElemOptions } from '@/app/components/base/portal-to-follow-elem' + +type IFloatRightContainerProps = { + isMobile: boolean + open: boolean + toggle: () => void + triggerElement?: React.ReactNode + children?: React.ReactNode +} & PortalToFollowElemOptions + +const FloatRightContainer = ({ open, toggle, triggerElement, isMobile, children, ...portalProps }: IFloatRightContainerProps) => { + return ( + <> + {isMobile && ( + + + {triggerElement} + + + {children} + + + )} + {!isMobile && open && ( + <>{children} + )} + + ) +} + +export default FloatRightContainer diff --git a/web/app/components/base/float-right-container/index.tsx b/web/app/components/base/float-right-container/index.tsx new file mode 100644 index 0000000000..4148c70a01 --- /dev/null +++ b/web/app/components/base/float-right-container/index.tsx @@ -0,0 +1,23 @@ +'use client' +import Drawer from '@/app/components/base/drawer' +import type { IDrawerProps } from '@/app/components/base/drawer' + +type IFloatRightContainerProps = { + isMobile: boolean + children?: React.ReactNode +} & IDrawerProps + +const FloatRightContainer = ({ isMobile, children, isOpen, ...drawerProps }: IFloatRightContainerProps) => { + return ( + <> + {isMobile && ( + {children} + )} + {(!isMobile && isOpen) && ( + <>{children} + )} + + ) +} + +export default FloatRightContainer diff --git a/web/app/components/base/popover/style.module.css b/web/app/components/base/popover/style.module.css index cea72901f3..2809386a3e 100644 --- a/web/app/components/base/popover/style.module.css +++ b/web/app/components/base/popover/style.module.css @@ -5,5 +5,5 @@ @apply absolute z-10 w-full max-w-sm px-4 mt-1 sm:px-0 lg:max-w-3xl } .panelContainer { - @apply overflow-hidden bg-white w-full rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 + @apply overflow-hidden bg-white w-fit min-w-[130px] rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 } diff --git a/web/app/components/base/portal-to-follow-elem/index.tsx b/web/app/components/base/portal-to-follow-elem/index.tsx index c1174413b9..2100f2601d 100644 --- a/web/app/components/base/portal-to-follow-elem/index.tsx +++ b/web/app/components/base/portal-to-follow-elem/index.tsx @@ -17,7 +17,7 @@ import { import type { OffsetOptions, Placement } from '@floating-ui/react' -type PortalToFollowElemOptions = { +export type PortalToFollowElemOptions = { /* * top, bottom, left, right * start, end. Default is middle diff --git a/web/app/components/base/select/index.tsx b/web/app/components/base/select/index.tsx index c4063c77f5..44bdc7c15f 100644 --- a/web/app/components/base/select/index.tsx +++ b/web/app/components/base/select/index.tsx @@ -148,7 +148,7 @@ const Select: FC = ({ const SimpleSelect: FC = ({ className, - wrapperClassName, + wrapperClassName = '', items = defaultItems, defaultValue = 1, disabled = false, diff --git a/web/app/components/datasets/create/file-uploader/index.module.css b/web/app/components/datasets/create/file-uploader/index.module.css index bfb9919477..1ba282513c 100644 --- a/web/app/components/datasets/create/file-uploader/index.module.css +++ b/web/app/components/datasets/create/file-uploader/index.module.css @@ -15,10 +15,10 @@ color: #667085; } .uploader { - @apply relative box-border flex justify-center items-center mb-2; + @apply relative box-border flex justify-center items-center mb-2 p-3; flex-direction: column; max-width: 640px; - height: 80px; + min-height: 80px; background: #F9FAFB; border: 1px dashed #EAECF0; border-radius: 12px; diff --git a/web/app/components/datasets/create/file-uploader/index.tsx b/web/app/components/datasets/create/file-uploader/index.tsx index e431251049..40bb4a6d2b 100644 --- a/web/app/components/datasets/create/file-uploader/index.tsx +++ b/web/app/components/datasets/create/file-uploader/index.tsx @@ -234,10 +234,12 @@ const FileUploader = ({ />
          {t('datasetCreation.stepOne.uploader.title')}
          -
          +
          - {t('datasetCreation.stepOne.uploader.button')} - + + {t('datasetCreation.stepOne.uploader.button')} + +
          {t('datasetCreation.stepOne.uploader.tip', { size: fileUploadConfig.file_size_limit })}
          {dragging &&
          } diff --git a/web/app/components/datasets/create/index.tsx b/web/app/components/datasets/create/index.tsx index e9c4026468..f96dac6762 100644 --- a/web/app/components/datasets/create/index.tsx +++ b/web/app/components/datasets/create/index.tsx @@ -103,7 +103,7 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => { return (
          -
          +
          diff --git a/web/app/components/datasets/create/step-one/index.module.css b/web/app/components/datasets/create/step-one/index.module.css index 3e2035f4d4..4e3cf67cd6 100644 --- a/web/app/components/datasets/create/step-one/index.module.css +++ b/web/app/components/datasets/create/step-one/index.module.css @@ -15,9 +15,6 @@ background-color: #fff; } -.dataSourceTypeList { - @apply flex items-center mb-8; -} .dataSourceItem { @apply box-border relative shrink-0 flex items-center mr-3 p-3 h-14 bg-white rounded-xl cursor-pointer; border: 0.5px solid #EAECF0; diff --git a/web/app/components/datasets/create/step-one/index.tsx b/web/app/components/datasets/create/step-one/index.tsx index 450f09b405..43e251ead9 100644 --- a/web/app/components/datasets/create/step-one/index.tsx +++ b/web/app/components/datasets/create/step-one/index.tsx @@ -106,7 +106,7 @@ const StepOne = ({
          { shouldShowDataSourceTypeList && ( -
          +
          { const { t } = useTranslation() + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + return (
          -
          +
          {!datasetId && ( <> @@ -46,13 +50,13 @@ const StepThree = ({ datasetId, datasetName, indexingType, creationCache }: Step />
          -
          + {!isMobile &&
          {t('datasetCreation.stepThree.sideTipTitle')}
          {t('datasetCreation.stepThree.sideTipContent')}
          -
          +
          }
          ) } diff --git a/web/app/components/datasets/create/step-two/index.module.css b/web/app/components/datasets/create/step-two/index.module.css index ce644992eb..622ca1e73a 100644 --- a/web/app/components/datasets/create/step-two/index.module.css +++ b/web/app/components/datasets/create/step-two/index.module.css @@ -1,5 +1,5 @@ .pageHeader { - @apply px-16; + @apply px-16 flex justify-between items-center; position: sticky; top: 0; left: 0; @@ -251,7 +251,7 @@ } .ruleItem { - @apply flex items-center h-7; + @apply flex items-center; } .formFooter { @@ -382,7 +382,7 @@ .previewWrap { flex-shrink: 0; - width: 524px; + max-width: 524px; } .previewHeader { diff --git a/web/app/components/datasets/create/step-two/index.tsx b/web/app/components/datasets/create/step-two/index.tsx index 639d8631dc..308d0972bf 100644 --- a/web/app/components/datasets/create/step-two/index.tsx +++ b/web/app/components/datasets/create/step-two/index.tsx @@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import { useBoolean } from 'ahooks' import { XMarkIcon } from '@heroicons/react/20/solid' +import { RocketLaunchIcon } from '@heroicons/react/24/outline' import cn from 'classnames' import Link from 'next/link' import { groupBy } from 'lodash-es' @@ -20,6 +21,7 @@ import { } from '@/service/datasets' import Button from '@/app/components/base/button' import Loading from '@/app/components/base/loading' +import FloatRightContainer from '@/app/components/base/float-right-container' import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-method-config' import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config' import { type RetrievalConfig } from '@/types/app' @@ -37,6 +39,8 @@ import I18n from '@/context/i18n' import { IS_CE_EDITION } from '@/config' import { RETRIEVE_METHOD } from '@/types/app' import { useProviderContext } from '@/context/provider-context' +import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' +import Tooltip from '@/app/components/base/tooltip' type ValueOf = T[keyof T] type StepTwoProps = { @@ -84,6 +88,9 @@ const StepTwo = ({ const { t } = useTranslation() const { locale } = useContext(I18n) + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const { dataset: currentDataset, mutateDatasetRes } = useDatasetDetailContext() const scrollRef = useRef(null) const [scrolled, setScrolled] = useState(false) @@ -467,7 +474,7 @@ const StepTwo = ({ useEffect(() => { if (segmentationType === SegmentType.AUTO) { setAutomaticFileIndexingEstimate(null) - setShowPreview() + !isMobile && setShowPreview() fetchFileIndexingEstimate() setPreviewSwitched(false) } @@ -493,8 +500,23 @@ const StepTwo = ({ return (
          -
          {t('datasetCreation.steps.two')}
          -
          +
          + {t('datasetCreation.steps.two')} + {isMobile && ( + + )} +
          +
          {t('datasetCreation.stepTwo.segmentation')}
          -
          +
          {t('datasetCreation.stepTwo.rules')}
          {rules.map(rule => (
          @@ -574,7 +596,7 @@ const StepTwo = ({
          {t('datasetCreation.stepTwo.indexMode')}
          -
          +
          {(!hasSetIndexType || (hasSetIndexType && indexingType === IndexingType.QUALIFIED)) && (
          - {(showPreview) - ? ( -
          -
          -
          -
          -
          {t('datasetCreation.stepTwo.previewTitle')}
          - {docForm === DocForm.QA && !previewSwitched && ( - - )} -
          -
          - -
          + + {showPreview &&
          +
          +
          +
          +
          {t('datasetCreation.stepTwo.previewTitle')}
          + {docForm === DocForm.QA && !previewSwitched && ( + + )} +
          +
          +
          - {docForm === DocForm.QA && !previewSwitched && ( -
          - {t('datasetCreation.stepTwo.previewSwitchTipStart')} - {t('datasetCreation.stepTwo.previewSwitchTipEnd')} -
          - )}
          -
          - {previewSwitched && docForm === DocForm.QA && fileIndexingEstimate?.qa_preview && ( - <> - {fileIndexingEstimate?.qa_preview.map((item, index) => ( - - ))} - - )} - {(docForm === DocForm.TEXT || !previewSwitched) && fileIndexingEstimate?.preview && ( - <> - {fileIndexingEstimate?.preview.map((item, index) => ( - - ))} - - )} - {previewSwitched && docForm === DocForm.QA && !fileIndexingEstimate?.qa_preview && ( -
          - -
          - )} - {!previewSwitched && !fileIndexingEstimate?.preview && ( -
          - -
          - )} + {docForm === DocForm.QA && !previewSwitched && ( +
          + {t('datasetCreation.stepTwo.previewSwitchTipStart')} + {t('datasetCreation.stepTwo.previewSwitchTipEnd')} +
          + )} +
          +
          + {previewSwitched && docForm === DocForm.QA && fileIndexingEstimate?.qa_preview && ( + <> + {fileIndexingEstimate?.qa_preview.map((item, index) => ( + + ))} + + )} + {(docForm === DocForm.TEXT || !previewSwitched) && fileIndexingEstimate?.preview && ( + <> + {fileIndexingEstimate?.preview.map((item, index) => ( + + ))} + + )} + {previewSwitched && docForm === DocForm.QA && !fileIndexingEstimate?.qa_preview && ( +
          + +
          + )} + {!previewSwitched && !fileIndexingEstimate?.preview && ( +
          + +
          + )} +
          +
          } + {!showPreview && ( +
          +
          + +
          {t('datasetCreation.stepTwo.sideTipTitle')}
          +
          +

          {t('datasetCreation.stepTwo.sideTipP1')}

          +

          {t('datasetCreation.stepTwo.sideTipP2')}

          +

          {t('datasetCreation.stepTwo.sideTipP3')}

          +

          {t('datasetCreation.stepTwo.sideTipP4')}

          +
          - ) - : (
          -
          - -
          {t('datasetCreation.stepTwo.sideTipTitle')}
          -
          -

          {t('datasetCreation.stepTwo.sideTipP1')}

          -

          {t('datasetCreation.stepTwo.sideTipP2')}

          -

          {t('datasetCreation.stepTwo.sideTipP3')}

          -

          {t('datasetCreation.stepTwo.sideTipP4')}

          -
          -
          -
          )} + )} +
          ) } diff --git a/web/app/components/datasets/create/steps-nav-bar/index.module.css b/web/app/components/datasets/create/steps-nav-bar/index.module.css index b1d15988ab..965b1511fc 100644 --- a/web/app/components/datasets/create/steps-nav-bar/index.module.css +++ b/web/app/components/datasets/create/steps-nav-bar/index.module.css @@ -14,14 +14,15 @@ background-size: 16px; } .stepList { - @apply p-4; + @apply p-4 relative; line-height: 18px; } .stepItem { - @apply relative flex justify-items-start pt-3 pr-0 pb-3; + @apply relative flex justify-items-start pt-3 pr-0 pb-3 box-content; padding-left: 52px; font-size: 13px; + height: 18px; } .stepItem.step1::before { diff --git a/web/app/components/datasets/create/steps-nav-bar/index.tsx b/web/app/components/datasets/create/steps-nav-bar/index.tsx index 53b81b033c..340d2c9603 100644 --- a/web/app/components/datasets/create/steps-nav-bar/index.tsx +++ b/web/app/components/datasets/create/steps-nav-bar/index.tsx @@ -3,46 +3,56 @@ import { useTranslation } from 'react-i18next' import { useRouter } from 'next/navigation' import cn from 'classnames' +import { useCallback } from 'react' import s from './index.module.css' +import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' type IStepsNavBarProps = { - step: number, - datasetId?: string, + step: number + datasetId?: string } +const STEP_T_MAP: Record = { + 1: 'datasetCreation.steps.one', + 2: 'datasetCreation.steps.two', + 3: 'datasetCreation.steps.three', +} + +const STEP_LIST = [1, 2, 3] + const StepsNavBar = ({ step, datasetId, }: IStepsNavBarProps) => { const { t } = useTranslation() const router = useRouter() - const navBackHandle = () => { - if (!datasetId) { + + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + + const navBackHandle = useCallback(() => { + if (!datasetId) router.replace('/datasets') - } else { + else router.replace(`/datasets/${datasetId}/documents`) - } - } + }, [router, datasetId]) return (
          -
          -
          - {!datasetId ? t('datasetCreation.steps.header.creation') : t('datasetCreation.steps.header.update')} +
          +
          + {!isMobile && (!datasetId ? t('datasetCreation.steps.header.creation') : t('datasetCreation.steps.header.update'))}
          -
          -
          -
          {step === 1 ? 1 : ''}
          -
          {t('datasetCreation.steps.one')}
          -
          -
          -
          {step !== 3 ? 2 : ''}
          -
          {t('datasetCreation.steps.two')}
          -
          -
          -
          3
          -
          {t('datasetCreation.steps.three')}
          -
          +
          + {STEP_LIST.map(item => ( +
          item && s.done, isMobile && 'px-0')} + > +
          {item}
          +
          {isMobile ? '' : t(STEP_T_MAP[item])}
          +
          + ))}
          ) diff --git a/web/app/components/datasets/documents/detail/completed/index.tsx b/web/app/components/datasets/documents/detail/completed/index.tsx index f4bde5c32e..8b10a9315c 100644 --- a/web/app/components/datasets/documents/detail/completed/index.tsx +++ b/web/app/components/datasets/documents/detail/completed/index.tsx @@ -178,7 +178,7 @@ const SegmentDetailComponent: FC = ({ }
          -
          +
          {formatNumber(segInfo?.word_count as number)} {t('datasetDocuments.segment.characters')}
          {formatNumber(segInfo?.hit_count as number)} {t('datasetDocuments.segment.hitCount')}
          {t('datasetDocuments.segment.vectorHash')}{segInfo?.index_node_hash} diff --git a/web/app/components/datasets/documents/detail/completed/style.module.css b/web/app/components/datasets/documents/detail/completed/style.module.css index 0a8790ad0f..7633d53209 100644 --- a/web/app/components/datasets/documents/detail/completed/style.module.css +++ b/web/app/components/datasets/documents/detail/completed/style.module.css @@ -8,7 +8,7 @@ @apply text-gray-900 font-medium text-base flex-1; } .docSearchWrapper { - @apply sticky w-full h-10 -top-3 bg-white flex items-center mb-3 justify-between z-10; + @apply sticky w-full py-1 -top-3 bg-white flex items-center mb-3 justify-between z-10 flex-wrap gap-y-1; } .listContainer { height: calc(100% - 3.25rem); @@ -18,7 +18,7 @@ @apply grid gap-4 grid-cols-3 min-w-[902px] last:mb-[30px]; } .segWrapper { - @apply box-border h-[180px] min-w-[290px] bg-gray-50 px-4 pt-4 flex flex-col text-opacity-50 rounded-xl border border-transparent hover:border-gray-200 hover:shadow-lg hover:cursor-pointer hover:bg-white; + @apply box-border h-[180px] w-full xl:min-w-[290px] bg-gray-50 px-4 pt-4 flex flex-col text-opacity-50 rounded-xl border border-transparent hover:border-gray-200 hover:shadow-lg hover:cursor-pointer hover:bg-white; } .segTitleWrapper { @apply flex items-center justify-between; @@ -48,7 +48,7 @@ white-space: pre-line; } .footer { - @apply flex items-center justify-between box-border border-t-gray-200 border-t-[0.5px] pt-3 mt-4; + @apply flex items-center justify-between box-border border-t-gray-200 border-t-[0.5px] pt-3 mt-4 flex-wrap gap-y-2; } .numberInfo { @apply text-gray-500 text-xs font-medium; diff --git a/web/app/components/datasets/documents/detail/index.tsx b/web/app/components/datasets/documents/detail/index.tsx index 1240ef0829..cda6e98a26 100644 --- a/web/app/components/datasets/documents/detail/index.tsx +++ b/web/app/components/datasets/documents/detail/index.tsx @@ -23,6 +23,8 @@ import { checkSegmentBatchImportProgress, fetchDocumentDetail, segmentBatchImpor import { ToastContext } from '@/app/components/base/toast' import type { DocForm } from '@/models/datasets' import { useDatasetDetailContext } from '@/context/dataset-detail' +import FloatRightContainer from '@/app/components/base/float-right-container' +import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' export const DocumentContext = createContext<{ datasetId?: string; documentId?: string; docForm: string }>({ docForm: '' }) @@ -50,10 +52,14 @@ type Props = { const DocumentDetail: FC = ({ datasetId, documentId }) => { const router = useRouter() const { t } = useTranslation() + + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const { notify } = useContext(ToastContext) const { dataset } = useDatasetDetailContext() const embeddingAvailable = !!dataset?.embedding_available - const [showMetadata, setShowMetadata] = useState(true) + const [showMetadata, setShowMetadata] = useState(!isMobile) const [newSegmentModalVisible, setNewSegmentModalVisible] = useState(false) const [batchModalVisible, setBatchModalVisible] = useState(false) const [importStatus, setImportStatus] = useState() @@ -124,44 +130,46 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { return (
          -
          -
          +
          +
          - - {embeddingAvailable && documentDetail && !documentDetail.archived && ( - + + {embeddingAvailable && documentDetail && !documentDetail.archived && ( + + )} + - )} - -
          {isDetailLoading ? - :
          + :
          {embedding ? : = ({ datasetId, documentId }) => { }
          } - {showMetadata && } + setShowMetadata(false)} isMobile={isMobile} panelClassname='!justify-start' footer={null}> + +
          = ({ datasetId }) => {

          {t('datasetDocuments.list.desc')}

          -
          +
          = ({ datasetId }) => { value={searchValue} /> {embeddingAvailable && ( -
          {t('appLog.table.header.time')}{t('appLog.table.header.endUser')}{isChatMode ? t('appLog.table.header.summary') : t('appLog.table.header.input')}{isChatMode ? t('appLog.table.header.messageCount') : t('appLog.table.header.output')}{t('appLog.table.header.userRate')}{t('appLog.table.header.adminRate')}{t('appLog.table.header.time')}{t('appLog.table.header.endUser')}{isChatMode ? t('appLog.table.header.summary') : t('appLog.table.header.input')}{isChatMode ? t('appLog.table.header.messageCount') : t('appLog.table.header.output')}{t('appLog.table.header.userRate')}{t('appLog.table.header.adminRate')}
          +
          +
          @@ -380,7 +380,7 @@ const DocumentList: FC = ({ embeddingAvailable, documents = })}
          #
          - +
          ) } diff --git a/web/app/components/datasets/hit-testing/hit-detail.tsx b/web/app/components/datasets/hit-testing/hit-detail.tsx index 1dfffa5866..806662aeb5 100644 --- a/web/app/components/datasets/hit-testing/hit-detail.tsx +++ b/web/app/components/datasets/hit-testing/hit-detail.tsx @@ -65,8 +65,8 @@ const HitDetail: FC = ({ segInfo, vectorInfo }) => { } return ( -
          -
          +
          +
          { const HitTesting: FC = ({ datasetId }: Props) => { const { t } = useTranslation() + + const media = useBreakpoints() + const isMobile = media === MediaType.mobile + const [hitResult, setHitResult] = useState() // 初始化记录为空数组 const [submitLoading, setSubmitLoading] = useState(false) const [currParagraph, setCurrParagraph] = useState<{ paraInfo?: HitTestingType; showModal: boolean }>({ showModal: false }) @@ -63,6 +70,11 @@ const HitTesting: FC = ({ datasetId }: Props) => { const [retrievalConfig, setRetrievalConfig] = useState(currentDataset?.retrieval_model_dict as RetrievalConfig) const [isShowModifyRetrievalModal, setIsShowModifyRetrievalModal] = useState(false) + const [isShowRightPanel, { setTrue: showRightPanel, setFalse: hideRightPanel, set: setShowRightPanel }] = useBoolean(!isMobile) + + useEffect(() => { + setShowRightPanel(!isMobile) + }, [isMobile, setShowRightPanel]) return (
          @@ -74,6 +86,7 @@ const HitTesting: FC = ({ datasetId }: Props) => {