Skip to content

Commit

Permalink
Merge branch 'dev' into CSCEXAM-1291
Browse files Browse the repository at this point in the history
  • Loading branch information
lupari authored Jun 19, 2024
2 parents c0f097b + 0d05a6e commit dff4e4a
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 117 deletions.
3 changes: 2 additions & 1 deletion app/controllers/ReviewDocumentsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ import scala.jdk.CollectionConverters.*
import scala.util.Using

class ReviewDocumentsController @Inject() (
val controllerComponents: ControllerComponents,
csvBuilder: CsvBuilder,
fileHandler: FileHandler,
authenticated: AuthenticatedAction,
implicit val ec: AuthExecutionContext
) extends InjectedController
) extends BaseController
with JavaApiHelper
with DbApiHelper
with Logging:
Expand Down
13 changes: 9 additions & 4 deletions ui/src/app/calendar/helpers/slot-picker.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ <h2 class="calendar-phase-title">{{ sequenceNumber }}. {{ 'i18n_calendar_phase_2
</button>
<div ngbDropdownMenu role="menu" aria-labelledby="dropDownMenu1" class="xm-scrollable-menu">
@for (room of rooms(); track room.id) {
<button ngbDropdownItem role="presentation" (click)="selectRoom(room)" title="{{ room.name }}">
<div ngbDropdownItem [disabled]="room.outOfService" role="menuitem">
<a> {{ room.name }}</a>
</div>
<button
ngbDropdownItem
[class]="room.outOfService ? 'disabled' : ''"
role="menuitem"
(click)="selectRoom(room)"
title="{{ room.name }}"
[attr.aria-disabled]="room.outOfService"
>
<a> {{ room.name }}</a>
</button>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,101 +6,90 @@
<div ngbDropdownMenu>
<!-- enrolment with reservation, allow changing -->
@if (enrolment.reservation && canChangeReservation(enrolment.reservation)) {
<div ngbDropdownItem>
<!-- collaborative exam taken here -->
@if (enrolment.reservation.machine && enrolment.collaborativeExam) {
<a
class="btn btn-outline-secondary"
[routerLink]="['/calendar', enrolment.collaborativeExam.id, 'collaborative']"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
<!-- regular exam taken here -->
@if (enrolment.reservation.machine && !enrolment.collaborativeExam) {
<a class="btn btn-outline-secondary" [routerLink]="['/calendar', enrolment.exam.id]"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
<!-- regular exam taken elsewhere -->
@if (enrolment.reservation.externalReservation && enrolment.exam) {
<a class="btn btn-outline-secondary" [routerLink]="['/calendar', enrolment.exam.id, 'external']"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
<!-- collaborative exam taken elsewhere -->
@if (enrolment.reservation.externalReservation && enrolment.collaborativeExam) {
<a
class="btn btn-outline-secondary"
[routerLink]="['/calendar', enrolment.collaborativeExam.id, 'external']"
[queryParams]="{ isCollaborative: true }"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
</div>
<!-- collaborative exam taken here -->
@if (enrolment.reservation.machine && enrolment.collaborativeExam) {
<a
ngbDropdownItem
class="btn btn-outline-secondary"
[routerLink]="['/calendar', enrolment.collaborativeExam.id, 'collaborative']"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
<!-- regular exam taken here -->
@if (enrolment.reservation.machine && !enrolment.collaborativeExam) {
<a ngbDropdownItem class="btn btn-outline-secondary" [routerLink]="['/calendar', enrolment.exam.id]"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
<!-- regular exam taken elsewhere -->
@if (enrolment.reservation.externalReservation && enrolment.exam) {
<a
ngbDropdownItem
class="btn btn-outline-secondary"
[routerLink]="['/calendar', enrolment.exam.id, 'external']"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
<!-- collaborative exam taken elsewhere -->
@if (enrolment.reservation.externalReservation && enrolment.collaborativeExam) {
<a
ngbDropdownItem
class="btn btn-outline-secondary"
[routerLink]="['/calendar', enrolment.collaborativeExam.id, 'external']"
[queryParams]="{ isCollaborative: true }"
>{{ 'i18n_student_change_reservation' | translate }}
</a>
}
}
<!-- enrolment with examination event, allow changing -->
@if (enrolment.examinationEventConfiguration && hasUpcomingAlternativeEvents()) {
<div ngbDropdownItem>
<button class="btn btn-outline-secondary" (click)="makeReservation()">
{{ 'i18n_student_change_reservation' | translate }}
</button>
</div>
<button ngbDropdownItem class="btn btn-outline-secondary" (click)="makeReservation()">
{{ 'i18n_student_change_reservation' | translate }}
</button>
}
<!-- enrolment with reservation, allow reservation removal -->
@if (enrolment.reservation && canChangeReservation(enrolment.reservation)) {
<div ngbDropdownItem>
<button class="btn btn-outline-danger" (click)="removeReservation()">
{{ 'i18n_student_remove_reservation' | translate }}
</button>
</div>
<button ngbDropdownItem class="btn btn-outline-danger" (click)="removeReservation()">
{{ 'i18n_student_remove_reservation' | translate }}
</button>
}
<!-- reservation in progress, inform with a disabled item -->
@if (enrolment.reservation && !canChangeReservation(enrolment.reservation)) {
<div>
<button class="btn btn-outline-danger" [disabled]="true" (click)="removeReservation()">
{{ 'i18n_not_allowed_to_modify_reservation' | translate }}
</button>
</div>
<button ngbDropdownItem class="btn btn-outline-danger" [disabled]="true" (click)="removeReservation()">
{{ 'i18n_not_allowed_to_modify_reservation' | translate }}
</button>
}
<!-- enrolment with examination event, allow event removal -->
@if (enrolment.examinationEventConfiguration) {
<div ngbDropdownItem>
<button class="btn btn-outline-danger" (click)="removeReservation()">
{{ 'i18n_student_remove_reservation' | translate }}
</button>
</div>
<button ngbDropdownItem class="btn btn-outline-danger" (click)="removeReservation()">
{{ 'i18n_student_remove_reservation' | translate }}
</button>
}
<!-- enrolment without reservation or examination event, allow unenrolling (if other conditions pass) -->
@if (
!enrolment.reservation &&
!enrolment.examinationEventConfiguration &&
(enrolment.exam?.executionType?.type === 'PUBLIC' || enrolment.collaborativeExam)
) {
<div ngbDropdownItem>
<button (click)="removeEnrolment()" class="btn btn-outline-danger">
{{ 'i18n_student_remove_enrolment' | translate }}
</button>
</div>
<button ngbDropdownItem (click)="removeEnrolment()" class="btn btn-outline-danger">
{{ 'i18n_student_remove_enrolment' | translate }}
</button>
}
<!-- enrolment without reservation, allow making reservation -->
@if ((!enrolment.reservation && enrolment.exam?.implementation === 'AQUARIUM') || enrolment.collaborativeExam) {
<div ngbDropdownItem>
<button (click)="makeReservation()" class="btn btn-outline-secondary">
{{ 'i18n_student_new_reservation' | translate }}
</button>
</div>
<button ngbDropdownItem (click)="makeReservation()" class="btn btn-outline-secondary">
{{ 'i18n_student_new_reservation' | translate }}
</button>
}
<!-- enrolment without examination event, allow making reservation -->
@if (
!enrolment.examinationEventConfiguration &&
enrolment.exam?.implementation !== 'AQUARIUM' &&
hasUpcomingAlternativeEvents()
) {
<div ngbDropdownItem>
<button class="btn btn-outline-secondary" (click)="makeReservation()">
{{ 'i18n_student_new_reservation' | translate }}
</button>
</div>
<button ngbDropdownItem class="btn btn-outline-secondary" (click)="makeReservation()">
{{ 'i18n_student_new_reservation' | translate }}
</button>
}
</div>
</div>
2 changes: 1 addition & 1 deletion ui/src/app/enrolment/enrolment.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export class EnrolmentService {
this.http.get<CollaborativeParticipation[]>('/app/iop/student/finishedExams');

searchExams$ = (searchTerm: string): Observable<CollaborativeExam[]> => {
const paramStr = '?filter=' + (searchTerm && searchTerm.length > 0 ? encodeURIComponent(searchTerm) : '');
const paramStr = '?filter=' + (searchTerm?.length > 0 ? encodeURIComponent(searchTerm) : '');
const path = `/app/iop/enrolment${paramStr}`;
return this.http.get<CollaborativeExam[]>(path);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class CollaborativeParticipationsComponent implements OnInit, AfterViewIn
pageSize = 10;
currentPage = 0;
filter = { ordering: 'ended', reverse: true, text: '' };
searchDone = false;

constructor(
private changeDetector: ChangeDetectorRef,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@
<div class="input-group-append search">
<img alt="" src="/assets/images/icon_search.png" width="49" height="40" />
</div>
<div class="invisible">{{ participations.length > 0 ? '' : '' }}</div>
</div>
</div>
@if (searchDone) {
<div class="row my-2">
<div class="col-12" aria-live="polite">
{{ 'i18n_student_exam_search_result' | translate }} {{ participations.length }}
{{ 'i18n_student_exam_search_result_continues' | translate }}
</div>
</div>
}
<div class="col-8" ngbDropdown>
<button class="btn btn-outline-secondary" type="button" ngbDropdownToggle aria-expanded="true">
{{ 'i18n_set_ordering' | translate }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class ExamParticipationsComponent implements OnInit, OnDestroy {
collaborative = false;
filterChanged: Subject<string> = new Subject<string>();
ngUnsubscribe = new Subject();
searchDone = false;

constructor(
private toast: ToastrService,
Expand Down Expand Up @@ -91,6 +92,7 @@ export class ExamParticipationsComponent implements OnInit, OnDestroy {
(p) => (p.ended = p.reservation ? p.reservation.endAt : p.started),
);
this.participations = data.filter((d) => d.ended);
this.searchDone = true;
},
error: (err) => this.toast.error(err),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,11 @@ import { ExamSearchResultComponent } from './exam-search-result.component';
</div>
</div>
</div>
@if (exams.length > 0 && filter.text.length > 2) {
@if (searchDone) {
<div class="row mt-2">
<div class="col-12">
<div class="col-12" aria-live="polite">
{{ 'i18n_student_exam_search_result' | translate }} {{ exams.length }}
{{ 'i18n_student_exam_search_result_continues' | translate }}
<b>"{{ filter.text }}"</b>
</div>
</div>
}
Expand Down Expand Up @@ -95,6 +93,7 @@ export class CollaborativeExamSearchComponent implements OnInit, OnDestroy {
loader = { loading: false };
filterChanged: Subject<string> = new Subject<string>();
ngUnsubscribe = new Subject();
searchDone = false;

constructor(private Enrolment: EnrolmentService) {
this.filterChanged
Expand Down Expand Up @@ -140,7 +139,7 @@ export class CollaborativeExamSearchComponent implements OnInit, OnDestroy {
if (text.length > 2) {
this.filter.text = text;
this.loader = { loading: true };

this.searchDone = true;
this.Enrolment.searchExams$(text)
.pipe(
tap((exams) => this.updateExamList(exams)),
Expand Down
8 changes: 4 additions & 4 deletions ui/src/app/enrolment/search/exam-search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,11 @@ import { ExamSearchService } from './exam-search.service';
</div>
</div>
}
@if (exams.length > 0) {
@if (searchDone) {
<div class="row my-2">
<div class="col-md-12">
<div class="col-12" aria-live="polite">
{{ 'i18n_student_exam_search_result' | translate }} {{ exams.length }}
{{ 'i18n_student_exam_search_result_continues' | translate }}
<b>"{{ filter.text }}"</b>
</div>
</div>
}
Expand Down Expand Up @@ -116,6 +114,7 @@ export class ExamSearchComponent implements OnInit, OnDestroy {
ngUnsubscribe = new Subject();
filter = { text: '' };
permissionCheck = { active: false };
searchDone = false;

constructor(
private toast: ToastrService,
Expand Down Expand Up @@ -163,6 +162,7 @@ export class ExamSearchComponent implements OnInit, OnDestroy {
});
this.exams = exams;
this.checkEnrolment();
this.searchDone = true;
},
error: (err) => this.toast.error(err),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class CollaborativeExamListingComponent implements OnInit, OnDestroy {
distinctUntilChanged(),
switchMap((text) => this.CollaborativeExam.searchExams$(text)),
tap(() => (this.loader.loading = true)),
map((exams) => this.returnListedCollaborativeExams(exams)),
map((exams) => this.searchExams(exams)),
tap((exams) => (this.exams = exams)),
tap(() => (this.loader.loading = false)),
takeUntil(this.ngUnsubscribe),
Expand All @@ -120,20 +120,6 @@ export class CollaborativeExamListingComponent implements OnInit, OnDestroy {

listAllExams = () => this.filterChanged.next('');

returnListedCollaborativeExams(exams: CollaborativeExam[]): ListedCollaborativeExam[] {
const listedExams: ListedCollaborativeExam[] = exams
.map((e) => {
const ownerAggregate = e.examOwners.map((o) => o.email).join();
const stateTranslation = this.getStateTranslation(e);
const listingView = this.determineListingView(e);

return { ...e, ownerAggregate, stateTranslation, listingView };
})
.filter((e) => e.listingView !== ListingView.OTHER);

return listedExams;
}

determineListingView(exam: CollaborativeExam) {
if (
(exam.state === CollaborativeExamState.PUBLISHED || exam.state === CollaborativeExamState.PRE_PUBLISHED) &&
Expand Down Expand Up @@ -181,4 +167,15 @@ export class CollaborativeExamListingComponent implements OnInit, OnDestroy {
const e = event.target as HTMLInputElement;
return this.filterChanged.next(e.value);
};

private searchExams = (exams: CollaborativeExam[]): ListedCollaborativeExam[] =>
exams
.map((e) => {
const ownerAggregate = e.examOwners.map((o) => o.email).join();
const stateTranslation = this.getStateTranslation(e);
const listingView = this.determineListingView(e);

return { ...e, ownerAggregate, stateTranslation, listingView };
})
.filter((e) => e.listingView !== ListingView.OTHER);
}
26 changes: 12 additions & 14 deletions ui/src/app/shared/select/dropdown-select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,19 @@ export interface Option<V, I> {
</button>
<div ngbDropdownMenu class="xm-scrollable-menu" role="menu" aria-labelledby="dd1">
@if (!noSearch) {
<button ngbDropdownItem>
<div class="input-group">
<input
[(ngModel)]="searchFilter"
class="form-control"
(input)="filterOptions()"
placeholder="{{ placeholder | translate }}"
/>
<div class="input-group-append">
<span class="input-group-text">
<i class="bi-search"></i>
</span>
</div>
<div class="input-group" ngbDropdownItem>
<input
[(ngModel)]="searchFilter"
class="form-control"
(input)="filterOptions()"
placeholder="{{ placeholder | translate }}"
/>
<div class="input-group-append">
<span class="input-group-text">
<i class="bi-search"></i>
</span>
</div>
</button>
</div>
}
<button ngbDropdownItem (click)="clearSelection(); d.close()">
<i class="bi-x text text-danger"></i>
Expand Down
4 changes: 2 additions & 2 deletions ui/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,8 @@
"i18n_print_attachment": "Download the attachment of the exam for printing",
"i18n_print_attachment_reminder": "There is an attachment in the exam. Please remember to print it",
"i18n_examination_date_missing": "Examination dates haven´t been set",
"i18n_student_exam_search_result": "Results for exam search",
"i18n_student_exam_search_result_continues": "exams",
"i18n_student_exam_search_result": "Search found",
"i18n_student_exam_search_result_continues": "results",
"i18n_printout_exams": "Printed exams",
"i18n_exam_new_question": "Add new question",
"i18n_exam_library_new_question": "Add new question to question bank",
Expand Down
Loading

0 comments on commit dff4e4a

Please sign in to comment.