integrasi fimter device

This commit is contained in:
Fuzi_fauzia 2024-06-20 15:50:40 +07:00
parent d1393d6ec5
commit 49d37ee7e1
9 changed files with 1171 additions and 873 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,13 @@
.bg-maintenance-image { :host ::ng-deep .ng-select .ng-select-container {
background-size: cover; color: #ffffff !important;
display: flex; background-color: #252525 !important;
justify-content: center; height: 40px !important;
align-items: center; }
}
.background-round {
.centered-card { background-color: #252525 !important;
display: flex; padding: 8px;
justify-content: center; border-radius: 50%;
align-items: center; border: 2px solid #BEF264;
width: 100%; border-color: #BEF264 !important;
height: 100%; }
}
.box-shadow-2 {
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.box-shadow-3 {
box-shadow: 0 3px 20px rgba(0, 0, 0, 0.2);
}
.card {
background-color: rgba(255, 255, 255, 0.5);
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 20px;
max-width: 400px;
width: 100%;
}
.spinner {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -1,30 +1,155 @@
<div class="app-content content bg-maintenance-image"> <div class="app-content content" style="background-color: #000000 !important">
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content-header row mb-1">
<app-breadcrumb class="col-12" [breadcrumb]="breadcrumb"></app-breadcrumb>
</div>
<div class="content-body"> <div class="content-body">
<section class="flexbox-container"> <section id="configuration">
<div class="centered-card"> <div class="row">
<div class="card box-shadow-3"> <div class="col-12">
<div class="card-body"> <div class="card" style="background-color: #252525 !important">
<span class="card-title text-center"> <div class="card-content">
<img <div class="card-body">
src="assets/images/logo/smart.png" <div class="row mb-2">
class="img-fluid mx-auto d-block pt-2" <div class="col-2">
width="250" <div class="form-group">
alt="logo" <ng-select
/> class="select-custom"
</span> [items]="singleSelectArray"
</div> [searchable]="true"
<div class="card-body text-center"> bindLabel="item_text"
<h3 style="font-weight: 600; color: #000000">Coming Soon</h3> placeholder="Select Building"
<p style="color: #000000"> [(ngModel)]="singlebasicSelected"
We're working hard to bring you this page. <br /> >
Please check back later. </ng-select>
</p> </div>
<div class="mt-2"> </div>
<i class="la la-cog spinner font-large-2"></i> <div class="col-2">
<div class="form-group">
<ng-select
class="select-custom"
[items]="singleSelectArray"
[searchable]="true"
bindLabel="item_text"
placeholder="Select Type"
[(ngModel)]="singlebasicSelected"
>
</ng-select>
</div>
</div>
<div class="col-2">
<div class="form-group">
<ng-select
class="select-custom"
[items]="singleSelectArray"
[searchable]="true"
bindLabel="item_text"
placeholder="Select Category"
[(ngModel)]="singlebasicSelected"
>
</ng-select>
</div>
</div>
<div class="col-2 text-left">
<button
type="button"
class="btn btn-success mr-1"
style="
background-color: #252525 !important;
border-color: #bef264 !important;
"
>
<i
class="la la-search"
style="color: #ffffff !important"
></i>
</button>
</div>
<div class="col-2"></div>
<div class="col-2 text-right">
<button
class="btn btn-secondary"
[disabled]="spinnerActive"
(click)="addDevice()"
style="
background-color: #bef264 !important;
border-color: #bef264 !important;
color: #000000 !important;
"
>
<i
class="la la-spinner spinner"
*ngIf="spinnerActive"
></i>
<i class="feather ft-plus" *ngIf="!spinnerActive"></i
>&nbsp;
<span style="font-weight: 600">Synchronization</span>
</button>
</div>
</div>
<div class="card-dashboard"></div>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="configuration">
<div class="row">
<div class="col-lg-4 col-12" *ngFor="let item of filteredRows">
<div
class="card"
style="background-color: #252525; position: relative"
>
<div class="card-content">
<div class="card-body">
<div class="media d-flex">
<div class="align-self-center">
<div
style="
background-color: #414F2B;
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
"
>
<i
class="icon-bulb font-large-1 blue-grey d-block"
style="color: #bef264 !important"
></i>
</div>
<div style="margin-top: 10px">
<span
class="text-muted"
style="color: #ffffff !important"
>{{ item.name }}</span
>
<br />
<span
class="text-muted"
>lamp</span
>
</div>
</div>
<div class="ui-switch-container" style="position: absolute; bottom: 10px; right: 10px;">
<ui-switch
style="border-color: #bef264 !important"
class="switchery"
switchColor="black"
color="rgb(190, 242, 100)"
checked
></ui-switch>
</div>
</div>
</div>
</div> </div>
</div> </div>
<hr />
</div> </div>
</div> </div>
</section> </section>

View File

@ -1,4 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { BuildingService } from '../../service/monitoring-api.service';
import { DeviceService } from '../../service/device.service';
@Component({ @Component({
selector: 'app-device-control', selector: 'app-device-control',
@ -6,5 +9,84 @@ import { Component } from '@angular/core';
styleUrls: ['./device-control.component.css'] styleUrls: ['./device-control.component.css']
}) })
export class DeviceControlComponent { export class DeviceControlComponent {
data: any;
totalOn: any;
totalOff: any;
filteredRows: any[];
searchTerm: string = "";
rows: any = [];
public breadcrumb: any;
spinnerActive: boolean = false;
singlebasicSelected: any;
singleSelectArray = [
{ item_id: 1, item_text: "Alaska" },
{ item_id: 2, item_text: "California" },
{ item_id: 3, item_text: "Colorado" },
{ item_id: 4, item_text: "New Mexico" },
{ item_id: 5, item_text: "Alabama" },
{ item_id: 6, item_text: "Connecticut" },
{ item_id: 7, item_text: "New York" },
];
constructor(
private router: Router,
private deviceService: DeviceService
) {}
ngOnInit() {
this.breadcrumb = {
mainlabel: "Device",
links: [
{
name: "Home",
isLink: false,
link: "/dashboard/sales",
},
{
name: "Device",
isLink: false,
},
],
};
this.fetchData();
}
fetchData() {
this.deviceService.getDeviceLIst().subscribe((res) => {
console.log(res);
this.data = res;
this.filteredRows = this.data.data;
console.log(this.filteredRows);
});
}
filterRows() {
if (!this.searchTerm) {
this.filteredRows = [...this.data.results.data];
} else {
this.filteredRows = this.data.results.data.filter((row) =>
this.rowContainsSearchTerm(row)
);
}
}
rowContainsSearchTerm(row: any): boolean {
const searchTermLC = this.searchTerm.toLowerCase();
return Object.values(row).some(
(value) =>
value !== null && value.toString().toLowerCase().includes(searchTermLC)
);
}
addFieldValue() {
}
addDevice(): void {
}
} }

View File

@ -42,7 +42,7 @@
<div class="media d-flex"> <div class="media d-flex">
<div class="media-body text-left"> <div class="media-body text-left">
<h6 class="text-light" style="color: #ffffff !important"> <h6 class="text-light" style="color: #ffffff !important">
Total Device Aktive Total Device Active
</h6> </h6>
<h3 style="color: #ffffff !important">{{ totalOn }}</h3> <h3 style="color: #ffffff !important">{{ totalOn }}</h3>
</div> </div>
@ -94,11 +94,12 @@
<div class="form-group"> <div class="form-group">
<ng-select <ng-select
class="select-custom" class="select-custom"
[items]="singleSelectArray" [items]="dataBuildingList"
[searchable]="true" [searchable]="true"
bindLabel="item_text" bindLabel="name"
bindValue="id"
placeholder="Select Building" placeholder="Select Building"
[(ngModel)]="singlebasicSelected" [(ngModel)]="buildingSelected"
> >
</ng-select> </ng-select>
</div> </div>
@ -107,47 +108,57 @@
<div class="form-group"> <div class="form-group">
<ng-select <ng-select
class="select-custom" class="select-custom"
[items]="singleSelectArray" [items]="dataMasterCategori"
[searchable]="true" [searchable]="true"
bindLabel="item_text" bindLabel="name"
placeholder="Select Type" bindValue="id"
[(ngModel)]="singlebasicSelected"
>
</ng-select>
</div>
</div>
<div class="col-2">
<div class="form-group">
<ng-select
class="select-custom"
[items]="singleSelectArray"
[searchable]="true"
bindLabel="item_text"
placeholder="Select Category" placeholder="Select Category"
[(ngModel)]="singlebasicSelected" [(ngModel)]="categorySelected"
>
</ng-select>
</div>
</div>
<div class="col-2">
<div class="form-group">
<ng-select
class="select-custom"
[items]="dataMasterStatus"
[searchable]="true"
bindLabel="name"
bindValue="id"
placeholder="Select Status"
[(ngModel)]="statusSelected"
> >
</ng-select> </ng-select>
</div> </div>
</div> </div>
<div class="col-2 text-left"> <div class="col-2 text-left">
<button <div class="d-flex">
type="button" <button
class="btn btn-success mr-1" type="button"
style=" class="btn btn-outline-success ml-2"
background-color: #252525 !important; (click)="doFilter()"
border-color: #bef264 !important; style="
" background-color: #252525 !important;
> border-color: #bef264 !important;
<i "
class="la la-search" [disabled]="spinnerFilterActive"
style="color: #ffffff !important" >
></i> <i
</button> class="la la-search"
</div> style="color: #ffffff !important"
<div class="col-2"> *ngIf="!spinnerFilterActive"
></i>
<i
class="la la-spinner spinner"
style="color: #ffffff !important"
*ngIf="spinnerFilterActive"
></i>
</button>
</div>
</div> </div>
<div class="col-2"></div>
<div class="col-2 text-right"> <div class="col-2 text-right">
<button <button
@ -175,7 +186,7 @@
<ngx-datatable <ngx-datatable
class="bootstrap table-bordered" class="bootstrap table-bordered"
[limit]="5" [limit]="5"
[rows]="filteredRows" [rows]="data_device"
[columnMode]="'force'" [columnMode]="'force'"
[headerHeight]="50" [headerHeight]="50"
[footerHeight]="50" [footerHeight]="50"
@ -198,7 +209,7 @@
<ngx-datatable-column <ngx-datatable-column
name="icon" name="icon"
[flexGrow]="1" [flexGrow]="1"
[minWidth]="140" [minWidth]="20"
> >
<ng-template ngx-datatable-header-template> <ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important">Image</span> <span style="color: #ffffff !important">Image</span>
@ -212,7 +223,7 @@
<ngx-datatable-column <ngx-datatable-column
name="Name" name="Name"
[flexGrow]="1" [flexGrow]="1"
[minWidth]="90" [minWidth]="150"
> >
<ng-template ngx-datatable-header-template> <ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important" <span style="color: #ffffff !important"
@ -227,7 +238,24 @@
</ng-template> </ng-template>
</ngx-datatable-column> </ngx-datatable-column>
<ngx-datatable-column <ngx-datatable-column
name="categoryEntity" name="buildingName"
[flexGrow]="1"
[minWidth]="90"
>
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important"
>Building</span
>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<p style="color: #ffffff !important">{{ value }}</p>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column
name="categoryName"
[flexGrow]="1" [flexGrow]="1"
[minWidth]="90" [minWidth]="90"
> >
@ -241,7 +269,7 @@
let-value="value" let-value="value"
> >
<p style="color: #ffffff !important"> <p style="color: #ffffff !important">
{{ value.name }} {{ value }}
</p> </p>
</ng-template> </ng-template>
</ngx-datatable-column> </ngx-datatable-column>
@ -261,7 +289,7 @@
</ng-template> </ng-template>
</ngx-datatable-column> </ngx-datatable-column>
<ngx-datatable-column <ngx-datatable-column
name="typeEntity" name="typeName"
[flexGrow]="1" [flexGrow]="1"
[minWidth]="90" [minWidth]="90"
> >
@ -273,12 +301,12 @@
let-value="value" let-value="value"
> >
<p style="color: #ffffff !important"> <p style="color: #ffffff !important">
{{ value.name }} {{ value }}
</p> </p>
</ng-template> </ng-template>
</ngx-datatable-column> </ngx-datatable-column>
<ngx-datatable-column <ngx-datatable-column
name="voltageEntity" name="voltageName"
[flexGrow]="1" [flexGrow]="1"
[minWidth]="90" [minWidth]="90"
> >
@ -290,12 +318,12 @@
let-value="value" let-value="value"
> >
<p style="color: #ffffff !important"> <p style="color: #ffffff !important">
{{ value.name }} {{ value }}
</p> </p>
</ng-template> </ng-template>
</ngx-datatable-column> </ngx-datatable-column>
<ngx-datatable-column <ngx-datatable-column
name="statusEntity" name="statusName"
[flexGrow]="1" [flexGrow]="1"
[minWidth]="90" [minWidth]="90"
> >
@ -307,7 +335,7 @@
let-value="value" let-value="value"
> >
<p style="color: #ffffff !important"> <p style="color: #ffffff !important">
{{ value.name }} {{ value }}
</p> </p>
</ng-template> </ng-template>
</ngx-datatable-column> </ngx-datatable-column>

View File

@ -1,10 +1,11 @@
import { Component, OnInit, ViewChild } from "@angular/core"; import { Component, OnInit, ViewChild } from "@angular/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import { NgBlockUI, BlockUI } from "ng-block-ui";
import { TableApiService } from "src/app/_services/table-api.service"; import { TableApiService } from "src/app/_services/table-api.service";
import { ModalAddEditComponent } from "./modal-add-edit/modal-add-edit.component"; import { ModalAddEditComponent } from "./modal-add-edit/modal-add-edit.component";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute, Router } from "@angular/router";
import { BuildingService } from "../service/monitoring-api.service"; import { BuildingService } from "../service/monitoring-api.service";
import { DeviceService } from "../service/device.service";
import { ToastrService } from "ngx-toastr";
@Component({ @Component({
selector: "app-device", selector: "app-device",
@ -17,6 +18,16 @@ export class DeviceComponent implements OnInit {
totalOff: any; totalOff: any;
filteredRows: any[]; filteredRows: any[];
searchTerm: string = ""; searchTerm: string = "";
buildingSelected: any;
statusSelected: any;
categorySelected: any;
dataMasterCategori: any;
dataBuildingList: any;
dataMasterStatus: any;
data_device: any;
spinnerFilterActive = false;
storedData: any;
rows: any = []; rows: any = [];
public breadcrumb: any; public breadcrumb: any;
spinnerActive: boolean = false; spinnerActive: boolean = false;
@ -33,13 +44,12 @@ export class DeviceComponent implements OnInit {
{ item_id: 7, item_text: "New York" }, { item_id: 7, item_text: "New York" },
]; ];
@BlockUI("zeroConfiguration") blockUIZeroConfiguration: NgBlockUI;
constructor( constructor(
private tableApiservice: TableApiService,
private modalService: NgbModal, private modalService: NgbModal,
private router: Router, private router: Router,
private monitoringApiService: BuildingService private monitoringApiService: BuildingService,
private deviceService: DeviceService,
private toastr: ToastrService
) {} ) {}
ngOnInit() { ngOnInit() {
@ -57,19 +67,71 @@ export class DeviceComponent implements OnInit {
}, },
], ],
}; };
this.fetchData(); this.storedData = JSON.parse(localStorage.getItem("currentUser"));
this.buildingSelected = this.storedData.buildingId;
this.fetchData(this.buildingSelected, this.categorySelected, this.statusSelected);
this.dataListMaster();
this.dataListBuilding();
} }
fetchData() { fetchData(buildingSelected, categorySelected, statusSelected) {
this.monitoringApiService.getDeviceData().subscribe((res) => { this.deviceService
this.data = res; .getDeviceData(buildingSelected, categorySelected, statusSelected)
this.filteredRows = this.data.results.data; .subscribe((res) => {
console.log(this.filteredRows); this.data = res;
this.totalOn = this.filteredRows.filter((row) => row.statusEntity.name.toLowerCase() === 'aktif').length this.filteredRows = this.data.results.data;
this.totalOff = this.filteredRows.filter((row) => row.statusEntity.name.toLowerCase() === 'nonaktif').length this.data_device = this.filteredRows.map((item) => ({
buildingName: item.building_name,
id: item.id,
name: item.name,
icon: item.icon,
watt: item.watt,
categoryName: item.category_name,
typeName: item.type_name,
voltageName: item.voltage_name,
statusName: item.status_name,
}));
this.totalOn = this.filteredRows.filter(
(row) => row.status_id === 2
).length;
this.totalOff = this.filteredRows.filter(
(row) => row.status_id === 3
).length;
});
}
dataListMaster() {
this.monitoringApiService.getMasterListData().subscribe((data) => {
const dataCategory = data.data.find(
(item) => item.name === "master_category"
).headerDetailParam;
const dataStatus = data.data.find(
(item) => item.name === "master_status"
).headerDetailParam;
this.dataMasterCategori = dataCategory.filter(
(item) => item.status === "2"
);
this.dataMasterStatus = dataStatus.filter((item) => item.status === "2");
}); });
} }
dataListBuilding() {
this.monitoringApiService.getBuildingList().subscribe((data) => {
this.dataBuildingList = data.data.filter((item) => item.statusId === 2);
});
}
doFilter() {
this.spinnerFilterActive = true;
this.fetchData(
this.buildingSelected,
this.categorySelected, this.statusSelected
);
setTimeout(() => {
this.spinnerFilterActive = false;
}, 3000);
}
filterRows() { filterRows() {
if (!this.searchTerm) { if (!this.searchTerm) {
this.filteredRows = [...this.data.results.data]; this.filteredRows = [...this.data.results.data];
@ -130,13 +192,17 @@ export class DeviceComponent implements OnInit {
addDevice(): void { addDevice(): void {
// Aktifkan spinner // Aktifkan spinner
this.spinnerActive = true; this.spinnerActive = true;
this.monitoringApiService.getSyncDeviceData().subscribe((res) => { this.deviceService.getSyncDeviceData().subscribe((res) => {
console.log(res); console.log(res);
}); });
setTimeout(() => { setTimeout(() => {
this.spinnerActive = false; this.spinnerActive = false;
this.fetchData(); this.toastr.success("Success", "Sync Completed.", {
timeOut: 2000,
closeButton: true,
});
this.fetchData(this.buildingSelected, this.categorySelected, this.statusSelected);
}, 3000); }, 3000);
} }
} }

View File

@ -15,6 +15,7 @@ import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { AddEditDeviceComponent } from './add-edit-device/add-edit-device.component'; import { AddEditDeviceComponent } from './add-edit-device/add-edit-device.component';
import { ModalAddEditComponent } from './modal-add-edit/modal-add-edit.component'; import { ModalAddEditComponent } from './modal-add-edit/modal-add-edit.component';
import { DeviceControlComponent } from './device-control/device-control.component'; import { DeviceControlComponent } from './device-control/device-control.component';
import { UiSwitchModule } from 'ngx-ui-switch';
@ -34,6 +35,7 @@ import { DeviceControlComponent } from './device-control/device-control.componen
ReactiveFormsModule, ReactiveFormsModule,
ClipboardModule, ClipboardModule,
PerfectScrollbarModule, PerfectScrollbarModule,
UiSwitchModule,
NgxDatatableModule, NgxDatatableModule,
BlockUIModule.forRoot({ BlockUIModule.forRoot({
template: BlockTemplateComponent template: BlockTemplateComponent

View File

@ -0,0 +1,53 @@
import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";
const BASE_URL = 'https://kapi.absys.ninja/hemat';
@Injectable({
providedIn: "root",
})
export class DeviceService {
constructor(private http: HttpClient) {}
getDeviceData(id, category, status): Observable<any> {
const endpoint = `/devices`;
const params = new URLSearchParams({
page: "1",
limit: "100",
building_id: id
});
if (category) {
params.append("category_id", category);
}
if (status) {
params.append("status_id", status);
}
const url = `${BASE_URL}${endpoint}?${params.toString()}`;
const headers = new HttpHeaders({
"Content-Type": "application/json",
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
});
return this.http.get<any>(url, { headers });
}
getDeviceLIst(): Observable<any> {
const endpoint = `/devices`;
const url = `${BASE_URL}${endpoint}/list`;
const headers = new HttpHeaders({
"Content-Type": "application/json",
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
});
return this.http.get<any>(url, { headers });
}
getSyncDeviceData(): Observable<any> {
const endpoint = `/devices`;
const url = `${BASE_URL}${endpoint}/Synchronization`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'x-api-key': 'j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT'
});
return this.http.get<any>(url, { headers });
}
}

View File

@ -26,15 +26,6 @@ export class BuildingService {
return this.http.get<any>(url, { headers }); return this.http.get<any>(url, { headers });
} }
listDevicePerBuilding(id): Observable<any> {
const url = `https://kapi.absys.ninja/hemat/devices/aggregate/on?building_id=${id}`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'x-api-key': 'j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT'
});
return this.http.get<any>(url, { headers });
}
getBuildingData(page: number = 1, limit: number = 10): Observable<any> { getBuildingData(page: number = 1, limit: number = 10): Observable<any> {
const url = `https://kapi.absys.ninja/hemat/building?page=${page}&limit=${limit}`; const url = `https://kapi.absys.ninja/hemat/building?page=${page}&limit=${limit}`;
// const headers = new HttpHeaders().set('Content-Type', 'application/json'); // const headers = new HttpHeaders().set('Content-Type', 'application/json');
@ -54,24 +45,6 @@ export class BuildingService {
return this.http.get<any>(url, { headers }); return this.http.get<any>(url, { headers });
} }
getDeviceData(page: number = 1, limit: number = 10): Observable<any> {
const url = `https://kapi.absys.ninja/hemat/devices?page=${page}&limit=${limit}`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'x-api-key': 'j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT'
});
return this.http.get<any>(url, { headers });
}
getSyncDeviceData(page: number = 1, limit: number = 10): Observable<any> {
const url = `https://kapi.absys.ninja/hemat/devices/Synchronization`;
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'x-api-key': 'j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT'
});
return this.http.get<any>(url, { headers });
}
getDeviceById(deviceId: any): Observable<any> { getDeviceById(deviceId: any): Observable<any> {
const url = `https://kapi.absys.ninja/hemat/devices/${deviceId}`; const url = `https://kapi.absys.ninja/hemat/devices/${deviceId}`;
const headers = new HttpHeaders({ const headers = new HttpHeaders({