This is an automated email from the ASF dual-hosted git repository. young pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push: new 63dd73d8c feat(services): filter routes/stream_routes by `service_id` (#3111) 63dd73d8c is described below commit 63dd73d8cedfb2ac70d55f29e3318e8410495e96 Author: YYYoung <isk...@outlook.com> AuthorDate: Thu Jun 12 15:19:26 2025 +0800 feat(services): filter routes/stream_routes by `service_id` (#3111) * feat(services/routes): filter by `service_id` * feat(services): filter stream_routes by service_id * fix: type --- src/apis/hooks.ts | 8 +++++--- src/apis/routes.ts | 8 +++++++- src/apis/stream_routes.ts | 8 ++++++-- src/config/req.ts | 10 ++++++++-- src/routes/routes/index.tsx | 9 +++++++-- src/routes/services/detail.$id/routes/index.tsx | 5 +++++ src/routes/services/detail.$id/stream_routes/index.tsx | 5 +++++ src/routes/stream_routes/index.tsx | 9 +++++++-- 8 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/apis/hooks.ts b/src/apis/hooks.ts index 1e427c45e..4825f3398 100644 --- a/src/apis/hooks.ts +++ b/src/apis/hooks.ts @@ -82,14 +82,16 @@ export const genUseList = < routeKey: T, listQueryOptions: ReturnType<typeof genListQueryOptions<P, R>> ) => { - return (replaceKey?: U) => { + return (replaceKey?: U, defaultParams?: Partial<P>) => { const key = replaceKey || routeKey; const { params, setParams } = useSearchParams<T | U, P>(key); - const listQuery = useSuspenseQuery(listQueryOptions(params)); + const listQuery = useSuspenseQuery( + listQueryOptions({ ...defaultParams, ...params }) + ); const { data, isLoading, refetch } = listQuery; const opts = { data, setParams, params }; const pagination = useTablePagination(opts); - return { data, isLoading, refetch, pagination }; + return { data, isLoading, refetch, pagination, setParams }; }; }; diff --git a/src/apis/routes.ts b/src/apis/routes.ts index fc5af3717..cb99f7177 100644 --- a/src/apis/routes.ts +++ b/src/apis/routes.ts @@ -21,7 +21,13 @@ import { API_ROUTES, PAGE_SIZE_MAX, PAGE_SIZE_MIN } from '@/config/constant'; import type { APISIXType } from '@/types/schema/apisix'; import type { PageSearchType } from '@/types/schema/pageSearch'; -export const getRouteListReq = (req: AxiosInstance, params: PageSearchType) => +export type WithServiceIdFilter = PageSearchType & { + filter?: { + service_id?: string; + }; +}; + +export const getRouteListReq = (req: AxiosInstance, params: WithServiceIdFilter) => req .get<undefined, APISIXType['RespRouteList']>(API_ROUTES, { params }) .then((v) => v.data); diff --git a/src/apis/stream_routes.ts b/src/apis/stream_routes.ts index 0e26ae225..0dbf09d30 100644 --- a/src/apis/stream_routes.ts +++ b/src/apis/stream_routes.ts @@ -20,9 +20,13 @@ import type { AxiosInstance } from 'axios'; import type { StreamRoutePostType } from '@/components/form-slice/FormPartStreamRoute/schema'; import { API_STREAM_ROUTES } from '@/config/constant'; import type { APISIXType } from '@/types/schema/apisix'; -import type { PageSearchType } from '@/types/schema/pageSearch'; -export const getStreamRouteListReq = (req: AxiosInstance, params: PageSearchType) => +import type { WithServiceIdFilter } from './routes'; + +export const getStreamRouteListReq = ( + req: AxiosInstance, + params: WithServiceIdFilter +) => req .get<unknown, APISIXType['RespStreamRouteList']>(API_STREAM_ROUTES, { params, diff --git a/src/config/req.ts b/src/config/req.ts index 232a9b00b..283338feb 100644 --- a/src/config/req.ts +++ b/src/config/req.ts @@ -29,10 +29,16 @@ import { globalStore } from '@/stores/global'; export const req = axios.create(); req.interceptors.request.use((conf) => { - conf.paramsSerializer = (p) => - stringify(p, { + conf.paramsSerializer = (p) => { + // from { filter: { service_id: 1 } } + // to `filter=service_id%3D1` + if (p.filter) { + p.filter = stringify(p.filter); + } + return stringify(p, { arrayFormat: 'repeat', }); + }; conf.baseURL = API_PREFIX; conf.headers.set(API_HEADER_KEY, globalStore.settings.adminKey); return conf; diff --git a/src/routes/routes/index.tsx b/src/routes/routes/index.tsx index 7374b4811..6b44fbd77 100644 --- a/src/routes/routes/index.tsx +++ b/src/routes/routes/index.tsx @@ -21,6 +21,7 @@ import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { getRouteListQueryOptions, useRouteList } from '@/apis/hooks'; +import type { WithServiceIdFilter } from '@/apis/routes'; import { DeleteResourceBtn } from '@/components/page/DeleteResourceBtn'; import PageHeader from '@/components/page/PageHeader'; import { ToAddPageBtn, ToDetailPageBtn } from '@/components/page/ToAddPageBtn'; @@ -33,14 +34,18 @@ import type { ListPageKeys } from '@/utils/useTablePagination'; export type RouteListProps = { routeKey: Extract<ListPageKeys, '/routes/' | '/services/detail/$id/routes/'>; + defaultParams?: Partial<WithServiceIdFilter>; ToDetailBtn: (props: { record: APISIXType['RespRouteItem']; }) => React.ReactNode; }; export const RouteList = (props: RouteListProps) => { - const { routeKey, ToDetailBtn } = props; - const { data, isLoading, refetch, pagination } = useRouteList(routeKey); + const { routeKey, ToDetailBtn, defaultParams } = props; + const { data, isLoading, refetch, pagination } = useRouteList( + routeKey, + defaultParams + ); const { t } = useTranslation(); const columns = useMemo<ProColumns<APISIXType['RespRouteItem']>[]>(() => { diff --git a/src/routes/services/detail.$id/routes/index.tsx b/src/routes/services/detail.$id/routes/index.tsx index 4a041708a..97e092c62 100644 --- a/src/routes/services/detail.$id/routes/index.tsx +++ b/src/routes/services/detail.$id/routes/index.tsx @@ -32,6 +32,11 @@ function RouteComponent() { <PageHeader title={t('sources.routes')} /> <RouteList routeKey="/services/detail/$id/routes/" + defaultParams={{ + filter: { + service_id: id, + }, + }} ToDetailBtn={({ record }) => ( <ToDetailPageBtn key="detail" diff --git a/src/routes/services/detail.$id/stream_routes/index.tsx b/src/routes/services/detail.$id/stream_routes/index.tsx index 8c3f6d128..f3503272f 100644 --- a/src/routes/services/detail.$id/stream_routes/index.tsx +++ b/src/routes/services/detail.$id/stream_routes/index.tsx @@ -39,6 +39,11 @@ function StreamRouteComponent() { params={{ id, routeId: record.value.id }} /> )} + defaultParams={{ + filter: { + service_id: id, + }, + }} /> </> ); diff --git a/src/routes/stream_routes/index.tsx b/src/routes/stream_routes/index.tsx index 1909744c8..3fb5247ba 100644 --- a/src/routes/stream_routes/index.tsx +++ b/src/routes/stream_routes/index.tsx @@ -21,6 +21,7 @@ import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { getStreamRouteListQueryOptions, useStreamRouteList } from '@/apis/hooks'; +import type { WithServiceIdFilter } from '@/apis/routes'; import { DeleteResourceBtn } from '@/components/page/DeleteResourceBtn'; import PageHeader from '@/components/page/PageHeader'; import { ToAddPageBtn, ToDetailPageBtn } from '@/components/page/ToAddPageBtn'; @@ -39,11 +40,15 @@ export type StreamRouteListProps = { ToDetailBtn: (props: { record: APISIXType['RespStreamRouteItem']; }) => React.ReactNode; + defaultParams?: Partial<WithServiceIdFilter>; }; export const StreamRouteList = (props: StreamRouteListProps) => { - const { routeKey, ToDetailBtn } = props; - const { data, isLoading, refetch, pagination } = useStreamRouteList(routeKey); + const { routeKey, ToDetailBtn, defaultParams } = props; + const { data, isLoading, refetch, pagination } = useStreamRouteList( + routeKey, + defaultParams + ); const { t } = useTranslation(); const columns = useMemo<