Skip to content

Commit

Permalink
Unit Note Validation, Submission, Error Handling (#1434)
Browse files Browse the repository at this point in the history
* Validation for Unit Notes
* Unit Note submission, validation, and other updates
* Add submission error handling
* Update tests for Unit Note validation
  • Loading branch information
dimak1 authored Jul 18, 2023
1 parent da0fc0b commit 7ac2df3
Show file tree
Hide file tree
Showing 25 changed files with 482 additions and 144 deletions.
4 changes: 2 additions & 2 deletions ppr-ui/package-lock.json

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

2 changes: 1 addition & 1 deletion ppr-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ppr-ui",
"version": "2.0.31",
"version": "2.0.32",
"private": true,
"appName": "Assets UI",
"sbcName": "SBC Common Components",
Expand Down
6 changes: 5 additions & 1 deletion ppr-ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import * as Views from '@/views'
import {
authPprError, authAssetsError, draftDeleteError, historyRegError, loginError, openDocError, paymentErrorReg,
paymentErrorSearch, registrationCompleteError, registrationDeleteError, registrationLoadError,
registrationOpenDraftError, registrationSaveDraftError, searchResultsError
registrationOpenDraftError, registrationSaveDraftError, searchResultsError, unitNoteFilingError
} from '@/resources/dialogOptions'
import {
getFees,
Expand Down Expand Up @@ -548,6 +548,10 @@ export default defineComponent({
localState.errorOptions = openDocError
localState.errorDisplay = true
break
case ErrorCategories.MHR_UNIT_NOTE_FILING:
localState.errorOptions = unitNoteFilingError
localState.errorDisplay = true
break
case ErrorCategories.SEARCH:
handleErrorSearch(error)
break
Expand Down
40 changes: 20 additions & 20 deletions ppr-ui/src/components/common/ContactInformation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
<PartySearch
v-if="!hidePartySearch"
isMhrPartySearch
@selectItem="setStoreProperty($event)"
@selectItem="emitStoreUpdate($event)"
/>

<v-card
id="contact-info"
flat
rounded
class="mt-8 pa-8 pr-6"
:class="{ 'border-error-left': showError }"
:class="{ 'border-error-left': showBorderError }"
>
<v-row no-gutters>
<v-col cols="12" sm="3">
<label
class="generic-label"
:class="{ 'error-text': showError }"
:class="{ 'error-text': showBorderError }"
>
{{ content.sideLabel }}
</label>
Expand Down Expand Up @@ -191,7 +191,7 @@ import { PartySearch } from '../parties/party'
export default defineComponent({
name: 'ContactInformation',
emits: ['isValid'],
emits: ['isValid', 'setStoreProperty'],
components: {
BaseAddress,
PartySearch
Expand All @@ -209,10 +209,6 @@ export default defineComponent({
type: Object as () => ContentIF,
default: () => {}
},
setStoreProperty: {
type: Function,
required: true
},
hidePartySearch: {
type: Boolean,
default: false
Expand Down Expand Up @@ -251,16 +247,22 @@ export default defineComponent({
hasLongCombinedName: false,
longCombinedNameErrorMsg: computed(() =>
localState.hasLongCombinedName ? 'Person\'s Legal Name combined cannot exceed 40 characters' : ''),
isContactInfoValid: computed(() =>
localState.isContactInfoFormValid && localState.isAddressValid
),
isPersonOption: computed((): boolean =>
localState.contactInfoType === SubmittingPartyTypes.PERSON
),
isBusinessOption: computed((): boolean =>
localState.contactInfoType === SubmittingPartyTypes.BUSINESS
),
showError: computed(() => props.validate && !localState.isContactInfoFormValid)
showBorderError: computed((): boolean => props.validate &&
!(localState.isContactInfoFormValid && localState.isAddressValid))
})
const emitStoreUpdate = (val) => {
emit('setStoreProperty', val)
}
watch(() => [localState.isContactInfoFormValid, localState.isAddressValid], () => {
emit('isValid', localState.isContactInfoFormValid && localState.isAddressValid)
})
watch(() => localState.contactInfoModel.businessName, (val: string) => {
Expand All @@ -270,7 +272,7 @@ export default defineComponent({
})
watch(() => localState.contactInfoModel, (val) => {
props.setStoreProperty(val)
emitStoreUpdate(val)
}, { deep: true, immediate: true })
const clearFields = () => {
Expand All @@ -290,16 +292,12 @@ export default defineComponent({
contactInfoForm.value?.validate()
})
watch(() => localState.isContactInfoValid, (val: boolean) => {
emit('isValid', val)
})
watch(() => localState.contactInfoModel.personName, async () => {
localState.hasLongCombinedName =
props.enableCombinedNameValidation &&
(0 || localState.contactInfoModel.personName?.first.length) +
(0 || localState.contactInfoModel.personName?.middle.length) +
(0 || localState.contactInfoModel.personName?.last.length) > 40
(0 || localState.contactInfoModel.personName?.first?.length) +
(0 || localState.contactInfoModel.personName?.middle?.length) +
(0 || localState.contactInfoModel.personName?.last?.length) > 40
}, { deep: true })
const firstNameRules = customRules(
Expand Down Expand Up @@ -338,6 +336,8 @@ export default defineComponent({
return {
clearFields,
emitStoreUpdate,
contactInfoForm,
emailRules,
firstNameRules,
middleNameRules,
Expand Down
51 changes: 27 additions & 24 deletions ppr-ui/src/components/common/DocumentId.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
<v-card
id="document-id-card"
class="mt-8 pa-8 pr-6 pb-3"
:class="{ 'border-error-left': validateDocId }"
:class="{ 'border-error-left': showBorderError }"
flat
>
<v-row no-gutters>
<v-col cols="12" sm="2">
<label
class="generic-label"
:class="{ 'error-text': validateDocId }"
:class="{ 'error-text': showBorderError }"
for="doc-id-field"
>
Document ID
Expand All @@ -28,6 +28,7 @@
label="Document ID Number"
v-model="documentIdModel"
:rules="documentIdRules"
:error="!isUniqueDocId && validate"
:error-messages="uniqueDocIdError"
>
<template v-slot:append>
Expand All @@ -50,7 +51,7 @@
</template>

<script lang="ts">
import { computed, defineComponent, reactive, ref, toRefs, watch } from 'vue-demi'
import { computed, defineComponent, nextTick, reactive, ref, toRefs, watch } from 'vue-demi'
import { validateDocumentID } from '@/utils'
import { FormIF, MhrDocIdResponseIF } from '@/interfaces'
import { useInputRules } from '@/composables'
Expand All @@ -62,18 +63,14 @@ export default defineComponent({
type: String,
required: true
},
setStoreProperty: {
type: Function,
required: true
},
validate: {
type: Boolean,
default: false
}
},
emits: ['isValid'],
emits: ['isValid', 'setStoreProperty'],
setup (props, { emit }) {
const { customRules, isNumber, maxLength, required } = useInputRules()
const { customRules, isNumber, maxLength, minLength, required } = useInputRules()
const documentIdForm = ref(null) as FormIF
Expand All @@ -83,35 +80,42 @@ export default defineComponent({
loadingDocId: false,
isUniqueDocId: false,
displayDocIdError: false,
validateDocId: computed(() => props.validate && !localState.isVerifiedDocId),
showBorderError: computed(() => props.validate && !localState.isVerifiedDocId),
isVerifiedDocId: computed(() => {
return localState.isDocumentIdFormValid && localState.isUniqueDocId
}),
uniqueDocIdError: computed(() => {
// Manual error handling for Unique DocId Lookup
return localState.displayDocIdError ? ['Must be unique number'] : []
return localState.displayDocIdError ? ['Must be unique number'] : ''
}),
documentIdRules: computed(() => {
return props.validate
? customRules(
required('Enter a Document ID'),
maxLength(8, true),
minLength(8, true),
isNumber()
)
: customRules(
maxLength(8, true),
isNumber()
)
})
})
const documentIdRules = customRules(
required('Enter a Document ID'),
maxLength(8, true),
isNumber()
)
watch(() => props.validate, async () => {
documentIdForm.value?.validate()
})
watch(() => props.validate, async (val) => {
if (val) documentIdForm.value?.validate()
}, { immediate: true })
watch(
() => localState.documentIdModel,
async (val: string) => {
if (localState.documentIdModel.length === 8) {
if (localState.documentIdModel?.length === 8) {
localState.loadingDocId = true
const validateDocId: MhrDocIdResponseIF = await validateDocumentID(localState.documentIdModel)
localState.isUniqueDocId = !validateDocId.exists && validateDocId.valid
localState.displayDocIdError = !localState.isUniqueDocId
await nextTick()
emit('isValid', localState.isVerifiedDocId)
} else {
localState.isUniqueDocId = false
Expand All @@ -121,13 +125,12 @@ export default defineComponent({
}
localState.loadingDocId = false
props.setStoreProperty(val)
emit('setStoreProperty', val)
},
{ immediate: true }
)
return {
documentIdRules,
...toRefs(localState)
}
}
Expand Down
14 changes: 5 additions & 9 deletions ppr-ui/src/components/common/Remarks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
<v-card
id="remarks-card"
class="py-6 px-8 rounded"
:class="{ 'border-error-left': showErrors }"
:class="{ 'border-error-left': showBorderError }"
flat
>
<v-row>
<v-col cols="2">
<label
for="remarks-textarea"
class="generic-label"
:class="{ 'error-text': showErrors }"
:class="{ 'error-text': showBorderError }"
>Add Remarks</label>
</v-col>
<v-col cols="10">
Expand Down Expand Up @@ -42,7 +42,7 @@ import { computed, defineComponent, reactive, toRefs, watch } from 'vue-demi'
export default defineComponent({
name: 'Remarks',
emits: ['isValid'],
emits: ['isValid', 'setStoreProperty'],
props: {
unitNoteRemarks: {
type: String,
Expand All @@ -51,10 +51,6 @@ export default defineComponent({
description: {
type: String
},
setStoreProperty: {
type: Function,
required: true
},
validate: {
type: Boolean,
default: false
Expand All @@ -66,13 +62,13 @@ export default defineComponent({
const localState = reactive({
isFormValid: false,
remarks: props.unitNoteRemarks,
showErrors: computed(() => props.validate && !localState.isFormValid)
showBorderError: computed(() => props.validate && !localState.isFormValid)
})
watch(
() => localState.remarks,
(val: string) => {
props.setStoreProperty(val)
emit('setStoreProperty', val)
}
)
Expand Down
Loading

0 comments on commit 7ac2df3

Please sign in to comment.