Added new tab search in groups

pull/6/head
Manuel Aranda Rosales 2024-07-30 11:17:13 +02:00
parent e90316161c
commit 70c6ea59b1
5 changed files with 302 additions and 83 deletions

View File

@ -56,7 +56,7 @@ import { DeleteGroupsModalComponent } from './components/groups/delete-groups-mo
import { DragDropModule } from '@angular/cdk/drag-drop';
import { ToastrModule } from 'ngx-toastr';
import { ShowOrganizationalUnitComponent } from './components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component';
import { MatGridList } from "@angular/material/grid-list";
import {MatGridList, MatGridTile} from "@angular/material/grid-list";
import { TreeViewComponent } from './components/groups/tree-view/tree-view.component';
import {
MatNestedTreeNode,
@ -68,6 +68,7 @@ import {
} from "@angular/material/tree";
import { LegendComponent } from './components/groups/legend/legend.component';
import { ClassroomViewDialogComponent } from './components/groups/classroom-view/classroom-view-modal';
import {MatPaginator} from "@angular/material/paginator";
@NgModule({
declarations: [
@ -132,7 +133,7 @@ import { ClassroomViewDialogComponent } from './components/groups/classroom-view
progressAnimation: 'increasing',
closeButton: true
}
), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet
), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet, MatPaginator, MatGridTile
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA,

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {HttpClient, HttpParams} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { UnidadOrganizativa } from './model';
@ -10,7 +10,7 @@ import { UnidadOrganizativa } from './model';
export class DataService {
private apiUrl = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=1000';
private clientsUrl = 'http://127.0.0.1:8080/clients?page=1&itemsPerPage=30';
private clientsUrl = 'http://127.0.0.1:8080/clients?page=1&itemsPerPage=1000';
constructor(private http: HttpClient) {}
@ -107,5 +107,36 @@ export class DataService {
);
}
getFilteredResults(filter1: string, filter2: string, filterName: string, page: number, pageSize: number): Observable<any> {
let params = new HttpParams();
if (filter2 && filter2 !== 'none') {
params = params.set('type', filter2);
}
if (filterName) {
params = params.set('name', filterName);
}
params = params.set('page', page.toString());
params = params.set('itemsPerPage', pageSize.toString());
const url = filter1 === 'client' ? this.clientsUrl : this.apiUrl;
return this.http.get<any>(url, { params }).pipe(
map(response => {
if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
return {
results: response['hydra:member'],
total: response['hydra:totalItems'] || response['hydra:member'].length
};
} else {
throw new Error('Unexpected response format');
}
}),
catchError(error => {
console.error('Error fetching data', error);
return throwError(error);
})
);
}
}

View File

@ -131,3 +131,68 @@ mat-spinner {
.roomMap-btn {
}
.container {
display: flex;
flex-direction: column;
}
.header {
display: flex;
align-items: center;
gap: 10px;
padding: 20px;
}
.header mat-form-field {
width: 300px;
}
.main-content {
display: flex;
}
.filters {
padding: 20px;
display: flex;
flex-direction: column;
width: 300px;
}
.saved-filter {
display: flex;
flex-direction: column;
width: 300px;
margin-bottom: 10px;
padding: 10px;
}
.results {
width: 100%;
}
.results-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 16px;
margin-bottom: 16px;
}
.result-card {
width: 100%;
max-width: 250px;
height: 250px; /* Fijo para mantener la forma cuadrada */
}
.paginator-container {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
.divider {
margin: 20px 0;
}
mat-card {
margin-bottom: 20px;
}

View File

@ -1,11 +1,11 @@
<mat-tab-group>
<mat-tab label="General">
<div class="header-container">
<h2 class="title">Administrar grupos</h2>
<div class="groups-button-row">
<button mat-flat-button color="primary" (click)="addOU($event)">Nueva Unidad Organizativa</button>
<button mat-flat-button color="primary" (click)="addClient($event)">Nuevo Cliente</button>
<button mat-raised-button (click)="openBottomSheet()">Leyenda</button>
</div>
<div class="container">
<button mat-flat-button class="roomMap-btn" color="accent" (click)="roomMap()" *ngIf="selectedDetail && selectedDetail.type === 'classroom'">Plano de aula</button>
@ -85,7 +85,6 @@
</mat-list>
</mat-card-content>
</mat-card>
<mat-card class="card elements-card">
<mat-card-title>
<div class="title-with-breadcrumb">
@ -146,6 +145,84 @@
</mat-list>
</mat-card-content>
</mat-card>
<!-- <app-classroom-view class="card classroom-view" [clients]="clientsData" [pcInTable]="5"></app-classroom-view> -->
</div>
</mat-tab>
<mat-tab label="Búsqueda avanzada">
<h2 class="title">Búsqueda</h2>
<div class="container">
<div class="header">
<mat-form-field>
<mat-label>Seleccione filtro</mat-label>
<mat-select (selectionChange)="loadSelectedFilter($event.value)">
<mat-option *ngFor="let savedFilter of savedFilters" [value]="savedFilter">
{{ savedFilter.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-divider class="divider"></mat-divider>
<div class="main-content">
<div class="filters">
<mat-form-field>
<mat-label>Selecciona una opción</mat-label>
<mat-select [(value)]="selectedFilter1" (selectionChange)="applyFilter()">
<mat-option value="ou">Unidades organizativas</mat-option>
<mat-option value="client">Clientes</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="example-full-width">
<mat-label>Nombre</mat-label>
<input matInput placeholder="Unidad organizativa" (input)="applyFilter()" [(ngModel)]="filterName" >
</mat-form-field>
<mat-form-field disabled="selectedFilter1 === 'ou'">
<mat-label>Tipo de unidad </mat-label>
<mat-select [(value)]="selectedFilter2" (selectionChange)="applyFilter()">
<mat-option value="organizational-unit">Unidad organizativa</mat-option>
<mat-option value="classroom-group">Grupos de aulas</mat-option>
<mat-option value="classroom">Aulas</mat-option>
<mat-option value="client-group">Grupos de clientes</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>Select an option</mat-label>
<mat-select [(value)]="selectedFilter1" (selectionChange)="applyFilter()">
<mat-option value="none">None</mat-option>
<mat-option value="option1">Option 1</mat-option>
<mat-option value="option2">Option 2</mat-option>
<mat-option value="option3">Option 3</mat-option>
</mat-select>
</mat-form-field>
<button mat-raised-button color="primary" (click)="saveFilters()">Guardar Filtros</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">
<mat-card-title>{{ result.name }}</mat-card-title>
<mat-card-content>
<p>{{ result.type }}</p>
<p *ngIf="result.type !== 'client'">Unidades internas: {{ result.type !== 'client' ? result.children.length : 0}}</p>
<p *ngIf="result.type !== 'client'">Clientes: {{ result.type !== 'client' ? result.clients.length : 0}}</p>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
<div class="paginator-container">
<mat-paginator [length]="length"
[pageSize]="itemsPerPage"
[pageIndex]="page"
[pageSizeOptions]="pageSizeOptions"
(page)="onPageChange($event)">
</mat-paginator>
</div>
</ng-container>
<ng-template #noResults>
<p>No hay resultados para mostrar.</p>
</ng-template>
</div>
</div>
</div>
</mat-tab>
</mat-tab-group>

View File

@ -15,6 +15,9 @@ import {MatBottomSheet} from "@angular/material/bottom-sheet";
import {LegendComponent} from "./legend/legend.component";
import { ClassroomViewComponent } from './classroom-view/classroom-view.component';
import { ClassroomViewDialogComponent } from './classroom-view/classroom-view-modal';
import {HttpClient} from "@angular/common/http";
import {Observable} from "rxjs";
import {PageEvent} from "@angular/material/paginator";
@Component({
selector: 'app-groups',
@ -32,11 +35,22 @@ export class GroupsComponent implements OnInit {
loading:boolean = false;
loadingChildren:boolean = false;
searchTerm: string = '';
selectedFilter1: string = 'none';
selectedFilter2: string = 'none';
filterName: string = '';
filteredResults: any[] = [];
savedFilters: any[] = [];
length: number = 0;
itemsPerPage: number = 10;
page: number = 1;
pageSizeOptions: number[] = [5, 10, 25, 100];
constructor(
private dataService: DataService,
public dialog: MatDialog,
private toastService: ToastrService,
private _bottomSheet: MatBottomSheet
private _bottomSheet: MatBottomSheet,
private http: HttpClient
) {}
ngOnInit(): void {
@ -267,4 +281,35 @@ constructor(
});
}
}
applyFilter() {
this.dataService.getFilteredResults(this.selectedFilter1, this.selectedFilter2, this.filterName, this.page, this.itemsPerPage)
.subscribe(
response => {
this.filteredResults = response.results;
this.length = response.total;
},
error => {
console.error('Error al obtener los resultados filtrados', error);
this.filteredResults = [];
}
);
}
onPageChange(event: PageEvent) {
this.page = event.pageIndex;
this.itemsPerPage = event.pageSize;
this.applyFilter();
}
saveFilters() {
const filters = {
name: `Filter ${new Date().toISOString()}`,
filter1: this.selectedFilter1,
filter2: this.selectedFilter2
};
}
loadSelectedFilter(savedFilter: any) {
}
}