Skip to content
Snippets Groups Projects
Commit 920f01ea authored by Tore.Brede's avatar Tore.Brede
Browse files

GREG-255: Doing some changes on the edit role screen

parent 2673b853
No related branches found
No related tags found
1 merge request!325GREG-255: Doing some changes on the edit role screen
......@@ -56,6 +56,7 @@ export type Role = {
contact_person_unit: string | null
comments: string | null
sponsor_name: string
ou_id: number
}
export type FetchedRole = {
......@@ -70,6 +71,7 @@ export type FetchedRole = {
contact_person_unit: string | null
comments: string | null
sponsor_name: string
ou_id: number
}
export type ConsentType = {
......
......@@ -5,7 +5,8 @@ import { LocalizationProvider } from '@mui/lab'
// eslint-disable-next-line import/no-extraneous-dependencies
import { Guest } from 'interfaces'
import parse from 'date-fns/parse'
import { BrowserRouter } from 'react-router-dom'
import { MemoryRouter, Route, Routes } from 'react-router-dom'
import { addDays } from 'date-fns/fp'
import GuestRoleInfo from './index'
import { waitFor } from '../../../../test-utils'
......@@ -30,11 +31,12 @@ const guest: Guest = {
name_en: 'Guest role',
name_nb: 'Gjesterolle',
start_date: parse('2021-08-10', 'yyyy-MM-dd', new Date()),
end_date: parse('2021-08-16', 'yyyy-MM-dd', new Date()),
end_date: addDays(10)(new Date()),
contact_person_unit: 'Test contact person',
max_days: 100,
comments: 'Test comment',
sponsor_name: 'Test',
ou_id: 1,
},
{
id: '201',
......@@ -43,22 +45,41 @@ const guest: Guest = {
name_en: 'Test role',
name_nb: 'Testrolle',
start_date: parse('2021-09-06', 'yyyy-MM-dd', new Date()),
end_date: parse('2021-09-20', 'yyyy-MM-dd', new Date()),
end_date: addDays(10)(new Date()),
contact_person_unit: 'Test contact person',
max_days: 100,
comments: 'Test comment',
sponsor_name: 'Test',
ou_id: 2,
},
],
}
test('Button state correct on load', async () => {
// Mock useOus so that it looks like the user is a sponsor for
// the unit with ID 1
jest.mock('hooks/useOus', () => () => ({
ous: [
{
id: 1,
nb: 'Test',
en: 'Test2',
},
],
loading: false,
}))
test('End now enabled for role that is not expired and in unit where user is host', async () => {
render(
<BrowserRouter>
<MemoryRouter initialEntries={['/sponsor/guest/1/roles/200']}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<GuestRoleInfo guest={guest} reloadGuest={() => {}} />
<Routes>
<Route
path="sponsor/guest/:pid/roles/:id"
element={<GuestRoleInfo guest={guest} reloadGuest={() => {}} />}
/>
</Routes>
</LocalizationProvider>
</BrowserRouter>
</MemoryRouter>
)
await waitFor(
......@@ -69,3 +90,26 @@ test('Button state correct on load', async () => {
{ timeout: 5000 }
)
}, 10000)
test('End now disabled for role that is not expired and in unit where user is not host', async () => {
render(
<MemoryRouter initialEntries={['/sponsor/guest/1/roles/201']}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Routes>
<Route
path="sponsor/guest/:pid/roles/:id"
element={<GuestRoleInfo guest={guest} reloadGuest={() => {}} />}
/>
</Routes>
</LocalizationProvider>
</MemoryRouter>
)
await waitFor(
() => {
expect(screen.getByText('button.save')).toBeDisabled()
expect(screen.getByText('sponsor.endNow')).toBeDisabled()
},
{ timeout: 5000 }
)
}, 10000)
......@@ -18,6 +18,7 @@ import { Controller, SubmitHandler, useForm } from 'react-hook-form'
import { getRoleName, getRoleOuName, submitJsonOpts } from 'utils'
import { useFeatureContext } from 'contexts/featureContext'
import ConfirmDialog from '../../../../components/confirmDialog'
import useOus from '../../../../hooks/useOus'
interface GuestRoleInfoProps {
guest: Guest
......@@ -101,6 +102,7 @@ export default function GuestRoleInfo({
reloadGuest,
}: GuestRoleInfoProps) {
const { pid, id } = useParams<GuestRoleInfoParams>()
const { ous } = useOus()
const [t] = useTranslation('common')
const { displayContactAtUnit, displayComment } = useFeatureContext()
const navigate = useNavigate()
......@@ -116,6 +118,7 @@ export default function GuestRoleInfo({
contact_person_unit: null,
comments: null,
sponsor_name: '',
ou_id: -1,
})
// Prepare min and max date values
const today = new Date()
......@@ -141,6 +144,13 @@ export default function GuestRoleInfo({
formState: { isDirty, isValid },
} = useForm<RoleFormData>({ mode: 'onChange' })
// A sponsor can only edit roles belonging to departments where he is a sponsor.
// Look at the unit where the role is registered and see if that unit is present
// in the list of units where a sponsor can assign roles to determine if
// he can edit this role
const allowEdit =
ous === undefined ? false : ous.some((value) => value.id === role.ou_id)
// Submit function for the save button
const submit: SubmitHandler<RoleFormData> = (data) => {
const payload: { start_date?: string; end_date: string } = {
......@@ -198,12 +208,16 @@ export default function GuestRoleInfo({
to={`/sponsor/guest/${pid}`}
name={`${guest.first} ${guest.last}`}
/>
<Typography sx={{ marginBottom: '1rem' }} variant="h2">
{t('sponsor.roleInfoHead')}
</Typography>
<Typography sx={{ marginBottom: '1rem' }} variant="body1">
{t('sponsor.roleInfoText')}
</Typography>
{allowEdit && (
<>
<Typography sx={{ marginBottom: '1rem' }} variant="h2">
{t('sponsor.roleInfoHead')}
</Typography>
<Typography sx={{ marginBottom: '1rem' }} variant="body1">
{t('sponsor.roleInfoText')}
</Typography>
</>
)}
<form onSubmit={onSubmit}>
<TableContainer>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
......@@ -239,6 +253,7 @@ export default function GuestRoleInfo({
inputFormat="yyyy-MM-dd"
onChange={onChange}
renderInput={(params) => <TextField {...params} />}
disabled={!allowEdit}
/>
)}
/>
......@@ -257,6 +272,7 @@ export default function GuestRoleInfo({
inputFormat="yyyy-MM-dd"
onChange={onChange}
renderInput={(params) => <TextField {...params} />}
disabled={!allowEdit}
/>
)}
/>
......@@ -301,7 +317,7 @@ export default function GuestRoleInfo({
variant="contained"
color="success"
type="submit"
disabled={!isDirty || !isValid}
disabled={!isDirty || !isValid || !allowEdit}
>
{t('button.save')}
</Button>{' '}
......@@ -309,7 +325,7 @@ export default function GuestRoleInfo({
<Button
aria-label={t('sponsor.endNow')}
color="primary"
disabled={role.end_date < today}
disabled={role.end_date < today || !allowEdit}
onClick={() => setShowEndRoleConfirmationDialog(true)}
>
{t('sponsor.endNow')}
......
......@@ -150,6 +150,7 @@ export function parseRole(role: FetchedRole): Role {
contact_person_unit: role.contact_person_unit,
comments: role.comments,
sponsor_name: role.sponsor_name,
ou_id: role.ou_id
}
}
......
......@@ -104,6 +104,7 @@ class ExtendedRoleSerializer(serializers.ModelSerializer):
ou_en = SerializerMethodField(source="orgunit")
max_days = SerializerMethodField(source="type")
sponsor_name = SerializerMethodField(source="sponsor")
ou_id = SerializerMethodField(source="orgunit")
def get_name_nb(self, obj):
return obj.type.name_nb
......@@ -123,6 +124,9 @@ class ExtendedRoleSerializer(serializers.ModelSerializer):
def get_sponsor_name(self, obj):
return f"{obj.sponsor.first_name} {obj.sponsor.last_name}"
def get_ou_id(self, obj):
return obj.orgunit.id
class Meta:
model = Role
fields = [
......@@ -137,5 +141,6 @@ class ExtendedRoleSerializer(serializers.ModelSerializer):
"contact_person_unit",
"comments",
"sponsor_name",
"ou_id",
]
read_only_fields = ["contact_person_unit", "sponsor_name"]
......@@ -35,6 +35,7 @@ def test_serialize_guest(invited_person):
"contact_person_unit": "",
"comments": "",
"sponsor_name": "Sponsor Bar",
"ou_id": 1,
},
],
"verified": False,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment