mirror of
https://github.com/overleaf/overleaf.git
synced 2025-01-27 10:03:13 +00:00
Merge pull request #7786 from overleaf/ii-departments-override
Override default departments GitOrigin-RevId: 23061bc8c083bb8099ca62bd0cdb3c796e49979d
This commit is contained in:
parent
35e0d83343
commit
85f731110c
6 changed files with 114 additions and 16 deletions
|
@ -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() {
|
|||
<>
|
||||
<div className="form-group mb-2">
|
||||
<DownshiftInput
|
||||
items={roles}
|
||||
items={defaultRoles}
|
||||
inputValue={role}
|
||||
placeholder={t('role')}
|
||||
label={t('role')}
|
||||
|
|
|
@ -7,9 +7,10 @@ import { useUserEmailsContext } from '../../context/user-email-context'
|
|||
import DownshiftInput from './downshift-input'
|
||||
import Icon from '../../../../shared/components/icon'
|
||||
import useAsync from '../../../../shared/hooks/use-async'
|
||||
import { postJSON } from '../../../../infrastructure/fetch-json'
|
||||
import { defaults as roles } from '../../roles'
|
||||
import { defaults as departments } from '../../departments'
|
||||
import { getJSON, postJSON } from '../../../../infrastructure/fetch-json'
|
||||
import { defaults as defaultRoles } from '../../roles'
|
||||
import { defaults as defaultDepartments } from '../../departments'
|
||||
import { University } from '../../../../../../types/university'
|
||||
|
||||
type InstitutionAndRoleProps = {
|
||||
userEmailData: UserEmailData
|
||||
|
@ -18,6 +19,7 @@ type InstitutionAndRoleProps = {
|
|||
function InstitutionAndRole({ userEmailData }: InstitutionAndRoleProps) {
|
||||
const { t } = useTranslation()
|
||||
const { isLoading, isError, runAsync } = useAsync()
|
||||
const changeAffiliationAsync = useAsync()
|
||||
const { affiliation } = userEmailData
|
||||
const {
|
||||
state,
|
||||
|
@ -27,6 +29,7 @@ function InstitutionAndRole({ userEmailData }: InstitutionAndRoleProps) {
|
|||
} = useUserEmailsContext()
|
||||
const [role, setRole] = useState(affiliation?.role || '')
|
||||
const [department, setDepartment] = useState(affiliation?.department || '')
|
||||
const [departments, setDepartments] = useState(defaultDepartments)
|
||||
|
||||
useEffect(() => {
|
||||
setUserEmailsContextLoading(isLoading)
|
||||
|
@ -34,6 +37,23 @@ function InstitutionAndRole({ userEmailData }: InstitutionAndRoleProps) {
|
|||
|
||||
const handleChangeAffiliation = () => {
|
||||
setEmailAffiliationBeingEdited(userEmailData.email)
|
||||
|
||||
if (!affiliation?.institution.id) {
|
||||
return
|
||||
}
|
||||
|
||||
changeAffiliationAsync
|
||||
.runAsync<University>(
|
||||
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) {
|
|||
<div className="affiliation-change-container small">
|
||||
<form onSubmit={handleSubmit}>
|
||||
<DownshiftInput
|
||||
items={roles}
|
||||
items={defaultRoles}
|
||||
inputValue={role}
|
||||
placeholder={t('role')}
|
||||
label={t('role')}
|
||||
|
|
|
@ -5,6 +5,7 @@ const fakeUsersData = [
|
|||
affiliation: {
|
||||
institution: {
|
||||
confirmed: true,
|
||||
id: 1,
|
||||
name: 'Overleaf',
|
||||
},
|
||||
licence: 'pro_plus',
|
||||
|
@ -22,6 +23,7 @@ const fakeUsersData = [
|
|||
affiliation: {
|
||||
institution: {
|
||||
confirmed: true,
|
||||
id: 2,
|
||||
name: 'Overleaf',
|
||||
},
|
||||
licence: 'pro_plus',
|
||||
|
@ -38,8 +40,27 @@ const fakeUsersData = [
|
|||
]
|
||||
|
||||
const fakeInstitutions = [
|
||||
{ id: 9326, name: 'Unknown', country_code: 'al', departments: [] },
|
||||
{
|
||||
id: 9326,
|
||||
name: 'Unknown',
|
||||
country_code: 'al',
|
||||
departments: ['New department'],
|
||||
},
|
||||
]
|
||||
const fakeInstitution = {
|
||||
id: 123,
|
||||
name: 'test',
|
||||
country_code: 'de',
|
||||
departments: [],
|
||||
team_id: null,
|
||||
}
|
||||
const bazFakeInstitution = {
|
||||
id: 2,
|
||||
name: 'Baz',
|
||||
country_code: 'de',
|
||||
departments: ['Custom department 1', 'Custom department 2'],
|
||||
team_id: null,
|
||||
}
|
||||
|
||||
const fakeInstitutionDomain = [
|
||||
{
|
||||
|
@ -56,7 +77,11 @@ const fakeInstitutionDomain = [
|
|||
export function defaultSetupMocks(fetchMock) {
|
||||
fetchMock
|
||||
.get(/\/user\/emails/, fakeUsersData, { delay: MOCK_DELAY })
|
||||
.get(/\/institutions\/list/, fakeInstitutions, { delay: MOCK_DELAY })
|
||||
.get(/\/institutions\/list\/2/, bazFakeInstitution, { delay: MOCK_DELAY })
|
||||
.get(/\/institutions\/list\/\d+/, fakeInstitution, { delay: MOCK_DELAY })
|
||||
.get(/\/institutions\/list\?country_code=.*/, fakeInstitutions, {
|
||||
delay: MOCK_DELAY,
|
||||
})
|
||||
.get(/\/institutions\/domains/, fakeInstitutionDomain)
|
||||
.post(/\/user\/emails\/*/, 200, {
|
||||
delay: MOCK_DELAY,
|
||||
|
|
|
@ -196,8 +196,9 @@ describe('<EmailsSection />', 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(<EmailsSection />)
|
||||
|
||||
|
@ -225,7 +226,7 @@ describe('<EmailsSection />', function () {
|
|||
id: userEmailData.affiliation.institution.id,
|
||||
name: userEmailData.affiliation.institution.name,
|
||||
country_code: 'de',
|
||||
departments: [],
|
||||
departments: [customDepartment],
|
||||
},
|
||||
])
|
||||
|
||||
|
@ -252,10 +253,19 @@ describe('<EmailsSection />', 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('<EmailsSection />', 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 () {
|
||||
|
|
|
@ -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(<EmailsSection />)
|
||||
|
||||
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(<EmailsSection />)
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@ export type University = {
|
|||
id: number
|
||||
name: string
|
||||
country_code: CountryCode
|
||||
departments: unknown[]
|
||||
departments: string[]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue