Skip to content

Commit

Permalink
Merge pull request #230 from Dudrie/issue-222-Add_overview_page_for_a…
Browse files Browse the repository at this point in the history
…dmin_which_shows_the_results_of_a_criteria

Add overview page for admin which shows the results of a criteria
  • Loading branch information
Dudrie authored Jan 30, 2020
2 parents ef83d25 + fa7f371 commit fbfdbb6
Show file tree
Hide file tree
Showing 33 changed files with 817 additions and 470 deletions.
5 changes: 4 additions & 1 deletion client/public/static/locales/de/scheincriteria.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,8 @@
"UNIT_LABEL_PRESENTATION_plural" : "Präsentationen",
"UNIT_LABEL_SHEET_plural" : "Blätter",
"true" : "Ja",
"false" : "Nein"
"false" : "Nein",
"ACHIEVED_PIE_CHART_LABEL_achieved": "Bestanden",
"ACHIEVED_PIE_CHART_LABEL_notAchieved": "Nicht bestanden",
"ACHIEVED_PIE_CHART_LABEL_notPresent": "Abwesend"
}
70 changes: 70 additions & 0 deletions client/src/components/info-paper/ChartPaper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { CircularProgress, PaperProps } from '@material-ui/core';
import { createStyles, makeStyles, useTheme } from '@material-ui/core/styles';
import React from 'react';
import Chart from 'react-google-charts';
import { ReactGoogleChartProps } from 'react-google-charts/dist/types';
import InfoPaper from './InfoPaper';

const useStyles = makeStyles(theme =>
createStyles({
summaryPaper: {
flex: 1,
background: theme.palette.background.default,
padding: theme.spacing(1.5),
},
title: {
textAlign: 'center',
},
chart: {
width: '100%',
height: '100%',
},
loader: {
position: 'absolute',
top: '50%',
left: '50%',
},
})
);

interface Props extends ReactGoogleChartProps {
title: string;
PaperProps?: PaperProps;
}

function ChartPaper({ PaperProps, title, ...chartProps }: Props): JSX.Element {
const classes = useStyles();
const theme = useTheme();
const { fontStyle } = theme.mixins.chart(theme);

return (
<InfoPaper title={title} {...PaperProps}>
<Chart
{...chartProps}
options={{
backgroundColor: 'transparent',
...fontStyle,
...chartProps.options,
legend: {
...fontStyle,
...chartProps.options?.legend,
},
hAxis: {
...fontStyle,
...chartProps.options?.hAxis,
baselineColor: theme.palette.text.primary,
},
vAxis: {
...fontStyle,
...chartProps.options?.vAxis,
baselineColor: theme.palette.text.primary,
},
}}
className={classes.chart}
loader={<CircularProgress className={classes.loader} />}
/>
</InfoPaper>
);
}

export default ChartPaper;
37 changes: 37 additions & 0 deletions client/src/components/info-paper/InfoPaper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Paper, PaperProps, Typography } from '@material-ui/core';
import { createStyles, makeStyles } from '@material-ui/core/styles';
import clsx from 'clsx';
import React from 'react';

const useStyles = makeStyles(theme =>
createStyles({
summaryPaper: {
flex: 1,
background: theme.palette.background.default,
padding: theme.spacing(1.5),
position: 'relative',
},
title: {
textAlign: 'center',
},
})
);

interface Props extends PaperProps {
title: string;
children?: React.ReactNode;
}

function InfoPaper({ children, title, className, ...props }: Props): JSX.Element {
const classes = useStyles();

return (
<Paper variant='outlined' {...props} className={clsx(className, classes.summaryPaper)}>
<Typography className={classes.title}>{title}</Typography>

{children}
</Paper>
);
}

export default InfoPaper;
18 changes: 17 additions & 1 deletion client/src/hooks/fetching/Scheincriteria.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import axios from './Axios';
import { FormDataResponse } from '../../components/generatedForm/types/FieldData';
import { ScheinCriteriaResponse, ScheinCriteriaDTO } from 'shared/dist/model/ScheinCriteria';
import {
ScheinCriteriaResponse,
ScheinCriteriaDTO,
CriteriaInformation,
} from 'shared/dist/model/ScheinCriteria';

export async function getAllScheinCriterias(): Promise<ScheinCriteriaResponse[]> {
const response = await axios.get<ScheinCriteriaResponse[]>('scheincriteria');
Expand All @@ -12,6 +16,18 @@ export async function getAllScheinCriterias(): Promise<ScheinCriteriaResponse[]>
return Promise.reject(`Wrong response code (${response.status}).`);
}

export async function getScheincriteriaInformation(
criteriaId: string
): Promise<CriteriaInformation> {
const response = await axios.get<CriteriaInformation>(`scheincriteria/${criteriaId}/info`);

if (response.status === 200) {
return response.data;
}

return Promise.reject(`Wrong response code (${response.status}).`);
}

export async function getScheinCriteriaFormData(): Promise<FormDataResponse> {
const response = await axios.get<FormDataResponse>('scheincriteria/form');

Expand Down
15 changes: 8 additions & 7 deletions client/src/hooks/fetching/Student.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Attendance, AttendanceDTO } from 'shared/dist/model/Attendance';
import { UpdatePointsDTO } from 'shared/dist/model/Points';
import { ScheinCriteriaSummary } from 'shared/dist/model/ScheinCriteria';
import {
ScheinCriteriaSummary,
ScheincriteriaSummaryByStudents,
} from 'shared/dist/model/ScheinCriteria';
import {
CakeCountDTO,
PresentationPointsDTO,
Expand Down Expand Up @@ -152,12 +155,10 @@ export async function getScheinCriteriaSummaryOfStudent(
return Promise.reject(`Wrong status code (${response.status}).`);
}

export async function getScheinCriteriaSummaryOfAllStudents(): Promise<{
[studentId: string]: ScheinCriteriaSummary;
}> {
const response = await axios.get<{ [studentId: string]: ScheinCriteriaSummary }>(
`/scheincriteria/student`
);
export async function getScheinCriteriaSummaryOfAllStudents(): Promise<
ScheincriteriaSummaryByStudents
> {
const response = await axios.get<ScheincriteriaSummaryByStudents>(`/scheincriteria/student`);

if (response.status === 200) {
return response.data;
Expand Down
4 changes: 4 additions & 0 deletions client/src/routes/Routing.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,7 @@ export function getStudentInfoPath({ studentId, tutorialId }: StudentInfoParams)
.replace(':tutorialId?', tutorialId ?? '')
.replace(/\/\/+/, '/');
}

export function getScheincriteriaInfoPath(criteriaId: string): string {
return RoutingPath.SCHEIN_CRITERIAS_INFO.replace(':id', criteriaId).replace(/\/\/+/, '/');
}
13 changes: 12 additions & 1 deletion client/src/routes/Routing.routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import UserManagement from '../view/usermanagement/UserManagement';
import ScheinexamPointsOverview from '../view/points-scheinexam/overview/ScheinexamPointsOverview';
import EnterScheinexamPoints from '../view/points-scheinexam/enter-form/EnterScheinexamPoints';
import StudentInfo from '../view/studentmanagement/student-info/StudentInfo';
import CriteriaInfoView from '../view/criteria-info-view/CriteriaInfoView';

export enum RoutingPath {
ROOT = '/',
Expand All @@ -52,7 +53,8 @@ export enum RoutingPath {
MANAGE_USERS = '/admin/usermanagement',
MANAGE_TUTORIALS = '/admin/tutorialmanagement',
MANAGE_TUTORIALS_SUBSTITUTES = '/admin/tutorialmanagement/:tutorialid/substitute',
MANAGE_SCHEIN_CRITERIAS = '/admin/scheincriteriamanagement',
MANAGE_SCHEIN_CRITERIAS = '/admin/scheincriterias',
SCHEIN_CRITERIAS_INFO = '/admin/scheincriterias/info/:id',
MANAGE_ATTENDANCES = '/admin/attendances',
MANAGE_SHEETS = '/admin/sheets',
MANAGE_ALL_STUDENTS = '/admin/students',
Expand Down Expand Up @@ -224,6 +226,15 @@ export const ROUTES: readonly RouteType[] = [
isInDrawer: true,
isPrivate: true,
},
{
path: RoutingPath.SCHEIN_CRITERIAS_INFO,
title: 'Scheinkriterien',
component: CriteriaInfoView,
icon: ScriptTextIcon,
roles: [Role.ADMIN, Role.EMPLOYEE],
isInDrawer: false,
isPrivate: true,
},
{
path: RoutingPath.MANAGE_SCHEIN_CRITERIAS,
title: 'Scheinkriterien',
Expand Down
19 changes: 6 additions & 13 deletions client/src/view/attendance/AttendanceManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import { useSnackbar } from 'notistack';
import React, { ChangeEvent, useEffect, useState } from 'react';
import { Attendance, AttendanceDTO, AttendanceState } from 'shared/dist/model/Attendance';
import { Student, StudentStatus } from 'shared/dist/model/Student';
import { LoggedInUser, TutorInfo } from 'shared/dist/model/User';
import { LoggedInUser } from 'shared/dist/model/User';
import { NoteFormCallback } from '../../components/attendance-controls/components/AttendanceNotePopper';
import CustomSelect from '../../components/CustomSelect';
import DateOfTutorialSelection from '../../components/DateOfTutorialSelection';
import SubmitButton from '../../components/loading/SubmitButton';
import LoadingSpinner from '../../components/loading/LoadingSpinner';
import SubmitButton from '../../components/loading/SubmitButton';
import TableWithPadding from '../../components/TableWithPadding';
import { useAxios } from '../../hooks/FetchingService';
import { useLogin } from '../../hooks/LoginService';
import { TutorialWithFetchedStudents as Tutorial } from '../../typings/types';
import { parseDateToMapKey, saveBlob } from '../../util/helperFunctions';
import StudentAttendanceRow from './components/StudentsAttendanceRow';
import { NoteFormCallback } from '../../components/attendance-controls/components/AttendanceNotePopper';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
Expand Down Expand Up @@ -112,7 +112,6 @@ function AttendanceManager({ tutorial: tutorialFromProps }: Props): JSX.Element

const [date, setDate] = useState<Date | undefined>(undefined);

const [tutorInfo, setTutorInfo] = useState<TutorInfo | undefined>();
const [tutorial, setTutorial] = useState<Tutorial | undefined>();
const [tutorials, setTutorials] = useState<Tutorial[]>([]);

Expand All @@ -128,7 +127,6 @@ function AttendanceManager({ tutorial: tutorialFromProps }: Props): JSX.Element
setAttendanceOfStudent,
setCakeCountForStudent,
getAllTutorialsAndFetchStudents,
getTutorInfoOfTutorial,
getAttendancePDF,
} = useAxios();

Expand All @@ -137,16 +135,11 @@ function AttendanceManager({ tutorial: tutorialFromProps }: Props): JSX.Element
}, [tutorialFromProps]);

useEffect(() => {
let students: Student[] = [];

if (tutorial) {
students = tutorial.students;
getTutorInfoOfTutorial(tutorial.id).then(info => setTutorInfo(info));
}
const students: Student[] = tutorial?.students ?? [];

setFetchedStudents(students);
setDate(undefined);
}, [tutorial, getTutorInfoOfTutorial]);
}, [tutorial]);

useEffect(() => {
setFilteredStudents(getFilteredStudents(fetchedStudents, filterOption));
Expand Down Expand Up @@ -378,7 +371,7 @@ function AttendanceManager({ tutorial: tutorialFromProps }: Props): JSX.Element
color='primary'
isSubmitting={isLoadingPDF}
onClick={printAttendanceSheet}
disabled={!tutorial || !date || !tutorInfo}
disabled={!tutorial || !date}
tooltipText='Erstellt eine Unterschriftenliste für den ausgewählten Tag.'
>
Unterschriftenliste erstellen
Expand Down
Loading

0 comments on commit fbfdbb6

Please sign in to comment.