Skip to content

Commit

Permalink
Improve presentation scheduling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-emilius committed Oct 7, 2024
1 parent 7156a6e commit ea72a07
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 95 deletions.
26 changes: 19 additions & 7 deletions client/src/components/PresentationsTable/PresentationsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ import React from 'react'
import { DataTable, DataTableColumn } from 'mantine-datatable'
import {
IPublishedPresentation,
isPublishedPresentation,
isThesisPresentation,
IThesis,
IThesisPresentation,
} from '../../requests/responses/thesis'
import { formatDate, formatPresentationType } from '../../utils/format'
import { GLOBAL_CONFIG } from '../../config/global'
import { Anchor, Badge, Center } from '@mantine/core'
import AvatarUserList from '../AvatarUserList/AvatarUserList'

type PresentationColumn =
| 'state'
| 'students'
| 'type'
| 'location'
| 'streamUrl'
Expand Down Expand Up @@ -51,14 +55,22 @@ const PresentationsTable = <T extends IThesisPresentation | IPublishedPresentati
ellipsis: true,
render: (presentation) => (
<Center>
{isThesisPresentation(presentation) && (
<Badge color={presentation.state === 'DRAFTED' ? 'grey' : undefined}>
{presentation.state}
</Badge>
)}
<Badge color={presentation.state === 'DRAFTED' ? 'grey' : undefined}>
{presentation.state}
</Badge>
</Center>
),
},
students: {
accessor: 'students',
title: 'Student',
width: 180,
ellipsis: true,
render: (presentation) =>
isPublishedPresentation(presentation) && (
<AvatarUserList users={presentation.thesis.students} />
),
},
type: {
accessor: 'type',
title: 'Type',
Expand Down Expand Up @@ -122,7 +134,7 @@ const PresentationsTable = <T extends IThesisPresentation | IPublishedPresentati
page={pagination.page}
onPageChange={pagination.onPageChange}
idAccessor='presentationId'
columns={columns.map((column) => columnConfig[column])}
columns={columns.filter((column) => column).map((column) => columnConfig[column])}
onRowClick={onRowClick ? ({ record }) => onRowClick(record) : undefined}
/>
)
Expand All @@ -138,7 +150,7 @@ const PresentationsTable = <T extends IThesisPresentation | IPublishedPresentati
highlightOnHover
records={presentations}
idAccessor='presentationId'
columns={columns.map((column) => columnConfig[column])}
columns={columns.filter((column) => column).map((column) => columnConfig[column])}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import PresentationsTable from '../PresentationsTable/PresentationsTable'
import React, { useEffect, useState } from 'react'
import { PaginationResponse } from '../../requests/responses/pagination'
import { IPublishedPresentation } from '../../requests/responses/thesis'
import { doRequest } from '../../requests/request'
import { showSimpleError } from '../../utils/notification'
import { getApiResponseErrorMessage } from '../../requests/handler'
import { useNavigate } from 'react-router-dom'

interface IPublicPresentationsTableProps {
includeDrafts?: boolean
limit?: number
reducedData?: boolean
}

const PublicPresentationsTable = (props: IPublicPresentationsTableProps) => {
const { includeDrafts = false, limit = 10, reducedData = false } = props

const navigate = useNavigate()

const [presentations, setPresentations] = useState<PaginationResponse<IPublishedPresentation>>()
const [page, setPage] = useState(0)

useEffect(() => {
setPresentations(undefined)

return doRequest<PaginationResponse<IPublishedPresentation>>(
`/v2/published-presentations`,
{
method: 'GET',
requiresAuth: false,
params: {
page,
limit,
includeDrafts,
},
},
(res) => {
if (res.ok) {
setPresentations(res.data)
} else {
showSimpleError(getApiResponseErrorMessage(res))
}
},
)
}, [page, limit, includeDrafts])

return (
<PresentationsTable
columns={
reducedData
? [includeDrafts ? 'state' : '', 'students', 'location', 'scheduledAt']
: [
includeDrafts ? 'state' : '',
'students',
'type',
'location',
'streamUrl',
'language',
'scheduledAt',
]
}
presentations={presentations?.content}
onRowClick={(presentation) => navigate(`/presentations/${presentation.presentationId}`)}
pagination={{
totalRecords: presentations?.totalElements ?? 0,
recordsPerPage: limit,
page: page + 1,
onPageChange: (newPage) => setPage(newPage - 1),
}}
/>
)
}

export default PublicPresentationsTable
14 changes: 7 additions & 7 deletions client/src/components/ThesesTable/ThesesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const ThesesTable = (props: IThesesTableProps) => {
title: 'State',
textAlign: 'center',
width: 150,
render: (thesis: IThesis) => {
render: (thesis) => {
return (
<Center>
<ThesisStateBadge state={thesis.state} />
Expand All @@ -57,28 +57,28 @@ const ThesesTable = (props: IThesesTableProps) => {
accessor: 'supervisors',
title: 'Supervisor',
width: 180,
render: (thesis: IThesis) => <AvatarUserList users={thesis.supervisors} />,
render: (thesis) => <AvatarUserList users={thesis.supervisors} />,
},
advisors: {
accessor: 'advisors',
title: 'Advisor(s)',
ellipsis: true,
width: 180,
render: (thesis: IThesis) => <AvatarUserList users={thesis.advisors} />,
render: (thesis) => <AvatarUserList users={thesis.advisors} />,
},
students: {
accessor: 'students',
title: 'Student(s)',
ellipsis: true,
width: 180,
render: (thesis: IThesis) => <AvatarUserList users={thesis.students} />,
render: (thesis) => <AvatarUserList users={thesis.students} />,
},
type: {
accessor: 'type',
title: 'Type',
ellipsis: true,
width: 150,
render: (thesis: IThesis) => formatThesisType(thesis.type),
render: (thesis) => formatThesisType(thesis.type),
},
title: {
accessor: 'title',
Expand All @@ -91,15 +91,15 @@ const ThesesTable = (props: IThesesTableProps) => {
sortable: true,
ellipsis: true,
width: 130,
render: (thesis: IThesis) => formatDate(thesis.startDate, { withTime: false }),
render: (thesis) => formatDate(thesis.startDate, { withTime: false }),
},
end_date: {
accessor: 'endDate',
title: 'End Date',
sortable: true,
ellipsis: true,
width: 130,
render: (thesis: IThesis) => formatDate(thesis.endDate, { withTime: false }),
render: (thesis) => formatDate(thesis.endDate, { withTime: false }),
},
...extraColumns,
}
Expand Down
4 changes: 4 additions & 0 deletions client/src/hooks/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ export function useHasGroupAccess(...groups: string[]) {

return user?.groups.some((group) => groups.includes(group)) ?? false
}

export function useManagementAccess() {
return useHasGroupAccess('admin', 'supervisor', 'advisor')
}
4 changes: 2 additions & 2 deletions client/src/pages/DashboardPage/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ThesesProvider from '../../contexts/ThesesProvider/ThesesProvider'
import { Button, Center, Group, Stack, Title } from '@mantine/core'
import { ApplicationState, IApplication } from '../../requests/responses/application'
import ThesesGanttChart from '../../components/ThesesGanttChart/ThesesGanttChart'
import { useHasGroupAccess } from '../../hooks/authentication'
import { useHasGroupAccess, useManagementAccess } from '../../hooks/authentication'
import { Link } from 'react-router-dom'
import ApplicationModal from '../../components/ApplicationModal/ApplicationModal'
import MyTasksSection from './components/MyTasksSection/MyTasksSection'
Expand All @@ -20,7 +20,7 @@ const DashboardPage = () => {

const [application, setApplication] = useState<IApplication>()

const managementAccess = useHasGroupAccess('admin', 'supervisor', 'advisor')
const managementAccess = useManagementAccess()

return (
<Stack gap='md'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,14 @@ import {
Title,
Tooltip,
} from '@mantine/core'
import React, { useEffect, useState } from 'react'
import PresentationsTable from '../../../../components/PresentationsTable/PresentationsTable'
import { IPublishedPresentation } from '../../../../requests/responses/thesis'
import { doRequest } from '../../../../requests/request'
import { PaginationResponse } from '../../../../requests/responses/pagination'
import { showSimpleError } from '../../../../utils/notification'
import { getApiResponseErrorMessage } from '../../../../requests/handler'
import React from 'react'
import { GLOBAL_CONFIG } from '../../../../config/global'
import { Check, Copy } from 'phosphor-react'
import { useNavigate } from 'react-router-dom'
import { useManagementAccess } from '../../../../hooks/authentication'
import PublicPresentationsTable from '../../../../components/PublicPresentationsTable/PublicPresentationsTable'

const PublicPresentationsSection = () => {
const limit = 10

const navigate = useNavigate()

const [presentations, setPresentations] = useState<PaginationResponse<IPublishedPresentation>>()
const [page, setPage] = useState(0)

useEffect(() => {
setPresentations(undefined)

return doRequest<PaginationResponse<IPublishedPresentation>>(
`/v2/published-presentations`,
{
method: 'GET',
requiresAuth: false,
params: {
page,
limit,
},
},
(res) => {
if (res.ok) {
setPresentations(res.data)
} else {
showSimpleError(getApiResponseErrorMessage(res))
}
},
)
}, [page, limit])
const managementAccess = useManagementAccess()

const calendarUrl =
GLOBAL_CONFIG.calendar_url || `${GLOBAL_CONFIG.server_host}/api/v2/calendar/presentations`
Expand Down Expand Up @@ -77,16 +44,7 @@ const PublicPresentationsSection = () => {
</CopyButton>
</div>
</Group>
<PresentationsTable
presentations={presentations?.content}
onRowClick={(presentation) => navigate(`/presentations/${presentation.presentationId}`)}
pagination={{
totalRecords: presentations?.totalElements ?? 0,
recordsPerPage: limit,
page: page + 1,
onPageChange: (newPage) => setPage(newPage - 1),
}}
/>
<PublicPresentationsTable includeDrafts={managementAccess} />
</Stack>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Group, Stack, Text } from '@mantine/core'
import { usePageTitle } from '../../../../hooks/theme'
import { useHasGroupAccess, useLoggedInUser } from '../../../../hooks/authentication'
import { useHasGroupAccess, useLoggedInUser, useManagementAccess } from '../../../../hooks/authentication'
import ThesesTable from '../../../../components/ThesesTable/ThesesTable'
import ThesesProvider from '../../../../contexts/ThesesProvider/ThesesProvider'
import React, { useEffect, useState } from 'react'
Expand All @@ -12,7 +12,7 @@ const NotificationSettings = () => {
usePageTitle('Notification Settings')

const user = useLoggedInUser()
const managementAccess = useHasGroupAccess('admin', 'supervisor', 'advisor')
const managementAccess = useManagementAccess()

const [settings, setSettings] = useState<Array<{ name: string; email: string }>>()

Expand Down
4 changes: 2 additions & 2 deletions client/src/pages/ThesisOverviewPage/ThesisOverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { Button, Group, Space, Stack, Title } from '@mantine/core'
import { ThesisState } from '../../requests/responses/thesis'
import CreateThesisModal from './components/CreateThesisModal/CreateThesisModal'
import { Plus } from 'phosphor-react'
import { useHasGroupAccess } from '../../hooks/authentication'
import { useManagementAccess } from '../../hooks/authentication'

const ThesisOverviewPage = () => {
usePageTitle('Theses')

const [openCreateThesisModal, setOpenCreateThesisModal] = useState(false)

const managementAccess = useHasGroupAccess('admin', 'supervisor', 'advisor')
const managementAccess = useManagementAccess()

return (
<Stack>
Expand Down
Loading

0 comments on commit ea72a07

Please sign in to comment.