diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index d60b118..7d2e8fd 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -13,8 +13,8 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { CustomInterceptor } from './services/custom.interceptor'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; -import {MatToolbarModule} from '@angular/material/toolbar'; -import {MatIconModule} from '@angular/material/icon'; +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'; @@ -26,37 +26,37 @@ import { MatInputModule } from '@angular/material/input'; import { MatListModule } from '@angular/material/list'; import { UsersComponent } from './components/pages/admin/users/users/users.component'; import { RolesComponent } from './components/pages/admin/roles/roles/roles.component'; -import {MatTableModule} from '@angular/material/table'; -import {MatDialogModule} from '@angular/material/dialog'; +import { MatTableModule } from '@angular/material/table'; +import { MatDialogModule } from '@angular/material/dialog'; import { DeleteUserModalComponent } from './components/pages/admin/users/users/delete-user-modal/delete-user-modal.component'; import { AddUserModalComponent } from './components/pages/admin/users/users/add-user-modal/add-user-modal.component'; -import {MatSelectModule} from '@angular/material/select'; +import { MatSelectModule } from '@angular/material/select'; import { EditUserModalComponent } from './components/pages/admin/users/users/edit-user-modal/edit-user-modal.component'; import { AddRoleModalComponent } from './components/pages/admin/roles/roles/add-role-modal/add-role-modal.component'; import { DeleteRoleModalComponent } from './components/pages/admin/roles/roles/delete-role-modal/delete-role-modal.component'; import { ChangePasswordModalComponent } from './components/pages/admin/users/users/change-password-modal/change-password-modal.component'; import { GroupsComponent } from './components/groups/groups.component'; -import {MatDividerModule} from '@angular/material/divider'; +import { MatDividerModule } from '@angular/material/divider'; import { CreateOrganizationalUnitComponent } from './components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component'; -import {MatStepperModule} from '@angular/material/stepper'; +import { MatStepperModule } from '@angular/material/stepper'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { CreateClientComponent } from './components/groups/clients/create-client/create-client.component'; import { DeleteModalComponent } from './components/groups/delete-modal/delete-modal.component'; import { EditOrganizationalUnitComponent } from './components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component'; import { EditClientComponent } from './components/groups/clients/edit-client/edit-client.component'; import { ClassroomViewComponent } from './components/groups/classroom-view/classroom-view.component'; -import {MatProgressSpinner} from "@angular/material/progress-spinner"; -import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; -import {MatAutocomplete} from "@angular/material/autocomplete"; -import {MatChip, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule} from "@angular/material/chips"; +import { MatProgressSpinner } from "@angular/material/progress-spinner"; +import { MatMenu, MatMenuItem, MatMenuTrigger } from "@angular/material/menu"; +import { MatAutocomplete } from "@angular/material/autocomplete"; +import { MatChip, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule } from "@angular/material/chips"; import { ClientViewComponent } from './components/groups/client-view/client-view.component'; -import {MatTab, MatTabGroup} from "@angular/material/tabs"; -import {MatTooltip} from "@angular/material/tooltip"; +import { MatTab, MatTabGroup } from "@angular/material/tabs"; +import { MatTooltip } from "@angular/material/tooltip"; import { DeleteGroupsModalComponent } from './components/groups/delete-groups-modal/delete-groups-modal.component'; - +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 } from "@angular/material/grid-list"; import { TreeViewComponent } from './components/groups/tree-view/tree-view.component'; import { MatNestedTreeNode, @@ -67,38 +67,41 @@ import { MatTreeNodeToggle } from "@angular/material/tree"; import { LegendComponent } from './components/groups/legend/legend.component'; +import { ClassroomViewDialogComponent } from './components/groups/classroom-view/classroom-view-modal'; -@NgModule({ declarations: [ - AppComponent, - AuthLayoutComponent, - MainLayoutComponent, - HeaderComponent, - SidebarComponent, - LoginComponent, - AdminComponent, - MainLayoutComponent, - UsersComponent, - RolesComponent, - DeleteUserModalComponent, - AddUserModalComponent, - EditUserModalComponent, - AddRoleModalComponent, - DeleteRoleModalComponent, - ChangePasswordModalComponent, - GroupsComponent, - CreateOrganizationalUnitComponent, - CreateClientComponent, - DeleteModalComponent, - EditOrganizationalUnitComponent, - EditClientComponent, - ClassroomViewComponent, - ClientViewComponent, - DeleteGroupsModalComponent, - ShowOrganizationalUnitComponent, - TreeViewComponent, - LegendComponent - ], - bootstrap: [AppComponent], +@NgModule({ + declarations: [ + AppComponent, + AuthLayoutComponent, + MainLayoutComponent, + HeaderComponent, + SidebarComponent, + LoginComponent, + AdminComponent, + MainLayoutComponent, + UsersComponent, + RolesComponent, + DeleteUserModalComponent, + AddUserModalComponent, + EditUserModalComponent, + AddRoleModalComponent, + DeleteRoleModalComponent, + ChangePasswordModalComponent, + GroupsComponent, + CreateOrganizationalUnitComponent, + CreateClientComponent, + DeleteModalComponent, + EditOrganizationalUnitComponent, + EditClientComponent, + ClassroomViewComponent, + ClientViewComponent, + DeleteGroupsModalComponent, + ShowOrganizationalUnitComponent, + TreeViewComponent, + LegendComponent, + ClassroomViewDialogComponent + ], + bootstrap: [AppComponent], imports: [BrowserModule, AppRoutingModule, FormsModule, @@ -118,6 +121,7 @@ import { LegendComponent } from './components/groups/legend/legend.component'; MatSelectModule, MatDividerModule, MatStepperModule, + DragDropModule, MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip, ToastrModule.forRoot( { @@ -130,16 +134,17 @@ import { LegendComponent } from './components/groups/legend/legend.component'; } ), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA, - ], - providers: [ - { - provide: HTTP_INTERCEPTORS, - useClass: CustomInterceptor, - multi: true - }, - provideAnimationsAsync(), - provideHttpClient(withInterceptorsFromDi()) - ], }) + schemas: [ + CUSTOM_ELEMENTS_SCHEMA, + ], + providers: [ + { + provide: HTTP_INTERCEPTORS, + useClass: CustomInterceptor, + multi: true + }, + provideAnimationsAsync(), + provideHttpClient(withInterceptorsFromDi()) + ], +}) export class AppModule { } diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view-modal.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view-modal.ts new file mode 100644 index 0000000..760c666 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view-modal.ts @@ -0,0 +1,35 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA } from '@angular/material/dialog'; + +@Component({ + selector: 'app-classroom-view-dialog', + template: ` +

Plano de {{ classroomName }}

+ + + + `, + styles: [` + mat-dialog-content { + overflow: hidden; + } + `] +}) +export class ClassroomViewDialogComponent { + classroomName: string | undefined; + + constructor(@Inject(MAT_DIALOG_DATA) public data: any) { + console.log('ClassroomViewDialogComponent'); + console.log(data); + } + ngOnInit() { + if (this.data.clients && this.data.clients.length > 0) { + this.classroomName = this.data.clients[0].organizationalUnit.name; + } else { + this.classroomName = 'N/A'; + } + } + + + +} diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index a03bf1c..de8a3a0 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -2,7 +2,8 @@ display: flex; flex-wrap: wrap; gap: 10px; - min-height: 43vh; + height: 90%; + border: 3px solid black; } .classroom-group { @@ -26,7 +27,7 @@ mat-card { .proyector-image { width: auto; - height: 100px; /* Ajusta la altura según sea necesario */ + height: 100px; } .client-info { @@ -37,8 +38,8 @@ mat-card { height: 100%; display: flex; flex-direction: column; - background-color: rgba(0, 0, 0, 0); /* Fondo semitransparente para el texto */ - color: black; /* Color del texto */ + background-color: rgba(0, 0, 0, 0); + color: black; text-align: center; padding: 10px; box-sizing: border-box; @@ -121,7 +122,7 @@ mat-chip { align-items: center; justify-content: center; text-align: center; - margin-right: 20px; /* Espacio entre la pizarra y el proyector */ + margin-right: 20px; } .misc-clients { @@ -130,3 +131,7 @@ mat-chip { justify-content: center; margin-bottom: 25px; } + +.saveDisposition-btn{ + margin-top: 10px; +} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html index 617043b..8f75087 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -1,13 +1,14 @@ +
- Clientes dentro de: {{ group.organizationalUnitName }}
-
Pizarra digital
- Proyector +
Pizarra digital
+ Proyector
-
-
+
+
Client @@ -24,3 +25,4 @@
+ diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts index 4689922..0889dc2 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts @@ -1,6 +1,9 @@ -import { Component, Input, OnInit } from '@angular/core'; -import {MatDialog} from "@angular/material/dialog"; -import {ClientViewComponent} from "../client-view/client-view.component"; +import { Component, Input, OnInit, OnChanges } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ClientViewComponent } from "../client-view/client-view.component"; +import { CdkDragMove } from '@angular/cdk/drag-drop'; +import { HttpClient } from '@angular/common/http'; +import { ToastrService } from 'ngx-toastr'; interface GroupedClients { organizationalUnitName: string; @@ -12,19 +15,23 @@ interface GroupedClients { templateUrl: './classroom-view.component.html', styleUrls: ['./classroom-view.component.css'] }) -export class ClassroomViewComponent implements OnInit { +export class ClassroomViewComponent implements OnInit, OnChanges { + @Input() clients: any[] = []; @Input() pcInTable: number = 5; groupedClients: GroupedClients[] = []; - constructor(public dialog: MatDialog) {} + constructor(public dialog: MatDialog, private http: HttpClient, private toastService: ToastrService) {} + ngOnInit(): void { this.groupClientsByOrganizationalUnit(); + this.initializeClientPositions(); } ngOnChanges(): void { this.groupClientsByOrganizationalUnit(); + this.initializeClientPositions(); } groupClientsByOrganizationalUnit(): void { @@ -41,8 +48,21 @@ export class ClassroomViewComponent implements OnInit { organizationalUnitName: ouName, clientRows: this.chunkArray(grouped[ouName], this.pcInTable) })); + console.log(this.groupedClients); } + initializeClientPositions(): void { + this.groupedClients.forEach(group => { + group.clientRows.forEach(row => { + row.forEach(client => { + const position = client.position || { x: 0, y: 0 }; + client.dragPosition = { x: position.x, y: position.y }; + }); + }); + }); + } + + chunkArray(arr: any[], chunkSize: number): any[][] { const chunks = []; for (let i = 0; i < arr.length; i += chunkSize) { @@ -52,6 +72,40 @@ export class ClassroomViewComponent implements OnInit { } handleClientClick(client: any): void { - const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height:'700px'}); + const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height:'700px' }); + } + + onDragMoved(event: CdkDragMove, client: any): void { + const dragPosition = event.source.getFreeDragPosition() + client.position.x = dragPosition.x; + client.position.y = dragPosition.y; + } + + saveDisposition(): void { + this.groupedClients.forEach(group => { + group.clientRows.forEach(row => { + row.forEach(client => { + const url = `http://127.0.0.1:8080/clients/${client.uuid}`; + const payload = { + name: client.name, + position: client.position + }; + this.http.patch(url, payload).subscribe(response => { + console.log('Cliente actualizado:', response); + this.openSnackBar(false, 'Plano actualizado!'); + }, error => { + console.error('Error al actualizar cliente:', error); + this.openSnackBar(true, error); + }); + }); + }); + }); + } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al actualizar cliente: ' + message, 'Error'); + } else + this.toastService.success('Cliente actualizado!', 'Éxito'); } } diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 3ceb1dd..a406e9b 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -121,3 +121,13 @@ mat-spinner { margin: 0 auto; align-self: center; } + + +.container { /* Asegúrate de que esta clase sea la del contenedor del botón */ + display: flex; + justify-content: flex-end; +} + +.roomMap-btn { +} + diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 541d2cc..8226e41 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -4,7 +4,12 @@ + +
+
+ +
@@ -142,5 +147,5 @@ - +
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index e68d3d6..c68ba3d 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -13,6 +13,8 @@ import {ToastrService} from "ngx-toastr"; import {TreeViewComponent} from "./tree-view/tree-view.component"; 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'; @Component({ selector: 'app-groups', @@ -251,4 +253,18 @@ constructor( openBottomSheet(): void { this._bottomSheet.open(LegendComponent); } + + roomMap(): void { + if (this.selectedDetail && this.selectedDetail.type === 'classroom') { + const dialogRef = this.dialog.open(ClassroomViewDialogComponent, { + width: '90vw', + height: '90vh', + data: { clients: this.clientsData } + }); + + dialogRef.afterClosed().subscribe(result => { + console.log('The dialog was closed'); + }); + } + } }