| const newIndex = options.findIndex(option => option.value === value) | const newIndex = options.findIndex(option => option.value === value) | ||||
| setActiveIndex(newIndex) | setActiveIndex(newIndex) | ||||
| updateSliderStyle(newIndex) | updateSliderStyle(newIndex) | ||||
| }, [value, options, pluginList]) | |||||
| }, [value, options, pluginList?.total]) | |||||
| return ( | return ( | ||||
| <div className={cn(className, 'relative inline-flex items-center justify-center rounded-[10px] bg-components-segmented-control-bg-normal p-0.5')}> | <div className={cn(className, 'relative inline-flex items-center justify-center rounded-[10px] bg-components-segmented-control-bg-normal p-0.5')}> | ||||
| {option.text} | {option.text} | ||||
| {/* if no plugin installed, the badge won't show */} | {/* if no plugin installed, the badge won't show */} | ||||
| {option.value === 'plugins' | {option.value === 'plugins' | ||||
| && (pluginList?.plugins.length ?? 0) > 0 | |||||
| && (pluginList?.total ?? 0) > 0 | |||||
| && <Badge | && <Badge | ||||
| size='s' | size='s' | ||||
| uppercase={true} | uppercase={true} | ||||
| state={BadgeState.Default} | state={BadgeState.Default} | ||||
| > | > | ||||
| {pluginList?.plugins.length} | |||||
| {pluginList?.total} | |||||
| </Badge> | </Badge> | ||||
| } | } | ||||
| </div> | </div> |
| import type { FilterState } from './filter-management' | import type { FilterState } from './filter-management' | ||||
| import FilterManagement from './filter-management' | import FilterManagement from './filter-management' | ||||
| import List from './list' | import List from './list' | ||||
| import { useInstalledLatestVersion, useInstalledPluginListWithPagination, useInvalidateInstalledPluginList } from '@/service/use-plugins' | |||||
| import { useInstalledLatestVersion, useInstalledPluginList, useInvalidateInstalledPluginList } from '@/service/use-plugins' | |||||
| import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' | import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' | ||||
| import { usePluginPageContext } from './context' | import { usePluginPageContext } from './context' | ||||
| import { useDebounceFn } from 'ahooks' | import { useDebounceFn } from 'ahooks' | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const filters = usePluginPageContext(v => v.filters) as FilterState | const filters = usePluginPageContext(v => v.filters) as FilterState | ||||
| const setFilters = usePluginPageContext(v => v.setFilters) | const setFilters = usePluginPageContext(v => v.setFilters) | ||||
| const { data: pluginList, isLoading: isPluginListLoading, isFetching, isLastPage, loadNextPage } = useInstalledPluginListWithPagination() | |||||
| const { data: pluginList, isLoading: isPluginListLoading, isFetching, isLastPage, loadNextPage } = useInstalledPluginList() | |||||
| const { data: installedLatestVersion } = useInstalledLatestVersion( | const { data: installedLatestVersion } = useInstalledLatestVersion( | ||||
| pluginList?.plugins | pluginList?.plugins | ||||
| .filter(plugin => plugin.source === PluginSource.marketplace) | .filter(plugin => plugin.source === PluginSource.marketplace) |
| GitHubItemAndMarketPlaceDependency, | GitHubItemAndMarketPlaceDependency, | ||||
| InstallPackageResponse, | InstallPackageResponse, | ||||
| InstalledLatestVersionResponse, | InstalledLatestVersionResponse, | ||||
| InstalledPluginListResponse, | |||||
| InstalledPluginListWithTotalResponse, | InstalledPluginListWithTotalResponse, | ||||
| PackageDependency, | PackageDependency, | ||||
| Permissions, | Permissions, | ||||
| }) | }) | ||||
| } | } | ||||
| export const useInstalledPluginList = (disable?: boolean) => { | |||||
| return useQuery<InstalledPluginListResponse>({ | |||||
| queryKey: useInstalledPluginListKey, | |||||
| queryFn: () => get<InstalledPluginListResponse>('/workspaces/current/plugin/list'), | |||||
| enabled: !disable, | |||||
| initialData: !disable ? undefined : { plugins: [] }, | |||||
| }) | |||||
| } | |||||
| export const useInstalledPluginListWithPagination = (pageSize = 100) => { | |||||
| export const useInstalledPluginList = (disable?: boolean, pageSize = 100) => { | |||||
| const fetchPlugins = async ({ pageParam = 1 }) => { | const fetchPlugins = async ({ pageParam = 1 }) => { | ||||
| const response = await get<InstalledPluginListWithTotalResponse>( | const response = await get<InstalledPluginListWithTotalResponse>( | ||||
| `/workspaces/current/plugin/list?page=${pageParam}&page_size=${pageSize}`, | `/workspaces/current/plugin/list?page=${pageParam}&page_size=${pageSize}`, | ||||
| hasNextPage, | hasNextPage, | ||||
| isFetchingNextPage, | isFetchingNextPage, | ||||
| isLoading, | isLoading, | ||||
| isSuccess, | |||||
| } = useInfiniteQuery({ | } = useInfiniteQuery({ | ||||
| queryKey: ['installed-plugins', pageSize], | |||||
| enabled: !disable, | |||||
| queryKey: useInstalledPluginListKey, | |||||
| queryFn: fetchPlugins, | queryFn: fetchPlugins, | ||||
| getNextPageParam: (lastPage, pages) => { | getNextPageParam: (lastPage, pages) => { | ||||
| const totalItems = lastPage.total | const totalItems = lastPage.total | ||||
| }) | }) | ||||
| const plugins = data?.pages.flatMap(page => page.plugins) ?? [] | const plugins = data?.pages.flatMap(page => page.plugins) ?? [] | ||||
| const total = data?.pages[0].total ?? 0 | |||||
| return { | return { | ||||
| data: { | |||||
| data: disable ? undefined : { | |||||
| plugins, | plugins, | ||||
| total, | |||||
| }, | }, | ||||
| isLastPage: !hasNextPage, | isLastPage: !hasNextPage, | ||||
| loadNextPage: () => { | loadNextPage: () => { | ||||
| isLoading, | isLoading, | ||||
| isFetching: isFetchingNextPage, | isFetching: isFetchingNextPage, | ||||
| error, | error, | ||||
| isSuccess, | |||||
| } | } | ||||
| } | } | ||||