diff --git a/FrontEnd/package.json b/FrontEnd/package.json index 260fa5f..f701bf9 100644 --- a/FrontEnd/package.json +++ b/FrontEnd/package.json @@ -41,6 +41,7 @@ "popper.js": "^1.12.9", "primeicons": "^1.0.0", "primeng": "^6.1.7", + "ngx-csv": "^0.3.1", "rxjs": "^5.5.2", "zone.js": "^0.8.14" }, diff --git a/FrontEnd/src/app/app-routing.module.ts b/FrontEnd/src/app/app-routing.module.ts index b9a7e19..0b1ce1e 100644 --- a/FrontEnd/src/app/app-routing.module.ts +++ b/FrontEnd/src/app/app-routing.module.ts @@ -46,6 +46,7 @@ import { BagdesComponent } from './user/bagdes/bagdes.component'; import { RankingComponent } from './groups/ranking/ranking.component'; import { HistoryOfActivityInGroupComponent } from './groups/history-of-activity-in-group/history-of-activity-in-group.component'; import { LoginUsosComponent } from './login/login-usos/login-usos.component'; +import { TestsInGroupResultsComponent } from './groups/tests-in-group-results/tests-in-group-results.component'; const routes: Routes = [ @@ -87,7 +88,8 @@ const routes: Routes = [ { path: 'groups/ranking/:id', component: RankingComponent , canActivate: [AuthGuard] }, { path: 'groups/waiting-resources/:id', component: WaitingResourcesComponent, canActivate: [AuthGuard] }, { path: 'groups/waiting-resources/:id', component: WaitingResourcesComponent, canActivate: [AuthGuard] }, - { path: 'groups/history/:id', component: HistoryOfActivityInGroupComponent, canActivate: [AuthGuard] } + { path: 'groups/history/:id', component: HistoryOfActivityInGroupComponent, canActivate: [AuthGuard] }, + { path: 'groups/tests-results/:id', component: TestsInGroupResultsComponent, canActivate: [AuthGuard] } ]; @NgModule({ diff --git a/FrontEnd/src/app/authentication.service.ts b/FrontEnd/src/app/authentication.service.ts index 37215ee..5dd3e25 100644 --- a/FrontEnd/src/app/authentication.service.ts +++ b/FrontEnd/src/app/authentication.service.ts @@ -7,6 +7,7 @@ import 'rxjs/add/observable/throw'; import { MatSnackBar } from '@angular/material/snack-bar'; import { Subject } from 'rxjs/Subject'; import { USOSUrl, LoginKey } from './login'; +import { environment } from './../environments/environment'; @Injectable() export class AuthenticationService { @@ -68,7 +69,7 @@ export class AuthenticationService { } getUSOSTokens(): Observable { - return this.http.get(encodeURI('usos/request_token?oauth_callback=http://localhost:4200/login/usos')); + return this.http.get(encodeURI(`usos/request_token?oauth_callback=${environment.frontend}login/usos`)); } getToken(): String { diff --git a/FrontEnd/src/app/footer/footer.component.html b/FrontEnd/src/app/footer/footer.component.html index a92880e..1133d47 100644 --- a/FrontEnd/src/app/footer/footer.component.html +++ b/FrontEnd/src/app/footer/footer.component.html @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/FrontEnd/src/app/groups/group-details/group-details.component.html b/FrontEnd/src/app/groups/group-details/group-details.component.html index 9881f36..77fff7f 100644 --- a/FrontEnd/src/app/groups/group-details/group-details.component.html +++ b/FrontEnd/src/app/groups/group-details/group-details.component.html @@ -6,6 +6,9 @@ + +

diff --git a/FrontEnd/src/app/groups/group-details/group-details.component.ts b/FrontEnd/src/app/groups/group-details/group-details.component.ts index 0670d8a..2bf54a4 100644 --- a/FrontEnd/src/app/groups/group-details/group-details.component.ts +++ b/FrontEnd/src/app/groups/group-details/group-details.component.ts @@ -249,6 +249,10 @@ export class GroupDetailsComponent implements OnInit, OnDestroy { this.router.navigate(['groups/ranking', this.id]); } + goToTestsResults() { + this.router.navigate(['groups/tests-results', this.id]); + } + goToHistory() { this.router.navigate(['groups/history', this.id]); } diff --git a/FrontEnd/src/app/groups/group.ts b/FrontEnd/src/app/groups/group.ts index f9a5516..fc4290e 100644 --- a/FrontEnd/src/app/groups/group.ts +++ b/FrontEnd/src/app/groups/group.ts @@ -30,3 +30,20 @@ export class ActivityHistory { constructor() {} } + +export class TestsInGroup { + public id: number; + public title: string; + public maxScore: number; + + constructor() {} +} + +export class TestsInGroupResults { + public name: string; + public surname: string; + public userScore: number; + public percent: number; + + constructor() {} +} diff --git a/FrontEnd/src/app/groups/groups.module.ts b/FrontEnd/src/app/groups/groups.module.ts index 9a2d1b5..9657517 100644 --- a/FrontEnd/src/app/groups/groups.module.ts +++ b/FrontEnd/src/app/groups/groups.module.ts @@ -30,6 +30,7 @@ import { MaterialToGroupPreviewComponent } from './waiting-resources/material-to import { FlashcardsToGroupPreviewComponent } from './waiting-resources/flashcards-to-group-preview/flashcards-to-group-preview.component'; import { RankingComponent } from './ranking/ranking.component'; import { HistoryOfActivityInGroupComponent } from './history-of-activity-in-group/history-of-activity-in-group.component'; +import { TestsInGroupResultsComponent } from './tests-in-group-results/tests-in-group-results.component'; @NgModule({ @@ -63,7 +64,8 @@ import { HistoryOfActivityInGroupComponent } from './history-of-activity-in-grou MaterialToGroupPreviewComponent, FlashcardsToGroupPreviewComponent, RankingComponent, - HistoryOfActivityInGroupComponent + HistoryOfActivityInGroupComponent, + TestsInGroupResultsComponent ], providers: [GroupsService, ConfirmationService] diff --git a/FrontEnd/src/app/groups/groups.service.ts b/FrontEnd/src/app/groups/groups.service.ts index 33a1a4a..97a9b78 100644 --- a/FrontEnd/src/app/groups/groups.service.ts +++ b/FrontEnd/src/app/groups/groups.service.ts @@ -28,6 +28,9 @@ export class GroupsService { private getActivityHistoryURL = 'groups/{groupId}/users/activity?sort={sort}'; + private getTestsInGroupsURL = 'groups/{groupId}/tests'; + private getResultsInTestsURL = 'groups/{groupId}/tests/{testId}/results'; + constructor(private httpClient: HttpClient, private authenticationService: AuthenticationService) { this.setHeaders(); } @@ -45,6 +48,18 @@ export class GroupsService { } } + getTestsInGroups(groupId: number): Observable { + this.setHeaders(); + const url = this.getTestsInGroupsURL.replace('{groupId}', groupId.toString()); + return this.httpClient.get(url, { headers: this.headers }); + } + + getResultsInTests(groupId: number, testId: number): Observable { + this.setHeaders(); + const url = this.getResultsInTestsURL.replace('{groupId}', groupId.toString()).replace('{testId}', testId.toString()); + return this.httpClient.get(url, { headers: this.headers }); + } + getGroups(): Observable { this.setHeaders(); const url = this.getGroupsURL; diff --git a/FrontEnd/src/app/groups/ranking/ranking.component.html b/FrontEnd/src/app/groups/ranking/ranking.component.html index 76b7ff6..d4432b2 100644 --- a/FrontEnd/src/app/groups/ranking/ranking.component.html +++ b/FrontEnd/src/app/groups/ranking/ranking.component.html @@ -15,6 +15,12 @@ Ranking testów +
+
+ +
+
+
{ + this.rankingSubscription = this.groupService.getGlobalRanking(this.id).subscribe(data => { this.data = data.sort((a, b) => { if (a.points > b.points) { return -1; @@ -143,7 +149,7 @@ export class RankingComponent implements OnInit, OnDestroy { showOnlyTestsRanking(): void { this.typeOfRankingToDisplay = RankingType.test; - this.rankingSubscription = this.groupService.getTestsRanking(this.group.id).subscribe(data => { + this.rankingSubscription = this.groupService.getTestsRanking(this.id).subscribe(data => { this.data = data.sort((a, b) => { if (a.points > b.points) { return -1; diff --git a/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.css b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.css new file mode 100644 index 0000000..722b21b --- /dev/null +++ b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.css @@ -0,0 +1,24 @@ +.wrapper{ + width: 100%; + padding: 30px; + min-height: 100%; + margin-bottom: 40px; +} + +.content{ + background-color: #181616; + padding: 30px; + margin-top: 2rem; + margin-bottom: 2rem; + text-align: center; + margin-left: auto; + margin-right: auto; +} + +ag-grid-angular{ + margin: 10px; +} + +.buttons-container > div{ + margin: 10px; +} diff --git a/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.html b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.html new file mode 100644 index 0000000..11ee87a --- /dev/null +++ b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.html @@ -0,0 +1,28 @@ +
+
+

{{group?.name}}

+
+
+

Wybierz test aby zobaczyć wyniki:

+
+ + +
+

+
+

Wybrany test: {{selectedTest.title}}

+
+ +
+
+ + +
+
+
\ No newline at end of file diff --git a/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.spec.ts b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.spec.ts new file mode 100644 index 0000000..565ba78 --- /dev/null +++ b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TestsInGroupResultsComponent } from './tests-in-group-results.component'; + +describe('TestsInGroupResultsComponent', () => { + let component: TestsInGroupResultsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TestsInGroupResultsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestsInGroupResultsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.ts b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.ts new file mode 100644 index 0000000..4fd37a1 --- /dev/null +++ b/FrontEnd/src/app/groups/tests-in-group-results/tests-in-group-results.component.ts @@ -0,0 +1,188 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { GroupsService } from '../groups.service'; +import { Group, TestsInGroup, TestsInGroupResults } from '../group'; +import { Subscription } from 'rxjs/Subscription'; +import localeText from './../../../assets/localeText'; +import { GridOptions, RowDoubleClickedEvent } from 'ag-grid-community/main'; +import { MatSnackBar } from '@angular/material'; +import { ngxCsv } from 'ngx-csv/ngx-csv'; + + +@Component({ + selector: 'app-tests-in-group-results', + templateUrl: './tests-in-group-results.component.html', + styleUrls: ['./tests-in-group-results.component.css'] +}) +export class TestsInGroupResultsComponent implements OnInit, OnDestroy { + + id: number; + currentUser; + subs: Subscription[] = []; + public group: Group; + public selectedTest: TestsInGroup; + + public localeText = localeText; + + // chooseTests + public data: TestsInGroup[] = []; + public gridApi; + public gridOptions: GridOptions; + public columnDefs = [ + { headerName: 'ID', field: 'id', headerTooltip: 'ID' }, + { headerName: 'Nazwa', field: 'title', headerTooltip: 'Nazwa' }, + { headerName: 'Liczba punktów do zdobycia', field: 'maxScore', headerTooltip: 'Liczba punktów do zdobycia', hide: false } + ]; + + // showTestResult + public testdata: TestsInGroupResults[] = []; + public testgridApi; + public testgridOptions: GridOptions; + public testcolumnDefs = [ + { headerName: 'Imię', field: 'name', headerTooltip: 'Imię' }, + { headerName: 'Nazwisko', field: 'surname', headerTooltip: 'Nazwisko' }, + { headerName: 'Wynik', field: 'userScore', headerTooltip: 'Wynik', hide: false }, + { headerName: 'Wynik (%)', field: 'percent', headerTooltip: 'Wynik (%)', hide: false } + ]; + + constructor(private route: ActivatedRoute, + private groupService: GroupsService, + public snackBar: MatSnackBar) { } + + ngOnInit() { + this.id = this.route.snapshot.params.id; + this.currentUser = JSON.parse(localStorage.getItem('currentUser')); + this.subs.push( + this.groupService.getGroupDetails(this.id) + .subscribe( + data => { + this.group = data; + this.getTests(); + localStorage.setItem('groupOwnerUsername', this.group.owner); + } + ) + ); + + this.gridOptions = { + rowHeight: 50, + headerHeight: 25, + getRowStyle: function (params) { + return { + cursor: 'pointer' + }; + }, + }; + + this.testgridOptions = { + rowHeight: 50, + headerHeight: 25, + getRowStyle: function (params) { + return { + cursor: 'pointer' + }; + }, + }; + } + + getTests() { + this.subs.push(this.groupService.getTestsInGroups(this.id).subscribe( + success => { + this.data = success; + }, + error => { + console.log(error); + this.snackBar.open('Nie udało się załadować listy testów!', null, + { duration: 3000, verticalPosition: 'top', panelClass: ['snackbar-error'] }); + } + )); + } + + goTo(event: RowDoubleClickedEvent) { + this.selectedTest = event.data; + this.getResults(event.data.id); + } + + downloadCSVResults() { + // tslint:disable-next-line:no-unused-expression + new ngxCsv(this.testdata, this.group.name + '_' + this.selectedTest.title + '_wyniki'); + } + + getResults(id: number) { + this.subs.push(this.groupService.getResultsInTests(this.id, id).subscribe( + success => { + this.testdata = success; + }, + error => { + console.log(error); + this.snackBar.open('Nie udało się załadować wyników za test!', null, + { duration: 3000, verticalPosition: 'top', panelClass: ['snackbar-error'] }); + } + )); + } + + ngOnDestroy() { + if (this.subs) { + this.subs.forEach(x => x.unsubscribe()); + } + + localStorage.removeItem('groupOwnerUsername'); + } + + // chooseTests + public onRowClicked(e) { + if (e.event.target !== undefined) { + this.goTo(e); + } + } + + onGridReady(params) { + this.gridApi = params.api; + this.gridApi.sizeColumnsToFit(); + } + + onGridColumnsChanged(params) { + params.api.sizeColumnsToFit(); + } + + onGridSizeChanged(params) { + this.columnDefs = [ + { headerName: 'ID', field: 'id', headerTooltip: 'ID' }, + { headerName: 'Nazwa', field: 'title', headerTooltip: 'Nazwa' }, + { headerName: 'Liczba punktów do zdobycia', field: 'maxScore', headerTooltip: 'Liczba punktów do zdobycia', hide: false } + ]; + + params.api.sizeColumnsToFit(); + } + + onGidColumnsChanged(params) { + params.api.sizeColumnsToFit(); + } + + // showTestResult + public testonRowClicked(e) {} + + testonGridReady(params) { + this.testgridApi = params.api; + this.testgridApi.sizeColumnsToFit(); + } + + testonGridColumnsChanged(params) { + params.api.sizeColumnsToFit(); + } + + testonGridSizeChanged(params) { + this.testcolumnDefs = [ + { headerName: 'Imię', field: 'name', headerTooltip: 'Imię' }, + { headerName: 'Nazwisko', field: 'surname', headerTooltip: 'Nazwisko' }, + { headerName: 'Wynik', field: 'userScore', headerTooltip: 'Wynik', hide: false }, + { headerName: 'Wynik (%)', field: 'percent', headerTooltip: 'Wynik (%)', hide: false } + ]; + + params.api.sizeColumnsToFit(); + } + + testonGidColumnsChanged(params) { + params.api.sizeColumnsToFit(); + } + +} diff --git a/FrontEnd/src/app/groups/waiting-resources/material-to-group-preview/material-to-group-preview.component.ts b/FrontEnd/src/app/groups/waiting-resources/material-to-group-preview/material-to-group-preview.component.ts index 1e9ccd4..dc3dcfc 100644 --- a/FrontEnd/src/app/groups/waiting-resources/material-to-group-preview/material-to-group-preview.component.ts +++ b/FrontEnd/src/app/groups/waiting-resources/material-to-group-preview/material-to-group-preview.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit, Input } from '@angular/core'; +import { environment } from './../../../../environments/environment'; @Component({ selector: 'app-material-to-group-preview', @@ -11,7 +12,7 @@ export class MaterialToGroupPreviewComponent implements OnInit { @Input() public title: string; // public serverURL = 'http://studycave.eu-west-1.elasticbeanstalk.com/file/files/'; // działa na globalu - public serverURL = 'http://localhost:8080/file/files/' ; // działa na localhost + public serverURL = `${environment.api}file/files/` ; // działa na localhost constructor() {} diff --git a/FrontEnd/src/app/http-interceptors/api-interceptor.ts b/FrontEnd/src/app/http-interceptors/api-interceptor.ts index d4cbfdd..89fa7d6 100644 --- a/FrontEnd/src/app/http-interceptors/api-interceptor.ts +++ b/FrontEnd/src/app/http-interceptors/api-interceptor.ts @@ -1,11 +1,12 @@ import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; +import { environment } from './../../environments/environment'; @Injectable() export class ApiInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable> { - const apiReq = req.clone({ url: `http://localhost:8080/${req.url}` }); + const apiReq = req.clone({ url: `${environment.api}${req.url}` }); return next.handle(apiReq); } } diff --git a/FrontEnd/src/app/materials/materials-details/materials-details.component.ts b/FrontEnd/src/app/materials/materials-details/materials-details.component.ts index 31b14dc..3493d87 100644 --- a/FrontEnd/src/app/materials/materials-details/materials-details.component.ts +++ b/FrontEnd/src/app/materials/materials-details/materials-details.component.ts @@ -4,6 +4,7 @@ import { MaterialsService } from '../materials.service'; import { Subscription } from 'rxjs/Subscription'; import { MatSnackBar } from '@angular/material/snack-bar'; import { RoutingStateService } from '../../routing-state.service'; +import { environment } from './../../../environments/environment'; @Component({ selector: 'app-materials-details', @@ -24,8 +25,9 @@ export class MaterialsDetailsComponent implements OnInit, OnDestroy { perm: string; owned: Boolean = false; display = false; + environment; // serverURL = 'http://studycave.eu-west-1.elasticbeanstalk.com/file/files/'; // działa na globalu - serverURL = 'http://localhost:8080/file/files/' ; // działa na localhost + serverURL = `${environment.api}file/files/` ; // działa na localhost constructor(private route: ActivatedRoute, private materialsService: MaterialsService, private router: Router, private routingState: RoutingStateService, public snackBar: MatSnackBar) { } diff --git a/FrontEnd/src/app/materials/materials-list/materials-list.component.ts b/FrontEnd/src/app/materials/materials-list/materials-list.component.ts index 24755b6..ae901c9 100644 --- a/FrontEnd/src/app/materials/materials-list/materials-list.component.ts +++ b/FrontEnd/src/app/materials/materials-list/materials-list.component.ts @@ -5,6 +5,7 @@ import { MaterialsService } from '../materials.service'; import { GridOptions, RowDoubleClickedEvent } from 'ag-grid-community/main'; import localeText from './localeText'; import { MatSnackBar } from '@angular/material/snack-bar'; +import { environment } from './../../../environments/environment'; @Component({ selector: 'app-materials-list', @@ -31,7 +32,7 @@ export class MaterialsListComponent implements OnInit, OnDestroy { private permission; isGroup = false; // serverURL = 'http://studycave-api.eu-west-1.elasticbeanstalk.com/file/files/' ; // działa na globalu - serverURL = 'http://localhost:8080/file/files/' ; // działa na localhost + serverURL = `${environment.api}file/files/` ; // działa na localhost columnDefs = [ { headerName: 'Nazwa', field: 'title', headerTooltip: 'Nazwa' }, diff --git a/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.html b/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.html index 7489590..c651806 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.html +++ b/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.html @@ -1,6 +1,6 @@
- {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu + {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu
{{item.content}} diff --git a/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.ts b/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.ts index 5947c47..be89f3c 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.ts +++ b/FrontEnd/src/app/tests/test-details/question-view/gaps/gaps.component.ts @@ -11,8 +11,7 @@ import { NgForm } from '@angular/forms'; styleUrls: ['./gaps.component.css'] }) export class GapsComponent implements OnInit, OnDestroy { - @Input() - question; + private _question; @Output() emitNextQuestionRequest = new EventEmitter(); private id; private verifyAnswerSubscription: ISubscription; @@ -48,15 +47,26 @@ export class GapsComponent implements OnInit, OnDestroy { }, 1000); } - ngOnInit() { + public get question() { + return this._question; + } + + @Input('question') + public set question(data) { + this._question = data; + this.ngOnDestroy(); this.timeLeft = this.question.time; if (this.timeLeft > 0) { this.startTimer(); } } + ngOnInit() {} + ngOnDestroy() { - clearInterval(this.interval); + if (this.interval) { + clearInterval(this.interval); + } if (this.verifyAnswerSubscription) { this.verifyAnswerSubscription.unsubscribe(); } diff --git a/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.html b/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.html index 11e3a3b..5c1c327 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.html +++ b/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.html @@ -1,6 +1,6 @@
- {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu + {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu
{{item.content}} diff --git a/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.ts b/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.ts index 4aa31f0..ab14ebb 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.ts +++ b/FrontEnd/src/app/tests/test-details/question-view/multiple-choice/multiple-choice.component.ts @@ -11,8 +11,7 @@ import { NgForm } from '@angular/forms'; styleUrls: ['./multiple-choice.component.css'] }) export class MultipleChoiceComponent implements OnInit, OnDestroy{ - @Input() - question; + private _question; @Output() emitNextQuestionRequest = new EventEmitter(); private id; private verifyAnswerSubscription: ISubscription; @@ -45,15 +44,26 @@ export class MultipleChoiceComponent implements OnInit, OnDestroy{ }, 1000); } - ngOnInit() { + public get question() { + return this._question; + } + + @Input('question') + public set question(data) { + this._question = data; + this.ngOnDestroy(); this.timeLeft = this.question.time; if (this.timeLeft > 0) { this.startTimer(); } } + ngOnInit() {} + ngOnDestroy() { - clearInterval(this.interval); + if (this.interval) { + clearInterval(this.interval); + } if (this.verifyAnswerSubscription) { this.verifyAnswerSubscription.unsubscribe(); } diff --git a/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.html b/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.html index 4e4a31a..3b25b0e 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.html +++ b/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.html @@ -1,5 +1,5 @@
- {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu + {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu

Dostępne lewe strony:

diff --git a/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.ts b/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.ts index 232a03e..dd7b508 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.ts +++ b/FrontEnd/src/app/tests/test-details/question-view/pairs/pairs.component.ts @@ -10,8 +10,7 @@ import { ISubscription } from 'rxjs/Subscription'; styleUrls: ['./pairs.component.css'] }) export class PairsComponent implements OnInit, OnChanges, OnDestroy { - @Input() - question; + private _question; @Output() emitNextQuestionRequest = new EventEmitter(); private id; private verifyAnswerSubscription: ISubscription; @@ -91,7 +90,14 @@ export class PairsComponent implements OnInit, OnChanges, OnDestroy { }); } - ngOnInit() { + public get question() { + return this._question; + } + + @Input('question') + public set question(data) { + this._question = data; + this.ngOnDestroy(); this.timeLeft = this.question.time; this.prepareLists(); if (this.timeLeft > 0) { @@ -99,12 +105,16 @@ export class PairsComponent implements OnInit, OnChanges, OnDestroy { } } + ngOnInit() {} + ngOnChanges() { this.prepareLists(); } ngOnDestroy() { - clearInterval(this.interval); + if (this.interval) { + clearInterval(this.interval); + } if (this.verifyAnswerSubscription) { this.verifyAnswerSubscription.unsubscribe(); } diff --git a/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.html b/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.html index 18a2695..e9b7b67 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.html +++ b/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.html @@ -1,5 +1,5 @@
- {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu + {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu

Dostępne elementy rozsypanki:

diff --git a/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.ts b/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.ts index 0958812..ec8edfc 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.ts +++ b/FrontEnd/src/app/tests/test-details/question-view/puzzle/puzzle.component.ts @@ -10,8 +10,7 @@ import { ISubscription } from 'rxjs/Subscription'; styleUrls: ['./puzzle.component.css'] }) export class PuzzleComponent implements OnInit, OnChanges, OnDestroy { - @Input() - question; + private _question; @Output() emitNextQuestionRequest = new EventEmitter(); private id; private verifyAnswerSubscription: ISubscription; @@ -78,7 +77,14 @@ export class PuzzleComponent implements OnInit, OnChanges, OnDestroy { }); } - ngOnInit() { + public get question() { + return this._question; + } + + @Input('question') + public set question(data) { + this._question = data; + this.ngOnDestroy(); this.timeLeft = this.question.time; this.prepareLists(); if (this.timeLeft > 0) { @@ -86,12 +92,16 @@ export class PuzzleComponent implements OnInit, OnChanges, OnDestroy { } } + ngOnInit() {} + ngOnChanges() { this.prepareLists(); } ngOnDestroy() { - clearInterval(this.interval); + if (this.interval) { + clearInterval(this.interval); + } if (this.verifyAnswerSubscription) { this.verifyAnswerSubscription.unsubscribe(); } diff --git a/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.css b/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.css index 2f54d55..e2d36f6 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.css +++ b/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.css @@ -1,6 +1,70 @@ .answers{ display: flex; flex-direction: column; - align-items: flex-start; + align-items: center; justify-content: flex-start; -} \ No newline at end of file + +} + +.pytanie +{ + background-color: white; + color: black; + width: 50%; + margin-left: auto; + margin-right: auto; + border: 10px solid white; + font-size: larger; + +} + + + + +.radio-answer +{ + display: none; +} + +label +{ + clip-path: polygon(0% 50%, 15% 0%, 85% 0%, 100% 50%, 85% 100%, 15% 100%); + background-color: #000080; + width: 300px; + text-align: center; + border: 3px solid #000080; + border-bottom: #000080; + color: white; + cursor: pointer; + margin-top:10px; + font-size: large; +} + +label:hover +{ + background-color: orange; + border-color: orange; +} + +.radio-answer:checked + label +{ + background-color: orange; + border-color: orange; +} + +@media screen and (max-width: 800px) { + label + { + width: 254px; + } + + .pytanie + { + width: 100%; + } + + .alert-grey + { + background-color: #181616; + } +} diff --git a/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.html b/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.html index ec4810b..4fce135 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.html +++ b/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.html @@ -1,12 +1,15 @@
- {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu + Pytanie za {{question.points}}pkt.
Czas: {{ timeLeft }} sek. Czas: bez limitu +
{{question.question}}
-
- {{item.content}} +
+ + +
- \ No newline at end of file + diff --git a/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.ts b/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.ts index 7af0b8f..32c02a2 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.ts +++ b/FrontEnd/src/app/tests/test-details/question-view/single-choice/single-choice.component.ts @@ -11,8 +11,7 @@ import { NgForm } from '@angular/forms'; styleUrls: ['./single-choice.component.css'] }) export class SingleChoiceComponent implements OnInit, OnDestroy { - @Input() - question; + private _question; private answer; @Output() emitNextQuestionRequest = new EventEmitter(); private id; @@ -46,15 +45,26 @@ export class SingleChoiceComponent implements OnInit, OnDestroy { }, 1000); } - ngOnInit() { + public get question() { + return this._question; + } + + @Input('question') + public set question(data) { + this._question = data; + this.ngOnDestroy(); this.timeLeft = this.question.time; if (this.timeLeft > 0) { this.startTimer(); } } + ngOnInit() {} + ngOnDestroy() { - clearInterval(this.interval); + if (this.interval) { + clearInterval(this.interval); + } if (this.verifyAnswerSubscription) { this.verifyAnswerSubscription.unsubscribe(); } diff --git a/FrontEnd/src/app/tests/test-details/question-view/true-false/true-false.component.html b/FrontEnd/src/app/tests/test-details/question-view/true-false/true-false.component.html index 154392f..05e1631 100644 --- a/FrontEnd/src/app/tests/test-details/question-view/true-false/true-false.component.html +++ b/FrontEnd/src/app/tests/test-details/question-view/true-false/true-false.component.html @@ -1,5 +1,5 @@
- {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu + {{question.question}} ({{question.points}}pkt.)
Czas: {{ timeLeft }} sek. Czas: bez limitu