From 38aa2dace82ba293959b0d205e61b232fea41601 Mon Sep 17 00:00:00 2001 From: Fred KISSIE Date: Fri, 6 Mar 2026 04:03:25 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20show=20list=20of=20resourc?= =?UTF-8?q?es=20on=20policy=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routers/policy/listResourcePolicies.ts | 54 +++++++++++++++++-- server/routers/resource/types.ts | 13 +++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/server/private/routers/policy/listResourcePolicies.ts b/server/private/routers/policy/listResourcePolicies.ts index 72d4ff39d..a10cfb4fb 100644 --- a/server/private/routers/policy/listResourcePolicies.ts +++ b/server/private/routers/policy/listResourcePolicies.ts @@ -11,11 +11,20 @@ * This file is not licensed under the AGPLv3. */ -import { db, resourcePolicies, rolePolicies, userPolicies } from "@server/db"; +import { + db, + resourcePolicies, + resources, + rolePolicies, + userPolicies +} from "@server/db"; import response from "@server/lib/response"; import logger from "@server/logger"; import { OpenAPITags, registry } from "@server/openApi"; -import type { ListResourcePoliciesResponse } from "@server/routers/resource/types"; +import type { + ListResourcePoliciesResponse, + ResourcePolicyWithResources +} from "@server/routers/resource/types"; import HttpCode from "@server/types/HttpCode"; import { and, asc, eq, inArray, like, or, sql } from "drizzle-orm"; import { NextFunction, Request, Response } from "express"; @@ -191,9 +200,48 @@ export async function listResourcePolicies( countQuery ]); + const attachedResources = + rows.length === 0 + ? [] + : await db + .select({ + resourceId: resources.resourceId, + name: resources.name, + fullDomain: resources.fullDomain, + resourcePolicyId: resources.resourcePolicyId + }) + .from(resources) + .where( + inArray( + resources.resourcePolicyId, + rows.map((row) => row.resourcePolicyId) + ) + ); + const entries: ResourcePolicyWithResources[] = []; + + // avoids TS issues with reduce/never[] + const map = new Map(); + + for (const row of rows) { + let entry = map.get(row.resourcePolicyId); + if (!entry) { + entry = { + ...row, + resources: [] + }; + map.set(row.resourcePolicyId, entry); + } + + entry.resources = attachedResources.filter( + (r) => r.resourcePolicyId === entry?.resourcePolicyId + ); + } + + const policiesList = Array.from(map.values()); + return response(res, { data: { - policies: rows, + policies: policiesList, pagination: { total: totalCount, pageSize, diff --git a/server/routers/resource/types.ts b/server/routers/resource/types.ts index 223154a01..c79e78d69 100644 --- a/server/routers/resource/types.ts +++ b/server/routers/resource/types.ts @@ -1,4 +1,4 @@ -import type { ResourcePolicy } from "@server/db"; +import type { Resource, ResourcePolicy } from "@server/db"; import type { PaginatedResponse } from "@server/types/Pagination"; export type GetMaintenanceInfoResponse = { @@ -12,8 +12,13 @@ export type GetMaintenanceInfoResponse = { maintenanceEstimatedTime: string | null; }; +export type ResourcePolicyWithResources = Pick< + ResourcePolicy, + "resourcePolicyId" | "niceId" | "name" | "orgId" +> & { + resources: Array>; +}; + export type ListResourcePoliciesResponse = PaginatedResponse<{ - policies: Array< - Pick - >; + policies: Array; }>;