From 85f731110ca8e142767ce296c13a4da94f642718 Mon Sep 17 00:00:00 2001 From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Date: Fri, 29 Apr 2022 14:09:53 +0300 Subject: [PATCH] Merge pull request #7786 from overleaf/ii-departments-override Override default departments GitOrigin-RevId: 23061bc8c083bb8099ca62bd0cdb3c796e49979d --- .../settings/components/emails/add-email.tsx | 19 ++++++++++-- .../emails/institution-and-role.tsx | 28 ++++++++++++++--- .../stories/settings/helpers/emails.js | 29 ++++++++++++++++-- .../emails-section-add-new-email.test.tsx | 22 ++++++++++---- ...ails-section-institution-and-role.test.tsx | 30 +++++++++++++++++++ services/web/types/university.ts | 2 +- 6 files changed, 114 insertions(+), 16 deletions(-) diff --git a/services/web/frontend/js/features/settings/components/emails/add-email.tsx b/services/web/frontend/js/features/settings/components/emails/add-email.tsx index 584ccb0fb2..906e65c034 100644 --- a/services/web/frontend/js/features/settings/components/emails/add-email.tsx +++ b/services/web/frontend/js/features/settings/components/emails/add-email.tsx @@ -9,8 +9,8 @@ import { AddEmailInput, InstitutionInfo } from './add-email-input' import useAsync from '../../../../shared/hooks/use-async' import { useUserEmailsContext } from '../../context/user-email-context' import { getJSON, postJSON } from '../../../../infrastructure/fetch-json' -import { defaults as roles } from '../../roles' -import { defaults as departments } from '../../departments' +import { defaults as defaultRoles } from '../../roles' +import { defaults as defaultDepartments } from '../../departments' import { University } from '../../../../../../types/university' import { CountryCode } from '../../../../../../types/country' import { ExposedSettings } from '../../../../../../types/exposed-settings' @@ -49,6 +49,7 @@ function AddEmail() { const [university, setUniversity] = useState('') const [role, setRole] = useState('') const [department, setDepartment] = useState('') + const [departments, setDepartments] = useState(defaultDepartments) const [isInstitutionFieldsVisible, setIsInstitutionFieldsVisible] = useState(false) const [isUniversityDirty, setIsUniversityDirty] = useState(false) @@ -70,6 +71,18 @@ function AddEmail() { } }, [setIsUniversityDirty, university]) + useEffect(() => { + const selectedKnownUniversity = countryCode + ? universities[countryCode]?.find(({ name }) => name === university) + : undefined + + if (selectedKnownUniversity && selectedKnownUniversity.departments.length) { + setDepartments(selectedKnownUniversity.departments) + } else { + setDepartments(defaultDepartments) + } + }, [countryCode, universities, university]) + // Fetch country institution useEffect(() => { // Skip if country not selected or universities for @@ -222,7 +235,7 @@ function AddEmail() { <>
{ setUserEmailsContextLoading(isLoading) @@ -34,6 +37,23 @@ function InstitutionAndRole({ userEmailData }: InstitutionAndRoleProps) { const handleChangeAffiliation = () => { setEmailAffiliationBeingEdited(userEmailData.email) + + if (!affiliation?.institution.id) { + return + } + + changeAffiliationAsync + .runAsync( + getJSON(`/institutions/list/${affiliation.institution.id}`) + ) + .then(data => { + if (data.departments.length) { + setDepartments(data.departments) + } + }) + .catch(() => { + setDepartments(defaultDepartments) + }) } const handleCancelAffiliationChange = () => { @@ -87,7 +107,7 @@ function InstitutionAndRole({ userEmailData }: InstitutionAndRoleProps) {
', function () { await screen.findByRole('link', { name: 'Link Accounts and Add Email' }) }) - it('adds new email address with existing institution', async function () { + it('adds new email address with existing institution and custom departments', async function () { const country = 'Germany' + const customDepartment = 'Custom department' fetchMock.get('/user/emails?ensureAffiliation=true', []) render() @@ -225,7 +226,7 @@ describe('', function () { id: userEmailData.affiliation.institution.id, name: userEmailData.affiliation.institution.name, country_code: 'de', - departments: [], + departments: [customDepartment], }, ]) @@ -252,10 +253,19 @@ describe('', function () { const roleInput = screen.getByRole('textbox', { name: /role/i }) await userEvent.type(roleInput, userEmailData.affiliation.role) const departmentInput = screen.getByRole('textbox', { name: /department/i }) - await userEvent.type(departmentInput, userEmailData.affiliation.department) + await userEvent.click(departmentInput) + await userEvent.click(screen.getByText(customDepartment)) + + const userEmailDataCopy = { + ...userEmailData, + affiliation: { + ...userEmailData.affiliation, + department: customDepartment, + }, + } fetchMock - .get('/user/emails?ensureAffiliation=true', [userEmailData]) + .get('/user/emails?ensureAffiliation=true', [userEmailDataCopy]) .post(/\/user\/emails/, 200) await userEvent.click( @@ -272,13 +282,13 @@ describe('', function () { id: userEmailData.affiliation?.institution.id, }, role: userEmailData.affiliation?.role, - department: userEmailData.affiliation?.department, + department: customDepartment, }) screen.getByText(userEmailData.email) screen.getByText(userEmailData.affiliation.institution.name) screen.getByText(userEmailData.affiliation.role, { exact: false }) - screen.getByText(userEmailData.affiliation.department, { exact: false }) + screen.getByText(customDepartment, { exact: false }) }) it('adds new email address without existing institution', async function () { diff --git a/services/web/test/frontend/features/settings/components/emails/emails-section-institution-and-role.test.tsx b/services/web/test/frontend/features/settings/components/emails/emails-section-institution-and-role.test.tsx index 06e3719b5b..56e48b38c5 100644 --- a/services/web/test/frontend/features/settings/components/emails/emails-section-institution-and-role.test.tsx +++ b/services/web/test/frontend/features/settings/components/emails/emails-section-institution-and-role.test.tsx @@ -111,9 +111,39 @@ describe('user role and institution', function () { .to.not.exist }) + it('fetches institution data and replaces departments dropdown on add/change', async function () { + const userEmailData = userData1 + fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailData]) + render() + + await fetchMock.flush(true) + fetchMock.reset() + + const fakeDepartment = 'Fake department' + const institution = userEmailData.affiliation.institution + fetchMock.get(`/institutions/list/${institution.id}`, { + id: institution.id, + name: institution.name, + country_code: 'de', + departments: [fakeDepartment], + }) + + fireEvent.click( + screen.getByRole('button', { name: /add role and department/i }) + ) + + await fetchMock.flush(true) + fetchMock.reset() + + fireEvent.click(screen.getByRole('textbox', { name: /department/i })) + + screen.getByText(fakeDepartment) + }) + it('adds new role and department', async function () { fetchMock .get('/user/emails?ensureAffiliation=true', [userData1]) + .get(/\/institutions\/list/, { departments: [] }) .post('/user/emails/endorse', 200) render() diff --git a/services/web/types/university.ts b/services/web/types/university.ts index 6447325e76..a6377d6dbf 100644 --- a/services/web/types/university.ts +++ b/services/web/types/university.ts @@ -4,5 +4,5 @@ export type University = { id: number name: string country_code: CountryCode - departments: unknown[] + departments: string[] }