diff --git a/apiserver/bll/project/project_bll.py b/apiserver/bll/project/project_bll.py index 3968dd5..4ac0f24 100644 --- a/apiserver/bll/project/project_bll.py +++ b/apiserver/bll/project/project_bll.py @@ -17,6 +17,7 @@ from typing import ( Any, ) +from boltons.iterutils import partition from mongoengine import Q, Document from apiserver import database @@ -511,14 +512,16 @@ class ProjectBLL: project_ids: Sequence[str], specific_state: Optional[EntityVisibility] = None, include_children: bool = True, - return_hidden_children: bool = False, + search_hidden: bool = False, filter_: Mapping[str, Any] = None, ) -> Tuple[Dict[str, dict], Dict[str, dict]]: if not project_ids: return {}, {} child_projects = ( - _get_sub_projects(project_ids, _only=("id", "name", "system_tags")) + _get_sub_projects( + project_ids, _only=("id", "name"), search_hidden=search_hidden + ) if include_children else {} ) @@ -627,24 +630,9 @@ class ProjectBLL: for project in project_ids } - def filter_child_projects(project: str) -> Sequence[Project]: - non_filtered_children = child_projects.get(project, []) - if not non_filtered_children or return_hidden_children: - return non_filtered_children - - return [ - c - for c in non_filtered_children - if not c.system_tags - or EntityVisibility.hidden.value not in c.system_tags - ] - children = { project: sorted( - [ - {"id": c.id, "name": c.name} - for c in filter_child_projects(project) - ], + [{"id": c.id, "name": c.name} for c in child_projects.get(project, [])], key=itemgetter("name"), ) for project in project_ids @@ -829,7 +817,11 @@ class ProjectBLL: raise errors.bad_request.ValidationError( f"List of strings expected for the field: {field}" ) - conditions[field] = {"$in": field_filter} + exclude, include = partition(field_filter, lambda x: x.startswith("-")) + conditions[field] = { + **({"$in": include} if include else {}), + **({"$nin": [e[1:] for e in exclude]} if exclude else {}), + } return conditions diff --git a/apiserver/bll/project/sub_projects.py b/apiserver/bll/project/sub_projects.py index 0c46a6e..2d2f305 100644 --- a/apiserver/bll/project/sub_projects.py +++ b/apiserver/bll/project/sub_projects.py @@ -4,6 +4,7 @@ from typing import Tuple, Optional, Sequence, Mapping from apiserver import database from apiserver.apierrors import errors +from apiserver.database.model import EntityVisibility from apiserver.database.model.project import Project name_separator = "/" @@ -100,12 +101,17 @@ def _get_writable_project_from_name( def _get_sub_projects( - project_ids: Sequence[str], _only: Sequence[str] = ("id", "path") + project_ids: Sequence[str], + _only: Sequence[str] = ("id", "path"), + search_hidden=True, ) -> Mapping[str, Sequence[Project]]: """ Return the list of child projects of all the levels for the parent project ids """ - qs = Project.objects(path__in=project_ids) + query = dict(path__in=project_ids) + if not search_hidden: + query["system_tags__nin"] = [EntityVisibility.hidden.value] + qs = Project.objects(**query) if _only: _only = set(_only) | {"path"} qs = qs.only(*_only) diff --git a/apiserver/services/projects.py b/apiserver/services/projects.py index c22247d..3991f89 100644 --- a/apiserver/services/projects.py +++ b/apiserver/services/projects.py @@ -154,7 +154,7 @@ def get_all_ex(call: APICall, company_id: str, request: ProjectsGetRequest): project_ids=list(project_ids), specific_state=request.stats_for_state, include_children=request.stats_with_children, - return_hidden_children=request.search_hidden, + search_hidden=request.search_hidden, filter_=request.include_stats_filter, )