Skip to content

Commit e83af63

Browse files
authored
Merge pull request #960 from CDLUC3/feature/947/JS-update-subdomain-on-Project-Details-page
Updated Project Details page to hide subDomain field until user selects a research domain
2 parents e8224d3 + 22febc5 commit e83af63

File tree

7 files changed

+125
-123
lines changed

7 files changed

+125
-123
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- Hooked up the `Download plan` page and added a `download-narrative` api endpoint [#313]
44

55
### Updated
6+
- Updated Project Details subdomains field to only display once a user selects a research domain [#947]
67

78
### Fixed
89

app/[locale]/projects/[projectId]/project/page.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,12 @@ import { getCalendarDateValue } from "@/utils/dateUtils";
4040
import { scrollToTop } from '@/utils/general';
4141
import { logECS, routePath } from '@/utils/index';
4242
import { useToast } from '@/context/ToastContext';
43+
import { ProjectDetailsFormInterface } from "@/app/types";
4344

44-
interface ProjectFormErrorsInterface {
45-
projectName: string;
46-
projectAbstract: string;
47-
}
4845

49-
interface ProjectDetailsFormInterface {
46+
interface ProjectFormErrorsInterface {
5047
projectName: string;
5148
projectAbstract: string;
52-
startDate: string | CalendarDate | null;
53-
endDate: string | CalendarDate | null;
54-
researchDomainId: string | number;
55-
isTestProject: string | boolean;
56-
parentResearchDomainId: string | number;
5749
}
5850

5951
const ProjectsProjectDetail = () => {

app/types/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ReactNode } from "react";
22
import { PlanSectionProgress, TemplateVisibility, PlanFeedback, ProjectFundingStatus } from "@/generated/graphql";
33
import { AffiliationSearchQuestionType, AnyQuestionType } from '@dmptool/types';
4+
import { CalendarDate } from "@internationalized/date";
45

56
// Re-export types from questionAdd module
67
export * from './questionAdd';
@@ -513,3 +514,14 @@ export interface ProjectFundingInterface {
513514
funderOpportunityNumber: string;
514515
funderProjectNumber: string;
515516
}
517+
518+
export interface ProjectDetailsFormInterface {
519+
projectName: string;
520+
projectAbstract: string;
521+
startDate: string | CalendarDate | null;
522+
endDate: string | CalendarDate | null;
523+
researchDomainId: string | number;
524+
isTestProject: string | boolean;
525+
parentResearchDomainId: string | number;
526+
}
527+

components/ResearchDomainCascadingDropdown/__tests__/index.spec.tsx

Lines changed: 76 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,30 @@ describe('ResearchDomainCascadingDropdown', () => {
3333
refetch: jest.fn(),
3434
});
3535

36+
const mockProjectData = {
37+
projectName: 'Test Project',
38+
projectAbstract: 'This is a test project.',
39+
startDate: '2023-01-01',
40+
endDate: '2023-12-31',
41+
parentResearchDomainId: '2',
42+
researchDomainId: '3',
43+
isTestProject: false
44+
};
45+
3646
render(
3747
<ResearchDomainCascadingDropdown
38-
projectData={{}}
48+
projectData={mockProjectData}
3949
setProjectData={mockSetProjectData}
4050
/>
4151
);
4252

43-
expect(screen.getByText(/labels.researchDomain/i)).toBeInTheDocument();
44-
expect(await screen.findByText('Domain 1')).toBeInTheDocument();
45-
expect(await screen.findByText('Domain 2')).toBeInTheDocument();
53+
const hiddenContainers = screen.getAllByTestId('hidden-select-container');
54+
const select = hiddenContainers[0].querySelector('select[name="researchDomain"]');
55+
const options = select?.querySelectorAll('option');
56+
const domain1Option = Array.from(options || []).find(opt => opt.textContent === 'Domain 1');
57+
const domain2Option = Array.from(options || []).find(opt => opt.textContent === 'Domain 2');
58+
expect(domain1Option).toBeInTheDocument();
59+
expect(domain2Option).toBeInTheDocument();
4660
});
4761

4862
it('should set correct parent and child values on page load', async () => {
@@ -79,10 +93,14 @@ describe('ResearchDomainCascadingDropdown', () => {
7993
});
8094

8195
const mockSetProjectData = jest.fn();
96+
8297
const mockProjectData = {
98+
projectName: 'Test Project',
99+
projectAbstract: 'This is a test project.',
100+
startDate: '2023-01-01',
101+
endDate: '2023-12-31',
83102
parentResearchDomainId: '1',
84103
researchDomainId: '3',
85-
projectName: 'Test Project',
86104
isTestProject: false
87105
};
88106

@@ -145,9 +163,18 @@ describe('ResearchDomainCascadingDropdown', () => {
145163
refetch: refetchMock,
146164
}));
147165

166+
const mockProjectData = {
167+
projectName: 'Test Project',
168+
projectAbstract: 'This is a test project.',
169+
startDate: '2023-01-01',
170+
endDate: '2023-12-31',
171+
parentResearchDomainId: '2',
172+
researchDomainId: '3',
173+
isTestProject: false
174+
};
148175
render(
149176
<ResearchDomainCascadingDropdown
150-
projectData={{}}
177+
projectData={mockProjectData}
151178
setProjectData={mockSetProjectData}
152179
/>
153180
);
@@ -166,26 +193,27 @@ describe('ResearchDomainCascadingDropdown', () => {
166193
expect(refetchMock).toHaveBeenCalledWith({ parentResearchDomainId: 1 });
167194
});
168195

169-
// Trigger re-render to reflect updated child domains
170-
171196
// Find and click the child select button to open the dropdown
172-
const childDropdownButton = selectButtons[1];
197+
const childDropdownButton = screen.getAllByTestId('select-button')[1];
173198
fireEvent.click(childDropdownButton);
174199

175-
// Confirm child dropdown updated
176-
const childOption1 = await screen.findAllByText(/Child Domain 1/i);
177-
const childOption2 = await screen.findAllByText(/Child Domain 2/i);
178-
expect(childOption1[0]).toBeInTheDocument();
179-
expect(childOption2[0]).toBeInTheDocument();
200+
// Wait for the child dropdown options to appear and select one
201+
const childOptions = await screen.findAllByRole('option', { name: 'Child Domain 1' });
202+
await userEvent.click(childOptions[0]);
180203

181-
// Select a child option
182-
await userEvent.click(childOption1[0]);
204+
// Assert that mockSetProjectData was called with the correct value
183205
expect(mockSetProjectData).toHaveBeenCalledWith({
184206
researchDomainId: '1',
207+
endDate: '2023-12-31',
208+
startDate: '2023-01-01',
209+
projectAbstract: 'This is a test project.',
210+
projectName: 'Test Project',
211+
isTestProject: false,
212+
parentResearchDomainId: '2'
185213
});
186214
});
187215

188-
it('should set child list to empty array if parentResearchDomainId is missing', async () => {
216+
it('should not display subdomains if parent domain is not selected', async () => {
189217
// Explicitly define the type for childDomainsData
190218
let childDomainsData: { childResearchDomains: { id: number; name: string, description: string }[] } = { childResearchDomains: [] };
191219

@@ -217,53 +245,26 @@ describe('ResearchDomainCascadingDropdown', () => {
217245
refetch: refetchMock,
218246
}));
219247

248+
249+
const mockProjectData = {
250+
projectName: 'Test Project',
251+
projectAbstract: 'This is a test project.',
252+
startDate: '2023-01-01',
253+
endDate: '2023-12-31',
254+
parentResearchDomainId: '',
255+
researchDomainId: '3',
256+
isTestProject: false
257+
};
258+
220259
render(
221260
<ResearchDomainCascadingDropdown
222-
projectData={{}}
261+
projectData={mockProjectData}
223262
setProjectData={mockSetProjectData}
224263
/>
225264
);
226265

227-
// Find and click the parent select button to open the dropdown
228-
const selectButtons = screen.getAllByTestId('select-button');
229-
const parentDropdownButton = selectButtons[0];
230-
fireEvent.click(parentDropdownButton);
231-
232-
// Wait for the dropdown item to appear
233-
const options = await screen.findAllByRole('option', { name: 'Domain 1' });
234-
await userEvent.click(options[0]);
235-
236-
// Find and click the child select button to open the dropdown
237-
const childDropdownButton = selectButtons[1];
238-
fireEvent.click(childDropdownButton);
239-
240-
// Get all elements with the same data-testid
241-
const hiddenContainers = screen.getAllByTestId('hidden-select-container');
242-
243-
// Find the correct container by looking for the <select> with name="childDomain"
244-
const correctContainer = hiddenContainers.find(container =>
245-
container.querySelector('select[name="childDomain"]')
246-
);
247-
248-
// Assert that the correct container was found
249-
expect(correctContainer).toBeDefined();
250-
251-
// Query the <select> element inside the correct container
252-
const hiddenChildDomainSelect = correctContainer?.querySelector('select[name="childDomain"]');
253-
254-
// Assert that the <select> element exists and is disabled
255-
expect(hiddenChildDomainSelect).toBeDisabled();
256-
257-
// Assert that there are no options within the <select>
258-
const childOptions = hiddenChildDomainSelect?.querySelectorAll('option');
259-
260-
// Filter out empty or placeholder options
261-
const meaningfulOptions = Array.from(childOptions || []).filter(
262-
option => option.value.trim() !== '' || option.textContent?.trim() !== ''
263-
);
264-
265-
// Assert that there are no meaningful options
266-
expect(meaningfulOptions.length).toBe(0);
266+
const subdomainSelect = screen.queryByTestId('subdomain-select');
267+
expect(subdomainSelect).not.toBeInTheDocument();
267268
});
268269

269270

@@ -299,9 +300,19 @@ describe('ResearchDomainCascadingDropdown', () => {
299300
refetch: refetchMock,
300301
}));
301302

303+
const mockProjectData = {
304+
projectName: 'Test Project',
305+
projectAbstract: 'This is a test project.',
306+
startDate: '2023-01-01',
307+
endDate: '2023-12-31',
308+
parentResearchDomainId: '2',
309+
researchDomainId: '3',
310+
isTestProject: false
311+
};
312+
302313
render(
303314
<ResearchDomainCascadingDropdown
304-
projectData={{}}
315+
projectData={mockProjectData}
305316
setProjectData={mockSetProjectData}
306317
/>
307318
);
@@ -330,6 +341,12 @@ describe('ResearchDomainCascadingDropdown', () => {
330341
// Assert that mockSetProjectData was called with the correct value
331342
expect(mockSetProjectData).toHaveBeenCalledWith({
332343
researchDomainId: '1',
344+
endDate: '2023-12-31',
345+
startDate: '2023-01-01',
346+
projectAbstract: 'This is a test project.',
347+
projectName: 'Test Project',
348+
isTestProject: false,
349+
parentResearchDomainId: '2'
333350
});
334351
});
335352
});

0 commit comments

Comments
 (0)