Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSCEXAM-1204 Max date of examination event to equal exam period #1037

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions app/controllers/SettingsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,6 @@ public Result getMaxFilesize() {
return ok(Json.toJson(node));
}

@Restrict({ @Group("ADMIN"), @Group("TEACHER") })
public Result getExamMaxDate() {
ObjectNode node = Json.newObject();
node.put("maxDate", configReader.getExamMaxDate());
return ok(Json.toJson(node));
}

@Restrict({ @Group("ADMIN"), @Group("TEACHER") })
public Result getExamDurations() {
ObjectNode node = Json.newObject();
Expand Down
10 changes: 10 additions & 0 deletions app/impl/ExamUpdaterImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ public Optional<Result> updateTemporalFieldsAndValidate(Exam exam, User user, Ht
exam.setDuration(newDuration.orElse(null));
return Optional.empty();
}
if (exam.isUnsupervised() && newEnd.isPresent()) {
Set<DateTime> dates = exam
.getExaminationEventConfigurations()
.stream()
.map(c -> c.getExaminationEvent().getStart())
.collect(Collectors.toSet());
if (dates.stream().anyMatch(d -> d.isAfter(newEnd.get()))) {
return Optional.of(forbidden("i18n_error_future_reservations_exist"));
}
}
boolean hasFutureReservations = hasFutureReservations(exam);
boolean isAdmin = user.hasRole(Role.Name.ADMIN);
if (newStart.isPresent()) {
Expand Down
28 changes: 4 additions & 24 deletions app/models/Exam.java
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,10 @@ public boolean isPrintout() {
return executionType.getType().equals(ExamExecutionType.Type.PRINTOUT.toString());
}

public boolean isUnsupervised() {
return !executionType.getType().equals(Implementation.AQUARIUM.toString());
}

public boolean hasState(State... states) {
return Arrays.asList(states).contains(state);
}
Expand Down Expand Up @@ -895,30 +899,6 @@ public int hashCode() {
return new HashCodeBuilder().append(id).build();
}

@Override
public String toString() {
return (
"Exam{" +
"course=" +
course +
", id='" +
id +
'\'' +
", name='" +
name +
'\'' +
", examType=" +
examType +
", hash='" +
hash +
'\'' +
", state='" +
state +
'\'' +
'}'
);
}

@Override
public int compareTo(@Nonnull Exam other) {
return created.compareTo(other.created);
Expand Down
1 change: 0 additions & 1 deletion app/util/config/ConfigReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ public interface ConfigReader {
DateTimeZone getDefaultTimeZone();
String getHostName();
Integer getMaxFileSize();
String getExamMaxDate();
List<Integer> getExamDurations();
Integer getExamMaxDuration();
Integer getExamMinDuration();
Expand Down
7 changes: 0 additions & 7 deletions app/util/config/ConfigReaderImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,6 @@ public Integer getMaxFileSize() {
return config.getInt("exam.attachment.maxsize");
}

@Override
public String getExamMaxDate() {
DateTime newDate = new DateTime(0);
Period period = Period.parse(config.getString("exam.exam.maxDate"));
return newDate.plus(period).toString();
}

@Override
public List<Integer> getExamDurations() {
String[] durations = config.getString("exam.exam.durations").split(",");
Expand Down
1 change: 0 additions & 1 deletion conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,6 @@ PUT /app/settings/deadline controlle
GET /app/settings/reservationWindow controllers.SettingsController.getReservationWindowSize
PUT /app/settings/reservationWindow controllers.SettingsController.setReservationWindowSize(request: Request)
GET /app/settings/hostname controllers.SettingsController.getHostname
GET /app/settings/maxDate controllers.SettingsController.getExamMaxDate
GET /app/settings/durations controllers.SettingsController.getExamDurations
GET /app/settings/maxDuration controllers.SettingsController.getExamMaxDuration
GET /app/settings/minDuration controllers.SettingsController.getExamMinDuration
Expand Down
2 changes: 1 addition & 1 deletion lefthook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pre-commit:
prettier-java:
tags: backend style
glob: "**/*.java"
run: prettier --write --plugin=prettier-plugin-java --print-width=120 --tab-width=4 {staged_files}
run: npx prettier --write --plugin=prettier-plugin-java --print-width=120 --tab-width=4 {staged_files}
eslint:
tags: frontend rules
glob: "**/*.ts"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h1 class="student-enroll-title">
[hourStep]="1"
[minuteStep]="15"
[initialTime]="start()"
[examMaxDate]="examMaxDate"
[maxDate]="examMaxDate"
(updated)="onStartDateChange($event)"
autofocus
>
Expand Down Expand Up @@ -129,10 +129,7 @@ <h1 class="student-enroll-title">
</form>
<div class="modal-footer">
<div class="student-message-dialog-button-save">
<button
[disabled]="eventForm.invalid || (maxDateValidator && maxDateValidator < start())"
(click)="ok()"
>
<button [disabled]="eventForm.invalid" (click)="ok()">
{{ 'i18n_button_accept' | translate }}
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { Component, Input, computed, effect, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { DateTime } from 'luxon';
import { ToastrService } from 'ngx-toastr';
import { DateTimePickerComponent } from 'src/app/shared/date/date-time-picker.component';
import { OrderByPipe } from 'src/app/shared/sorting/order-by.pipe';
Expand All @@ -40,7 +39,7 @@ export class ExaminationEventDialogComponent implements OnInit {
@Input() config?: ExaminationEventConfiguration;
@Input() maintenancePeriods: MaintenancePeriod[] = [];
@Input() requiresPassword = false;
@Input() examMaxDate?: string;
@Input() examMaxDate = '';
start = signal(new Date(new Date().getTime() + 60 * 1000));
description = signal('');
capacity = signal(0);
Expand All @@ -54,7 +53,6 @@ export class ExaminationEventDialogComponent implements OnInit {
hasEnrolments = signal(false);
settingsPasswordInputType = signal('password');
quitPasswordInputType = signal('password');
maxDateValidator?: Date;
private now = new Date();

constructor(
Expand Down Expand Up @@ -89,10 +87,6 @@ export class ExaminationEventDialogComponent implements OnInit {
return d;
});
}
if (this.examMaxDate) {
const maxDate = new Date(Date.parse(this.examMaxDate)).getTime() - new Date(0).getTime();
this.maxDateValidator = new Date(this.now.getTime() + maxDate);
}
this.http
.get<{ max: number }>('/app/settings/byodmaxparticipants')
.subscribe((value) => this.maxSimultaneousCapacity.set(value.max));
Expand All @@ -104,13 +98,6 @@ export class ExaminationEventDialogComponent implements OnInit {
this.quitPasswordInputType.set(this.quitPasswordInputType() === 'text' ? 'password' : 'text');

onStartDateChange = (event: { date: Date }) => {
if (this.maxDateValidator && this.maxDateValidator < event.date) {
this.toast.error(
this.translate.instant('i18n_date_too_far_in_future') +
' ' +
DateTime.fromJSDate(this.maxDateValidator || new Date()).toFormat('dd.MM.yyyy HH:mm'),
);
}
if (this.now > event.date) {
this.toast.error(this.translate.instant('i18n_select_time_in_future'));
}
Expand All @@ -121,10 +108,6 @@ export class ExaminationEventDialogComponent implements OnInit {
if (!this.start) {
this.toast.error(this.translate.instant('i18n_no_examination_start_date_picked'));
}
if (this.maxDateValidator && this.maxDateValidator < this.start()) {
this.toast.error(this.translate.instant('i18n_invalid_start_date_picked'));
return;
}
const config = {
config: {
examinationEvent: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export class ExamPublicationComponent implements OnInit {
examDurations: number[] = [];
maintenancePeriods: MaintenancePeriod[] = [];
visibleParticipantSelector = 'participant';
examMaxDate?: Date;
timeValue?: number;
hourValue?: number;
minuteValue?: number;
Expand Down Expand Up @@ -107,9 +106,6 @@ export class ExamPublicationComponent implements OnInit {
next: (data) => (this.examDurations = data.examDurations),
error: (err) => this.toast.error(err),
});
this.http
.get<{ maxDate: Date }>('/app/settings/maxDate')
.subscribe({ next: (data) => (this.examMaxDate = data.maxDate), error: (err) => this.toast.error(err) });
this.http.get<{ maxDuration: number }>('/app/settings/maxDuration').subscribe({
next: (data) => (this.maxDuration = data.maxDuration),
error: (err) => this.toast.error(err),
Expand Down Expand Up @@ -295,7 +291,7 @@ export class ExamPublicationComponent implements OnInit {
size: 'lg',
});
modalRef.componentInstance.requiresPassword = this.exam.implementation === 'CLIENT_AUTH';
modalRef.componentInstance.examMaxDate = this.examMaxDate;
modalRef.componentInstance.examMaxDate = this.exam.periodEnd;
modalRef.componentInstance.maintenancePeriods = this.maintenancePeriods;
modalRef.componentInstance.examId = this.exam.id;
modalRef.componentInstance.duration = this.exam.duration;
Expand All @@ -314,7 +310,7 @@ export class ExamPublicationComponent implements OnInit {
});
modalRef.componentInstance.config = configuration;
modalRef.componentInstance.requiresPassword = this.exam.implementation === 'CLIENT_AUTH';
modalRef.componentInstance.examMaxDate = this.examMaxDate;
modalRef.componentInstance.examMaxDate = this.exam.periodEnd;
modalRef.componentInstance.maintenancePeriods = this.maintenancePeriods;
modalRef.componentInstance.examId = this.exam.id;
modalRef.componentInstance.duration = this.exam.duration;
Expand Down
7 changes: 2 additions & 5 deletions ui/src/app/shared/date/date-time-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,13 @@ export class DateTimePickerComponent implements OnInit, OnChanges {
@Input() hourStep = 0;
@Input() minuteStep = 0;
@Input() disabled = false;
@Input() examMaxDate?: string;
@Input() maxDate?: string;
@Input() disableDate?: boolean = false;
@Input() disableTime?: boolean = false;
@Output() updated = new EventEmitter<{ date: Date }>();

date: Date = new Date();
time!: { hour: number; minute: number; second: number; millisecond?: number };
maxDate?: string;
minDate?: string;

ngOnInit() {
Expand All @@ -69,10 +68,8 @@ export class DateTimePickerComponent implements OnInit, OnChanges {
this.setDateTime(this.initialTime);
}
this.minDate = now.toISOString();
if (this.examMaxDate) {
this.maxDate = new Date(now.getTime() + new Date(this.examMaxDate).getTime()).toISOString();
}
}

ngOnChanges() {
const now = new Date();
this.time = { hour: now.getHours(), minute: now.getMinutes(), second: now.getSeconds() };
Expand Down
Loading