diff --git a/backend/core/src/multiselect-question/types/multiselect-option.ts b/backend/core/src/multiselect-question/types/multiselect-option.ts index 581602d67e..c4da532868 100644 --- a/backend/core/src/multiselect-question/types/multiselect-option.ts +++ b/backend/core/src/multiselect-question/types/multiselect-option.ts @@ -3,6 +3,7 @@ import { IsBoolean, IsNumber, IsOptional, IsString, ValidateNested } from "class import { ValidationsGroupsEnum } from "../../shared/types/validations-groups-enum" import { ApiProperty } from "@nestjs/swagger" import { MultiselectLink } from "./multiselect-link" +import { ValidationMethod } from "./validation-method-enum" export class MultiselectOption { @Expose() @@ -38,7 +39,34 @@ export class MultiselectOption { @IsOptional({ groups: [ValidationsGroupsEnum.default] }) @IsBoolean({ groups: [ValidationsGroupsEnum.default] }) @ApiProperty({ required: false }) - collectAddress?: boolean | null + collectAddress?: boolean + + @Expose() + @IsOptional({ groups: [ValidationsGroupsEnum.default] }) + @ApiProperty({ + required: false, + enum: ValidationMethod, + enumName: "ValidationMethod", + }) + validationMethod?: ValidationMethod + + @Expose() + @IsOptional({ groups: [ValidationsGroupsEnum.default] }) + @IsNumber({}, { groups: [ValidationsGroupsEnum.default] }) + @ApiProperty({ required: false }) + radiusSize?: number + + @Expose() + @IsOptional({ groups: [ValidationsGroupsEnum.default] }) + @IsBoolean({ groups: [ValidationsGroupsEnum.default] }) + @ApiProperty({ required: false }) + collectName?: boolean + + @Expose() + @IsOptional({ groups: [ValidationsGroupsEnum.default] }) + @IsBoolean({ groups: [ValidationsGroupsEnum.default] }) + @ApiProperty({ required: false }) + collectRelationship?: boolean @Expose() @IsOptional({ groups: [ValidationsGroupsEnum.default] }) diff --git a/backend/core/src/multiselect-question/types/validation-method-enum.ts b/backend/core/src/multiselect-question/types/validation-method-enum.ts new file mode 100644 index 0000000000..517a363d76 --- /dev/null +++ b/backend/core/src/multiselect-question/types/validation-method-enum.ts @@ -0,0 +1,5 @@ +export enum ValidationMethod { + radius = "radius", + map = "map", + none = "none", +} diff --git a/backend/core/types/src/backend-swagger.ts b/backend/core/types/src/backend-swagger.ts index fbd056ac24..7197a2499b 100644 --- a/backend/core/types/src/backend-swagger.ts +++ b/backend/core/types/src/backend-swagger.ts @@ -4517,6 +4517,18 @@ export interface MultiselectOption { /** */ collectAddress?: boolean + /** */ + validationMethod?: ValidationMethod + + /** */ + radiusSize?: number + + /** */ + collectName?: boolean + + /** */ + collectRelationship?: boolean + /** */ exclusive?: boolean } @@ -6356,6 +6368,12 @@ export enum ListingEventType { "lotteryResults" = "lotteryResults", } +export enum ValidationMethod { + "radius" = "radius", + "map" = "map", + "none" = "none", +} + export enum ApplicationSection { "programs" = "programs", "preferences" = "preferences", diff --git a/shared-helpers/__tests__/testHelpers.ts b/shared-helpers/__tests__/testHelpers.ts index fff64c6489..c9a53c9b77 100644 --- a/shared-helpers/__tests__/testHelpers.ts +++ b/shared-helpers/__tests__/testHelpers.ts @@ -36,8 +36,9 @@ export const multiselectQuestionPreference: MultiselectQuestion = { url: "https://www.example.com", }, ], + collectAddress: false, }, - { text: "Work in County", ordinal: 1 }, + { text: "Work in County", ordinal: 1, collectAddress: false }, ], applicationSection: ApplicationSection.preferences, } diff --git a/sites/partners/cypress/e2e/default/08-preference-management.spec.ts b/sites/partners/cypress/e2e/default/08-preference-management.spec.ts index dae1d3fb6e..af5425f9cb 100644 --- a/sites/partners/cypress/e2e/default/08-preference-management.spec.ts +++ b/sites/partners/cypress/e2e/default/08-preference-management.spec.ts @@ -27,10 +27,16 @@ describe("Preference Management Tests", () => { cy.getByTestId("preference-option-description").type("Preference Option Description") cy.getByTestId("preference-option-link").type("https://www.example2.com") cy.getByTestId("preference-option-link-title").type("Preference Option Link Title") - cy.getByTestId("preference-option-collect-address").check() + cy.getByTestId("collect-address-yes").click() cy.getByTestId("exclusive-question-exclusive").check() cy.getByTestId("preference-option-save").click() + cy.getByTestId("validation-method-radius").click() + cy.getByTestId("preference-option-radius-size").type("100") + cy.getByTestId("collect-name-yes").click() + cy.getByTestId("collect-relationship-yes").click() + cy.getByTestId("preference-option-save").click() + cy.getByTestId("preference-opt-out-label").clear() cy.getByTestId("preference-opt-out-label").type("Preference Opt Out Label") cy.getByTestId("preference-jurisdiction").select("Alameda") @@ -59,7 +65,12 @@ describe("Preference Management Tests", () => { "have.value", "Preference Option Link Title" ) - cy.getByTestId("preference-option-collect-address").should("be.checked") + + cy.getByTestId("collect-address-yes").should("be.checked") + cy.getByTestId("validation-method-radius").should("be.checked") + cy.getByTestId("preference-option-radius-size").should("have.value", "100") + cy.getByTestId("collect-name-yes").should("be.checked") + cy.getByTestId("collect-relationship-yes").should("be.checked") cy.getByTestId("exclusive-question-exclusive").should("have.value", "exclusive") cy.getByTestId("preference-option-save").click() diff --git a/sites/partners/page_content/locale_overrides/general.json b/sites/partners/page_content/locale_overrides/general.json index 687884c554..8a444f24e5 100644 --- a/sites/partners/page_content/locale_overrides/general.json +++ b/sites/partners/page_content/locale_overrides/general.json @@ -337,13 +337,16 @@ "settings.createCopyDescription": "Create a copy of your preference.", "settings.preference": "Preference", "settings.preferenceAdd": "Add Preference", + "settings.preferenceAdditionalFields": "Additional Fields", "settings.preferenceAlertCreated": "Preference Created", "settings.preferenceAlertUpdated": "Preference Updated", "settings.preferenceAlertDeleted": "Preference Removed", "settings.preferenceOptionAdd": "Add Preference Option", "settings.preferenceAddOption": "Add Option", "settings.preferenceEditOption": "Edit Option", - "settings.preferenceCollectAddress": "Collect the applicant address", + "settings.preferenceCollectAddress": "Do you want to collect address information?", + "settings.preferenceCollectAddressHolderName": "Do you want to collect name of address holder?", + "settings.preferenceCollectAddressHolderRelationship": "Do you want to collect relationship to address holder?", "settings.preferenceDelete": "Deleting a preference cannot be undone.", "settings.preferenceDescription": "Preference Description", "settings.preferenceEdit": "Edit Preference", @@ -356,6 +359,10 @@ "settings.preferenceOptionDescription": "Preference Option Description", "settings.preferenceOptionEdit": "Edit Option", "settings.preferenceShowOnListing": "Show preference on listing?", + "settings.preferenceValidatingAddress": "Do you need help validating the address?", + "settings.preferenceValidatingAddress.checkWithinRadius": "Yes, check if within geographic radius of property", + "settings.preferenceValidatingAddress.checkManually": "No, will check manually", + "settings.preferenceValidatingAddress.howManyMiles": "How many miles is the qualifying geographic radius?", "settings.preferenceDeleteConfirmation": "Deleting a preference cannot be undone.", "settings.preferenceChangesRequired": "Changes required before deleting", "settings.preferenceDeleteError": "This preference is currently added to listings and needs to be removed before being deleted.", diff --git a/sites/partners/src/components/settings/PreferenceDrawer.tsx b/sites/partners/src/components/settings/PreferenceDrawer.tsx index bf97efbe36..860dcb85f3 100644 --- a/sites/partners/src/components/settings/PreferenceDrawer.tsx +++ b/sites/partners/src/components/settings/PreferenceDrawer.tsx @@ -1,4 +1,4 @@ -import React, { useState, useContext, useEffect, useMemo } from "react" +import React, { useContext, useEffect, useMemo, useState } from "react" import { AppearanceSizeType, AppearanceStyleType, @@ -22,6 +22,7 @@ import { MultiselectQuestion, MultiselectQuestionCreate, MultiselectQuestionUpdate, + ValidationMethod, } from "@bloom-housing/backend-core" import ManageIconSection from "./ManageIconSection" import { DrawerType } from "../../pages/settings/index" @@ -41,7 +42,11 @@ type PreferenceDrawerProps = { } type OptionForm = { - collectAddress: boolean + collectAddress: YesNoAnswer + validationMethod?: ValidationMethod + radiusSize?: string + collectRelationship?: YesNoAnswer + collectName?: YesNoAnswer exclusiveQuestion: "exclusive" | "multiselect" optionDescription: string optionLinkTitle: string @@ -89,6 +94,14 @@ const PreferenceDrawer = ({ const optOutQuestion = watch("canYouOptOutQuestion") + const collectAddressExpand = + (optionData?.collectAddress && watch("collectAddress") === undefined) || + watch("collectAddress") === YesNoAnswer.Yes + const readiusExpand = + (optionData?.validationMethod === ValidationMethod.radius && + watch("validationMethod") === undefined) || + watch("validationMethod") === ValidationMethod.radius + // Update local state with dragged state useEffect(() => { if (questionData?.options?.length > 0 && dragOrder?.length > 0) { @@ -441,35 +454,36 @@ const PreferenceDrawer = ({ onClose={() => { setOptionDrawerOpen(null) }} - className={"w-auto"} > - - - { - clearErrors("optionTitle") - }, - }} - /> - + + + + { + clearErrors("optionTitle") + }, + }} + /> + + - - + +