Skip to content

Commit 7a3313c

Browse files
committed
Add loading spinner when fetching all data
1 parent a354be1 commit 7a3313c

File tree

3 files changed

+87
-70
lines changed

3 files changed

+87
-70
lines changed

frontend/src/app/questions/question.service.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,21 @@ export class QuestionService {
6464
}
6565

6666
addQuestion(question: QuestionBody): Observable<SingleQuestionResponse> {
67-
return this.http.post<SingleQuestionResponse>(this.baseUrl + '/questions', question, this.httpOptions).pipe(catchError(this.handleError));
67+
return this.http
68+
.post<SingleQuestionResponse>(this.baseUrl + '/questions', question, this.httpOptions)
69+
.pipe(catchError(this.handleError));
6870
}
6971

7072
updateQuestion(id: number, question: QuestionBody): Observable<SingleQuestionResponse> {
71-
return this.http.put<SingleQuestionResponse>(this.baseUrl + '/questions/' + id, question, this.httpOptions).pipe(catchError(this.handleError));
73+
return this.http
74+
.put<SingleQuestionResponse>(this.baseUrl + '/questions/' + id, question, this.httpOptions)
75+
.pipe(catchError(this.handleError));
7276
}
7377

7478
deleteQuestion(id: number): Observable<SingleQuestionResponse> {
75-
return this.http.delete<SingleQuestionResponse>(this.baseUrl + '/questions/' + id).pipe(catchError(this.handleError));
79+
return this.http
80+
.delete<SingleQuestionResponse>(this.baseUrl + '/questions/' + id)
81+
.pipe(catchError(this.handleError));
7682
}
7783

7884
handleError(error: HttpErrorResponse) {

frontend/src/app/questions/questions.component.html

Lines changed: 73 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,79 @@
11
<div class="card mx-8">
2+
<p-progressSpinner
3+
class="flex align-items-center justify-content-center h-screen"
4+
*ngIf="loading"
5+
styleClass="w-4rem h-4rem"
6+
strokeWidth="8"
7+
fill="var(--surface-ground)"
8+
animationDuration=".5s" />
29
<p-toast />
3-
<p-toolbar styleClass="mb-2 gap-2">
4-
<div class="p-justify-end">
5-
<p-button
6-
icon="pi pi-plus"
7-
severity="primary"
8-
[outlined]="true"
9-
label="New"
10-
class="mr-2"
11-
(onClick)="openNewQuestion()" />
12-
<p-button
13-
icon="pi pi-trash"
14-
severity="danger"
15-
label="Delete"
16-
(onClick)="deleteSelectedQuestions()"
17-
[disabled]="!selectedQuestions || !selectedQuestions.length" />
18-
</div>
19-
</p-toolbar>
20-
<p-table
21-
[columns]="cols"
22-
[value]="questions"
23-
[(selection)]="selectedQuestions"
24-
datakey="id"
25-
[tableStyle]="{ 'min-width': '50rem' }"
26-
[paginator]="true"
27-
[rows]="5"
28-
[rowsPerPageOptions]="[5, 10, 20]"
29-
styleClass="p-datatable-gridlines-striped">
30-
<ng-template pTemplate="caption">
31-
<div class="flex">
32-
<h3 class="m-0">Manage Questions</h3>
10+
<ng-container *ngIf="!loading">
11+
<p-toolbar styleClass="mb-2 gap-2">
12+
<div class="p-justify-end">
13+
<p-button
14+
icon="pi pi-plus"
15+
severity="primary"
16+
[outlined]="true"
17+
label="New"
18+
class="mr-2"
19+
(onClick)="openNewQuestion()" />
20+
<p-button
21+
icon="pi pi-trash"
22+
severity="danger"
23+
label="Delete"
24+
(onClick)="deleteSelectedQuestions()"
25+
[disabled]="!selectedQuestions || !selectedQuestions.length" />
3326
</div>
34-
</ng-template>
35-
<ng-template pTemplate="header" let-columns>
36-
<tr>
37-
<th style="width: 4rem"><p-tableHeaderCheckbox /></th>
38-
<th>Id</th>
39-
<th>Title</th>
40-
<th>Description</th>
41-
<th>Topics</th>
42-
<th>Difficulty</th>
43-
<th></th>
44-
</tr>
45-
</ng-template>
46-
<ng-template pTemplate="body" let-question>
47-
<tr>
48-
<td>
49-
<p-tableCheckbox [value]="question" />
50-
</td>
51-
<td>{{ question.id }}</td>
52-
<td>{{ question.title }}</td>
53-
<td>{{ question.description }}</td>
54-
<td>{{ question.topics.join(', ') }}</td>
55-
<td>{{ question.difficulty }}</td>
56-
<td>
57-
<p-button
58-
label="Edit"
59-
severity="primary"
60-
icon="pi pi-file-edit"
61-
class="mr-2"
62-
[text]="true"
63-
(onClick)="editQuestion(question)" />
64-
</td>
65-
</tr>
66-
</ng-template>
67-
</p-table>
68-
27+
</p-toolbar>
28+
<p-table
29+
[columns]="cols"
30+
[value]="questions"
31+
[(selection)]="selectedQuestions"
32+
datakey="id"
33+
[tableStyle]="{ 'min-width': '50rem' }"
34+
[paginator]="true"
35+
[rows]="5"
36+
[rowsPerPageOptions]="[5, 10, 20]"
37+
styleClass="p-datatable-gridlines-striped">
38+
<ng-template pTemplate="caption">
39+
<div class="flex">
40+
<h3 class="m-0">Manage Questions</h3>
41+
</div>
42+
</ng-template>
43+
<ng-template pTemplate="header" let-columns>
44+
<tr>
45+
<th style="width: 4rem"><p-tableHeaderCheckbox /></th>
46+
<th>Id</th>
47+
<th>Title</th>
48+
<th>Description</th>
49+
<th>Topics</th>
50+
<th>Difficulty</th>
51+
<th></th>
52+
</tr>
53+
</ng-template>
54+
<ng-template pTemplate="body" let-question>
55+
<tr>
56+
<td>
57+
<p-tableCheckbox [value]="question" />
58+
</td>
59+
<td>{{ question.id }}</td>
60+
<td>{{ question.title }}</td>
61+
<td>{{ question.description }}</td>
62+
<td>{{ question.topics.join(', ') }}</td>
63+
<td>{{ question.difficulty }}</td>
64+
<td>
65+
<p-button
66+
label="Edit"
67+
severity="primary"
68+
icon="pi pi-file-edit"
69+
class="mr-2"
70+
[text]="true"
71+
(onClick)="editQuestion(question)" />
72+
</td>
73+
</tr>
74+
</ng-template>
75+
</p-table>
76+
</ng-container>
6977
<p-dialog header="Header" [(visible)]="isDialogVisible" [modal]="true" [style]="{ width: '25rem' }">
7078
<ng-template pTemplate="header">
7179
<div class="inline-flex align-items-center justify-content-center gap-2">

frontend/src/app/questions/questions.component.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { DialogModule } from 'primeng/dialog';
1111
import { MultiSelectModule } from 'primeng/multiselect';
1212
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
1313
import { DropdownModule } from 'primeng/dropdown';
14+
import { ProgressSpinnerModule } from 'primeng/progressspinner';
1415
import { Question, SingleQuestionResponse, QuestionBody } from './question.model';
1516
import { Column } from './column.model';
1617
import { Topic } from './topic.model';
@@ -37,12 +38,15 @@ import { HttpErrorResponse } from '@angular/common/http';
3738
ReactiveFormsModule,
3839
MultiSelectModule,
3940
DropdownModule,
41+
ProgressSpinnerModule,
4042
],
4143
providers: [QuestionService, ConfirmationService, MessageService],
4244
templateUrl: './questions.component.html',
4345
styleUrl: './questions.component.css',
4446
})
4547
export class QuestionsComponent implements OnInit {
48+
loading = true;
49+
4650
questions: Question[] = [];
4751

4852
topics!: Topic[];
@@ -302,8 +306,7 @@ export class QuestionsComponent implements OnInit {
302306
});
303307
},
304308
complete: () => {
305-
// TODO: add loading state for this
306-
console.log('complete');
309+
this.loading = false;
307310
},
308311
});
309312
}

0 commit comments

Comments
 (0)