Refactor groups component to update filter option value and add sync functionality
parent
aecc16c332
commit
e9b4411ea7
|
@ -22,33 +22,34 @@
|
|||
|
||||
<mat-expansion-panel *ngIf="isTreeViewActive" class="filters-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Filtros</mat-panel-title>
|
||||
<mat-panel-title>{{ 'filters' | translate }}</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div class="filters-container">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-select (selectionChange)="loadSelectedFilter($event.value)" placeholder="Cargar filtro">
|
||||
<mat-label>{{ 'searchClient' | translate }}</mat-label>
|
||||
<input matInput (input)="onClientFilterInput($event)" placeholder="Buscar nombre, IP, estado o MAC">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-select (selectionChange)="loadSelectedFilter($event.value)" placeholder="Cargar filtro" disabled>
|
||||
<mat-option *ngFor="let savedFilter of savedFilterNames" [value]="savedFilter">
|
||||
{{ savedFilter[0] }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Buscar en el árbol</mat-label>
|
||||
<input matInput (input)="onTreeFilterInput($event)" placeholder="Buscar nombre o tipo">
|
||||
<mat-label>{{ 'searchTree' | translate }}</mat-label>
|
||||
<input matInput (input)="onTreeFilterInput($event)" placeholder="Buscar nombre o tipo" disabled>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Filtrar por tipo</mat-label>
|
||||
<mat-select [(value)]="selectedTreeFilter" (selectionChange)="filterTree(searchTerm, $event.value)">
|
||||
<mat-option [value]="">Todos</mat-option>
|
||||
<mat-option value="classrooms-group">Grupos de aulas</mat-option>
|
||||
<mat-option value="classroom">Aulas</mat-option>
|
||||
<mat-option value="group">Grupos de ordenadores</mat-option>
|
||||
<mat-label>{{ 'filterByType' | translate }}</mat-label>
|
||||
<mat-select [(value)]="selectedTreeFilter" (selectionChange)="filterTree(searchTerm, $event.value)" disabled>
|
||||
<mat-option [value]=""> {{ 'all' | translate }} </mat-option>
|
||||
<mat-option value="classrooms-group">{{ 'classroomsGroup' | translate }}</mat-option>
|
||||
<mat-option value="classroom">{{ 'classrooms' | translate }}</mat-option>
|
||||
<mat-option value="group">{{ 'computerGroups' | translate }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Buscar cliente</mat-label>
|
||||
<input matInput (input)="onClientFilterInput($event)" placeholder="Buscar nombre, IP, estado o MAC">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
|
@ -166,7 +167,7 @@
|
|||
<mat-menu #menu="matMenu">
|
||||
<button *ngIf="selectedNode?.type === 'classroom'" mat-menu-item [matMenuTriggerFor]="commandMenu" (click)="fetchCommands()">
|
||||
<mat-icon>play_arrow</mat-icon>
|
||||
<span>Ejecutar Comando</span>
|
||||
<span>{{ 'executeCommand' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onShowDetailsClick($event, selectedNode)">
|
||||
<mat-icon matTooltip="{{ 'viewUnitTooltip' | translate }}" matTooltipHideDelay="0">visibility</mat-icon>
|
||||
|
@ -174,29 +175,29 @@
|
|||
</button>
|
||||
<button *ngIf="selectedNode?.type === 'classroom'" mat-menu-item (click)="onRoomMap(selectedNode)">
|
||||
<mat-icon>map</mat-icon>
|
||||
<span>Plano aula</span>
|
||||
<span>{{ 'roomMap' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="addClient($event, selectedNode)">
|
||||
<mat-icon>add</mat-icon>
|
||||
<span>Añadir clientes</span>
|
||||
<span>{{ 'addClientMenu' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="addOU($event, selectedNode)">
|
||||
<mat-icon>playlist_add</mat-icon>
|
||||
<span>Añadir unidad organizativa</span>
|
||||
<span>{{ 'addOrganizationalUnit' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onEditNode($event, selectedNode)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
<span>Edit</span>
|
||||
<span>{{ 'edit' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onDeleteClick($event, selectedNode)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>Delete</span>
|
||||
<span>{{ 'delete' | translate }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
<div class="clients-container" *ngIf="selectedClients.length > 0">
|
||||
<h3>Clientes {{ selectedNode?.name ? 'del ' + selectedNode?.name : '' }}</h3>
|
||||
<div class="clients-container" *ngIf="(selectedClients.data?.length || 0) > 0">
|
||||
<h3>{{ 'clients' | translate }} {{ selectedNode?.name ? ('del ' + selectedNode?.name) : '' }}</h3>
|
||||
<div class="clients-grid" *ngIf="currentView === 'card'">
|
||||
<div *ngFor="let client of selectedClients" class="client-item">
|
||||
<div *ngFor="let client of selectedClients.data" class="client-item">
|
||||
<div class="client-card">
|
||||
<img src="assets/images/client.png" alt="Client Icon" class="client-image" />
|
||||
<div class="client-details">
|
||||
|
@ -216,20 +217,20 @@
|
|||
<mat-menu #clientMenu="matMenu">
|
||||
<button mat-menu-item *ngIf="(!syncStatus || syncingClientId !== client.uuid)" (click)="getStatus(client)">
|
||||
<mat-icon>sync</mat-icon>
|
||||
<span>Sincronizar</span>
|
||||
<span>{{ 'sync' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button mat-menu-item (click)="onEditClick($event, client.type, client.uuid)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
<span>Edit</span>
|
||||
<span>{{ 'edit' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onShowClientDetail($event, client)">
|
||||
<mat-icon>visibility</mat-icon>
|
||||
<span>Ver detalles</span>
|
||||
<span>{{ 'viewDetails' | translate }}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="onDeleteClick($event, client, selectedNode)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>Delete</span>
|
||||
<span>{{ 'delete' | translate }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
@ -238,25 +239,25 @@
|
|||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
<div class="clients-table" *ngIf="currentView === 'list'">
|
||||
<table mat-table [dataSource]="selectedClients" class="mat-elevation-z8">
|
||||
<table mat-table matSort [dataSource]="selectedClients" class="mat-elevation-z8">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Nombre </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Nombre </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.name }} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="ip">
|
||||
<th mat-header-cell *matHeaderCellDef> IP </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> IP </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.ip }} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="mac">
|
||||
<th mat-header-cell *matHeaderCellDef> MAC </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> MAC </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.mac }} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="oglive">
|
||||
<th mat-header-cell *matHeaderCellDef> OG Live </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> OG Live </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.oglive }} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef> Estado </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Estado </th>
|
||||
<td mat-cell *matCellDef="let client">
|
||||
<mat-chip [ngClass]="{
|
||||
'chip-og-live': client.status === 'og-live',
|
||||
|
@ -271,19 +272,25 @@
|
|||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="maintenace">
|
||||
<th mat-header-cell *matHeaderCellDef> Mantenimiento </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Mantenimiento </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.mantenimiento }} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="subnet">
|
||||
<th mat-header-cell *matHeaderCellDef> Subred </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Subred </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.subnet }} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="pxeTemplate">
|
||||
<th mat-header-cell *matHeaderCellDef> Plantilla PXE </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Plantilla PXE </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.pxeTemplate }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="parentName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Padre </th>
|
||||
<td mat-cell *matCellDef="let client"> {{ client.parentName }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Acciones </th>
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Acciones </th>
|
||||
<td mat-cell *matCellDef="let client">
|
||||
<button mat-icon-button [matMenuTriggerFor]="clientMenu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
|
@ -310,8 +317,8 @@
|
|||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="['name', 'ip', 'mac', 'oglive', 'status', 'maintenace', 'subnet', 'pxeTemplate', 'actions']"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: ['name', 'ip', 'mac', 'oglive', 'status', 'maintenace', 'subnet', 'pxeTemplate', 'actions'];"></tr>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
|
|
|
@ -9,9 +9,8 @@ import { JoyrideService } from 'ngx-joyride';
|
|||
import { FlatTreeControl } from '@angular/cdk/tree';
|
||||
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { DataService } from './services/data.service';
|
||||
import { UnidadOrganizativa, Client, TreeNode, FlatNode, Command, Filter } from './model/model';
|
||||
import { UnidadOrganizativa, Client, TreeNode, FlatNode, Command } from './model/model';
|
||||
import { CreateOrganizationalUnitComponent } from './shared/organizational-units/create-organizational-unit/create-organizational-unit.component';
|
||||
import { CreateClientComponent } from './shared/clients/create-client/create-client.component';
|
||||
import { EditOrganizationalUnitComponent } from './shared/organizational-units/edit-organizational-unit/edit-organizational-unit.component';
|
||||
|
@ -23,6 +22,9 @@ import { ClientTabViewComponent } from './components/client-tab-view/client-tab-
|
|||
import { OrganizationalUnitTabViewComponent } from './components/organizational-unit-tab-view/organizational-unit-tab-view.component';
|
||||
import { DeleteModalComponent } from '../../shared/delete_modal/delete-modal/delete-modal.component';
|
||||
import { ClassroomViewDialogComponent } from './shared/classroom-view/classroom-view-modal';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
|
||||
enum NodeType {
|
||||
OrganizationalUnit = 'organizational-unit',
|
||||
|
@ -50,7 +52,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
selectedNode: TreeNode | null = null;
|
||||
commands: Command[] = [];
|
||||
commandsLoading = false;
|
||||
selectedClients: Client[] = [];
|
||||
selectedClients = new MatTableDataSource<Client>([]);
|
||||
cols = 4;
|
||||
selectedClientsOriginal: Client[] = [];
|
||||
currentView: 'card' | 'list' = 'list';
|
||||
|
@ -61,6 +63,28 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
syncingClientId: string | null = null;
|
||||
private originalTreeData: TreeNode[] = [];
|
||||
|
||||
|
||||
|
||||
displayedColumns: string[] = ['name', 'ip', 'mac', 'oglive', 'status', 'maintenace', 'subnet', 'pxeTemplate', 'parentName', 'actions'];
|
||||
|
||||
private _sort!: MatSort;
|
||||
private _paginator!: MatPaginator;
|
||||
|
||||
@ViewChild(MatSort)
|
||||
set matSort(ms: MatSort) {
|
||||
this._sort = ms;
|
||||
if (this.selectedClients) {
|
||||
this.selectedClients.sort = this._sort;
|
||||
}
|
||||
}
|
||||
|
||||
@ViewChild(MatPaginator)
|
||||
set matPaginator(mp: MatPaginator) {
|
||||
this._paginator = mp;
|
||||
if (this.selectedClients) {
|
||||
this.selectedClients.paginator = this._paginator;
|
||||
}
|
||||
}
|
||||
@ViewChild('clientTab') clientTabComponent!: ClientTabViewComponent;
|
||||
@ViewChild('organizationalUnitTab') organizationalUnitTabComponent!: OrganizationalUnitTabViewComponent;
|
||||
|
||||
|
@ -95,6 +119,16 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
this.getFilters();
|
||||
this.updateGridCols();
|
||||
window.addEventListener('resize', this.updateGridCols);
|
||||
|
||||
this.selectedClients.filterPredicate = (client: Client, filter: string): boolean => {
|
||||
const lowerTerm = filter.toLowerCase();
|
||||
return (
|
||||
client.name.toLowerCase().includes(lowerTerm) ||
|
||||
client.ip?.toLowerCase().includes(lowerTerm) ||
|
||||
client.status?.toLowerCase().includes(lowerTerm) ||
|
||||
client.mac?.toLowerCase().includes(lowerTerm)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
@ -124,7 +158,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
clearSelection(): void {
|
||||
this.selectedUnidad = null;
|
||||
this.selectedDetail = null;
|
||||
this.selectedClients = [];
|
||||
this.selectedClients.data = [];
|
||||
this.isTreeViewActive = false;
|
||||
}
|
||||
|
||||
|
@ -183,36 +217,46 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
onSelectUnidad(unidad: UnidadOrganizativa): void {
|
||||
this.selectedUnidad = unidad;
|
||||
this.selectedDetail = unidad;
|
||||
this.selectedClients = this.collectAllClients(unidad);
|
||||
this.selectedClientsOriginal = [...this.selectedClients];
|
||||
this.selectedClients.data = this.collectAllClients(unidad);
|
||||
this.selectedClientsOriginal = [...this.selectedClients.data];
|
||||
this.loadChildrenAndClients(unidad.id).then((fullData) => {
|
||||
const treeData = this.convertToTreeData(fullData);
|
||||
this.treeDataSource.data = treeData[0]?.children || [];
|
||||
});
|
||||
this.isTreeViewActive = true;
|
||||
|
||||
console.log('Selected unidad:', unidad);
|
||||
}
|
||||
|
||||
private collectAllClients(node: UnidadOrganizativa): Client[] {
|
||||
let clients = node.clients || [];
|
||||
let clients = (node.clients || []).map(client => ({
|
||||
...client,
|
||||
parentName: node.name
|
||||
}));
|
||||
|
||||
if (node.children) {
|
||||
node.children.forEach((child) => {
|
||||
clients = clients.concat(this.collectAllClients(child));
|
||||
clients = clients.concat(this.collectAllClients(child).map(client => ({
|
||||
...client,
|
||||
parentName: client.parentName || ''
|
||||
})));
|
||||
});
|
||||
}
|
||||
return clients;
|
||||
}
|
||||
|
||||
|
||||
private async loadChildrenAndClients(id: string): Promise<UnidadOrganizativa> {
|
||||
try {
|
||||
const childrenData = await this.dataService.getChildren(id).toPromise();
|
||||
|
||||
|
||||
const processHierarchy = (nodes: UnidadOrganizativa[]): UnidadOrganizativa[] => {
|
||||
return nodes.map((node) => ({
|
||||
...node,
|
||||
children: node.children ? processHierarchy(node.children) : [],
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
...this.selectedUnidad!,
|
||||
children: childrenData ? processHierarchy(childrenData) : [],
|
||||
|
@ -222,19 +266,19 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
return this.selectedUnidad!;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private convertToTreeData(data: UnidadOrganizativa): TreeNode[] {
|
||||
const processNode = (node: UnidadOrganizativa): TreeNode => ({
|
||||
name: node.name,
|
||||
type: node.type,
|
||||
'@id': node['@id'],
|
||||
children: node.children?.map(processNode) || [],
|
||||
hasClients: (node.clients?.length ?? 0) > 0,
|
||||
});
|
||||
return [processNode(data)];
|
||||
}
|
||||
|
||||
const processNode = (node: UnidadOrganizativa): TreeNode => ({
|
||||
name: node.name,
|
||||
type: node.type,
|
||||
'@id': node['@id'],
|
||||
children: node.children?.map(processNode) || [],
|
||||
hasClients: (node.clients?.length ?? 0) > 0,
|
||||
});
|
||||
return [processNode(data)];
|
||||
}
|
||||
|
||||
|
||||
onNodeClick(node: TreeNode): void {
|
||||
this.selectedNode = node;
|
||||
|
@ -246,8 +290,15 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
this.subscriptions.add(
|
||||
this.http.get<{ clients: Client[] }>(`${this.baseUrl}${node['@id']}`).subscribe(
|
||||
(data) => {
|
||||
this.selectedClientsOriginal = [...data.clients];
|
||||
this.selectedClients = data.clients || [];
|
||||
const clientsWithParentName = (data.clients || []).map(client => ({
|
||||
...client,
|
||||
parentName: node.name
|
||||
}));
|
||||
this.selectedClients.data = clientsWithParentName;
|
||||
this.selectedClients._updateChangeSubscription();
|
||||
if (this._paginator) {
|
||||
this._paginator.firstPage();
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.error('Error fetching clients:', error);
|
||||
|
@ -255,11 +306,11 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
);
|
||||
} else {
|
||||
this.selectedClients = [];
|
||||
this.selectedClientsOriginal = [];
|
||||
this.selectedClients.data = [];
|
||||
this.selectedClients._updateChangeSubscription();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getNodeIcon(node: TreeNode): string {
|
||||
switch (node.type) {
|
||||
case NodeType.OrganizationalUnit:
|
||||
|
@ -309,11 +360,11 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
this.organizationalUnits = data;
|
||||
if (this.selectedUnidad) {
|
||||
this.loadChildrenAndClients(this.selectedUnidad?.id || '').then((updatedData) => {
|
||||
this.selectedUnidad = updatedData;
|
||||
this.selectedUnidad = updatedData;
|
||||
const treeData = this.convertToTreeData(updatedData);
|
||||
this.originalTreeData = treeData[0]?.children || [];
|
||||
this.treeDataSource.data = [...this.originalTreeData];
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
(error) => console.error('Error fetching organizational units', error)
|
||||
|
@ -333,9 +384,9 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
onDeleteClick(event: MouseEvent, node: TreeNode | null, clientNode?: TreeNode | null): void{
|
||||
onDeleteClick(event: MouseEvent, node: TreeNode | null, clientNode?: TreeNode | null): void {
|
||||
event.stopPropagation();
|
||||
const uuid = node ? this.extractUuid(node['@id']) : null;
|
||||
const uuid = node ? this.extractUuid(node['@id']) : null;
|
||||
if (!uuid) return;
|
||||
|
||||
if (!node) return;
|
||||
|
@ -371,7 +422,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
|
||||
private refreshClientsForNode(node: TreeNode): void {
|
||||
if (!node['@id']) {
|
||||
this.selectedClients = [];
|
||||
this.selectedClients.data = [];
|
||||
return;
|
||||
}
|
||||
this.fetchClientsForNode(node);
|
||||
|
@ -420,7 +471,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
executeCommand(command: Command, selectedNode: TreeNode | null): void {
|
||||
|
||||
|
||||
if (!selectedNode) {
|
||||
this.toastr.error('No hay un nodo seleccionado.');
|
||||
return;
|
||||
|
@ -474,19 +525,19 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
const matchesName = node.name.toLowerCase().includes(searchTerm.toLowerCase());
|
||||
const matchesType = filterType ? node.type.toLowerCase() === filterType.toLowerCase() : true;
|
||||
const filteredChildren = node.children ? filterNodes(node.children) : [];
|
||||
|
||||
|
||||
if ((matchesName && matchesType) || filteredChildren.length > 0) {
|
||||
filteredNodes.push({ ...node, children: filteredChildren });
|
||||
}
|
||||
}
|
||||
return filteredNodes;
|
||||
};
|
||||
|
||||
|
||||
const filteredData = filterNodes(this.originalTreeData);
|
||||
this.treeDataSource.data = filteredData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
onTreeFilterInput(event: Event): void {
|
||||
const input = event.target as HTMLInputElement;
|
||||
|
@ -501,23 +552,11 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
filterClients(searchTerm: string): void {
|
||||
if (!searchTerm) {
|
||||
this.selectedClients = [...this.selectedClientsOriginal];
|
||||
return;
|
||||
}
|
||||
|
||||
const lowerTerm = searchTerm.toLowerCase();
|
||||
|
||||
this.selectedClients = this.selectedClientsOriginal.filter((client) => {
|
||||
return (
|
||||
client.name.toLowerCase().includes(lowerTerm) ||
|
||||
client.ip?.toLowerCase().includes(lowerTerm) ||
|
||||
client.status?.toLowerCase().includes(lowerTerm) ||
|
||||
client.mac?.toLowerCase().includes(lowerTerm)
|
||||
);
|
||||
});
|
||||
this.searchTerm = searchTerm.trim().toLowerCase();
|
||||
this.selectedClients.filter = this.searchTerm;
|
||||
}
|
||||
|
||||
|
||||
public setSelectedNode(node: TreeNode): void {
|
||||
this.selectedNode = node;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ export interface Client {
|
|||
createdAt: string;
|
||||
createdBy: string;
|
||||
uuid: string;
|
||||
parentName?: string;
|
||||
}
|
||||
|
||||
export interface ClientCollection {
|
||||
|
|
|
@ -420,5 +420,6 @@
|
|||
"TOOLTIP_MENUS": "Menu management (option disabled)",
|
||||
"search": "Search",
|
||||
"TOOLTIP_SEARCH": "Search function (option disabled)",
|
||||
"detailsOf": "Details of"
|
||||
"detailsOf": "Details of",
|
||||
"filters": "Filters"
|
||||
}
|
||||
|
|
|
@ -424,5 +424,21 @@
|
|||
"detailsOf": "Detalles de",
|
||||
"editUnitMenu": "Editar",
|
||||
"addInternalUnitMenu": "Añadir",
|
||||
"addClientMenu": "Añadir cliente"
|
||||
"addClientMenu": "Añadir cliente",
|
||||
"filters": "Filtros",
|
||||
"searchClient": "Buscar cliente",
|
||||
"searchTree": "Buscar en árbol",
|
||||
"filterByType": "Filtrar por tipo",
|
||||
"all": "Todos",
|
||||
"classroomsGroup": "Grupos de aulas",
|
||||
"classrooms": "Aulas",
|
||||
"computerGroups": "Grupos de PCs",
|
||||
"executeCommand": "Ejecutar comando",
|
||||
"roomMap": "Plano de aula",
|
||||
"addOrganizationalUnit": "Añadir unidad organizativa",
|
||||
"edit": "Editar",
|
||||
"delete": "Eliminar",
|
||||
"clients": "Clientes",
|
||||
"sync": "Sincronizar",
|
||||
"viewDetails": "Ver detalles"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue