Merge branch 'develop' of ssh://ognproject.evlt.uma.es:21987/opengnsys/oggui into develop

oggui/calendar
Manuel Aranda Rosales 2024-10-02 11:36:43 +02:00
commit 070aef716f
8 changed files with 147 additions and 102 deletions

View File

@ -1,63 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatDividerModule } from '@angular/material/divider';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatTableModule } from '@angular/material/table';
import { MatMenuModule } from '@angular/material/menu';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ToastrService } from 'ngx-toastr';
import { CommandsGroupsComponent } from './commands-groups.component';
class MockToastrService {
success() {}
}
class MockMatDialogRef {
close() {}
}
describe('CommandsGroupsComponent', () => {
let component: CommandsGroupsComponent;
let fixture: ComponentFixture<CommandsGroupsComponent>;
let toastService: ToastrService;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [CommandsGroupsComponent],
imports: [
HttpClientModule,
MatDialogModule,
MatPaginatorModule,
MatDividerModule,
MatButtonModule,
MatIconModule,
MatFormFieldModule,
MatInputModule,
MatTableModule,
MatMenuModule,
FormsModule,
BrowserAnimationsModule,
],
providers: [
{ provide: ToastrService, useClass: MockToastrService },
{ provide: MatDialogRef, useClass: MockMatDialogRef }
]
}).compileComponents();
fixture = TestBed.createComponent(CommandsGroupsComponent);
component = fixture.componentInstance;
toastService = TestBed.inject(ToastrService);
fixture.detectChanges();
});
it('should create the component', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,3 +1,74 @@
.task-button-row{
margin-bottom: 10px;
}
.commands-list {
margin-bottom: 20px;
}
.command-item {
cursor: pointer;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #f9f9f9;
}
.command-item:hover {
background-color: #e9e9e9;
}
.command-details {
padding: 20px;
border: 1px solid #ddd;
background-color: #f4f4f4;
border-radius: 4px;
}
.script-display {
margin-top: 20px;
background-color: #000;
color: #fff;
padding: 10px;
border-radius: 4px;
}
pre {
margin: 0;
font-family: 'Courier New', Courier, monospace;
}
.mat-elevation-z8{
margin-top: 20px;
}
tr:hover {
background-color: rgba(219, 219, 219, 0.219);
}
.detailBtn{
cursor: pointer;
}
.search-container {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 0 5px;
box-sizing: border-box;
}
.search-string {
flex: 2;
padding: 5px;
}
.search-boolean {
flex: 1;
padding: 5px;
}
.command-groups-button-row{
margin-bottom: 10px;
}

View File

@ -5,6 +5,15 @@
</div>
</div>
<div class="search-container">
<mat-form-field appearance="fill" class="search-string">
<mat-label>Buscar tarea</mat-label>
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" />
<mat-icon matSuffix>search</mat-icon>
<mat-hint>Pulsar 'enter' para buscar</mat-hint>
</mat-form-field>
</div>
<table mat-table [dataSource]="tasks" class="mat-elevation-z8">
<ng-container matColumnDef="notes">
<th mat-header-cell *matHeaderCellDef> Info</th>

View File

@ -28,6 +28,11 @@ export class CommandsTaskComponent implements OnInit {
this.loadTasks();
}
search(): void {
this.page = 1;
this.loadTasks();
}
loadTasks(): void {
this.http.get<any>(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
(data) => {

View File

@ -48,7 +48,7 @@
<button mat-button color="primary" class="primary-button" [disabled]="false" (click)="execute()" >
{{ showClientSelect ? 'Ejecutar' : 'Configurar ejecución' }}
</button>
<button mat-button color="accent" class="accent-button" (click)="edit()">Editar</button>
<!-- <button mat-button color="accent" class="accent-button" (click)="edit()">Editar</button> -->
<button mat-button class="cancel-button" (click)="cancel()">Cancelar</button>
</div>
</div>

View File

@ -47,6 +47,7 @@
</mat-form-field>
<!-- Campo nuevo para seleccionar el calendario asociado -->
<p>Calendario asociado actual {{currentCalendar.name}}</p>
<mat-form-field appearance="fill">
<mat-label>Calendario Asociado</mat-label>
<mat-select formControlName="calendarSelect" (selectionChange)="onCalendarChange($event)">

View File

@ -19,9 +19,10 @@ export class EditOrganizationalUnitComponent implements OnInit {
networkSettingsFormGroup: FormGroup;
classroomInfoFormGroup: FormGroup;
types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group'];
parentUnits: any[] = []; // Array to store parent units fetched from API
parentUnits: any[] = [];
hardwareProfiles: any[] = [];
isEditMode: boolean; // Flag to check if it's edit mode
isEditMode: boolean;
currentCalendar: any;
protected p2pModeOptions = [
{"name": 'Leecher', "value": "p2p-mode-leecher"},
{"name": 'Peer', "value": "p2p-mode-peer"},
@ -31,18 +32,18 @@ export class EditOrganizationalUnitComponent implements OnInit {
{"name": 'Half duplex', "value": "half-duplex"},
{"name": 'Full duplex', "value": "full-duplex"},
];
@Output() unitAdded = new EventEmitter(); // Event emitter to notify parent component about unit addition
@Output() unitAdded = new EventEmitter();
calendars: any;
constructor(
private _formBuilder: FormBuilder,
private dialogRef: MatDialogRef<CreateOrganizationalUnitComponent>,
private http: HttpClient, // Inject HttpClient for HTTP requests
private http: HttpClient,
private dataService: DataService,
private toastService: ToastrService,
@Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode
@Inject(MAT_DIALOG_DATA) public data: any
) {
this.isEditMode = !!data?.uuid; // Check if uuid is passed to determine edit mode
this.isEditMode = !!data?.uuid;
this.generalFormGroup = this._formBuilder.group({
name: ['', Validators.required],
@ -126,6 +127,16 @@ export class EditOrganizationalUnitComponent implements OnInit {
);
}
loadCurrentCalendar(uuid: string): void {
const apiUrl = `${this.baseUrl}/remote-calendars/${uuid}`;
this.http.get<any>(apiUrl).subscribe(
response => this.currentCalendar = response,
error => {
console.error('Error loading current calendar', error);
this.openSnackBar(true, 'Error loading current calendar');
}
);}
onCalendarChange(event: any) {
const selectedCalendarId = event.value;
console.log('Selected calendar ID:', selectedCalendarId);
@ -170,6 +181,7 @@ export class EditOrganizationalUnitComponent implements OnInit {
capacity: data.capacity,
calendarSelect: data.remoteCalendar['@id']
});
this.loadCurrentCalendar(data.remoteCalendar.uuid);
},
error => {
console.error('Error fetching data for edit:', error);

View File

@ -1,3 +1,4 @@
import { HttpClient } from '@angular/common/http';
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA} from "@angular/material/dialog";
@ -7,43 +8,52 @@ import {MAT_DIALOG_DATA} from "@angular/material/dialog";
styleUrl: './show-organizational-unit.component.css'
})
export class ShowOrganizationalUnitComponent {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
displayedColumns: string[] = ['property', 'value'];
generalData = [
{ property: 'Nombre', value: this.data.data.name },
{ property: 'Uuid', value: this.data.data.uuid },
{ property: 'Descripción', value: this.data.data.description },
{ property: 'Comentarios', value: this.data.data.comments },
{ property: 'Tipo', value: this.data.data.type },
{ property: 'Unidad organizativa superior', value: this.data.data.parent ? this.data.data.parent.name : '-' },
{ property: 'Creado por', value: this.data.data.createdBy },
{ property: 'Creado el', value: this.data.data.createdAt }
];
currentCalendar: any;
generalData: any[] = [];
networkData = [
{ property: 'Localización', value: this.data.data.location },
{ property: 'Proyector', value: this.data.data.projector ? 'Sí' : 'No' },
{ property: 'Pizzarra', value: this.data.data.board ? 'Sí' : 'No' },
{ property: 'Aforo', value: this.data.data.capacity },
{ property: 'Url servidor proxy', value: this.data.data.networkSettings ? this.data.data.networkSettings.proxy : '' },
{ property: 'IP DNS', value: this.data.data.networkSettings ? this.data.data.networkSettings.dns : '' },
{ property: 'Máscara de red', value: this.data.data.networkSettings ? this.data.data.networkSettings.netmask : '' },
{ property: 'Router', value: this.data.data.networkSettings ? this.data.data.networkSettings.router : '' },
{ property: 'NTP', value: this.data.data.networkSettings ? this.data.data.networkSettings.ntp : '' },
{ property: 'Modo p2p', value: this.data.data.networkSettings ? this.data.data.networkSettings.p2pMode : '' },
{ property: 'Tiempo p2p', value: this.data.data.networkSettings ? this.data.data.networkSettings.p2pTime : '' },
{ property: 'IP multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastIp : '' },
{ property: 'Modo multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastMode : '' },
{ property: 'Puerto multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastPort : '' },
{ property: 'Velocidad multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastSpeed : '' },
{ property: 'Perfil hardware', value: this.data.data.networkSettings && this.data.data.networkSettings.hardwareProfile ? this.data.data.networkSettings.hardwareProfile.description : '' },
{ property: 'Menú', value: this.data.data.networkSettings && this.data.data.networkSettings.menu ? this.data.data.networkSettings.menu.description : '' }
];
constructor(
@Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode
@Inject(MAT_DIALOG_DATA) public data: any,
private http: HttpClient
) {
console.log(this.data)
}
ngOnInit(): void {
if (this.data.data.remoteCalendar) {
this.loadCurrentCalendar(this.data.data.remoteCalendar.uuid);
} else {
this.initializeGeneralData();
}
}
loadCurrentCalendar(uuid: string): void {
const apiUrl = `${this.baseUrl}/remote-calendars/${uuid}`;
this.http.get<any>(apiUrl).subscribe(
response => {
this.currentCalendar = response.name;
this.initializeGeneralData();
},
error => {
console.error('Error loading current calendar', error);
this.initializeGeneralData();
}
);
}
initializeGeneralData(): void {
this.generalData = [
{ property: 'Nombre', value: this.data.data.name },
{ property: 'Uuid', value: this.data.data.uuid },
{ property: 'Descripción', value: this.data.data.description },
{ property: 'Comentarios', value: this.data.data.comments },
{ property: 'Tipo', value: this.data.data.type },
{ property: 'Unidad organizativa superior', value: this.data.data.parent ? this.data.data.parent.name : '-' },
{ property: 'Creado por', value: this.data.data.createdBy },
{ property: 'Creado el', value: this.data.data.createdAt },
{ property: 'Calendario asociado', value: this.data.data.remoteCalendar ? this.currentCalendar : '-' }
];
}
}