Skip to content

Commit 9f6ed56

Browse files
authored
Merge pull request #423 from bcgov/feature/electrification-form-updates
Electrification form updates
2 parents ebf8482 + 2811da8 commit 9f6ed56

File tree

7 files changed

+55
-40
lines changed

7 files changed

+55
-40
lines changed

frontend/src/components/electrification/project/ProjectFormNavigator.vue

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
} from '@/services';
3030
import { useCodeStore, useProjectStore } from '@/store';
3131
import { MIN_SEARCH_INPUT_LENGTH, YES_NO_LIST } from '@/utils/constants/application';
32+
import { BC_HYDRO_POWER_AUTHORITY } from '@/utils/constants/electrification';
3233
import {
3334
APPLICATION_STATUS_LIST,
3435
ATS_ENQUIRY_TYPE_CODE_PROJECT_INTAKE_SUFFIX,
@@ -264,16 +265,25 @@ function onInvalidSubmit(e: GenericObject) {
264265
scrollToFirstError(e.errors);
265266
}
266267
267-
async function onRegisteredNameInput(e: AutoCompleteCompleteEvent) {
268-
if (e?.query?.length >= 2) {
269-
const results = (await externalApiService.searchOrgBook(e.query))?.data?.results ?? [];
268+
async function getOrgBookOptions(companyNameRegistered: string) {
269+
if (companyNameRegistered.length >= 2) {
270+
const results = (await externalApiService.searchOrgBook(companyNameRegistered))?.data?.results ?? [];
270271
orgBookOptions.value = results
271272
.filter((obo: Record<string, string>) => obo.type === 'name')
272273
// map value and topic_source_id for AutoComplete display and selection
273274
.map((obo: Record<string, string>) => ({
274275
registeredName: obo.value,
275276
registeredId: obo.topic_source_id
276277
}));
278+
// If the searched company name includes BC Hydro Power Authority, add it as an option since it is not registered
279+
if (BC_HYDRO_POWER_AUTHORITY.includes(companyNameRegistered.toUpperCase())) {
280+
orgBookOptions.value.push({
281+
registeredName: BC_HYDRO_POWER_AUTHORITY,
282+
registeredId: ''
283+
});
284+
}
285+
// sort options alphabetically
286+
orgBookOptions.value.sort((a, b) => a.registeredName.localeCompare(b.registeredName));
277287
}
278288
}
279289
@@ -392,6 +402,9 @@ onBeforeMount(async () => {
392402
assigneeOptions.value = (await userService.searchUsers({ userId: [project.assignedUserId] })).data;
393403
}
394404
405+
// Load options for org book autocomplete to prevent schema validation errors on existing values
406+
if (project.companyNameRegistered) await getOrgBookOptions(project.companyNameRegistered);
407+
395408
// Default form values
396409
initialFormValues.value = initilizeFormValues(project);
397410
});
@@ -469,7 +482,7 @@ onBeforeMount(async () => {
469482
:placeholder="t('i.common.projectForm.searchBCRegistered')"
470483
:get-option-label="(option: OrgBookOption) => option.registeredName"
471484
:suggestions="orgBookOptions"
472-
@on-complete="onRegisteredNameInput"
485+
@on-complete="(e: AutoCompleteCompleteEvent) => getOrgBookOptions(e.query)"
473486
@on-select="
474487
(orgBookOption: OrgBookOption) => {
475488
setFieldValue('project.companyIdRegistered', orgBookOption.registeredId);

frontend/src/components/electrification/project/ProjectIntakeForm.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { createProjectIntakeSchema } from '@/validators/electrification/projectI
1313
import { Button, Card, Message, useConfirm, useToast } from '@/lib/primevue';
1414
import { documentService, electrificationProjectService, externalApiService } from '@/services';
1515
import { useAppStore, useConfigStore, useCodeStore, useContactStore, useProjectStore } from '@/store';
16+
import { BC_HYDRO_POWER_AUTHORITY } from '@/utils/constants/electrification';
1617
import { RouteName } from '@/utils/enums/application';
1718
import { confirmationTemplateElectrificationSubmission, confirmationTemplateEnquiry } from '@/utils/templates';
1819
import { omit, setEmptyStringsToNull, toTitleCase } from '@/utils/utils';
@@ -140,6 +141,15 @@ async function onRegisteredNameInput(e: AutoCompleteCompleteEvent) {
140141
registeredName: obo.value,
141142
registeredId: obo.topic_source_id
142143
}));
144+
// If the searched company name includes BC Hydro Power Authority, add it as an option since it is not registered
145+
if (BC_HYDRO_POWER_AUTHORITY.includes(e.query.toUpperCase())) {
146+
orgBookOptions.value.push({
147+
registeredName: BC_HYDRO_POWER_AUTHORITY,
148+
registeredId: ''
149+
});
150+
}
151+
// sort options alphabetically
152+
orgBookOptions.value.sort((a, b) => a.registeredName.localeCompare(b.registeredName));
143153
}
144154
}
145155

frontend/src/components/electrification/project/ProjectListNavigatorElectrification.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,20 @@ const { codeDisplay } = codeStore;
8888
style="min-width: 150px"
8989
/>
9090
<Column
91-
field="activity.activity_contact.0.contact.first_name"
91+
field="activity.activityContact.0.contact.firstName"
9292
header="First name"
9393
:sortable="true"
9494
style="min-width: 150px"
9595
/>
9696
<Column
97-
field="activity.activity_contact.0.contact.last_name"
97+
field="activity.activityContact.0.contact.lastName"
9898
header="Last name"
9999
:sortable="true"
100100
style="min-width: 150px"
101101
/>
102102
<Column
103103
field="user.fullName"
104-
header="Assigned-to"
104+
header="Assigned to"
105105
:sortable="true"
106106
style="min-width: 200px"
107107
/>

frontend/src/components/projectCommon/ProjectListNavigator.vue

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { useAppStore, useAuthZStore } from '@/store';
2121
import { APPLICATION_STATUS_LIST } from '@/utils/constants/projectCommon';
2222
import { Action, Initiative } from '@/utils/enums/application';
23-
import { ApplicationStatus } from '@/utils/enums/projectCommon';
23+
import { ActivityContactRole, ApplicationStatus } from '@/utils/enums/projectCommon';
2424
import { projectRouteNameKey, projectServiceKey, resourceKey } from '@/utils/keys';
2525
import { toNumber } from '@/utils/utils';
2626
@@ -77,7 +77,7 @@ const selection: Ref<Project | undefined> = ref(undefined);
7777
const selectedFilter: Ref<FilterOption> = ref(FILTER_OPTIONS[0]!);
7878
7979
/**
80-
* Filter projects based on status
80+
* Filter projects based on status and reduce contacts to primary contact only
8181
* Inject a joined location field for housing for proper sorting and searching
8282
*/
8383
const filteredProjects = computed(() => {
@@ -86,12 +86,27 @@ const filteredProjects = computed(() => {
8686
return selectedFilter.value.statuses.includes(element.applicationStatus);
8787
})
8888
.map((x) => {
89+
const primaryContact = x.activity?.activityContact?.find(
90+
(contact) => contact.role === ActivityContactRole.PRIMARY
91+
);
92+
8993
if ('housingProjectId' in x) {
9094
return {
9195
...x,
92-
location: [x.streetAddress, x.locality, x.province].filter((str) => str?.trim()).join(', ')
96+
location: [x.streetAddress, x.locality, x.province].filter((str) => str?.trim()).join(', '),
97+
activity: {
98+
...x.activity,
99+
activityContact: primaryContact ? [primaryContact] : []
100+
}
101+
};
102+
} else
103+
return {
104+
...x,
105+
activity: {
106+
...x.activity,
107+
activityContact: primaryContact ? [primaryContact] : []
108+
}
93109
};
94-
} else return x;
95110
});
96111
});
97112
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const BC_HYDRO_POWER_AUTHORITY = 'BC HYDRO AND POWER AUTHORITY';

frontend/src/validators/electrification/projectFormNavigatorSchema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function createProjectFormSchema(
3737
project: object({
3838
companyIdRegistered: string().nullable(),
3939
bcEnvironmentAssessNeeded: string().notRequired().oneOf(YES_NO_LIST).label('BC Environmental Assessment needed?'),
40-
bcHydroNumber: string().required().max(255).label('BC Hydro Call for Power project number'),
40+
bcHydroNumber: string().notRequired().max(255).label('BC Hydro Call for Power project number'),
4141
companyNameRegistered: string()
4242
.required()
4343
.max(255)

frontend/tests/unit/components/electrification/project/ProjectForm.spec.ts

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe('onRegisteredNameInput', () => {
9292
vi.clearAllMocks();
9393
});
9494

95-
it('should not call searchOrgBook when query length is less than 2', async () => {
95+
it('should call searchOrgBook once when query length is less than 2', async () => {
9696
const wrapper = mount(ProjectForm, wrapperSettingsForm());
9797
await nextTick();
9898
await nextTick();
@@ -106,10 +106,10 @@ describe('onRegisteredNameInput', () => {
106106
await autoComplete.vm.$emit('on-complete', event);
107107
await nextTick();
108108

109-
expect(searchOrgBookSpy).not.toHaveBeenCalled();
109+
expect(searchOrgBookSpy).toHaveBeenCalledOnce();
110110
});
111111

112-
it('should call searchOrgBook when query length is 2 or more', async () => {
112+
it('should call searchOrgBook twice when query length is 2 or more', async () => {
113113
const mockResponse = {
114114
data: {
115115
results: [
@@ -134,7 +134,7 @@ describe('onRegisteredNameInput', () => {
134134
await autoComplete.vm.$emit('on-complete', event);
135135
await nextTick();
136136

137-
expect(searchOrgBookSpy).toHaveBeenCalledTimes(1);
137+
expect(searchOrgBookSpy).toHaveBeenCalledTimes(2);
138138
expect(searchOrgBookSpy).toHaveBeenCalledWith('Test');
139139
});
140140

@@ -203,30 +203,6 @@ describe('onRegisteredNameInput', () => {
203203
expect(orgBookOptions).toHaveLength(0);
204204
});
205205

206-
it('should handle undefined results from searchOrgBook', async () => {
207-
const mockResponse = {
208-
data: {}
209-
};
210-
211-
searchOrgBookSpy.mockResolvedValue(mockResponse as AxiosResponse);
212-
213-
const wrapper = mount(ProjectForm, wrapperSettingsForm());
214-
await nextTick();
215-
await nextTick();
216-
217-
const event: AutoCompleteCompleteEvent = {
218-
query: 'Test',
219-
originalEvent: new Event('input')
220-
};
221-
222-
const autoComplete = wrapper.findComponent({ name: 'AutoComplete' });
223-
await autoComplete.vm.$emit('on-complete', event);
224-
await nextTick();
225-
226-
const orgBookOptions = (wrapper.vm as any).orgBookOptions; // eslint-disable-line @typescript-eslint/no-explicit-any
227-
expect(orgBookOptions).toHaveLength(0);
228-
});
229-
230206
it('should handle results with only non-name types', async () => {
231207
const mockResponse = {
232208
data: {

0 commit comments

Comments
 (0)