Skip to content

Commit

Permalink
fix: foreign language in export (#3865)
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyjablonski authored Feb 7, 2024
1 parent 9df926e commit 1c99bcf
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 18 deletions.
14 changes: 14 additions & 0 deletions shared-helpers/__tests__/views/multiselectQuestions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { cleanup } from "@testing-library/react"
import { cleanMultiselectString } from "../../src/views/multiselectQuestions"

afterEach(cleanup)

describe("multiselectQuestions", () => {
describe("cleanMultiselectString", () => {
it("should remove expected characters", () => {
expect(
cleanMultiselectString("I'm a string, and I have a comma, period, and apostrophe.")
).toBe("Im a string and I have a comma period and apostrophe")
})
})
})
34 changes: 25 additions & 9 deletions shared-helpers/src/views/multiselectQuestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import { stateKeys } from "../utilities/formKeys"
import { AddressHolder } from "../utilities/constants"
import { FormAddressAlternate } from "./address/FormAddressAlternate"

// Removes periods, commas, and apostrophes
export const cleanMultiselectString = (name: string | undefined) => {
return name?.replace(/\.|,|'/g, "")
}

export const listingSectionQuestions = (
listing: Listing,
applicationSection: ApplicationSection
Expand All @@ -37,8 +42,8 @@ export const fieldName = (
applicationSection: ApplicationSection,
optionName?: string
) => {
return `application.${applicationSection}.${questionName?.replace(/'/g, "")}${
optionName ? `.${optionName?.replace(/'/g, "")}` : ""
return `application.${applicationSection}.${cleanMultiselectString(questionName)}${
optionName ? `.${cleanMultiselectString(optionName)}` : ""
}`
}

Expand Down Expand Up @@ -343,7 +348,8 @@ export const mapCheckboxesToApi = (
question: MultiselectQuestion,
applicationSection: ApplicationSection
): ApplicationMultiselectQuestion => {
const data = formData["application"][applicationSection][question.text.replace(/'/g, "")]
const data =
formData["application"][applicationSection][cleanMultiselectString(question.text) || ""]
const claimed = !!Object.keys(data).filter((key) => data[key] === true).length

const addressFields = Object.keys(data).filter((option) => Object.keys(data[option]))
Expand Down Expand Up @@ -378,8 +384,17 @@ export const mapCheckboxesToApi = (
}
}

const getFinalKey = () => {
const optionKey = question?.options?.find(
(elem) => cleanMultiselectString(elem.text) === key
)?.text
const cleanOptOutKey = cleanMultiselectString(question?.optOutText)
if (cleanOptOutKey === key) return question?.optOutText || key
return optionKey || key
}

return {
key,
key: getFinalKey(),
mapPinPosition: data?.[`${key}-mapPinPosition`],
checked: data[key] === true,
extraData: extraData,
Expand Down Expand Up @@ -433,26 +448,27 @@ export const mapApiToMultiselectForm = (
if (appQuestion.inputType === "checkbox") {
options = question.options.reduce((acc, curr) => {
const claimed = curr.checked
const cleanKey = cleanMultiselectString(curr.key) || ""
if (appQuestion.inputType === "checkbox") {
acc[curr.key] = claimed
acc[cleanKey] = claimed
if (curr.extraData?.length) {
acc[`${curr.key}-address`] = curr.extraData[0].value
acc[`${cleanKey}-address`] = curr.extraData[0].value

const addressHolderName = curr.extraData?.find(
(field) => field.key === AddressHolder.Name
)
if (addressHolderName) {
acc[`${curr.key}-${AddressHolder.Name}`] = addressHolderName.value
acc[`${cleanKey}-${AddressHolder.Name}`] = addressHolderName.value
}

const addressHolderRelationship = curr.extraData?.find(
(field) => field.key === AddressHolder.Relationship
)
if (addressHolderRelationship) {
acc[`${curr.key}-${AddressHolder.Relationship}`] = addressHolderRelationship.value
acc[`${cleanKey}-${AddressHolder.Relationship}`] = addressHolderRelationship.value
}
if (curr?.mapPinPosition) {
acc[`${curr.key}-mapPinPosition`] = curr.mapPinPosition
acc[`${cleanKey}-mapPinPosition`] = curr.mapPinPosition
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import React, { useEffect, useMemo, useState } from "react"
import { Field, t, FieldGroup, resolveObject } from "@bloom-housing/ui-components"
import { FieldValue, Grid } from "@bloom-housing/ui-seeds"
import { useFormContext } from "react-hook-form"
import { stateKeys, getInputType, fieldName, AddressHolder } from "@bloom-housing/shared-helpers"
import {
stateKeys,
getInputType,
fieldName,
AddressHolder,
cleanMultiselectString,
} from "@bloom-housing/shared-helpers"
import {
ApplicationSection,
ListingMultiselectQuestion,
Expand Down Expand Up @@ -41,7 +47,11 @@ const FormMultiselectQuestions = ({
questions?.forEach((listingQuestion) =>
listingQuestion?.multiselectQuestion.options.forEach((option) =>
keys.push(
fieldName(listingQuestion?.multiselectQuestion.text, applicationSection, option.text)
fieldName(
listingQuestion?.multiselectQuestion.text,
applicationSection,
cleanMultiselectString(option.text)
)
)
)
)
Expand All @@ -68,7 +78,11 @@ const FormMultiselectQuestions = ({
const watchQuestions = watch(allOptionFieldNames)

const getCheckboxOption = (option: MultiselectOption, question: MultiselectQuestion) => {
const optionFieldName = fieldName(question.text, applicationSection, option.text)
const optionFieldName = fieldName(
question.text,
applicationSection,
cleanMultiselectString(option.text)
)
return (
<React.Fragment key={option.text}>
<Field
Expand Down
30 changes: 28 additions & 2 deletions sites/public/src/components/shared/FormSummaryDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { Fragment, useEffect, useState } from "react"
import { LocalizedLink, MultiLineAddress, t } from "@bloom-housing/ui-components"
import { FieldValue } from "@bloom-housing/ui-seeds"
import { getUniqueUnitTypes, AddressHolder } from "@bloom-housing/shared-helpers"
import {
getUniqueUnitTypes,
AddressHolder,
cleanMultiselectString,
} from "@bloom-housing/shared-helpers"
import {
Address,
AllExtraDataTypes,
Expand Down Expand Up @@ -107,6 +111,28 @@ const FormSummaryDetails = ({
return `${name ? `${name}\n` : ""}${relationship ? `${relationship}\n` : ""}${helperText}`
}

const getOptionText = (
question: ApplicationMultiselectQuestion,
option: ApplicationMultiselectQuestionOption
) => {
const initialMultiselectQuestion = listing.listingMultiselectQuestions.find(
(elem) =>
cleanMultiselectString(elem.multiselectQuestion.text) ===
cleanMultiselectString(question.key)
)

const initialOption = initialMultiselectQuestion?.multiselectQuestion.options.find(
(elem) => cleanMultiselectString(elem.text) === option.key
)

const initialOptOut = initialMultiselectQuestion?.multiselectQuestion.optOutText

const optOutOption =
option.key === cleanMultiselectString(initialOptOut) ? initialOptOut : undefined

return initialOption?.text || optOutOption || option.key
}

const multiselectQuestionSection = (
applicationSection: ApplicationSection,
appLink: string,
Expand Down Expand Up @@ -141,7 +167,7 @@ const FormSummaryDetails = ({
testId={"app-summary-preference"}
className={"pb-6 whitespace-pre-wrap"}
>
{option.key}
{getOptionText(question, option)}
</FieldValue>
))
)}
Expand Down
15 changes: 11 additions & 4 deletions sites/public/src/lib/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
imageUrlFromListing,
getSummariesTable,
IMAGE_FALLBACK_URL,
cleanMultiselectString,
} from "@bloom-housing/shared-helpers"

export const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
Expand Down Expand Up @@ -184,19 +185,24 @@ export const untranslateMultiselectQuestion = (

data.forEach((datum) => {
const question = multiselectQuestions.find(
(elem) => elem.multiselectQuestion.text === datum.key
(elem) =>
elem.multiselectQuestion.text === datum.key ||
elem.multiselectQuestion.untranslatedText === datum.key
)?.multiselectQuestion

if (question) {
datum.key = question.untranslatedText ?? question.text

if (datum.options) {
datum.options.forEach((option) => {
const selectedOption = question.options.find((elem) => elem.text === option.key)

const selectedOption = question.options.find((elem) => {
return cleanMultiselectString(elem.text) === cleanMultiselectString(option.key)
})
if (selectedOption) {
option.key = selectedOption.untranslatedText ?? selectedOption.text
} else if (question.optOutText === option.key) {
} else if (
cleanMultiselectString(question?.optOutText) === cleanMultiselectString(option.key)
) {
option.key = question.untranslatedOptOutText ?? question.optOutText
}

Expand Down Expand Up @@ -226,6 +232,7 @@ export const downloadExternalPDF = async (fileURL: string, fileName: string) =>
const url = window.URL.createObjectURL(new Blob([blob]))
const link = document.createElement("a")
link.href = url
link.target = "_blank"
link.setAttribute("download", `${fileName}.pdf`)

document.body.appendChild(link)
Expand Down

0 comments on commit 1c99bcf

Please sign in to comment.