| @@ -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<HTMLDivElement>(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('') | |||
| @@ -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 ( | |||
| <> | |||
| <GA gaType={GaType.admin} /> | |||
| <SwrInitor> | |||
| <AppContextProvider> | |||
| <EventEmitterContextProvider> | |||
| <ProviderContextProvider> | |||
| <ModalContextProvider> | |||
| <HeaderWrapper> | |||
| <Header /> | |||
| </HeaderWrapper> | |||
| {children} | |||
| </ModalContextProvider> | |||
| </ProviderContextProvider> | |||
| </EventEmitterContextProvider> | |||
| </AppContextProvider> | |||
| <TanstackQueryIniter> | |||
| <AppContextProvider> | |||
| <EventEmitterContextProvider> | |||
| <ProviderContextProvider> | |||
| <ModalContextProvider> | |||
| <HeaderWrapper> | |||
| <Header /> | |||
| </HeaderWrapper> | |||
| {children} | |||
| </ModalContextProvider> | |||
| </ProviderContextProvider> | |||
| </EventEmitterContextProvider> | |||
| </AppContextProvider> | |||
| </TanstackQueryIniter> | |||
| </SwrInitor> | |||
| </> | |||
| ) | |||
| @@ -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<PropsWithChildren> = (props) => { | |||
| const { children } = props | |||
| return <QueryClientProvider client={client}> | |||
| {children} | |||
| <ReactQueryDevtools initialIsOpen={false} /> | |||
| </QueryClientProvider> | |||
| } | |||
| @@ -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", | |||
| @@ -0,0 +1,13 @@ | |||
| import { | |||
| useQueryClient, | |||
| } from '@tanstack/react-query' | |||
| export const useInvalid = (key: string[]) => { | |||
| const queryClient = useQueryClient() | |||
| return () => { | |||
| queryClient.invalidateQueries( | |||
| { | |||
| queryKey: key, | |||
| }) | |||
| } | |||
| } | |||
| @@ -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<T>({ name, defaultValue }: CreateCtxOptions<T> = {}): CreateCtxReturn<T> { | |||
| const emptySymbol = Symbol(`empty ${name}`) | |||
| // @ts-expect-error it's ok here | |||
| const context = createContextImpl<T>(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<T> | |||
| result.context = context | |||
| result.provider = context.Provider | |||
| result.useContextValue = useContextValue | |||
| return result | |||
| } | |||
| } | |||
| type CreateCtxOptions<T> = { | |||
| defaultValue?: T | |||
| name?: string | |||
| } | |||
| type CreateCtxReturn<T> = [Provider<T>, () => T, Context<T>] & { | |||
| context: Context<T> | |||
| provider: Provider<T> | |||
| useContextValue: () => T | |||
| } | |||
| // example | |||
| // const [AppProvider, useApp, AppContext] = createCtx<AppContextValue>() | |||
| export const createCtx = createCreateCtxFunction(useContext, createContext) | |||
| export const createSelectorCtx = createCreateCtxFunction( | |||
| selector.useContext, | |||
| selector.createContext as typeof createContext, | |||
| ) | |||
| @@ -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" | |||