Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
32 changes: 32 additions & 0 deletions api/src/utilities/application-export-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export const getExportHeaders = (
user.jurisdictions,
FeatureFlagEnum.disableWorkInRegion,
);
const enableApplicationStatus = doAnyJurisdictionHaveFeatureFlagSet(
user.jurisdictions,
FeatureFlagEnum.enableApplicationStatus,
);

const headers: CsvHeader[] = [
{
Expand Down Expand Up @@ -83,6 +87,34 @@ export const getExportHeaders = (
format: (val: string): string =>
formatLocalDate(val, dateFormat, timeZone ?? process.env.TIME_ZONE),
},
],
);

if (enableApplicationStatus) {
headers.push(
...[
{
path: 'status',
label: 'Application Status',
},
{
path: 'manualLotteryPositionNumber',
label: 'Lottery Position Number',
},
{
path: 'accessibleUnitWaitlistNumber',
label: 'Waitlist Position (Accessible Unit)',
},
{
path: 'conventionalUnitWaitlistNumber',
label: 'Waitlist Position (Conventional Unit)',
},
],
);
}

headers.push(
...[
{
path: 'applicant.firstName',
label: 'Primary Applicant First Name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import userEvent from "@testing-library/user-event"
import {
LanguagesEnum,
ApplicationStatusEnum,
ReviewOrderTypeEnum,
} from "@bloom-housing/shared-helpers/src/types/backend-swagger"
import { FormProviderWrapper } from "../../../../testUtils"
import { FormApplicationData } from "../../../../../src/components/applications/PaperApplicationForm/sections/FormApplicationData"
Expand Down Expand Up @@ -147,4 +148,74 @@ describe("<FormApplicationData>", () => {
expect((statusSelect as HTMLSelectElement).value).toBe(ApplicationStatusEnum.waitlistDeclined)
})
})

describe("Application status fields", () => {
it("renders waitlist fields when status is waitlist", async () => {
render(
<FormProviderWrapper>
<FormApplicationData enableApplicationStatus={true} />
</FormProviderWrapper>
)

const statusSelect = screen.getByLabelText(/status/i)
await userEvent.selectOptions(statusSelect, ApplicationStatusEnum.waitlist)

const auwlInput = screen.getByLabelText(/accessible unit waitlist \(AUWL\)/i)
const cuwlInput = screen.getByLabelText(/conventional unit waitlist \(CUWL\)/i)
expect(auwlInput).toBeInTheDocument()
expect(cuwlInput).toBeInTheDocument()
expect(auwlInput.closest(".hidden")).not.toBeInTheDocument()
expect(cuwlInput.closest(".hidden")).not.toBeInTheDocument()
expect(screen.queryByLabelText(/lottery number/i)).not.toBeInTheDocument()
})

it("renders waitlist fields when status is waitlistDeclined", async () => {
render(
<FormProviderWrapper>
<FormApplicationData enableApplicationStatus={true} />
</FormProviderWrapper>
)

const statusSelect = screen.getByLabelText(/status/i)
await userEvent.selectOptions(statusSelect, ApplicationStatusEnum.waitlistDeclined)

const auwlInput = screen.getByLabelText(/accessible unit waitlist \(AUWL\)/i)
const cuwlInput = screen.getByLabelText(/conventional unit waitlist \(CUWL\)/i)
expect(auwlInput).toBeInTheDocument()
expect(cuwlInput).toBeInTheDocument()
expect(auwlInput.closest(".hidden")).not.toBeInTheDocument()
expect(cuwlInput.closest(".hidden")).not.toBeInTheDocument()
})

it("does not render waitlist fields when status is not waitlist and no numbers are present", async () => {
render(
<FormProviderWrapper>
<FormApplicationData enableApplicationStatus={true} />
</FormProviderWrapper>
)

const statusSelect = screen.getByLabelText(/status/i)
await userEvent.selectOptions(statusSelect, ApplicationStatusEnum.submitted)

const auwlInput = screen.getByLabelText(/accessible unit waitlist/i)
const cuwlInput = screen.getByLabelText(/conventional unit waitlist/i)

// Check if the closest Grid.Cell has the hidden class
expect(auwlInput.closest(".hidden")).toBeInTheDocument()
expect(cuwlInput.closest(".hidden")).toBeInTheDocument()
})

it("renders lottery position field when reviewOrderType is lottery", () => {
render(
<FormProviderWrapper>
<FormApplicationData
enableApplicationStatus={true}
reviewOrderType={ReviewOrderTypeEnum.lottery}
/>
</FormProviderWrapper>
)

expect(screen.getByLabelText(/lottery number/i)).toBeInTheDocument()
})
})
})
1 change: 0 additions & 1 deletion sites/partners/__tests__/pages/application/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { application, listing, user } from "@bloom-housing/shared-helpers/__test
import ApplicationsList from "../../../src/pages/application/[id]"
import {
AlternateContactRelationship,
LanguagesEnum,
UnitTypeEnum,
YesNoEnum,
} from "@bloom-housing/shared-helpers/src/types/backend-swagger"
Expand Down
3 changes: 3 additions & 0 deletions sites/partners/page_content/locale_overrides/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
"application.details.annualIncome": "Annual income",
"application.details.applicationData": "Application data",
"application.details.applicationStatus": "Status",
"application.details.accessibleUnitWaitlistNumber": "Accessible unit waitlist (AUWL)",
"application.details.conventionalUnitWaitlistNumber": "Conventional unit waitlist (CUWL)",
"application.details.manualLotteryPositionNumber": "Lottery number",
"application.details.householdIncome": "Declared household income",
"application.details.householdMemberDetails": "Household member details",
"application.details.householdSize": "Household size",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import customParseFormat from "dayjs/plugin/customParseFormat"
import {
Application,
IncomePeriodEnum,
ReviewOrderTypeEnum,
} from "@bloom-housing/shared-helpers/src/types/backend-swagger"
dayjs.extend(customParseFormat)

Expand Down Expand Up @@ -42,7 +43,8 @@ export function getColDefs(
maxHouseholdSize: number,
enableFullTimeStudentQuestion?: boolean,
disableWorkInRegion?: boolean,
enableApplicationStatus?: boolean
enableApplicationStatus?: boolean,
reviewOrderType?: ReviewOrderTypeEnum
): ColDef[] {
const defs: ColDef[] = [
{
Expand Down Expand Up @@ -99,6 +101,34 @@ export function getColDefs(
return t(`application.details.applicationStatus.${data.status}`)
},
},
{
headerName: t("application.details.accessibleUnitWaitlistNumber"),
field: "accessibleUnitWaitlistNumber",
sortable: false,
filter: false,
width: 120,
minWidth: 50,
},
{
headerName: t("application.details.conventionalUnitWaitlistNumber"),
field: "conventionalUnitWaitlistNumber",
sortable: false,
filter: false,
width: 120,
minWidth: 50,
},
...(reviewOrderType === ReviewOrderTypeEnum.lottery
? [
{
headerName: t("application.details.manualLotteryPositionNumber"),
field: "manualLotteryPositionNumber",
sortable: false,
filter: false,
width: 120,
minWidth: 50,
},
]
: []),
]
: []),
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { ApplicationContext } from "../../ApplicationContext"
import { convertDataToLocal } from "../../../../lib/helpers"
import SectionWithGrid from "../../../shared/SectionWithGrid"

const DetailsApplicationData = () => {
type DetailsApplicationDataProps = {
enableApplicationStatus?: boolean
}

const DetailsApplicationData = ({ enableApplicationStatus }: DetailsApplicationDataProps) => {
const application = useContext(ApplicationContext)

const applicationDate = useMemo(() => {
Expand Down Expand Up @@ -67,6 +71,25 @@ const DetailsApplicationData = () => {
</FieldValue>
</Grid.Cell>
</Grid.Row>
{enableApplicationStatus && (
<Grid.Row columns={3}>
<Grid.Cell>
<FieldValue label={t("application.details.accessibleUnitWaitlistNumber")}>
{application.accessibleUnitWaitlistNumber ?? t("t.n/a")}
</FieldValue>
</Grid.Cell>
<Grid.Cell>
<FieldValue label={t("application.details.conventionalUnitWaitlistNumber")}>
{application.conventionalUnitWaitlistNumber ?? t("t.n/a")}
</FieldValue>
</Grid.Cell>
<Grid.Cell>
<FieldValue label={t("application.details.manualLotteryPositionNumber")}>
{application.manualLotteryPositionNumber ?? t("t.n/a")}
</FieldValue>
</Grid.Cell>
</Grid.Row>
)}
</SectionWithGrid>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,10 @@ const ApplicationForm = ({ listingId, editMode, application }: ApplicationFormPr
<Form id="application-form" onSubmit={handleSubmit(triggerSubmit, onError)}>
<div className="flex flex-row flex-wrap">
<div className="info-card md:w-9/12">
<FormApplicationData enableApplicationStatus={enableApplicationStatus} />
<FormApplicationData
enableApplicationStatus={enableApplicationStatus}
reviewOrderType={listingDto?.reviewOrderType}
/>

<FormPrimaryApplicant
enableFullTimeStudentQuestion={enableFullTimeStudentQuestion}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import React from "react"
import { t, Select, TimeField, DateField, DateFieldValues } from "@bloom-housing/ui-components"
import {
t,
Select,
TimeField,
DateField,
DateFieldValues,
Field,
} from "@bloom-housing/ui-components"
import { Grid } from "@bloom-housing/ui-seeds"
import {
LanguagesEnum,
ApplicationStatusEnum,
ReviewOrderTypeEnum,
} from "@bloom-housing/shared-helpers/src/types/backend-swagger"
import { useFormContext } from "react-hook-form"
import SectionWithGrid from "../../../shared/SectionWithGrid"

type FormApplicationDataProps = {
enableApplicationStatus: boolean
reviewOrderType?: ReviewOrderTypeEnum
}

const FormApplicationData = ({ enableApplicationStatus }: FormApplicationDataProps) => {
const FormApplicationData = ({
enableApplicationStatus,
reviewOrderType,
}: FormApplicationDataProps) => {
const formMethods = useFormContext()

// eslint-disable-next-line @typescript-eslint/unbound-method
Expand All @@ -25,6 +37,15 @@ const FormApplicationData = ({ enableApplicationStatus }: FormApplicationDataPro
const isDateRequired =
dateSubmittedValue?.day || dateSubmittedValue?.month || dateSubmittedValue?.year

const applicationStatus: ApplicationStatusEnum = watch("application.status")

const accessibleUnitWaitlistNumberValue = watch("application.accessibleUnitWaitlistNumber")
const conventionalUnitWaitlistNumberValue = watch("application.conventionalUnitWaitlistNumber")

const isWaitlistStatus =
applicationStatus === ApplicationStatusEnum.waitlist ||
applicationStatus === ApplicationStatusEnum.waitlistDeclined

const applicationStatusOptions = Array.from(Object.values(ApplicationStatusEnum))
return (
<SectionWithGrid heading={t("application.details.applicationData")}>
Expand Down Expand Up @@ -74,19 +95,85 @@ const FormApplicationData = ({ enableApplicationStatus }: FormApplicationDataPro
</Grid.Cell>
</Grid.Row>
{enableApplicationStatus && (
<Grid.Row columns={3}>
<Grid.Cell>
<Select
id="application.status"
name="application.status"
label={t("application.details.applicationStatus")}
register={register}
controlClassName="control"
options={applicationStatusOptions}
keyPrefix="application.details.applicationStatus"
/>
</Grid.Cell>
</Grid.Row>
<>
<Grid.Row columns={3}>
<Grid.Cell>
<Select
id="application.status"
name="application.status"
label={t("application.details.applicationStatus")}
register={register}
controlClassName="control"
options={applicationStatusOptions}
keyPrefix="application.details.applicationStatus"
/>
</Grid.Cell>
</Grid.Row>
<Grid.Row columns={3}>
{/* We need active hidden field to send value even when field is not visible and disabled */}
<Grid.Cell
className={isWaitlistStatus || accessibleUnitWaitlistNumberValue ? "" : "hidden"}
>
<Field
className={isWaitlistStatus ? "" : "hidden"}
type="number"
id="application.accessibleUnitWaitlistNumber"
name="application.accessibleUnitWaitlistNumber"
label={t("application.details.accessibleUnitWaitlistNumber")}
register={register}
error={!!errors?.application?.accessibleUnitWaitlistNumber}
/>
{!isWaitlistStatus && (
<Field
type="number"
name="application.accessibleUnitWaitlistNumber"
label={t("application.details.accessibleUnitWaitlistNumber")}
inputProps={{
value: accessibleUnitWaitlistNumberValue,
}}
disabled
/>
)}
</Grid.Cell>
{/* We need active hidden field to send value even when field is not visible and disabled */}
<Grid.Cell
className={isWaitlistStatus || conventionalUnitWaitlistNumberValue ? "" : "hidden"}
>
<Field
className={isWaitlistStatus ? "" : "hidden"}
type="number"
id="application.conventionalUnitWaitlistNumber"
name="application.conventionalUnitWaitlistNumber"
label={t("application.details.conventionalUnitWaitlistNumber")}
register={register}
error={!!errors?.application?.conventionalUnitWaitlistNumber}
/>
{!isWaitlistStatus && (
<Field
type="number"
name="application.conventionalUnitWaitlistNumber"
label={t("application.details.conventionalUnitWaitlistNumber")}
inputProps={{
value: conventionalUnitWaitlistNumberValue,
}}
disabled
/>
)}
</Grid.Cell>
{reviewOrderType === ReviewOrderTypeEnum.lottery && (
<Grid.Cell>
<Field
type="number"
id="application.manualLotteryPositionNumber"
name="application.manualLotteryPositionNumber"
label={t("application.details.manualLotteryPositionNumber")}
register={register}
error={!!errors?.application?.manualLotteryPositionNumber}
/>
</Grid.Cell>
)}
</Grid.Row>
</>
)}
</SectionWithGrid>
)
Expand Down
Loading
Loading