Skip to content

Commit

Permalink
ATS client push UI: New ATSUserCreateModal, SubmissionForm, ATSUserLi…
Browse files Browse the repository at this point in the history
…nkModal, atsService updated
  • Loading branch information
sanjaytkbabu committed Oct 29, 2024
1 parent f8b24e6 commit e54fdce
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 10 deletions.
26 changes: 23 additions & 3 deletions frontend/src/components/housing/submission/SubmissionForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
TextArea
} from '@/components/form';
import ATSUserLinkModal from '@/components/user/ATSUserLinkModal.vue';
import ATSUserCreateModal from '@/components/user/ATSUserCreateModal.vue';
import ATSUserDetailsModal from '@/components/user/ATSUserDetailsModal.vue';
import { Button, Message, useToast } from '@/lib/primevue';
import { submissionService, userService } from '@/services';
Expand Down Expand Up @@ -60,6 +61,7 @@ const assigneeOptions: Ref<Array<User>> = ref([]);
const atsClientNumber: Ref<string | undefined> = ref(undefined);
const atsUserLinkModalVisible: Ref<boolean> = ref(false);
const atsUserDetailsModalVisible: Ref<boolean> = ref(false);
const atsUserCreateModalVisible: Ref<boolean> = ref(false);
const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
const initialFormValues: Ref<any | undefined> = ref(undefined);
const showCancelMessage: Ref<boolean> = ref(false);
Expand Down Expand Up @@ -632,7 +634,15 @@ onMounted(async () => {
class="h-2rem ml-2"
@click="atsUserLinkModalVisible = true"
>
Link to ATS
Search ATS
</Button>
<Button
v-if="!atsClientNumber"
aria-label="New ATS client"
class="h-2rem ml-4"
@click="atsUserCreateModalVisible = true"
>
New ATS Client
</Button>
</div>
<Checkbox
Expand Down Expand Up @@ -723,8 +733,7 @@ onMounted(async () => {
</div>
<ATSUserLinkModal
v-model:visible="atsUserLinkModalVisible"
:f-name="values.contactFirstName"
:l-name="values.contactLastName"
:submission="submission"
@ats-user-link:link="
(atsUser: ATSUser) => {
atsClientNumber = atsUser.atsClientNumber;
Expand All @@ -743,6 +752,17 @@ onMounted(async () => {
}
"
/>
<ATSUserCreateModal
v-model:visible="atsUserCreateModalVisible"
:submission="submission"
@ats-user-link:link="
(atsClientId: string) => {
atsClientNumber = atsClientId;
submissionStore.setSubmission({ ...submission, atsClientNumber: atsClientId ?? null });
atsUserCreateModalVisible = false;
}
"
/>
</Form>
</template>

Expand Down
171 changes: 171 additions & 0 deletions frontend/src/components/user/ATSUserCreateModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<script setup lang="ts">
import axios from 'axios';
import { onMounted, ref } from 'vue';
import { Button, Column, DataTable, Dialog, useToast } from '@/lib/primevue';
import { Spinner } from '@/components/layout';
import { atsService } from '@/services';
import { BasicResponse } from '@/utils/enums/application';
import type { Ref } from 'vue';
import type { ATSUser, Submission } from '@/types';
// Props
const { submission } = defineProps<{
submission: Submission;
}>();
// Emits
const emit = defineEmits(['atsUserLink:link']);
// Constants
const REGION_BC = 'BC';
// State
const atsClientNumber: Ref<string> = ref('');
const loading: Ref<boolean> = ref(false);
const proponent: Ref<ATSUser | undefined> = ref(undefined);
const selectedUser: Ref<ATSUser | undefined> = ref(undefined);
const visible = defineModel<boolean>('visible');
// Actions
const toast = useToast();
async function createATSClient() {
selectedUser.value = undefined;
try {
loading.value = true;
const data = setEmptyStringsToNullAndOmitNulls({
'@type': 'ClientResource',
address: {
'@type': 'AddressResource',
addressLine1: submission.streetAddress,
city: submission.locality,
provinceCode: submission.province,
primaryPhone: submission.contactPhoneNumber,
email: submission.contactEmail
},
firstName: submission.contactFirstName,
surName: submission.contactLastName,
regionName: REGION_BC,
optOutOfBCStatSurveyInd: BasicResponse.NO.toUpperCase()
});
const response = await atsService.createATSClient(data);
if (response.status === 201) {
atsClientNumber.value = response.data.clientId;
emit('atsUserLink:link', atsClientNumber.value);
toast.success('New client pushed to ATS');
} else {
toast.error('Error pushing client to ATS');
}
} catch (error) {
if (!axios.isCancel(error)) toast.error('Error pushing client to ATS ' + error);
} finally {
loading.value = false;
}
}
function setEmptyStringsToNullAndOmitNulls(obj: Record<string, any>): Record<string, any> {
const result: Record<string, any> = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
if (typeof obj[key] === 'string' && obj[key].trim() === '') {
// Skip adding this key if the value is an empty string
continue;
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
const nestedResult = setEmptyStringsToNullAndOmitNulls(obj[key]);
if (Object.keys(nestedResult).length > 0) {
result[key] = nestedResult;
}
} else if (obj[key] !== null) {
result[key] = obj[key];
}
}
}
return result;
}
onMounted(async () => {
const locationAddressStr = [submission.streetAddress, submission.locality, submission.province]
.filter((str) => str?.trim())
.join(', ');
proponent.value = {
firstName: submission.contactFirstName ?? '',
lastName: submission.contactLastName ?? '',
email: submission.contactEmail ?? '',
address: locationAddressStr,
phone: submission.contactPhoneNumber ?? ''
};
});
</script>

<template>
<Dialog
v-model:visible="visible"
:draggable="false"
:modal="true"
class="app-info-dialog w-max"
>
<template #header>
<span class="p-dialog-title title-colour">Create new client in ATS</span>
</template>
<div>
<DataTable
:row-hover="true"
class="datatable mt-3 mb-4"
:value="[proponent]"
selection-mode="single"
:rows="1"
>
<template #empty>
<div class="flex justify-content-center">
<h5 class="m-0">No users found.</h5>
</div>
</template>
<template #loading>
<Spinner />
</template>

<Column
field="firstName"
header="First Name"
/>
<Column
field="lastName"
header="Last Name"
/>
<Column
field="lastName"
header="Phone"
/>
<Column
field="email"
header="Email"
/>
<Column
field="address"
header="Location address"
/>
</DataTable>
<div class="flex justify-content-end">
<Button
class="p-button-solid"
label="Push to ATS"
icon="pi pi-upload"
visible="false"
@click="createATSClient()"
/>
</div>
</div>
</Dialog>
</template>
<style scoped lang="scss">
.title-colour {
color: $app-primary;
}
</style>
32 changes: 25 additions & 7 deletions frontend/src/components/user/ATSUserLinkModal.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
<script setup lang="ts">
import axios from 'axios';
import { onMounted, ref } from 'vue';
import { Button, Column, DataTable, Dialog, InputText, useToast } from '@/lib/primevue';
import { Spinner } from '@/components/layout';
import { Button, Column, DataTable, Dialog, InputText, useToast } from '@/lib/primevue';
import { atsService } from '@/services';
import type { Ref } from 'vue';
import type { ATSUser } from '@/types';
import type { ATSUser, Submission } from '@/types';
// Props
const { fName, lName } = defineProps<{
fName: string;
lName: string;
const { submission } = defineProps<{
submission: Submission;
}>();
// Emits
Expand All @@ -25,7 +24,9 @@ const firstName: Ref<string> = ref('');
const lastName: Ref<string> = ref('');
const loading: Ref<boolean> = ref(false);
const phone: Ref<string> = ref('');
const proponent: Ref<ATSUser | undefined> = ref(undefined);
const selectedUser: Ref<ATSUser | undefined> = ref(undefined);
const showCreateATS = defineModel<boolean>('showCreateATS');
const users: Ref<Array<ATSUser>> = ref([]);
const visible = defineModel<boolean>('visible');
Expand All @@ -46,6 +47,8 @@ async function searchATSUsers() {
email: email.value
});
showCreateATS.value = true;
users.value = response.data.clients.map((client: any) => {
// Combine address lines and filter out empty lines
const address = [client.address.addressLine1, client.address.addressLine2].filter((line) => line).join(', ');
Expand All @@ -67,8 +70,21 @@ async function searchATSUsers() {
}
onMounted(async () => {
firstName.value = fName;
lastName.value = lName;
if (submission.contactFirstName && submission.contactLastName) {
firstName.value = submission.contactFirstName;
lastName.value = submission.contactLastName;
}
const locationAddressStr = [submission.streetAddress, submission.locality, submission.province]
.filter((str) => str?.trim())
.join(', ');
proponent.value = {
firstName: submission.contactFirstName ?? '',
lastName: submission.contactLastName ?? '',
email: submission.contactEmail ?? '',
address: locationAddressStr,
phone: submission.contactPhoneNumber ?? ''
};
});
</script>

Expand Down Expand Up @@ -136,6 +152,8 @@ onMounted(async () => {
data-key="atsClientNumber"
:rows="5"
:paginator="true"
paginator-template="RowsPerPageDropdown CurrentPageReport PrevPageLink NextPageLink "
current-page-report-template="{first}-{last} of {totalRecords}"
>
<template #empty>
<div class="flex justify-content-center">
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/services/atsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,13 @@ export default {

searchATSUsers(params?: any) {
return appAxios().get('ats/clients', { params: params });
},

/**
* @function createATSClient
* @returns {Promise} An axios response
*/
createATSClient(data?: any) {
return appAxios().post('ats/client', data);
}
};

0 comments on commit e54fdce

Please sign in to comment.