diff --git a/submit-api/src/submit_api/models/queries/project.py b/submit-api/src/submit_api/models/queries/project.py
index a7994236..3b8eac87 100644
--- a/submit-api/src/submit_api/models/queries/project.py
+++ b/submit-api/src/submit_api/models/queries/project.py
@@ -13,6 +13,7 @@
# limitations under the License.
"""Model to handle all complex operations related to User."""
+from sqlalchemy import or_
from submit_api.models import AccountProject, Project, db
from submit_api.models.account_project_search_options import AccountProjectSearchOptions
from submit_api.models.package import Package
@@ -33,11 +34,13 @@ def get_projects_by_proponent_id(cls, proponent_id: int):
return query.all()
@classmethod
- def get_projects_by_account_id(cls, account_id: int, search_options: AccountProjectSearchOptions = None):
+ def get_filtered_projects(cls, account_id: int = None, search_options: AccountProjectSearchOptions = None):
"""Find projects by account_id with optional search and pagination."""
- query = db.session.query(AccountProject).filter(
- AccountProject.account_id == account_id,
- ).join(AccountProject.project)
+ query = db.session.query(AccountProject).join(AccountProject.project)
+
+ # Apply account_id filter only if provided
+ if account_id is not None:
+ query = query.filter(AccountProject.account_id == account_id)
# Apply search filters if provided
if search_options and any(bool(search_option) for search_option in search_options.__dict__.values()):
@@ -52,7 +55,7 @@ def filter_by_search_criteria(cls, project_query, search_options: AccountProject
package_query = db.session.query(Package)
if search_options.search_text:
- package_query = cls._filter_by_submission_name(package_query, search_options.search_text)
+ package_query = cls._filter_by_search_text(package_query, search_options.search_text)
if search_options.status:
package_query = cls._filter_by_submission_status(package_query, search_options.status)
if search_options.submitted_on_start or search_options.submitted_on_end:
@@ -65,14 +68,19 @@ def filter_by_search_criteria(cls, project_query, search_options: AccountProject
project_query = project_query.join(Package).filter(
Package.id.in_(filtered_package_ids)).options(
- db.contains_eager(AccountProject.packages))
+ db.contains_eager(AccountProject._packages))
return project_query
@classmethod
- def _filter_by_submission_name(cls, query, search_text):
+ def _filter_by_search_text(cls, query, search_text):
"""Filter by search text across package name."""
- return query.filter(Package.name.ilike(f"%{search_text}%"))
+ return query.filter(
+ or_(
+ Package.name.ilike(f"%{search_text}%"),
+ Project.name.ilike(f"%{search_text}%")
+ )
+ )
@classmethod
def _filter_by_submission_status(cls, query, statuses):
diff --git a/submit-api/src/submit_api/resources/staff/project.py b/submit-api/src/submit_api/resources/staff/project.py
index 8ed8d96d..99f1b6ee 100644
--- a/submit-api/src/submit_api/resources/staff/project.py
+++ b/submit-api/src/submit_api/resources/staff/project.py
@@ -14,10 +14,13 @@
"""API endpoints for managing a project resource."""
from http import HTTPStatus
+from flask import request
from flask_restx import Namespace, Resource, cors
from submit_api.auth import auth
+from submit_api.models.account_project_search_options import AccountProjectSearchOptions
+from submit_api.models.package import PackageStatus
from submit_api.resources.apihelper import Api as ApiHelper
from submit_api.schemas.project import StaffAccountProjectSchema
from submit_api.services.project_service import ProjectService
@@ -52,7 +55,19 @@ class AccountProjects(Resource):
@cors.crossdomain(origin="*")
def get():
"""Get all account projects."""
- account_projects = ProjectService.get_all_account_projects()
+ args = request.args
+ search_text = args.get('search_text')
+ submitted_on_start = args.get('submitted_on_start')
+ submitted_on_end = args.get('submitted_on_end')
+ status = list(map(PackageStatus, args.getlist('status[]')))
+ search_options = AccountProjectSearchOptions(
+ search_text=search_text,
+ submitted_on_start=submitted_on_start,
+ submitted_on_end=submitted_on_end,
+ status=status,
+ )
+
+ account_projects = ProjectService.get_all_account_projects(search_options)
return StaffAccountProjectSchema(many=True).dump(account_projects), HTTPStatus.OK
diff --git a/submit-api/src/submit_api/services/project_service.py b/submit-api/src/submit_api/services/project_service.py
index e617ee85..1d3b1230 100644
--- a/submit-api/src/submit_api/services/project_service.py
+++ b/submit-api/src/submit_api/services/project_service.py
@@ -17,7 +17,7 @@ def get_account_project_by_id(cls, account_project_id):
@classmethod
def get_projects_by_account_id(cls, account_id, search_options: AccountProjectSearchOptions):
"""Get projects by account id."""
- return ProjectQueries.get_projects_by_account_id(account_id, search_options)
+ return ProjectQueries.get_filtered_projects(account_id, search_options)
@classmethod
def get_projects_by_proponent_id(cls, proponent_id):
@@ -35,9 +35,9 @@ def bulk_add_projects(cls, account_id: int, project_ids: list):
return projects
@classmethod
- def get_all_account_projects(cls):
+ def get_all_account_projects(cls, search_options: AccountProjectSearchOptions):
"""Get projects by proponent id."""
- return AccountProjectModel.get_all()
+ return ProjectQueries.get_filtered_projects(None, search_options)
@classmethod
def get_all_account_projects_with_latest_packages(cls):
diff --git a/submit-web/src/components/Filters/ProjectFilters.tsx b/submit-web/src/components/Filters/ProjectFilters.tsx
index 65695396..eee792b2 100644
--- a/submit-web/src/components/Filters/ProjectFilters.tsx
+++ b/submit-web/src/components/Filters/ProjectFilters.tsx
@@ -7,7 +7,7 @@ import { useProjectFilters } from "./projectFilterStore";
import DateSubmittedFromFilter from "./DateSubmittedFromFilter";
import DateSubmittedToFilter from "./DateSubmittedToFilter";
-function ProjectFilters() {
+function ProjectFilters({userType}: {userType: string;}) {
const { resetFilters } = useProjectFilters();
return (
@@ -17,7 +17,7 @@ function ProjectFilters() {
sx={{ maxWidth: "1448px", justifyContent: "space-between" }}
>
-
+
diff --git a/submit-web/src/components/Filters/SearchFilter.tsx b/submit-web/src/components/Filters/SearchFilter.tsx
index fd642824..010e2c73 100644
--- a/submit-web/src/components/Filters/SearchFilter.tsx
+++ b/submit-web/src/components/Filters/SearchFilter.tsx
@@ -3,8 +3,9 @@ import { InputAdornment, IconButton, TextField } from "@mui/material";
import { Search, Clear } from "@mui/icons-material";
import { useProjectFilters } from "./projectFilterStore";
import { BCDesignTokens } from "epic.theme";
+import { USER_TYPE } from "@/models/User";
-export const SearchFilter = () => {
+export const SearchFilter = ({userType}: {userType: string;}) => {
const { filters, setFilters } = useProjectFilters();
const [searchText, setSearchText] = useState(filters.search_text);
@@ -27,13 +28,17 @@ export const SearchFilter = () => {
+
),
diff --git a/submit-web/src/components/Filters/StatusFilter.tsx b/submit-web/src/components/Filters/StatusFilter.tsx
index d2e6cbe2..377323ec 100644
--- a/submit-web/src/components/Filters/StatusFilter.tsx
+++ b/submit-web/src/components/Filters/StatusFilter.tsx
@@ -22,7 +22,7 @@ function StatusFilter() {
(status) => status.value,
),
});
- } else if (value.length <= 2) {
+ } else if (value.length <= 3) {
setFilters({ status: value });
}
};
diff --git a/submit-web/src/routes/proponent/_proponentLayout/projects/index.tsx b/submit-web/src/routes/proponent/_proponentLayout/projects/index.tsx
index 3dda4a52..8c37293f 100644
--- a/submit-web/src/routes/proponent/_proponentLayout/projects/index.tsx
+++ b/submit-web/src/routes/proponent/_proponentLayout/projects/index.tsx
@@ -9,6 +9,7 @@ import { notify } from "@/components/Shared/Snackbar/snackbarStore";
import { PageGrid } from "@/components/Shared/PageGrid";
import ProjectFilters from "@/components/Filters/ProjectFilters";
import { useProjectFilters } from "@/components/Filters/projectFilterStore";
+import { USER_TYPE } from "@/models/User";
export const Route = createFileRoute(
"/proponent/_proponentLayout/projects/",
@@ -42,7 +43,7 @@ export function ProjectsPage() {
return (
-
+
diff --git a/submit-web/src/routes/staff/_staffLayout/projects/index.tsx b/submit-web/src/routes/staff/_staffLayout/projects/index.tsx
index c62143a0..a34635b6 100644
--- a/submit-web/src/routes/staff/_staffLayout/projects/index.tsx
+++ b/submit-web/src/routes/staff/_staffLayout/projects/index.tsx
@@ -8,6 +8,7 @@ import { Grid } from "@mui/material";
import { createFileRoute, Navigate } from "@tanstack/react-router";
import { useEffect } from "react";
import { Else, If, Then } from "react-if";
+import { USER_TYPE } from "@/models/User";
export const Route = createFileRoute("/staff/_staffLayout/projects/")({
component: ProjectsPage,
@@ -37,7 +38,7 @@ function ProjectsPage() {
return (
-
+