Skip to content
Snippets Groups Projects
Commit cdb2a423 authored by Andreas Ellewsen's avatar Andreas Ellewsen
Browse files

Merge branch 'GREG-61-role-button' into 'master'

Greg 61 role button

See merge request !124
parents 2f00d3e9 701afd23
No related branches found
No related tags found
1 merge request!124Greg 61 role button
Pipeline #98594 passed
Showing
with 504 additions and 141 deletions
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
"roleStartDate": "From", "roleStartDate": "From",
"roleEndDate": "To", "roleEndDate": "To",
"comment": "Comment", "comment": "Comment",
"contact": "Contact person",
"searchable": "Available in search?",
"email": "E-mail", "email": "E-mail",
"fullName": "Full name", "fullName": "Full name",
"mobilePhone": "Mobile phone", "mobilePhone": "Mobile phone",
...@@ -25,14 +27,21 @@ ...@@ -25,14 +27,21 @@
"countryCallingCode": "Country code" "countryCallingCode": "Country code"
}, },
"sponsor": { "sponsor": {
"contactInfo": "Contact information", "addRole": "Add role",
"roleInfo": "Guest role- and period information",
"roleInfoText": "You can change the start and end dates for the role.", "roleInfoText": "You can change the start and end dates for the role.",
"choose": "Choose", "choose": "Choose",
"details": "Details", "details": "Details",
"modifyEnd": "Change end date", "modifyEnd": "Change end date",
"endNow": "End role", "endNow": "End role"
"overviewGuest": "Guest overview" },
"guestInfo": {
"contactInfo": "Contact information",
"roleInfoHead": "Roles and periods",
"roleInfoBody": "You can only change roles that you have given"
},
"guest": {
"headerText": "Add new role and period.",
"bodyText": "Here you can add a new role to the same guest"
}, },
"register": { "register": {
"registerHeading": "Register new guest", "registerHeading": "Register new guest",
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
"roleStartDate": "Fra", "roleStartDate": "Fra",
"roleEndDate": "Til", "roleEndDate": "Til",
"comment": "Kommentar", "comment": "Kommentar",
"contact": "Kontaktperson",
"searchable": "Synlig i søk?",
"email": "E-post", "email": "E-post",
"fullName": "Fullt navn", "fullName": "Fullt navn",
"mobilePhone": "Mobilnummer", "mobilePhone": "Mobilnummer",
...@@ -25,14 +27,21 @@ ...@@ -25,14 +27,21 @@
"countryCallingCode": "Landkode" "countryCallingCode": "Landkode"
}, },
"sponsor": { "sponsor": {
"contactInfo": "Kontaktinformasjon", "addRole": "Legg til rolle",
"roleInfo": "Gjesterolle- og periodeinformasjon",
"roleInfoText": "Her kan du endre på start- og sluttdato for gjesterollen eller avslutte perioden", "roleInfoText": "Her kan du endre på start- og sluttdato for gjesterollen eller avslutte perioden",
"choose": "Velg", "choose": "Velg",
"details": "Detaljer", "details": "Detaljer",
"modifyEnd": "Endre sluttdato", "modifyEnd": "Endre sluttdato",
"endNow": "Avslutt rolle", "endNow": "Avslutt rolle"
"overviewGuest": "Oversikt over gjest" },
"guestInfo": {
"contactInfo": "Kontaktinformasjon",
"roleInfoHead": "Roller og perioder",
"roleInfoBody": "Du kan bare endre på gjesteroller som du er vert for"
},
"guest": {
"headerText": "Legg til ny rolle og periode",
"bodyText": "Her kan du legge til en ny rolle på samme gjest"
}, },
"register": { "register": {
"registerHeading": "Registrer ny gjest", "registerHeading": "Registrer ny gjest",
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
"roleStartDate": "Frå", "roleStartDate": "Frå",
"roleEndDate": "Til", "roleEndDate": "Til",
"comment": "Kommentar", "comment": "Kommentar",
"contact": "Kontaktperson",
"searchable": "Synleg i søk?",
"email": "E-post", "email": "E-post",
"fullName": "Fullt namn", "fullName": "Fullt namn",
"mobilePhone": "Mobilnummer", "mobilePhone": "Mobilnummer",
...@@ -26,14 +28,21 @@ ...@@ -26,14 +28,21 @@
"countryCallingCode": "Landkode" "countryCallingCode": "Landkode"
}, },
"sponsor": { "sponsor": {
"contactInfo": "Kontaktinformasjon", "addRole": "Legg til role",
"roleInfo": "Gjesterolle- og periodeinformasjon",
"roleInfoText": "Her kan du endre på start- og sluttdato for gjesterollen eller avslutte perioden", "roleInfoText": "Her kan du endre på start- og sluttdato for gjesterollen eller avslutte perioden",
"choose": "Velg", "choose": "Velg",
"details": "Detaljer", "details": "Detaljer",
"modifyEnd": "Endre sluttdato", "modifyEnd": "Endre sluttdato",
"endNow": "Avslutt rolle", "endNow": "Avslutt rolle"
"overviewGuest": "Oversikt over gjest" },
"guestInfo": {
"contactInfo": "Kontaktinformasjon",
"roleInfoHead": "Roller og perioder",
"roleInfoBody": "Du kan bare endre på gjesteroller som du er vert for"
},
"guest": {
"headerText": "Legg til ny rolle og periode",
"bodyText": "Her kan du legge til en ny rolle på samme gjest"
}, },
"register": { "register": {
"registerHeading": "Registrer ny gjest", "registerHeading": "Registrer ny gjest",
......
...@@ -22,5 +22,25 @@ function useOus(): OuData[] { ...@@ -22,5 +22,25 @@ function useOus(): OuData[] {
return ous return ous
} }
export const enSort = (a: OuData, b: OuData) => {
if (a.en > b.en) {
return 1
}
if (b.en > a.en) {
return -1
}
return 0
}
export const nbSort = (a: OuData, b: OuData) => {
if (a.nb > b.nb) {
return 1
}
if (b.nb > a.nb) {
return -1
}
return 0
}
export type { OuData } export type { OuData }
export default useOus export default useOus
...@@ -5,6 +5,7 @@ type RoleTypeData = { ...@@ -5,6 +5,7 @@ type RoleTypeData = {
identifier: string identifier: string
name_en: string name_en: string
name_nb: string name_nb: string
max_days: number
} }
function useRoleTypes(): RoleTypeData[] { function useRoleTypes(): RoleTypeData[] {
......
...@@ -2,14 +2,16 @@ import { IconButton, Theme, Box } from '@mui/material' ...@@ -2,14 +2,16 @@ import { IconButton, Theme, Box } from '@mui/material'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import PersonOutlineRoundedIcon from '@mui/icons-material/PersonOutlineRounded' import PersonOutlineRoundedIcon from '@mui/icons-material/PersonOutlineRounded'
import ArrowBackIcon from '@mui/icons-material/ArrowBack' import ArrowBackIcon from '@mui/icons-material/ArrowBack'
import { useTranslation } from 'react-i18next'
interface SponsorInfoButtonsProps { interface SponsorInfoButtonsProps {
to: string to: string
name: string
} }
export default function SponsorInfoButtons({ to }: SponsorInfoButtonsProps) { export default function SponsorInfoButtons({
const { t } = useTranslation(['common']) to,
name,
}: SponsorInfoButtonsProps) {
return ( return (
<Box <Box
sx={{ sx={{
...@@ -46,7 +48,7 @@ export default function SponsorInfoButtons({ to }: SponsorInfoButtonsProps) { ...@@ -46,7 +48,7 @@ export default function SponsorInfoButtons({ to }: SponsorInfoButtonsProps) {
typography: 'caption', typography: 'caption',
}} }}
> >
{t('sponsor.overviewGuest')} {name}
</Box> </Box>
</Box> </Box>
</Box> </Box>
......
import React, { useEffect, useState } from 'react'
import { Link, useParams } from 'react-router-dom' import { Link, useParams } from 'react-router-dom'
import Page from 'components/page' import Page from 'components/page'
...@@ -13,10 +12,9 @@ import { ...@@ -13,10 +12,9 @@ import {
TableRow, TableRow,
Paper, Paper,
} from '@mui/material' } from '@mui/material'
import { Guest, Role, FetchedRole } from 'interfaces' import { Guest, Role } from 'interfaces'
import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons'
import { format } from 'date-fns' import { format } from 'date-fns'
import { parseRole } from 'utils'
type GuestInfoParams = { type GuestInfoParams = {
pid: string pid: string
...@@ -25,14 +23,15 @@ interface RoleLineProps { ...@@ -25,14 +23,15 @@ interface RoleLineProps {
role: Role role: Role
pid: string pid: string
} }
type GuestInfoProps = {
guest: Guest
roles: Role[]
}
const RoleLine = ({ role, pid }: RoleLineProps) => { const RoleLine = ({ role, pid }: RoleLineProps) => {
const [t, i18n] = useTranslation('common') const [t, i18n] = useTranslation('common')
return ( return (
<TableRow <TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
key={role.id}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell align="left"> <TableCell align="left">
{i18n.language === 'en' ? role.name_en : role.name_nb} {i18n.language === 'en' ? role.name_en : role.name_nb}
</TableCell> </TableCell>
...@@ -56,60 +55,19 @@ const RoleLine = ({ role, pid }: RoleLineProps) => { ...@@ -56,60 +55,19 @@ const RoleLine = ({ role, pid }: RoleLineProps) => {
) )
} }
export default function GuestInfo() { export default function GuestInfo({ guest, roles }: GuestInfoProps) {
const { pid } = useParams<GuestInfoParams>() const { pid } = useParams<GuestInfoParams>()
const [t] = useTranslation(['common']) const [t] = useTranslation(['common'])
const [guestInfo, setGuest] = useState<Guest>({
pid: '',
first: '',
last: '',
email: '',
fnr: '',
mobile: '',
active: false,
registered: false,
verified: false,
roles: [],
})
const [roles, setRoles] = useState<Role[]>([])
const getPerson = async (id: string) => {
try {
const response = await fetch(`/api/ui/v1/person/${id}`)
const rjson = await response.json()
if (response.ok) {
setGuest({
pid: rjson.pid,
first: rjson.first,
last: rjson.last,
email: rjson.email,
mobile: rjson.mobile,
fnr: rjson.fnr,
active: rjson.active,
registered: rjson.registered,
verified: rjson.verified,
roles: rjson.roles,
})
setRoles(rjson.roles.map((role: FetchedRole) => parseRole(role)))
}
} catch (error) {
console.error(error)
}
}
useEffect(() => {
getPerson(pid)
}, [])
return ( return (
<Page> <Page>
<SponsorInfoButtons to="/sponsor" /> <SponsorInfoButtons to="/sponsor" name={`${guest.first} ${guest.last}`} />
<h4>{t('sponsor.contactInfo')}</h4> <h4>{t('guestInfo.contactInfo')}</h4>
<TableContainer component={Paper}> <TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table"> <Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead sx={{ backgroundColor: 'primary.light' }}> <TableHead sx={{ backgroundColor: 'primary.light' }}>
<TableRow> <TableRow>
<TableCell align="left">{t('sponsor.contactInfo')}</TableCell> <TableCell align="left">{t('guestInfo.contactInfo')}</TableCell>
<TableCell /> <TableCell />
</TableRow> </TableRow>
</TableHead> </TableHead>
...@@ -117,25 +75,36 @@ export default function GuestInfo() { ...@@ -117,25 +75,36 @@ export default function GuestInfo() {
<TableRow> <TableRow>
<TableCell align="left">{t('input.fullName')}</TableCell> <TableCell align="left">{t('input.fullName')}</TableCell>
<TableCell align="left"> <TableCell align="left">
{`${guestInfo.first} ${guestInfo.last}`} {`${guest.first} ${guest.last}`}
</TableCell> </TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell align="left">{t('input.email')}</TableCell> <TableCell align="left">{t('input.email')}</TableCell>
<TableCell align="left">{guestInfo.email}</TableCell> <TableCell align="left">{guest.email}</TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell align="left">{t('input.nationalIdNumber')}</TableCell> <TableCell align="left">{t('input.nationalIdNumber')}</TableCell>
<TableCell align="left">{guestInfo.fnr}</TableCell> <TableCell align="left">{guest.fnr}</TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell align="left">{t('input.mobilePhone')}</TableCell> <TableCell align="left">{t('input.mobilePhone')}</TableCell>
<TableCell align="left">{guestInfo.mobile}</TableCell> <TableCell align="left">{guest.mobile}</TableCell>
</TableRow> </TableRow>
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>
<h4>{t('sponsor.roleInfo')}</h4> <h4>{t('guestInfo.roleInfoHead')}</h4>
<h5>
{t('guestInfo.roleInfoBody')}
<Button
variant="contained"
component={Link}
to={`/sponsor/guest/${pid}/newrole`}
>
{t('sponsor.addRole')}
</Button>
</h5>
<TableContainer component={Paper}> <TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table"> <Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead sx={{ backgroundColor: 'primary.light' }}> <TableHead sx={{ backgroundColor: 'primary.light' }}>
...@@ -148,7 +117,7 @@ export default function GuestInfo() { ...@@ -148,7 +117,7 @@ export default function GuestInfo() {
</TableHead> </TableHead>
<TableBody> <TableBody>
{roles.map((role) => ( {roles.map((role) => (
<RoleLine pid={pid} role={role} /> <RoleLine key={role.id} pid={pid} role={role} />
))} ))}
</TableBody> </TableBody>
</Table> </Table>
......
...@@ -12,16 +12,17 @@ import { ...@@ -12,16 +12,17 @@ import {
TextField, TextField,
} from '@mui/material' } from '@mui/material'
import Page from 'components/page' import Page from 'components/page'
import { Guest } from 'interfaces' import { Guest, Role } from 'interfaces'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useParams } from 'react-router-dom' import { useParams } from 'react-router-dom'
import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons'
import { DatePicker } from '@mui/lab' import { DatePicker } from '@mui/lab'
import { Controller, SubmitHandler, useForm } from 'react-hook-form' import { Controller, SubmitHandler, useForm } from 'react-hook-form'
import { submitJsonOpts } from '../../../utils' import { submitJsonOpts } from '../../../../utils'
interface GuestRoleInfoProps { interface GuestRoleInfoProps {
guests: Guest[] guest: Guest
roles: Role[]
} }
const endPeriodPost = (id: string, data: { end_date: Date }) => { const endPeriodPost = (id: string, data: { end_date: Date }) => {
const payload = { const payload = {
...@@ -56,15 +57,12 @@ type RoleFormData = { ...@@ -56,15 +57,12 @@ type RoleFormData = {
end_date: Date end_date: Date
} }
export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) { export default function GuestRoleInfo({ guest, roles }: GuestRoleInfoProps) {
const { pid, id } = useParams<GuestRoleInfoParams>() const { pid, id } = useParams<GuestRoleInfoParams>()
const [t, i18n] = useTranslation('common') const [t, i18n] = useTranslation('common')
// Find the role info relevant for this page // Find the role info relevant for this page
const guestInfo = guests.filter((guest) => guest.pid.toString() === pid)[0] const roleInfo = roles.filter((role) => role.id.toString() === id)[0]
const roleInfo = guestInfo.roles.filter(
(role) => role.id.toString() === id
)[0]
// Prepare min and max date values // Prepare min and max date values
const today = new Date() const today = new Date()
...@@ -106,10 +104,12 @@ export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) { ...@@ -106,10 +104,12 @@ export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) {
const { control, handleSubmit } = useForm() const { control, handleSubmit } = useForm()
const onSubmit = handleSubmit(submit) const onSubmit = handleSubmit(submit)
return ( return (
<Page> <Page>
<SponsorInfoButtons to={`/sponsor/guest/${pid}`} /> <SponsorInfoButtons
to={`/sponsor/guest/${pid}`}
name={`${guest.first} ${guest.last}`}
/>
<h4>{t('sponsor.roleInfoText')}</h4> <h4>{t('sponsor.roleInfoText')}</h4>
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<TableContainer component={Paper}> <TableContainer component={Paper}>
...@@ -139,9 +139,7 @@ export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) { ...@@ -139,9 +139,7 @@ export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) {
render={({ field: { onChange, value } }) => ( render={({ field: { onChange, value } }) => (
<DatePicker <DatePicker
mask="____-__-__" mask="____-__-__"
disabled={ disabled={roleInfo.start_date <= today}
roleInfo.start_date.getDate() <= today.getDate()
}
label={t('input.roleStartDate')} label={t('input.roleStartDate')}
value={value} value={value}
minDate={today} minDate={today}
...@@ -162,7 +160,7 @@ export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) { ...@@ -162,7 +160,7 @@ export default function GuestRoleInfo({ guests }: GuestRoleInfoProps) {
<DatePicker <DatePicker
mask="____-__-__" mask="____-__-__"
label={t('input.roleEndDate')} label={t('input.roleEndDate')}
disabled={roleInfo.end_date.getDate() < today.getDate()} disabled={roleInfo.end_date < today}
minDate={today} minDate={today}
maxDate={todayPlusMaxDays} maxDate={todayPlusMaxDays}
value={value} value={value}
......
import { FetchedRole, Guest, Role } from 'interfaces'
import { useEffect, useState } from 'react'
import { Route, useParams } from 'react-router-dom'
import { parseRole } from 'utils'
import GuestInfo from './guestInfo'
import GuestRoleInfo from './guestRoleInfo'
import NewGuestRole from './newGuestRole'
type GuestInfoParams = {
pid: string
}
function GuestRoutes() {
const { pid } = useParams<GuestInfoParams>()
const [guestInfo, setGuest] = useState<Guest>({
pid: '',
first: '',
last: '',
email: '',
fnr: '',
mobile: '',
active: false,
registered: false,
verified: false,
roles: [],
})
const [roles, setRoles] = useState<Role[]>([])
const getPerson = async (id: string) => {
try {
const response = await fetch(`/api/ui/v1/person/${id}`)
const rjson = await response.json()
if (response.ok) {
setGuest({
pid: rjson.pid,
first: rjson.first,
last: rjson.last,
email: rjson.email,
mobile: rjson.mobile,
fnr: rjson.fnr,
active: rjson.active,
registered: rjson.registered,
verified: rjson.verified,
roles: rjson.roles,
})
setRoles(rjson.roles.map((role: FetchedRole) => parseRole(role)))
}
} catch (error) {
console.error(error)
}
}
useEffect(() => {
getPerson(pid)
}, [])
return (
<>
<Route path="/sponsor/guest/:pid/roles/:id">
<GuestRoleInfo guest={guestInfo} roles={roles} />
</Route>
<Route exact path="/sponsor/guest/:pid/newrole">
<NewGuestRole guest={guestInfo} />
</Route>
<Route exact path="/sponsor/guest/:pid">
<GuestInfo guest={guestInfo} roles={roles} />
</Route>
</>
)
}
export default GuestRoutes
import { DatePicker } from '@mui/lab'
import { addDays } from 'date-fns/fp'
import {
Checkbox,
Button,
Select,
FormControl,
InputLabel,
MenuItem,
Stack,
TextField,
SelectChangeEvent,
FormControlLabel,
} from '@mui/material'
import Page from 'components/page'
import { format } from 'date-fns'
import useOus, { enSort, nbSort, OuData } from 'hooks/useOus'
import useRoleTypes, { RoleTypeData } from 'hooks/useRoleTypes'
import { Guest } from 'interfaces'
import { useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import { Link, useParams } from 'react-router-dom'
import SponsorInfoButtons from 'routes/components/sponsorInfoButtons'
import { submitJsonOpts } from 'utils'
type AddRoleFormData = {
orgunit: number
type: string
end_date: Date
start_date?: Date
contact_person_unit?: string
comments?: string
available_in_search?: boolean
}
type AddRolePayload = {
orgunit: number
person: string
type: string
end_date: string
start_date?: string
contact_person_unit?: string
comments?: string
available_in_search?: boolean
}
type GuestInfoParams = {
pid: string
}
interface NewGuestRoleProps {
guest: Guest
}
const postRole = (formData: AddRoleFormData, pid: string) => {
const payload: AddRolePayload = {
orgunit: formData.orgunit,
person: pid,
type: formData.type,
end_date: format(formData.end_date as Date, 'yyyy-MM-dd'),
}
if (formData.start_date) {
payload.start_date = format(formData.start_date as Date, 'yyyy-MM-dd')
}
if (formData.contact_person_unit) {
payload.contact_person_unit = formData.contact_person_unit
}
if (formData.comments) {
payload.comments = formData.comments
}
if (formData.available_in_search) {
payload.available_in_search = formData.available_in_search
}
console.log('submitting', JSON.stringify(payload))
fetch('/api/ui/v1/role', submitJsonOpts('POST', payload))
.then((res) => {
if (!res.ok) {
console.log('result', res)
return null
}
console.log('result', res)
return res.text()
})
.then((result) => {
if (result !== null) {
console.log('result', result)
}
})
.catch((error) => {
console.log('error', error)
})
}
function NewGuestRole({ guest }: NewGuestRoleProps) {
const {
register,
control,
handleSubmit,
formState: { errors },
setValue,
getValues,
} = useForm<AddRoleFormData>()
const { pid } = useParams<GuestInfoParams>()
const onSubmit = handleSubmit(() => {
postRole(getValues(), pid)
})
const ous = useOus()
const roleTypes = useRoleTypes()
const [ouChoice, setOuChoice] = useState<string>('')
const [roleTypeChoice, setRoleTypeChoice] = useState<string>('')
const [t, i18n] = useTranslation('common')
const today = new Date()
const todayPlusMaxDays = () => {
if (roleTypeChoice) {
const role = roleTypes.filter(
(rt) => rt.id.toString() === roleTypeChoice.toString()
)[0]
return addDays(role.max_days)(today)
}
return addDays(0)(today)
}
const roleTypeSort = () => (a: RoleTypeData, b: RoleTypeData) => {
if (i18n.language === 'en') {
return a.name_nb.localeCompare(b.name_nb)
}
return a.name_en.localeCompare(b.name_en)
}
// Handling choices in menus
const handleRoleTypeChange = (event: SelectChangeEvent) => {
setValue('type', event.target.value)
setRoleTypeChoice(event.target.value)
}
const handleOuChange = (event: SelectChangeEvent) => {
if (event.target.value) {
setOuChoice(event.target.value)
setValue('orgunit', parseInt(event.target.value, 10))
}
}
// Functions for menu items
const rolesToItem = (roleType: RoleTypeData) => (
<MenuItem key={roleType.id.toString()} value={roleType.id}>
{i18n.language === 'en' ? roleType.name_en : roleType.name_nb}
</MenuItem>
)
const ouToItem = (ou: OuData) => (
<MenuItem key={ou.id.toString()} value={ou.id}>
{i18n.language === 'en' ? ou.en : ou.nb} ({ou.id})
</MenuItem>
)
return (
<Page>
<SponsorInfoButtons
to={`/sponsor/guest/${pid}`}
name={`${guest.first} ${guest.last}`}
/>
<h3>{t('guest.headerText')}</h3>
<h4>{t('guest.bodyText')}</h4>
<form onSubmit={onSubmit}>
<Stack spacing={2}>
<FormControl>
<InputLabel id="ou-select-label">{t('input.roleType')}</InputLabel>
<Select
id="roletype-select"
defaultValue=""
value={roleTypeChoice}
error={!!errors.type}
label={t('input.roleType')}
onChange={handleRoleTypeChange}
>
{roleTypes.sort(roleTypeSort()).map((rt) => rolesToItem(rt))}
</Select>
</FormControl>
<FormControl>
<InputLabel id="ou-select-label">{t('common:ou')}</InputLabel>
<Select
labelId="ou-select-label"
id="ou-select-label"
defaultValue=""
value={ouChoice.toString()}
label={t('common:ou')}
onChange={handleOuChange}
>
{ous.length > 0 ? (
ous
.sort(i18n.language === 'en' ? enSort : nbSort)
.map((ou) => ouToItem(ou))
) : (
<></>
)}
</Select>
</FormControl>
<Controller
name="start_date"
control={control}
defaultValue={today}
render={({ field }) => (
<DatePicker
mask="____-__-__"
label={t('input.roleStartDate')}
disabled={!roleTypeChoice}
value={field.value}
minDate={today}
maxDate={todayPlusMaxDays()}
inputFormat="yyyy-MM-dd"
onChange={(value) => {
field.onChange(value)
}}
renderInput={(params) => <TextField {...params} />}
/>
)}
/>
<Controller
name="end_date"
control={control}
defaultValue={today}
render={({ field }) => (
<DatePicker
mask="____-__-__"
label={t('input.roleEndDate')}
disabled={!roleTypeChoice}
value={field.value}
minDate={today}
maxDate={todayPlusMaxDays()}
inputFormat="yyyy-MM-dd"
onChange={(value) => {
field.onChange(value)
}}
renderInput={(params) => <TextField {...params} />}
/>
)}
/>
<TextField
id="contact"
label={t('input.contact')}
multiline
rows={5}
{...register('contact_person_unit')}
/>
<TextField
id="comments"
label={t('input.comment')}
multiline
rows={5}
{...register('comments')}
/>
<FormControlLabel
control={
<Checkbox
id="available_in_search"
{...register('available_in_search')}
/>
}
label={t('input.searchable')}
/>
<Button variant="contained" type="submit">
{t('button.save')}
</Button>
<Button component={Link} to={`/sponsor/guest/${pid}`}>
{t('button.cancel')}
</Button>
</Stack>
</form>
</Page>
)
}
export default NewGuestRole
import React, { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Route } from 'react-router-dom' import { Route } from 'react-router-dom'
import FrontPage from 'routes/sponsor/frontpage' import FrontPage from 'routes/sponsor/frontpage'
import GuestInfo from 'routes/sponsor/guestInfo'
import GuestRoleInfo from 'routes/sponsor/guestRoleInfo'
import { FetchedGuest, Guest } from 'interfaces' import { FetchedGuest, Guest } from 'interfaces'
import { parseRole } from 'utils' import { parseRole } from 'utils'
import GuestRoutes from './guest'
function Sponsor() { function Sponsor() {
const [guests, setGuests] = useState<Guest[]>([]) const [guests, setGuests] = useState<Guest[]>([])
...@@ -44,11 +43,8 @@ function Sponsor() { ...@@ -44,11 +43,8 @@ function Sponsor() {
return ( return (
<> <>
<Route path="/sponsor/guest/:pid/roles/:id"> <Route path="/sponsor/guest/:pid">
<GuestRoleInfo guests={guests} /> <GuestRoutes />
</Route>
<Route exact path="/sponsor/guest/:pid">
<GuestInfo />
</Route> </Route>
<Route exact path="/sponsor"> <Route exact path="/sponsor">
<FrontPage guests={guests} /> <FrontPage guests={guests} />
......
...@@ -11,7 +11,7 @@ import { ...@@ -11,7 +11,7 @@ import {
} from '@mui/material' } from '@mui/material'
import { Controller, SubmitHandler, useForm } from 'react-hook-form' import { Controller, SubmitHandler, useForm } from 'react-hook-form'
import { DatePicker } from '@mui/lab' import { DatePicker } from '@mui/lab'
import React, { import {
forwardRef, forwardRef,
Ref, Ref,
useEffect, useEffect,
...@@ -21,7 +21,7 @@ import React, { ...@@ -21,7 +21,7 @@ import React, {
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { RegisterFormData } from './formData' import { RegisterFormData } from './formData'
import { PersonFormMethods } from './personFormMethods' import { PersonFormMethods } from './personFormMethods'
import useOus, { OuData } from '../../../hooks/useOus' import useOus, { enSort, nbSort } from '../../../hooks/useOus'
import useRoleTypes, { RoleTypeData } from '../../../hooks/useRoleTypes' import useRoleTypes, { RoleTypeData } from '../../../hooks/useRoleTypes'
import { isValidEmail } from '../../../utils' import { isValidEmail } from '../../../utils'
...@@ -51,26 +51,6 @@ const StepPersonForm = forwardRef( ...@@ -51,26 +51,6 @@ const StepPersonForm = forwardRef(
return a.name_en.localeCompare(b.name_en) return a.name_en.localeCompare(b.name_en)
} }
const enSort = (a: OuData, b: OuData) => {
if (a.en > b.en) {
return 1
}
if (b.en > a.en) {
return -1
}
return 0
}
const nbSort = (a: OuData, b: OuData) => {
if (a.nb > b.nb) {
return 1
}
if (b.nb > a.nb) {
return -1
}
return 0
}
const submit: SubmitHandler<RegisterFormData> = (data) => { const submit: SubmitHandler<RegisterFormData> = (data) => {
nextHandler(data) nextHandler(data)
} }
......
...@@ -71,7 +71,7 @@ export default function StepRegistration() { ...@@ -71,7 +71,7 @@ export default function StepRegistration() {
? null ? null
: format(formData.role_end as Date, 'yyyy-MM-dd'), : format(formData.role_end as Date, 'yyyy-MM-dd'),
comments: formData.comment, comments: formData.comment,
orgunit_id: formData.ou_id, orgunit: formData.ou_id,
}, },
} }
......
...@@ -15,8 +15,8 @@ class RoleSerializer(serializers.ModelSerializer): ...@@ -15,8 +15,8 @@ class RoleSerializer(serializers.ModelSerializer):
"id", "id",
"start_date", "start_date",
"end_date", "end_date",
"sponsor_id", "sponsor",
"orgunit_id", "orgunit",
"created", "created",
"updated", "updated",
"type", "type",
......
# Generated by Django 3.2.8 on 2021-10-26 14:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('greg', '0010_roletype_max_days'),
]
operations = [
migrations.RenameField(
model_name='role',
old_name='orgunit_id',
new_name='orgunit',
),
migrations.RenameField(
model_name='role',
old_name='sponsor_id',
new_name='sponsor',
),
]
...@@ -203,7 +203,7 @@ class Role(BaseModel): ...@@ -203,7 +203,7 @@ class Role(BaseModel):
type = models.ForeignKey( type = models.ForeignKey(
"RoleType", on_delete=models.PROTECT, related_name="persons" "RoleType", on_delete=models.PROTECT, related_name="persons"
) )
orgunit_id = models.ForeignKey( orgunit = models.ForeignKey(
"OrganizationalUnit", on_delete=models.PROTECT, related_name="unit_person_role" "OrganizationalUnit", on_delete=models.PROTECT, related_name="unit_person_role"
) )
# The start date can be null for people that are already # The start date can be null for people that are already
...@@ -213,7 +213,7 @@ class Role(BaseModel): ...@@ -213,7 +213,7 @@ class Role(BaseModel):
contact_person_unit = models.TextField(blank=True) contact_person_unit = models.TextField(blank=True)
comments = models.TextField(blank=True) comments = models.TextField(blank=True)
available_in_search = models.BooleanField(default=False) available_in_search = models.BooleanField(default=False)
sponsor_id = models.ForeignKey( sponsor = models.ForeignKey(
"Sponsor", on_delete=models.PROTECT, related_name="sponsor_role" "Sponsor", on_delete=models.PROTECT, related_name="sponsor_role"
) )
......
...@@ -55,8 +55,8 @@ def role_data_guest( ...@@ -55,8 +55,8 @@ def role_data_guest(
"type": "Test Guest", "type": "Test Guest",
"start_date": "2021-06-10", "start_date": "2021-06-10",
"end_date": "2021-08-10", "end_date": "2021-08-10",
"sponsor_id": sponsor_bar.id, "sponsor": sponsor_bar.id,
"orgunit_id": unit_foo.id, "orgunit": unit_foo.id,
} }
...@@ -131,8 +131,8 @@ def test_add_role( ...@@ -131,8 +131,8 @@ def test_add_role(
"type": "visiting_professor", "type": "visiting_professor",
"start_date": "2021-06-10", "start_date": "2021-06-10",
"end_date": "2021-08-10", "end_date": "2021-08-10",
"sponsor_id": "1", "sponsor": "1",
"orgunit_id": "1", "orgunit": "1",
} }
response = client.post(url, role_data) response = client.post(url, role_data)
...@@ -425,8 +425,8 @@ def test_add_duplicate_role_fails(client, person_foo: Person, role_person_foo): ...@@ -425,8 +425,8 @@ def test_add_duplicate_role_fails(client, person_foo: Person, role_person_foo):
"type": role_person_foo.type.identifier, "type": role_person_foo.type.identifier,
"start_date": role_person_foo.start_date, "start_date": role_person_foo.start_date,
"end_date": role_person_foo.end_date, "end_date": role_person_foo.end_date,
"sponsor_id": role_person_foo.sponsor_id.id, "sponsor": role_person_foo.sponsor.id,
"orgunit_id": role_person_foo.unit_id, "orgunit": role_person_foo.unit_id,
} }
response = client.post(url, role_data) response = client.post(url, role_data)
# If the role cannot be create the return code is 400 # If the role cannot be create the return code is 400
...@@ -453,8 +453,8 @@ def test_filter_active_includes_person_with_active_role( ...@@ -453,8 +453,8 @@ def test_filter_active_includes_person_with_active_role(
person=person_foo, person=person_foo,
type=role_type_test_guest, type=role_type_test_guest,
end_date=date_today + datetime.timedelta(days=1), end_date=date_today + datetime.timedelta(days=1),
sponsor_id=sponsor_guy, sponsor=sponsor_guy,
orgunit_id=unit_foo, orgunit=unit_foo,
) )
url = reverse("v1:person-list") url = reverse("v1:person-list")
...@@ -491,8 +491,8 @@ def test_filter_active_value_false( ...@@ -491,8 +491,8 @@ def test_filter_active_value_false(
person=person_foo, person=person_foo,
type=role_type_test_guest, type=role_type_test_guest,
end_date=date_today - datetime.timedelta(days=1), end_date=date_today - datetime.timedelta(days=1),
sponsor_id=sponsor_guy, sponsor=sponsor_guy,
orgunit_id=unit_foo, orgunit=unit_foo,
) )
url = reverse("v1:person-list") url = reverse("v1:person-list")
......
...@@ -152,8 +152,8 @@ def role_person_foo( ...@@ -152,8 +152,8 @@ def role_person_foo(
type=role_type_test_guest, type=role_type_test_guest,
start_date="2021-08-02", start_date="2021-08-02",
end_date="2021-08-06", end_date="2021-08-06",
sponsor_id=sponsor_guy, sponsor=sponsor_guy,
orgunit_id=unit_foo, orgunit=unit_foo,
) )
return Role.objects.get(id=role.id) return Role.objects.get(id=role.id)
......
...@@ -98,14 +98,14 @@ def test_add_multiple_roles_to_person( ...@@ -98,14 +98,14 @@ def test_add_multiple_roles_to_person(
role_with( role_with(
person=person, person=person,
type=role_type_foo, type=role_type_foo,
orgunit_id=ou, orgunit=ou,
sponsor_id=Sponsor.objects.create(feide_id="foosponsor@uio.no"), sponsor=Sponsor.objects.create(feide_id="foosponsor@uio.no"),
) )
role_with( role_with(
person=person, person=person,
type=role_type_bar, type=role_type_bar,
orgunit_id=ou, orgunit=ou,
sponsor_id=Sponsor.objects.create(feide_id="barsponsor@uio.no"), sponsor=Sponsor.objects.create(feide_id="barsponsor@uio.no"),
) )
assert person.roles.count() == 2 assert person.roles.count() == 2
......
...@@ -33,12 +33,12 @@ def role( ...@@ -33,12 +33,12 @@ def role(
return Role.objects.create( return Role.objects.create(
person=person, person=person,
type=role_type_bar, type=role_type_bar,
orgunit_id=unit_foo, orgunit=unit_foo,
start_date="2020-03-05", start_date="2020-03-05",
end_date=datetime.today() + timedelta(days=30), end_date=datetime.today() + timedelta(days=30),
contact_person_unit="Contact Person", contact_person_unit="Contact Person",
available_in_search=True, available_in_search=True,
sponsor_id=sponsor_guy, sponsor=sponsor_guy,
) )
......
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