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

Feature/dynamic preferences #1167

Merged
merged 39 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
14b5634
Created expandable content component
dominikx96 Apr 20, 2021
d631e25
Exported ExpandableContext component
dominikx96 Apr 22, 2021
4d2e866
Updated seeds to add preference links
dominikx96 Apr 22, 2021
ef61f11
Added new preferences page - keep old for now
dominikx96 Apr 22, 2021
3c2811c
Moved reusable logic to the helper
dominikx96 Apr 22, 2021
c016bb9
Built dynamic form
dominikx96 Apr 22, 2021
596d7dc
Add hhMemberSelect type to InputTypes (#1144)
pbn4 Apr 22, 2021
8591a07
Added household member type
dominikx96 Apr 22, 2021
f618408
Integrated hh select
dominikx96 Apr 22, 2021
408e263
Refactored all FormAddress instances
dominikx96 Apr 22, 2021
dcd0bb9
Created helper to have an access to nested properties from string
dominikx96 Apr 22, 2021
8116d62
Exported helper
dominikx96 Apr 22, 2021
7e786af
Validate nested form options
dominikx96 Apr 22, 2021
55cf25a
Added validation function
dominikx96 Apr 22, 2021
863d282
Added form validation
dominikx96 Apr 23, 2021
7b8cb20
Added new step to the config & cleanup
dominikx96 Apr 23, 2021
497a527
Set default preference values
dominikx96 Apr 23, 2021
2742e4f
Cleanup
dominikx96 Apr 23, 2021
bf3536f
Merge branch 'master' into feature/dynamic-preferences
dominikx96 Apr 23, 2021
b936a98
Cleanup
dominikx96 Apr 23, 2021
46eb2e3
Updated summary details
dominikx96 Apr 23, 2021
360f69e
Cleanup
dominikx96 Apr 23, 2021
46d7efa
Updating preferences page styles
Apr 23, 2021
b5231ae
remove legend reset
Apr 23, 2021
12b438f
Merge branch 'master' into feature/dynamic-preferences
dominikx96 Apr 24, 2021
eed8a6e
Updated preferences path
dominikx96 Apr 24, 2021
1c78d7d
Created test for dynamic preferences
dominikx96 Apr 24, 2021
bb3a08e
Updated form to store selected preferences only
dominikx96 Apr 26, 2021
447e7a7
Fix application hook issue with empty search param
dominikx96 Apr 26, 2021
e2c1a6f
Added context test
dominikx96 Apr 26, 2021
c2a880d
Updated test and cleanup
dominikx96 Apr 27, 2021
a94a9bb
Removed old translations
dominikx96 Apr 27, 2021
b851119
Merge branch 'master' into feature/dynamic-preferences
dominikx96 Apr 28, 2021
fbb827d
Removed old displaced preference page
dominikx96 Apr 28, 2021
8c5427d
Added missing translation
dominikx96 Apr 28, 2021
aaa1764
Fixed broken tests
dominikx96 Apr 28, 2021
65fbe64
Updated tests to load listing with 2 preferences
dominikx96 Apr 28, 2021
5443312
Added more information about function
dominikx96 Apr 29, 2021
5dc694c
Cleanup
dominikx96 Apr 29, 2021
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
26 changes: 22 additions & 4 deletions backend/core/src/seeds/listings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,16 @@ export const listingSeed1: ListingSeed = {
subtitle: "",
description:
"At least one member of my household lives in City of Hayward. At least one member of my household works in the City of Hayward",
links: [],
links: [
{
title: "example.com",
url: "https://example.com",
},
{
title: "example2.com",
url: "https://example2.com",
},
],
formMetadata: {
key: "liveWork",
options: [
Expand All @@ -202,7 +211,16 @@ export const listingSeed1: ListingSeed = {
subtitle: "",
description:
"At least one member of my household was displaced from a residential property due to redevelopment activity by the Hayward Housing Authority, the Redevelopment Agency or the City of Hayward.",
links: [],
links: [
{
title: "example.com",
url: "https://example.com",
},
{
title: "example2.com",
url: "https://example2.com",
},
],
formMetadata: {
key: "displacedTenant",
options: [
Expand All @@ -211,7 +229,7 @@ export const listingSeed1: ListingSeed = {
extraData: [
{
key: "name",
type: InputType.text,
type: InputType.hhMemberSelect,
},
{
key: "address",
Expand All @@ -224,7 +242,7 @@ export const listingSeed1: ListingSeed = {
extraData: [
{
key: "name",
type: InputType.text,
type: InputType.hhMemberSelect,
},
{
key: "address",
Expand Down
1 change: 1 addition & 0 deletions backend/core/src/shared/types/input-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export enum InputType {
boolean = "boolean",
text = "text",
address = "address",
hhMemberSelect = "hhMemberSelect",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does hhMemberSelect stand for / refer to?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because we need to show to choose household members (user can add hh members few steps before).

}
3 changes: 2 additions & 1 deletion backend/core/types/src/backend-swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3662,7 +3662,8 @@ export enum CSVFormattingType {
export enum InputType {
'boolean' = 'boolean',
'text' = 'text',
'address' = 'address'
'address' = 'address',
'hhMemberSelect' = 'hhMemberSelect'
}
export type CombinedAmiChartTypes = AmiChart;
export enum ApplicationMethodType {
Expand Down
101 changes: 7 additions & 94 deletions sites/partners/lib/formatApplicationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import {
ApplicationStatus,
Address,
HouseholdMember,
InputType,
} from "@bloom-housing/backend-core/types"

import { TimeFieldPeriod } from "@bloom-housing/ui-components"
import {
TimeFieldPeriod,
mapPreferencesToApi,
mapApiToPreferencesForm,
} from "@bloom-housing/ui-components"
import {
FormTypes,
YesNoAnswer,
Expand Down Expand Up @@ -96,60 +99,7 @@ export const mapFormToApi = (data: FormData, listingId: string, editMode: boolea
}
})()

const preferences = (() => {
const CLAIMED_KEY = "claimed"
const preferencesFormData = data.application.preferences

const keys = Object.keys(preferencesFormData)

return keys.map((key) => {
const currentPreference = preferencesFormData[key]
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const currentPreferenceValues = Object.values(currentPreference) as Record<string, any>
const claimed = currentPreferenceValues.map((c) => c.claimed).includes(true)

const options = Object.keys(currentPreference).map((option) => {
const currentOption = currentPreference[option]

// count keys except claimed
const extraKeys = Object.keys(currentOption).filter((item) => item !== CLAIMED_KEY)

const response = {
key: option,
checked: currentOption[CLAIMED_KEY],
}

// assign extra data and detect data type
if (extraKeys.length) {
const extraData = extraKeys.map((extraKey) => {
const type = (() => {
if (typeof currentOption[extraKey] === "boolean") return InputType.boolean
// if object includes "city" property, it should be an address
if (Object.keys(currentOption[extraKey]).includes("city")) return InputType.address

return InputType.text
})()

return {
key: extraKey,
type,
value: currentOption[extraKey],
}
})

Object.assign(response, { extraData })
}

return response
})

return {
key,
claimed,
options,
}
})
})()
const preferences = mapPreferencesToApi(data)

// additional phone
const {
Expand Down Expand Up @@ -293,44 +243,7 @@ export const mapApiToForm = (applicationData: ApplicationUpdate) => {

const phoneNumber = applicationData.applicant.phoneNumber

const preferences = (() => {
const preferencesFormData = {}

const preferencesApiData = applicationData.preferences

preferencesApiData.forEach((item) => {
const options = item.options.reduce((acc, curr) => {
// extraData which comes from the API is an array, in the form we expect an object
const extraData =
curr?.extraData?.reduce((extraAcc, extraCurr) => {
// value - it can be string or nested address object
const value = extraCurr.value
Object.assign(extraAcc, {
[extraCurr.key]: value,
})

return extraAcc
}, {}) || {}

// each form option has "claimed" property - it's "checked" property in the API
const claimed = curr.checked

Object.assign(acc, {
[curr.key]: {
claimed,
...extraData,
},
})
return acc
}, {})

Object.assign(preferencesFormData, {
[item.key]: options,
})
})

return preferencesFormData
})()
const preferences = mapApiToPreferencesForm(applicationData.preferences)

const application: ApplicationTypes = (() => {
const {
Expand Down
38 changes: 29 additions & 9 deletions sites/partners/lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,36 @@ export function useListingsData() {
}
}

export function useApplicationsData(pageIndex: number, limit = 10, listingId: string, search = "") {
export function useApplicationsData(
pageIndex: number,
limit = 10,
listingId: string,
search: string
) {
const { applicationsService } = useContext(ApiClientContext)
const endpoint = `${process.env.backendApiBase}/applications?listingId=${listingId}&page=${pageIndex}&limit=${limit}&search=${search}`
const fetcher = () =>
applicationsService.list({
listingId,
page: pageIndex,
limit,
search,
})

const searchParams = new URLSearchParams()
searchParams.append("listingId", listingId)
searchParams.append("page", pageIndex.toString())
searchParams.append("limit", limit.toString())

if (search) {
searchParams.append("search", search)
}

const endpoint = `${process.env.backendApiBase}/applications?${searchParams.toString()}`

const params = {
listingId,
page: pageIndex,
limit,
}

if (search) {
Object.assign(params, search)
}

const fetcher = () => applicationsService.list(params)
const { data, error } = useSWR(endpoint, fetcher)

return {
Expand Down

This file was deleted.

29 changes: 18 additions & 11 deletions sites/partners/src/applications/PaperApplicationForm/FormMember.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
FieldGroup,
Button,
Form,
FormAddress,
} from "@bloom-housing/ui-components"
import { useForm } from "react-hook-form"
import { FormAddress } from "./FormAddress"
import { YesNoAnswer } from "./FormTypes"

type ApplicationFormMemberProps = {
Expand Down Expand Up @@ -208,16 +208,23 @@ const FormMember = ({ onSubmit, onClose, members, editedMemberId }: ApplicationF
</GridCell>
</GridSection>

{sameAddressField === YesNoAnswer.No &&
FormAddress(
t("application.details.residenceAddress"),
"address",
"residence-member",
register
)}

{workInRegionField === YesNoAnswer.Yes &&
FormAddress(t("application.contact.workAddress"), "workAddress", "work", register)}
{sameAddressField === YesNoAnswer.No && (
<FormAddress
subtitle={t("application.details.residenceAddress")}
dataKey="address"
type="residence-member"
register={register}
/>
)}

{workInRegionField === YesNoAnswer.Yes && (
<FormAddress
subtitle={t("application.contact.workAddress")}
dataKey="workAddress"
type="work"
register={register}
/>
)}
</div>

<div className="mt-6">
Expand Down
Loading