Updated groups. Added new ou tab

oggui/calendar
Manuel Aranda Rosales 2024-10-02 11:37:15 +02:00
parent 070aef716f
commit 2ec3731db7
8 changed files with 285 additions and 15 deletions

View File

@ -100,6 +100,7 @@ import { DetailTaskComponent } from './components/commands/commands-task/detail-
import { ClientTabViewComponent } from './components/groups/components/client-tab-view/client-tab-view.component';
import { AdvancedSearchComponent } from './components/groups/components/advanced-search/advanced-search.component';
import { TaskLogsComponent } from './components/commands/commands-task/task-logs/task-logs.component';
import { OrganizationalUnitTabViewComponent } from './components/groups/components/organizational-unit-tab-view/organizational-unit-tab-view.component';
@NgModule({
declarations: [
AppComponent,
@ -156,7 +157,8 @@ import { TaskLogsComponent } from './components/commands/commands-task/task-logs
DetailTaskComponent,
ClientTabViewComponent,
AdvancedSearchComponent,
TaskLogsComponent
TaskLogsComponent,
OrganizationalUnitTabViewComponent
],
bootstrap: [AppComponent],
imports: [BrowserModule,

View File

@ -45,10 +45,11 @@
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions">Acciones</th>
<td mat-cell *matCellDef="let client">
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
<td mat-cell *matCellDef="let client" style="text-align: center;">
<button mat-icon-button color="info" (click)="handleClientClick($event, client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
<button mat-icon-button color="primary" (click)="onEditClick($event, client.uuid)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
<button mat-icon-button (click)="onDeleteClick($event, client)">
<button mat-icon-button color="warn" (click)="onDeleteClick($event, client)">
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
</button>
</td>

View File

@ -11,6 +11,7 @@ import {CreateClientComponent} from "../../shared/clients/create-client/create-c
import {DeleteModalComponent} from "../../../../shared/delete_modal/delete-modal/delete-modal.component";
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import {ClientViewComponent} from "../../shared/client-view/client-view.component";
@Component({
selector: 'app-client-tab-view',
templateUrl: './client-tab-view.component.html',
@ -23,7 +24,7 @@ export class ClientTabViewComponent {
loading:boolean = false;
itemsPerPage: number = 10;
pageSizeOptions: number[] = [5, 10, 25, 100];
page: number = 1;
page: number = 0;
filters: { [key: string]: string } = {};
organizationalUnits: any[] = [];
datePipe: DatePipe = new DatePipe('es-ES');
@ -77,7 +78,7 @@ export class ClientTabViewComponent {
}
getClients() {
this.http.get<any>(`${this.apiUrl}?&page=${this.page}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
this.http.get<any>(`${this.apiUrl}?&page=${this.page + 1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
(data) => {
this.dataSource.data = data['hydra:member'];
this.length = data['hydra:totalItems'];
@ -123,6 +124,11 @@ export class ClientTabViewComponent {
});
}
handleClientClick(event: MouseEvent, client: any): void {
event.stopPropagation();
const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height:'700px' });
}
resetFilters() {
this.loading = true;
this.filters = {};

View File

@ -0,0 +1,36 @@
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
height: 100px;
padding: 10px;
margin-top: 16px;
}
.search-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 5px;
box-sizing: border-box;
}
.search-string {
flex: 1;
padding: 5px;
}
.search-boolean {
flex: 1;
padding: 5px;
}
.search-select {
flex: 2;
padding: 5px;
}
button{
margin-left: 10px;
}

View File

@ -0,0 +1,58 @@
<div class="header-container">
<h2 class="title" i18n="@@adminImagesTitle">Administrar unidades organizativas</h2>
<div class="images-button-row">
<button mat-flat-button color="primary" (click)="resetFilters()">Reiniciar filtros</button>
<button mat-flat-button color="primary" (click)="addOrganizationalUnit($event)">Añadir OU</button>
</div>
</div>
<mat-divider class="divider"></mat-divider>
<div class="search-container">
<mat-form-field appearance="fill" class="search-string">
<mat-label i18n="@@searchLabel">Buscar nombre de cliente</mat-label>
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
<mat-icon matSuffix>search</mat-icon>
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill" class="search-boolean">
<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]="'classroom'">Aula</mat-option>
<mat-option [value]="'clients-group'">Grupos de PCs</mat-option>
</mat-select>
</mat-form-field>
</div>
<table mat-table [dataSource]="dataSource">
<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) }}
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
<td mat-cell *matCellDef="let client" style="text-align: center;">
<button mat-icon-button color="info" (click)="onShowClick($event, client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
<button mat-icon-button color="primary" (click)="onEditClick($event, client.uuid)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
<button mat-icon-button color="warn" (click)="onDeleteClick($event, client)">
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<div class="paginator-container">
<mat-paginator [length]="length"
[pageSize]="itemsPerPage"
[pageIndex]="page"
[pageSizeOptions]="pageSizeOptions"
(page)="onPageChange($event)">
</mat-paginator>
</div>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OrganizationalUnitTabViewComponent } from './organizational-unit-tab-view.component';
describe('OrganizationalUnitTabViewComponent', () => {
let component: OrganizationalUnitTabViewComponent;
let fixture: ComponentFixture<OrganizationalUnitTabViewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [OrganizationalUnitTabViewComponent]
})
.compileComponents();
fixture = TestBed.createComponent(OrganizationalUnitTabViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,149 @@
import { Component } from '@angular/core';
import {MatTableDataSource} from "@angular/material/table";
import {DatePipe} from "@angular/common";
import {DataService} from "../client-tab-view/data.service";
import {MatDialog} from "@angular/material/dialog";
import {ToastrService} from "ngx-toastr";
import {HttpClient} from "@angular/common/http";
import {EditClientComponent} from "../../shared/clients/edit-client/edit-client.component";
import {CreateClientComponent} from "../../shared/clients/create-client/create-client.component";
import {DeleteModalComponent} from "../../../../shared/delete_modal/delete-modal/delete-modal.component";
import {catchError} from "rxjs/operators";
import {throwError} from "rxjs";
import {
CreateOrganizationalUnitComponent
} from "../../shared/organizational-units/create-organizational-unit/create-organizational-unit.component";
import {
ShowOrganizationalUnitComponent
} from "../../shared/organizational-units/show-organizational-unit/show-organizational-unit.component";
import {
EditOrganizationalUnitComponent
} from "../../shared/organizational-units/edit-organizational-unit/edit-organizational-unit.component";
@Component({
selector: 'app-organizational-unit-tab-view',
templateUrl: './organizational-unit-tab-view.component.html',
styleUrl: './organizational-unit-tab-view.component.css'
})
export class OrganizationalUnitTabViewComponent {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
dataSource = new MatTableDataSource<any>();
length: number = 0;
loading:boolean = false;
itemsPerPage: number = 10;
pageSizeOptions: number[] = [5, 10, 25, 100];
page: number = 0;
filters: { [key: string]: string } = {};
organizationalUnits: any[] = [];
datePipe: DatePipe = new DatePipe('es-ES');
private apiUrl = `${this.baseUrl}/organizational-units`;
columns = [
{
columnDef: 'id',
header: 'ID',
cell: (ou: any) => `${ou.id}`
},
{
columnDef: 'name',
header: 'Nombre',
cell: (ou: any) => `${ou.name}`
},
{
columnDef: 'type',
header: 'Tipo',
cell: (ou: any) => `${ou.type}`
},
{
columnDef: 'createdAt',
header: 'Fecha de creación',
cell: (ou: any) => `${this.datePipe.transform(ou.createdAt, 'dd/MM/yyyy hh:mm:ss')}`
}
];
displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];
constructor(
private dataService: DataService,
public dialog: MatDialog,
private toastService: ToastrService,
private http: HttpClient
) {}
ngOnInit(): void {
this.getOrganizationalUnits();
}
getOrganizationalUnits() {
this.http.get<any>(`${this.apiUrl}?&page=${this.page + 1}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
(data) => {
this.dataSource.data = data['hydra:member'];
this.length = data['hydra:totalItems'];
},
(error) => {
console.error('Error fetching commands', error);
}
);
}
onShowClick(event: MouseEvent, data: any): void {
event.stopPropagation();
if (data.type != "client") {
const dialogRef = this.dialog.open(ShowOrganizationalUnitComponent, { data: { data }, width: '700px'});
}
}
onEditClick(event: MouseEvent, uuid: string): void {
event.stopPropagation();
const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid }, width: '700px'});
dialogRef.afterClosed().subscribe(() => this.getOrganizationalUnits());
}
addOrganizationalUnit(event: MouseEvent, organizationalUnit:any = null): void {
event.stopPropagation();
const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent, { data: { organizationalUnit }, width: '900px'});
dialogRef.afterClosed().subscribe(() => {
this.getOrganizationalUnits();
});
}
onDeleteClick(event: MouseEvent, client: any): void {
event.stopPropagation();
const dialogRef = this.dialog.open(DeleteModalComponent, {
width: '400px'
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.http.delete<void>(`${this.apiUrl}/${client.uuid}`).pipe(
catchError(error => {
this.toastService.error(error.error['hydra:description']);
return throwError(error);
})
).subscribe(() => {
this.toastService.success('Elemento eliminado correctamente');
this.getOrganizationalUnits();
});
}
});
}
resetFilters() {
this.loading = true;
this.filters = {};
this.getOrganizationalUnits();
}
search(): void {
this.loading = true;
this.getOrganizationalUnits()
}
onPageChange(event: any): void {
this.page = event.pageIndex;
this.itemsPerPage = event.pageSize;
this.length = event.length;
this.getOrganizationalUnits();
}
}

View File

@ -29,15 +29,7 @@
[ngClass]="{'selected-item': unidad === selectedUnidad, 'clickable-item': true}" (click)="onSelectUnidad(unidad)">
<div class="item-content">
<mat-icon>apartment</mat-icon>
{{ breadcrumb.length === 0 ? unidad.name : null }}
<ng-container *ngIf="unidad === selectedUnidad">
<span class="breadcrumb">
<ng-container *ngFor="let crumb of breadcrumb; let i = index">
<a (click)="navigateToBreadcrumb(i)">{{ crumb }}</a>
<span *ngIf="i < breadcrumb.length - 1"> > </span>
</ng-container>
</span>
</ng-container>
{{ unidad.name }}
<span class="actions">
<mat-icon mat-button [matMenuTriggerFor]="menu" (click)="$event.stopPropagation()">more_vert</mat-icon>
<mat-menu #menu="matMenu">
@ -161,4 +153,7 @@
<mat-tab i18n-label label="Clientes">
<app-client-tab-view></app-client-tab-view>
</mat-tab>
<mat-tab i18n-label label="Unidades organizativas">
<app-organizational-unit-tab-view></app-organizational-unit-tab-view>
</mat-tab>
</mat-tab-group>