integrasi cost management
This commit is contained in:
parent
38c936b389
commit
ad91c844d6
|
@ -28,17 +28,17 @@
|
|||
<div class="navbar-container content" [hidden]="isMobile && !showNavbar">
|
||||
<div class="collapse navbar-collapse" id="navbar-mobile">
|
||||
<ul class="nav navbar-nav mr-auto float-left">
|
||||
<li class="nav-item d-none d-md-block"><a [routerLink]="" class="nav-link nav-link-expand"
|
||||
<!-- <li class="nav-item d-none d-md-block"><a [routerLink]="" class="nav-link nav-link-expand"
|
||||
(click)="toggleFullScreen()" *ngIf="maximize === 'on'"><i class="ficon feather ft-maximize"></i></a></li>
|
||||
<li class="nav-item nav-search"><a [routerLink]="" class="nav-link nav-link-search" (click)="clickSearch()"
|
||||
*ngIf="search === 'on'"><i class="ficon feather ft-search"></i></a>
|
||||
<div class="search-input" [ngClass]="{'open': isHeaderSearchOpen}">
|
||||
<input class="input" type="text" placeholder="Explore Modern...">
|
||||
</div>
|
||||
</li>
|
||||
</li> -->
|
||||
</ul>
|
||||
<ul class="nav navbar-nav float-right">
|
||||
<li class="dropdown-language nav-item" ngbDropdown *ngIf="internationalization === 'on'">
|
||||
<!-- <li class="dropdown-language nav-item" ngbDropdown *ngIf="internationalization === 'on'">
|
||||
<a [routerLink]="" class="dropdown-toggle nav-link" ngbDropdownToggle id="dropdown-flag">
|
||||
<i class="flag-icon flag-icon-gb"></i><span class="selected-language"></span>
|
||||
</a>
|
||||
|
@ -56,7 +56,7 @@
|
|||
<i class="flag-icon flag-icon-de"></i> German
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</li> -->
|
||||
<li class="dropdown-notification nav-item dropdown" ngbDropdown *ngIf="notification === 'on'">
|
||||
<a class="nav-link nav-link-label" ngbDropdownToggle>
|
||||
<i class="ficon feather ft-bell"></i>
|
||||
|
@ -133,7 +133,7 @@
|
|||
href="javascript:void(0)">Read all notifications</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-notification nav-item" ngbDropdown>
|
||||
<!-- <li class="dropdown-notification nav-item" ngbDropdown>
|
||||
<a class="nav-link nav-link-label" ngbDropdownToggle *ngIf="email === 'on'"><i
|
||||
class="ficon feather ft-mail"></i></a>
|
||||
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
||||
|
@ -194,7 +194,7 @@
|
|||
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
||||
href="javascript:void(0)">Read all messages</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</li> -->
|
||||
|
||||
<li class="dropdown-user nav-item" ngbDropdown>
|
||||
<a class="nav-link dropdown-user-link" ngbDropdownToggle>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,63 +1,253 @@
|
|||
:host ::ng-deep .donut-chart1 .ct-series-a .ct-slice-donut {
|
||||
stroke: green;
|
||||
stroke-width: 50px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart1 .ct-series-b .ct-slice-donut {
|
||||
stroke: yellow;
|
||||
stroke-width: 50px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart1 .ct-series-c .ct-slice-donut {
|
||||
stroke: orange;
|
||||
stroke-width: 50px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart1 .ct-series-d .ct-slice-donut {
|
||||
stroke: red;
|
||||
stroke-width: 50px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart1 .ct-series-e .ct-slice-donut {
|
||||
stroke: darkred;
|
||||
stroke-width: 50px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart2 .ct-series-a .ct-slice-donut {
|
||||
:host ::ng-deep .donut-chart2 .ct-series-a .ct-slice-donut {
|
||||
stroke: #8a8a8a;
|
||||
stroke-width: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart2 .ct-series-b .ct-slice-donut {
|
||||
:host ::ng-deep .donut-chart2 .ct-series-b .ct-slice-donut {
|
||||
stroke: #bef264;
|
||||
stroke-width: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart2 {
|
||||
:host ::ng-deep .donut-chart2 {
|
||||
-webkit-filter: drop-shadow(0px 10px 11px rgba(187, 187, 187)) !important;
|
||||
filter: drop-shadow(0px 10px 11px rgba(187, 187, 187));
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart2 .ct-label {
|
||||
:host ::ng-deep .donut-chart2 .ct-label {
|
||||
fill: #111010;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
font-size: 1.75rem;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .sp-line-total-cost .ct-series-a .ct-point {
|
||||
:host ::ng-deep .sp-line-total-cost .ct-series-a .ct-point {
|
||||
stroke: #bef264;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .sp-line-total-cost .ct-series-a .ct-line {
|
||||
:host ::ng-deep .sp-line-total-cost .ct-series-a .ct-line {
|
||||
stroke: #bef264;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .sp-line-total-cost .ct-series-a .ct-area {
|
||||
:host ::ng-deep .sp-line-total-cost .ct-series-a .ct-area {
|
||||
fill: #bef264;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep .sp-line-total-cost .ct-point {
|
||||
:host ::ng-deep .sp-line-total-cost .ct-point {
|
||||
stroke-width: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.ct-chart-bar .ct-series .ct-bar {
|
||||
stroke-width: 20px !important; /* Atur lebar bar sesuai kebutuhan */
|
||||
}
|
||||
|
||||
.ct-chart-bar .ct-label.ct-horizontal {
|
||||
margin-left: -10px !important; /* Mengatur margin label horizontal */
|
||||
margin-right: -10px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart3 .ct-series-a .ct-bar {
|
||||
stroke: #cd560c;
|
||||
fill: none;
|
||||
stroke-width: 30px;
|
||||
}
|
||||
|
||||
:host ::ng-deep .donut-chart3 .ct-series-b .ct-bar {
|
||||
stroke: #49cd0c;
|
||||
fill: none;
|
||||
stroke-width: 30px;
|
||||
}
|
||||
|
||||
/* table */
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-header .datatable-header-cell .datatable-header-cell-label {
|
||||
font-family: inherit;
|
||||
font-size: medium;
|
||||
font-weight: bold;
|
||||
color: #6B6F82;
|
||||
}
|
||||
:host ::ng-deep .ngx-datatable .datatable-row-center, .ngx-datatable .datatable-row-group, .ngx-datatable .datatable-row-right {
|
||||
position: relative;
|
||||
height: 50px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-right:before {
|
||||
font-family: 'icofont';
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-skip:before {
|
||||
font-family: 'icofont';
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-left:before {
|
||||
font-family: 'icofont';
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-left:before {
|
||||
content: "\2039";
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-prev:before {
|
||||
content: "\00AB";
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-right:before {
|
||||
content: "\203A";
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-icon-skip:before {
|
||||
content: "\00BB";
|
||||
font-size: x-large;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-left,
|
||||
.ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-right,
|
||||
.ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-prev {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #d4d2e7;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-right,
|
||||
.ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-right {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #d4d2e7;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-skip {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #d4d2e7;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-prev {
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #d4d2e7;
|
||||
}
|
||||
|
||||
:host ::ng-deep .datatable-footer .datatable-pager ul li:not(.disabled).active a,
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] ul[_ngcontent-c11] li[_ngcontent-c11]:not(.disabled):hover a[_ngcontent-c11] {
|
||||
background-color: #d4d2e7;
|
||||
font-weight: bold;
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager a {
|
||||
height: 32px;
|
||||
min-width: 34px;
|
||||
line-height: 22px;
|
||||
padding: 0;
|
||||
border-radius: 3px;
|
||||
margin: 0 3px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
padding-top: 3px;
|
||||
text-decoration: none;
|
||||
vertical-align: bottom;
|
||||
color: #7c8091;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-left,
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-right[_ngcontent-c11],
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-prev[_ngcontent-c11] {
|
||||
font-size: 14px;
|
||||
line-height: 9px;
|
||||
padding: 0px 08px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-left,
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-right[_ngcontent-c11],
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-prev[_ngcontent-c11] {
|
||||
font-size: 0px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-right,
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-right[_ngcontent-c11],
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-prev[_ngcontent-c11] {
|
||||
font-size: 0px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-skip,
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-right[_ngcontent-c11],
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-prev[_ngcontent-c11] {
|
||||
font-size: 0px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager .datatable-icon-prev,
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-right[_ngcontent-c11],
|
||||
.ngx-datatable.bootstrap[_ngcontent-c11] .datatable-footer[_ngcontent-c11] .datatable-pager[_ngcontent-c11] .datatable-icon-prev[_ngcontent-c11] {
|
||||
font-size: 0px;
|
||||
line-height: 22px;
|
||||
padding: 0px 09px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager ul li:not(.disabled):hover a {
|
||||
background-color: #545454;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer .datatable-pager ul li:not(.disabled).active a,
|
||||
.ngx-datatable.bootstrap .datatable-footer .datatable-pager ul li:not(.disabled):hover a {
|
||||
background-color: #545454;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer {
|
||||
background: #727e8e;
|
||||
color: #ededed;
|
||||
margin-top: -1px;
|
||||
overflow: inherit;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-header {
|
||||
font-weight: bold;
|
||||
height: unset !important;
|
||||
overflow: inherit
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable .datatable-footer .datatable-pager {
|
||||
flex: 0 0 0%;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable .datatable-footer .datatable-pager .pager {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
:host ::ng-deep .block-ui-wrapper {
|
||||
background: rgba(255, 249, 249, 0.5) !important;
|
||||
}
|
||||
:host ::ng-deep .ngx-datatable .datatable-footer .selected-count .datatable-pager {
|
||||
flex: 0 0 0%;
|
||||
}
|
||||
|
||||
:host ::ng-deep .ngx-datatable {
|
||||
display: -webkit-box;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
<div class="col-lg-4 col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title text-center">Temperature and Humidity</h4>
|
||||
<h4 class="card-title text-center">
|
||||
Comparison of Water and Electricity Costs
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-block">
|
||||
|
@ -30,35 +32,25 @@
|
|||
<div class="col-lg-4 col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title text-center">Air Quality</h4>
|
||||
<h4 class="card-title text-center">
|
||||
Comparison of Previous Month Costs
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-block">
|
||||
<div class="donut-chart1" style="height: 150px !important">
|
||||
<x-chartist
|
||||
*ngIf="donutChart1"
|
||||
[data]="donutChart1.data"
|
||||
[type]="donutChart1.type"
|
||||
[options]="donutChart1.options"
|
||||
[responsiveOptions]="donutChart1.responsiveOptions"
|
||||
[events]="donutChart1.events"
|
||||
></x-chartist>
|
||||
</div>
|
||||
<div
|
||||
class="text-center"
|
||||
style="
|
||||
position: absolute;
|
||||
top: 80%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
"
|
||||
class="donut-chart3 text-center"
|
||||
style="height: 150px !important"
|
||||
>
|
||||
<h3
|
||||
class="display-4 blue-grey darken-1"
|
||||
style="font-size: 2em"
|
||||
<x-chartist
|
||||
*ngIf="barChart"
|
||||
[data]="barChart.data"
|
||||
[type]="barChart.type"
|
||||
[options]="barChart.options"
|
||||
[responsiveOptions]="barChart.responsiveOptions"
|
||||
[events]="barChart.events"
|
||||
>
|
||||
76 %
|
||||
</h3>
|
||||
</x-chartist>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -67,7 +59,9 @@
|
|||
<div class="col-lg-4 col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title text-center">Comparison of Actual Costs and Estimated Costs</h4>
|
||||
<h4 class="card-title text-center">
|
||||
Comparison of Actual Costs and Estimated Costs
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-block">
|
||||
|
@ -75,30 +69,36 @@
|
|||
<div class="flex-grow-1">
|
||||
<ngb-progressbar
|
||||
height="45px"
|
||||
type="danger"
|
||||
[value]="89"
|
||||
type="success"
|
||||
[value]="dataCompAct?.est_cost"
|
||||
[max]="dataCompAct?.real_cost"
|
||||
></ngb-progressbar>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 d-flex align-items-center"
|
||||
style="height: 20px"
|
||||
>
|
||||
<span class="text-bold-600">1.234.242</span>
|
||||
<span class="text-bold-600">{{
|
||||
dataCompAct?.est_cost
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="flex-grow-1">
|
||||
<ngb-progressbar
|
||||
height="45px"
|
||||
type="success"
|
||||
[value]="50"
|
||||
type="danger"
|
||||
[value]="dataCompAct?.real_cost"
|
||||
[max]="dataCompAct?.real_cost"
|
||||
></ngb-progressbar>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 d-flex align-items-center"
|
||||
style="height: 20px"
|
||||
>
|
||||
<span class="text-bold-600">1.545.232</span>
|
||||
<span class="text-bold-600">{{
|
||||
dataCompAct?.real_cost
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -107,6 +107,276 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="configuration">
|
||||
<div class="row">
|
||||
<div
|
||||
class="col-12"
|
||||
*blockUI="'zeroConfiguration'; message: 'Loading'"
|
||||
>
|
||||
<m-card>
|
||||
<!-- <ng-container mCardHeaderTitle> Device Table </ng-container> -->
|
||||
<ng-container mCardBody>
|
||||
<div class="row mb-2">
|
||||
<div class="col-3">
|
||||
<div class="form-group">
|
||||
<ng-select
|
||||
[items]="dataBuildingList"
|
||||
[searchable]="true"
|
||||
bindLabel="name"
|
||||
bindValue="id"
|
||||
placeholder="Select Building"
|
||||
[(ngModel)]="buildingSelected"
|
||||
>
|
||||
</ng-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="month"
|
||||
class="form-control"
|
||||
[(ngModel)]="dateSelected"
|
||||
id="month12"
|
||||
(focus)="focusElement('month12')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="form-group">
|
||||
<ng-select
|
||||
[items]="dataMasterCategori"
|
||||
[searchable]="true"
|
||||
bindLabel="name"
|
||||
bindValue="id"
|
||||
placeholder="Select Category"
|
||||
[(ngModel)]="categorySelected"
|
||||
>
|
||||
</ng-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<div class="d-flex">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Search..."
|
||||
[(ngModel)]="searchTerm"
|
||||
/>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-success ml-2"
|
||||
(click)="doFilter()"
|
||||
>
|
||||
<i class="la la-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-2">
|
||||
<div class="col-4">
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Kwh"
|
||||
[(ngModel)]="kwhTerm"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="form-group">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="Cost"
|
||||
[(ngModel)]="costTerm"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-4">
|
||||
<div class="d-flex justify-content-end">
|
||||
<button
|
||||
class="btn btn-secondary mr-2"
|
||||
style="width: 100%"
|
||||
(click)="syncData()"
|
||||
>
|
||||
<i
|
||||
class="la la-spinner spinner"
|
||||
*ngIf="spinnerActive"
|
||||
></i>
|
||||
<i class="la la-spinner" *ngIf="!spinnerActive"></i
|
||||
>
|
||||
<span>Syncing Data</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
style="width: 100%"
|
||||
(click)="addFieldValue()"
|
||||
>
|
||||
<i class="feather ft-plus"></i
|
||||
>
|
||||
<span>Add Actual Cost</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-dashboard">
|
||||
<ngx-datatable
|
||||
class="bootstrap table-bordered"
|
||||
[limit]="5"
|
||||
[rows]="data_cost"
|
||||
[columnMode]="'force'"
|
||||
[headerHeight]="50"
|
||||
[footerHeight]="50"
|
||||
[rowHeight]="50"
|
||||
fxFlex="auto"
|
||||
[scrollbarH]="true"
|
||||
>
|
||||
<ngx-datatable-column
|
||||
name="#"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="10"
|
||||
>
|
||||
<ng-template
|
||||
ngx-datatable-cell-template
|
||||
let-rowIndex="rowIndex"
|
||||
>
|
||||
{{ rowIndex + 1 }}
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="building"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="90"
|
||||
>
|
||||
<ng-template ngx-datatable-header-template>
|
||||
<span>Building</span>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
let-value="value"
|
||||
ngx-datatable-cell-template
|
||||
>
|
||||
{{ value }}
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="categoryName"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="90"
|
||||
>
|
||||
<ng-template ngx-datatable-header-template>
|
||||
<span>Category</span>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
let-value="value"
|
||||
ngx-datatable-cell-template
|
||||
>
|
||||
{{ value }}
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="estimationCost"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="90"
|
||||
>
|
||||
<ng-template ngx-datatable-header-template>
|
||||
<span>Estimation Cost</span>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
let-value="value"
|
||||
ngx-datatable-cell-template
|
||||
>
|
||||
{{
|
||||
value.toLocaleString("id-ID", {
|
||||
style: "currency",
|
||||
currency: "IDR"
|
||||
})
|
||||
}}
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="totalUse"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="90"
|
||||
>
|
||||
<ng-template ngx-datatable-header-template>
|
||||
<span>Total Use</span>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
let-value="value"
|
||||
ngx-datatable-cell-template
|
||||
>
|
||||
{{ value }} kWh
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="endDate"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="90"
|
||||
>
|
||||
<ng-template ngx-datatable-header-template>
|
||||
<span>Tanggal</span>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
let-value="value"
|
||||
ngx-datatable-cell-template
|
||||
>
|
||||
{{ value | date : "MM/yyyy" }}
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="status_id"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="90"
|
||||
>
|
||||
<ng-template ngx-datatable-header-template>
|
||||
<span>Status</span>
|
||||
</ng-template>
|
||||
<ng-template
|
||||
ngx-datatable-cell-template
|
||||
let-value="value"
|
||||
>
|
||||
{{ value === 2 ? "Aktif" : "Tidak Aktif" }}
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
<ngx-datatable-column
|
||||
name="Actions"
|
||||
[flexGrow]="1"
|
||||
[minWidth]="150"
|
||||
>
|
||||
<ng-template
|
||||
ngx-datatable-cell-template
|
||||
let-rowIndex="rowIndex"
|
||||
let-row="row"
|
||||
>
|
||||
<button
|
||||
class="btn btn-sm btn-warning mr-1"
|
||||
(click)="editRow(row)"
|
||||
>
|
||||
<i class="ficon feather ft-edit"></i>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-danger"
|
||||
(click)="deleteRow(row)"
|
||||
>
|
||||
<i class="ficon feather ft-trash-2"></i>
|
||||
</button>
|
||||
</ng-template>
|
||||
</ngx-datatable-column>
|
||||
</ngx-datatable>
|
||||
</div>
|
||||
</ng-container>
|
||||
</m-card>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,50 +1,51 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { TableApiService } from 'src/app/_services/table-api.service';
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { TableApiService } from "src/app/_services/table-api.service";
|
||||
import { BuildingService } from "../service/monitoring-api.service";
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { CostManagementService } from "../service/cost-management.service";
|
||||
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||
import { ModalAddActualComponent } from "./modal-add-actual/modal-add-actual.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-cost-management',
|
||||
templateUrl: './cost-management.component.html',
|
||||
styleUrls: ['./cost-management.component.css']
|
||||
selector: "app-cost-management",
|
||||
templateUrl: "./cost-management.component.html",
|
||||
styleUrls: ["./cost-management.component.css"],
|
||||
})
|
||||
export class CostManagementComponent implements OnInit{
|
||||
export class CostManagementComponent implements OnInit {
|
||||
public breadcrumb: any;
|
||||
data: any;
|
||||
filteredRows: any[];
|
||||
data_cost: any;
|
||||
searchTerm: string = "";
|
||||
kwhTerm: string = "";
|
||||
costTerm: string = "";
|
||||
rows: any = [];
|
||||
dataMasterCategori: any;
|
||||
dataBuildingList: any;
|
||||
public focucedElement = "";
|
||||
spinnerActive = false;
|
||||
spinnerActiveActual = false;
|
||||
|
||||
donutChart1: any;
|
||||
donutChart2: any;
|
||||
dataChart = {
|
||||
donut: {
|
||||
series: [50, 50],
|
||||
labels: [],
|
||||
},
|
||||
};
|
||||
dataChart2 = {
|
||||
donut: {
|
||||
series: [50, 50],
|
||||
labels: [],
|
||||
},
|
||||
};
|
||||
|
||||
barChart: any;
|
||||
dataBar = {
|
||||
"Bar": {
|
||||
"labels": [],
|
||||
"series": [
|
||||
[
|
||||
80,
|
||||
60
|
||||
]
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
dateSelected: any;
|
||||
buildingSelected: any;
|
||||
categorySelected: any;
|
||||
dataComp: any;
|
||||
dataCompPrev: any;
|
||||
dataCompAct: any;
|
||||
storedData: any;
|
||||
|
||||
constructor(
|
||||
private tableApiservice: TableApiService,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private monitoringApiService: BuildingService,
|
||||
private costService: CostManagementService,
|
||||
private datePipe: DatePipe,
|
||||
private modalService: NgbModal
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -61,42 +62,68 @@ export class CostManagementComponent implements OnInit{
|
|||
},
|
||||
],
|
||||
};
|
||||
this.fetchData();
|
||||
this.storedData = JSON.parse(localStorage.getItem("currentUser"));
|
||||
this.buildingSelected = this.storedData.buildingId;
|
||||
const currentDate = new Date();
|
||||
this.dateSelected = currentDate.toISOString().slice(0, 7);
|
||||
|
||||
this.barChart = {
|
||||
type: 'Bar',
|
||||
data: this.dataBar.Bar,
|
||||
options: {
|
||||
fullwidth: true,
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
showLabel: false,
|
||||
offset: 100
|
||||
},
|
||||
this.fetchData(this.storedData.buildingId, this.dateSelected, this.categorySelected);
|
||||
this.dataListMaster();
|
||||
this.dataListBuilding();
|
||||
|
||||
this.dataCompWaterElectCost(this.storedData.buildingId);
|
||||
this.dataCompPrevMonthCost(this.storedData.buildingId);
|
||||
this.dataCompActEstCost(this.storedData.buildingId);
|
||||
|
||||
axisY: {
|
||||
showGrid: false,
|
||||
showLabel: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.donutChart1 = {
|
||||
type: "Pie",
|
||||
data: this.dataChart.donut,
|
||||
options: {
|
||||
fullwidth: true,
|
||||
height: "300px",
|
||||
donut: true,
|
||||
donutWidth: 70,
|
||||
startAngle: 270,
|
||||
total: 200,
|
||||
showLabel: true,
|
||||
fetchData(id, period, category) {
|
||||
this.costService.getCostManagement(id, period, category).subscribe((response) => {
|
||||
this.data = response.results.data;
|
||||
this.filteredRows = this.data;
|
||||
this.kwhTerm = response.results.kwh;
|
||||
this.costTerm = response.results.cost;
|
||||
|
||||
this.data_cost = this.filteredRows.map((item) => ({
|
||||
building: item.name,
|
||||
categoryName: item.category_name,
|
||||
estimationCost: item.estimation_cost,
|
||||
totalUse: item.total_use,
|
||||
endDate: item.end_date,
|
||||
statusId: item.status_id,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
dataListMaster() {
|
||||
this.monitoringApiService.getMasterListData().subscribe((data) => {
|
||||
const dataCategory = data.data.find(
|
||||
(item) => item.name === "master_category"
|
||||
).headerDetailParam;
|
||||
this.dataMasterCategori = dataCategory.filter(
|
||||
(item) => item.status === "2"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
dataListBuilding() {
|
||||
this.monitoringApiService.getBuildingList().subscribe((data) => {
|
||||
this.dataBuildingList = data.data.filter((item) => item.statusId === 2);
|
||||
});
|
||||
}
|
||||
|
||||
dataCompWaterElectCost(buildingId) {
|
||||
this.costService.getCompWaterElectCost(buildingId).subscribe((data) => {
|
||||
this.dataComp = data.data;
|
||||
const dataChart2 = {
|
||||
donut: {
|
||||
series: [this.dataComp.elect, this.dataComp.water],
|
||||
labels: [],
|
||||
},
|
||||
};
|
||||
this.donutChart2 = {
|
||||
type: "Pie",
|
||||
data: this.dataChart2.donut,
|
||||
data: dataChart2.donut,
|
||||
options: {
|
||||
chartPadding: 0,
|
||||
fullwidth: true,
|
||||
|
@ -104,10 +131,10 @@ export class CostManagementComponent implements OnInit{
|
|||
donut: true,
|
||||
showLabel: true,
|
||||
startAngle: 0,
|
||||
labelInterpolationFnc: function (value) {
|
||||
const total = 82;
|
||||
return total + "C";
|
||||
},
|
||||
// labelInterpolationFnc: function (value) {
|
||||
// const total = 82;
|
||||
// return total + "C";
|
||||
// },
|
||||
},
|
||||
events: {
|
||||
draw(data: any): void {
|
||||
|
@ -124,15 +151,134 @@ export class CostManagementComponent implements OnInit{
|
|||
},
|
||||
},
|
||||
};
|
||||
|
||||
// this.dataChart2.donut.labels = ["Water", "Electricity"];
|
||||
});
|
||||
}
|
||||
|
||||
fetchData() {
|
||||
this.tableApiservice.getTableInitialisationData().subscribe((response) => {
|
||||
this.data = response;
|
||||
this.filteredRows = this.data.rows;
|
||||
dataCompPrevMonthCost(buildingId) {
|
||||
this.costService.getCompPrevMonthCost(buildingId).subscribe((data) => {
|
||||
this.dataCompPrev = data.data;
|
||||
const randomValue = Math.floor(Math.random() * (100 - 50 + 1)) + 50;
|
||||
const dataBar = {
|
||||
Bar: {
|
||||
labels: [[this.dataCompPrev[0].name], [this.dataCompPrev[1].name]],
|
||||
series: [[randomValue], [this.dataCompPrev[1].value]],
|
||||
},
|
||||
};
|
||||
this.barChart = {
|
||||
type: "Bar",
|
||||
data: dataBar.Bar,
|
||||
options: {
|
||||
fullwidth: true,
|
||||
width: "100px",
|
||||
height: "150px",
|
||||
seriesBarDistance: 100,
|
||||
axisX: {
|
||||
showGrid: false,
|
||||
showLabel: false,
|
||||
offset: 5,
|
||||
},
|
||||
axisY: {
|
||||
showGrid: false,
|
||||
showLabel: false,
|
||||
scaleMinSpace: 30,
|
||||
},
|
||||
classNames: {
|
||||
bar: "ct-bar", // Menambahkan kelas CSS ke batang
|
||||
},
|
||||
},
|
||||
responsiveOptions: [
|
||||
[
|
||||
"screen and (max-width: 640px)",
|
||||
{
|
||||
seriesBarDistance: 100,
|
||||
axisX: {
|
||||
labelInterpolationFnc: function (value) {
|
||||
return value[0];
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
dataCompActEstCost(buildingId) {
|
||||
this.costService.getCompActEstCost(buildingId).subscribe((data) => {
|
||||
this.dataCompAct = data.data[0];
|
||||
});
|
||||
}
|
||||
|
||||
syncData() {
|
||||
const dataDate = {
|
||||
buildingId: this.buildingSelected,
|
||||
periode: this.dateSelected,
|
||||
};
|
||||
this.spinnerActive = true;
|
||||
this.costService.getSyncCost(dataDate).subscribe((data) => {
|
||||
console.log(data);
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.spinnerActive = false;
|
||||
this.fetchData(this.buildingSelected, this.dateSelected, this.categorySelected );
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
actualData() {
|
||||
this.spinnerActiveActual = true;
|
||||
this.costService
|
||||
.getRealCostByBuildingId(4, this.dateSelected)
|
||||
.subscribe((data) => {
|
||||
console.log(data.data[0]);
|
||||
// this.costTerm = data.data[0].est_cost
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.spinnerActiveActual = false;
|
||||
this.fetchData(this.buildingSelected, this.dateSelected, this.categorySelected );
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
doFilter() {
|
||||
const requestData = {
|
||||
building: this.buildingSelected,
|
||||
category: this.categorySelected,
|
||||
date: this.dateSelected,
|
||||
searchTerm: this.searchTerm,
|
||||
};
|
||||
this.fetchData(this.buildingSelected, this.dateSelected, this.categorySelected );
|
||||
this.dataCompWaterElectCost(this.buildingSelected);
|
||||
this.dataCompPrevMonthCost(this.buildingSelected);
|
||||
this.dataCompActEstCost(this.buildingSelected);
|
||||
}
|
||||
|
||||
addFieldValue() {
|
||||
const modalRef = this.modalService.open(ModalAddActualComponent, {
|
||||
size: "sm",
|
||||
});
|
||||
modalRef.componentInstance.newAttribute = {
|
||||
id: null,
|
||||
name: "",
|
||||
};
|
||||
|
||||
modalRef.result.then(
|
||||
(result) => {
|
||||
if (result) {
|
||||
this.rows.push(result);
|
||||
this.rows = [...this.rows];
|
||||
}
|
||||
},
|
||||
(reason) => {
|
||||
console.log(`Dismissed: ${reason}`);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
focusElement(focucedElement: any) {
|
||||
this.focucedElement = focucedElement;
|
||||
}
|
||||
|
||||
filterRows() {
|
||||
if (!this.searchTerm) {
|
||||
this.filteredRows = [...this.data.rows];
|
||||
|
@ -147,8 +293,7 @@ export class CostManagementComponent implements OnInit{
|
|||
const searchTermLC = this.searchTerm.toLowerCase();
|
||||
return Object.values(row).some(
|
||||
(value) =>
|
||||
value !== null &&
|
||||
value.toString().toLowerCase().includes(searchTermLC)
|
||||
value !== null && value.toString().toLowerCase().includes(searchTermLC)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -169,4 +314,6 @@ export class CostManagementComponent implements OnInit{
|
|||
onTouchStart(event: Event) {
|
||||
event.preventDefault(); // Add this if necessary
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CommonModule, DatePipe } from '@angular/common';
|
||||
import { CostManagementComponent } from './cost-management.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { BreadcrumbModule } from 'src/app/_layout/breadcrumb/breadcrumb.module';
|
||||
|
@ -15,13 +15,16 @@ import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
|||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
import { ChartistModule } from 'ng-chartist';
|
||||
import { MatchHeightModule } from '../../partials/general/match-height/match-height.module';
|
||||
import { ModalAddActualComponent } from './modal-add-actual/modal-add-actual.component';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CostManagementComponent,
|
||||
AddEditCostComponent
|
||||
AddEditCostComponent,
|
||||
ModalAddActualComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
@ -36,6 +39,7 @@ import { ChartistModule } from 'ng-chartist';
|
|||
NgxDatatableModule,
|
||||
NgChartsModule,
|
||||
ChartistModule,
|
||||
MatchHeightModule,
|
||||
BlockUIModule.forRoot({
|
||||
template: BlockTemplateComponent
|
||||
}),
|
||||
|
@ -60,6 +64,9 @@ import { ChartistModule } from 'ng-chartist';
|
|||
data: { mode: 'view' }
|
||||
}
|
||||
])
|
||||
]
|
||||
],
|
||||
providers: [
|
||||
DatePipe // Add DatePipe to providers
|
||||
],
|
||||
})
|
||||
export class CostManagementModule { }
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* modal-add-edit.component.css */
|
||||
::ng-deep .modal-backdrop.show {
|
||||
z-index: auto !important;
|
||||
}
|
||||
|
||||
::ng-deep .input-group-append .btn {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-radius: 0;
|
||||
border-left: 0;
|
||||
flex-grow: 0;
|
||||
border-left: 1px solid #ced4da;
|
||||
padding: 0.375rem 0.75rem;
|
||||
}
|
||||
|
||||
::ng-deep .input-group {
|
||||
display: flex;
|
||||
flex-wrap: nowrap; /* Prevents wrapping of the items */
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
::ng-deep .form-control {
|
||||
flex-grow: 1; /* Ensures select takes up available space */
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
::ng-deep .input-group select,
|
||||
::ng-deep .input-group .input-group-append .btn {
|
||||
padding-right: 5px; /* Adjust padding if necessary */
|
||||
}
|
||||
|
||||
::ng-deep .input-group .form-control {
|
||||
margin-right: 2px; /* Adjust margin to make space */
|
||||
}
|
||||
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: calc(1.5em + 0.75rem + 2px);
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #495057;
|
||||
background-color: #fff;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<div class="modal-header">
|
||||
<!-- <h4 class="modal-title">Add New Row</h4> -->
|
||||
<button type="button" class="close" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form [formGroup]="myForm">
|
||||
<div class="form-group">
|
||||
<label for="name">Name:</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="name"
|
||||
formControlName="name"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
(click)="activeModal.dismiss('Cross click')"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" (click)="addRow()">
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ModalAddActualComponent } from './modal-add-actual.component';
|
||||
|
||||
describe('ModalAddActualComponent', () => {
|
||||
let component: ModalAddActualComponent;
|
||||
let fixture: ComponentFixture<ModalAddActualComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ModalAddActualComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ModalAddActualComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
@Component({
|
||||
selector: 'app-modal-add-actual',
|
||||
templateUrl: './modal-add-actual.component.html',
|
||||
styleUrls: ['./modal-add-actual.component.css']
|
||||
})
|
||||
export class ModalAddActualComponent {
|
||||
@Input() newAttribute: any = {};
|
||||
myForm: FormGroup;
|
||||
|
||||
constructor(public activeModal: NgbActiveModal, private fb: FormBuilder) {
|
||||
this.createForm();
|
||||
}
|
||||
|
||||
createForm() {
|
||||
this.myForm = this.fb.group({
|
||||
name: ['', Validators.required],
|
||||
});
|
||||
}
|
||||
|
||||
addRow() {
|
||||
if (this.myForm.valid) {
|
||||
this.activeModal.close(this.myForm.value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -94,7 +94,7 @@
|
|||
[items]="singleSelectArray"
|
||||
[searchable]="true"
|
||||
bindLabel="item_text"
|
||||
placeholder="Select Month"
|
||||
placeholder="Select Type"
|
||||
[(ngModel)]="singlebasicSelected"
|
||||
>
|
||||
</ng-select>
|
||||
|
|
|
@ -67,16 +67,14 @@ export class DeviceComponent implements OnInit {
|
|||
console.log(this.filteredRows);
|
||||
this.totalOn = this.filteredRows.filter((row) => row.statusEntity.name.toLowerCase() === 'aktif').length
|
||||
this.totalOff = this.filteredRows.filter((row) => row.statusEntity.name.toLowerCase() === 'nonaktif').length
|
||||
// console.log(totalon);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
filterRows() {
|
||||
if (!this.searchTerm) {
|
||||
this.filteredRows = [...this.data.rows];
|
||||
this.filteredRows = [...this.data.results.data];
|
||||
} else {
|
||||
this.filteredRows = this.data.rows.filter((row) =>
|
||||
this.filteredRows = this.data.results.data.filter((row) =>
|
||||
this.rowContainsSearchTerm(row)
|
||||
);
|
||||
}
|
||||
|
@ -136,13 +134,9 @@ export class DeviceComponent implements OnInit {
|
|||
console.log(res);
|
||||
});
|
||||
|
||||
// Lakukan proses tambahan (misalnya, panggil API atau proses yang memakan waktu)
|
||||
setTimeout(() => {
|
||||
// Selesaikan proses tambahan di sini
|
||||
|
||||
// Nonaktifkan spinner setelah proses selesai
|
||||
this.spinnerActive = false;
|
||||
this.fetchData();
|
||||
}, 3000); // Ganti 3000 dengan waktu yang sesuai dengan proses tambahan Anda (dalam milidetik)
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
<div class="row">
|
||||
<div class="col-12" *blockUI="'barCharts'; message: 'Loading'">
|
||||
<m-card [options]="options">
|
||||
<ng-container mCardHeaderTitle> Appointment </ng-container>
|
||||
<ng-container mCardHeaderTitle> </ng-container>
|
||||
<ng-container mCardBody>
|
||||
<div class="z" style="display: block">
|
||||
<canvas
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
import { Injectable } from "@angular/core";
|
||||
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class CostManagementService {
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
getCostManagement(id, period, category): Observable<any> {
|
||||
const baseUrl = `https://kapi.absys.ninja/hemat/cost_management`;
|
||||
const params = new URLSearchParams({
|
||||
page: "1",
|
||||
limit: "100",
|
||||
building_id: id,
|
||||
periode: period,
|
||||
});
|
||||
if (category) {
|
||||
params.append("category_id", category);
|
||||
}
|
||||
const url = `${baseUrl}?${params.toString()}`;
|
||||
const headers = new HttpHeaders({
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
|
||||
});
|
||||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
getCompWaterElectCost(id): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/cost_management/card/comp-water-elect-cost?building_id=${id}`;
|
||||
const headers = new HttpHeaders({
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
|
||||
});
|
||||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
getCompPrevMonthCost(id): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/cost_management/card/comp-prev-month-cost?building_id=${id}`;
|
||||
const headers = new HttpHeaders({
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
|
||||
});
|
||||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
getCompActEstCost(id): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/cost_management/card/comp-act-est-cost?building_id=${id}`;
|
||||
const headers = new HttpHeaders({
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
|
||||
});
|
||||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
|
||||
getSyncCost(data: any): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/cost_management/cost/sync`;
|
||||
const headers = new HttpHeaders({
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
|
||||
});
|
||||
return this.http.post<any>(url, data, { headers });
|
||||
}
|
||||
|
||||
getRealCostByBuildingId(id: any, period: any): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/real-cost/get/byBuildingId?building_id=${id}&periode=${period}`;
|
||||
const headers = new HttpHeaders({
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
|
||||
});
|
||||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
}
|
|
@ -135,6 +135,15 @@ export class BuildingService {
|
|||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
|
||||
getCostManagement(page: number = 1, limit: number = 100, ): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/cost_management?page=${page}&limit=${limit}&building_id=4&periode=2024-06`;
|
||||
const headers = new HttpHeaders({
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': 'j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT'
|
||||
});
|
||||
return this.http.get<any>(url, { headers });
|
||||
}
|
||||
|
||||
postHeaderDetailParam(data: any): Observable<any> {
|
||||
const url = `https://kapi.absys.ninja/hemat/header-detail-param`;
|
||||
const headers = new HttpHeaders({
|
||||
|
|
|
@ -122,6 +122,7 @@ export class LoginComponent implements OnInit {
|
|||
// Store the user profile information
|
||||
const userProfile = {
|
||||
displayName: this.loginForm.value.email,
|
||||
buildingId: 4
|
||||
};
|
||||
localStorage.setItem('currentUser', JSON.stringify(userProfile));
|
||||
|
||||
|
|
Loading…
Reference in New Issue