Groups base structure

pull/4/head
Alvaro Puente Mella 2024-06-20 15:40:24 +02:00
parent 8ae5d44757
commit 3852c95b6a
9 changed files with 109 additions and 123 deletions

View File

@ -1,35 +1,55 @@
// data.service.ts
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { UnidadOrganizativa } from './model'; import { UnidadOrganizativa } from './model';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root'
}) })
export class DataService { export class DataService {
private unidadesOrganizativas: UnidadOrganizativa[] = [
{
id: 1,
nombre: 'Unidad Organizativa 1',
aulas: [
{
id: 1,
nombre: 'Aula 1',
clientes: [
{ id: 1, nombre: 'Cliente 1' },
{ id: 2, nombre: 'Cliente 2' },
],
},
{
id: 2,
nombre: 'Aula 2',
clientes: [{ id: 3, nombre: 'Cliente 3' }],
},
],
},
// Otros datos de ejemplo
];
getUnidadesOrganizativas(): UnidadOrganizativa[] { private apiUrl = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30';
return this.unidadesOrganizativas;
constructor(private http: HttpClient) {}
getUnidadesOrganizativas(): Observable<UnidadOrganizativa[]> {
return this.http.get<any>(this.apiUrl).pipe(
map(response => {
if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
return response['hydra:member']
.filter((unidad: any) => unidad.type === 'organizational-unit')
.map((unidad: any) => ({
id: unidad.id,
nombre: unidad.name,
uuid: unidad.uuid,
type: unidad.type,
aulas: []
}));
} else {
throw new Error('Unexpected response format');
}
}),
catchError(error => {
console.error('Error fetching unidades organizativas', error);
return throwError(error);
})
);
}
getChildren(uuid: string): Observable<any[]> {
return this.http.get<any>(this.apiUrl).pipe(
map(response => {
if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
return response['hydra:member'].filter((element: any) => element.parent === `/organizational-units/${uuid}`);
} else {
throw new Error('Unexpected response format');
}
}),
catchError(error => {
console.error('Error fetching children', error);
return throwError(error);
})
);
} }
} }

View File

@ -15,3 +15,11 @@ button {
margin-bottom: 20px; margin-bottom: 20px;
} }
.clickable-item:hover {
cursor: pointer;
}
.selected-item {
background-color: #e0e0e0;
}

View File

@ -1,8 +1,6 @@
<h2>Crear</h2> <h2>Crear</h2>
<div class="groups-button-row"> <div class="groups-button-row">
<button mat-flat-button color="primary" (click)="addOU()">+ Unidad Organizativa</button> <button mat-flat-button color="primary" (click)="addOU()">Nueva Unidad Organizativa</button>
<button mat-flat-button color="primary">+ Aula</button>
<button mat-flat-button color="primary" (click)="addClient()">+ Cliente</button>
</div> </div>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<h2>Grupos</h2> <h2>Grupos</h2>
@ -10,36 +8,13 @@
<mat-card> <mat-card>
<mat-card-title>Unidad organizativa</mat-card-title> <mat-card-title>Unidad organizativa</mat-card-title>
<mat-card-content> <mat-card-content>
<mat-selection-list role="list"> <mat-list role="list">
<mat-list-option <mat-list-item *ngFor="let unidad of unidadesOrganizativas"
*ngFor="let unidad of unidadesOrganizativas" (click)="onSelectUnidad(unidad)"
(click)="onSelectUnidad(unidad)"> [ngClass]="{'selected-item': unidad === selectedUnidad, 'clickable-item': true}">
{{ unidad.nombre }} {{ unidad.nombre }}
</mat-list-option> </mat-list-item>
</mat-selection-list> </mat-list>
</mat-card-content>
</mat-card>
<mat-card *ngIf="selectedUnidad">
<mat-card-title>Aulas</mat-card-title>
<mat-card-content>
<mat-selection-list role="list">
<mat-list-option
*ngFor="let aula of selectedUnidad.aulas"
(click)="onSelectAula(aula)">
{{ aula.nombre }}
</mat-list-option>
</mat-selection-list>
</mat-card-content>
</mat-card>
<mat-card *ngIf="selectedAula">
<mat-card-title>Clientes</mat-card-title>
<mat-card-content>
<mat-selection-list role="list">
<mat-list-option
*ngFor="let cliente of selectedClientes">
{{ cliente.nombre }}
</mat-list-option>
</mat-selection-list>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
</div> </div>

View File

@ -1,10 +1,8 @@
// groups.component.ts
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { UnidadOrganizativa, Aula, Cliente } from './model'; import { UnidadOrganizativa } from './model';
import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { CreateClientComponent } from './clients/create-client/create-client.component'; import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component';
@Component({ @Component({
selector: 'app-groups', selector: 'app-groups',
@ -14,32 +12,21 @@ import { CreateClientComponent } from './clients/create-client/create-client.com
export class GroupsComponent implements OnInit { export class GroupsComponent implements OnInit {
unidadesOrganizativas: UnidadOrganizativa[] = []; unidadesOrganizativas: UnidadOrganizativa[] = [];
selectedUnidad: UnidadOrganizativa | null = null; selectedUnidad: UnidadOrganizativa | null = null;
selectedAula: Aula | null = null;
selectedClientes: Cliente[] = [];
constructor(private dataService: DataService, public dialog: MatDialog) {} constructor(private dataService: DataService, public dialog: MatDialog) {}
ngOnInit(): void { ngOnInit(): void {
this.unidadesOrganizativas = this.dataService.getUnidadesOrganizativas(); this.dataService.getUnidadesOrganizativas().subscribe(
data => this.unidadesOrganizativas = data,
error => console.error('Error fetching unidades organizativas', error)
);
} }
onSelectUnidad(unidad: UnidadOrganizativa): void { onSelectUnidad(unidad: UnidadOrganizativa): void {
this.selectedUnidad = unidad; this.selectedUnidad = unidad;
this.selectedAula = null;
this.selectedClientes = [];
} }
onSelectAula(aula: Aula): void { addOU(): void {
this.selectedAula = aula; this.dialog.open(CreateOrganizationalUnitComponent);
this.selectedClientes = aula.clientes;
}
addOU() {
const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent);
}
addClient() {
const dialogRef = this.dialog.open(CreateClientComponent);
} }
} }

View File

@ -1,19 +1,16 @@
// models.ts // model.ts
export interface Cliente { export interface Cliente {
id: number;
nombre: string; nombre: string;
} }
export interface Aula { export interface Aula {
id: number;
nombre: string; nombre: string;
clientes: Cliente[]; clientes: Cliente[];
bloques?: Aula[]; }
}
export interface UnidadOrganizativa { export interface UnidadOrganizativa {
id: number; id: number;
nombre: string; nombre: string;
uuid: string;
aulas: Aula[]; aulas: Aula[];
} }

View File

@ -1,24 +1,30 @@
<h1 mat-dialog-title>Añadir Unidad Organizativa</h1> <h1 mat-dialog-title>Añadir Unidad Organizativa</h1>
<div mat-dialog-content> <div mat-dialog-content>
<mat-stepper orientation="vertical" [linear]="isLinear" #stepper> <mat-stepper orientation="vertical" [linear]="isLinear">
<!-- Step 1: General --> <!-- Step 1: General -->
<mat-step [stepControl]="generalFormGroup"> <mat-step [stepControl]="generalFormGroup">
<form [formGroup]="generalFormGroup"> <form [formGroup]="generalFormGroup">
<ng-template matStepLabel>General</ng-template> <ng-template matStepLabel>General</ng-template>
<mat-form-field class="form-field">
<mat-label>Tipo</mat-label>
<mat-select formControlName="type" required>
<mat-option *ngFor="let type of types" [value]="type">{{ type }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="form-field"> <mat-form-field class="form-field">
<mat-label>Nombre</mat-label> <mat-label>Nombre</mat-label>
<input matInput formControlName="name" required> <input matInput formControlName="name" required>
</mat-form-field> </mat-form-field>
<mat-form-field class="form-field"> <mat-form-field class="form-field">
<mat-label>Padre</mat-label> <mat-label>Padre</mat-label>
<input matInput formControlName="parent" type="url" required> <input matInput formControlName="parent" required>
</mat-form-field> </mat-form-field>
<mat-form-field class="form-field"> <mat-form-field class="form-field">
<mat-label>Descripción</mat-label> <mat-label>Descripción</mat-label>
<textarea matInput formControlName="description"></textarea> <textarea matInput formControlName="description"></textarea>
</mat-form-field> </mat-form-field>
<div> <div>
<button mat-button matStepperSiguiente>Siguiente</button> <button mat-button matStepperNext>Siguiente</button>
</div> </div>
</form> </form>
</mat-step> </mat-step>
@ -31,13 +37,9 @@
<mat-label>Comentarios</mat-label> <mat-label>Comentarios</mat-label>
<textarea matInput formControlName="comments"></textarea> <textarea matInput formControlName="comments"></textarea>
</mat-form-field> </mat-form-field>
<mat-form-field class="form-field">
<mat-label>Tipo</mat-label>
<input matInput formControlName="type" required>
</mat-form-field>
<div> <div>
<button mat-button matStepperPrevious>Atrás</button> <button mat-button matStepperPrevious>Atrás</button>
<button mat-button matStepperSiguiente>Siguiente</button> <button mat-button matStepperNext>Siguiente</button>
</div> </div>
</form> </form>
</mat-step> </mat-step>
@ -101,7 +103,7 @@
<mat-slide-toggle formControlName="validation">Validación</mat-slide-toggle> <mat-slide-toggle formControlName="validation">Validación</mat-slide-toggle>
<div> <div>
<button mat-button matStepperPrevious>Atrás</button> <button mat-button matStepperPrevious>Atrás</button>
<button mat-button (click)="onSubmit()" [disabled]="!networkForm.valid">Añadir</button> <button mat-button (click)="onSubmit()" [disabled]="!networkSettingsFormGroup.valid">Añadir</button>
</div> </div>
</form> </form>
</mat-step> </mat-step>

View File

@ -9,10 +9,10 @@ import { MatDialogRef } from '@angular/material/dialog';
}) })
export class CreateOrganizationalUnitComponent implements OnInit { export class CreateOrganizationalUnitComponent implements OnInit {
isLinear = true; isLinear = true;
networkForm: FormGroup;
generalFormGroup: FormGroup; generalFormGroup: FormGroup;
additionalInfoFormGroup: FormGroup; additionalInfoFormGroup: FormGroup;
networkSettingsFormGroup: FormGroup; networkSettingsFormGroup: FormGroup;
types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group'];
constructor( constructor(
private _formBuilder: FormBuilder, private _formBuilder: FormBuilder,
@ -20,12 +20,12 @@ export class CreateOrganizationalUnitComponent implements OnInit {
) { ) {
this.generalFormGroup = this._formBuilder.group({ this.generalFormGroup = this._formBuilder.group({
name: ['', Validators.required], name: ['', Validators.required],
parent: ['', [Validators.required, Validators.pattern('https?://.+')]], parent: ['', Validators.required],
description: [''] description: [''],
type: ['', Validators.required]
}); });
this.additionalInfoFormGroup = this._formBuilder.group({ this.additionalInfoFormGroup = this._formBuilder.group({
comments: [''], comments: [''],
type: ['', Validators.required]
}); });
this.networkSettingsFormGroup = this._formBuilder.group({ this.networkSettingsFormGroup = this._formBuilder.group({
proxy: [''], proxy: [''],
@ -43,26 +43,23 @@ export class CreateOrganizationalUnitComponent implements OnInit {
hardwareProfile: ['', Validators.pattern('https?://.+')], hardwareProfile: ['', Validators.pattern('https?://.+')],
validation: [false] validation: [false]
}); });
this.networkForm = this._formBuilder.group({
general: this.generalFormGroup,
additionalInfo: this.additionalInfoFormGroup,
networkSettings: this.networkSettingsFormGroup
});
} }
ngOnInit() {} ngOnInit() {}
onSubmit() { onSubmit() {
if (this.networkForm.valid) { if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) {
const formData = this.networkForm.value; const formData = {
...this.generalFormGroup.value,
...this.additionalInfoFormGroup.value,
...this.networkSettingsFormGroup.value,
};
console.log('Form Data:', formData); console.log('Form Data:', formData);
// handle form submission logic this.dialogRef.close(formData);
this.dialogRef.close(formData); // Cierra el modal y pasa los datos del formulario
} }
} }
onNoClick(): void { onNoClick(): void {
this.dialogRef.close(); // Cierra el modal sin pasar datos this.dialogRef.close();
} }
} }

View File

@ -7,6 +7,7 @@
background-color: rgb(245, 245, 245); background-color: rgb(245, 245, 245);
transition: left 0.3s ease-in-out; transition: left 0.3s ease-in-out;
box-shadow: 10px 0 10px -5px rgba(0, 0, 0, 0.5); box-shadow: 10px 0 10px -5px rgba(0, 0, 0, 0.5);
z-index: 99999999999;
} }
.sidebar.visible { .sidebar.visible {

View File

@ -21,7 +21,6 @@ export class SidebarComponent {
if (token) { if (token) {
try { try {
this.decodedToken = jwtDecode(token); this.decodedToken = jwtDecode(token);
console.log('Decoded token:', this.decodedToken);
this.isSuperAdmin = this.decodedToken.roles.includes('ROLE_SUPER_ADMIN'); this.isSuperAdmin = this.decodedToken.roles.includes('ROLE_SUPER_ADMIN');
this.username = this.decodedToken.username; this.username = this.decodedToken.username;
} catch (error) { } catch (error) {