Skip to content

Commit

Permalink
Adjustments to schema, add preliminary units tests for intake validation
Browse files Browse the repository at this point in the history
  • Loading branch information
wilwong89 committed May 14, 2024
1 parent e02e26f commit 6ff69f5
Show file tree
Hide file tree
Showing 5 changed files with 546 additions and 153 deletions.
23 changes: 16 additions & 7 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions frontend/src/components/form/internal/InputTextInternal.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<script setup lang="ts">
import { toRef, ref } from 'vue';
import { toRef } from 'vue';
import { useField } from 'vee-validate';
import { InputText } from '@/lib/primevue';
import type { Ref } from 'vue';
// Props
type Props = {
helpText: string;
Expand Down
222 changes: 79 additions & 143 deletions frontend/src/components/intake/ShasIntakeForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { storeToRefs } from 'pinia';
import { Form, FieldArray, ErrorMessage } from 'vee-validate';
import { onBeforeMount, ref } from 'vue';
import { array, mixed, number, object, string } from 'yup';
import FileUpload from '@/components/file/FileUpload.vue';
import {
Expand Down Expand Up @@ -40,6 +39,7 @@ import {
} from '@/utils/constants';
import { BASIC_RESPONSES } from '@/utils/enums';
import { deepToRaw } from '@/utils/utils';
import { getIntakeSchema } from './ShasIntakeSchema';
import type { Ref } from 'vue';
import Calendar from '../form/Calendar.vue';
Expand All @@ -65,139 +65,8 @@ const enum PROJECT_LOCATION {
// Constants
const ProjectLocation = [PROJECT_LOCATION.STREET_ADDRESS, PROJECT_LOCATION.LOCATION_COORDINATES];
const formSchema = getIntakeSchema(ProjectLocation);
// Form validation schema
const YesNoUnsureSchema = string().required().oneOf(YesNoUnsure);
const prevYesSelected = (prevQuestion: string) => prevQuestion === BASIC_RESPONSES.YES;
const stringRequired = string().required().max(255);
const formSchema = object({
applicant: object({
firstName: stringRequired.label('First name'),
lastName: stringRequired.label('Last name'),
phoneNumber: stringRequired.label('Phone number'),
email: stringRequired.label('Email'),
relationshipToProject: stringRequired.label('Relationship to project'),
contactPreference: stringRequired.label('Contact Preference')
}),
basic: object({
isDevelopedByCompanyOrOrg: string().required().oneOf(YesNo).label('Project developed'),
isDevelopedInBC: string().when('isDevelopedByCompanyOrOrg', {
is: (previousQuestion: string) => previousQuestion === BASIC_RESPONSES.YES,
then: (schema) => schema.required().oneOf(YesNo).label('Registered in BC')
}),
registeredName: string().when('isDevelopedInBC', {
is: (previousQuestion: string) => previousQuestion,
then: (schema) => schema.required().max(255).label('Business name')
})
}),
housing: object({
projectName: stringRequired.label('Project name'),
projectDescription: string().required().label('Project description'),
hasRentalUnits: YesNoUnsureSchema.label('Rental units'),
financiallySupportedBC: YesNoUnsureSchema.label('BC Housing'),
financiallySupportedIndigenous: YesNoUnsureSchema.label('Indigenous Housing Provider'),
financiallySupportedNonProfit: YesNoUnsureSchema.label('Non-profit housing society'),
financiallySupportedHousingCoop: YesNoUnsureSchema.label('Housing co-operative'),
rentalUnits: string().when('hasRentalUnits', {
is: prevYesSelected,
then: () => string().oneOf(NumResidentialUnits).required().label('Expected rental units'),
otherwise: () => string().nullable()
}),
indigenousDescription: string().when('financiallySupportedIndigenous', {
is: prevYesSelected,
then: () => stringRequired.label('Indigenous housing provider'),
otherwise: () => string().nullable()
}),
nonProfitDescription: string().when('financiallySupportedNonProfit', {
is: prevYesSelected,
then: () => stringRequired.label('Non-profit housing society'),
otherwise: () => string().nullable()
}),
housingCoopDescription: string().when('financiallySupportedHousingCoop', {
is: prevYesSelected,
then: () => stringRequired.label('Housing co-operative'),
otherwise: () => string().nullable()
}),
singleFamilyUnits: string().when('singleFamilySelected', {
is: (prev: boolean) => prev,
then: (schema) => schema.required().oneOf(NumResidentialUnits).label('Expected number of single-family units'),
otherwise: () => string().nullable()
}),
multiFamilyUnits: string().when('multiFamilySelected', {
is: (prev: boolean) => prev,
then: (schema) => schema.required().oneOf(NumResidentialUnits).label('Expected number of multi-family units'),
otherwise: () => string().nullable()
}),
otherUnitsDescription: string().when('otherSelected', {
is: (prev: boolean) => prev,
then: (schema) => schema.required().label('Description of units'),
otherwise: () => string().nullable()
}),
otherUnits: string().when('otherSelected', {
is: (prev: boolean) => prev,
then: (schema) => schema.required().oneOf(NumResidentialUnits).label('Expected number of other units'),
otherwise: () => string().nullable()
})
}).test('housing-checkbox-test', 'At least one residential type must be selected', (value, context) => {
return (
context.originalValue.singleFamilySelected ||
context.originalValue.multiFamilySelected ||
context.originalValue.otherSelected
);
}),
location: object({
projectLocation: string().required().label('Location'),
streetAddress: string().when('projectLocation', {
is: (prevQuestion: string) => prevQuestion === ProjectLocation[0],
then: () => stringRequired.label('Street address'),
otherwise: () => string().nullable()
}),
locality: string().when('projectLocation', {
is: (prevQuestion: string) => prevQuestion === ProjectLocation[0],
then: () => stringRequired.label('Locality'),
otherwise: () => string().nullable()
}),
province: string().when('projectLocation', {
is: (prevQuestion: string) => prevQuestion === ProjectLocation[0],
then: () => stringRequired.label('Province'),
otherwise: () => string().nullable()
}),
latitude: number().when('projectLocation', {
is: (prevQuestion: string) => prevQuestion === ProjectLocation[1],
then: () => number().required().min(48).max(60).label('Latitude'),
otherwise: () => string().nullable()
}),
longitude: number().when('projectLocation', {
is: (prevQuestion: string) => prevQuestion === ProjectLocation[1],
then: () => number().required().min(-139).max(-114).label('Longitude'),
otherwise: () => string().nullable()
}),
ltsaPIDLookup: string().max(255).label('Parcel ID'),
geomarkUrl: string().max(255).label('Geomark web service url')
}),
permits: object({
hasAppliedProvincialPermits: string().oneOf(YesNoUnsure).required().label('Applied permits'),
checkProvincialPermits: string().when('hasAppliedProvincialPermits', {
is: (prevQuestion: string) => prevQuestion === BASIC_RESPONSES.YES || prevQuestion === BASIC_RESPONSES.UNSURE,
then: (schema) => schema.oneOf(YesNo).required().label('Check permits'),
otherwise: (schema) => schema.nullable()
})
}),
appliedPermits: array().of(
object({
permitTypeId: number().required().max(255).label('Permit type'),
statusLastVerified: mixed()
.test('verified-date', 'Verified date must be valid', (val) => val instanceof Date)
.required()
.label('Last verified date'),
trackingId: string().max(255).label('Tracking ID')
})
)
});
function test(input: any) {
console.log('input', JSON.parse(JSON.stringify(input)));
}
// Actions
const confirm = useConfirm();
const toast = useToast();
Expand Down Expand Up @@ -257,7 +126,11 @@ async function onSubmit(data: any) {
onBeforeMount(async () => {
// Default form values
initialFormValues.value = {};
initialFormValues.value = {
location: {
province: 'BC'
}
};
typeStore.setPermitTypes((await permitService.getPermitTypes()).data);
});
Expand Down Expand Up @@ -287,7 +160,6 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
:click-callback="clickCallback"
title="Basic info"
icon="fa-user"
@click="() => test(values)"
/>
</template>
<template #content="{ nextCallback }">
Expand Down Expand Up @@ -609,8 +481,11 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
() => {
setFieldValue('housing.financiallySupportedBC', BASIC_RESPONSES.NO);
setFieldValue('housing.financiallySupportedIndigenous', BASIC_RESPONSES.NO);
setFieldValue('housing.indigenousDescription', undefined);
setFieldValue('housing.financiallySupportedNonProfit', BASIC_RESPONSES.NO);
setFieldValue('housing.nonProfitDescription', undefined);
setFieldValue('housing.financiallySupportedHousingCoop', BASIC_RESPONSES.NO);
setFieldValue('housing.housingCoopDescription', undefined);
}
"
>
Expand Down Expand Up @@ -653,13 +528,28 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
:disabled="!editable"
:options="YesNoUnsure"
/>
<div class="col mb-2"><label>Indigenous Housing Provider</label></div>
<div class="col mb-2">
<label>
<a
href="https://www.bchousing.org/housing-assistance/rental-housing/indigenous-housing-providers"
target="_blank"
>
Indigenous Housing Provider
</a>
</label>
</div>
<RadioList
class="col-12"
name="housing.financiallySupportedIndigenous"
:bold="false"
:disabled="!editable"
:options="YesNoUnsure"
@on-change="
(e) => {
console.log(e);
if (e !== BASIC_RESPONSES.YES) setFieldValue('housing.indigenousDescription', undefined);
}
"
/>
<div class="col-12">
<InputText
Expand All @@ -670,13 +560,28 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
placeholder="Name of Indigenous Housing Provider"
/>
</div>
<div class="col mb-2"><label>Non-profit housing society</label></div>
<div class="col mb-2">
<label>
<a
href="https://bcnpha.ca/member-programs-list/"
target="_blank"
>
Non-profit housing society
</a>
</label>
</div>
<RadioList
class="col-12"
name="housing.financiallySupportedNonProfit"
:bold="false"
:disabled="!editable"
:options="YesNoUnsure"
@on-change="
(e) => {
console.log(e);
if (e !== BASIC_RESPONSES.YES) setFieldValue('housing.nonProfitDescription', undefined);
}
"
/>
<div class="col-12">
<InputText
Expand All @@ -687,13 +592,28 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
placeholder="Name of Non-profit housing society"
/>
</div>
<div class="col mb-2"><label>Housing co-operative</label></div>
<div class="col mb-2">
<label>
<a
href="https://www.chf.bc.ca/find-co-op/"
target="_blank"
>
Housing co-operative
</a>
</label>
</div>
<RadioList
class="col-12"
name="housing.financiallySupportedHousingCoop"
:bold="false"
:disabled="!editable"
:options="YesNoUnsure"
@on-change="
(e) => {
console.log(e);
if (e !== BASIC_RESPONSES.YES) setFieldValue('housing.housingCoopDescription', undefined);
}
"
/>
<div class="col-12">
<InputText
Expand Down Expand Up @@ -889,7 +809,14 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
<Card class="no-shadow">
<template #content>
<div class="formgrid grid">
<div class="col-12 text-blue-500">See acceptable file formats</div>
<div class="col-12 text-blue-500">
<a
href="https://portal.nrs.gov.bc.ca/documents/10184/0/SpatialFileFormats.pdf/39b29b91-d2a7-b8d1-af1b-7216f8db38b4"
target="_blank"
>
See acceptable file formats
</a>
</div>
<FileUpload
class="col-12"
activity-id="TODO_HOW_TO_CREATE_DOCUMENTS_WITHOUT_ACTIVITY_ID"
Expand All @@ -908,10 +835,19 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
<Card class="no-shadow">
<template #content>
<div class="formgrid grid">
<div class="col-12">
<label>
<a
href="https://apps.gov.bc.ca/pub/geomark/overview"
target="_blank"
>
Open Geomark Web Service
</a>
</label>
</div>
<InputText
class="col-12"
name="location.geomarkUrl"
label="Open Geomark Web Service"
:bold="false"
:disabled="!editable"
placeholder="Type in URL"
Expand Down Expand Up @@ -1143,7 +1079,7 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
class="w-full flex align-items-center"
>
<Dropdown
class="col-3"
class="col-4"
:name="`investigatePermits[${idx}].permitTypeId`"
placeholder="Select Permit type"
:options="getPermitTypes"
Expand All @@ -1153,7 +1089,7 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
/>
<div class="col-1">
<div class="flex justify-content-left">
<div class="flex align-items-center ml-2 mb-3">
<div class="flex align-items-center mb-3">
<Button
class="p-button-lg p-button-text p-button-danger p-0"
aria-label="Delete"
Expand Down Expand Up @@ -1214,7 +1150,7 @@ const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
label="Submit"
type="submit"
icon="pi pi-upload"
:disabled="!editable"
:disabled="!editable || activeStep !== 3"
/>
</div>
</Form>
Expand Down
Loading

0 comments on commit 6ff69f5

Please sign in to comment.