Skip to content

Commit

Permalink
feat(FSADT1-1347): contact for staff page
Browse files Browse the repository at this point in the history
  • Loading branch information
paulushcgcj committed Jul 11, 2024
1 parent c7d6028 commit e4a8dc7
Show file tree
Hide file tree
Showing 3 changed files with 640 additions and 2 deletions.
278 changes: 278 additions & 0 deletions frontend/src/components/grouping/StaffContactGroupComponent.vue
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 &quot;${getContactDescription(
selectedValue,
id,
)}&quot;`"
kind="danger--tertiary"
@click.prevent="emit('remove', id)"
>
<span>Delete contact</span>
<Delete16 slot="icon" />
</cds-button>
</div>
</div>
</template>
Loading

0 comments on commit e4a8dc7

Please sign in to comment.