Merge branch 'master' of https://git.wmi.amu.edu.pl/s416178/Punktonerzy
This commit is contained in:
commit
e38aa097c1
@ -41,6 +41,7 @@
|
|||||||
"popper.js": "^1.12.9",
|
"popper.js": "^1.12.9",
|
||||||
"primeicons": "^1.0.0",
|
"primeicons": "^1.0.0",
|
||||||
"primeng": "^6.1.7",
|
"primeng": "^6.1.7",
|
||||||
|
"ngx-csv": "^0.3.1",
|
||||||
"rxjs": "^5.5.2",
|
"rxjs": "^5.5.2",
|
||||||
"zone.js": "^0.8.14"
|
"zone.js": "^0.8.14"
|
||||||
},
|
},
|
||||||
|
@ -46,6 +46,7 @@ import { BagdesComponent } from './user/bagdes/bagdes.component';
|
|||||||
import { RankingComponent } from './groups/ranking/ranking.component';
|
import { RankingComponent } from './groups/ranking/ranking.component';
|
||||||
import { HistoryOfActivityInGroupComponent } from './groups/history-of-activity-in-group/history-of-activity-in-group.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 { LoginUsosComponent } from './login/login-usos/login-usos.component';
|
||||||
|
import { TestsInGroupResultsComponent } from './groups/tests-in-group-results/tests-in-group-results.component';
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
@ -87,7 +88,8 @@ const routes: Routes = [
|
|||||||
{ path: 'groups/ranking/:id', component: RankingComponent , canActivate: [AuthGuard] },
|
{ 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/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({
|
@NgModule({
|
||||||
|
@ -7,6 +7,7 @@ import 'rxjs/add/observable/throw';
|
|||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
import { USOSUrl, LoginKey } from './login';
|
import { USOSUrl, LoginKey } from './login';
|
||||||
|
import { environment } from './../environments/environment';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthenticationService {
|
export class AuthenticationService {
|
||||||
@ -68,7 +69,7 @@ export class AuthenticationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getUSOSTokens(): Observable<USOSUrl> {
|
getUSOSTokens(): Observable<USOSUrl> {
|
||||||
return this.http.get<USOSUrl>(encodeURI('usos/request_token?oauth_callback=http://localhost:4200/login/usos'));
|
return this.http.get<USOSUrl>(encodeURI(`usos/request_token?oauth_callback=${environment.frontend}login/usos`));
|
||||||
}
|
}
|
||||||
|
|
||||||
getToken(): String {
|
getToken(): String {
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
Regulamin | Polityka Cookies | © 2019 StudyCave
|
© 2019 Punktonerzy
|
||||||
</div>
|
</div>
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
<button class="btn btn-study-cave float-right mr-1" (click)="goToRankings()"><i class="fas fa-trophy"></i>
|
<button class="btn btn-study-cave float-right mr-1" (click)="goToRankings()"><i class="fas fa-trophy"></i>
|
||||||
Rankingi</button>
|
Rankingi</button>
|
||||||
|
|
||||||
|
<button *ngIf="group?.owner===currentUser.username" class="btn btn-study-cave float-right mr-1" (click)="goToTestsResults()"><i class="fas fa-trophy"></i>
|
||||||
|
Wyniki za testy</button>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear: both;"></div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
@ -249,6 +249,10 @@ export class GroupDetailsComponent implements OnInit, OnDestroy {
|
|||||||
this.router.navigate(['groups/ranking', this.id]);
|
this.router.navigate(['groups/ranking', this.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goToTestsResults() {
|
||||||
|
this.router.navigate(['groups/tests-results', this.id]);
|
||||||
|
}
|
||||||
|
|
||||||
goToHistory() {
|
goToHistory() {
|
||||||
this.router.navigate(['groups/history', this.id]);
|
this.router.navigate(['groups/history', this.id]);
|
||||||
}
|
}
|
||||||
|
@ -30,3 +30,20 @@ export class ActivityHistory {
|
|||||||
|
|
||||||
constructor() {}
|
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() {}
|
||||||
|
}
|
||||||
|
@ -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 { FlashcardsToGroupPreviewComponent } from './waiting-resources/flashcards-to-group-preview/flashcards-to-group-preview.component';
|
||||||
import { RankingComponent } from './ranking/ranking.component';
|
import { RankingComponent } from './ranking/ranking.component';
|
||||||
import { HistoryOfActivityInGroupComponent } from './history-of-activity-in-group/history-of-activity-in-group.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({
|
@NgModule({
|
||||||
@ -63,7 +64,8 @@ import { HistoryOfActivityInGroupComponent } from './history-of-activity-in-grou
|
|||||||
MaterialToGroupPreviewComponent,
|
MaterialToGroupPreviewComponent,
|
||||||
FlashcardsToGroupPreviewComponent,
|
FlashcardsToGroupPreviewComponent,
|
||||||
RankingComponent,
|
RankingComponent,
|
||||||
HistoryOfActivityInGroupComponent
|
HistoryOfActivityInGroupComponent,
|
||||||
|
TestsInGroupResultsComponent
|
||||||
|
|
||||||
],
|
],
|
||||||
providers: [GroupsService, ConfirmationService]
|
providers: [GroupsService, ConfirmationService]
|
||||||
|
@ -28,6 +28,9 @@ export class GroupsService {
|
|||||||
|
|
||||||
private getActivityHistoryURL = 'groups/{groupId}/users/activity?sort={sort}';
|
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) {
|
constructor(private httpClient: HttpClient, private authenticationService: AuthenticationService) {
|
||||||
this.setHeaders();
|
this.setHeaders();
|
||||||
}
|
}
|
||||||
@ -45,6 +48,18 @@ export class GroupsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTestsInGroups(groupId: number): Observable<any> {
|
||||||
|
this.setHeaders();
|
||||||
|
const url = this.getTestsInGroupsURL.replace('{groupId}', groupId.toString());
|
||||||
|
return this.httpClient.get(url, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
|
getResultsInTests(groupId: number, testId: number): Observable<any> {
|
||||||
|
this.setHeaders();
|
||||||
|
const url = this.getResultsInTestsURL.replace('{groupId}', groupId.toString()).replace('{testId}', testId.toString());
|
||||||
|
return this.httpClient.get(url, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
getGroups(): Observable<any> {
|
getGroups(): Observable<any> {
|
||||||
this.setHeaders();
|
this.setHeaders();
|
||||||
const url = this.getGroupsURL;
|
const url = this.getGroupsURL;
|
||||||
|
@ -15,6 +15,12 @@
|
|||||||
<input type="radio" name="options" id="option2" autocomplete="off"><i class="fas fa-pencil-ruler"></i> Ranking testów
|
<input type="radio" name="options" id="option2" autocomplete="off"><i class="fas fa-pencil-ruler"></i> Ranking testów
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
<div *ngIf="group">
|
||||||
|
<button class="btn btn-study-cave float-right mr-1" (click)="downloadCSVResults()">Eksportuj ranking do pliku CSV</button>
|
||||||
|
<div style="clear: both;"></div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
<ag-grid-angular style="width: 100%; height: 475px;" class="ag-theme-dark" [rowData]="data" [columnDefs]="columnDefs"
|
<ag-grid-angular style="width: 100%; height: 475px;" class="ag-theme-dark" [rowData]="data" [columnDefs]="columnDefs"
|
||||||
[enableSorting]="true" [enableFilter]="true" (gridReady)="onGridReady($event)" [gridOptions]="gridOptions"
|
[enableSorting]="true" [enableFilter]="true" (gridReady)="onGridReady($event)" [gridOptions]="gridOptions"
|
||||||
[pagination]="true" [paginationAutoPageSize]="true" [localeText]="localeText" (gridColumnsChanged)="onGridColumnsChanged($event)"
|
[pagination]="true" [paginationAutoPageSize]="true" [localeText]="localeText" (gridColumnsChanged)="onGridColumnsChanged($event)"
|
||||||
|
@ -6,6 +6,7 @@ import { Subscription } from 'rxjs/Subscription';
|
|||||||
import { RankingType } from './ranking';
|
import { RankingType } from './ranking';
|
||||||
import { GridOptions } from 'ag-grid-community/main';
|
import { GridOptions } from 'ag-grid-community/main';
|
||||||
import localeText from './../../../assets/localeText';
|
import localeText from './../../../assets/localeText';
|
||||||
|
import { ngxCsv } from 'ngx-csv/ngx-csv';
|
||||||
import * as picasso from 'picasso.js';
|
import * as picasso from 'picasso.js';
|
||||||
picasso.default('canvas');
|
picasso.default('canvas');
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ export class RankingComponent implements OnInit, OnDestroy {
|
|||||||
{ headerName: 'Użytkownik', field: 'username', headerTooltip: 'Użytkownik' },
|
{ headerName: 'Użytkownik', field: 'username', headerTooltip: 'Użytkownik' },
|
||||||
{ headerName: 'Punkty', field: 'points', headerTooltip: 'Punkty' },
|
{ headerName: 'Punkty', field: 'points', headerTooltip: 'Punkty' },
|
||||||
];
|
];
|
||||||
public data;
|
public data = [];
|
||||||
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private groupService: GroupsService, private router: Router) { }
|
constructor(private route: ActivatedRoute, private groupService: GroupsService, private router: Router) { }
|
||||||
@ -58,6 +59,11 @@ export class RankingComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downloadCSVResults() {
|
||||||
|
// tslint:disable-next-line:no-unused-expression
|
||||||
|
new ngxCsv(this.data, this.group.name + '_ranking_' + this.typeOfRankingToDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
if (this.groupDetailsSubscription) {
|
if (this.groupDetailsSubscription) {
|
||||||
this.groupDetailsSubscription.unsubscribe();
|
this.groupDetailsSubscription.unsubscribe();
|
||||||
@ -127,7 +133,7 @@ export class RankingComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
showGlobalRanking(): void {
|
showGlobalRanking(): void {
|
||||||
this.typeOfRankingToDisplay = RankingType.all;
|
this.typeOfRankingToDisplay = RankingType.all;
|
||||||
this.rankingSubscription = this.groupService.getGlobalRanking(this.group.id).subscribe(data => {
|
this.rankingSubscription = this.groupService.getGlobalRanking(this.id).subscribe(data => {
|
||||||
this.data = data.sort((a, b) => {
|
this.data = data.sort((a, b) => {
|
||||||
if (a.points > b.points) {
|
if (a.points > b.points) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -143,7 +149,7 @@ export class RankingComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
showOnlyTestsRanking(): void {
|
showOnlyTestsRanking(): void {
|
||||||
this.typeOfRankingToDisplay = RankingType.test;
|
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) => {
|
this.data = data.sort((a, b) => {
|
||||||
if (a.points > b.points) {
|
if (a.points > b.points) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
<div class="wrapper">
|
||||||
|
<div class="content">
|
||||||
|
<h1>{{group?.name}}</h1>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<h2>Wybierz test aby zobaczyć wyniki:</h2>
|
||||||
|
<br />
|
||||||
|
<ag-grid-angular style="width: 100%; height: 475px;" class="ag-theme-dark" [rowData]="data" [columnDefs]="columnDefs"
|
||||||
|
[enableSorting]="true" [enableFilter]="true" (gridReady)="onGridReady($event)" [gridOptions]="gridOptions"
|
||||||
|
[pagination]="true" [paginationAutoPageSize]="true" [localeText]="localeText" (gridColumnsChanged)="onGridColumnsChanged($event)"
|
||||||
|
(rowClicked)="onRowClicked($event)" (gridSizeChanged)="onGridSizeChanged($event)">
|
||||||
|
</ag-grid-angular>
|
||||||
|
</div>
|
||||||
|
<br /><br />
|
||||||
|
<div *ngIf="selectedTest">
|
||||||
|
<h2>Wybrany test: {{selectedTest.title}}</h2>
|
||||||
|
<br />
|
||||||
|
<button *ngIf="group" class="btn btn-study-cave float-right mr-1" (click)="downloadCSVResults()">Eksportuj wyniki do pliku CSV</button>
|
||||||
|
<div style="clear: both;"></div>
|
||||||
|
<br />
|
||||||
|
<ag-grid-angular style="width: 100%; height: 475px;" class="ag-theme-dark" [rowData]="testdata" [columnDefs]="testcolumnDefs"
|
||||||
|
[enableSorting]="true" [enableFilter]="true" (gridReady)="testonGridReady($event)" [gridOptions]="testgridOptions"
|
||||||
|
[pagination]="true" [paginationAutoPageSize]="true" [localeText]="localeText" (gridColumnsChanged)="testonGridColumnsChanged($event)"
|
||||||
|
(rowClicked)="testonRowClicked($event)" (gridSizeChanged)="testonGridSizeChanged($event)">
|
||||||
|
</ag-grid-angular>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -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<TestsInGroupResultsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ TestsInGroupResultsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TestsInGroupResultsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { environment } from './../../../../environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-material-to-group-preview',
|
selector: 'app-material-to-group-preview',
|
||||||
@ -11,7 +12,7 @@ export class MaterialToGroupPreviewComponent implements OnInit {
|
|||||||
@Input() public title: string;
|
@Input() public title: string;
|
||||||
|
|
||||||
// public serverURL = 'http://studycave.eu-west-1.elasticbeanstalk.com/file/files/'; // działa na globalu
|
// 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() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
|
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { environment } from './../../environments/environment';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApiInterceptor implements HttpInterceptor {
|
export class ApiInterceptor implements HttpInterceptor {
|
||||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
const apiReq = req.clone({ url: `http://localhost:8080/${req.url}` });
|
const apiReq = req.clone({ url: `${environment.api}${req.url}` });
|
||||||
return next.handle(apiReq);
|
return next.handle(apiReq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { MaterialsService } from '../materials.service';
|
|||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { RoutingStateService } from '../../routing-state.service';
|
import { RoutingStateService } from '../../routing-state.service';
|
||||||
|
import { environment } from './../../../environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-materials-details',
|
selector: 'app-materials-details',
|
||||||
@ -24,8 +25,9 @@ export class MaterialsDetailsComponent implements OnInit, OnDestroy {
|
|||||||
perm: string;
|
perm: string;
|
||||||
owned: Boolean = false;
|
owned: Boolean = false;
|
||||||
display = false;
|
display = false;
|
||||||
|
environment;
|
||||||
// serverURL = 'http://studycave.eu-west-1.elasticbeanstalk.com/file/files/'; // działa na globalu
|
// 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,
|
constructor(private route: ActivatedRoute, private materialsService: MaterialsService, private router: Router,
|
||||||
private routingState: RoutingStateService, public snackBar: MatSnackBar) { }
|
private routingState: RoutingStateService, public snackBar: MatSnackBar) { }
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { MaterialsService } from '../materials.service';
|
|||||||
import { GridOptions, RowDoubleClickedEvent } from 'ag-grid-community/main';
|
import { GridOptions, RowDoubleClickedEvent } from 'ag-grid-community/main';
|
||||||
import localeText from './localeText';
|
import localeText from './localeText';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
import { environment } from './../../../environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-materials-list',
|
selector: 'app-materials-list',
|
||||||
@ -31,7 +32,7 @@ export class MaterialsListComponent implements OnInit, OnDestroy {
|
|||||||
private permission;
|
private permission;
|
||||||
isGroup = false;
|
isGroup = false;
|
||||||
// serverURL = 'http://studycave-api.eu-west-1.elasticbeanstalk.com/file/files/' ; // działa na globalu
|
// 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 = [
|
columnDefs = [
|
||||||
{ headerName: 'Nazwa', field: 'title', headerTooltip: 'Nazwa' },
|
{ headerName: 'Nazwa', field: 'title', headerTooltip: 'Nazwa' },
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<form #f="ngForm" (ngSubmit)="nextQuestion(f)" novalidate>
|
<form #f="ngForm" (ngSubmit)="nextQuestion(f)" novalidate>
|
||||||
<div class="alert alert-grey question">
|
<div class="alert alert-grey question">
|
||||||
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="timeLeft === 0">Czas: bez limitu</span>
|
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="question.time === 0">Czas: bez limitu</span>
|
||||||
<div class="answers">
|
<div class="answers">
|
||||||
<div *ngFor="let item of question.answers">
|
<div *ngFor="let item of question.answers">
|
||||||
<span *ngIf="!item.is_gap">{{item.content}}</span>
|
<span *ngIf="!item.is_gap">{{item.content}}</span>
|
||||||
|
@ -11,8 +11,7 @@ import { NgForm } from '@angular/forms';
|
|||||||
styleUrls: ['./gaps.component.css']
|
styleUrls: ['./gaps.component.css']
|
||||||
})
|
})
|
||||||
export class GapsComponent implements OnInit, OnDestroy {
|
export class GapsComponent implements OnInit, OnDestroy {
|
||||||
@Input()
|
private _question;
|
||||||
question;
|
|
||||||
@Output() emitNextQuestionRequest = new EventEmitter();
|
@Output() emitNextQuestionRequest = new EventEmitter();
|
||||||
private id;
|
private id;
|
||||||
private verifyAnswerSubscription: ISubscription;
|
private verifyAnswerSubscription: ISubscription;
|
||||||
@ -48,15 +47,26 @@ export class GapsComponent implements OnInit, OnDestroy {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
public get question() {
|
||||||
|
return this._question;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input('question')
|
||||||
|
public set question(data) {
|
||||||
|
this._question = data;
|
||||||
|
this.ngOnDestroy();
|
||||||
this.timeLeft = this.question.time;
|
this.timeLeft = this.question.time;
|
||||||
if (this.timeLeft > 0) {
|
if (this.timeLeft > 0) {
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
clearInterval(this.interval);
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
if (this.verifyAnswerSubscription) {
|
if (this.verifyAnswerSubscription) {
|
||||||
this.verifyAnswerSubscription.unsubscribe();
|
this.verifyAnswerSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<form #f="ngForm" (ngSubmit)="nextQuestion(f)" novalidate>
|
<form #f="ngForm" (ngSubmit)="nextQuestion(f)" novalidate>
|
||||||
<div class="alert alert-grey question">
|
<div class="alert alert-grey question">
|
||||||
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="timeLeft === 0">Czas: bez limitu</span>
|
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="question.time === 0">Czas: bez limitu</span>
|
||||||
<div class="answers">
|
<div class="answers">
|
||||||
<div *ngFor="let item of question.answers">
|
<div *ngFor="let item of question.answers">
|
||||||
<input type="checkbox" [name]="item.id" [value]="item" ngModel /> {{item.content}}
|
<input type="checkbox" [name]="item.id" [value]="item" ngModel /> {{item.content}}
|
||||||
|
@ -11,8 +11,7 @@ import { NgForm } from '@angular/forms';
|
|||||||
styleUrls: ['./multiple-choice.component.css']
|
styleUrls: ['./multiple-choice.component.css']
|
||||||
})
|
})
|
||||||
export class MultipleChoiceComponent implements OnInit, OnDestroy{
|
export class MultipleChoiceComponent implements OnInit, OnDestroy{
|
||||||
@Input()
|
private _question;
|
||||||
question;
|
|
||||||
@Output() emitNextQuestionRequest = new EventEmitter();
|
@Output() emitNextQuestionRequest = new EventEmitter();
|
||||||
private id;
|
private id;
|
||||||
private verifyAnswerSubscription: ISubscription;
|
private verifyAnswerSubscription: ISubscription;
|
||||||
@ -45,15 +44,26 @@ export class MultipleChoiceComponent implements OnInit, OnDestroy{
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
public get question() {
|
||||||
|
return this._question;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input('question')
|
||||||
|
public set question(data) {
|
||||||
|
this._question = data;
|
||||||
|
this.ngOnDestroy();
|
||||||
this.timeLeft = this.question.time;
|
this.timeLeft = this.question.time;
|
||||||
if (this.timeLeft > 0) {
|
if (this.timeLeft > 0) {
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
clearInterval(this.interval);
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
if (this.verifyAnswerSubscription) {
|
if (this.verifyAnswerSubscription) {
|
||||||
this.verifyAnswerSubscription.unsubscribe();
|
this.verifyAnswerSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div>
|
<div>
|
||||||
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="timeLeft === 0">Czas: bez limitu</span>
|
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="question.time === 0">Czas: bez limitu</span>
|
||||||
<h3>Dostępne lewe strony:</h3>
|
<h3>Dostępne lewe strony:</h3>
|
||||||
<div class="puzzles-container">
|
<div class="puzzles-container">
|
||||||
<div class='puzzle' *ngFor="let item of leftSides; let i = index" (click)="leftSideClick(item,i)" [ngClass]="{'active': (selectedLeftSide.leftSideText === item && selectedLeftSide.indexOfLeftSide === i && selectedLeftSide.from === 'leftSides'), 'empty': (item === undefined || item === '')}">
|
<div class='puzzle' *ngFor="let item of leftSides; let i = index" (click)="leftSideClick(item,i)" [ngClass]="{'active': (selectedLeftSide.leftSideText === item && selectedLeftSide.indexOfLeftSide === i && selectedLeftSide.from === 'leftSides'), 'empty': (item === undefined || item === '')}">
|
||||||
|
@ -10,8 +10,7 @@ import { ISubscription } from 'rxjs/Subscription';
|
|||||||
styleUrls: ['./pairs.component.css']
|
styleUrls: ['./pairs.component.css']
|
||||||
})
|
})
|
||||||
export class PairsComponent implements OnInit, OnChanges, OnDestroy {
|
export class PairsComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input()
|
private _question;
|
||||||
question;
|
|
||||||
@Output() emitNextQuestionRequest = new EventEmitter();
|
@Output() emitNextQuestionRequest = new EventEmitter();
|
||||||
private id;
|
private id;
|
||||||
private verifyAnswerSubscription: ISubscription;
|
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.timeLeft = this.question.time;
|
||||||
this.prepareLists();
|
this.prepareLists();
|
||||||
if (this.timeLeft > 0) {
|
if (this.timeLeft > 0) {
|
||||||
@ -99,12 +105,16 @@ export class PairsComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.prepareLists();
|
this.prepareLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
clearInterval(this.interval);
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
if (this.verifyAnswerSubscription) {
|
if (this.verifyAnswerSubscription) {
|
||||||
this.verifyAnswerSubscription.unsubscribe();
|
this.verifyAnswerSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div>
|
<div>
|
||||||
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="timeLeft === 0">Czas: bez limitu</span>
|
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="question.time === 0">Czas: bez limitu</span>
|
||||||
<h3>Dostępne elementy rozsypanki:</h3>
|
<h3>Dostępne elementy rozsypanki:</h3>
|
||||||
<div class="puzzles-container">
|
<div class="puzzles-container">
|
||||||
<div class='puzzle' *ngFor="let item of puzzles; let i = index" (click)="puzzleClick(item,i)" [ngClass]="{'active': (selectedPuzzle.puzzleText === item && selectedPuzzle.indexOfPuzzle === i && selectedPuzzle.from === 'puzzles'), 'empty': (item === undefined || item === '')}">
|
<div class='puzzle' *ngFor="let item of puzzles; let i = index" (click)="puzzleClick(item,i)" [ngClass]="{'active': (selectedPuzzle.puzzleText === item && selectedPuzzle.indexOfPuzzle === i && selectedPuzzle.from === 'puzzles'), 'empty': (item === undefined || item === '')}">
|
||||||
|
@ -10,8 +10,7 @@ import { ISubscription } from 'rxjs/Subscription';
|
|||||||
styleUrls: ['./puzzle.component.css']
|
styleUrls: ['./puzzle.component.css']
|
||||||
})
|
})
|
||||||
export class PuzzleComponent implements OnInit, OnChanges, OnDestroy {
|
export class PuzzleComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input()
|
private _question;
|
||||||
question;
|
|
||||||
@Output() emitNextQuestionRequest = new EventEmitter();
|
@Output() emitNextQuestionRequest = new EventEmitter();
|
||||||
private id;
|
private id;
|
||||||
private verifyAnswerSubscription: ISubscription;
|
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.timeLeft = this.question.time;
|
||||||
this.prepareLists();
|
this.prepareLists();
|
||||||
if (this.timeLeft > 0) {
|
if (this.timeLeft > 0) {
|
||||||
@ -86,12 +92,16 @@ export class PuzzleComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.prepareLists();
|
this.prepareLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
clearInterval(this.interval);
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
if (this.verifyAnswerSubscription) {
|
if (this.verifyAnswerSubscription) {
|
||||||
this.verifyAnswerSubscription.unsubscribe();
|
this.verifyAnswerSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,70 @@
|
|||||||
.answers{
|
.answers{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
<form #f="ngForm" (ngSubmit)="nextQuestion(f)" novalidate>
|
<form #f="ngForm" (ngSubmit)="nextQuestion(f)" novalidate>
|
||||||
<div class="alert alert-grey question">
|
<div class="alert alert-grey question">
|
||||||
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="timeLeft === 0">Czas: bez limitu</span>
|
Pytanie za {{question.points}}pkt. <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="question.time === 0">Czas: bez limitu</span>
|
||||||
|
<div class="pytanie">{{question.question}} </div>
|
||||||
<div class="answers">
|
<div class="answers">
|
||||||
<div *ngFor="let item of question.answers">
|
<div *ngFor="let item of question.answers" >
|
||||||
<input type="radio" name="answer" [value]="item.content" ngModel> {{item.content}}
|
|
||||||
|
<input type="radio" name="answer" class="radio-answer" id="{{item.content}}" [value]="item.content" ngModel ><label for="{{item.content}}">{{item.content}}</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-study-cave" type="submit"><i class="fas fa-arrow-right"></i> Dalej</button>
|
<button class="btn btn-study-cave" type="submit"><i class="fas fa-arrow-right"></i> Dalej</button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -11,8 +11,7 @@ import { NgForm } from '@angular/forms';
|
|||||||
styleUrls: ['./single-choice.component.css']
|
styleUrls: ['./single-choice.component.css']
|
||||||
})
|
})
|
||||||
export class SingleChoiceComponent implements OnInit, OnDestroy {
|
export class SingleChoiceComponent implements OnInit, OnDestroy {
|
||||||
@Input()
|
private _question;
|
||||||
question;
|
|
||||||
private answer;
|
private answer;
|
||||||
@Output() emitNextQuestionRequest = new EventEmitter();
|
@Output() emitNextQuestionRequest = new EventEmitter();
|
||||||
private id;
|
private id;
|
||||||
@ -46,15 +45,26 @@ export class SingleChoiceComponent implements OnInit, OnDestroy {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
public get question() {
|
||||||
|
return this._question;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input('question')
|
||||||
|
public set question(data) {
|
||||||
|
this._question = data;
|
||||||
|
this.ngOnDestroy();
|
||||||
this.timeLeft = this.question.time;
|
this.timeLeft = this.question.time;
|
||||||
if (this.timeLeft > 0) {
|
if (this.timeLeft > 0) {
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
clearInterval(this.interval);
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
if (this.verifyAnswerSubscription) {
|
if (this.verifyAnswerSubscription) {
|
||||||
this.verifyAnswerSubscription.unsubscribe();
|
this.verifyAnswerSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="alert alert-grey question">
|
<div class="alert alert-grey question">
|
||||||
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="timeLeft === 0">Czas: bez limitu</span>
|
{{question.question}} ({{question.points}}pkt.) <br /><span *ngIf="timeLeft > 0">Czas: {{ timeLeft }} sek. </span><span *ngIf="question.time === 0">Czas: bez limitu</span>
|
||||||
|
|
||||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||||
<label class="btn btn-study-cave mr-2" (click)="chooseAnswer('Prawda')">
|
<label class="btn btn-study-cave mr-2" (click)="chooseAnswer('Prawda')">
|
||||||
|
@ -10,8 +10,7 @@ import { ISubscription, Subscription } from 'rxjs/Subscription';
|
|||||||
styleUrls: ['./true-false.component.css']
|
styleUrls: ['./true-false.component.css']
|
||||||
})
|
})
|
||||||
export class TrueFalseComponent implements OnInit, OnDestroy {
|
export class TrueFalseComponent implements OnInit, OnDestroy {
|
||||||
@Input()
|
private _question;
|
||||||
question;
|
|
||||||
private answer;
|
private answer;
|
||||||
@Output() emitNextQuestionRequest = new EventEmitter();
|
@Output() emitNextQuestionRequest = new EventEmitter();
|
||||||
private id;
|
private id;
|
||||||
@ -49,15 +48,26 @@ export class TrueFalseComponent implements OnInit, OnDestroy {
|
|||||||
this.answer = answer;
|
this.answer = answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
public get question() {
|
||||||
|
return this._question;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input('question')
|
||||||
|
public set question(data) {
|
||||||
|
this._question = data;
|
||||||
|
this.ngOnDestroy();
|
||||||
this.timeLeft = this.question.time;
|
this.timeLeft = this.question.time;
|
||||||
if (this.timeLeft > 0) {
|
if (this.timeLeft > 0) {
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
clearInterval(this.interval);
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
if (this.verifyAnswerSubscription) {
|
if (this.verifyAnswerSubscription) {
|
||||||
this.verifyAnswerSubscription.unsubscribe();
|
this.verifyAnswerSubscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
.content{
|
.content{
|
||||||
background-color: #181616;
|
background-color: #181616;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -39,4 +39,17 @@
|
|||||||
.header{
|
.header{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button
|
||||||
|
{
|
||||||
|
background-color: #000080;
|
||||||
|
border-color: #000080;
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover
|
||||||
|
{
|
||||||
|
background-color: orange;
|
||||||
|
border-color: orange;
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div *ngIf="test">
|
<div *ngIf="test">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button class="btn btn-study-cave" (click)="back()"><i class="fas fa-arrow-left"></i> Powrót</button>
|
<button class="button" (click)="back()"><i class="fas fa-arrow-left"></i> Powrót</button>
|
||||||
<span>
|
<span>
|
||||||
<div *ngIf="currentUser">Twój maksymalny wynik: {{prevMaxResult}}/{{maxPoints}}</div>
|
<div *ngIf="currentUser">Twój maksymalny wynik: {{prevMaxResult}}/{{maxPoints}}</div>
|
||||||
<button title="Usuń" *ngIf="currentUser && currentUser.username === test.owner && (!isStarted || isEnded)" class="btn btn-study-cave" (click)="openPopup()"><i class="fas fa-trash-alt"></i></button>
|
<button title="Usuń" *ngIf="currentUser && currentUser.username === test.owner && (!isStarted || isEnded)" class="btn btn-study-cave" (click)="openPopup()"><i class="fas fa-trash-alt"></i></button>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="!isStarted">
|
<div *ngIf="!isStarted">
|
||||||
<button class="btn btn-study-cave" (click)="start()"> <i class="far fa-play-circle"></i> Rozpocznij test</button>
|
<button class="button" (click)="start()"> <i class="far fa-play-circle"></i> Rozpocznij test</button>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="isStarted && !isEnded">
|
<div *ngIf="isStarted && !isEnded">
|
||||||
|
|
||||||
@ -54,8 +54,8 @@
|
|||||||
<p-dialog header="Potwierdź" [(visible)]="display">
|
<p-dialog header="Potwierdź" [(visible)]="display">
|
||||||
Czy chcesz usunąć test?
|
Czy chcesz usunąć test?
|
||||||
<p-footer>
|
<p-footer>
|
||||||
<button type="button" pButton icon="pi pi-check" (click)="deleteTest()" label="TAK"></button>
|
<button type="button" pButton icon="pi pi-check" (click)="deleteTest()" label="TAK" class="button" ></button>
|
||||||
<button type="button" pButton icon="pi pi-close" (click)="display=false" label="NIE" class="ui-button-secondary"></button>
|
<button type="button" pButton icon="pi pi-close" (click)="display=false" label="NIE" class="button" ></button>
|
||||||
</p-footer>
|
</p-footer>
|
||||||
</p-dialog>
|
</p-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,14 +6,15 @@
|
|||||||
|
|
||||||
<div class="profile">
|
<div class="profile">
|
||||||
<div class="profile-headers">
|
<div class="profile-headers">
|
||||||
<div>Login:</div>
|
<div>Login (lub specjalny identyfikator z systemu USOS):</div>
|
||||||
<div>E-mail:</div>
|
<div>E-mail:</div>
|
||||||
<div>Imię:</div>
|
<div>Imię:</div>
|
||||||
<div>Nazwisko:</div>
|
<div>Nazwisko:</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="profile-content">
|
<div class="profile-content">
|
||||||
<div>{{user.username}}</div>
|
<div>{{user.username}}</div>
|
||||||
<div>{{user.email}}</div>
|
<div *ngIf="user.email && user.email.length > 0">{{user.email}}</div>
|
||||||
|
<div *ngIf="!user.email || user.email.length === 0">Nie podano adresu e-mail</div>
|
||||||
<div>{{user.name}}</div>
|
<div>{{user.name}}</div>
|
||||||
<div>{{user.surname}}</div>
|
<div>{{user.surname}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,7 +49,7 @@ const localeText = {
|
|||||||
toolPanelButton: 'Narzędzia',
|
toolPanelButton: 'Narzędzia',
|
||||||
|
|
||||||
// other
|
// other
|
||||||
noRowsToShow: 'Brak testów do wyświetlenia',
|
noRowsToShow: 'Brak elementów do wyświetlenia',
|
||||||
|
|
||||||
// enterprise menu
|
// enterprise menu
|
||||||
pinColumn: 'Przypiąta kolumna',
|
pinColumn: 'Przypiąta kolumna',
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
export const environment = {
|
export const environment = {
|
||||||
production: true
|
production: true,
|
||||||
|
api: 'http://51.75.30.146:8080/',
|
||||||
|
frontend: 'http://51.75.30.146/'
|
||||||
};
|
};
|
||||||
|
@ -4,5 +4,7 @@
|
|||||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false
|
production: false,
|
||||||
|
api: 'http://localhost:8080/',
|
||||||
|
frontend: 'http://localhost:4200/'
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>StudyCave</title>
|
<title>Punktonerzy</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<!-- <script>document.write('<base href="' + document.location + '" />');</script> -->
|
<!-- <script>document.write('<base href="' + document.location + '" />');</script> -->
|
||||||
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<script language="javascript" type="text/javascript" src="./assets/js/standard_fonts_metrics.js"></script>
|
<script language="javascript" type="text/javascript" src="./assets/js/standard_fonts_metrics.js"></script>
|
||||||
<script language="javascript" type="text/javascript" src="./assets/js/jspdf.customfonts.min.js"></script>
|
<script language="javascript" type="text/javascript" src="./assets/js/jspdf.customfonts.min.js"></script>
|
||||||
<script language="javascript" type="text/javascript" src="./assets/js/split_text_to_size.js"></script>
|
<script language="javascript" type="text/javascript" src="./assets/js/split_text_to_size.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
|
@ -152,9 +152,13 @@ a:hover{
|
|||||||
background-color: #000080;
|
background-color: #000080;
|
||||||
width: 180px;
|
width: 180px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
border-color: #000080;
|
||||||
|
border-bottom: #000080;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover
|
.button:hover
|
||||||
{
|
{
|
||||||
background-color: orange;
|
background-color: orange;
|
||||||
|
border-color: orange;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user