| @@ -5,11 +5,11 @@ export const alarmData = [ | |||
| position: 'Hanoi', | |||
| coordinates: { | |||
| lat: 21.0285, | |||
| lng: 105.8542 | |||
| lng: 105.8542, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: true | |||
| warning: true, | |||
| }, | |||
| { | |||
| title: ' Alarm System 2', | |||
| @@ -17,23 +17,23 @@ export const alarmData = [ | |||
| position: 'Hai Phong', | |||
| coordinates: { | |||
| lat: 20.8449, | |||
| lng: 106.6881 | |||
| lng: 106.6881, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: true | |||
| warning: true, | |||
| }, | |||
| { | |||
| title: ' Alarm System 3', | |||
| detail: { | |||
| position: 'Ha Long', | |||
| coordinates: { | |||
| lat: 20.9460, | |||
| lng: 107.0740 | |||
| lat: 20.946, | |||
| lng: 107.074, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: false | |||
| warning: false, | |||
| }, | |||
| { | |||
| title: ' Alarm System 4', | |||
| @@ -41,11 +41,11 @@ export const alarmData = [ | |||
| position: 'Vinh', | |||
| coordinates: { | |||
| lat: 18.6796, | |||
| lng: 105.6813 | |||
| lng: 105.6813, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: true | |||
| warning: true, | |||
| }, | |||
| { | |||
| title: ' Alarm System 5', | |||
| @@ -53,11 +53,11 @@ export const alarmData = [ | |||
| position: 'Dong Hoi', | |||
| coordinates: { | |||
| lat: 17.4834, | |||
| lng: 106.6000 | |||
| lng: 106.6, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: false | |||
| warning: false, | |||
| }, | |||
| { | |||
| title: ' Alarm System 6', | |||
| @@ -65,11 +65,11 @@ export const alarmData = [ | |||
| position: 'Hue', | |||
| coordinates: { | |||
| lat: 16.4637, | |||
| lng: 107.5909 | |||
| lng: 107.5909, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: true | |||
| warning: true, | |||
| }, | |||
| { | |||
| title: ' Alarm System 7', | |||
| @@ -77,23 +77,23 @@ export const alarmData = [ | |||
| position: 'Da Nang', | |||
| coordinates: { | |||
| lat: 16.0471, | |||
| lng: 108.2068 | |||
| lng: 108.2068, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: false | |||
| warning: false, | |||
| }, | |||
| { | |||
| title: ' Alarm System 8', | |||
| detail: { | |||
| position: 'Quy Nhon', | |||
| coordinates: { | |||
| lat: 13.7820, | |||
| lng: 109.2198 | |||
| lat: 13.782, | |||
| lng: 109.2198, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: false | |||
| warning: false, | |||
| }, | |||
| { | |||
| title: ' Alarm System 9', | |||
| @@ -101,11 +101,11 @@ export const alarmData = [ | |||
| position: 'Nha Trang', | |||
| coordinates: { | |||
| lat: 12.2388, | |||
| lng: 109.1967 | |||
| lng: 109.1967, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: true | |||
| warning: true, | |||
| }, | |||
| { | |||
| title: ' Alarm System 10', | |||
| @@ -113,11 +113,11 @@ export const alarmData = [ | |||
| position: 'Da Lat', | |||
| coordinates: { | |||
| lat: 11.9416, | |||
| lng: 108.4580 | |||
| lng: 108.458, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: false | |||
| warning: false, | |||
| }, | |||
| { | |||
| title: ' Alarm System 11', | |||
| @@ -125,11 +125,11 @@ export const alarmData = [ | |||
| position: 'Ho Chi Minh City', | |||
| coordinates: { | |||
| lat: 10.8231, | |||
| lng: 106.6297 | |||
| lng: 106.6297, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: false | |||
| warning: false, | |||
| }, | |||
| { | |||
| title: ' Alarm System 12', | |||
| @@ -137,23 +137,85 @@ export const alarmData = [ | |||
| position: 'Can Tho', | |||
| coordinates: { | |||
| lat: 10.0452, | |||
| lng: 105.7469 | |||
| lng: 105.7469, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| warning: true | |||
| warning: true, | |||
| }, | |||
| ]; | |||
| export const alarmDemo = { | |||
| title: ' Demo Alarm System', // Thêm mới warning | |||
| export const alarmDemo = { | |||
| title: ' Demo Alarm System', // Thêm mới warning | |||
| detail: { | |||
| position: 'Vinhomes Quận 9', | |||
| coordinates: { | |||
| lat: 10.7483, | |||
| lng: 106.8016 | |||
| lng: 106.8016, | |||
| }, | |||
| time: '06-07-2024' | |||
| time: '06-07-2024', | |||
| }, | |||
| } | |||
| }; | |||
| export const atmWarningData = [ | |||
| { | |||
| id: 'ward-15', | |||
| title: 'Vibration warning', | |||
| detail: { | |||
| position: 'Phuong 15, District 5, Ho Chi Minh City', | |||
| coordinates: { | |||
| lat: 10.7601, | |||
| lng: 106.6603, | |||
| }, | |||
| time: '26/08/2024 12:14', | |||
| }, | |||
| }, | |||
| { | |||
| id: 'ward-11', | |||
| title: 'Demo Atm System', | |||
| detail: { | |||
| position: 'Phuong 11, District 5, Ho Chi Minh City', | |||
| coordinates: { | |||
| lat: 10.7561, | |||
| lng: 106.6678, | |||
| }, | |||
| time: '26/08/2024 10:14', | |||
| }, | |||
| }, | |||
| { | |||
| id: 'ward-9', | |||
| title: 'Demo Atm System', | |||
| detail: { | |||
| position: 'Phuong 9, District 5, Ho Chi Minh City', | |||
| coordinates: { | |||
| lat: 10.7586, | |||
| lng: 106.6684, | |||
| }, | |||
| time: '25/08/2024 12:14', | |||
| }, | |||
| }, | |||
| { | |||
| id: 'ward-1', | |||
| title: 'Vibration warning', | |||
| detail: { | |||
| position: 'Phuong 1, District 5, Ho Chi Minh City', | |||
| coordinates: { | |||
| lat: 10.7596, | |||
| lng: 106.6665, | |||
| }, | |||
| time: '25/08/2024 12:14', | |||
| }, | |||
| }, | |||
| { | |||
| id: 'ward-2', | |||
| title: 'Vibration warning', | |||
| detail: { | |||
| position: 'Phuong 2, District 5, Ho Chi Minh City', | |||
| coordinates: { | |||
| lat: 10.7608, | |||
| lng: 106.6624, | |||
| }, | |||
| time: '25/08/2024 12:14', | |||
| }, | |||
| }, | |||
| ]; | |||
| @@ -5,7 +5,9 @@ | |||
| <div class="state t2" id="State2"> | |||
| <div fxLayout="row"> | |||
| <div class="sensor-off" [class.sensor-on]="(state1 && state5 && status1)"> | |||
| <img [src]="(state5 && status1) ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" style="width: 30px; height: 30px"> | |||
| <img [src]="(state5 && status1) ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" | |||
| style="width: 30px; height: 30px; cursor: pointer" | |||
| (click)="openPositionDialog($event, 'ward-11')"> | |||
| </div> | |||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||
| </div> | |||
| @@ -16,7 +18,9 @@ | |||
| <div class="state t3" id="State3"> | |||
| <div fxLayout="row"> | |||
| <div class="sensor-off" [class.sensor-on]="(state2 && state5 && status2)"> | |||
| <img [src]="(state5 && status2) ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" style="width: 30px; height: 30px"> | |||
| <img [src]="(state5 && status2) ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" | |||
| style="width: 30px; height: 30px; cursor: pointer" | |||
| (click)="openPositionDialog($event, 'ward-9')"> | |||
| </div> | |||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||
| </div> | |||
| @@ -24,15 +28,18 @@ | |||
| [ngClass]="{'alarm-text-on': (state2 && state5 && status2) }">VIBRATION ALARM</div> | |||
| </div> | |||
| <div class="state t4" id="State4" fxLayout="row" > | |||
| <img [src]="getImageSource()" style="width: 30px; height: 30px"> | |||
| <img [src]="getImageSource()" style="width: 30px; height: 30px; cursor: pointer" | |||
| (click)="openPositionDialog($event, 'ward-2')"> | |||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||
| </div> | |||
| <div class="state t5 tooltip" id="State5" fxLayout="row"> | |||
| <img [src]="getImageSource()" style="width: 30px; height: 30px"> | |||
| <img [src]="getImageSource()" style="width: 30px; height: 30px; cursor: pointer" | |||
| (click)="openPositionDialog($event, 'ward-1')"> | |||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||
| </div> | |||
| <div class="state t6 tooltip" id="State6" fxLayout="row"> | |||
| <img [src]="getImageSource()" style="width: 30px; height: 30px"> | |||
| <img [src]="getImageSource()" style="width: 30px; height: 30px; cursor: pointer" | |||
| (click)="openPositionDialog($event, 'ward-15')"> | |||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||
| </div> | |||
| @@ -1,22 +1,23 @@ | |||
| import {Component, OnDestroy, OnInit} from '@angular/core'; | |||
| import {debounceTime, filter, Subject, Subscription} from "rxjs"; | |||
| import {SocketService} from "../../../shared/services/socket.service"; | |||
| import {CameraDialogComponent} from "../../../shared/component/camera-dialog/camera-dialog.component"; | |||
| import {MatDialog} from "@angular/material/dialog"; | |||
| import { ConfirmDialogService } from '../../../shared/services/confirm-dialog.service'; | |||
| import { AlarmSoundService } from "../../../shared/services/alarm-sound.service"; | |||
| import {MatTableDataSource} from "@angular/material/table"; | |||
| import { Component, OnDestroy, OnInit } from '@angular/core'; | |||
| import { Subject } from 'rxjs'; | |||
| import { CameraDialogComponent } from '../../../shared/component/camera-dialog/camera-dialog.component'; | |||
| import { MatDialog } from '@angular/material/dialog'; | |||
| import { AlarmSoundService } from '../../../shared/services/alarm-sound.service'; | |||
| import { MatTableDataSource } from '@angular/material/table'; | |||
| import { DetailPositionDialogComponent } from '../../../shared/component/detail-postion-dialog/detail-position-dialog.component'; | |||
| import { atmWarningData } from '../data/fake-data'; | |||
| const ELEMENT_DATA: any[] = [ | |||
| {title: 'Vibration warning Phường 15', date: '26/08/2024 12:14'}, | |||
| {title: 'Fire warning Phường 11', date: '26/08/2024 10:14'}, | |||
| {title: 'Fire warning Phường 9', date: '25/08/2024 12:14'}, | |||
| {title: 'Vibration warning Phường 1', date: '25/08/2024 12:14'}, | |||
| {title: 'Vibration warning Phường 2', date: '25/08/2024 12:14'}, | |||
| { title: 'Vibration warning Phường 15', date: '26/08/2024 12:14' }, | |||
| { title: 'Fire warning Phường 11', date: '26/08/2024 10:14' }, | |||
| { title: 'Fire warning Phường 9', date: '25/08/2024 12:14' }, | |||
| { title: 'Vibration warning Phường 1', date: '25/08/2024 12:14' }, | |||
| { title: 'Vibration warning Phường 2', date: '25/08/2024 12:14' }, | |||
| ]; | |||
| @Component({ | |||
| selector: 'app-security-atm-details', | |||
| templateUrl: './security-atm-details.component.html', | |||
| styleUrls: ['./security-atm-details.component.scss'] | |||
| styleUrls: ['./security-atm-details.component.scss'], | |||
| }) | |||
| export class SecurityAtmDetailsComponent implements OnInit, OnDestroy { | |||
| isConnected = false; | |||
| @@ -31,11 +32,10 @@ export class SecurityAtmDetailsComponent implements OnInit, OnDestroy { | |||
| switchArm = false; | |||
| isReady = true; | |||
| private unsubscribeAll = new Subject(); | |||
| data = atmWarningData; | |||
| constructor( | |||
| private socketService$: SocketService, | |||
| private dialog: MatDialog, | |||
| private confirm$: ConfirmDialogService, | |||
| private alarmSoundService$: AlarmSoundService, | |||
| ) {} | |||
| @@ -49,17 +49,19 @@ export class SecurityAtmDetailsComponent implements OnInit, OnDestroy { | |||
| state2: '0', | |||
| }; | |||
| this.onMessage(fakeData); | |||
| setTimeout(() => {{ | |||
| const fakeData = { | |||
| state5: '1', | |||
| state6: '1', | |||
| status1: '1', | |||
| state1: '0', | |||
| status2: '1', | |||
| state2: '0', | |||
| }; | |||
| this.onMessage(fakeData); | |||
| }}, 3000); | |||
| setTimeout(() => { | |||
| { | |||
| const fakeData = { | |||
| state5: '1', | |||
| state6: '1', | |||
| status1: '1', | |||
| state1: '0', | |||
| status2: '1', | |||
| state2: '0', | |||
| }; | |||
| this.onMessage(fakeData); | |||
| } | |||
| }, 3000); | |||
| } | |||
| ngOnDestroy(): void { | |||
| @@ -69,20 +71,22 @@ export class SecurityAtmDetailsComponent implements OnInit, OnDestroy { | |||
| } | |||
| getImageSource(): string { | |||
| return (this.state5 && this.state6) || this.state5 ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'; | |||
| return (this.state5 && this.state6) || this.state5 | |||
| ? 'assets/images/sensor-on.png' | |||
| : 'assets/images/sensor-off.png'; | |||
| } | |||
| onMessage(message: any) { | |||
| this.state1 = message.state1 == '0'; // 1 OFF // alarm 12h | |||
| this.status1 = message.status1 == '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||
| this.state2 = message.state2 == '0'; // 1 OFF // alarm 1h | |||
| this.status2 = message.status2 == '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||
| this.state3 = message.state3 == '1' ? 'ON' : 'OFF'; | |||
| this.state4 = message.state4 == '1' ? 'ON' : 'OFF'; | |||
| this.state5 = message.state5 == '1'; // alarm 9h && 6h // 1 ON, 0 OFF | |||
| this.state6 = message.state6 == '1'; // ? 'ON' : 'OFF'; | |||
| this.switchArm = message.state5 == '1';// alarm 9h && 6h // 1 ON, 0 OFF | |||
| this.isReady = message.ready == '1'; | |||
| this.state1 = message.state1 == '0'; // 1 OFF // alarm 12h | |||
| this.status1 = message.status1 == '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||
| this.state2 = message.state2 == '0'; // 1 OFF // alarm 1h | |||
| this.status2 = message.status2 == '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||
| this.state3 = message.state3 == '1' ? 'ON' : 'OFF'; | |||
| this.state4 = message.state4 == '1' ? 'ON' : 'OFF'; | |||
| this.state5 = message.state5 == '1'; // alarm 9h && 6h // 1 ON, 0 OFF | |||
| this.state6 = message.state6 == '1'; // ? 'ON' : 'OFF'; | |||
| this.switchArm = message.state5 == '1'; // alarm 9h && 6h // 1 ON, 0 OFF | |||
| this.isReady = message.ready == '1'; | |||
| } | |||
| openDialog(): void { | |||
| this.dialog.open(CameraDialogComponent, { | |||
| @@ -93,4 +97,17 @@ export class SecurityAtmDetailsComponent implements OnInit, OnDestroy { | |||
| displayedColumns: string[] = ['title', 'date']; | |||
| dataSource = new MatTableDataSource(ELEMENT_DATA); | |||
| openPositionDialog(event: MouseEvent, itemId: string): void { | |||
| const item = this.data.find((item) => item.id === itemId); | |||
| const rect = (event.target as HTMLElement).getBoundingClientRect(); | |||
| this.dialog.open(DetailPositionDialogComponent, { | |||
| data: item, | |||
| position: { | |||
| top: `${rect.top + window.scrollY - 180}px`, | |||
| left: `${rect.left + window.scrollX - 50}px`, | |||
| }, | |||
| width: '250px', | |||
| }); | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| <div class="popup-container"> | |||
| <div class="popup-header"> | |||
| <span class="popup-title">{{item.title}}</span> | |||
| <mat-icon class="close-button" (click)="onClose()">close</mat-icon> | |||
| </div> | |||
| <div> | |||
| <p><strong>Địa điểm:</strong> {{item.detail.position}}</p> | |||
| <p><strong>Tọa độ:</strong> {{item.detail.coordinates.lat}}, {{item.detail.coordinates.lng}}</p> | |||
| <p><strong>Thời gian:</strong> {{item.detail.time}}</p> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,29 @@ | |||
| .popup-container { | |||
| background-color: white; | |||
| border-radius: 8px; | |||
| box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1); | |||
| padding: 10px; | |||
| position: relative; | |||
| } | |||
| .popup-header { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| margin-bottom: 10px; | |||
| } | |||
| .popup-title { | |||
| color: #F33152; | |||
| font-weight: 500; | |||
| } | |||
| .close-button { | |||
| cursor: pointer; | |||
| color: #eeeeee; | |||
| &:hover{ | |||
| color: #000000; | |||
| } | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| import { Component, Inject } from '@angular/core'; | |||
| import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; | |||
| @Component({ | |||
| selector: 'app-detail-postion-dialog', | |||
| templateUrl: './detail-position-dialog.component.html', | |||
| styleUrls: ['./detail-position-dialog.component.scss'], | |||
| }) | |||
| export class DetailPositionDialogComponent { | |||
| constructor( | |||
| public dialogRef: MatDialogRef<DetailPositionDialogComponent>, | |||
| @Inject(MAT_DIALOG_DATA) public item: any, | |||
| ) {} | |||
| onClose(): void { | |||
| this.dialogRef.close(); | |||
| } | |||
| } | |||
| @@ -7,6 +7,7 @@ import { SliderRangeComponent } from './slider-range/slider-range.component'; | |||
| import { FormsModule } from '@angular/forms'; | |||
| import { CameraDialogComponent } from './camera-dialog/camera-dialog.component'; | |||
| import { ConfirmDialogComponent } from './confirm-dialog/confirm-dialog.component'; | |||
| import { DetailPositionDialogComponent } from './detail-postion-dialog/detail-position-dialog.component'; | |||
| @NgModule({ | |||
| declarations: [ | |||
| @@ -14,6 +15,7 @@ import { ConfirmDialogComponent } from './confirm-dialog/confirm-dialog.componen | |||
| SliderRangeComponent, | |||
| CameraDialogComponent, | |||
| ConfirmDialogComponent, | |||
| DetailPositionDialogComponent, | |||
| ], | |||
| imports: [CommonModule, SharedMaterialModule, RouterModule, FormsModule], | |||
| exports: [LayoutComponent, SliderRangeComponent, CameraDialogComponent], | |||