Skip to content

Commit

Permalink
feat: ORV2-1781 Permit Search and Sort through API (#964)
Browse files Browse the repository at this point in the history
  • Loading branch information
krishnan-aot authored Dec 27, 2023
1 parent 4bec372 commit ddc7ff7
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 20 deletions.
36 changes: 36 additions & 0 deletions frontend/src/common/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,46 @@ export type PaginationOptions = {
page: number;
/**
* The number of items in the current page.
* Max. value is 25.
*/
take: number;
};

/**
* The config for sorting data.
*/
export type SortingConfig = {
/**
* The field to order by.
*/
orderBy: string;
/**
* Boolean indicating if the sort is in descending order.
* If not given a value, defaulted to false.
*/
descending?: boolean;
};

/**
* Additional data filters that could be used for
* filtering data further.
*/
export type DataFilterOptions = {
/**
* The search value entered by the user.
*/
searchValue?: string;
/**
* The sorting configuration selected by the user.
*/
sorting?: Array<SortingConfig>;
};

/**
* The options for pagination and filtering data.
*/
export type PaginationAndFilters = PaginationOptions & DataFilterOptions;

/**
* A generic paginated response structure for all the paginated responses from APIs.
*/
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/features/idir/search/api/idirSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { VEHICLES_URL } from "../../../../common/apiManager/endpoints/endpoints"
import { httpGETRequest } from "../../../../common/apiManager/httpRequestHandler";
import {
PaginatedResponse,
PaginationOptions,
PaginationOptions
} from "../../../../common/types/common";
import { Permit } from "../../../permits/types/permit";
import { SearchFields } from "../types/types";
Expand All @@ -19,6 +19,8 @@ export const getDataBySearch = (
const searchURL = new URL(`${VEHICLES_URL}/${searchEntity}/ppc/search`);
searchURL.searchParams.set("searchColumn", searchByFilter);
searchURL.searchParams.set("searchString", searchValue);

// API pagination index starts at 1. Hence page + 1.
searchURL.searchParams.set("page", (page + 1).toString());
searchURL.searchParams.set("take", take.toString());
return httpGETRequest(searchURL.toString()).then((response) => response.data);
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/features/permits/apiManager/permitsAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { mapApplicationToApplicationRequestData } from "../helpers/mappers";
import { IssuePermitsResponse, Permit } from "../types/permit";
import {
PaginatedResponse,
PaginationOptions,
PaginationAndFilters,
RequiredOrNull,
} from "../../../common/types/common";
import { PERMIT_STATUSES } from "../types/PermitStatus";
Expand Down Expand Up @@ -347,11 +347,12 @@ export const getCurrentAmendmentApplication = async (
/**
* Retrieve the list of active or expired permits.
* @param expired If set to true, expired permits will be retrieved.
* @param paginationOptions The pagination and filters applied.
* @returns A list of permits.
*/
export const getPermits = async (
{ expired = false } = {},
{ page = 0, take = 10 }: PaginationOptions,
{ page = 0, take = 10, searchValue, sorting = [] }: PaginationAndFilters,
): Promise<PaginatedResponse<Permit>> => {
const companyId = getDefaultRequiredVal("", getCompanyIdFromSession());
const permitsURL = new URL(PERMITS_API_ROUTES.GET);
Expand All @@ -361,8 +362,15 @@ export const getPermits = async (
if (expired) {
permitsURL.searchParams.set("expired", "true");
}
// API pagination index starts at 1. Hence page + 1.
permitsURL.searchParams.set("page", (page + 1).toString());
permitsURL.searchParams.set("take", take.toString());
if (searchValue) {
permitsURL.searchParams.set("searchValue", searchValue);
}
if (sorting.length > 0) {
permitsURL.searchParams.set("sorting", JSON.stringify(sorting));
}
const permits = await httpGETRequest(permitsURL.toString())
.then((response) => {
const paginatedResponseObject = getDefaultRequiredVal(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
MRT_GlobalFilterTextField,
MRT_PaginationState,
MRT_Row,
MRT_SortingState,
MRT_TableInstance,
MaterialReactTable,
useMaterialReactTable,
Expand Down Expand Up @@ -38,20 +39,42 @@ export const BasePermitList = ({
pageIndex: 0,
pageSize: 10,
});
const [globalFilter, setGlobalFilter] = useState<string>("");
const [sorting, setSorting] = useState<MRT_SortingState>([]);

const permitsQuery = useQuery({
queryKey: ["permits", isExpired, pagination.pageIndex, pagination.pageSize],
queryKey: [
"permits",
isExpired,
globalFilter,
pagination.pageIndex,
pagination.pageSize,
sorting,
],
queryFn: () =>
getPermits(
{ expired: isExpired },
{ page: pagination.pageIndex, take: pagination.pageSize },
{
page: pagination.pageIndex,
take: pagination.pageSize,
searchValue: globalFilter,
sorting:
sorting.length > 0
? [
{
orderBy: sorting.at(0)?.id as string,
descending: Boolean(sorting.at(0)?.desc),
},
]
: [],
},
),
keepPreviousData: true,
staleTime: FIVE_MINUTES,
retry: 1,
});

const { data, isError, isInitialLoading, isLoading } = permitsQuery;
const { data, isError, isLoading } = permitsQuery;

const table = useMaterialReactTable({
...defaultTableOptions,
Expand All @@ -65,10 +88,11 @@ export const BasePermitList = ({
state: {
...defaultTableStateOptions,
showAlertBanner: isError,
showProgressBars: isInitialLoading,
showProgressBars: isLoading,
columnVisibility: { applicationId: true },
isLoading: isInitialLoading || isLoading,
isLoading: isLoading,
pagination,
globalFilter,
},
renderTopToolbar: useCallback(
({ table }: { table: MRT_TableInstance<Permit> }) => (
Expand All @@ -85,9 +109,13 @@ export const BasePermitList = ({
[],
),
autoResetPageIndex: false,
manualFiltering: true,
manualPagination: true,
manualSorting: true,
rowCount: data?.meta?.totalItems ?? 0,
pageCount: data?.meta?.pageCount ?? 0,
onSortingChange: setSorting,
onGlobalFilterChange: setGlobalFilter,
onPaginationChange: setPagination,
enablePagination: true,
enableBottomToolbar: true,
Expand Down
19 changes: 7 additions & 12 deletions frontend/src/features/permits/components/permit-list/Columns.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import Link from "@mui/material/Link";
import { MRT_ColumnDef } from "material-react-table";
import { formatCellValuetoDatetime } from "../../../../common/constants/defaultTableOptions";
import { viewPermitPdf } from "../../helpers/permitPDFHelper";
import { Permit } from "../../types/permit";
import { PermitChip } from "./PermitChip";
import {
dateTimeStringSortingFn,
formatCellValuetoDatetime,
} from "../../../../common/constants/defaultTableOptions";

/**
* The column definition for Permits.
*/
export const PermitsColumnDefinition: MRT_ColumnDef<Permit>[] = [
{
accessorKey: "permitNumber",
id: "permitNumber",
header: "Permit #",
enableSorting: true,
sortingFn: "alphanumeric",
size: 500,
accessorFn: (row) => row.permitNumber,
Cell: (props: { row: any; renderedCellValue: any }) => {
Expand All @@ -36,28 +33,27 @@ export const PermitsColumnDefinition: MRT_ColumnDef<Permit>[] = [
},
{
accessorKey: "permitType",
id: "permitType",
header: "Permit Type",
enableSorting: true,
sortingFn: "alphanumeric",
},
{
accessorFn: (row) => `${row.permitData.vehicleDetails?.unitNumber ?? ""}`,
id: "unitNumber",
header: "Unit #",
enableSorting: true,
sortingFn: "alphanumeric",
},
{
accessorKey: "permitData.vehicleDetails.plate",
header: "Plate",
id: "plate",
enableSorting: true,
sortingFn: "alphanumeric",
},
{
accessorKey: "permitData.startDate",
id: "startDate",
header: "Permit Start Date",
enableSorting: true,
sortingFn: dateTimeStringSortingFn,
Cell: (props: { cell: any }) => {
const formattedDate = formatCellValuetoDatetime(props.cell.getValue());
return formattedDate;
Expand All @@ -66,8 +62,8 @@ export const PermitsColumnDefinition: MRT_ColumnDef<Permit>[] = [
{
accessorKey: "permitData.expiryDate",
header: "Permit End Date",
id: "expiryDate",
enableSorting: true,
sortingFn: dateTimeStringSortingFn,
Cell: (props: { cell: any }) => {
const formattedDate = formatCellValuetoDatetime(props.cell.getValue());
return formattedDate;
Expand All @@ -76,10 +72,9 @@ export const PermitsColumnDefinition: MRT_ColumnDef<Permit>[] = [
{
accessorFn: (row) =>
`${row.permitData.contactDetails?.firstName} ${row.permitData.contactDetails?.lastName} `,
id: "application",
id: "applicant",
header: "Applicant",
enableSorting: true,
sortingFn: "alphanumericCaseSensitive",
},
];

Expand Down

0 comments on commit ddc7ff7

Please sign in to comment.