refs #1549. Add loading state management to ManageOrganizationalUnitComponent for improved user experience during data fetching
testing/ogGui-multibranch/pipeline/head This commit looks good Details

deb-pkg
Lucas Lara García 2025-02-24 16:13:29 +01:00
parent f1ddf20d0c
commit 1c4343bb48
3 changed files with 221 additions and 177 deletions

View File

@ -1,3 +1,6 @@
<app-loading [isLoading]="loading"></app-loading>
<div *ngIf="!loading">
<h1 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Crear' }} Unidad Organizativa</h1> <h1 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Crear' }} Unidad Organizativa</h1>
<div class="mat-dialog-content"> <div class="mat-dialog-content">
<!-- Paso 1: General --> <!-- Paso 1: General -->
@ -40,7 +43,8 @@
<!-- Paso 2: Información del Aula --> <!-- Paso 2: Información del Aula -->
<span *ngIf="generalFormGroup.value.type === 'classroom'" class="step-title">Información del aula</span> <span *ngIf="generalFormGroup.value.type === 'classroom'" class="step-title">Información del aula</span>
<form *ngIf="generalFormGroup.value.type === 'classroom'" class="grid-form" [formGroup]="classroomInfoFormGroup"> <form *ngIf="generalFormGroup.value.type === 'classroom'" class="grid-form"
[formGroup]="classroomInfoFormGroup">
<mat-form-field class="form-field"> <mat-form-field class="form-field">
<mat-label>Localización</mat-label> <mat-label>Localización</mat-label>
<input matInput formControlName="location"> <input matInput formControlName="location">
@ -170,3 +174,4 @@
[disabled]="!generalFormGroup.valid || !additionalInfoFormGroup.valid || !networkSettingsFormGroup.valid">{{ [disabled]="!generalFormGroup.valid || !additionalInfoFormGroup.valid || !networkSettingsFormGroup.valid">{{
isEditMode ? 'Editar' : 'Crear' }}</button> isEditMode ? 'Editar' : 'Crear' }}</button>
</div> </div>
</div>

View File

@ -11,6 +11,8 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { LoadingComponent } from '../../../../../shared/loading/loading.component';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
describe('ManageOrganizationalUnitComponent', () => { describe('ManageOrganizationalUnitComponent', () => {
let component: ManageOrganizationalUnitComponent; let component: ManageOrganizationalUnitComponent;
@ -18,7 +20,7 @@ describe('ManageOrganizationalUnitComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ManageOrganizationalUnitComponent], declarations: [ManageOrganizationalUnitComponent, LoadingComponent],
imports: [ imports: [
HttpClientTestingModule, HttpClientTestingModule,
ReactiveFormsModule, ReactiveFormsModule,
@ -29,7 +31,8 @@ describe('ManageOrganizationalUnitComponent', () => {
MatSlideToggleModule, MatSlideToggleModule,
MatCheckboxModule, MatCheckboxModule,
TranslateModule.forRoot(), TranslateModule.forRoot(),
BrowserAnimationsModule BrowserAnimationsModule,
MatProgressSpinnerModule
], ],
providers: [ providers: [
{ provide: MatDialogRef, useValue: {} }, { provide: MatDialogRef, useValue: {} },

View File

@ -43,6 +43,7 @@ export class ManageOrganizationalUnitComponent implements OnInit {
]; ];
@Output() unitAdded = new EventEmitter(); @Output() unitAdded = new EventEmitter();
calendars: any; calendars: any;
loading: boolean = false;
constructor( constructor(
private _formBuilder: FormBuilder, private _formBuilder: FormBuilder,
@ -111,6 +112,7 @@ export class ManageOrganizationalUnitComponent implements OnInit {
} }
loadParentUnits() { loadParentUnits() {
this.loading = true;
const url = `${this.baseUrl}/organizational-units?page=1&itemsPerPage=1000`; const url = `${this.baseUrl}/organizational-units?page=1&itemsPerPage=1000`;
this.http.get<any>(url).subscribe( this.http.get<any>(url).subscribe(
response => { response => {
@ -120,8 +122,12 @@ export class ManageOrganizationalUnitComponent implements OnInit {
name: unit.name, name: unit.name,
path: this.dataService.getOrganizationalUnitPath(unit, this.parentUnits) path: this.dataService.getOrganizationalUnitPath(unit, this.parentUnits)
})); }));
this.loading = false;
}, },
error => console.error('Error fetching parent units:', error) error => {
console.error('Error fetching parent units:', error);
this.loading = false;
}
); );
} }
@ -131,64 +137,91 @@ export class ManageOrganizationalUnitComponent implements OnInit {
} }
loadHardwareProfiles(): void { loadHardwareProfiles(): void {
this.loading = true;
this.dataService.getHardwareProfiles().subscribe( this.dataService.getHardwareProfiles().subscribe(
(data: any[]) => { (data: any[]) => {
this.hardwareProfiles = data; this.hardwareProfiles = data;
this.loading = false;
}, },
(error: any) => { (error: any) => {
console.error('Error fetching hardware profiles', error); console.error('Error fetching hardware profiles', error);
this.loading = false;
} }
); );
} }
loadMenus(): void { loadMenus(): void {
this.loading = true;
const url = `${this.baseUrl}/menus?page=1&itemsPerPage=10000`; const url = `${this.baseUrl}/menus?page=1&itemsPerPage=10000`;
this.http.get<any>(url).subscribe( this.http.get<any>(url).subscribe(
response => { response => {
this.menus = response['hydra:member']; this.menus = response['hydra:member'];
this.loading = false;
}, },
error => { error => {
console.error('Error fetching menus:', error); console.error('Error fetching menus:', error);
this.loading = false;
} }
); );
} }
loadOgLives() { loadOgLives() {
this.loading = true;
this.dataService.getOgLives().subscribe( this.dataService.getOgLives().subscribe(
(data: any[]) => { (data: any[]) => {
this.ogLives = data this.ogLives = data;
this.loading = false;
}, },
error => console.error('Error fetching ogLives', error) error => {
console.error('Error fetching ogLives', error);
this.loading = false;
}
); );
} }
loadRepositories() { loadRepositories() {
this.loading = true;
this.dataService.getRepositories().subscribe( this.dataService.getRepositories().subscribe(
(data: any[]) => this.repositories = data, (data: any[]) => {
error => console.error('Error fetching repositories', error) this.repositories = data;
this.loading = false;
},
error => {
console.error('Error fetching repositories', error);
this.loading = false;
}
); );
} }
loadCalendars() { loadCalendars() {
this.loading = true;
const apiUrl = `${this.baseUrl}/remote-calendars?page=1&itemsPerPage=30`; const apiUrl = `${this.baseUrl}/remote-calendars?page=1&itemsPerPage=30`;
this.http.get<any>(apiUrl).subscribe( this.http.get<any>(apiUrl).subscribe(
response => this.calendars = response['hydra:member'], response => {
this.calendars = response['hydra:member'];
this.loading = false;
},
error => { error => {
console.error('Error loading calendars', error); console.error('Error loading calendars', error);
this.toastService.error('Error loading current calendar'); this.toastService.error('Error loading current calendar');
this.loading = false;
} }
); );
} }
loadCurrentCalendar(uuid: string): void { loadCurrentCalendar(uuid: string): void {
this.loading = true;
const apiUrl = `${this.baseUrl}/remote-calendars/${uuid}`; const apiUrl = `${this.baseUrl}/remote-calendars/${uuid}`;
this.http.get<any>(apiUrl).subscribe( this.http.get<any>(apiUrl).subscribe(
response => this.currentCalendar = response, response => {
this.currentCalendar = response;
this.loading = false;
},
error => { error => {
console.error('Error loading current calendar', error); console.error('Error loading current calendar', error);
this.toastService.error('Error loading current calendar'); this.toastService.error('Error loading current calendar');
this.loading = false;
} }
); );
} }
@ -206,6 +239,7 @@ export class ManageOrganizationalUnitComponent implements OnInit {
} }
loadData(uuid: string) { loadData(uuid: string) {
this.loading = true;
const url = `${this.baseUrl}/organizational-units/${uuid}`; const url = `${this.baseUrl}/organizational-units/${uuid}`;
this.http.get<any>(url).subscribe( this.http.get<any>(url).subscribe(
@ -244,11 +278,13 @@ export class ManageOrganizationalUnitComponent implements OnInit {
capacity: data.capacity, capacity: data.capacity,
remoteCalendar: data.remoteCalendar ? data.remoteCalendar['@id'] : null remoteCalendar: data.remoteCalendar ? data.remoteCalendar['@id'] : null
}); });
this.loading = false;
}, },
error => { error => {
console.error('Error fetching data for edit:', error); console.error('Error fetching data for edit:', error);
this.toastService.error('Error fetching data'); this.toastService.error('Error fetching data');
this.loading = false;
this.onNoClick(); this.onNoClick();
} }
); );