Added new tab in groups. Search client
commit
ab303ba76e
|
@ -1,12 +1,12 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing'; // Asegúrate de que está importado
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [
|
||||
RouterTestingModule
|
||||
RouterTestingModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
|
@ -20,16 +20,4 @@ describe('AppComponent', () => {
|
|||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have as title 'ogWebconsole'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('ogWebconsole');
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, ogWebconsole');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@ import { MatToolbarModule } from '@angular/material/toolbar';
|
|||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AdminComponent } from './components/admin/admin.component';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
|
@ -157,7 +157,7 @@ import { ClientTabViewComponent } from './components/groups/client-tab-view/clie
|
|||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatSidenavModule,
|
||||
BrowserAnimationsModule,
|
||||
NoopAnimationsModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatFormFieldModule,
|
||||
|
|
|
@ -1,23 +1,57 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { AdminComponent } from './admin.component';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { UsersComponent } from './admin.component';
|
||||
|
||||
describe('UsersComponent', () => {
|
||||
let component: UsersComponent;
|
||||
let fixture: ComponentFixture<UsersComponent>;
|
||||
describe('AdminComponent', () => {
|
||||
let component: AdminComponent;
|
||||
let fixture: ComponentFixture<AdminComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [UsersComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UsersComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
declarations: [AdminComponent],
|
||||
imports: [
|
||||
RouterTestingModule, // Importa RouterTestingModule para manejar routerLink
|
||||
MatButtonModule, // Importa MatButtonModule para botones
|
||||
MatIconModule // Importa MatIconModule para iconos
|
||||
]
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AdminComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges(); // Detecta cambios para renderizar el componente
|
||||
});
|
||||
|
||||
it('debería crear el componente', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('debería contener dos botones', () => {
|
||||
const buttons = fixture.debugElement.queryAll(By.css('button'));
|
||||
expect(buttons.length).toBe(2); // Verifica que hay dos botones
|
||||
});
|
||||
|
||||
it('el primer botón debería tener el texto "Usuarios"', () => {
|
||||
const firstButton = fixture.debugElement.query(By.css('.fab-button:first-child'));
|
||||
expect(firstButton.nativeElement.textContent).toContain('Usuarios'); // Verifica que el texto sea "Usuarios"
|
||||
});
|
||||
|
||||
it('el segundo botón debería tener el texto "Roles"', () => {
|
||||
const secondButton = fixture.debugElement.query(By.css('.fab-button:last-child'));
|
||||
expect(secondButton.nativeElement.textContent).toContain('Roles'); // Verifica que el texto sea "Roles"
|
||||
});
|
||||
|
||||
it('el primer botón debería tener el routerLink correcto', () => {
|
||||
const firstButton = fixture.debugElement.query(By.css('.fab-button:first-child'));
|
||||
expect(firstButton.nativeElement.getAttribute('ng-reflect-router-link')).toBe('/users'); // Verifica el routerLink
|
||||
});
|
||||
|
||||
it('el segundo botón debería tener el routerLink correcto', () => {
|
||||
const secondButton = fixture.debugElement.query(By.css('.fab-button:last-child'));
|
||||
expect(secondButton.nativeElement.getAttribute('ng-reflect-router-link')).toBe('/user-groups'); // Verifica el routerLink
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin',
|
||||
templateUrl: './admin.component.html',
|
||||
styleUrl: './admin.component.css'
|
||||
})
|
||||
|
||||
export class AdminComponent {
|
||||
|
||||
}
|
||||
|
||||
export class UsersComponent {
|
||||
}
|
||||
|
|
|
@ -1,17 +1,34 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { EditUserModalComponent } from './edit-user-modal.component';
|
||||
import { UserService } from '../users.service';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
describe('EditUserModalComponent', () => {
|
||||
let component: EditUserModalComponent;
|
||||
let fixture: ComponentFixture<EditUserModalComponent>;
|
||||
let dialogRefSpy: jasmine.SpyObj<MatDialogRef<EditUserModalComponent>>;
|
||||
let userServiceSpy: jasmine.SpyObj<UserService>;
|
||||
let toastServiceSpy: jasmine.SpyObj<ToastrService>;
|
||||
|
||||
beforeEach(async () => {
|
||||
dialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']);
|
||||
userServiceSpy = jasmine.createSpyObj('UserService', ['getUserGroups', 'getOrganizationalUnits']);
|
||||
toastServiceSpy = jasmine.createSpyObj('ToastrService', ['success', 'error']);
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [EditUserModalComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
declarations: [EditUserModalComponent],
|
||||
imports: [ReactiveFormsModule],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRefSpy },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: { user: { username: 'testUser', userGroups: [], allowedOrganizationalUnits: [] } } },
|
||||
{ provide: UserService, useValue: userServiceSpy },
|
||||
{ provide: ToastrService, useValue: toastServiceSpy }
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(EditUserModalComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UsersComponent } from './users.component';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { of } from 'rxjs';
|
||||
import { UserService } from './users.service';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core'; // Add this import for schema
|
||||
|
||||
// Create a mock for UserService
|
||||
class MockUserService {
|
||||
getUsers() {
|
||||
return of({
|
||||
'hydra:member': [
|
||||
{ id: 1, username: 'user1', allowedOrganizationalUnits: [], roles: ['admin'] },
|
||||
{ id: 2, username: 'user2', allowedOrganizationalUnits: [], roles: ['user'] }
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
describe('UsersComponent', () => {
|
||||
let component: UsersComponent;
|
||||
|
@ -8,7 +26,17 @@ describe('UsersComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [UsersComponent]
|
||||
declarations: [UsersComponent],
|
||||
imports: [
|
||||
MatTableModule,
|
||||
MatDialogModule,
|
||||
HttpClientTestingModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: UserService, useClass: MockUserService },
|
||||
{ provide: ToastrService, useValue: { success: () => {} } }, // Mock ToastrService
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA], // Use this to ignore unrecognized components in template
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
|
@ -20,4 +48,9 @@ describe('UsersComponent', () => {
|
|||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should load users on init', () => {
|
||||
component.ngOnInit();
|
||||
expect(component.dataSource.data.length).toBe(2); // Expect 2 mock users
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,6 +13,7 @@ import { ToastrService } from 'ngx-toastr';
|
|||
templateUrl: './users.component.html',
|
||||
styleUrls: ['./users.component.css']
|
||||
})
|
||||
|
||||
export class UsersComponent implements OnInit {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
dataSource = new MatTableDataSource<any>();
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
<input matInput [(ngModel)]="groupName" name="groupName" required />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Posición</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="position" name="position" required min="1" />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-slide-toggle [(ngModel)]="enabled" name="enabled">Habilitado</mat-slide-toggle>
|
||||
|
||||
<div class="command-selection">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
||||
@Component({
|
||||
|
@ -13,21 +13,28 @@ export class CreateCommandGroupComponent implements OnInit {
|
|||
availableCommands: any[] = [];
|
||||
selectedCommands: any[] = [];
|
||||
groupName: string = '';
|
||||
position: number = 1;
|
||||
enabled: boolean = true;
|
||||
editing: boolean = false;
|
||||
private apiUrl = 'http://127.0.0.1:8001/commands';
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private dialogRef: MatDialogRef<CreateCommandGroupComponent>,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadAvailableCommands();
|
||||
|
||||
if (this.data && this.data.group) {
|
||||
this.editing = true;
|
||||
this.loadGroupData(this.data.group);
|
||||
}
|
||||
}
|
||||
|
||||
loadAvailableCommands(): void {
|
||||
this.http.get<any>(`${this.baseUrl}/commands`).subscribe(
|
||||
this.http.get<any>(this.apiUrl).subscribe(
|
||||
(data) => {
|
||||
this.availableCommands = data['hydra:member'];
|
||||
},
|
||||
|
@ -37,6 +44,12 @@ export class CreateCommandGroupComponent implements OnInit {
|
|||
);
|
||||
}
|
||||
|
||||
loadGroupData(group: any): void {
|
||||
this.groupName = group.name;
|
||||
this.enabled = group.enabled;
|
||||
this.selectedCommands = group.commands;
|
||||
}
|
||||
|
||||
addCommand(command: any): void {
|
||||
this.selectedCommands.push(command);
|
||||
}
|
||||
|
@ -52,20 +65,31 @@ export class CreateCommandGroupComponent implements OnInit {
|
|||
const payload = {
|
||||
name: this.groupName,
|
||||
commands: this.selectedCommands.map(cmd => cmd['@id']),
|
||||
position: this.position,
|
||||
enabled: this.enabled
|
||||
};
|
||||
|
||||
console.log('Payload', payload);
|
||||
this.http.post(`${this.baseUrl}/command-groups`, payload).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Grupo de comandos creado con éxito');
|
||||
this.dialogRef.close();
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error creando el grupo de comandos', error);
|
||||
}
|
||||
});
|
||||
if (this.editing) {
|
||||
const groupId = this.data.group.uuid;
|
||||
this.http.patch(`http://127.0.0.1:8001/command-groups/${groupId}`, payload).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Grupo de comandos actualizado con éxito');
|
||||
this.dialogRef.close();
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error actualizando el grupo de comandos', error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.http.post('http://127.0.0.1:8001/command-groups', payload).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Grupo de comandos creado con éxito');
|
||||
this.dialogRef.close();
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error creando el grupo de comandos', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
|
|
|
@ -8,20 +8,14 @@
|
|||
<table mat-table [dataSource]="tasks" class="mat-elevation-z8">
|
||||
<!-- Nombre de la tarea -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Nombre </th>
|
||||
<td mat-cell *matCellDef="let task"> {{ task.name }} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Grupo de comandos -->
|
||||
<ng-container matColumnDef="commandGroup">
|
||||
<th mat-header-cell *matHeaderCellDef> Grupo de Comandos </th>
|
||||
<td mat-cell *matCellDef="let task"> {{ task.commandGroup.name }} </td>
|
||||
<th mat-header-cell *matHeaderCellDef> Creado por </th>
|
||||
<td mat-cell *matCellDef="let task"> {{ task.createdBy }} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Fecha de ejecución -->
|
||||
<ng-container matColumnDef="scheduledDate">
|
||||
<th mat-header-cell *matHeaderCellDef> Fecha de Ejecución </th>
|
||||
<td mat-cell *matCellDef="let task"> {{ task.scheduledDate | date:'short' }} </td>
|
||||
<td mat-cell *matCellDef="let task"> {{ task.dateTime | date:'short' }} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Estado -->
|
||||
|
|
|
@ -19,8 +19,8 @@ export class CommandsTaskComponent implements OnInit {
|
|||
itemsPerPage: number = 10;
|
||||
page: number = 1;
|
||||
pageSizeOptions: number[] = [5, 10, 20, 40, 100];
|
||||
displayedColumns: string[] = ['name', 'commandGroup', 'scheduledDate', 'enabled', 'actions'];
|
||||
private apiUrl = `${this.baseUrl}/tasks`;
|
||||
displayedColumns: string[] = ['name', 'scheduledDate', 'enabled', 'actions']; // Actualizado con las nuevas columnas
|
||||
private apiUrl = `${this.baseUrl}/command-tasks`;
|
||||
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {}
|
||||
|
||||
|
@ -33,6 +33,7 @@ export class CommandsTaskComponent implements OnInit {
|
|||
(data) => {
|
||||
this.tasks = data['hydra:member'];
|
||||
this.length = data['hydra:totalItems'];
|
||||
console.log('Tasks:', this.tasks);
|
||||
},
|
||||
(error) => {
|
||||
console.error('Error fetching tasks', error);
|
||||
|
@ -63,7 +64,7 @@ export class CommandsTaskComponent implements OnInit {
|
|||
deleteTask(task: any): void {
|
||||
this.dialog.open(DeleteModalComponent, {
|
||||
width: '300px',
|
||||
data: { name: task.name },
|
||||
data: { name: task.createdBy }, // Usamos 'createdBy' en lugar de 'name' ya que cambiaste la columna
|
||||
}).afterClosed().subscribe((result) => {
|
||||
if (result) {
|
||||
this.http.delete(`${this.apiUrl}/${task.uuid}`).subscribe({
|
||||
|
@ -80,7 +81,7 @@ export class CommandsTaskComponent implements OnInit {
|
|||
}
|
||||
|
||||
onPageChange(event: any): void {
|
||||
this.page = event.pageIndex;
|
||||
this.page = event.pageIndex + 1; // pageIndex es cero basado, así que sumamos 1
|
||||
this.itemsPerPage = event.pageSize;
|
||||
this.loadTasks();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<h2 mat-dialog-title>Crear Tarea</h2>
|
||||
|
||||
<mat-dialog-content [formGroup]="taskForm">
|
||||
<!-- Grupo de Comandos -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Selecciona Comandos</mat-label>
|
||||
<mat-select formControlName="commandGroup" (selectionChange)="onCommandGroupChange()">
|
||||
|
@ -20,6 +21,7 @@
|
|||
<mat-error *ngIf="taskForm.get('commandGroup')?.invalid">Este campo es obligatorio</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Mostrar Comandos del Grupo Seleccionado -->
|
||||
<div *ngIf="selectedGroupCommands.length > 0" class="commands-list">
|
||||
<h3>Comandos del Grupo Seleccionado</h3>
|
||||
<div *ngFor="let command of selectedGroupCommands" class="command-item">
|
||||
|
@ -27,6 +29,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Comandos Extras -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Selecciona Comandos Individuales (Opcional)</mat-label>
|
||||
<mat-select formControlName="extraCommands" multiple>
|
||||
<mat-option *ngFor="let command of availableIndividualCommands" [value]="command.uuid">
|
||||
{{ command.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Fecha de Ejecución -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Fecha de Ejecución</mat-label>
|
||||
<input matInput [matDatepicker]="picker" formControlName="date" placeholder="Selecciona una fecha">
|
||||
|
@ -35,12 +48,14 @@
|
|||
<mat-error *ngIf="taskForm.get('date')?.invalid">Este campo es obligatorio</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Hora de Ejecución -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Hora de Ejecución</mat-label>
|
||||
<input matInput type="time" formControlName="time" placeholder="Selecciona una hora">
|
||||
<mat-error *ngIf="taskForm.get('time')?.invalid">Este campo es obligatorio</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Notas -->
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Notas</mat-label>
|
||||
<textarea matInput formControlName="notes" placeholder="Opcional"></textarea>
|
||||
|
|
|
@ -1,23 +1,188 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CreateTaskComponent } from './create-task.component';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { of, throwError } from 'rxjs';
|
||||
|
||||
describe('CreateTaskComponent', () => {
|
||||
let component: CreateTaskComponent;
|
||||
let fixture: ComponentFixture<CreateTaskComponent>;
|
||||
let httpMock: HttpTestingController;
|
||||
let toastrService: jasmine.SpyObj<ToastrService>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const toastrSpy = jasmine.createSpyObj('ToastrService', ['success', 'error']);
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [CreateTaskComponent]
|
||||
imports: [ReactiveFormsModule, HttpClientTestingModule],
|
||||
declarations: [CreateTaskComponent],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: { close: jasmine.createSpy('close') } },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: {} },
|
||||
{ provide: ToastrService, useValue: toastrSpy },
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(CreateTaskComponent);
|
||||
component = fixture.componentInstance;
|
||||
httpMock = TestBed.inject(HttpTestingController);
|
||||
toastrService = TestBed.inject(ToastrService) as jasmine.SpyObj<ToastrService>;
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
httpMock.verify();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should initialize the form with default values', () => {
|
||||
expect(component.taskForm).toBeTruthy();
|
||||
expect(component.taskForm.get('commandGroup')?.value).toBe('');
|
||||
expect(component.taskForm.get('extraCommands')?.value).toEqual([]);
|
||||
expect(component.taskForm.get('date')?.value).toBe('');
|
||||
expect(component.taskForm.get('time')?.value).toBe('');
|
||||
expect(component.taskForm.get('notes')?.value).toBe('');
|
||||
});
|
||||
|
||||
it('should load command groups and set availableCommandGroups', () => {
|
||||
const mockCommandGroups = { 'hydra:member': [{ uuid: '1', name: 'Group 1' }, { uuid: '2', name: 'Group 2' }] };
|
||||
|
||||
component.loadCommandGroups();
|
||||
|
||||
const req = httpMock.expectOne(`${component.baseUrl}/command-groups`);
|
||||
expect(req.request.method).toBe('GET');
|
||||
req.flush(mockCommandGroups);
|
||||
|
||||
expect(component.availableCommandGroups.length).toBe(2);
|
||||
expect(component.availableCommandGroups).toEqual(mockCommandGroups['hydra:member']);
|
||||
});
|
||||
|
||||
it('should handle error when loading command groups', () => {
|
||||
component.loadCommandGroups();
|
||||
|
||||
const req = httpMock.expectOne(`${component.baseUrl}/command-groups`);
|
||||
req.flush('Error loading command groups', { status: 500, statusText: 'Server Error' });
|
||||
|
||||
expect(toastrService.error).toHaveBeenCalledWith('Error al cargar los grupos de comandos');
|
||||
});
|
||||
|
||||
it('should load individual commands and set availableIndividualCommands', () => {
|
||||
const mockCommands = { 'hydra:member': [{ uuid: '1', name: 'Command 1' }, { uuid: '2', name: 'Command 2' }] };
|
||||
|
||||
component.loadIndividualCommands();
|
||||
|
||||
const req = httpMock.expectOne(`${component.baseUrl}/commands`);
|
||||
expect(req.request.method).toBe('GET');
|
||||
req.flush(mockCommands);
|
||||
|
||||
expect(component.availableIndividualCommands.length).toBe(2);
|
||||
expect(component.availableIndividualCommands).toEqual(mockCommands['hydra:member']);
|
||||
});
|
||||
|
||||
it('should handle error when loading individual commands', () => {
|
||||
component.loadIndividualCommands();
|
||||
|
||||
const req = httpMock.expectOne(`${component.baseUrl}/commands`);
|
||||
req.flush('Error loading individual commands', { status: 500, statusText: 'Server Error' });
|
||||
|
||||
expect(toastrService.error).toHaveBeenCalledWith('Error al cargar los comandos individuales');
|
||||
});
|
||||
|
||||
it('should fetch selected group commands on command group change', () => {
|
||||
component.taskForm.patchValue({ commandGroup: '1' });
|
||||
|
||||
component.onCommandGroupChange();
|
||||
|
||||
const mockGroupCommands = { commands: [{ uuid: '1', name: 'Group Command 1' }, { uuid: '2', name: 'Group Command 2' }] };
|
||||
|
||||
const req = httpMock.expectOne(`${component.baseUrl}/command-groups/1`);
|
||||
expect(req.request.method).toBe('GET');
|
||||
req.flush(mockGroupCommands);
|
||||
|
||||
expect(component.selectedGroupCommands.length).toBe(2);
|
||||
expect(component.selectedGroupCommands).toEqual(mockGroupCommands.commands);
|
||||
});
|
||||
|
||||
it('should handle error when fetching group commands', () => {
|
||||
component.taskForm.patchValue({ commandGroup: '1' });
|
||||
component.onCommandGroupChange();
|
||||
|
||||
const req = httpMock.expectOne(`${component.baseUrl}/command-groups/1`);
|
||||
req.flush('Error loading group commands', { status: 500, statusText: 'Server Error' });
|
||||
|
||||
expect(toastrService.error).toHaveBeenCalledWith('Error al cargar los comandos del grupo seleccionado');
|
||||
});
|
||||
|
||||
it('should save the task successfully', () => {
|
||||
const mockFormData = {
|
||||
commandGroup: '1',
|
||||
extraCommands: ['1', '2'],
|
||||
date: '2024-09-27',
|
||||
time: '12:00',
|
||||
notes: 'Test notes'
|
||||
};
|
||||
|
||||
component.taskForm.setValue(mockFormData);
|
||||
|
||||
component.saveTask();
|
||||
|
||||
const expectedPayload = {
|
||||
commandGroups: ['/command-groups/1'],
|
||||
commands: ['/commands/1', '/commands/2'],
|
||||
dateTime: jasmine.any(String),
|
||||
notes: 'Test notes'
|
||||
};
|
||||
|
||||
const req = httpMock.expectOne(component.apiUrl);
|
||||
expect(req.request.method).toBe('POST');
|
||||
req.flush({}); // Mock successful response
|
||||
|
||||
expect(toastrService.success).toHaveBeenCalledWith('Tarea creada con éxito');
|
||||
expect(component.dialogRef.close).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should not save the task if form is invalid', () => {
|
||||
component.taskForm.setValue({
|
||||
commandGroup: '',
|
||||
extraCommands: [],
|
||||
date: '',
|
||||
time: '',
|
||||
notes: ''
|
||||
});
|
||||
|
||||
component.saveTask();
|
||||
|
||||
expect(toastrService.error).toHaveBeenCalledWith('Por favor, rellene todos los campos obligatorios');
|
||||
expect(component.dialogRef.close).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle error when saving the task', () => {
|
||||
const mockFormData = {
|
||||
commandGroup: '1',
|
||||
extraCommands: ['1'],
|
||||
date: '2024-09-27',
|
||||
time: '12:00',
|
||||
notes: 'Test notes'
|
||||
};
|
||||
|
||||
component.taskForm.setValue(mockFormData);
|
||||
component.saveTask();
|
||||
|
||||
const req = httpMock.expectOne(component.apiUrl);
|
||||
expect(req.request.method).toBe('POST');
|
||||
req.flush('Error creating task', { status: 500, statusText: 'Server Error' });
|
||||
|
||||
expect(toastrService.error).toHaveBeenCalledWith('Error al crear la tarea');
|
||||
});
|
||||
|
||||
it('should close the dialog', () => {
|
||||
component.close();
|
||||
expect(component.dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,17 +14,20 @@ export class CreateTaskComponent implements OnInit {
|
|||
taskForm: FormGroup;
|
||||
availableCommandGroups: any[] = [];
|
||||
selectedGroupCommands: any[] = [];
|
||||
availableIndividualCommands: any[] = [];
|
||||
apiUrl = `${this.baseUrl}/command-tasks`;
|
||||
editing: boolean = false; // Flag to check if in edit mode
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private http: HttpClient,
|
||||
private toastr: ToastrService,
|
||||
public dialogRef: MatDialogRef<CreateTaskComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
@Inject(MAT_DIALOG_DATA) public data: any // Inject the task data if editing
|
||||
) {
|
||||
this.taskForm = this.fb.group({
|
||||
commandGroup: ['', Validators.required],
|
||||
commandGroup: [''],
|
||||
extraCommands: [[]],
|
||||
date: ['', Validators.required],
|
||||
time: ['', Validators.required],
|
||||
notes: ['']
|
||||
|
@ -33,6 +36,13 @@ export class CreateTaskComponent implements OnInit {
|
|||
|
||||
ngOnInit(): void {
|
||||
this.loadCommandGroups();
|
||||
this.loadIndividualCommands();
|
||||
|
||||
// If task data is provided, load it into the form (edit mode)
|
||||
if (this.data && this.data.task) {
|
||||
this.editing = true;
|
||||
this.loadTaskData(this.data.task);
|
||||
}
|
||||
}
|
||||
|
||||
loadCommandGroups(): void {
|
||||
|
@ -46,6 +56,33 @@ export class CreateTaskComponent implements OnInit {
|
|||
);
|
||||
}
|
||||
|
||||
loadIndividualCommands(): void {
|
||||
this.http.get<any>(`${this.baseUrl}/commands`).subscribe(
|
||||
(data) => {
|
||||
this.availableIndividualCommands = data['hydra:member'];
|
||||
},
|
||||
(error) => {
|
||||
this.toastr.error('Error al cargar los comandos individuales');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
loadTaskData(task: any): void {
|
||||
// Populate form fields with task data when editing
|
||||
this.taskForm.patchValue({
|
||||
commandGroup: task.commandGroup ? task.commandGroup['@id'] : '',
|
||||
extraCommands: task.commands ? task.commands.map((cmd: any) => cmd['@id']) : [],
|
||||
date: task.dateTime ? task.dateTime.split('T')[0] : '',
|
||||
time: task.dateTime ? task.dateTime.split('T')[1].slice(0, 5) : '',
|
||||
notes: task.notes || ''
|
||||
});
|
||||
|
||||
// If a command group is selected, load its commands
|
||||
if (task.commandGroup) {
|
||||
this.selectedGroupCommands = task.commandGroup.commands;
|
||||
}
|
||||
}
|
||||
|
||||
onCommandGroupChange(): void {
|
||||
const selectedGroupId = this.taskForm.get('commandGroup')?.value;
|
||||
this.http.get<any>(`${this.baseUrl}/command-groups/${selectedGroupId}`).subscribe(
|
||||
|
@ -67,22 +104,41 @@ export class CreateTaskComponent implements OnInit {
|
|||
const formData = this.taskForm.value;
|
||||
const dateTime = this.combineDateAndTime(formData.date, formData.time);
|
||||
|
||||
const selectedCommands = formData.extraCommands.length > 0
|
||||
? formData.extraCommands.map((id: any) => `/commands/${id}`)
|
||||
: [""];
|
||||
|
||||
const payload = {
|
||||
commandGroups: '/command-groups/'+formData.commandGroup,
|
||||
commandGroups: [formData.commandGroup ? `/command-groups/${formData.commandGroup}` : [""]],
|
||||
commands: selectedCommands,
|
||||
dateTime: dateTime,
|
||||
notes: formData.notes || ''
|
||||
};
|
||||
console.log(payload);
|
||||
stop;
|
||||
this.http.post<any>(this.apiUrl, payload).subscribe({
|
||||
next: () => {
|
||||
this.toastr.success('Tarea creada con éxito');
|
||||
this.dialogRef.close(true);
|
||||
},
|
||||
error: () => {
|
||||
this.toastr.error('Error al crear la tarea');
|
||||
}
|
||||
});
|
||||
|
||||
if (this.editing) {
|
||||
// Perform a PATCH request if editing an existing task
|
||||
const taskId = this.data.task.uuid;
|
||||
this.http.patch<any>(`${this.apiUrl}/${taskId}`, payload).subscribe({
|
||||
next: () => {
|
||||
this.toastr.success('Tarea actualizada con éxito');
|
||||
this.dialogRef.close(true);
|
||||
},
|
||||
error: () => {
|
||||
this.toastr.error('Error al actualizar la tarea');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Perform a POST request if creating a new task
|
||||
this.http.post<any>(this.apiUrl, payload).subscribe({
|
||||
next: () => {
|
||||
this.toastr.success('Tarea creada con éxito');
|
||||
this.dialogRef.close(true);
|
||||
},
|
||||
error: () => {
|
||||
this.toastr.error('Error al crear la tarea');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
combineDateAndTime(date: string, time: string): string {
|
||||
|
@ -90,7 +146,7 @@ export class CreateTaskComponent implements OnInit {
|
|||
const [hours, minutes] = time.split(':').map(Number);
|
||||
|
||||
dateObj.setHours(hours, minutes, 0);
|
||||
return dateObj.toISOString(); // Return in ISO format (e.g., 2021-10-01T00:00:00+00:00)
|
||||
return dateObj.toISOString();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
|
||||
@Component({
|
||||
template: '<app-dashboard></app-dashboard>' // Use the component in a simple template
|
||||
})
|
||||
class TestHostComponent {}
|
||||
|
||||
describe('DashboardComponent', () => {
|
||||
let component: DashboardComponent;
|
||||
let fixture: ComponentFixture<DashboardComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [DashboardComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [DashboardComponent, TestHostComponent] // Declare the component
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DashboardComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
|
|
@ -1,19 +1,27 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { CreateClientComponent } from './create-client.component';
|
||||
|
||||
describe('CreateClientComponent', () => {
|
||||
let component: CreateClientComponent;
|
||||
let fixture: ComponentFixture<CreateClientComponent>;
|
||||
let dialogRefSpy: jasmine.SpyObj<MatDialogRef<CreateClientComponent>>;
|
||||
|
||||
beforeEach(async () => {
|
||||
dialogRefSpy = jasmine.createSpyObj('MatDialogRef', ['close']);
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [CreateClientComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
declarations: [CreateClientComponent],
|
||||
imports: [ReactiveFormsModule],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRefSpy }
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(CreateClientComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.data = { organizationalUnit: { '@id': '1' } };
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GroupsComponent } from './groups.component';
|
||||
|
||||
describe('GroupsComponent', () => {
|
||||
let component: GroupsComponent;
|
||||
let fixture: ComponentFixture<GroupsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [GroupsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GroupsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,6 +1,7 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { SaveFiltersDialogComponent } from './save-filters-dialog.component';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
describe('SaveFiltersDialogComponent', () => {
|
||||
let component: SaveFiltersDialogComponent;
|
||||
|
@ -8,9 +9,12 @@ describe('SaveFiltersDialogComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [SaveFiltersDialogComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [SaveFiltersDialogComponent],
|
||||
imports: [ReactiveFormsModule],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: { close: jasmine.createSpy('close') } }
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SaveFiltersDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
@ -20,4 +24,21 @@ describe('SaveFiltersDialogComponent', () => {
|
|||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should close dialog with null on cancel', () => {
|
||||
component.onCancel();
|
||||
expect(component.dialogRef.close).toHaveBeenCalledWith(null);
|
||||
});
|
||||
|
||||
it('should close dialog with filter name on save', () => {
|
||||
component.filterNameControl.setValue('Test Filter');
|
||||
component.onSave();
|
||||
expect(component.dialogRef.close).toHaveBeenCalledWith('Test Filter');
|
||||
});
|
||||
|
||||
it('should not close dialog if filter name is invalid', () => {
|
||||
component.filterNameControl.setValue('');
|
||||
component.onSave();
|
||||
expect(component.dialogRef.close).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TreeViewComponent } from './tree-view.component';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { NestedTreeControl } from '@angular/cdk/tree';
|
||||
import { MatTreeNestedDataSource } from '@angular/material/tree';
|
||||
|
||||
describe('TreeViewComponent', () => {
|
||||
let component: TreeViewComponent;
|
||||
|
@ -8,10 +10,13 @@ describe('TreeViewComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [TreeViewComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
declarations: [TreeViewComponent],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: { close: jasmine.createSpy('close') } },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: { data: {} } }
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(TreeViewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
@ -20,4 +25,35 @@ describe('TreeViewComponent', () => {
|
|||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should initialize tree data correctly', () => {
|
||||
const mockData = {
|
||||
id: 1,
|
||||
name: 'Root',
|
||||
type: 'organizational-unit',
|
||||
clients: [],
|
||||
children: []
|
||||
};
|
||||
|
||||
component.data = { data: mockData };
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.dataSource.data).toEqual([mockData]);
|
||||
});
|
||||
|
||||
it('should close the dialog', () => {
|
||||
// Using type assertion to access the private dialogRef
|
||||
(component as any).dialogRef.close(); // Cast to any to bypass TypeScript's private checks
|
||||
expect((component as any).dialogRef.close).toHaveBeenCalled(); // Again casting to any
|
||||
});
|
||||
|
||||
it('should determine if a node has children or clients', () => {
|
||||
const nodeWithChildren: any = { children: [{ id: 2, name: 'Child', type: 'classroom' }], clients: [] };
|
||||
const nodeWithClients: any = { children: [], clients: [{ id: 1, name: 'Client 1', ip: '192.168.0.1', mac: '00:00:00:00:00:01' }] };
|
||||
const nodeWithoutChildrenOrClients: any = { children: [], clients: [] };
|
||||
|
||||
expect(component.hasChild(0, nodeWithChildren)).toBeTrue();
|
||||
expect(component.hasChild(0, nodeWithClients)).toBeTrue();
|
||||
expect(component.hasChild(0, nodeWithoutChildrenOrClients)).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { ToastrModule } from 'ngx-toastr'; // Importa el módulo de Toastr
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; // Importa el módulo de animaciones
|
||||
import { MatFormFieldModule } from '@angular/material/form-field'; // Importa MatFormFieldModule
|
||||
import { MatInputModule } from '@angular/material/input'; // Importa MatInputModule
|
||||
import { MatIconModule } from '@angular/material/icon'; // Importa MatIconModule
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
|
@ -10,10 +14,17 @@ describe('LoginComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [LoginComponent],
|
||||
imports: [FormsModule],
|
||||
providers: [provideHttpClient(withInterceptorsFromDi())]
|
||||
})
|
||||
declarations: [LoginComponent],
|
||||
imports: [
|
||||
FormsModule,
|
||||
ToastrModule.forRoot(),
|
||||
BrowserAnimationsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatIconModule
|
||||
],
|
||||
providers: [provideHttpClient(withInterceptorsFromDi())]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { HttpInterceptorFn } from '@angular/common/http';
|
||||
|
||||
import { CustomInterceptor } from './custom.interceptor';
|
||||
|
||||
describe('customInterceptor', () => {
|
||||
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RouterModule } from '@angular/router'; // Import RouterModule
|
||||
import { AuthLayoutComponent } from './auth-layout.component';
|
||||
|
||||
describe('AuthLayoutComponent', () => {
|
||||
|
@ -8,10 +8,11 @@ describe('AuthLayoutComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [AuthLayoutComponent]
|
||||
declarations: [AuthLayoutComponent],
|
||||
imports: [RouterModule.forRoot([])] // Include RouterModule with an empty route
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
|
||||
fixture = TestBed.createComponent(AuthLayoutComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
|
|
@ -8,6 +8,7 @@ import {MatDialog} from "@angular/material/dialog";
|
|||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.css'],
|
||||
})
|
||||
|
||||
export class HeaderComponent implements OnInit {
|
||||
isSuperAdmin: boolean = false;
|
||||
|
||||
|
@ -44,9 +45,6 @@ export class HeaderComponent implements OnInit {
|
|||
data: { user: this.decodedToken.username, uuid: this.decodedToken.uuid },
|
||||
width: '400px',
|
||||
});
|
||||
/* dialogRef.componentInstance.userEdited.subscribe(() => {
|
||||
console.log("User edited successfully!")
|
||||
}); */
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue