Browse Source

chore: perfect type definition (#1003)

bowen 1 year ago
parent
commit
f9bec1edf8
35 changed files with 122 additions and 104 deletions
  1. 4 3
      web/app/(commonLayout)/apps/AppCard.tsx
  2. 4 4
      web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx
  3. 5 4
      web/app/components/app-sidebar/index.tsx
  4. 18 5
      web/app/components/app-sidebar/navLink.tsx
  5. 4 4
      web/app/components/app/chat/icon-component/index.tsx
  6. 4 3
      web/app/components/app/configuration/config-var/index.tsx
  7. 1 1
      web/app/components/app/configuration/config-var/input-type-icon.tsx
  8. 2 2
      web/app/components/app/log/index.tsx
  9. 2 2
      web/app/components/app/log/list.tsx
  10. 2 2
      web/app/components/app/overview/appCard.tsx
  11. 8 7
      web/app/components/base/emoji-picker/index.tsx
  12. 5 5
      web/app/components/base/input/index.tsx
  13. 1 1
      web/app/components/base/notion-icon/index.tsx
  14. 3 4
      web/app/components/base/notion-page-selector/base.tsx
  15. 1 1
      web/app/components/base/radio/component/radio/index.tsx
  16. 6 5
      web/app/components/datasets/create/embedding-process/index.tsx
  17. 1 1
      web/app/components/datasets/create/file-uploader/index.tsx
  18. 3 5
      web/app/components/datasets/create/index.tsx
  19. 2 3
      web/app/components/datasets/create/notion-page-preview/index.tsx
  20. 3 5
      web/app/components/datasets/create/step-one/index.tsx
  21. 6 8
      web/app/components/datasets/create/step-two/index.tsx
  22. 1 1
      web/app/components/datasets/documents/detail/completed/InfiniteVirtualList.tsx
  23. 1 1
      web/app/components/datasets/documents/detail/completed/SegmentCard.tsx
  24. 2 2
      web/app/components/datasets/documents/detail/completed/index.tsx
  25. 3 3
      web/app/components/datasets/documents/detail/embedding/index.tsx
  26. 5 5
      web/app/components/datasets/documents/index.tsx
  27. 5 5
      web/app/components/datasets/documents/list.tsx
  28. 1 1
      web/app/components/datasets/hit-testing/hit-detail.tsx
  29. 4 3
      web/app/components/explore/app-list/index.tsx
  30. 4 3
      web/app/components/explore/category.tsx
  31. 2 2
      web/app/components/header/account-setting/index.tsx
  32. 1 1
      web/app/components/header/account-setting/model-page/model-item/Card.tsx
  33. 1 1
      web/app/components/share/text-generation/result/index.tsx
  34. 4 0
      web/models/common.ts
  35. 3 1
      web/models/explore.ts

+ 4 - 3
web/app/(commonLayout)/apps/AppCard.tsx

@@ -9,6 +9,7 @@ import style from '../list.module.css'
 import AppModeLabel from './AppModeLabel'
 import s from './style.module.css'
 import SettingsModal from '@/app/components/app/overview/settings'
+import type { ConfigParams } from '@/app/components/app/overview/settings'
 import type { App } from '@/types/app'
 import Confirm from '@/app/components/base/confirm'
 import { ToastContext } from '@/app/components/base/toast'
@@ -73,7 +74,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
   }
 
   const onSaveSiteConfig = useCallback(
-    async (params: any) => {
+    async (params: ConfigParams) => {
       const [err] = await asyncRunSafe<App>(
         updateAppSiteConfig({
           url: `/apps/${app.id}/site`,
@@ -100,12 +101,12 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
   )
 
   const Operations = (props: any) => {
-    const onClickSettings = async (e: any) => {
+    const onClickSettings = async (e: React.MouseEvent<HTMLButtonElement>) => {
       props?.onClose()
       e.preventDefault()
       await getAppDetail()
     }
-    const onClickDelete = async (e: any) => {
+    const onClickDelete = async (e: React.MouseEvent<HTMLDivElement>) => {
       props?.onClose()
       e.preventDefault()
       setShowConfirmDelete(true)

File diff suppressed because it is too large
+ 4 - 4
web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx


+ 5 - 4
web/app/components/app-sidebar/index.tsx

@@ -1,8 +1,9 @@
 import React from 'react'
-import type { FC } from 'react'
 import NavLink from './navLink'
 import AppBasic from './basic'
 
+import type { NavIcon } from './navLink'
+
 export type IAppDetailNavProps = {
   iconType?: 'app' | 'dataset' | 'notion'
   title: string
@@ -12,13 +13,13 @@ export type IAppDetailNavProps = {
   navigation: Array<{
     name: string
     href: string
-    icon: any
-    selectedIcon: any
+    icon: NavIcon
+    selectedIcon: NavIcon
   }>
   extraInfo?: React.ReactNode
 }
 
-const AppDetailNav: FC<IAppDetailNavProps> = ({ title, desc, icon, icon_background, navigation, extraInfo, iconType = 'app' }) => {
+const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInfo, iconType = 'app' }: IAppDetailNavProps) => {
   return (
     <div className="flex flex-col w-56 overflow-y-auto bg-white border-r border-gray-200 shrink-0">
       <div className="flex flex-shrink-0 p-4">

+ 18 - 5
web/app/components/app-sidebar/navLink.tsx

@@ -1,17 +1,30 @@
 'use client'
+
 import { useSelectedLayoutSegment } from 'next/navigation'
 import classNames from 'classnames'
 import Link from 'next/link'
 
+export type NavIcon = React.ComponentType<
+React.PropsWithoutRef<React.ComponentProps<'svg'>> & {
+  title?: string | undefined
+  titleId?: string | undefined
+}
+>
+
+export type NavLinkProps = {
+  name: string
+  href: string
+  iconMap: {
+    selected: NavIcon
+    normal: NavIcon
+  }
+}
+
 export default function NavLink({
   name,
   href,
   iconMap,
-}: {
-  name: string
-  href: string
-  iconMap: { selected: any; normal: any }
-}) {
+}: NavLinkProps) {
   const segment = useSelectedLayoutSegment()
   const isActive = href.toLowerCase().split('/')?.pop() === segment?.toLowerCase()
   const NavIcon = isActive ? iconMap.selected : iconMap.normal

File diff suppressed because it is too large
+ 4 - 4
web/app/components/app/chat/icon-component/index.tsx


+ 4 - 3
web/app/components/app/configuration/config-var/index.tsx

@@ -10,6 +10,7 @@ import OperationBtn from '../base/operation-btn'
 import VarIcon from '../base/icons/var-icon'
 import EditModel from './config-model'
 import IconTypeIcon from './input-type-icon'
+import type { IInputTypeIconProps } from './input-type-icon'
 import s from './style.module.css'
 import Tooltip from '@/app/components/base/tooltip'
 import type { PromptVariable } from '@/models/debug'
@@ -37,8 +38,8 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
     return obj
   })()
 
-  const updatePromptVariable = (key: string, updateKey: string, newValue: any) => {
-    const newPromptVariables = promptVariables.map((item, i) => {
+  const updatePromptVariable = (key: string, updateKey: string, newValue: string | boolean) => {
+    const newPromptVariables = promptVariables.map((item) => {
       if (item.key === key) {
         return {
           ...item,
@@ -179,7 +180,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
                 <tr key={index} className="h-9 leading-9">
                   <td className="w-[160px] border-b border-gray-100 pl-3">
                     <div className='flex items-center space-x-1'>
-                      <IconTypeIcon type={type} />
+                      <IconTypeIcon type={type as IInputTypeIconProps['type']} />
                       {!readonly
                         ? (
                           <input

+ 1 - 1
web/app/components/app/configuration/config-var/input-type-icon.tsx

@@ -2,7 +2,7 @@
 import React from 'react'
 import type { FC } from 'react'
 
-type IInputTypeIconProps = {
+export type IInputTypeIconProps = {
   type: 'string' | 'select'
 }
 

+ 2 - 2
web/app/components/app/log/index.tsx

@@ -1,5 +1,5 @@
 'use client'
-import type { FC } from 'react'
+import type { FC, SVGProps } from 'react'
 import React, { useState } from 'react'
 import useSWR from 'swr'
 import { usePathname } from 'next/navigation'
@@ -29,7 +29,7 @@ export type QueryParam = {
 // Custom page count is not currently supported.
 const limit = 10
 
-const ThreeDotsIcon: FC<{ className?: string }> = ({ className }) => {
+const ThreeDotsIcon = ({ className }: SVGProps<SVGElement>) => {
   return <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
     <path d="M5 6.5V5M8.93934 7.56066L10 6.5M10.0103 11.5H11.5103" stroke="#374151" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
   </svg>

File diff suppressed because it is too large
+ 2 - 2
web/app/components/app/log/list.tsx


+ 2 - 2
web/app/components/app/overview/appCard.tsx

@@ -1,5 +1,5 @@
 'use client'
-import type { FC } from 'react'
+import type { HTMLProps } from 'react'
 import React, { useMemo, useState } from 'react'
 import {
   Cog8ToothIcon,
@@ -37,7 +37,7 @@ export type IAppCardProps = {
   onGenerateCode?: () => Promise<void>
 }
 
-const EmbedIcon: FC<{ className?: string }> = ({ className = '' }) => {
+const EmbedIcon = ({ className = '' }: HTMLProps<HTMLDivElement>) => {
   return <div className={`${style.codeBrowserIcon} ${className}`}></div>
 }
 

+ 8 - 7
web/app/components/base/emoji-picker/index.tsx

@@ -3,6 +3,7 @@
 import type { ChangeEvent, FC } from 'react'
 import React, { useState } from 'react'
 import data from '@emoji-mart/data'
+import type { Emoji, EmojiMartData } from '@emoji-mart/data'
 import { SearchIndex, init } from 'emoji-mart'
 import cn from 'classnames'
 import {
@@ -30,9 +31,9 @@ declare global {
 init({ data })
 
 async function search(value: string) {
-  const emojis = await SearchIndex.search(value) || []
+  const emojis: Emoji[] = await SearchIndex.search(value) || []
 
-  const results = emojis.map((emoji: any) => {
+  const results = emojis.map((emoji) => {
     return emoji.skins[0].native
   })
   return results
@@ -59,6 +60,7 @@ const backgroundColors = [
   '#ECE9FE',
   '#FFE4E8',
 ]
+
 type IEmojiPickerProps = {
   isModal?: boolean
   onSelect?: (emoji: string, background: string) => void
@@ -69,14 +71,13 @@ const EmojiPicker: FC<IEmojiPickerProps> = ({
   isModal = true,
   onSelect,
   onClose,
-
 }) => {
   const { t } = useTranslation()
-  const { categories } = data as any
+  const { categories } = data as EmojiMartData
   const [selectedEmoji, setSelectedEmoji] = useState('')
   const [selectedBackground, setSelectedBackground] = useState(backgroundColors[0])
 
-  const [searchedEmojis, setSearchedEmojis] = useState([])
+  const [searchedEmojis, setSearchedEmojis] = useState<string[]>([])
   const [isSearching, setIsSearching] = useState(false)
 
   return isModal ? <Modal
@@ -133,11 +134,11 @@ const EmojiPicker: FC<IEmojiPickerProps> = ({
         </div>
       </>}
 
-      {categories.map((category: any, index: number) => {
+      {categories.map((category, index: number) => {
         return <div key={`category-${index}`} className='flex flex-col'>
           <p className='font-medium uppercase text-xs text-[#101828] mb-1'>{category.id}</p>
           <div className='w-full h-full grid grid-cols-8 gap-1'>
-            {category.emojis.map((emoji: string, index: number) => {
+            {category.emojis.map((emoji, index: number) => {
               return <div
                 key={`emoji-${index}`}
                 className='inline-flex w-10 h-10 rounded-lg items-center justify-center'

+ 5 - 5
web/app/components/base/input/index.tsx

@@ -1,5 +1,5 @@
 'use client'
-import type { FC } from 'react'
+import type { SVGProps } from 'react'
 import React, { useState } from 'react'
 import { useTranslation } from 'react-i18next'
 import s from './style.module.css'
@@ -8,7 +8,7 @@ type InputProps = {
   placeholder?: string
   value?: string
   defaultValue?: string
-  onChange?: (v: any) => void
+  onChange?: (v: string) => void
   className?: string
   wrapperClassName?: string
   type?: string
@@ -16,13 +16,13 @@ type InputProps = {
   prefixIcon?: React.ReactNode
 }
 
-const GlassIcon: FC<{ className?: string }> = ({ className }) => (
+const GlassIcon = ({ className }: SVGProps<SVGElement>) => (
   <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
     <path d="M12.25 12.25L10.2084 10.2083M11.6667 6.70833C11.6667 9.44675 9.44675 11.6667 6.70833 11.6667C3.96992 11.6667 1.75 9.44675 1.75 6.70833C1.75 3.96992 3.96992 1.75 6.70833 1.75C9.44675 1.75 11.6667 3.96992 11.6667 6.70833Z" stroke="#344054" strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round" />
   </svg>
 )
 
-const Input: FC<InputProps> = ({ value, defaultValue, onChange, className = '', wrapperClassName = '', placeholder, type, showPrefix, prefixIcon }) => {
+const Input = ({ value, defaultValue, onChange, className = '', wrapperClassName = '', placeholder, type, showPrefix, prefixIcon }: InputProps) => {
   const [localValue, setLocalValue] = useState(value ?? defaultValue)
   const { t } = useTranslation()
   return (
@@ -31,7 +31,7 @@ const Input: FC<InputProps> = ({ value, defaultValue, onChange, className = '',
       <input
         type={type ?? 'text'}
         className={`${s.input} ${showPrefix ? '!pl-7' : ''} ${className}`}
-        placeholder={placeholder ?? (showPrefix ? t('common.operation.search') : 'please input')}
+        placeholder={placeholder ?? (showPrefix ? t('common.operation.search') ?? '' : 'please input')}
         value={localValue}
         onChange={(e) => {
           setLocalValue(e.target.value)

+ 1 - 1
web/app/components/base/notion-icon/index.tsx

@@ -7,7 +7,7 @@ type NotionIconProps = {
   type?: IconTypes
   name?: string | null
   className?: string
-  src?: string | null | Pick<DataSourceNotionPage, 'page_icon'>['page_icon']
+  src?: string | null | DataSourceNotionPage['page_icon']
 }
 const NotionIcon = ({
   type = 'workspace',

+ 3 - 4
web/app/components/base/notion-page-selector/base.tsx

@@ -10,17 +10,16 @@ import PageSelector from './page-selector'
 import { preImportNotionPages } from '@/service/datasets'
 import AccountSetting from '@/app/components/header/account-setting'
 import { NotionConnector } from '@/app/components/datasets/create/step-one'
-import type { DataSourceNotionPage, DataSourceNotionPageMap, DataSourceNotionWorkspace } from '@/models/common'
+import type { DataSourceNotionPageMap, DataSourceNotionWorkspace, NotionPage } from '@/models/common'
 import { ToastContext } from '@/app/components/base/toast'
 
-export type NotionPageSelectorValue = DataSourceNotionPage & { workspace_id: string }
 
 type NotionPageSelectorProps = {
   value?: string[]
-  onSelect: (selectedPages: NotionPageSelectorValue[]) => void
+  onSelect: (selectedPages: NotionPage[]) => void
   canPreview?: boolean
   previewPageId?: string
-  onPreview?: (selectedPage: NotionPageSelectorValue) => void
+  onPreview?: (selectedPage: NotionPage) => void
   datasetId?: string
   countLimit: number
   countUsed: number

+ 1 - 1
web/app/components/base/radio/component/radio/index.tsx

@@ -12,7 +12,7 @@ export type IRadioProps = {
   checked?: boolean
   value?: string | number
   disabled?: boolean
-  onChange?: (e: any) => void
+  onChange?: (e?: IRadioProps['value']) => void
 }
 
 export default function Radio({

+ 6 - 5
web/app/components/datasets/create/embedding-process/index.tsx

@@ -87,7 +87,7 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
     setIndexingStatusDetail(status.data)
   }
 
-  const [runId, setRunId, getRunId] = useGetState<any>(null)
+  const [_, setRunId, getRunId] = useGetState<ReturnType<typeof setInterval>>()
 
   const stopQueryStatus = () => {
     clearInterval(getRunId())
@@ -136,10 +136,10 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
   }
 
   const isEmbedding = useMemo(() => {
-    return indexingStatusBatchDetail.some((indexingStatusDetail: { indexing_status: any }) => ['indexing', 'splitting', 'parsing', 'cleaning'].includes(indexingStatusDetail?.indexing_status || ''))
+    return indexingStatusBatchDetail.some(indexingStatusDetail => ['indexing', 'splitting', 'parsing', 'cleaning'].includes(indexingStatusDetail?.indexing_status || ''))
   }, [indexingStatusBatchDetail])
   const isEmbeddingCompleted = useMemo(() => {
-    return indexingStatusBatchDetail.every((indexingStatusDetail: { indexing_status: any }) => ['completed', 'error'].includes(indexingStatusDetail?.indexing_status || ''))
+    return indexingStatusBatchDetail.every(indexingStatusDetail => ['completed', 'error'].includes(indexingStatusDetail?.indexing_status || ''))
   }, [indexingStatusBatchDetail])
 
   const getSourceName = (id: string) => {
@@ -159,10 +159,11 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
     const doc = documents.find(document => document.id === id)
     return doc?.data_source_type as DataSourceType
   }
+
   const getIcon = (id: string) => {
-    const doc = documents.find(document => document.id === id) as any // TODO type fix
+    const doc = documents.find(document => document.id === id)
 
-    return doc.data_source_info.notion_page_icon
+    return doc?.data_source_info.notion_page_icon
   }
   const isSourceEmbedding = (detail: IndexingStatusResponse) => ['indexing', 'splitting', 'parsing', 'cleaning', 'waiting'].includes(detail.indexing_status || '')
 

+ 1 - 1
web/app/components/datasets/create/file-uploader/index.tsx

@@ -16,7 +16,7 @@ type IFileUploaderProps = {
   titleClassName?: string
   prepareFileList: (files: FileItem[]) => void
   onFileUpdate: (fileItem: FileItem, progress: number, list: FileItem[]) => void
-  onFileListUpdate?: (files: any) => void
+  onFileListUpdate?: (files: FileItem[]) => void
   onPreview: (file: File) => void
   countLimit: number
   countUsed: number

+ 3 - 5
web/app/components/datasets/create/index.tsx

@@ -11,13 +11,11 @@ import { DataSourceType } from '@/models/datasets'
 import type { DataSet, FileItem, createDocumentResponse } from '@/models/datasets'
 import { fetchDataSource } from '@/service/common'
 import { fetchDataDetail } from '@/service/datasets'
-import type { DataSourceNotionPage } from '@/models/common'
+import type { NotionPage } from '@/models/common'
 import { useProviderContext } from '@/context/provider-context'
 
 import AccountSetting from '@/app/components/header/account-setting'
 
-type Page = DataSourceNotionPage & { workspace_id: string }
-
 type DatasetUpdateFormProps = {
   datasetId?: string
 }
@@ -35,8 +33,8 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => {
   const [hasError, setHasError] = useState(false)
   const { embeddingsDefaultModel } = useProviderContext()
 
-  const [notionPages, setNotionPages] = useState<Page[]>([])
-  const updateNotionPages = (value: Page[]) => {
+  const [notionPages, setNotionPages] = useState<NotionPage[]>([])
+  const updateNotionPages = (value: NotionPage[]) => {
     setNotionPages(value)
   }
 

+ 2 - 3
web/app/components/datasets/create/notion-page-preview/index.tsx

@@ -4,13 +4,12 @@ import { useTranslation } from 'react-i18next'
 import cn from 'classnames'
 import { XMarkIcon } from '@heroicons/react/20/solid'
 import s from './index.module.css'
-import type { DataSourceNotionPage } from '@/models/common'
+import type { NotionPage } from '@/models/common'
 import NotionIcon from '@/app/components/base/notion-icon'
 import { fetchNotionPagePreview } from '@/service/datasets'
 
-type Page = DataSourceNotionPage & { workspace_id: string }
 type IProps = {
-  currentPage?: Page
+  currentPage?: NotionPage
   hidePreview: () => void
 }
 

+ 3 - 5
web/app/components/datasets/create/step-one/index.tsx

@@ -9,7 +9,7 @@ import NotionPagePreview from '../notion-page-preview'
 import EmptyDatasetCreationModal from '../empty-dataset-creation-modal'
 import s from './index.module.css'
 import type { FileItem } from '@/models/datasets'
-import type { DataSourceNotionPage } from '@/models/common'
+import type { NotionPage } from '@/models/common'
 import { DataSourceType } from '@/models/datasets'
 import Button from '@/app/components/base/button'
 import { NotionPageSelector } from '@/app/components/base/notion-page-selector'
@@ -25,14 +25,12 @@ type IStepOneProps = {
   files: FileItem[]
   updateFileList: (files: FileItem[]) => void
   updateFile: (fileItem: FileItem, progress: number, list: FileItem[]) => void
-  notionPages?: any[]
-  updateNotionPages: (value: any[]) => void
+  notionPages?: NotionPage[]
+  updateNotionPages: (value: NotionPage[]) => void
   onStepChange: () => void
   changeType: (type: DataSourceType) => void
 }
 
-type Page = DataSourceNotionPage & { workspace_id: string }
-
 type NotionConnectorProps = {
   onSetting: () => void
 }

+ 6 - 8
web/app/components/datasets/create/step-two/index.tsx

@@ -23,7 +23,7 @@ import Loading from '@/app/components/base/loading'
 
 import Toast from '@/app/components/base/toast'
 import { formatNumber } from '@/utils/format'
-import type { DataSourceNotionPage } from '@/models/common'
+import type { NotionPage } from '@/models/common'
 import { DataSourceType, DocForm } from '@/models/datasets'
 import NotionIcon from '@/app/components/base/notion-icon'
 import Switch from '@/app/components/base/switch'
@@ -33,8 +33,6 @@ import { useDatasetDetailContext } from '@/context/dataset-detail'
 import I18n from '@/context/i18n'
 import { IS_CE_EDITION } from '@/config'
 
-type Page = DataSourceNotionPage & { workspace_id: string }
-
 type StepTwoProps = {
   isSetting?: boolean
   documentDetail?: FullDocumentDetail
@@ -44,7 +42,7 @@ type StepTwoProps = {
   indexingType?: string
   dataSourceType: DataSourceType
   files: CustomFile[]
-  notionPages?: Page[]
+  notionPages?: NotionPage[]
   onStepChange?: (delta: number) => void
   updateIndexingTypeCache?: (type: string) => void
   updateResultCache?: (res: createDocumentResponse) => void
@@ -110,16 +108,16 @@ const StepTwo = ({
     return segmentationType === SegmentType.AUTO ? automaticFileIndexingEstimate : customFileIndexingEstimate
   })()
 
-  const scrollHandle = (e: any) => {
-    if (e.target.scrollTop > 0)
+  const scrollHandle = (e: Event) => {
+    if ((e.target as HTMLDivElement).scrollTop > 0)
       setScrolled(true)
 
     else
       setScrolled(false)
   }
 
-  const previewScrollHandle = (e: any) => {
-    if (e.target.scrollTop > 0)
+  const previewScrollHandle = (e: Event) => {
+    if ((e.target as HTMLDivElement).scrollTop > 0)
       setPreviewScrolled(true)
 
     else

+ 1 - 1
web/app/components/datasets/documents/detail/completed/InfiniteVirtualList.tsx

@@ -10,7 +10,7 @@ type IInfiniteVirtualListProps = {
   hasNextPage?: boolean // Are there more items to load? (This information comes from the most recent API request.)
   isNextPageLoading: boolean // Are we currently loading a page of items? (This may be an in-flight flag in your Redux store for example.)
   items: Array<SegmentDetailModel[]> // Array of items loaded so far.
-  loadNextPage: () => Promise<any> // Callback function responsible for loading the next page of items.
+  loadNextPage: () => Promise<void> // Callback function responsible for loading the next page of items.
   onClick: (detail: SegmentDetailModel) => void
   onChangeSwitch: (segId: string, enabled: boolean) => Promise<void>
   onDelete: (segId: string) => Promise<void>

+ 1 - 1
web/app/components/datasets/documents/detail/completed/SegmentCard.tsx

@@ -66,7 +66,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
     hit_count,
     index_node_hash,
     answer,
-  } = detail as any
+  } = detail as Required<ISegmentCardProps>['detail']
   const isDocScene = scene === 'doc'
   const [showModal, setShowModal] = useState(false)
 

+ 2 - 2
web/app/components/datasets/documents/detail/completed/index.tsx

@@ -177,8 +177,8 @@ const SegmentDetailComponent: FC<ISegmentDetailProps> = ({
       </div>
       <div className={cn(s.footer, s.numberInfo)}>
         <div className='flex items-center'>
-          <div className={cn(s.commonIcon, s.typeSquareIcon)} /><span className='mr-8'>{formatNumber(segInfo?.word_count as any)} {t('datasetDocuments.segment.characters')}</span>
-          <div className={cn(s.commonIcon, s.targetIcon)} /><span className='mr-8'>{formatNumber(segInfo?.hit_count as any)} {t('datasetDocuments.segment.hitCount')}</span>
+          <div className={cn(s.commonIcon, s.typeSquareIcon)} /><span className='mr-8'>{formatNumber(segInfo?.word_count as number)} {t('datasetDocuments.segment.characters')}</span>
+          <div className={cn(s.commonIcon, s.targetIcon)} /><span className='mr-8'>{formatNumber(segInfo?.hit_count as number)} {t('datasetDocuments.segment.hitCount')}</span>
           <div className={cn(s.commonIcon, s.bezierCurveIcon)} /><span className={s.hashText}>{t('datasetDocuments.segment.vectorHash')}{segInfo?.index_node_hash}</span>
         </div>
         <div className='flex items-center'>

File diff suppressed because it is too large
+ 3 - 3
web/app/components/datasets/documents/detail/embedding/index.tsx


File diff suppressed because it is too large
+ 5 - 5
web/app/components/datasets/documents/index.tsx


File diff suppressed because it is too large
+ 5 - 5
web/app/components/datasets/documents/list.tsx


+ 1 - 1
web/app/components/datasets/hit-testing/hit-detail.tsx

@@ -89,7 +89,7 @@ const HitDetail: FC<IHitDetailProps> = ({ segInfo, vectorInfo }) => {
         <div className={s.keywordWrapper}>
           {!segInfo?.keywords?.length
             ? '-'
-            : segInfo?.keywords?.map((word: any) => {
+            : segInfo?.keywords?.map((word) => {
               return <div className={s.keyword}>{word}</div>
             })}
         </div>

+ 4 - 3
web/app/components/explore/app-list/index.tsx

@@ -7,7 +7,7 @@ import { useContext } from 'use-context-selector'
 import Toast from '../../base/toast'
 import s from './style.module.css'
 import ExploreContext from '@/context/explore-context'
-import type { App } from '@/models/explore'
+import type { App, AppCategory } from '@/models/explore'
 import Category from '@/app/components/explore/category'
 import AppCard from '@/app/components/explore/app-card'
 import { fetchAppDetail, fetchAppList, installApp } from '@/service/explore'
@@ -22,7 +22,7 @@ const Apps: FC = () => {
   const { t } = useTranslation()
   const router = useRouter()
   const { setControlUpdateInstalledApps, hasEditPermission } = useContext(ExploreContext)
-  const [currCategory, setCurrCategory] = React.useState('')
+  const [currCategory, setCurrCategory] = React.useState<AppCategory | ''>('')
   const [allList, setAllList] = React.useState<App[]>([])
   const [isLoaded, setIsLoaded] = React.useState(false)
 
@@ -31,7 +31,8 @@ const Apps: FC = () => {
       return allList
     return allList.filter(item => item.category === currCategory)
   })()
-  const [categories, setCategories] = React.useState([])
+
+  const [categories, setCategories] = React.useState<AppCategory[]>([])
   useEffect(() => {
     (async () => {
       const { categories, recommended_apps }: any = await fetchAppList()

+ 4 - 3
web/app/components/explore/category.tsx

@@ -4,14 +4,15 @@ import React from 'react'
 import { useTranslation } from 'react-i18next'
 import cn from 'classnames'
 import exploreI18n from '@/i18n/lang/explore.en'
+import type { AppCategory } from '@/models/explore'
 
 const categoryI18n = exploreI18n.category
 
 export type ICategoryProps = {
   className?: string
-  list: string[]
+  list: AppCategory[]
   value: string
-  onChange: (value: string) => void
+  onChange: (value: AppCategory | '') => void
 }
 
 const Category: FC<ICategoryProps> = ({
@@ -40,7 +41,7 @@ const Category: FC<ICategoryProps> = ({
           style={itemStyle(name === value)}
           onClick={() => onChange(name)}
         >
-          {(categoryI18n as any)[name] ? t(`explore.category.${name}`) : name}
+          {categoryI18n[name] ? t(`explore.category.${name}`) : name}
         </div>
       ))}
     </div>

+ 2 - 2
web/app/components/header/account-setting/index.tsx

@@ -95,8 +95,8 @@ export default function AccountSetting({
   ]
   const scrollRef = useRef<HTMLDivElement>(null)
   const [scrolled, setScrolled] = useState(false)
-  const scrollHandle = (e: any) => {
-    if (e.target.scrollTop > 0)
+  const scrollHandle = (e: Event) => {
+    if ((e.target as HTMLDivElement).scrollTop > 0)
       setScrolled(true)
 
     else

+ 1 - 1
web/app/components/header/account-setting/model-page/model-item/Card.tsx

@@ -9,7 +9,7 @@ import Button from '@/app/components/base/button'
 type CardProps = {
   providerType: ProviderEnum
   models: Model[]
-  onOpenModal: (v: any) => void
+  onOpenModal: (v: Omit<Model, 'config'> & Model['config']) => void
   onOperate: (v: Record<string, any>) => void
 }
 

+ 1 - 1
web/app/components/share/text-generation/result/index.tsx

@@ -133,7 +133,7 @@ const Result: FC<IResultProps> = ({
 
     setResponsingTrue()
     sendCompletionMessage(data, {
-      onData: (data: string, _isFirstMessage: boolean, { messageId }: any) => {
+      onData: (data: string, _isFirstMessage: boolean, { messageId }) => {
         tempMessageId = messageId
         res.push(data)
         setCompletionRes(res.join(''))

+ 4 - 0
web/models/common.ts

@@ -138,6 +138,10 @@ export type DataSourceNotionPage = {
   is_bound: boolean
 }
 
+export type NotionPage = DataSourceNotionPage & {
+  workspace_id: string
+}
+
 export type DataSourceNotionPageMap = Record<string, DataSourceNotionPage & { workspace_id: string }>
 
 export type DataSourceNotionWorkspace = {

+ 3 - 1
web/models/explore.ts

@@ -8,13 +8,15 @@ export type AppBasicInfo = {
   icon_background: string
 }
 
+export type AppCategory = 'Writing' | 'Translate' | 'HR' | 'Programming' | 'Assistant'
+
 export type App = {
   app: AppBasicInfo
   app_id: string
   description: string
   copyright: string
   privacy_policy: string
-  category: string
+  category: AppCategory
   position: number
   is_listed: boolean
   install_count: number