Skip to content

Commit

Permalink
Allow selecting program manager when creating / editing a thesis to c…
Browse files Browse the repository at this point in the history
…hoose thesis approver
  • Loading branch information
AleksTeresh committed Oct 11, 2024
1 parent 87d354d commit 8947753
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/client/components/ThesisPage/ThesesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ const ThesesPage = () => {
programId: '',
topic: '',
authors: [],
approvers: [],
status: 'PLANNING',
startDate: '',
targetDate: '',
Expand Down Expand Up @@ -213,6 +214,7 @@ const ThesesPage = () => {
},
],
authors: [],
approvers: [],
graders: [{ user, isPrimaryGrader: true, isExternal: false }],
topic: '',
status: 'PLANNING',
Expand Down
68 changes: 62 additions & 6 deletions src/client/components/ThesisPage/ThesisEditForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { useTranslation } from 'react-i18next'
import { User, ThesisData, TranslationLanguage } from '@backend/types'
import BookmarkIcon from '@mui/icons-material/Bookmark'
import {
Alert,
AlertTitle,
Autocomplete,
Button,
Dialog,
Expand All @@ -33,6 +35,7 @@ import SupervisorSelect from './SupervisorSelect/SupervisorSelect'
import useUsers from '../../hooks/useUsers'
import { useDebounce } from '../../hooks/useDebounce'
import useLoggedInUser from '../../hooks/useLoggedInUser'
import useProgramManagements from '../../hooks/useProgramManagements'
import { getFormErrors, getSortedByName } from './util'
import GraderSelect from './GraderSelect/GraderSelect'
import ErrorSummary from '../Common/ErrorSummary'
Expand All @@ -56,6 +59,14 @@ const ThesisEditForm: React.FC<{
initialThesis
)
const [userSearch, setUserSearch] = useState('')
const { programManagements: programManagementsOfApprovers } =
useProgramManagements({
onlyThesisApprovers: true,
programId: editedThesis.programId,
})
const approvers = programManagementsOfApprovers?.map(
(programManagement) => programManagement.user
)

const debouncedSearch = useDebounce(userSearch, 700)
const { users: authorOptions } = useUsers({
Expand Down Expand Up @@ -287,15 +298,60 @@ const ThesisEditForm: React.FC<{
</MenuItem>
))}
</Select>
<FormHelperText error>
{t(
formErrors.find((error) => error.path[0] === 'programId')
?.message
)}
</FormHelperText>
</FormControl>
)}

{approvers && approvers.length > 0 && (
<>
<Alert
id="grader-select-instructions"
severity="info"
variant="outlined"
sx={{ whiteSpace: 'pre-line' }}
>
<AlertTitle>
{t('thesisForm:approverInstructions')}
</AlertTitle>
</Alert>
<FormControl fullWidth>
<InputLabel id="approver-select-label">
{t('thesisForm:approverHeader')}
</InputLabel>
<Select
data-testid="approver-select-input"
required
value={editedThesis.approvers[0]?.id ?? ''}
id="approver"
label="Approver"
name="approver"
onChange={(event) => {
setEditedThesis((oldThesis) => ({
...oldThesis,
approvers: [
approvers.find((a) => a.id === event.target.value),
],
}))

setFormErrors(
formErrors.filter(
(error) => error.path[0] !== 'approver'
)
)
}}
error={formErrors.some(
(error) => error.path[0] === 'approver'
)}
>
{approvers.map((approver) => (
<MenuItem key={approver.id} value={approver.id}>
{approver.firstName} {approver.lastName}
</MenuItem>
))}
</Select>
</FormControl>{' '}
</>
)}

<FormControl fullWidth>
<Autocomplete<User>
id="authors"
Expand Down
2 changes: 2 additions & 0 deletions src/client/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"targetDate": "Target date must be after start date"
},
"thesisForm": {
"approverHeader": "Program manager",
"approverInstructions": "Select a program manager, whose expertise is closest to the topic of the thesis, to manage the process.",
"errorSummary": "Form contains the following errors",
"newThesisFormTitle": "Create new thesis",
"editThesisFormTitle": "Edit thesis",
Expand Down
2 changes: 2 additions & 0 deletions src/client/locales/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"targetDate": "Tavoitepäivän on oltava aloituspäivän jälkeen"
},
"thesisForm": {
"approverHeader": "Vastaava",
"approverInstructions": "Valitse ohjelmavastaava, joka on lähimpänä tutkielman aihepiiriä, hallinnoimaan prosessia.",
"errorSummary": "Lomake sisältää seuraavia virheitä",
"newThesisFormTitle": "Uuden tutkielman luonti",
"editThesisFormTitle": "Tutkielman muokkaus",
Expand Down
20 changes: 20 additions & 0 deletions src/server/routes/thesis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
Thesis,
Supervision,
Author,
Approver,
User,
EventLog,
} from '../db/models'
Expand Down Expand Up @@ -49,6 +50,7 @@ const fetchThesisById = async (id: string, user: UserType) => {
}

const createThesis = async (thesisData: ThesisData, t: Transaction) => {
console.log('thesisData', thesisData)
const createdThesis = await Thesis.create(thesisData, { transaction: t })

const extUsers = await getAndCreateExtUsers(thesisData, t)
Expand All @@ -73,6 +75,14 @@ const createThesis = async (thesisData: ThesisData, t: Transaction) => {
{ transaction: t, validate: true, individualHooks: true }
)

await Approver.bulkCreate(
thesisData.approvers.map((approver) => ({
userId: approver.id,
thesisId: createdThesis.id,
})),
{ transaction: t, validate: true, individualHooks: true }
)

// Create the external users from the graders
await User.bulkCreate(
thesisData.graders
Expand Down Expand Up @@ -139,6 +149,7 @@ const updateThesis = async (
})),
{ transaction, validate: true, individualHooks: true }
)

await Author.destroy({ where: { thesisId: id }, transaction })
await Author.bulkCreate(
thesisData.authors.map((author) => ({
Expand All @@ -147,6 +158,15 @@ const updateThesis = async (
})),
{ transaction, validate: true, individualHooks: true }
)

await Approver.destroy({ where: { thesisId: id }, transaction })
await Approver.bulkCreate(
thesisData.approvers.map((approver) => ({
userId: approver.id,
thesisId: id,
})),
{ transaction, validate: true, individualHooks: true }
)
}

const deleteThesis = async (id: string, transaction: Transaction) => {
Expand Down
5 changes: 5 additions & 0 deletions src/server/routes/thesisHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ export const getFindThesesOptions = async ({
as: 'authors',
attributes: userFields,
},
{
model: User,
as: 'approvers',
attributes: userFields,
},
{
model: Attachment,
as: 'researchPlan',
Expand Down
1 change: 1 addition & 0 deletions src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export interface ThesisData {
targetDate?: string
supervisions: SupervisionData[]
authors: User[]
approvers: User[]
graders: GraderData[]
researchPlan?: FileData | File
waysOfWorking?: FileData | File
Expand Down

0 comments on commit 8947753

Please sign in to comment.