-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(FSADT1-1347): contact for staff page
- Loading branch information
1 parent
c7d6028
commit e4a8dc7
Showing
3 changed files
with
640 additions
and
2 deletions.
There are no files selected for viewing
278 changes: 278 additions & 0 deletions
278
frontend/src/components/grouping/StaffContactGroupComponent.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
<script setup lang="ts"> | ||
import { reactive, watch, ref, onMounted, getCurrentInstance } from "vue"; | ||
// Carbon | ||
import "@carbon/web-components/es/components/button/index"; | ||
// Importing composables | ||
import { useFocus } from "@/composables/useFocus"; | ||
// Importing types | ||
import type { CodeDescrType, CodeNameType } from "@/dto/CommonTypesDto"; | ||
import type { Contact } from "@/dto/ApplyClientNumberDto"; | ||
// Importing validatons | ||
import { getValidations } from "@/helpers/validators/GlobalValidators"; | ||
import { submissionValidation } from "@/helpers/validators/SubmissionValidators"; | ||
// @ts-ignore | ||
import Delete16 from "@carbon/icons-vue/es/trash-can/16"; | ||
import { getContactDescription } from "@/services/ForestClientService"; | ||
//Define the input properties for this component | ||
const props = defineProps<{ | ||
id: number; | ||
modelValue: Contact; | ||
enabled?: boolean; | ||
roleList: Array<CodeNameType>; | ||
addressList: Array<CodeNameType>; | ||
validations: Array<Function>; | ||
revalidate?: boolean; | ||
readOnlyName?: boolean; | ||
requiredLabel?: boolean; | ||
}>(); | ||
//Events we emit during component lifecycle | ||
const emit = defineEmits<{ | ||
(e: "valid", value: boolean): void; | ||
(e: "update:model-value", value: Contact | undefined): void; | ||
(e: "remove", value: number): void; | ||
}>(); | ||
const { safeSetFocusedComponent } = useFocus(); | ||
const noValidation = (value: string) => ""; | ||
//We set it as a separated ref due to props not being updatable | ||
const selectedValue = reactive<Contact>(props.modelValue); | ||
const validateData = | ||
props.validations.length === 0 | ||
? noValidation | ||
: props.validations[0]("Name", props.id + ""); | ||
const error = ref<string | undefined>(""); | ||
const uniquenessValidation = () => { | ||
error.value = validateData( | ||
`${selectedValue.firstName} ${selectedValue.lastName}` | ||
); | ||
}; | ||
//Watch for changes on the input | ||
watch([selectedValue], () => { | ||
uniquenessValidation(); | ||
emit("update:model-value", selectedValue); | ||
}); | ||
watch( | ||
() => props.revalidate, | ||
() => uniquenessValidation(), | ||
{ immediate: true } | ||
); | ||
//Validations | ||
const validation = reactive<Record<string, boolean>>({}); | ||
const checkValid = () => | ||
Object.values(validation).reduce( | ||
(accumulator: boolean, currentValue: boolean) => | ||
accumulator && currentValue, | ||
true | ||
); | ||
watch([validation], () => emit("valid", checkValid())); | ||
emit("valid", false); | ||
//Data conversion | ||
const nameTypeToCodeDescr = ( | ||
value: CodeNameType | undefined | ||
): CodeDescrType => { | ||
if (value) return { value: value.code, text: value.name }; | ||
return { value: "", text: "" }; | ||
}; | ||
const nameTypesToCodeDescr = ( | ||
values: CodeNameType[] | undefined | ||
): CodeDescrType[] => { | ||
if (values) return values.map(nameTypeToCodeDescr); | ||
return []; | ||
}; | ||
const updateContactType = (value: CodeNameType | undefined) => { | ||
if (value) { | ||
selectedValue.contactType = { value: value.code, text: value.name }; | ||
} | ||
}; | ||
</script> | ||
|
||
<template> | ||
<div class="frame-01"> | ||
<text-input-component | ||
:id="'fullName_' + id" | ||
label="Full name" | ||
placeholder="" | ||
autocomplete="off" | ||
v-bind:model-value="selectedValue.firstName + ' ' + selectedValue.lastName" | ||
:validations="[]" | ||
:enabled="false" | ||
required | ||
:requiredLabel="requiredLabel" | ||
:error-message="error" | ||
v-if="readOnlyName" | ||
/> | ||
|
||
<text-input-component | ||
:id="'firstName_' + id" | ||
label="First name" | ||
placeholder="" | ||
autocomplete="off" | ||
v-model="selectedValue.firstName" | ||
:validations="[ | ||
...getValidations('location.contacts.*.firstName'), | ||
submissionValidation(`location.contacts[${id}].firstName`) | ||
]" | ||
:enabled="true" | ||
required | ||
:requiredLabel="requiredLabel" | ||
:error-message="error" | ||
@empty="validation.firstName = !$event" | ||
@error="validation.firstName = !$event" | ||
v-if="!readOnlyName" | ||
/> | ||
|
||
<text-input-component | ||
:id="'lastName_' + id" | ||
label="Last name" | ||
placeholder="" | ||
autocomplete="off" | ||
v-model="selectedValue.lastName" | ||
:validations="[ | ||
...getValidations('location.contacts.*.lastName'), | ||
submissionValidation(`location.contacts[${id}].lastName`) | ||
]" | ||
:enabled="true" | ||
required | ||
:requiredLabel="requiredLabel" | ||
:error-message="error" | ||
@empty="validation.lastName = !$event" | ||
@error="validation.lastName = !$event" | ||
v-if="!readOnlyName" | ||
/> | ||
|
||
<text-input-component | ||
:id="'emailAddress_' + id" | ||
label="Email address" | ||
placeholder="" | ||
autocomplete="off" | ||
v-model="selectedValue.email" | ||
:validations="[ | ||
...getValidations('location.addresses.*.email'), | ||
submissionValidation(`location.addresses[${id}].email`) | ||
]" | ||
:enabled="true" | ||
@empty="validation.email = true" | ||
@error="validation.email = !$event" | ||
/> | ||
|
||
<div class="horizontal-input-grouping"> | ||
<text-input-component | ||
:id="'businessPhoneNumber_' + id" | ||
label="Primary phone number" | ||
type="tel" | ||
autocomplete="off" | ||
placeholder="( ) ___-____" | ||
mask="(###) ###-####" | ||
v-model="selectedValue.phoneNumber" | ||
:enabled="true" | ||
:validations="[ | ||
...getValidations('location.addresses.*.phoneNumber'), | ||
submissionValidation(`location.addresses[${id}].phoneNumber`) | ||
]" | ||
@empty="validation.phoneNumber = true" | ||
@error="validation.phoneNumber = !$event" | ||
/> | ||
|
||
<text-input-component | ||
:id="'secondaryPhoneNumber_' + id" | ||
label="Secondary phone number" | ||
type="tel" | ||
autocomplete="off" | ||
placeholder="( ) ___-____" | ||
mask="(###) ###-####" | ||
v-model="selectedValue.secondaryPhoneNumber" | ||
:enabled="true" | ||
:validations="[ | ||
...getValidations('location.addresses.*.secondaryPhoneNumber'), | ||
submissionValidation(`location.addresses[${id}].secondaryPhoneNumber`) | ||
]" | ||
@empty="validation.secondaryPhoneNumber = true" | ||
@error="validation.secondaryPhoneNumber = !$event" | ||
/> | ||
|
||
<text-input-component | ||
:id="'faxNumber_' + id" | ||
label="Fax" | ||
type="tel" | ||
autocomplete="off" | ||
placeholder="( ) ___-____" | ||
mask="(###) ###-####" | ||
v-model="selectedValue.faxNumber" | ||
:enabled="true" | ||
:validations="[ | ||
...getValidations('location.addresses.*.faxNumber'), | ||
submissionValidation(`location.addresses[${id}].faxNumber`) | ||
]" | ||
@empty="validation.faxNumber = true" | ||
@error="validation.faxNumber = !$event" | ||
/> | ||
</div> | ||
|
||
<dropdown-input-component | ||
:id="'role_' + id" | ||
label="Contact type" | ||
tip="" | ||
:initial-value="selectedValue.contactType?.text" | ||
:model-value="roleList" | ||
:validations="[ | ||
...getValidations('location.contacts.*.contactType.text'), | ||
submissionValidation(`location.contacts[${id}].contactType`) | ||
]" | ||
required | ||
:requiredLabel="requiredLabel" | ||
@update:selected-value="updateContactType($event)" | ||
@empty="validation.contactType = !$event" | ||
@error="validation.contactType = !$event" | ||
/> | ||
<multiselect-input-component | ||
:id="'addressname_' + id" | ||
label="Location name" | ||
tip="A contact can have more than one address" | ||
:initial-value="''" | ||
:model-value="addressList" | ||
:selectedValues="selectedValue.locationNames?.map((location:CodeDescrType) => location?.text)" | ||
:validations="[ | ||
...getValidations('location.contacts.*.locationNames'), | ||
submissionValidation(`location.contacts[${id}].locationNames`) | ||
]" | ||
required | ||
:requiredLabel="requiredLabel" | ||
@update:selected-value=" | ||
selectedValue.locationNames = nameTypesToCodeDescr($event) | ||
" | ||
@empty="validation.locationNames = !$event" | ||
@error="validation.locationNames = !$event" | ||
/> | ||
<div class="grouping-06"> | ||
<cds-button | ||
v-if="id > 0" | ||
:id="'deleteContact_' + id" | ||
:danger-descriptor="`Delete contact "${getContactDescription( | ||
selectedValue, | ||
id, | ||
)}"`" | ||
kind="danger--tertiary" | ||
@click.prevent="emit('remove', id)" | ||
> | ||
<span>Delete contact</span> | ||
<Delete16 slot="icon" /> | ||
</cds-button> | ||
</div> | ||
</div> | ||
</template> |
Oops, something went wrong.