Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ORV2-2848 - FE: Staff Edit Application in the Queue #1784

Closed
wants to merge 17 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
85a1e57
remove need for ReviewApplicationInQueue and ApplicationInQueueReview…
glen-aot Dec 17, 2024
684a4cf
Merge remote-tracking branch 'origin/main'
glen-aot Dec 17, 2024
7c0a0b3
Pass claimant back to the FE
praju-aot Dec 17, 2024
039cb6e
create UnavailableApplicationModal
glen-aot Dec 18, 2024
90ff834
restore ApplicationInQueueReview component
glen-aot Dec 18, 2024
d0dd37b
explore claimed application error state
glen-aot Dec 23, 2024
9454016
remove example for calling BE in ApplicationForm.tsx
glen-aot Jan 13, 2025
1280cae
Merge remote-tracking branch 'origin/main' into ORV2-2848
praju-aot Jan 30, 2025
9bcab3a
add check for currentUser against application claimedBy in Applicatio…
glen-aot Jan 30, 2025
2ecf96d
change currentClaimant variable name to assignedUser to match backend
glen-aot Jan 30, 2025
4f2623e
add logic for checking current assignedUser to ApplicationsInQueueList
glen-aot Jan 31, 2025
718b3fd
Merge remote-tracking branch 'origin/main' into ORV2-2848
glen-aot Feb 3, 2025
fc4849d
prevent users from accidentally claiming an application fromn the app…
glen-aot Feb 3, 2025
be810be
update ApplicationReview test to render component with updated props
glen-aot Feb 4, 2025
a03af7a
update ApplicationsInQueueList to fix issue with claiming a claimed a…
glen-aot Feb 4, 2025
f865b78
prevent users from saving changes to an application when hitting Cont…
glen-aot Feb 4, 2025
cca6d1a
update ApplicationReview to handle Approve and Reject when an applica…
glen-aot Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
restore ApplicationInQueueReview component
glen-aot committed Dec 18, 2024
commit 90ff834a37a35972f0a1b860dc8138a14fbc38ce
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@use "../../../common/components/dashboard/Dashboard";

@include Dashboard.layout-box-style(".application-in-queue-review .breadcrumb");

.application-in-queue-review {
display: flex;
flex-direction: column;
}
180 changes: 180 additions & 0 deletions frontend/src/features/queue/components/ApplicationInQueueReview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";

import "./ApplicationInQueueReview.scss";
import { getDefaultRequiredVal } from "../../../common/helpers/util";
import { Nullable } from "../../../common/types/common";
import {
APPLICATION_QUEUE_ROUTES,
APPLICATION_STEPS,
IDIR_ROUTES,
} from "../../../routes/constants";
import { useCompanyInfoDetailsQuery } from "../../manageProfile/apiManager/hooks";
import { usePowerUnitSubTypesQuery } from "../../manageVehicles/hooks/powerUnits";
import { useTrailerSubTypesQuery } from "../../manageVehicles/hooks/trailers";
import { calculateFeeByDuration } from "../../permits/helpers/feeSummary";
import { PermitReview } from "../../permits/pages/Application/components/review/PermitReview";
import { Application } from "../../permits/types/application";
import { PERMIT_REVIEW_CONTEXTS } from "../../permits/types/PermitReviewContext";
import { DEFAULT_PERMIT_TYPE } from "../../permits/types/PermitType";
import { useFetchSpecialAuthorizations } from "../../settings/hooks/specialAuthorizations";
import { CASE_ACTIVITY_TYPES } from "../types/CaseActivityType";
import { QueueBreadcrumb } from "./QueueBreadcrumb";
import { RejectApplicationModal } from "./RejectApplicationModal";
import { useUpdateApplicationInQueueStatus } from "../hooks/hooks";
import { usePolicyEngine } from "../../policy/hooks/usePolicyEngine";
import { useCommodityOptions } from "../../permits/hooks/useCommodityOptions";

export const ApplicationInQueueReview = ({
applicationData,
}: {
applicationData?: Nullable<Application>;
}) => {
const companyId = getDefaultRequiredVal(0, applicationData?.companyId);
const applicationId = getDefaultRequiredVal("", applicationData?.permitId);

const { data: specialAuth } = useFetchSpecialAuthorizations(companyId);
const isNoFeePermitType = Boolean(specialAuth?.noFeeType);

const { data: companyInfo } = useCompanyInfoDetailsQuery(companyId);
const doingBusinessAs = companyInfo?.alternateName;

const permitType = getDefaultRequiredVal(
DEFAULT_PERMIT_TYPE,
applicationData?.permitType,
);
const fee = isNoFeePermitType
? "0"
: `${calculateFeeByDuration(
permitType,
getDefaultRequiredVal(0, applicationData?.permitData?.permitDuration),
)}`;

const navigate = useNavigate();

const policyEngine = usePolicyEngine();
const { commodityOptions } = useCommodityOptions(policyEngine, permitType);
const powerUnitSubTypesQuery = usePowerUnitSubTypesQuery();
const trailerSubTypesQuery = useTrailerSubTypesQuery();
const methods = useForm<Application>();

// For the confirmation checkboxes
// For Applications in Queue review, confirmation checkboxes are checked and disabled by default
const [allConfirmed, setAllConfirmed] = useState(true);
const [hasAttemptedSubmission, setHasAttemptedSubmission] = useState(false);

const handleEdit = () => {
navigate(APPLICATION_QUEUE_ROUTES.EDIT(companyId, applicationId), {
replace: true,
});
};

const isSuccess = (status?: number) => status === 201;

const {
mutateAsync: updateApplication,
data: updateApplicationResponse,
isPending: updateApplicationMutationPending,
} = useUpdateApplicationInQueueStatus();

const handleApprove = async (): Promise<void> => {
setHasAttemptedSubmission(true);

await updateApplication({
applicationId,
companyId,
caseActivityType: CASE_ACTIVITY_TYPES.APPROVED,
});
};

const [showRejectApplicationModal, setShowRejectApplicationModal] =
useState<boolean>(false);

const handleRejectButton = () => {
setShowRejectApplicationModal(true);
};

const handleReject = async (comment: string): Promise<void> => {
setHasAttemptedSubmission(true);

await updateApplication({
applicationId,
companyId,
caseActivityType: CASE_ACTIVITY_TYPES.REJECTED,
comment,
});
};

const updateApplicationResponseStatus = updateApplicationResponse?.status;

useEffect(() => {
if (isSuccess(updateApplicationResponseStatus)) {
navigate(IDIR_ROUTES.STAFF_HOME);
}
}, [updateApplicationResponseStatus, navigate]);

useEffect(() => {
window.scrollTo(0, 0);
}, []);

return (
<div className="application-in-queue-review">
<QueueBreadcrumb
applicationNumber={applicationData?.applicationNumber}
applicationStep={APPLICATION_STEPS.REVIEW}
/>

<FormProvider {...methods}>
<PermitReview
reviewContext={PERMIT_REVIEW_CONTEXTS.QUEUE}
permitType={permitType}
permitNumber={applicationData?.permitNumber}
applicationNumber={applicationData?.applicationNumber}
isAmendAction={false}
permitStartDate={applicationData?.permitData?.startDate}
permitDuration={applicationData?.permitData?.permitDuration}
permitExpiryDate={applicationData?.permitData?.expiryDate}
permitConditions={applicationData?.permitData?.commodities}
permittedCommodity={applicationData?.permitData?.permittedCommodity}
commodityOptions={commodityOptions}
createdDateTime={applicationData?.createdDateTime}
updatedDateTime={applicationData?.updatedDateTime}
companyInfo={companyInfo}
contactDetails={applicationData?.permitData?.contactDetails}
onEdit={handleEdit}
handleApproveButton={handleApprove}
updateApplicationMutationPending={updateApplicationMutationPending}
handleRejectButton={handleRejectButton}
allConfirmed={allConfirmed}
setAllConfirmed={setAllConfirmed}
hasAttemptedCheckboxes={hasAttemptedSubmission}
powerUnitSubTypes={powerUnitSubTypesQuery.data}
trailerSubTypes={trailerSubTypesQuery.data}
vehicleDetails={applicationData?.permitData?.vehicleDetails}
vehicleWasSaved={
applicationData?.permitData?.vehicleDetails?.saveVehicle
}
vehicleConfiguration={
applicationData?.permitData?.vehicleConfiguration
}
route={applicationData?.permitData?.permittedRoute}
applicationNotes={applicationData?.permitData?.applicationNotes}
doingBusinessAs={doingBusinessAs}
calculatedFee={fee}
applicationRejectionHistory={applicationData?.rejectionHistory}
isStaffUser={true}
/>
</FormProvider>

{showRejectApplicationModal ? (
<RejectApplicationModal
showModal={showRejectApplicationModal}
onCancel={() => setShowRejectApplicationModal(false)}
onConfirm={handleReject}
isPending={updateApplicationMutationPending}
/>
) : null}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -3,14 +3,14 @@ import { Navigate, useParams } from "react-router-dom";
import { Banner } from "../../../common/components/dashboard/components/banner/Banner";
import { Loading } from "../../../common/pages/Loading";
import { useApplicationDetailsQuery } from "../../permits/hooks/hooks";
import { ApplicationInQueueReview } from "../components/ApplicationInQueueReview";
import {
applyWhenNotNullable,
getDefaultRequiredVal,
} from "../../../common/helpers/util";
import { ERROR_ROUTES } from "../../../routes/constants";
import { deserializeApplicationResponse } from "../../permits/helpers/serialize/deserializeApplication";
import { UniversalUnexpected } from "../../../common/pages/UniversalUnexpected";
import { ApplicationInQueueReview } from "../components/ApplicationInQueueReview";

export const ReviewApplicationInQueue = () => {
const { companyId: companyIdParam, permitId: permitIdParam } = useParams();
Loading