From e66ba6ffdd1291df1a87c12b04c9266cc02dd2b5 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 6 Nov 2024 18:13:06 +0800 Subject: [PATCH 1/3] chore: fill repo url --- web/app/components/plugins/base/key-value-item.tsx | 6 ++++-- web/app/components/plugins/plugin-page/plugin-info.tsx | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/web/app/components/plugins/base/key-value-item.tsx b/web/app/components/plugins/base/key-value-item.tsx index faa81f64e7..c249284bb9 100644 --- a/web/app/components/plugins/base/key-value-item.tsx +++ b/web/app/components/plugins/base/key-value-item.tsx @@ -2,7 +2,6 @@ import type { FC } from 'react' import React, { useCallback, useEffect, useState } from 'react' import copy from 'copy-to-clipboard' - import { RiClipboardLine, } from '@remixicon/react' @@ -11,16 +10,19 @@ import { ClipboardCheck } from '../../base/icons/src/vender/line/files' import Tooltip from '../../base/tooltip' import cn from '@/utils/classnames' import ActionButton from '@/app/components/base/action-button' + type Props = { label: string labelWidthClassName?: string value: string + valueMaxWidthClassName?: string } const KeyValueItem: FC = ({ label, labelWidthClassName = 'w-10', value, + valueMaxWidthClassName = 'max-w-[162px]', }) => { const { t } = useTranslation() const [isCopied, setIsCopied] = useState(false) @@ -46,7 +48,7 @@ const KeyValueItem: FC = ({
{label}
- + {value} diff --git a/web/app/components/plugins/plugin-page/plugin-info.tsx b/web/app/components/plugins/plugin-page/plugin-info.tsx index 6e30834c49..abd297905a 100644 --- a/web/app/components/plugins/plugin-page/plugin-info.tsx +++ b/web/app/components/plugins/plugin-page/plugin-info.tsx @@ -4,6 +4,7 @@ import React from 'react' import { useTranslation } from 'react-i18next' import KeyValueItem from '../base/key-value-item' import Modal from '../../base/modal' +import { convertRepoToUrl } from '../install-plugin/utils' const i18nPrefix = 'plugin.pluginInfoModal' type Props = { @@ -30,7 +31,7 @@ const PlugInfo: FC = ({ closable >
- {repository && } + {repository && } {release && } {packageName && }
From 92153328eaed3186513413f8e7709ea1e5c08a3b Mon Sep 17 00:00:00 2001 From: twwu Date: Wed, 6 Nov 2024 18:43:27 +0800 Subject: [PATCH 2/3] feat: add loading state for installed plugin list in context and update PluginsPanel to display loading indicator --- web/app/components/plugins/plugin-page/context.tsx | 5 ++++- web/app/components/plugins/plugin-page/plugins-panel.tsx | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index 8587012b79..cbe8f3bf93 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -27,6 +27,7 @@ export type PluginPageContextValue = { setCurrentPluginDetail: (plugin: PluginDetail) => void installedPluginList: PluginDetail[] mutateInstalledPluginList: () => void + isPluginListLoading: boolean filters: FilterState setFilters: (filter: FilterState) => void activeTab: string @@ -45,6 +46,7 @@ export const PluginPageContext = createContext({ setCurrentPluginDetail: () => {}, installedPluginList: [], mutateInstalledPluginList: () => {}, + isPluginListLoading: true, filters: { categories: [], tags: [], @@ -78,7 +80,7 @@ export const PluginPageContextProvider = ({ tags: [], searchQuery: '', }) - const { data, mutate: mutateInstalledPluginList } = useSWR({ url: '/workspaces/current/plugin/list' }, fetchInstalledPluginList) + const { data, mutate: mutateInstalledPluginList, isLoading: isPluginListLoading } = useSWR({ url: '/workspaces/current/plugin/list' }, fetchInstalledPluginList) const [currentPluginDetail, setCurrentPluginDetail] = useState() const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) @@ -106,6 +108,7 @@ export const PluginPageContextProvider = ({ setCurrentPluginDetail, installedPluginList: data?.plugins || [], mutateInstalledPluginList, + isPluginListLoading, filters, setFilters, activeTab, diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 6b8d2475fd..ae108d5b65 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -8,10 +8,12 @@ import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' import { usePluginPageContext } from './context' import { useDebounceFn } from 'ahooks' import Empty from './empty' +import Loading from '../../base/loading' const PluginsPanel = () => { const [filters, setFilters] = usePluginPageContext(v => [v.filters, v.setFilters]) as [FilterState, (filter: FilterState) => void] const pluginList = usePluginPageContext(v => v.installedPluginList) as PluginDetail[] + const isPluginListLoading = usePluginPageContext(v => v.isPluginListLoading) const mutateInstalledPluginList = usePluginPageContext(v => v.mutateInstalledPluginList) const { run: handleFilterChange } = useDebounceFn((filters: FilterState) => { @@ -38,7 +40,7 @@ const PluginsPanel = () => { onFilterChange={handleFilterChange} />
- {filteredList.length > 0 ? ( + {isPluginListLoading ? : filteredList.length > 0 ? (
From b1242ba1ac5fd26e8203b6b980b6d1b300b62ba4 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Thu, 7 Nov 2024 09:44:36 +0800 Subject: [PATCH 3/3] build: init `@tanstack/react-query` --- web/app/(commonLayout)/datasets/Container.tsx | 10 ++++- web/app/(commonLayout)/layout.tsx | 5 ++- web/context/query-client.tsx | 15 +++++++ web/package.json | 2 + web/pnpm-lock.yaml | 44 +++++++++++++++++-- 5 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 web/context/query-client.tsx diff --git a/web/app/(commonLayout)/datasets/Container.tsx b/web/app/(commonLayout)/datasets/Container.tsx index 02b3cbb61d..c30cc18418 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,7 @@ 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' +import { useQuery } from '@tanstack/react-query' const Container = () => { const { t } = useTranslation() @@ -47,7 +47,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', activeTab], + 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 af36d4d961..ef07732997 100644 --- a/web/app/(commonLayout)/layout.tsx +++ b/web/app/(commonLayout)/layout.tsx @@ -8,6 +8,7 @@ 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 ( @@ -21,7 +22,9 @@ const Layout = ({ children }: { children: ReactNode }) => {
- {children} + + {children} + diff --git a/web/context/query-client.tsx b/web/context/query-client.tsx new file mode 100644 index 0000000000..4cb66eb826 --- /dev/null +++ b/web/context/query-client.tsx @@ -0,0 +1,15 @@ +'use client' + +import type { FC, PropsWithChildren } from 'react' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' + +const client = new QueryClient() + +export const TanstackQueryIniter: FC = (props) => { + const { children } = props + return + {children} + + +} diff --git a/web/package.json b/web/package.json index 42ad410926..568a3d3cb0 100644 --- a/web/package.json +++ b/web/package.json @@ -44,6 +44,8 @@ "@svgdotjs/svg.js": "^3.2.4", "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.9", + "@tanstack/react-query": "^5.59.20", + "@tanstack/react-query-devtools": "^5.59.20", "ahooks": "^3.8.1", "class-variance-authority": "^0.7.0", "classnames": "^2.5.1", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index a919c971b7..f790bb5c3c 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -73,6 +73,12 @@ importers: '@tailwindcss/typography': specifier: ^0.5.9 version: 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))) + '@tanstack/react-query': + specifier: ^5.59.20 + version: 5.59.20(react@18.2.0) + '@tanstack/react-query-devtools': + specifier: ^5.59.20 + version: 5.59.20(@tanstack/react-query@5.59.20(react@18.2.0))(react@18.2.0) ahooks: specifier: ^3.8.1 version: 3.8.1(react@18.2.0) @@ -2377,6 +2383,23 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20' + '@tanstack/query-core@5.59.20': + resolution: {integrity: sha512-e8vw0lf7KwfGe1if4uPFhvZRWULqHjFcz3K8AebtieXvnMOz5FSzlZe3mTLlPuUBcydCnBRqYs2YJ5ys68wwLg==} + + '@tanstack/query-devtools@5.59.20': + resolution: {integrity: sha512-vxhuQ+8VV4YWQSFxQLsuM+dnEKRY7VeRzpNabFXdhEwsBYLrjXlF1pM38A8WyKNLqZy8JjyRO8oP4Wd/oKHwuQ==} + + '@tanstack/react-query-devtools@5.59.20': + resolution: {integrity: sha512-AL/eQS1NFZhwwzq2Bq9Gd8wTTH+XhPNOJlDFpzPMu9NC5CQVgA0J8lWrte/sXpdWNo5KA4hgHnEdImZsF4h6Lw==} + peerDependencies: + '@tanstack/react-query': ^5.59.20 + react: ^18 || ^19 + + '@tanstack/react-query@5.59.20': + resolution: {integrity: sha512-Zly0egsK0tFdfSbh5/mapSa+Zfc3Et0Zkar7Wo5sQkFzWyB3p3uZWOHR2wrlAEEV2L953eLuDBtbgFvMYiLvUw==} + peerDependencies: + react: ^18 || ^19 + '@tanstack/react-virtual@3.10.8': resolution: {integrity: sha512-VbzbVGSsZlQktyLrP5nxE+vE1ZR+U0NFAWPbJLoG2+DKPwd2D7dVICTVIIaYlJqX1ZCEnYDbaOpmMwbsyhBoIA==} peerDependencies: @@ -10699,6 +10722,21 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + '@tanstack/query-core@5.59.20': {} + + '@tanstack/query-devtools@5.59.20': {} + + '@tanstack/react-query-devtools@5.59.20(@tanstack/react-query@5.59.20(react@18.2.0))(react@18.2.0)': + dependencies: + '@tanstack/query-devtools': 5.59.20 + '@tanstack/react-query': 5.59.20(react@18.2.0) + react: 18.2.0 + + '@tanstack/react-query@5.59.20(react@18.2.0)': + dependencies: + '@tanstack/query-core': 5.59.20 + react: 18.2.0 + '@tanstack/react-virtual@3.10.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@tanstack/virtual-core': 3.10.8 @@ -12844,7 +12882,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -12862,7 +12900,7 @@ snapshots: dependencies: eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: @@ -12918,7 +12956,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3