diff --git a/web/app/(commonLayout)/datasets/Container.tsx b/web/app/(commonLayout)/datasets/Container.tsx index 02b3cbb61..a30521d99 100644 --- a/web/app/(commonLayout)/datasets/Container.tsx +++ b/web/app/(commonLayout)/datasets/Container.tsx @@ -5,7 +5,6 @@ import { useEffect, useMemo, useRef, useState } from 'react' import { useRouter } from 'next/navigation' import { useTranslation } from 'react-i18next' import { useDebounceFn } from 'ahooks' -import useSWR from 'swr' // Components import ExternalAPIPanel from '../../components/datasets/external-api/external-api-panel' @@ -28,6 +27,8 @@ import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import { useStore as useTagStore } from '@/app/components/base/tag-management/store' import { useAppContext } from '@/context/app-context' import { useExternalApiPanel } from '@/context/external-api-panel-context' +// eslint-disable-next-line import/order +import { useQuery } from '@tanstack/react-query' const Container = () => { const { t } = useTranslation() @@ -47,7 +48,13 @@ const Container = () => { defaultTab: 'dataset', }) const containerRef = useRef(null) - const { data } = useSWR(activeTab === 'dataset' ? null : '/datasets/api-base-info', fetchDatasetApiBaseUrl) + const { data } = useQuery( + { + queryKey: ['datasetApiBaseInfo'], + queryFn: () => fetchDatasetApiBaseUrl('/datasets/api-base-info'), + enabled: activeTab !== 'dataset', + }, + ) const [keywords, setKeywords] = useState('') const [searchKeywords, setSearchKeywords] = useState('') diff --git a/web/app/(commonLayout)/layout.tsx b/web/app/(commonLayout)/layout.tsx index af36d4d96..f0f7e0321 100644 --- a/web/app/(commonLayout)/layout.tsx +++ b/web/app/(commonLayout)/layout.tsx @@ -8,24 +8,27 @@ import Header from '@/app/components/header' import { EventEmitterContextProvider } from '@/context/event-emitter' import { ProviderContextProvider } from '@/context/provider-context' import { ModalContextProvider } from '@/context/modal-context' +import { TanstackQueryIniter } from '@/context/query-client' const Layout = ({ children }: { children: ReactNode }) => { return ( <> - - - - - -
- - {children} - - - - + + + + + + +
+ + {children} + + + + + ) diff --git a/web/context/query-client.tsx b/web/context/query-client.tsx new file mode 100644 index 000000000..f85930515 --- /dev/null +++ b/web/context/query-client.tsx @@ -0,0 +1,23 @@ +'use client' + +import type { FC, PropsWithChildren } from 'react' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' + +const STALE_TIME = 1000 * 60 * 30 // 30 minutes + +const client = new QueryClient({ + defaultOptions: { + queries: { + staleTime: STALE_TIME, + }, + }, +}) + +export const TanstackQueryIniter: FC = (props) => { + const { children } = props + return + {children} + + +} diff --git a/web/package.json b/web/package.json index e53f0543a..596faf81a 100644 --- a/web/package.json +++ b/web/package.json @@ -42,6 +42,8 @@ "@svgdotjs/svg.js": "^3.2.4", "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.9", + "@tanstack/react-query": "^5.60.5", + "@tanstack/react-query-devtools": "^5.60.5", "ahooks": "^3.7.5", "class-variance-authority": "^0.7.0", "classnames": "^2.3.2", diff --git a/web/service/use-base.ts b/web/service/use-base.ts new file mode 100644 index 000000000..5eeca2266 --- /dev/null +++ b/web/service/use-base.ts @@ -0,0 +1,13 @@ +import { + useQueryClient, +} from '@tanstack/react-query' + +export const useInvalid = (key: string[]) => { + const queryClient = useQueryClient() + return () => { + queryClient.invalidateQueries( + { + queryKey: key, + }) + } +} diff --git a/web/utils/context.ts b/web/utils/context.ts new file mode 100644 index 000000000..8829a679c --- /dev/null +++ b/web/utils/context.ts @@ -0,0 +1,45 @@ +import { type Context, type Provider, createContext, useContext } from 'react' +import * as selector from 'use-context-selector' + +const createCreateCtxFunction = ( + useContextImpl: typeof useContext, + createContextImpl: typeof createContext) => { + return function({ name, defaultValue }: CreateCtxOptions = {}): CreateCtxReturn { + const emptySymbol = Symbol(`empty ${name}`) + // @ts-expect-error it's ok here + const context = createContextImpl(defaultValue ?? emptySymbol) + const useContextValue = () => { + const ctx = useContextImpl(context) + if (ctx === emptySymbol) + throw new Error(`No ${name ?? 'related'} context found.`) + + return ctx + } + const result = [context.Provider, useContextValue, context] as CreateCtxReturn + result.context = context + result.provider = context.Provider + result.useContextValue = useContextValue + return result + } +} + +type CreateCtxOptions = { + defaultValue?: T + name?: string +} + +type CreateCtxReturn = [Provider, () => T, Context] & { + context: Context + provider: Provider + useContextValue: () => T +} + +// example +// const [AppProvider, useApp, AppContext] = createCtx() + +export const createCtx = createCreateCtxFunction(useContext, createContext) + +export const createSelectorCtx = createCreateCtxFunction( + selector.useContext, + selector.createContext as typeof createContext, +) diff --git a/web/yarn.lock b/web/yarn.lock index 9fddfc194..20253fa39 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -3108,6 +3108,30 @@ lodash.merge "^4.6.2" postcss-selector-parser "6.0.10" +"@tanstack/query-core@5.60.5": + version "5.60.5" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.60.5.tgz#37b7c5ab7e6894cea9ef341299a7a3febc2ea361" + integrity sha512-jiS1aC3XI3BJp83ZiTuDLerTmn9P3U95r6p+6/SNauLJaYxfIC4dMuWygwnBHIZxjn2zJqEpj3nysmPieoxfPQ== + +"@tanstack/query-devtools@5.59.20": + version "5.59.20" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.59.20.tgz#a827ac682ec1268fc9c99e7b6eb739f35b5606aa" + integrity sha512-vxhuQ+8VV4YWQSFxQLsuM+dnEKRY7VeRzpNabFXdhEwsBYLrjXlF1pM38A8WyKNLqZy8JjyRO8oP4Wd/oKHwuQ== + +"@tanstack/react-query-devtools@^5.60.5": + version "5.60.5" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.60.5.tgz#fe398b4896a292fbe835d3fd4799e929de94c25a" + integrity sha512-lzANl0ih3CNKBGUoXhhkAAHI1Y4Yqs9Jf3iuTUsGiPpmF0RWXTeYFaQxc+h1PhJz3VwYrIYCwmPoNts0mSjSuA== + dependencies: + "@tanstack/query-devtools" "5.59.20" + +"@tanstack/react-query@^5.60.5": + version "5.60.5" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.60.5.tgz#3194c390f7eff20542b321c3042880dc3f1a81e2" + integrity sha512-M77bOsPwj1wYE56gk7iJvxGAr4IC12NWdIDhT+Eo8ldkWRHMvIR8I/rufIvT1OXoV/bl7EECwuRuMlxxWtvW2Q== + dependencies: + "@tanstack/query-core" "5.60.5" + "@testing-library/dom@10.4.0": version "10.4.0" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.0.tgz#82a9d9462f11d240ecadbf406607c6ceeeff43a8"