Skip to content

Commit

Permalink
Load all required form data at once
Browse files Browse the repository at this point in the history
  • Loading branch information
kyle1morel committed Dec 4, 2023
1 parent 339ded3 commit 57469a6
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 72 deletions.
10 changes: 6 additions & 4 deletions app/src/controllers/chefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ import type { ChefsFormConfig, ChefsFormConfigData } from '../types/ChefsFormCon
import type { ChefsSubmissionDataSource } from '../types/ChefsSubmissionDataSource';

const controller = {
getSubmissions: async (req: Request, res: Response, next: NextFunction) => {
getFormExport: async (req: Request, res: Response, next: NextFunction) => {
try {
const cfg = config.get('server.chefs.forms') as ChefsFormConfig;
let formData = new Array<ChefsSubmissionDataSource>();

// Get a JSON export of all form data merged into a single array
await Promise.all(
Object.values<ChefsFormConfigData>(cfg).map(async (x: ChefsFormConfigData) => {
const data = await chefsService.getFormSubmissions(x.id);
const data = await chefsService.getFormExport(x.id);
data.forEach((d: ChefsSubmissionDataSource) => (d.form.id = x.id));
formData = formData.concat(data);
})
);
Expand All @@ -33,8 +35,8 @@ const controller = {

if (isTruthy(filterToUser)) {
return data.filter(
(x: { createdBy: string }) =>
x.createdBy.toUpperCase().substring(0, x.createdBy.indexOf('@')) ===
(x: { form: { username: string } }) =>
x.form.username.toUpperCase().substring(0, x.form.username.indexOf('@')) ===
(req.currentUser?.tokenPayload as JwtPayload).bceid_username.toUpperCase()
);
} else {
Expand Down
4 changes: 2 additions & 2 deletions app/src/routes/v1/chefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const router = express.Router();
router.use(requireSomeAuth);

// Submission endpoint
router.get('/submissions', (req: Request, res: Response, next: NextFunction): void => {
chefsController.getSubmissions(req, res, next);
router.get('/export', (req: Request, res: Response, next: NextFunction): void => {
chefsController.getFormExport(req, res, next);
});

// Submission endpoint
Expand Down
6 changes: 4 additions & 2 deletions app/src/services/chefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ function chefsAxios(formId: string, options: AxiosRequestConfig = {}): AxiosInst
}

const service = {
getFormSubmissions: async (formId: string) => {
getFormExport: async (formId: string) => {
try {
const response = await chefsAxios(formId).get(`forms/${formId}/submissions`);
const response = await chefsAxios(formId).get(`forms/${formId}/export`, {
params: { format: 'json', type: 'submissions' }
});
return response.data;
} catch (e: unknown) {
throw e;
Expand Down
24 changes: 15 additions & 9 deletions app/src/types/ChefsSubmissionDataSource.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
export type ChefsSubmissionDataSource = {
confirmationId: string;
createdAt: string;
formId: string;
formSubmissionStatusCode: string;
submissionId: string;
deleted: boolean;
createdBy: string;
formVersionId: string;
lateEntry: boolean;
form: {
id: string;
submissionId: string;
confirmationId: string;
formName: string;
version: number;
createdAt: string;
fullName: string;
username: string;
email: string;
status: string;
assignee: string;
assigneedEmail: string;
};
// Additional form field data will be added
};
6 changes: 3 additions & 3 deletions frontend/src/services/chefsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { appAxios } from './interceptors';

export default {
/**
* @function getSubmissions
* @function getFormExport
* @returns {Promise} An axios response
*/
getSubmissions() {
return appAxios().get('chefs/submissions');
getFormExport() {
return appAxios().get('chefs/export');
},

/**
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/views/InitiativesView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { RouteNames } from '@/utils/constants';
</script>

<template>
<h1>Submissions</h1>

<router-link :to="{ name: RouteNames.SUBMISSIONS }">
<Button>Housing</Button>
</router-link>
Expand Down
73 changes: 21 additions & 52 deletions frontend/src/views/SubmissionsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import { formatDateShort, formatJwtUsername } from '@/utils/formatters';
import type { Ref } from 'vue';
// State
const loading: Ref<boolean> = ref(false);
const submissions: Ref<Array<any>> = ref([]);
const displayRowsPerPage: Ref<number> = ref(10);
const topTableRowEntry: Ref<number> = ref(0);
// Datatable filter(s)
const filters = ref({
Expand All @@ -21,36 +20,10 @@ const filters = ref({
// Actions
onMounted(async () => {
submissions.value = (await chefsService.getSubmissions()).data;
updateFormsObject();
loading.value = true;
submissions.value = (await chefsService.getFormExport()).data;
loading.value = false;
});
// Tracks how many rows displayed
const updateRowsPerPage = (rowNumber: number) => {
displayRowsPerPage.value = rowNumber;
updateFormsObject();
};
// Only retrieve submissions data from rows displayed in table
const updateFormsObject = async () => {
for (let i = topTableRowEntry.value; i < topTableRowEntry.value+displayRowsPerPage.value; i++) {
if (submissions.value[i]?.retrieved) {
continue;
}
chefsService.getSubmission(submissions.value[i].formId, submissions.value[i].submissionId).then((res) => {
submissions.value[i] = {
retrieved: true,
...submissions.value[i],
...res?.data?.submission?.submission?.data
};
});
}
};
// Tracks the first submission entry displayed by table
const updateFirst = (firstRow: number) => {
topTableRowEntry.value = firstRow;
};
</script>

<template>
Expand All @@ -60,19 +33,17 @@ const updateFirst = (firstRow: number) => {
<div class="flex-grow-1">
<DataTable
v-model:filters="filters"
:loading="false"
:loading="loading"
:value="submissions"
data-key="id"
class="p-datatable-sm"
responsive-layout="scroll"
:paginator="true"
:rows="displayRowsPerPage"
:rows="10"
paginator-template="RowsPerPageDropdown CurrentPageReport PrevPageLink NextPageLink "
current-page-report-template="{first}-{last} of {totalRecords}"
:rows-per-page-options="[10, 20, 50]"
:global-filter-fields="['confirmationId', 'createdBy']"
@update:rows="updateRowsPerPage"
@update:first="updateFirst"
:global-filter-fields="['form.confirmationId', 'form.username']"
>
<template #empty>
<div class="flex justify-content-center">
Expand All @@ -88,30 +59,30 @@ const updateFirst = (firstRow: number) => {
<i class="pi pi-search" />
<InputText
v-model="filters['global'].value"
v-tooltip.bottom="'Search by confirmation ID or submitting user'"
placeholder="Search"
/>
</span>
</div>
</template>
<Column
header="Submission Id"
field="form.confirmationId"
header="Confirmation Id"
:sortable="true"
>
<template #body="{ data }">
<div>
<div :data-submissionId="data.form.submissionId">
<router-link
:to="{ name: RouteNames.SUBMISSION, query: { formId: data.formId, submissionId: data.submissionId } }"
:to="{
name: RouteNames.SUBMISSION,
query: { formId: data.form.id, submissionId: data.form.submissionId }
}"
>
{{ data.submissionId }}
{{ data.form.confirmationId }}
</router-link>
</div>
</template>
</Column>
<Column
field="confirmationId"
header="Confirmation Id"
:sortable="true"
/>
<Column
field="projectName"
header="Project Name"
Expand Down Expand Up @@ -141,9 +112,7 @@ const updateFirst = (firstRow: number) => {
header="Assignee"
:sortable="true"
/>
<Column
header="Address"
>
<Column header="Address">
<template #body="{ data }">
{{ data?.locationProvided?.fullAddress ?? '' }}
</template>
Expand All @@ -159,21 +128,21 @@ const updateFirst = (firstRow: number) => {
:sortable="true"
/>
<Column
field="createdBy"
field="form.username"
header="Created By"
:sortable="true"
>
<template #body="{ data }">
{{ formatJwtUsername(data?.createdBy) }}
{{ formatJwtUsername(data?.form.username) }}
</template>
</Column>
<Column
field="createdAt"
field="form.createdAt"
header="Submission Date"
:sortable="true"
>
<template #body="{ data }">
{{ formatDateShort(data?.createdAt) }}
{{ formatDateShort(data?.form.createdAt) }}
</template>
</Column>
</DataTable>
Expand Down

0 comments on commit 57469a6

Please sign in to comment.