Skip to content

Commit

Permalink
ORV2-2684 - FE:User Manage Applications in Review (#1594)
Browse files Browse the repository at this point in the history
Co-authored-by: GlenAOT <[email protected]>
Co-authored-by: zgong-gov <[email protected]>
  • Loading branch information
3 people authored Sep 16, 2024
1 parent 5c59222 commit c1ea3f4
Show file tree
Hide file tree
Showing 21 changed files with 890 additions and 96 deletions.
2 changes: 1 addition & 1 deletion frontend/src/common/components/banners/InfoBcGovBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const InfoBcGovBanner = ({
additionalInfo,
className,
}: {
msg: string;
msg: string | JSX.Element;
additionalInfo?: JSX.Element;
className?: string;
}) => (
Expand Down
147 changes: 79 additions & 68 deletions frontend/src/common/components/table/OnRouteBCTableRowActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ export const OnRouteBCTableRowActions = ({
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const isMenuOpen = Boolean(anchorEl);

const actionsButtonPressedClassName =
isMenuOpen ? " onroutebc-table-row-actions__button--pressed" : "";
const actionsButtonPressedClassName = isMenuOpen
? " onroutebc-table-row-actions__button--pressed"
: "";

const handleOpenActionsMenu = useCallback((event: MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
}, []);
const handleOpenActionsMenu = useCallback(
(event: MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
},
[],
);

const handleCloseActionsMenu = () => {
setAnchorEl(null);
Expand All @@ -42,69 +46,76 @@ export const OnRouteBCTableRowActions = ({
};

return (
<div className="onroutebc-table-row-actions">
<Tooltip
title="Actions"
classes={{
popper: "popper onroutebc-table-row-actions__popper",
tooltip: "tooltip",
tooltipPlacementBottom: "tooltip--bottom",
}}
>
<IconButton
className={`onroutebc-table-row-actions__button ${actionsButtonPressedClassName}`}
classes={{
disabled: "onroutebc-table-row-actions__button--disabled",
}}
aria-label="Actions"
id="actions-button"
aria-controls={isMenuOpen ? "actions-menu" : undefined}
aria-expanded={isMenuOpen ? "true" : undefined}
aria-haspopup="true"
onClick={handleOpenActionsMenu}
disabled={disabled}
>
<FontAwesomeIcon
icon={faEllipsisVertical}
className="onroutebc-table-row-actions__icon"
/>
</IconButton>
</Tooltip>
<>
{
// if there are no options, return null to prevent returning an empty menu
options.length > 0 ? (
<div className="onroutebc-table-row-actions">
<Tooltip
title="Actions"
classes={{
popper: "popper onroutebc-table-row-actions__popper",
tooltip: "tooltip",
tooltipPlacementBottom: "tooltip--bottom",
}}
>
<IconButton
className={`onroutebc-table-row-actions__button ${actionsButtonPressedClassName}`}
classes={{
disabled: "onroutebc-table-row-actions__button--disabled",
}}
aria-label="Actions"
id="actions-button"
aria-controls={isMenuOpen ? "actions-menu" : undefined}
aria-expanded={isMenuOpen ? "true" : undefined}
aria-haspopup="true"
onClick={handleOpenActionsMenu}
disabled={disabled}
>
<FontAwesomeIcon
icon={faEllipsisVertical}
className="onroutebc-table-row-actions__icon"
/>
</IconButton>
</Tooltip>

<Menu
className="onroutebc-table-row-actions__menu"
id="actions-menu"
MenuListProps={{
"aria-labelledby": "actions-button",
}}
anchorEl={anchorEl}
anchorOrigin={{
horizontal: "right",
vertical: "bottom",
}}
transformOrigin={{
horizontal: "right",
vertical: "top",
}}
open={isMenuOpen}
onClose={handleCloseActionsMenu}
slotProps={{
paper: {
className: "onroutebc-table-row-actions__paper",
},
}}
>
{options.map((option) => (
<MenuItem
key={`option-${option.value}`}
className="onroutebc-table-row-actions__menu-item"
onClick={onClickOption}
data-option-value={option.value}
>
{option.label}
</MenuItem>
))}
</Menu>
</div>
<Menu
className="onroutebc-table-row-actions__menu"
id="actions-menu"
MenuListProps={{
"aria-labelledby": "actions-button",
}}
anchorEl={anchorEl}
anchorOrigin={{
horizontal: "right",
vertical: "bottom",
}}
transformOrigin={{
horizontal: "right",
vertical: "top",
}}
open={isMenuOpen}
onClose={handleCloseActionsMenu}
slotProps={{
paper: {
className: "onroutebc-table-row-actions__paper",
},
}}
>
{options.map((option) => (
<MenuItem
key={`option-${option.value}`}
className="onroutebc-table-row-actions__menu-item"
onClick={onClickOption}
data-option-value={option.value}
>
{option.label}
</MenuItem>
))}
</Menu>
</div>
) : null
}
</>
);
};
8 changes: 6 additions & 2 deletions frontend/src/common/constants/bannerMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ export const BANNER_MESSAGES = {
POLICY_REMINDER:
"The applicant is responsible for ensuring they are following Legislation, policies, standards and guidelines in the operation of a commercial transportation business in British Columbia.",
CANNOT_FIND_VEHICLE: "Can't find a vehicle from your inventory?",
ISSUED_PERMIT_NUMBER_7_YEARS: "Enter any Permit No. issued to the above Client No. in the last 7 years",
SELECT_VEHICLES_LOA: "Only vehicles in the Vehicle Inventory can be designated to LOA(s).",
ISSUED_PERMIT_NUMBER_7_YEARS:
"Enter any Permit No. issued to the above Client No. in the last 7 years",
SELECT_VEHICLES_LOA:
"Only vehicles in the Vehicle Inventory can be designated to LOA(s).",
SELECT_VEHICLES_LOA_INFO:
"If you do not see the vehicle(s) you wish to designate here, please make sure you add them to the client's Vehicle Inventory first and come back to this page.",
REJECTED_APPLICATIONS:
"Rejected applications appear in Applications in Progress.",
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export const APPLICATIONS_API_ROUTES = {
DELETE: (companyId: string) => APPLICATIONS_API_BASE(companyId),
};

export const APPLICATION_QUEUE_API_ROUTES = {
UPDATE_QUEUE_STATUS: (companyId: string, applicationId: string) =>
`${APPLICATIONS_API_BASE(companyId)}/${applicationId}/queue/status`,
};

export const PERMITS_API_ROUTES = {
BASE: (companyId: string) => PERMITS_API_BASE(companyId),
GET: (companyId: string) => PERMITS_API_BASE(companyId),
Expand Down
54 changes: 50 additions & 4 deletions frontend/src/features/permits/apiManager/permitsAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
} from "../types/application";

import {
APPLICATION_QUEUE_API_ROUTES,
APPLICATIONS_API_ROUTES,
PAYMENT_API_ROUTES,
PERMITS_API_ROUTES,
Expand All @@ -63,6 +64,7 @@ import {
VoidPermitResponseData,
} from "../pages/Void/types/VoidPermit";
import { EmailNotificationType } from "../types/EmailNotificationType";
import { CaseActivityType } from "../types/CaseActivityType";

/**
* Create a new application.
Expand Down Expand Up @@ -116,17 +118,28 @@ const getApplications = async (
orderBy = [],
}: PaginationAndFilters,
pendingPermitsOnly?: boolean,
applicationsInQueueOnly?: boolean,
): Promise<PaginatedResponse<ApplicationListItem>> => {
const companyId = getDefaultRequiredVal("", getCompanyIdFromSession());
const applicationsURL = new URL(APPLICATIONS_API_ROUTES.GET(companyId));

// API pagination index starts at 1. Hence page + 1.
applicationsURL.searchParams.set("page", `${page + 1}`);
applicationsURL.searchParams.set("take", `${take}`);
applicationsURL.searchParams.set(
"pendingPermits",
`${Boolean(pendingPermitsOnly)}`,
);

if (typeof pendingPermitsOnly !== "undefined") {
applicationsURL.searchParams.set(
"pendingPermits",
`${Boolean(pendingPermitsOnly)}`,
);
}

if (typeof applicationsInQueueOnly !== "undefined") {
applicationsURL.searchParams.set(
"applicationsInQueue",
`${Boolean(applicationsInQueueOnly)}`,
);
}

if (searchString) {
applicationsURL.searchParams.set("searchString", searchString);
Expand Down Expand Up @@ -192,6 +205,16 @@ export const getPendingPermits = async (
return await getApplications(paginationFilters, true);
};

/**
* Fetch all applications in queue.
* @return A list of applications in queue (PENDING_REVIEW, IN_REVIEW)
*/
export const getApplicationsInQueue = async (
paginationFilters: PaginationAndFilters,
): Promise<PaginatedResponse<ApplicationListItem>> => {
return await getApplications(paginationFilters, undefined, true);
};

/**
* Fetch application by its permit id.
* @param permitId permit id of the application to fetch
Expand Down Expand Up @@ -615,3 +638,26 @@ export const resendPermit = async ({
replaceEmptyValuesWithNull(data),
);
};

export const updateApplicationQueueStatus = async (
applicationId: string,
caseActivityType: CaseActivityType,
comment?: string,
) => {
const companyId = getDefaultRequiredVal("", getCompanyIdFromSession());

const data: any = {
caseActivityType,
};

// Conditionally include the comment property if it is given as an argument and not an empty string
if (comment && comment.trim() !== "") {
data.comment = [comment];
}

const response = await httpPOSTRequest(
APPLICATION_QUEUE_API_ROUTES.UPDATE_QUEUE_STATUS(companyId, applicationId),
data,
);
return response;
};
18 changes: 18 additions & 0 deletions frontend/src/features/permits/components/dashboard/PermitLists.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { StartApplicationAction } from "../../pages/Application/components/dashb
import { ActivePermitList } from "../permit-list/ActivePermitList";
import { ExpiredPermitList } from "../permit-list/ExpiredPermitList";
import { ApplicationsInProgressList } from "../permit-list/ApplicationsInProgressList";
import { ApplicationsInReviewList } from "../permit-list/ApplicationsInReviewList";
import { Nullable } from "../../../../common/types/common";
import { usePermissionMatrix } from "../../../../common/authentication/PermissionMatrix";
import { RenderIf } from "../../../../common/components/reusable/RenderIf";
Expand All @@ -16,12 +17,14 @@ export const PermitLists = React.memo(() => {
setApplicationsInProgressCount(count);
};
const tabs = [];

const showApplicationsInProgressTab = usePermissionMatrix({
permissionMatrixKeys: {
permissionMatrixFeatureKey: "MANAGE_PERMITS",
permissionMatrixFunctionKey: "VIEW_LIST_OF_APPLICATIONS_IN_PROGRESS",
},
});

if (showApplicationsInProgressTab) {
tabs.push({
label: "Applications in Progress",
Expand All @@ -33,6 +36,21 @@ export const PermitLists = React.memo(() => {
),
});
}

const showApplicationsInReviewTab = usePermissionMatrix({
permissionMatrixKeys: {
permissionMatrixFeatureKey: "MANAGE_PERMITS",
permissionMatrixFunctionKey: "VIEW_LIST_OF_APPLICATIONS_IN_REVIEW",
},
});

if (showApplicationsInReviewTab) {
tabs.push({
label: "Applications in Review",
component: <ApplicationsInReviewList />,
});
}

tabs.push(
{
label: "Active Permits",
Expand Down
Loading

0 comments on commit c1ea3f4

Please sign in to comment.