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<

Reply via email to