From f67536f76b1f9b87e7ff2677d64c264f311f456e Mon Sep 17 00:00:00 2001 From: Atul Tameshwari Date: Tue, 4 Aug 2026 17:11:20 +0530 Subject: [PATCH] feat(api): enhance workspace module query to include member IDs Added an annotation to the WorkspaceModulesEndpoint to aggregate member IDs into an array, ensuring that only active members are included. This change improves the data structure returned by the API, allowing for better handling of member information in the frontend. Updated the corresponding utility function to handle potential null values for member IDs. --- apps/api/plane/app/views/workspace/module.py | 18 +++++++++++++++++- packages/utils/src/module.ts | 6 +++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/api/plane/app/views/workspace/module.py b/apps/api/plane/app/views/workspace/module.py index ea217809b99..0ace291286e 100644 --- a/apps/api/plane/app/views/workspace/module.py +++ b/apps/api/plane/app/views/workspace/module.py @@ -3,7 +3,10 @@ # See the LICENSE file for details. # Django imports -from django.db.models import Prefetch, Q, Count +from django.contrib.postgres.aggregates import ArrayAgg +from django.contrib.postgres.fields import ArrayField +from django.db.models import Prefetch, Q, Count, UUIDField, Value +from django.db.models.functions import Coalesce # Third party modules from rest_framework import status @@ -109,6 +112,19 @@ def get(self, request, slug): distinct=True, ) ) + .annotate( + member_ids=Coalesce( + ArrayAgg( + "members__id", + distinct=True, + filter=Q( + members__id__isnull=False, + modulemember__deleted_at__isnull=True, + ), + ), + Value([], output_field=ArrayField(UUIDField())), + ) + ) .order_by(self.kwargs.get("order_by", "-created_at")) ) diff --git a/packages/utils/src/module.ts b/packages/utils/src/module.ts index c4468361078..bd961203085 100644 --- a/packages/utils/src/module.ts +++ b/packages/utils/src/module.ts @@ -30,8 +30,8 @@ export const orderModules = (modules: IModule[], orderByKey: TModuleOrderByOptio let orderedModules: IModule[] = []; if (modules.length === 0 || !orderByKey) return []; - if (orderByKey === "name") orderedModules = [...modules].sort((a, b) => naturalSort(a.name, b.name)); - if (orderByKey === "-name") orderedModules = [...modules].sort((a, b) => naturalSort(b.name, a.name)); + if (orderByKey === "name") orderedModules = [...modules].toSorted((a, b) => naturalSort(a.name, b.name)); + if (orderByKey === "-name") orderedModules = [...modules].toSorted((a, b) => naturalSort(b.name, a.name)); if (["progress", "-progress"].includes(orderByKey)) orderedModules = sortBy(modules, [ (m) => { @@ -71,7 +71,7 @@ export const shouldFilterModule = ( if (filterKey === "lead" && filters.lead && filters.lead.length > 0) fallsInFilters = fallsInFilters && filters.lead.includes(`${module.lead_id}`); if (filterKey === "members" && filters.members && filters.members.length > 0) { - const memberIds = module.member_ids; + const memberIds = module.member_ids ?? []; fallsInFilters = fallsInFilters && filters.members.some((memberId) => memberIds.includes(memberId)); } if (filterKey === "start_date" && filters.start_date && filters.start_date.length > 0) {