From 82830fdfeec00efdbde0837afa81bf0b3499a0c4 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Mon, 13 May 2024 10:38:48 -0700 Subject: [PATCH 1/3] fix default sorting for funding year --- api/src/application/application.service.ts | 4 ++-- api/src/common/dto/get-applications.dto.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/application/application.service.ts b/api/src/application/application.service.ts index 8cde63b..42e529e 100644 --- a/api/src/application/application.service.ts +++ b/api/src/application/application.service.ts @@ -93,9 +93,9 @@ export class ApplicationService { if ( ['applicationType.name', 'assignedTo.displayName', 'status.name'].includes(query.orderBy) ) { - queryBuilder.orderBy({ [`${query.orderBy}`]: query.order }); + queryBuilder.orderBy(query.orderBy, query.order, 'NULLS LAST'); } else { - queryBuilder.orderBy({ [`app.${query.orderBy}`]: query.order }); + queryBuilder.orderBy(`app.${query.orderBy}`, query.order, 'NULLS LAST'); } } diff --git a/api/src/common/dto/get-applications.dto.ts b/api/src/common/dto/get-applications.dto.ts index bfd5ba8..e79a1e2 100644 --- a/api/src/common/dto/get-applications.dto.ts +++ b/api/src/common/dto/get-applications.dto.ts @@ -28,12 +28,12 @@ export class GetApplicationsDto extends PaginationDto { @IsOptional() @IsEnum(OrderByOptions) - order = OrderByOptions.ASC; + order = OrderByOptions.DESC; @ApiPropertyOptional({ enum: ApplicationSortOptions }) @IsOptional() @IsEnum(ApplicationSortOptions) - orderBy = ApplicationSortOptions.CONFIRMATION_ID; + orderBy = ApplicationSortOptions.FUNDING_YEAR; @IsOptional() @IsString() From c2005fdde0bc83ac13ee75d60f0072bcf54f6dbf Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Mon, 13 May 2024 11:34:40 -0700 Subject: [PATCH 2/3] add filer to funding year & status --- api/src/application/application.service.ts | 8 ++ api/src/common/dto/get-applications.dto.ts | 8 ++ .../application-dashboard.tsx | 73 +++++++++++++++++-- 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/api/src/application/application.service.ts b/api/src/application/application.service.ts index 42e529e..53eb38f 100644 --- a/api/src/application/application.service.ts +++ b/api/src/application/application.service.ts @@ -89,6 +89,14 @@ export class ApplicationService { }); } + if (query.fundingYear) { + queryBuilder.andWhere('app.fundingYear = :fundingYear', { fundingYear: query.fundingYear }); + } + + if (query.status) { + queryBuilder.andWhere('status.name = :status', { status: query.status }); + } + if (query.orderBy) { if ( ['applicationType.name', 'assignedTo.displayName', 'status.name'].includes(query.orderBy) diff --git a/api/src/common/dto/get-applications.dto.ts b/api/src/common/dto/get-applications.dto.ts index e79a1e2..7de4d2a 100644 --- a/api/src/common/dto/get-applications.dto.ts +++ b/api/src/common/dto/get-applications.dto.ts @@ -38,4 +38,12 @@ export class GetApplicationsDto extends PaginationDto { @IsOptional() @IsString() totalCost: string; + + @IsOptional() + @IsString() + fundingYear: string; + + @IsOptional() + @IsString() + status: string; } diff --git a/client/components/bcat-form-sections/application-dashboard.tsx b/client/components/bcat-form-sections/application-dashboard.tsx index db86292..2fb41c7 100644 --- a/client/components/bcat-form-sections/application-dashboard.tsx +++ b/client/components/bcat-form-sections/application-dashboard.tsx @@ -6,7 +6,7 @@ import { faTimes, faFilter } from '@fortawesome/free-solid-svg-icons'; import { useHttp } from '../../services/useHttp'; import { SetQueryParams } from '../../services/useQueryParams'; import { useRouter } from 'next/router'; -import { API_ENDPOINT } from '../../constants'; +import { API_ENDPOINT, ApplicationStatus } from '../../constants'; import { useDownloadXlsx } from 'services/useDownloadXlsx'; interface InputFilterProps { @@ -15,6 +15,10 @@ interface InputFilterProps { placeholder: string; } +interface SelectFilterProps extends InputFilterProps { + options: { name: string; value: string }[]; +} + const InputFilter: React.FC = ({ searchType, onChange, placeholder }) => { return ( = ({ searchType, onChange, placeho ); }; +const SelectFilter: React.FC = ({ + searchType, + onChange, + placeholder, + options, +}) => { + return ( + + ); +}; + export const ApplicationDashboard: React.FC = () => { const { push, query } = useRouter(); const router = useRouter(); @@ -40,6 +67,8 @@ export const ApplicationDashboard: React.FC = () => { searchApplicationType: query?.applicationType ?? '', searchAssignedTo: query?.assignedTo ?? '', searchConfirmationID: query?.confirmationId ?? '', + searchFundingYear: query?.fundingYear ?? '', + searchStatus: query?.status ?? '', searchTotalCost: '', totalApplications: 0, }); @@ -49,6 +78,8 @@ export const ApplicationDashboard: React.FC = () => { searchApplicationType, searchAssignedTo, searchConfirmationID, + searchFundingYear, + searchStatus, searchTotalCost, totalApplications, data, @@ -120,7 +151,9 @@ export const ApplicationDashboard: React.FC = () => { searchApplicationType.length === 0 && searchAssignedTo.length === 0 && searchConfirmationID.length == 0 && - searchTotalCost.length === 0; + searchTotalCost.length === 0 && + searchFundingYear == null && + searchStatus == null; return noValues; }; @@ -137,6 +170,8 @@ export const ApplicationDashboard: React.FC = () => { assignedTo: searchAssignedTo, confirmationId: searchConfirmationID, totalCost: searchTotalCost, + fundingYear: searchFundingYear, + status: searchStatus, }; SetQueryParams(push, query, params); @@ -151,6 +186,8 @@ export const ApplicationDashboard: React.FC = () => { searchAssignedTo: '', searchConfirmationID: '', searchTotalCost: '', + searchFundingYear: '', + searchStatus: '', })); const params = { ...query, @@ -159,6 +196,8 @@ export const ApplicationDashboard: React.FC = () => { assignedTo: '', confirmationId: '', totalCost: '', + fundingYear: '', + status: '', limit: 20, page: DEFAULT_QUERY.page, }; @@ -185,6 +224,30 @@ export const ApplicationDashboard: React.FC = () => {
Filter By:
+ setState(p => ({ ...p, searchFundingYear: e.target.value }))} + options={[ + { name: 'Funding Year', value: '' }, + { name: '2024/25', value: '2024/25' }, + { name: '2025/26', value: '2025/26' }, + { name: '2026/27', value: '2026/27' }, + ]} + /> + setState(p => ({ ...p, searchStatus: e.target.value }))} + options={[ + { name: 'Status', value: '' }, + { name: ApplicationStatus.RECEIVED, value: ApplicationStatus.RECEIVED }, + { name: ApplicationStatus.ASSIGNED, value: ApplicationStatus.ASSIGNED }, + { name: ApplicationStatus.APPROVED, value: ApplicationStatus.APPROVED }, + { name: ApplicationStatus.DENIED, value: ApplicationStatus.DENIED }, + { name: ApplicationStatus.WORKSHOP, value: ApplicationStatus.WORKSHOP }, + ]} + /> @@ -209,12 +272,6 @@ export const ApplicationDashboard: React.FC = () => { searchType={searchApplicationType} /> - setState(p => ({ ...p, searchTotalCost: e.target.value }))} - searchType={searchTotalCost} - /> - setState(p => ({ ...p, searchAssignedTo: e.target.value }))} From 4d33c2dc43785d54cc09855d68348b1c26c1613f Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Mon, 13 May 2024 11:36:57 -0700 Subject: [PATCH 3/3] fix when there is no value in select option --- .../components/bcat-form-sections/application-dashboard.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/components/bcat-form-sections/application-dashboard.tsx b/client/components/bcat-form-sections/application-dashboard.tsx index 2fb41c7..b8c5ee7 100644 --- a/client/components/bcat-form-sections/application-dashboard.tsx +++ b/client/components/bcat-form-sections/application-dashboard.tsx @@ -39,12 +39,13 @@ const SelectFilter: React.FC = ({ }) => { return (