Refactor. Removed unused components

develop-jenkins
Manuel Aranda Rosales 2024-10-22 07:29:41 +02:00
parent 833a586c96
commit 5d74c11cbe
22 changed files with 220 additions and 104 deletions

View File

@ -113,6 +113,9 @@ import { SoftwareProfileComponent } from './components/software-profile/software
import { CreateSoftwareProfileComponent } from './components/software-profile/create-software-profile/create-software-profile.component';
import { OperativeSystemComponent } from './components/operative-system/operative-system.component';
import { CreateOperativeSystemComponent } from './components/operative-system/create-operative-system/create-operative-system.component';
import { ShowTemplateContentComponent } from './components/ogboot/pxe/show-template-content/show-template-content.component';
import { AddClientsToPxeComponent } from './components/ogboot/pxe/add-clients-to-pxe/add-clients-to-pxe.component';
import { ClientsComponent } from './components/ogboot/pxe/clients/clients.component';
@NgModule({
declarations: [
AppComponent,
@ -183,6 +186,9 @@ import { CreateOperativeSystemComponent } from './components/operative-system/cr
CreateSoftwareProfileComponent,
OperativeSystemComponent,
CreateOperativeSystemComponent,
ShowTemplateContentComponent,
AddClientsToPxeComponent,
ClientsComponent,
],
bootstrap: [AppComponent],
imports: [BrowserModule,

View File

@ -74,13 +74,13 @@ export class CommandsGroupsComponent implements OnInit {
openCreateCommandGroupModal(): void {
this.dialog.open(CreateCommandGroupComponent, {
width: '600px',
width: '700px',
}).afterClosed().subscribe(() => this.search());
}
editCommandGroup(group: any): void {
this.dialog.open(CreateCommandGroupComponent, {
width: '600px',
width: '700px',
data: { group },
}).afterClosed().subscribe(() => this.search());
}

View File

@ -249,3 +249,13 @@ mat-card {
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.red-card {
background-color: #f35f53; /* Color rojo */
color: white; /* Texto en blanco */
}
.green-card {
background-color: #4caf50; /* Color verde */
color: white; /* Texto en blanco */
}

View File

@ -94,15 +94,23 @@
<button mat-raised-button color="primary" (click)="toggleSelectAll()">Seleccionar/Deseleccionar Todos</button>
<button mat-raised-button color="primary" (click)="saveFilters()" i18n="@@saveFiltersButton">Guardar Filtros</button>
<button mat-raised-button color="accent" (click)="sendActions()" i18n="@@sendFiltersButton" [disabled]="selectedElements.length === 0">Enviar Acción</button>
<button mat-flat-button color="primary" [disabled]="selectedElements.length === 0" (click)="onPxeBootFile()">Añadir fichero PXE</button>
</div>
<div class="results">
<ng-container *ngIf="filteredResults && filteredResults.length > 0; else noResults">
<mat-grid-list cols="4" rowHeight="1:1">
<mat-grid-tile *ngFor="let result of filteredResults">
<mat-card class="result-card" (dblclick)="onDobleClick($event, result.uuid, result.type)">
<mat-card
class="result-card"
(dblclick)="onDobleClick($event, result.uuid, result.type)"
[ngClass]="{
'red-card': result.type === 'client' && result.status === 'power-off',
'green-card': result.type === 'client' && result.status === 'active'
}"
>
<mat-checkbox
[checked]="isSelected(result.name)"
(change)="onCheckboxChange($event, result.name, result.uuid)"
(change)="onCheckboxChange($event, result.name, result['@id'])"
class="result-checkbox">
</mat-checkbox>
<mat-card-title class="result-title">{{ result.name }}</mat-card-title>
@ -119,7 +127,7 @@
</p>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
<div class="paginator-container">

View File

@ -20,6 +20,9 @@ import { AcctionsModalComponent } from '../../shared/acctions-modal/acctions-mod
import {MatTableDataSource} from "@angular/material/table";
import {DatePipe} from "@angular/common";
import { Router } from '@angular/router';
import {
CreatePxeBootFileComponent
} from "../../../ogboot/pxe-boot-files/create-pxeBootFile/create-pxe-boot-file/create-pxe-boot-file.component";
@Component({
@ -257,10 +260,10 @@ export class AdvancedSearchComponent {
onEditClick(event: MouseEvent, type: any, uuid: string): void {
event.stopPropagation();
if (type != "client") {
const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid }, width: '700px'});
const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid }, width: '900px'});
} else {
console.log('Editar cliente');
const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid }, width: '700px' } );
const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid }, width: '900px' } );
}
}
@ -397,7 +400,7 @@ export class AdvancedSearchComponent {
this.isAllSelected = !this.isAllSelected;
if (this.isAllSelected) {
this.selectedElements = this.filteredResults.map(result => result.uuid);
this.selectedElements = this.filteredResults.map(result => result['@id']);
} else {
this.selectedElements = [];
}
@ -412,9 +415,14 @@ export class AdvancedSearchComponent {
const dialogRef = this.dialog.open(AcctionsModalComponent, { data: { selectedElements: this.selectedElements }, width: '700px'});
}
onPxeBootFile(): void {
const dialog = this.dialog.open(CreatePxeBootFileComponent, { data: this.selectedElements, width: '400px' });
dialog.afterClosed().subscribe(() => {
this.dialog.closeAll();
});
}
onDobleClick(event: MouseEvent, data: any, type: string): void {
onDobleClick(event: MouseEvent, data: any, type: string): void {
if (type === 'client') {
this.router.navigate(['client', data]);
}

View File

@ -26,6 +26,7 @@
}
.mat-elevation-z8 {
margin-top: 30px;
box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
}
@ -42,3 +43,22 @@
button{
margin-left: 10px;
}
.client-info {
display: flex;
flex-direction: column;
gap: 3px;
margin: 5px;
}
.client-name {
font-size: 16px;
font-weight: bold;
}
.client-ip,
.client-mac {
font-size: 12px;
color: #666;
line-height: 1.5;
}

View File

@ -37,9 +37,21 @@
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
<td mat-cell *matCellDef="let image" >
<ng-container >
{{ column.cell(image) }}
<td mat-cell *matCellDef="let client" >
<ng-container *ngIf="column.columnDef === 'name'">
<div class="client-info">
<div class="client-name">{{ client.name }}</div>
<div class="client-ip">{{ client.ip }}</div>
<div class="client-mac">{{ client.mac }}</div>
</div>
</ng-container>
<ng-container *ngIf="column.columnDef === 'status'">
<mat-chip>
{{ client.status }}
</mat-chip>
</ng-container>
<ng-container *ngIf="column.columnDef !== 'status' && column.columnDef !== 'name'" >
{{ column.cell(client) }}
</ng-container>
</td>
</ng-container>

View File

@ -44,16 +44,6 @@ export class ClientTabViewComponent {
header: 'Nombre del cliente',
cell: (client: any) => `${client.name}`
},
{
columnDef: 'ip',
header: 'IP',
cell: (client: any) => `${client.ip}`
},
{
columnDef: 'mac',
header: 'Mac',
cell: (client: any) => `${client.mac}`
},
{
columnDef: 'status',
header: 'Estado',
@ -62,13 +52,23 @@ export class ClientTabViewComponent {
{
columnDef: 'organizationalUnit',
header: 'Pertenece a',
cell: (client: any) => `${client.organizationalUnit.name}`
cell: (client: any) => `${client.organizationalUnit?.name}`
},
{
columnDef: 'ogLive',
header: 'OgLive',
cell: (client: any) => `${client.ogLive?.name}`
},
{
columnDef: 'subnet',
header: 'Subred',
cell: (client: any) => `${client.subnet}`
},
{
columnDef: 'template',
header: 'Plantilla PXE',
cell: (client: any) => `${client.template?.name}`
},
];
displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];

View File

@ -17,8 +17,8 @@
<mat-label i18n="@@searchLabel">Tipo</mat-label>
<mat-select [(ngModel)]="filters['type']" (selectionChange)="search()" placeholder="Seleccionar opción" >
<mat-option [value]="''">Todos</mat-option>
<mat-option [value]="'organizational-unit'">Unidad organizativa</mat-option>
<mat-option [value]="'classroom-group'">Grupos de aulas</mat-option>
<mat-option [value]="'organizational-unit'">Centro</mat-option>
<mat-option [value]="'classrooms-group'">Grupos de aulas</mat-option>
<mat-option [value]="'classroom'">Aula</mat-option>
<mat-option [value]="'clients-group'">Grupos de PCs</mat-option>
</mat-select>
@ -28,13 +28,16 @@
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
<td mat-cell *matCellDef="let ou" >
<ng-container *ngIf="column.columnDef !== 'available'">
<ng-container *ngIf="column.columnDef !== 'available' && column.columnDef !== 'type'">
{{ column.cell(ou) }}
</ng-container>
<ng-container *ngIf="column.columnDef === 'available'" >
<mat-chip *ngIf="ou.available" class="mat-chip-success"><mat-icon style="color:white;">check</mat-icon></mat-chip>
<mat-chip *ngIf="!ou.available" class="mat-chip-error"> <mat-icon style="color:white;">close</mat-icon></mat-chip>
</ng-container>
<ng-container *ngIf="column.columnDef === 'type'" >
<mat-chip> {{ ou.type }} </mat-chip>
</ng-container>
</td>
</ng-container>

View File

@ -72,11 +72,10 @@ mat-card-subtitle a:hover {
.groups-button-row {
display: flex;
flex-grow: 1;
}
button {
margin-left: 10px;
gap: 10px;
margin-bottom: 20px;
margin-left: 10px;
margin-top: 10px;
}
.item-content {

View File

@ -1,4 +1,4 @@
<mat-tab-group>
<mat-tab-group (selectedTabChange)="onTabChange($event)">
<mat-tab label="General">
<div class="header-container">
<h2 class="title" i18n="@@adminGroupsTitle">Administrar grupos</h2>
@ -9,12 +9,6 @@
</div>
</div>
<div class="search-container">
<mat-form-field appearance="fill">
<mat-label i18n="@@searchLabel">Búsqueda</mat-label>
<input matInput placeholder="Búsqueda" [(ngModel)]="searchTerm" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
<mat-icon matSuffix>search</mat-icon>
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar entre las unidades organizativas</mat-hint>
</mat-form-field>
<div class="classroomBtn-container">
<button mat-flat-button class="roomMap-btn" color="accent" (click)="roomMap()" *ngIf="selectedDetail && selectedDetail.type === 'classroom'" i18n="@@classroomMapButton">Plano de aula</button>
</div>
@ -115,7 +109,7 @@
<ng-container *ngSwitchDefault>help_outline</ng-container>
</mat-icon>
{{child.name}}
<span class="actions">
<div class="actions">
<mat-icon mat-button [matMenuTriggerFor]="menu" (click)="$event.stopPropagation()">more_vert</mat-icon>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="onEditClick($event, child.type, child.uuid)">
@ -139,7 +133,7 @@
<span i18n="@@deleteElementMenu">Borrar elemento</span>
</button>
</mat-menu>
</span>
</div>
</div>
</mat-list-item>
</mat-list>
@ -147,13 +141,13 @@
</mat-card>
</div>
</mat-tab>
<mat-tab i18n-label label="Búsqueda avanzada" >
<mat-tab i18n-label label="Búsqueda avanzada">
<app-advanced-search></app-advanced-search>
</mat-tab>
<mat-tab i18n-label label="Clientes">
<app-client-tab-view></app-client-tab-view>
<app-client-tab-view #clientTab></app-client-tab-view>
</mat-tab>
<mat-tab i18n-label label="Unidades organizativas">
<app-organizational-unit-tab-view></app-organizational-unit-tab-view>
<app-organizational-unit-tab-view #organizationalUnitTab></app-organizational-unit-tab-view>
</mat-tab>
</mat-tab-group>

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit, ViewChild} from '@angular/core';
import { DataService } from './services/data.service';
import { ClientCollection, UnidadOrganizativa } from './model/model';
import { MatDialog } from '@angular/material/dialog';
@ -19,6 +19,12 @@ import { SaveFiltersDialogComponent } from './shared/save-filters-dialog/save-fi
import { AcctionsModalComponent } from './shared/acctions-modal/acctions-modal.component';
import {MatTableDataSource} from "@angular/material/table";
import {DatePipe} from "@angular/common";
import {AdvancedSearchComponent} from "./components/advanced-search/advanced-search.component";
import {MatTabChangeEvent} from "@angular/material/tabs";
import {ClientTabViewComponent} from "./components/client-tab-view/client-tab-view.component";
import {
OrganizationalUnitTabViewComponent
} from "./components/organizational-unit-tab-view/organizational-unit-tab-view.component";
@Component({
selector: 'app-groups',
@ -69,6 +75,22 @@ export class GroupsComponent implements OnInit {
this.getFilters();
}
@ViewChild('clientTab') clientTabComponent!: ClientTabViewComponent;
@ViewChild('organizationalUnitTab') organizationalUnitTabComponent!: OrganizationalUnitTabViewComponent;
onTabChange(event: MatTabChangeEvent) {
switch (event.index) {
case 2:
this.clientTabComponent.search();
break;
case 3:
this.organizationalUnitTabComponent.search();
break;
default:
break;
}
}
getFilters(): void {
this.dataService.getFilters().subscribe(
data => {
@ -257,9 +279,9 @@ export class GroupsComponent implements OnInit {
onEditClick(event: MouseEvent, type: any, uuid: string): void {
event.stopPropagation();
if (type != "client") {
const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid }, width: '700px'});
const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid }, width: '900px'});
} else {
const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid }, width: '700px' } );
const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid }, width: '900px' } );
}
}

View File

@ -1,14 +1,13 @@
/* Contenedor de los botones, organizados en 2 columnas */
.button-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
margin: 20px; }
.button-row {
display: contents;
}
.button-action {
width: 100%;
}
display: grid;
grid-template-columns: 1fr 1fr; /* 2 columnas iguales */
gap: 15px; /* Espacio entre los botones */
margin-top: 15px;
}
/* Opcional: ancho 100% para los botones */
.button-action {
width: 100%;
justify-self: stretch; /* Asegura que los botones se extiendan por toda la columna */
}

View File

@ -1,14 +1,14 @@
<h1 mat-dialog-title i18n="@@actions-modal-title">Acciones</h1>
<div class="button-container">
<div *ngFor="let row of chunkArray(commands, 4)" class="button-row">
<mat-dialog-content>
<div class="button-container">
<button
*ngFor="let command of row"
mat-flat-button
*ngFor="let command of commands"
mat-raised-button
color="primary"
class="button-action"
(click)="onCommandClick(command)">
{{ command.name }}
</button>
</div>
<button mat-flat-button color="primary" (click)="onPxeBootFile()">Añadir fichero PXE</button>
</div>
</mat-dialog-content>

View File

@ -16,12 +16,20 @@ export class AcctionsModalComponent {
selectedElements: any;
commands: any[] = [];
displayedColumns: string[] = ['name', 'createdBy', 'createdAt'];
filteredCommands = [...this.commands];
private apiUrl = `${this.baseUrl}/commands?page=1&itemsPerPage=40`;
ngOnInit(): void {
this.loadCommands();
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value.toLowerCase();
this.filteredCommands = this.commands.filter(command =>
command.name.toLowerCase().includes(filterValue)
);
}
loadCommands(): void {
this.http.get<any>(this.apiUrl).subscribe(
(data) => {
@ -57,11 +65,4 @@ export class AcctionsModalComponent {
}
chunkArray(arr: any[], chunkSize: number): any[] {
const chunks = [];
for (let i = 0; i < arr.length; i += chunkSize) {
chunks.push(arr.slice(i, i + chunkSize));
}
return chunks;
}
}

View File

@ -65,9 +65,12 @@
</mat-form-field>
<mat-form-field class="form-field">
<mat-label i18n="@@menu-url-label">Menú URL</mat-label>
<input matInput formControlName="menu" type="url">
<mat-error i18n="@@menu-url-error">Formato de URL inválido.</mat-error>
<mat-label i18n="@@oglive-label">Plantilla PXE</mat-label>
<mat-select formControlName="template">
<mat-option *ngFor="let template of templates" [value]="template['@id']">
{{ template.name }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="form-field">

View File

@ -16,7 +16,8 @@ export class CreateClientComponent implements OnInit {
clientForm!: FormGroup;
parentUnits: any[] = [];
hardwareProfiles: any[] = [];
ogLives: any[] = [];
ogLives: any[] = [];
templates: any[] = [];
private errorForm: boolean = false;
protected netifaceTypes = [
{ "name": 'Eth0', "value": "eth0" },
@ -42,7 +43,8 @@ export class CreateClientComponent implements OnInit {
console.log(this.data);
this.loadParentUnits();
this.loadHardwareProfiles();
this.loadOgLives();
this.loadOgLives();
this.loadPxeTemplates()
this.clientForm = this.fb.group({
organizationalUnit: [this.data.organizationalUnit ? this.data.organizationalUnit['@id'] : null, Validators.required],
name: ['', Validators.required],
@ -51,9 +53,9 @@ export class CreateClientComponent implements OnInit {
netDriver: null,
mac: ['', Validators.required],
ip: ['', Validators.required],
menu: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings && this.data.organizationalUnit.networkSettings.menu ? this.data.organizationalUnit.networkSettings.menu['@id'] : null],
template: [null],
hardwareProfile: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings && this.data.organizationalUnit.networkSettings.hardwareProfile ? this.data.organizationalUnit.networkSettings.hardwareProfile['@id'] : null],
ogLive: [null]
ogLive: [null]
});
}
@ -87,7 +89,7 @@ export class CreateClientComponent implements OnInit {
}
loadOgLives() {
const url = `${this.baseUrl}/og-lives?page=1&itemsPerPage=30`;
this.http.get<any>(url).subscribe(
response => {
@ -99,11 +101,24 @@ export class CreateClientComponent implements OnInit {
);
}
loadPxeTemplates(): void {
const url = `${this.baseUrl}/pxe-templates?page=1&itemsPerPage=10000`;
this.http.get<any>(url).subscribe(
response => {
this.templates = response['hydra:member'];
},
error => {
console.error('Error fetching ogLives:', error);
}
);
}
onSubmit() {
if (this.clientForm.valid) {
this.errorForm = false;
const formData = this.clientForm.value;
formData.ogLive = formData.ogLive;
formData.ogLive = formData.ogLive;
this.http.post(`${this.baseUrl}/clients`, formData).subscribe(
response => {
this.dialogRef.close(response);

View File

@ -62,9 +62,12 @@
</mat-form-field>
<mat-form-field class="form-field">
<mat-label i18n="@@menu-url-label">Menú URL</mat-label>
<input matInput formControlName="menu" type="url">
<mat-error i18n="@@menu-url-error">Formato de URL inválido.</mat-error>
<mat-label i18n="@@oglive-label">Plantilla PXE</mat-label>
<mat-select formControlName="template">
<mat-option *ngFor="let template of templates" [value]="template['@id']">
{{ template.name }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="form-field">

View File

@ -14,10 +14,11 @@ import { ToastrService } from 'ngx-toastr';
export class EditClientComponent {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
clientForm!: FormGroup;
parentUnits: any[] = [];
hardwareProfiles: any[] = [];
ogLives: any[] = [];
isEditMode: boolean;
parentUnits: any[] = [];
hardwareProfiles: any[] = [];
ogLives: any[] = [];
templates: any[] = [];
isEditMode: boolean;
protected netifaceTypes = [
{ "name": 'Eth0', "value": "eth0" },
{ "name": 'Eth1', "value": "eth1" },
@ -34,18 +35,19 @@ export class EditClientComponent {
private http: HttpClient,
private dataService: DataService,
private toastService: ToastrService,
@Inject(MAT_DIALOG_DATA) public data: any
@Inject(MAT_DIALOG_DATA) public data: any
) {
this.isEditMode = !!data?.uuid;
this.isEditMode = !!data?.uuid;
if (this.isEditMode) {
this.loadData(data.uuid);
}
}
ngOnInit(): void {
this.loadParentUnits();
this.loadHardwareProfiles();
this.loadOgLives();
this.loadParentUnits();
this.loadHardwareProfiles();
this.loadOgLives();
this.loadPxeTemplates()
this.clientForm = this.fb.group({
organizationalUnit: [null, Validators.required],
name: ['', Validators.required],
@ -54,9 +56,9 @@ export class EditClientComponent {
netDriver: null,
mac: null,
ip: null,
menu: null,
template: null,
hardwareProfile: null,
ogLive: null,
ogLive: null,
});
}
@ -97,6 +99,19 @@ export class EditClientComponent {
);
}
loadPxeTemplates(): void {
const url = `${this.baseUrl}/pxe-templates?page=1&itemsPerPage=10000`;
this.http.get<any>(url).subscribe(
response => {
this.templates = response['hydra:member'];
},
error => {
console.error('Error fetching ogLives:', error);
}
);
}
loadData(uuid: string) {
this.loading = true;
const url = `${this.baseUrl}/clients/${uuid}`;
@ -112,7 +127,8 @@ export class EditClientComponent {
serialNumber: data.serialNumber,
hardwareProfile: data.hardwareProfile ? data.hardwareProfile['@id'] : null,
organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : null,
ogLive: data.ogLive ? data.ogLive['@id'] : null,
ogLive: data.ogLive ? data.ogLive['@id'] : null,
template: data.template ? data.template['@id'] : null,
});
this.loading = false;
},

View File

@ -81,7 +81,7 @@
</mat-step>
<!-- Step 4: Configuración de Red -->
<mat-step [stepControl]="networkSettingsFormGroup">
<mat-step *ngIf="generalFormGroup.value.type === 'classroom'" [stepControl]="networkSettingsFormGroup">
<form [formGroup]="networkSettingsFormGroup">
<ng-template matStepLabel i18n="@@networkSettingsStepLabel">Configuración de Red</ng-template>
<mat-form-field class="form-field">
@ -156,14 +156,11 @@
</mat-select>
<mat-error i18n="@@urlFormatError">Formato de URL inválido.</mat-error>
</mat-form-field>
<div>
<button mat-button matStepperPrevious i18n="@@backButton">Atrás</button>
<button mat-button (click)="onSubmit()" [disabled]="!networkSettingsFormGroup.valid" i18n="@@submitButton">Añadir</button>
</div>
</form>
</mat-step>
</mat-stepper>
</div>
<div mat-dialog-actions>
<div mat-dialog-actions align="end">
<button mat-button (click)="onNoClick()" i18n="@@cancelButton">Cancelar</button>
<button mat-button (click)="onSubmit()" [disabled]="!networkSettingsFormGroup.valid" i18n="@@submitButton">Añadir</button>
</div>

View File

@ -19,7 +19,7 @@ export class CreateOrganizationalUnitComponent implements OnInit {
classroomInfoFormGroup: FormGroup;
types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group'];
typeTranslations: { [key: string]: string } = {
'organizational-unit': 'Unidad organizativa',
'organizational-unit': 'Centro',
'classrooms-group': 'Grupo de aulas',
'classroom': 'Aula',
'clients-group': 'Grupo de clientes'

View File

@ -51,6 +51,6 @@
</mat-nested-tree-node>
</mat-tree>
</mat-dialog-content>
<mat-dialog-actions>
<mat-dialog-actions align="end">
<button mat-button (click)="close()" i18n="@@closeButton">Cerrar</button>
</mat-dialog-actions>