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-1211 More information to library search dropdowns #1023

Merged
merged 2 commits into from
Dec 21, 2023
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
4 changes: 3 additions & 1 deletion app/controllers/ExamController.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ public Result listExams(
List<Long> courses = courseIds.orElse(Collections.emptyList());
List<Long> sections = sectionIds.orElse(Collections.emptyList());
List<Long> tags = tagIds.orElse(Collections.emptyList());
PathProperties pp = PathProperties.parse("(id, name, course(id, code), examSections(id, name))");
PathProperties pp = PathProperties.parse(
"(id, name, examActiveStartDate, examActiveEndDate, course(id, code), examSections(id, name))"
);
Query<Exam> query = DB.find(Exam.class);
pp.apply(query);
ExpressionList<Exam> el = query.where().isNotNull("name").isNotNull("course").isNull("parent");
Expand Down
12 changes: 12 additions & 0 deletions ui/src/app/question/library/library.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ import { LibraryTagsDialogComponent } from './tags/library-tags-dialog.component
<div class="row ms-4 mt-2">
<div class="col-12">
<strong>{{ 'sitnet_search' | translate }}:</strong>
<span
ngbPopover="{{ 'sitnet_library_search_instructions' | translate }}"
popoverTitle="{{ 'sitnet_instructions' | translate }}"
triggers="mouseenter:mouseleave"
class="ms-2"
>
<img
src="/assets/images/icon_tooltip.svg"
alt=""
onerror="this.onerror=null;this.src='/assets/images/icon_tooltip.png';"
/>
</span>
</div>
</div>
<xm-library-search (updated)="resultsUpdated($event)"></xm-library-search>
Expand Down
21 changes: 10 additions & 11 deletions ui/src/app/question/library/search/library-search.component.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
<div class="row ms-3 me-3" *ngIf="user.isAdmin">
<div class="col-md-12 ms-1">
{{ 'sitnet_choose_atleast_one' | translate }}
</div>
</div>
<div class="row ms-3 me-3 align-items-center">
<div class="col-md-4">
<div class="col-md-6">
<span class="m-1" ngbDropdown [autoClose]="'outside'">
<button
class="btn btn-outline-secondary btn-sm"
Expand All @@ -22,7 +17,7 @@
[(ngModel)]="limitations.course"
(ngModelChange)="filterCourses()"
class="form-control"
placeholder="{{ 'sitnet_search' | translate }}"
placeholder="{{ 'sitnet_search_course_hint' | translate }}"
aria-describedby="search-icon-1"
/>
<div class="input-group-append">
Expand All @@ -38,7 +33,7 @@
(click)="applyFilter(course)"
ngbDropdownItem
>
<a role="menuitem">{{ course.name }}</a>
<a role="menuitem">{{ formatCourse(course) }} {{ course.name }}</a>
</li>
</ul>
</span>
Expand All @@ -58,7 +53,7 @@
[(ngModel)]="limitations.exam"
(ngModelChange)="filterExams()"
class="form-control"
placeholder="{{ 'sitnet_search' | translate }}"
placeholder="{{ 'sitnet_search_exam_hint' | translate }}"
aria-describedby="search-icon-2"
/>
<div class="input-group-append">
Expand All @@ -74,7 +69,10 @@
(click)="applyFilter(exam)"
ngbDropdownItem
>
<a role="menuitem">{{ exam.name }}</a>
<a role="menuitem"
>{{ formatCourse(exam) }} {{ exam.name }}
<small *ngIf="exam.period" class="text-muted">({{ exam.period }})</small></a
>
</li>
</ul>
</span>
Expand Down Expand Up @@ -163,8 +161,9 @@
</li>
</ul>
</span>
<span class="ms-2 text-muted" *ngIf="user.isAdmin">{{ 'sitnet_choose_atleast_one' | translate }}</span>
</div>
<div class="col-md-8">
<div class="col-md-6">
<div class="row">
<div [ngClass]="user.isAdmin ? 'col-md-6' : 'col-md-12'">
<form>
Expand Down
42 changes: 30 additions & 12 deletions ui/src/app/question/library/search/library-search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
*/
import type { OnInit } from '@angular/core';
import { Component, EventEmitter, Output } from '@angular/core';
import { DateTime } from 'luxon';
import type { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { CourseCodeService } from 'src/app/shared/miscellaneous/course-code.service';
import type { Course, Exam, ExamSection, Tag } from '../../../exam/exam.model';
import type { User } from '../../../session/session.service';
import { SessionService } from '../../../session/session.service';
Expand All @@ -27,7 +29,9 @@ interface Filterable<T> {
filtered: boolean;
object: T;
name: string;
code?: string;
usage?: number;
period?: string;
}

@Component({
Expand All @@ -50,7 +54,11 @@ export class LibrarySearchComponent implements OnInit {
filteredTags = this.tags;
questions: LibraryQuestion[] = [];

constructor(private Library: LibraryService, private Session: SessionService) {
constructor(
private Library: LibraryService,
private Session: SessionService,
private CourseCode: CourseCodeService,
) {
this.user = this.Session.getUser();
}

Expand All @@ -63,15 +71,15 @@ export class LibrarySearchComponent implements OnInit {
this.tags = this.filteredTags = storedData.filters.tags || [];
this.filter.text = storedData.filters.text;
this.filter.owner = storedData.filters.owner;
this.query().subscribe((questions) => {
this.query$().subscribe((questions) => {
if (this.filter.text || this.filter.owner) {
this.applySearchFilter();
} else {
this.updated.emit(questions);
}
});
} else {
this.query().subscribe((resp) => this.updated.emit(resp));
this.query$().subscribe((resp) => this.updated.emit(resp));
}
}

Expand All @@ -92,6 +100,7 @@ export class LibrarySearchComponent implements OnInit {
resp.map((r) => ({
id: r.id,
name: r.name,
code: r.code,
object: r,
filtered: false,
})),
Expand All @@ -112,6 +121,8 @@ export class LibrarySearchComponent implements OnInit {
name: r.name || '',
object: r,
filtered: false,
code: r.course?.code,
period: this.formatPeriod(r.examActiveStartDate, r.examActiveEndDate),
})),
);
}),
Expand Down Expand Up @@ -164,33 +175,40 @@ export class LibrarySearchComponent implements OnInit {

applyFilter = (f: Filterable<unknown>) => {
f.filtered = !f.filtered;
this.query().subscribe(() => this.applySearchFilter());
this.query$().subscribe(() => this.applySearchFilter());
};

filterCourses = () => {
this.filteredCourses = this.courses.filter(
(c) => c.name.toLowerCase().indexOf(this.limitations.course.toLowerCase()) > -1,
(c) =>
c.name.toLowerCase().includes(this.limitations.course.toLowerCase()) ||
(c.code && c.code.toLowerCase().includes(this.limitations.course.toLowerCase())),
);
};

filterExams = () => {
this.filteredExams = this.exams.filter(
(e) => e.name.toLowerCase().indexOf(this.limitations.exam.toLowerCase()) > -1,
(e) =>
e.name.toLowerCase().includes(this.limitations.exam.toLowerCase()) ||
(e.code && e.code.toLowerCase().includes(this.limitations.exam.toLowerCase())),
);
};

filterSections = () => {
this.filteredSections = this.sections.filter(
(s) => s.name.toLowerCase().indexOf(this.limitations.section.toLowerCase()) > -1,
this.filteredSections = this.sections.filter((s) =>
s.name.toLowerCase().includes(this.limitations.section.toLowerCase()),
);
};

filterTags = () => {
this.filteredTags = this.tags.filter(
(t) => t.name.toLowerCase().indexOf(this.limitations.tag.toLowerCase()) > -1,
);
this.filteredTags = this.tags.filter((t) => t.name.toLowerCase().includes(this.limitations.tag.toLowerCase()));
};

formatCourse = (f: Filterable<Course | Exam>) => (f.code ? this.CourseCode.formatCode(f.code) : '');

formatPeriod = (s: string | null, e: string | null) =>
s && e ? `${DateTime.fromISO(s).toFormat('dd.LL.yyyy')}-${DateTime.fromISO(e).toFormat('dd.LL.yyyy')}` : '';

private saveFilters = () => {
const filters = {
courses: this.courses,
Expand All @@ -213,7 +231,7 @@ export class LibrarySearchComponent implements OnInit {
return filtered.concat(tags.filter((t) => filteredIds.indexOf(t.id) === -1));
}

private query = (): Observable<LibraryQuestion[]> =>
private query$ = (): Observable<LibraryQuestion[]> =>
this.Library.search(this.getCourseIds(), this.getExamIds(), this.getSectionIds(), this.getTagIds()).pipe(
tap((questions) => {
this.questions = questions;
Expand Down
8 changes: 2 additions & 6 deletions ui/src/app/shared/miscellaneous/course-code.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, Inject, Input } from '@angular/core';
import { SESSION_STORAGE, WebStorageService } from 'ngx-webstorage-service';
import { Component, Input } from '@angular/core';
import type { Course } from '../../exam/exam.model';
import { CourseCodeService } from './course-code.service';

Expand All @@ -9,10 +8,7 @@ import { CourseCodeService } from './course-code.service';
})
export class CourseCodeComponent {
@Input() course!: Course;
constructor(
@Inject(SESSION_STORAGE) private webStorageService: WebStorageService,
private CodeService: CourseCodeService,
) {}
constructor(private CodeService: CourseCodeService) {}

formatCode = () => this.CodeService.formatCode(this.course.code);
}
3 changes: 3 additions & 0 deletions ui/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,9 @@
"sitnet_examination_logout_title": "Examination logout",
"sitnet_tag_questions": "Lisää kysymyksille avainsanoja EN",
"sitnet_actions": "Toimenpiteet EN",
"sitnet_search_course_hint": "Hae opintojakson koodilla tai nimellä EN",
"sitnet_search_exam_hint": "Hae opintojakson koodilla tai tentin nimellä EN",
"sitnet_library_search_instructions": "Ohjeet kysymyspankin haun toiminnalle EN",
"sitnet_go_back": "Back",
"sitnet_preview_question": "Question Preview",
"sitnet_button_preview": "Preview question",
Expand Down
3 changes: 3 additions & 0 deletions ui/src/assets/i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,9 @@
"sitnet_examination_logout_title": "Tentin uloskirjautuminen",
"sitnet_tag_questions": "Lisää kysymyksille avainsanoja",
"sitnet_actions": "Toimenpiteet",
"sitnet_search_course_hint": "Hae opintojakson koodilla tai nimellä",
"sitnet_search_exam_hint": "Hae opintojakson koodilla tai tentin nimellä",
"sitnet_library_search_instructions": "Ohjeet kysymyspankin haun toiminnalle TBD",
"sitnet_go_back": "Takaisin",
"sitnet_preview_question": "Kysymyksen esikatselu",
"sitnet_button_preview": "Esikatsele kysymys",
Expand Down
3 changes: 3 additions & 0 deletions ui/src/assets/i18n/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,9 @@
"sitnet_examination_logout_title": "Utloggning",
"sitnet_tag_questions": "Lisää kysymyksille avainsanoja SV",
"sitnet_actions": "Toimenpiteet SV",
"sitnet_search_course_hint": "Hae opintojakson koodilla tai nimellä SV",
"sitnet_search_exam_hint": "Hae opintojakson koodilla tai tentin nimellä SV",
"sitnet_library_search_instructions": "Ohjeet kysymyspankin haun toiminnalle EN",
"sitnet_go_back": "Back SV",
"sitnet_preview_question": "Question Preview SV",
"sitnet_button_preview": "Preview question SV",
Expand Down
Loading