diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html
index 85c1ad6..f7aa9d2 100644
--- a/ogWebconsole/src/app/components/groups/groups.component.html
+++ b/ogWebconsole/src/app/components/groups/groups.component.html
@@ -22,33 +22,34 @@
- Filtros
+ {{ 'filters' | translate }}
-
+ {{ 'searchClient' | translate }}
+
+
+
+
{{ savedFilter[0] }}
- Buscar en el árbol
-
+ {{ 'searchTree' | translate }}
+
- Filtrar por tipo
-
- Todos
- Grupos de aulas
- Aulas
- Grupos de ordenadores
+ {{ 'filterByType' | translate }}
+
+ {{ 'all' | translate }}
+ {{ 'classroomsGroup' | translate }}
+ {{ 'classrooms' | translate }}
+ {{ 'computerGroups' | translate }}
-
- Buscar cliente
-
-
+
@@ -166,7 +167,7 @@
-
0">
-
Clientes {{ selectedNode?.name ? 'del ' + selectedNode?.name : '' }}
+
0">
+
{{ 'clients' | translate }} {{ selectedNode?.name ? ('del ' + selectedNode?.name) : '' }}
-
+
@@ -216,20 +217,20 @@
@@ -238,25 +239,25 @@
-
+
- Nombre |
+ Nombre |
{{ client.name }} |
- IP |
+ IP |
{{ client.ip }} |
- MAC |
+ MAC |
{{ client.mac }} |
- OG Live |
+ OG Live |
{{ client.oglive }} |
- Estado |
+ Estado |
- Mantenimiento |
+ Mantenimiento |
{{ client.mantenimiento }} |
- Subred |
+ Subred |
{{ client.subnet }} |
- Plantilla PXE |
+ Plantilla PXE |
{{ client.pxeTemplate }} |
+
+
+ Padre |
+ {{ client.parentName }} |
+
+
- Acciones |
+ Acciones |
|
-
-
+
+
|
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts
index 96cf096..8f57a06 100644
--- a/ogWebconsole/src/app/components/groups/groups.component.ts
+++ b/ogWebconsole/src/app/components/groups/groups.component.ts
@@ -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([]);
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 {
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;
}
diff --git a/ogWebconsole/src/app/components/groups/model/model.ts b/ogWebconsole/src/app/components/groups/model/model.ts
index 7789157..39f747a 100644
--- a/ogWebconsole/src/app/components/groups/model/model.ts
+++ b/ogWebconsole/src/app/components/groups/model/model.ts
@@ -44,6 +44,7 @@ export interface Client {
createdAt: string;
createdBy: string;
uuid: string;
+ parentName?: string;
}
export interface ClientCollection {
diff --git a/ogWebconsole/src/locale/en.json b/ogWebconsole/src/locale/en.json
index 59fe4cd..d73f805 100644
--- a/ogWebconsole/src/locale/en.json
+++ b/ogWebconsole/src/locale/en.json
@@ -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"
}
diff --git a/ogWebconsole/src/locale/es.json b/ogWebconsole/src/locale/es.json
index b13e8b4..eec7c10 100644
--- a/ogWebconsole/src/locale/es.json
+++ b/ogWebconsole/src/locale/es.json
@@ -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"
}