Compare commits
No commits in common. "develop" and "main" have entirely different histories.
File diff suppressed because it is too large
Load Diff
|
@ -62,8 +62,6 @@
|
||||||
"js-datepicker": "^5.18.2",
|
"js-datepicker": "^5.18.2",
|
||||||
"jspdf": "^2.5.1",
|
"jspdf": "^2.5.1",
|
||||||
"jspdf-autotable": "^3.5.28",
|
"jspdf-autotable": "^3.5.28",
|
||||||
"jwt-decode": "^4.0.0",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"ng-chartist": "^4.1.0",
|
"ng-chartist": "^4.1.0",
|
||||||
"ng-multiselect-dropdown": "^0.3.9",
|
"ng-multiselect-dropdown": "^0.3.9",
|
||||||
|
@ -73,7 +71,6 @@
|
||||||
"ngx-echarts": "^15.0.1",
|
"ngx-echarts": "^15.0.1",
|
||||||
"ngx-google-places-autocomplete": "^2.0.5",
|
"ngx-google-places-autocomplete": "^2.0.5",
|
||||||
"ngx-image-cropper": "^6.3.2",
|
"ngx-image-cropper": "^6.3.2",
|
||||||
"ngx-mask": "^14.2.4",
|
|
||||||
"ngx-masonry": "^14.0.1",
|
"ngx-masonry": "^14.0.1",
|
||||||
"ngx-perfect-scrollbar": "^10.1.1",
|
"ngx-perfect-scrollbar": "^10.1.1",
|
||||||
"ngx-quill": "^20.0.1",
|
"ngx-quill": "^20.0.1",
|
||||||
|
@ -85,16 +82,13 @@
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"quill-delta": "^5.0.0",
|
"quill-delta": "^5.0.0",
|
||||||
"quill-mention": "^3.1.0",
|
"quill-mention": "^3.1.0",
|
||||||
"remixicon": "^4.3.0",
|
|
||||||
"rxjs": "^7.5.5",
|
"rxjs": "^7.5.5",
|
||||||
"sass": "^1.57.1",
|
"sass": "^1.57.1",
|
||||||
"save": "^2.9.0",
|
"save": "^2.9.0",
|
||||||
"sweetalert2": "^11.11.0",
|
|
||||||
"tree-ngx": "^4.3.0",
|
"tree-ngx": "^4.3.0",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"util": "^0.12.5",
|
"util": "^0.12.5",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"video.js": "^8.12.0",
|
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -18,12 +18,3 @@
|
||||||
transform: translate(40px, 40px) !important;
|
transform: translate(40px, 40px) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb-item::before {
|
|
||||||
content: none !important; /* Removes any default content, such as "-" */
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumb-item + .breadcrumb-item::before {
|
|
||||||
content: none !important; /* Removes any default content, such as "-" */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,27 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div
|
<div class="content-header-left col-md-6 col-12 mb-2 breadcrumb-new" *ngIf="breadcrumb">
|
||||||
class="content-header-left col-md-6 col-12 mb-2 breadcrumb-new"
|
<h3 class="content-header-title mb-0 d-inline-block">{{breadcrumb.mainlabel}}</h3>
|
||||||
*ngIf="breadcrumb"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
*ngIf="breadcrumb.isLinkBack"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-icon btn-pure secondary mr-1"
|
|
||||||
routerLink="{{ breadcrumb.linkBack }}"
|
|
||||||
>
|
|
||||||
<i class="feather ft-chevron-left" style="color: #242222"></i>
|
|
||||||
</button>
|
|
||||||
<h3 class="content-header-title mb-0 d-inline-block" style="color: #242222">
|
|
||||||
{{ breadcrumb.mainlabel }}
|
|
||||||
</h3>
|
|
||||||
<div class="row breadcrumbs-top d-inline-block">
|
<div class="row breadcrumbs-top d-inline-block">
|
||||||
<div class="breadcrumb-wrapper col-12">
|
<div class="breadcrumb-wrapper col-12">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<ng-container *ngFor="let link of breadcrumb.links; let last = last">
|
<li class="breadcrumb-item" *ngFor="let link of breadcrumb.links">
|
||||||
<li class="breadcrumb-item" style="color: #242222">
|
<a *ngIf="link.isLink" routerLink="{{link.link}}">{{link.name}}</a>
|
||||||
<ng-container *ngIf="link.isLink; else notLink">
|
<span *ngIf="!link.isLink">{{link.name}}</span>
|
||||||
<a routerLink="{{ link.link }}" style="color: #242222">{{ link.name }}</a>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template #notLink>
|
|
||||||
<span style="color: #242222">{{ link.name }}</span>
|
|
||||||
</ng-template>
|
|
||||||
<span *ngIf="!last" class="breadcrumb-arrow" style="color: #242222; margin: 0 5px;">
|
|
||||||
<i class="feather ft-chevron-right"></i>
|
|
||||||
</span>
|
|
||||||
</li>
|
</li>
|
||||||
</ng-container>
|
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="content-header-right col-md-6 col-12">
|
||||||
|
<div class="d-inline-block float-md-right" ngbDropdown>
|
||||||
|
<button class="btn btn-info" id="dropdownBasic1" ngbDropdownToggle>Action</button>
|
||||||
|
<div ngbDropdownMenu class="arrow _dropdown_mob dropdown-menu-right" aria-labelledby="dropdownBasic1">
|
||||||
|
<button class="dropdown-item">Calender</button>
|
||||||
|
<button class="dropdown-item">Cart</button>
|
||||||
|
<button class="dropdown-item">Support</button>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<button class="dropdown-item">Settings</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,68 +1,29 @@
|
||||||
<footer
|
<footer id="footer" class="footer footer-static footer-light navbar-border navbar-shadow" *ngIf="showFooter">
|
||||||
id="footer"
|
<p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2"><span
|
||||||
class="footer footer-static footer-light navbar-border navbar-shadow"
|
class="float-md-left d-block d-md-inline-block">Copyright © 2022 <a [routerLink]=""
|
||||||
*ngIf="showFooter"
|
class="text-bold-800 grey darken-2" href="https://themeforest.net/user/pixinvent/portfolio?ref=pixinvent"
|
||||||
style="border: none !important;"
|
target="_blank">PIXINVENT </a></span><span *ngIf="!hideMadeWithLove"
|
||||||
>
|
class="float-md-right d-block d-md-inline-block d-none d-lg-block">Hand-crafted & Made with <i
|
||||||
<p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2">
|
class="feather ft-heart pink"></i>
|
||||||
<span class="float-md-ceter d-block d-md-inline-block"
|
<span id="scroll-top"></span></span></p>
|
||||||
>Copyright © 2024
|
|
||||||
<a
|
|
||||||
[routerLink]=""
|
|
||||||
class="text-bold-800 grey darken-2"
|
|
||||||
href="https://allbestsistem.com/"
|
|
||||||
target="_blank"
|
|
||||||
style="background-color: #ffffff !important;"
|
|
||||||
>Smart Building Management Systems (V@2024-08-28.1)
|
|
||||||
</a></span
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<footer
|
<footer id="footer" class="footer fixed-bottom footer-light navbar-border navbar-shadow" *ngIf="fixedFooter">
|
||||||
id="footer"
|
<p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2"><span
|
||||||
class="footer fixed-bottom footer-light navbar-border navbar-shadow"
|
class="float-md-left d-block d-md-inline-block">Copyright © 2022 <a [routerLink]=""
|
||||||
*ngIf="fixedFooter"
|
class="text-bold-800 grey darken-2" href="https://themeforest.net/user/pixinvent/portfolio?ref=pixinvent"
|
||||||
>
|
target="_blank">PIXINVENT </a></span><span *ngIf="!hideMadeWithLove"
|
||||||
<p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2">
|
class="float-md-right d-block d-md-inline-block d-none d-lg-block">Hand-crafted & Made with <i
|
||||||
<span class="float-md-left d-block d-md-inline-block"
|
class="feather ft-heart pink"></i>
|
||||||
>Copyright © 2022
|
<span id="scroll-top"></span></span></p>
|
||||||
<a
|
|
||||||
[routerLink]=""
|
|
||||||
class="text-bold-800 grey darken-2"
|
|
||||||
href="https://themeforest.net/user/pixinvent/portfolio?ref=pixinvent"
|
|
||||||
target="_blank"
|
|
||||||
>PIXINVENT
|
|
||||||
</a></span
|
|
||||||
><span
|
|
||||||
*ngIf="!hideMadeWithLove"
|
|
||||||
class="float-md-right d-block d-md-inline-block d-none d-lg-block"
|
|
||||||
>Hand-crafted & Made with <i class="feather ft-heart pink"></i>
|
|
||||||
<span id="scroll-top"></span
|
|
||||||
></span>
|
|
||||||
</p>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<footer
|
<footer id="footer" class="footer fixed-bottom footer-dark navbar-border navbar-shadow" *ngIf="darkFooter">
|
||||||
id="footer"
|
<p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2"><span
|
||||||
class="footer fixed-bottom footer-dark navbar-border navbar-shadow"
|
class="float-md-left d-block d-md-inline-block">Copyright © 2022 <a [routerLink]=""
|
||||||
*ngIf="darkFooter"
|
class="text-bold-800 grey darken-2" href="https://themeforest.net/user/pixinvent/portfolio?ref=pixinvent"
|
||||||
>
|
target="_blank">PIXINVENT </a></span><span *ngIf="!hideMadeWithLove"
|
||||||
<p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2">
|
class="float-md-right d-block d-md-inline-block d-none d-lg-block">Hand-crafted & Made with <i
|
||||||
<span class="float-md-left d-block d-md-inline-block"
|
class="feather ft-heart pink"></i>
|
||||||
>Copyright © 2022
|
<span id="scroll-top"></span></span></p>
|
||||||
<a
|
|
||||||
[routerLink]=""
|
|
||||||
class="text-bold-800 grey darken-2"
|
|
||||||
href="https://themeforest.net/user/pixinvent/portfolio?ref=pixinvent"
|
|
||||||
target="_blank"
|
|
||||||
>PIXINVENT
|
|
||||||
</a></span
|
|
||||||
><span
|
|
||||||
*ngIf="!hideMadeWithLove"
|
|
||||||
class="float-md-right d-block d-md-inline-block d-none d-lg-block"
|
|
||||||
>Hand-crafted & Made with <i class="feather ft-heart pink"></i>
|
|
||||||
<span id="scroll-top"></span
|
|
||||||
></span>
|
|
||||||
</p>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -2,17 +2,15 @@
|
||||||
<nav
|
<nav
|
||||||
class="top-header header-navbar navbar-expand-md navbar navbar-with-menu navbar-without-dd-arrow navbar-static-top navbar-light navbar-brand-center"
|
class="top-header header-navbar navbar-expand-md navbar navbar-with-menu navbar-without-dd-arrow navbar-static-top navbar-light navbar-brand-center"
|
||||||
id="top-header" [ngClass]="selectedHeaderNavBarClass">
|
id="top-header" [ngClass]="selectedHeaderNavBarClass">
|
||||||
<div class="navbar-wrapper" style="background-color: #2c343b !important;">
|
<div class="navbar-wrapper">
|
||||||
<div id="navbar-header" class="navbar-header">
|
<div id="navbar-header" class="navbar-header">
|
||||||
<ul class="nav navbar-nav flex-row">
|
<ul class="nav navbar-nav flex-row">
|
||||||
<li class="nav-item mobile-menu d-md-none mr-auto" ><a
|
<li class="nav-item mobile-menu d-md-none mr-auto" ><a
|
||||||
class="nav-link nav-menu-main menu-toggle hidden-xs11" (click)="toggleNavigation($event)"><i
|
class="nav-link nav-menu-main menu-toggle hidden-xs11" (click)="toggleNavigation($event)"><i
|
||||||
class="feather ft-menu font-large-1" ></i></a></li>
|
class="feather ft-menu font-large-1" ></i></a></li>
|
||||||
<li class="nav-item"><a [routerLink]="['/monitoring']" class="navbar-brand"><img class="brand-logo" alt="modern admin logo"
|
<li class="nav-item"><a [routerLink]="['/dashboard/sales']" class="navbar-brand"><img class="brand-logo" alt="modern admin logo"
|
||||||
src="../../../../assets/images/logo/logo.png">
|
src="../../../../assets/images/logo/logo.png">
|
||||||
<!-- <h3 class="brand-text">{{_themeSettingsConfig.brand.brand_name}}</h3> -->
|
<h3 class="brand-text">{{_themeSettingsConfig.brand.brand_name}}</h3>
|
||||||
<!-- <h3 class="brand-text">{{_themeSettingsConfig.brand.brand_name}}</h3> -->
|
|
||||||
<h3 class="brand-text" style="color: aliceblue;">Hemat</h3>
|
|
||||||
</a></li>
|
</a></li>
|
||||||
|
|
||||||
<li class="nav-item d-md-none"><a class="nav-link open-navbar-container" data-toggle="collapse"
|
<li class="nav-item d-md-none"><a class="nav-link open-navbar-container" data-toggle="collapse"
|
||||||
|
@ -22,7 +20,7 @@
|
||||||
<div class="navbar-container content">
|
<div class="navbar-container content">
|
||||||
<div class="collapse navbar-collapse show" id="navbar-mobile">
|
<div class="collapse navbar-collapse show" id="navbar-mobile">
|
||||||
<ul class="nav navbar-nav mr-auto float-left">
|
<ul class="nav navbar-nav mr-auto float-left">
|
||||||
<!-- <li class="nav-item d-none d-md-block"><a [routerLink]="" class="nav-link nav-menu-main menu-toggle hidden-xs"
|
<li class="nav-item d-none d-md-block"><a [routerLink]="" class="nav-link nav-menu-main menu-toggle hidden-xs"
|
||||||
(click)="toggleFixMenu($event)" ><i class="feather ft-menu"></i></a></li>
|
(click)="toggleFixMenu($event)" ><i class="feather ft-menu"></i></a></li>
|
||||||
<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>
|
(click)="toggleFullScreen()" *ngIf ="maximize === 'on'"><i class="ficon feather ft-maximize"></i></a></li>
|
||||||
|
@ -31,10 +29,10 @@
|
||||||
<div class="search-input" [ngClass]="{'open': isHeaderSearchOpen}">
|
<div class="search-input" [ngClass]="{'open': isHeaderSearchOpen}">
|
||||||
<input class="input" type="text" placeholder="Explore Modern...">
|
<input class="input" type="text" placeholder="Explore Modern...">
|
||||||
</div>
|
</div>
|
||||||
</li> -->
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav float-right" >
|
<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">
|
<a [routerLink]="" class="dropdown-toggle nav-link" ngbDropdownToggle id="dropdown-flag">
|
||||||
<i class="flag-icon flag-icon-gb"></i><span class="selected-language"></span>
|
<i class="flag-icon flag-icon-gb"></i><span class="selected-language"></span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -52,8 +50,8 @@
|
||||||
<i class="flag-icon flag-icon-de"></i> German
|
<i class="flag-icon flag-icon-de"></i> German
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li> -->
|
</li>
|
||||||
<!-- <li class="dropdown-notification nav-item dropdown" ngbDropdown *ngIf ="notification === 'on'">
|
<li class="dropdown-notification nav-item dropdown" ngbDropdown *ngIf ="notification === 'on'">
|
||||||
<a class="nav-link nav-link-label" ngbDropdownToggle>
|
<a class="nav-link nav-link-label" ngbDropdownToggle>
|
||||||
<i class="ficon feather ft-bell"></i>
|
<i class="ficon feather ft-bell"></i>
|
||||||
<span class="badge badge-pill badge-danger badge-up badge-glow">5</span>
|
<span class="badge badge-pill badge-danger badge-up badge-glow">5</span>
|
||||||
|
@ -126,8 +124,8 @@
|
||||||
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
||||||
href="javascript:void(0)">Read all notifications</a></li>
|
href="javascript:void(0)">Read all notifications</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li> -->
|
</li>
|
||||||
<!-- <li class="dropdown-notification nav-item" ngbDropdown *ngIf ="email === 'on'">
|
<li class="dropdown-notification nav-item" ngbDropdown *ngIf ="email === 'on'">
|
||||||
<a class="nav-link nav-link-label" ngbDropdownToggle><i class="ficon feather ft-mail"></i></a>
|
<a class="nav-link nav-link-label" ngbDropdownToggle><i class="ficon feather ft-mail"></i></a>
|
||||||
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
||||||
<li class="dropdown-menu-header">
|
<li class="dropdown-menu-header">
|
||||||
|
@ -187,7 +185,7 @@
|
||||||
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
||||||
href="javascript:void(0)">Read all messages</a></li>
|
href="javascript:void(0)">Read all messages</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li> -->
|
</li>
|
||||||
|
|
||||||
<li class="dropdown-user nav-item" ngbDropdown>
|
<li class="dropdown-user nav-item" ngbDropdown>
|
||||||
<a class="nav-link dropdown-user-link" ngbDropdownToggle>
|
<a class="nav-link dropdown-user-link" ngbDropdownToggle>
|
||||||
|
|
|
@ -33,9 +33,3 @@
|
||||||
.header-navbar .navbar-header .navbar-brand .brand-text {
|
.header-navbar .navbar-header .navbar-brand .brand-text {
|
||||||
padding-left: 11px !important;
|
padding-left: 11px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-text-wrapper {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,96 +1,44 @@
|
||||||
<nav
|
<nav class="header-navbar navbar-expand-md navbar navbar-with-menu navbar-without-dd-arrow fixed-top navbar-shadow"
|
||||||
class="header-navbar navbar-expand-md navbar navbar-with-menu navbar-without-dd-arrow fixed-top navbar-shadow"
|
[ngClass]="selectedHeaderNavBarClass">
|
||||||
[ngClass]="selectedHeaderNavBarClass"
|
|
||||||
>
|
|
||||||
<div class="navbar-wrapper">
|
<div class="navbar-wrapper">
|
||||||
<div
|
<div id="navbar-header" class="navbar-header" [ngClass]="selectedNavBarHeaderClass"
|
||||||
id="navbar-header"
|
(mouseenter)="mouseEnter($event)" (mouseleave)="mouseLeave($event)">
|
||||||
class="navbar-header"
|
|
||||||
[ngClass]="selectedNavBarHeaderClass"
|
|
||||||
(mouseenter)="mouseEnter($event)"
|
|
||||||
(mouseleave)="mouseLeave($event)"
|
|
||||||
style="background-color: #fbfbfb !important"
|
|
||||||
>
|
|
||||||
<ul class="nav navbar-nav flex-row">
|
<ul class="nav navbar-nav flex-row">
|
||||||
<!-- Remove position relative in responsive -->
|
<!-- Remove position relative in responsive -->
|
||||||
<li class="nav-item mobile-menu d-lg-none mr-auto">
|
<li class="nav-item mobile-menu d-lg-none mr-auto"><a class="nav-link nav-menu-main menu-toggle hidden-xs11"
|
||||||
<a
|
(click)="toggleNavigation($event)">
|
||||||
class="nav-link nav-menu-main menu-toggle hidden-xs11"
|
<i class="feather ft-menu font-large-1"></i></a></li>
|
||||||
(click)="toggleNavigation($event)"
|
<li class="nav-item mr-auto"><a [routerLink]="['/dashboard/sales']" class="navbar-brand"
|
||||||
>
|
routerLink="/dashboard/sales"><img class="brand-logo" alt="modern admin logo"
|
||||||
<i class="feather ft-menu font-large-1"></i
|
[src]="_themeSettingsConfig.brand.logo.value">
|
||||||
></a>
|
<h3 class="brand-text">{{_themeSettingsConfig.brand.brand_name}}</h3>
|
||||||
</li>
|
</a></li>
|
||||||
<li class="nav-item mr-auto">
|
|
||||||
<a
|
|
||||||
[routerLink]="['/monitoring']"
|
|
||||||
class="navbar-brand"
|
|
||||||
routerLink="/monitoring"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="brand-logo"
|
|
||||||
alt="modern admin logo"
|
|
||||||
src="../../../../assets/images/logo/smart2.png"
|
|
||||||
/>
|
|
||||||
<!-- <h3 class="brand-text" style="color: #ffffff;">{{_themeSettingsConfig.brand.brand_name}}</h3> -->
|
|
||||||
<div
|
|
||||||
class="brand-text-wrapper"
|
|
||||||
style="
|
|
||||||
max-width: 200px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<h3 class="brand-text" style="color: #242222; margin: 0">
|
|
||||||
Smart Building
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item d-none d-md-block nav-toggle">
|
<li class="nav-item d-none d-md-block nav-toggle">
|
||||||
<a
|
<a [routerLink]="" class="nav-link modern-nav-toggle pr-0" data-toggle="collapse"
|
||||||
[routerLink]=""
|
(click)="toggleFixMenu($event)">
|
||||||
class="nav-link modern-nav-toggle pr-0"
|
<i class="feather toggle-icon font-medium-3 white"
|
||||||
data-toggle="collapse"
|
[ngClass]="{'ft-toggle-left': _themeSettingsConfig.menu === 'collapse','ft-toggle-right': _themeSettingsConfig.menu === 'expand'}"></i>
|
||||||
|
|
||||||
(click)="toggleFixMenu($event)"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="feather toggle-icon font-medium-3 white"
|
|
||||||
[ngClass]="{
|
|
||||||
'ft-toggle-left': _themeSettingsConfig.menu === 'collapse',
|
|
||||||
'ft-toggle-right': _themeSettingsConfig.menu === 'expand'
|
|
||||||
}"
|
|
||||||
></i>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item d-lg-none">
|
<li class="nav-item d-lg-none"><a class="nav-link open-navbar-container" data-toggle="collapse"
|
||||||
<a
|
data-target="#navbar-mobile" (click)="toggleNavbar($event)"><i class="la la-ellipsis-v"></i></a></li>
|
||||||
class="nav-link open-navbar-container"
|
|
||||||
data-toggle="collapse"
|
|
||||||
data-target="#navbar-mobile"
|
|
||||||
(click)="toggleNavbar($event)"
|
|
||||||
><i class="la la-ellipsis-v"></i
|
|
||||||
></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<!-- New-->
|
<!-- New-->
|
||||||
<div class="navbar-container content" [hidden]="isMobile && !showNavbar">
|
<div class="navbar-container content" [hidden]="isMobile && !showNavbar">
|
||||||
<div class="collapse navbar-collapse" id="navbar-mobile">
|
<div class="collapse navbar-collapse" id="navbar-mobile">
|
||||||
<ul class="nav navbar-nav mr-auto float-left">
|
<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>
|
(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()"
|
<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>
|
*ngIf="search === 'on'"><i class="ficon feather ft-search"></i></a>
|
||||||
<div class="search-input" [ngClass]="{'open': isHeaderSearchOpen}">
|
<div class="search-input" [ngClass]="{'open': isHeaderSearchOpen}">
|
||||||
<input class="input" type="text" placeholder="Explore Modern...">
|
<input class="input" type="text" placeholder="Explore Modern...">
|
||||||
</div>
|
</div>
|
||||||
</li> -->
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav float-right">
|
<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">
|
<a [routerLink]="" class="dropdown-toggle nav-link" ngbDropdownToggle id="dropdown-flag">
|
||||||
<i class="flag-icon flag-icon-gb"></i><span class="selected-language"></span>
|
<i class="flag-icon flag-icon-gb"></i><span class="selected-language"></span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -108,152 +56,84 @@
|
||||||
<i class="flag-icon flag-icon-de"></i> German
|
<i class="flag-icon flag-icon-de"></i> German
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li> -->
|
</li>
|
||||||
<li
|
<li class="dropdown-notification nav-item dropdown" ngbDropdown *ngIf="notification === 'on'">
|
||||||
class="dropdown-notification nav-item dropdown"
|
<a class="nav-link nav-link-label" ngbDropdownToggle>
|
||||||
ngbDropdown
|
<i class="ficon feather ft-bell"></i>
|
||||||
*ngIf="notification === 'on'"
|
|
||||||
>
|
|
||||||
<!-- <a class="nav-link nav-link-label" ngbDropdownToggle>
|
|
||||||
<i class="ficon feather ft-bell" style="color: #bef264"></i>
|
|
||||||
<span class="badge badge-pill badge-danger badge-up badge-glow">5</span>
|
<span class="badge badge-pill badge-danger badge-up badge-glow">5</span>
|
||||||
</a> -->
|
|
||||||
<a class="nav-link nav-link-label">
|
|
||||||
<i class="ficon la la-bell" style="color: #242424"></i>
|
|
||||||
<!-- <span class="badge badge-pill badge-danger badge-up badge-glow">5</span> -->
|
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
||||||
<li class="dropdown-menu-header">
|
<li class="dropdown-menu-header">
|
||||||
<h6 class="dropdown-header m-0">
|
<h6 class="dropdown-header m-0"><span class="grey darken-2">Notifications</span></h6><span
|
||||||
<span class="grey darken-2">Notifications</span>
|
class="notification-tag badge badge-default badge-danger float-right m-0">5 New</span>
|
||||||
</h6>
|
|
||||||
<span
|
|
||||||
class="notification-tag badge badge-default badge-danger float-right m-0"
|
|
||||||
>5 New</span
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li class="scrollable-container media-list w-100 ps-container ps-theme-dark ps-active-y" fxFlex="auto" [perfectScrollbar]="config">
|
||||||
class="scrollable-container media-list w-100 ps-container ps-theme-dark ps-active-y"
|
|
||||||
fxFlex="auto"
|
|
||||||
[perfectScrollbar]="config"
|
|
||||||
>
|
|
||||||
<a href="javascript:void(0)">
|
<a href="javascript:void(0)">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left align-self-center">
|
<div class="media-left align-self-center"><i
|
||||||
<i
|
class="feather ft-plus-square icon-bg-circle bg-cyan"></i>
|
||||||
class="feather ft-plus-square icon-bg-circle bg-cyan"
|
|
||||||
></i>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<h6 class="media-heading">You have new order!</h6>
|
<h6 class="media-heading">You have new order!</h6>
|
||||||
<p class="notification-text font-small-3 text-muted">
|
<p class="notification-text font-small-3 text-muted">Lorem ipsum dolor sit amet, consectetuer
|
||||||
Lorem ipsum dolor sit amet, consectetuer elit.
|
elit.</p><small>
|
||||||
</p>
|
<time class="media-meta text-muted" datetime="2015-06-11T18:29:20+08:00">30 minutes
|
||||||
<small>
|
ago</time></small>
|
||||||
<time
|
|
||||||
class="media-meta text-muted"
|
|
||||||
datetime="2015-06-11T18:29:20+08:00"
|
|
||||||
>30 minutes ago</time
|
|
||||||
></small
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="javascript:void(0)">
|
<a href="javascript:void(0)">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left align-self-center">
|
<div class="media-left align-self-center"><i
|
||||||
<i
|
class="feather ft-download-cloud icon-bg-circle bg-red bg-darken-1"></i></div>
|
||||||
class="feather ft-download-cloud icon-bg-circle bg-red bg-darken-1"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<h6 class="media-heading red darken-1">
|
<h6 class="media-heading red darken-1">99% Server load</h6>
|
||||||
99% Server load
|
<p class="notification-text font-small-3 text-muted">Aliquam tincidunt mauris eu risus.</p><small>
|
||||||
</h6>
|
<time class="media-meta text-muted" datetime="2015-06-11T18:29:20+08:00">Five hour
|
||||||
<p class="notification-text font-small-3 text-muted">
|
ago</time></small>
|
||||||
Aliquam tincidunt mauris eu risus.
|
|
||||||
</p>
|
|
||||||
<small>
|
|
||||||
<time
|
|
||||||
class="media-meta text-muted"
|
|
||||||
datetime="2015-06-11T18:29:20+08:00"
|
|
||||||
>Five hour ago</time
|
|
||||||
></small
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="javascript:void(0)">
|
<a href="javascript:void(0)">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left align-self-center">
|
<div class="media-left align-self-center"><i
|
||||||
<i
|
class="feather ft-alert-triangle icon-bg-circle bg-yellow bg-darken-3"></i></div>
|
||||||
class="feather ft-alert-triangle icon-bg-circle bg-yellow bg-darken-3"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<h6 class="media-heading yellow darken-3">
|
<h6 class="media-heading yellow darken-3">Warning notifixation</h6>
|
||||||
Warning notifixation
|
<p class="notification-text font-small-3 text-muted">Vestibulum auctor dapibus neque.</p><small>
|
||||||
</h6>
|
<time class="media-meta text-muted" datetime="2015-06-11T18:29:20+08:00">Today</time></small>
|
||||||
<p class="notification-text font-small-3 text-muted">
|
|
||||||
Vestibulum auctor dapibus neque.
|
|
||||||
</p>
|
|
||||||
<small>
|
|
||||||
<time
|
|
||||||
class="media-meta text-muted"
|
|
||||||
datetime="2015-06-11T18:29:20+08:00"
|
|
||||||
>Today</time
|
|
||||||
></small
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="javascript:void(0)">
|
<a href="javascript:void(0)">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left align-self-center">
|
<div class="media-left align-self-center"><i
|
||||||
<i
|
class="feather ft-check-circle icon-bg-circle bg-cyan"></i>
|
||||||
class="feather ft-check-circle icon-bg-circle bg-cyan"
|
|
||||||
></i>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<h6 class="media-heading">Complete the task</h6>
|
<h6 class="media-heading">Complete the task</h6><small>
|
||||||
<small>
|
<time class="media-meta text-muted" datetime="2015-06-11T18:29:20+08:00">Last
|
||||||
<time
|
week</time></small>
|
||||||
class="media-meta text-muted"
|
|
||||||
datetime="2015-06-11T18:29:20+08:00"
|
|
||||||
>Last week</time
|
|
||||||
></small
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="javascript:void(0)">
|
<a href="javascript:void(0)">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left align-self-center">
|
<div class="media-left align-self-center"><i class="feather ft-file icon-bg-circle bg-teal"></i>
|
||||||
<i class="feather ft-file icon-bg-circle bg-teal"></i>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<h6 class="media-heading">Generate monthly report</h6>
|
<h6 class="media-heading">Generate monthly report</h6><small>
|
||||||
<small>
|
<time class="media-meta text-muted" datetime="2015-06-11T18:29:20+08:00">Last
|
||||||
<time
|
month</time></small>
|
||||||
class="media-meta text-muted"
|
|
||||||
datetime="2015-06-11T18:29:20+08:00"
|
|
||||||
>Last month</time
|
|
||||||
></small
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown-menu-footer">
|
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
||||||
<a
|
href="javascript:void(0)">Read all notifications</a></li>
|
||||||
class="dropdown-item text-muted text-center"
|
|
||||||
href="javascript:void(0)"
|
|
||||||
>Read all notifications</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</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
|
<a class="nav-link nav-link-label" ngbDropdownToggle *ngIf="email === 'on'"><i
|
||||||
class="ficon feather ft-mail"></i></a>
|
class="ficon feather ft-mail"></i></a>
|
||||||
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
<ul class="dropdown-menu-media dropdown-menu-right" ngbDropdownMenu>
|
||||||
|
@ -314,47 +194,28 @@
|
||||||
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
<li class="dropdown-menu-footer"><a class="dropdown-item text-muted text-center"
|
||||||
href="javascript:void(0)">Read all messages</a></li>
|
href="javascript:void(0)">Read all messages</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li> -->
|
</li>
|
||||||
|
|
||||||
<li class="dropdown-user nav-item" ngbDropdown>
|
<li class="dropdown-user nav-item" ngbDropdown>
|
||||||
<a class="nav-link dropdown-user-link" ngbDropdownToggle>
|
<a class="nav-link dropdown-user-link" ngbDropdownToggle>
|
||||||
<span
|
<span *ngIf="currentUser.displayName"
|
||||||
*ngIf="currentUser.displayName"
|
class="mr-1 user-name text-bold-700">{{currentUser.displayName}}</span>
|
||||||
class="mr-1 user-name text-bold-700"
|
<span *ngIf="!currentUser.displayName" class="mr-1 user-name text-bold-700">John Doe</span>
|
||||||
style="color: #242222"
|
|
||||||
>{{ currentUser.displayName }}</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
*ngIf="!currentUser.displayName"
|
|
||||||
class="mr-1 user-name text-bold-700"
|
|
||||||
>John Doe</span
|
|
||||||
>
|
|
||||||
<span class="avatar avatar-online">
|
<span class="avatar avatar-online">
|
||||||
<img src="{{ urlImage }}" alt="avatar" />
|
<img *ngIf="currentUser.photoURL" src="{{currentUser.photoURL}}" alt="avatar">
|
||||||
|
<img *ngIf="!currentUser.photoURL" src="../../../assets/images/portrait/small/avatar-s-19.png"
|
||||||
|
alt="avatar">
|
||||||
<i></i>
|
<i></i>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div ngbDropdownMenu class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownProfileMenu">
|
||||||
ngbDropdownMenu
|
<a class="dropdown-item" [routerLink]="['/user/user-profile']"><i class="feather ft-user"></i> Edit
|
||||||
class="dropdown-menu dropdown-menu-right"
|
Profile </a>
|
||||||
aria-labelledby="dropdownProfileMenu"
|
<a class="dropdown-item" [routerLink]="['/email']"><i class="feather ft-mail"></i> My Inbox </a>
|
||||||
>
|
<a class="dropdown-item" [routerLink]="['/todos']"><i class="feather ft-check-square"></i> Task </a>
|
||||||
<a class="dropdown-item" [routerLink]="'/user-profil'"
|
<a class="dropdown-item" [routerLink]="['/chats']"><i class="feather ft-message-square"></i> Chats </a>
|
||||||
><i class="feather ft-user"></i> Edit Profile
|
|
||||||
</a>
|
|
||||||
<!-- <a class="dropdown-item"
|
|
||||||
><i class="feather ft-mail"></i> My Inbox
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
><i class="feather ft-check-square"></i> Task
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
><i class="feather ft-message-square"></i> Chats
|
|
||||||
</a> -->
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item" [routerLink]="" (click)="logout()"
|
<a class="dropdown-item" [routerLink]="" (click)="logout()"><i class="feather ft-power"></i> Logout</a>
|
||||||
><i class="feather ft-power"></i> Logout</a
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { AuthService } from 'src/app/_services/auth.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { PerfectScrollbarConfigInterface, PerfectScrollbarComponent, PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
|
import { PerfectScrollbarConfigInterface, PerfectScrollbarComponent, PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
|
||||||
import { AppConstants } from 'src/app/_helpers/app.constants';
|
import { AppConstants } from 'src/app/_helpers/app.constants';
|
||||||
import { LoginService } from 'src/app/content/hemat-app/service/login.service';
|
|
||||||
|
|
||||||
const docElmWithBrowsersFullScreenFunctions = document.documentElement as HTMLElement & {
|
const docElmWithBrowsersFullScreenFunctions = document.documentElement as HTMLElement & {
|
||||||
mozRequestFullScreen(): Promise<void>;
|
mozRequestFullScreen(): Promise<void>;
|
||||||
|
@ -31,8 +30,6 @@ export class VerticalComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
insideTm: any;
|
insideTm: any;
|
||||||
outsideTm: any;
|
outsideTm: any;
|
||||||
urlImage: string = 'https://www.w3schools.com/howto/img_avatar.png';
|
|
||||||
dataAccount: any;
|
|
||||||
private _unsubscribeAll: Subject<any>;
|
private _unsubscribeAll: Subject<any>;
|
||||||
private _unsubscribeAllMenu: Subject<any>;
|
private _unsubscribeAllMenu: Subject<any>;
|
||||||
public _themeSettingsConfig: any;
|
public _themeSettingsConfig: any;
|
||||||
|
@ -60,8 +57,7 @@ export class VerticalComponent implements OnInit, AfterViewInit {
|
||||||
private _menuSettingsService: MenuSettingsService,
|
private _menuSettingsService: MenuSettingsService,
|
||||||
public authService: AuthService,
|
public authService: AuthService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private elementRef: ElementRef,
|
private elementRef: ElementRef
|
||||||
private authServiceLogin: LoginService,
|
|
||||||
) {
|
) {
|
||||||
this._unsubscribeAll = new Subject();
|
this._unsubscribeAll = new Subject();
|
||||||
this._unsubscribeAllMenu = new Subject();
|
this._unsubscribeAllMenu = new Subject();
|
||||||
|
@ -86,13 +82,6 @@ export class VerticalComponent implements OnInit, AfterViewInit {
|
||||||
if (localStorage.getItem('currentUser')) {
|
if (localStorage.getItem('currentUser')) {
|
||||||
this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
|
this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localStorage.getItem('account_info')) {
|
|
||||||
this.dataAccount = JSON.parse(localStorage.getItem('account_info'));
|
|
||||||
this.dataProfil(this.dataAccount.sub);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Subscribe to config changes
|
// Subscribe to config changes
|
||||||
this._themeSettingsService.config
|
this._themeSettingsService.config
|
||||||
.pipe(takeUntil(this._unsubscribeAll))
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
|
@ -112,14 +101,6 @@ export class VerticalComponent implements OnInit, AfterViewInit {
|
||||||
this.email = this._themeSettingsConfig.headerIcons.email;
|
this.email = this._themeSettingsConfig.headerIcons.email;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataProfil(userId){
|
|
||||||
this.authServiceLogin.getDataProfil(userId).subscribe(data => {
|
|
||||||
if (data.data.image_path !== "https://kapi.absys.ninja/hemat/image/null") {
|
|
||||||
this.urlImage = data.data.image_path
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
this.refreshView();
|
this.refreshView();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
.menu-item {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item.active::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
height: 100%;
|
|
||||||
width: 5px;
|
|
||||||
background-color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-link::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 4px;
|
|
||||||
background-color: green;
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div (mouseenter)="mouseEnter($event)" (mouseleave)="mouseLeave($event)" id="main-menu"
|
<div (mouseenter)="mouseEnter($event)" (mouseleave)="mouseLeave($event)" id="main-menu"
|
||||||
class="main-menu menu-fixed menu-dark menu-accordion menu-shadow" data-scroll-to-active="true" style="background-color: #fbfbfb !important; box-shadow: none !important; border-right: 3px solid #f4f4f4;">
|
class="main-menu menu-fixed menu-dark menu-accordion menu-shadow" data-scroll-to-active="true">
|
||||||
<div id="main-menu-content" class="main-menu-content ps-container ps-theme-light" fxFlex="auto"
|
<div id="main-menu-content" class="main-menu-content ps-container ps-theme-light" fxFlex="auto"
|
||||||
[perfectScrollbar]="config" >
|
[perfectScrollbar]="config">
|
||||||
<ul class="navigation navigation-main" id="main-menu-navigation" data-menu="menu-navigation" style="background-color: #fbfbfb !important;">
|
<ul class="navigation navigation-main" id="main-menu-navigation" data-menu="menu-navigation">
|
||||||
<!-- Menu -->
|
<!-- Menu -->
|
||||||
{{child?child.title:''}}
|
{{child?child.title:''}}
|
||||||
<li *ngFor="let child of _menuSettingsConfig.vertical_menu.items" class="" [ngClass]="{
|
<li *ngFor="let child of _menuSettingsConfig.vertical_menu.items" class="" [ngClass]="{
|
||||||
|
@ -13,24 +13,22 @@
|
||||||
'active': child.isSelected && !child.submenu,
|
'active': child.isSelected && !child.submenu,
|
||||||
'menu-collapsed-open': child.isSelected && child.submenu,
|
'menu-collapsed-open': child.isSelected && child.submenu,
|
||||||
'hover': child.hover
|
'hover': child.hover
|
||||||
}" >
|
}">
|
||||||
<!-- Section -->
|
<!-- Section -->
|
||||||
<span class="menu-title" *ngIf="child.section">{{child.section}}</span>
|
<span class="menu-title" *ngIf="child.section">{{child.section}}</span>
|
||||||
<i class="la" *ngIf="child.section" [ngClass]="child.icon" data-toggle="tooltip" data-placement="right"
|
<i class="la" *ngIf="child.section" [ngClass]="child.icon" data-toggle="tooltip" data-placement="right"
|
||||||
data-original-title="Support" style="color: #242222;"></i>
|
data-original-title="Support"></i>
|
||||||
|
|
||||||
<!-- Root Menu -->
|
<!-- Root Menu -->
|
||||||
<a *ngIf="child.title && !child.submenu && !child.excludeInVertical && !child.isExternalLink && !child.issupportExternalLink && !child.isStarterkitExternalLink"
|
<a *ngIf="child.title && !child.submenu && !child.excludeInVertical && !child.isExternalLink && !child.issupportExternalLink && !child.isStarterkitExternalLink"
|
||||||
routerLink="{{child.page !== 'null'?child.page:router.url}}" (click)="toggleMenu($event, child)"
|
routerLink="{{child.page !== 'null'?child.page:router.url}}" (click)="toggleMenu($event, child)">
|
||||||
style="background-color: #fbfbfb !important;">
|
<i class="la" [ngClass]="child.icon"></i>
|
||||||
<i class="la" [ngClass]="child.icon" style="color: #242222;"></i>
|
<span class="menu-title" data-i18n="">{{child.title}}</span>
|
||||||
<span class="menu-title" data-i18n="" style="color: #242222;">{{child.title}}</span>
|
|
||||||
<span *ngIf="child.badge" class="badge badge-pill float-right"
|
<span *ngIf="child.badge" class="badge badge-pill float-right"
|
||||||
[ngClass]="{'badge-info mr-2': child.badge.type==='badge-info' , 'badge-danger':child.badge.type==='badge-danger'}" style="color: #242222;">
|
[ngClass]="{'badge-info mr-2': child.badge.type==='badge-info' , 'badge-danger':child.badge.type==='badge-danger'}">
|
||||||
{{child.badge.value}}
|
{{child.badge.value}}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a *ngIf="child.title && !child.submenu && !child.excludeInVertical && child.isExternalLink"
|
<a *ngIf="child.title && !child.submenu && !child.excludeInVertical && child.isExternalLink"
|
||||||
[href]="child.page" target="_blank" (click)="toggleMenu($event, child)">
|
[href]="child.page" target="_blank" (click)="toggleMenu($event, child)">
|
||||||
<i class="la" [ngClass]="child.icon"></i>
|
<i class="la" [ngClass]="child.icon"></i>
|
||||||
|
@ -53,23 +51,20 @@
|
||||||
|
|
||||||
<!-- Submenu -->
|
<!-- Submenu -->
|
||||||
<a *ngIf="child.title && child.submenu && !child.excludeInVertical"
|
<a *ngIf="child.title && child.submenu && !child.excludeInVertical"
|
||||||
routerLink="{{child.page !== 'null'?child.page:router.url}}" (click)="toggleMenu($event, child)" style="background-color: #fbfbfb !important;">
|
routerLink="{{child.page !== 'null'?child.page:router.url}}" (click)="toggleMenu($event, child)">
|
||||||
<i class="la" [ngClass]="child.icon" style="color: #242222;"></i>
|
<i class="la" [ngClass]="child.icon"></i>
|
||||||
<span class="menu-title" data-i18n="" style="color: #242222;">{{child.title}}</span>
|
<span class="menu-title" data-i18n="">{{child.title}}</span>
|
||||||
<span *ngIf="child.badge" class="badge badge-pill float-right"
|
<span *ngIf="child.badge" class="badge badge-pill float-right"
|
||||||
[ngClass]="{'badge-info mr-2': child.badge.type==='badge-info' , 'badge-danger':child.badge.type==='badge-danger'}" style="color: #242222;">
|
[ngClass]="{'badge-info mr-2': child.badge.type==='badge-info' , 'badge-danger':child.badge.type==='badge-danger'}">
|
||||||
{{child.badge.value}}
|
{{child.badge.value}}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<ul *ngIf="child.submenu" class="menu-content" [@popOverState]="child.isOpen" style="background-color: #fbfbfb !important;">
|
<ul *ngIf="child.submenu" class="menu-content" [@popOverState]="child.isOpen">
|
||||||
<!-- Submenu of Submenu -->
|
<!-- Submenu of Submenu -->
|
||||||
<li *ngFor="let subchild of child.submenu.items" class="isShown"
|
<li *ngFor="let subchild of child.submenu.items" class="isShown"
|
||||||
[ngClass]="{'has-sub':(subchild.submenu),'active': subchild.isSelected && !subchild.submenu, 'open': subchild.isOpen && subchild.submenu}">
|
[ngClass]="{'has-sub':(subchild.submenu),'active': subchild.isSelected && !subchild.submenu, 'open': subchild.isOpen && subchild.submenu}">
|
||||||
<a class="menu-item" *ngIf="!subchild.submenu && !subchild.excludeInVertical"
|
<a class="menu-item" *ngIf="!subchild.submenu && !subchild.excludeInVertical" (click)="toggleMenu($event, subchild, true)"
|
||||||
(click)="toggleMenu($event, subchild, true)"
|
routerLink="{{subchild.page !== 'null'?subchild.page:router.url}}">{{subchild.title}}</a>
|
||||||
routerLink="{{subchild.page !== 'null'?subchild.page:router.url}}"
|
|
||||||
[ngClass]="{'active': subchild.isSelected}"
|
|
||||||
style="background-color: #fbfbfb !important; color: #242222;">{{subchild.title}}</a>
|
|
||||||
<a class="menu-item" *ngIf="subchild.submenu && !subchild.excludeInVertical" (click)="toggleMenu($event, subchild, true)"
|
<a class="menu-item" *ngIf="subchild.submenu && !subchild.excludeInVertical" (click)="toggleMenu($event, subchild, true)"
|
||||||
routerLink="{{subchild.page !== 'null'?subchild.page:router.url}}">{{subchild.title}}</a>
|
routerLink="{{subchild.page !== 'null'?subchild.page:router.url}}">{{subchild.title}}</a>
|
||||||
<ul *ngIf="subchild.submenu && !subchild.excludeInVertical" class="menu-content">
|
<ul *ngIf="subchild.submenu && !subchild.excludeInVertical" class="menu-content">
|
||||||
|
|
|
@ -384,7 +384,6 @@ export class VerticalnavComponent implements OnInit {
|
||||||
} else if ( child.page === '/chats' && this.loggedInUser.email !== 'john@pixinvent.com') {
|
} else if ( child.page === '/chats' && this.loggedInUser.email !== 'john@pixinvent.com') {
|
||||||
this.router.navigate(['/chats']);
|
this.router.navigate(['/chats']);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
<div (window:resize)="onResize($event)"></div>
|
<div (window:resize)="onResize($event)"></div>
|
||||||
<app-navigation></app-navigation>
|
<app-navigation></app-navigation>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
<div
|
<div class="sidenav-overlay d-none" id="sidenav-overlay" (click)="rightbar($event)"></div>
|
||||||
class="sidenav-overlay d-none"
|
|
||||||
id="sidenav-overlay"
|
|
||||||
(click)="rightbar($event)"
|
|
||||||
></div>
|
|
||||||
<app-footer></app-footer>
|
<app-footer></app-footer>
|
||||||
<!-- <div *ngIf="customizer === 'on'">
|
<div *ngIf ="customizer === 'on'">
|
||||||
<app-customizer *ngIf="layout === 'vertical'"></app-customizer>
|
<app-customizer *ngIf="layout === 'vertical'"></app-customizer>
|
||||||
<app-horizontal-customizer
|
<app-horizontal-customizer *ngIf="layout === 'horizontal'"></app-horizontal-customizer>
|
||||||
*ngIf="layout === 'horizontal'"
|
</div>
|
||||||
></app-horizontal-customizer>
|
<div *ngIf ="buybutton === 'on'">
|
||||||
</div> -->
|
<div class="buy-now" >
|
||||||
<!-- <div *ngIf="buybutton === 'on'">
|
|
||||||
<div class="buy-now" >
|
|
||||||
<a href="https://1.envato.market/modern_admin_angular" target="_blank" class="btn bg-gradient-directional-purple round white btn-purple btn-glow px-2">Buy Now</a>
|
<a href="https://1.envato.market/modern_admin_angular" target="_blank" class="btn bg-gradient-directional-purple round white btn-purple btn-glow px-2">Buy Now</a>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
File diff suppressed because it is too large
Load Diff
|
@ -29,5 +29,5 @@ export const ThemeSettingsConfig = {
|
||||||
// value:'http://evolvision.com/wp-content/uploads/2018/01/envelope4-green.png'
|
// value:'http://evolvision.com/wp-content/uploads/2018/01/envelope4-green.png'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultTitleSuffix: ''
|
defaultTitleSuffix: 'Modern Admin - Angular 11+ Bootstrap 5 Admin Dashboard Template'
|
||||||
};
|
};
|
||||||
|
|
|
@ -107,17 +107,11 @@ export class AuthService {
|
||||||
doLogout() {
|
doLogout() {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
if (firebase.auth().currentUser) {
|
if (firebase.auth().currentUser) {
|
||||||
console.log('masuk atas');
|
|
||||||
localStorage.removeItem('currentUser');
|
localStorage.removeItem('currentUser');
|
||||||
localStorage.removeItem('account_info');
|
|
||||||
localStorage.removeItem('access_token');
|
|
||||||
localStorage.removeItem('remember');
|
localStorage.removeItem('remember');
|
||||||
this.afAuth.signOut();
|
this.afAuth.signOut();
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
console.log('masuk bawah');
|
|
||||||
localStorage.removeItem('account_info');
|
|
||||||
localStorage.removeItem('access_token');
|
|
||||||
localStorage.removeItem('currentUser');
|
localStorage.removeItem('currentUser');
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,6 @@ export class TableApiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extractData(res: Response) {
|
private extractData(res: Response) {
|
||||||
console.log(res);
|
|
||||||
|
|
||||||
const body = res;
|
const body = res;
|
||||||
return body || {};
|
return body || {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,280 +1,37 @@
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from '@angular/core';
|
||||||
import * as FileSaver from "file-saver";
|
import * as FileSaver from 'file-saver';
|
||||||
import * as XLSX from "xlsx";
|
import * as XLSX from 'xlsx';
|
||||||
|
|
||||||
const EXCEL_TYPE =
|
const EXCEL_TYPE =
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8";
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
|
||||||
const EXCEL_EXTENSION = ".xlsx";
|
const EXCEL_EXTENSION = '.xlsx';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: "root",
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class TableexcelService {
|
export class TableexcelService {
|
||||||
constructor() {}
|
constructor() { }
|
||||||
public exportAsExcelFile(json: any[], excelFileName: string): void {
|
public exportAsExcelFile(json: any[], excelFileName: string): void {
|
||||||
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(json);
|
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(json);
|
||||||
console.log("worksheet", worksheet);
|
console.log('worksheet', worksheet);
|
||||||
const workbook: XLSX.WorkBook = {
|
const workbook: XLSX.WorkBook = {
|
||||||
Sheets: { data: worksheet },
|
Sheets: { data: worksheet },
|
||||||
SheetNames: ["data"],
|
SheetNames: ['data']
|
||||||
};
|
};
|
||||||
const excelBuffer: any = XLSX.write(workbook, {
|
const excelBuffer: any = XLSX.write(workbook, {
|
||||||
bookType: "xlsx",
|
bookType: 'xlsx',
|
||||||
type: "array",
|
type: 'array'
|
||||||
});
|
});
|
||||||
this.saveAsExcelFile(excelBuffer, excelFileName);
|
this.saveAsExcelFile(excelBuffer, excelFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private saveAsExcelFile(buffer: any, fileName: string): void {
|
private saveAsExcelFile(buffer: any, fileName: string): void {
|
||||||
const data: Blob = new Blob([buffer], {
|
const data: Blob = new Blob([buffer], {
|
||||||
type: EXCEL_TYPE,
|
type: EXCEL_TYPE
|
||||||
});
|
});
|
||||||
FileSaver.saveAs(
|
FileSaver.saveAs(
|
||||||
data,
|
data,
|
||||||
fileName + "_export_" + new Date().getTime() + EXCEL_EXTENSION
|
fileName + '_export_' + new Date().getTime() + EXCEL_EXTENSION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public exportAsExcelFileDevice(
|
|
||||||
json: any[],
|
|
||||||
excelFileName: string,
|
|
||||||
columns: string[]
|
|
||||||
): void {
|
|
||||||
const filteredJson = json.map((item) => {
|
|
||||||
const filteredItem = {};
|
|
||||||
columns.forEach((column) => {
|
|
||||||
filteredItem[column] = item[column];
|
|
||||||
});
|
|
||||||
return filteredItem;
|
|
||||||
});
|
|
||||||
|
|
||||||
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(filteredJson);
|
|
||||||
const columnWidths = [
|
|
||||||
{ wch: 40 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 10 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
];
|
|
||||||
worksheet["!cols"] = columnWidths;
|
|
||||||
|
|
||||||
const header = [
|
|
||||||
"Device",
|
|
||||||
"Building",
|
|
||||||
"Room",
|
|
||||||
"Watt",
|
|
||||||
"Category",
|
|
||||||
"Status",
|
|
||||||
"Type",
|
|
||||||
"Voltage",
|
|
||||||
];
|
|
||||||
XLSX.utils.sheet_add_aoa(worksheet, [header]);
|
|
||||||
|
|
||||||
const workbook: XLSX.WorkBook = {
|
|
||||||
Sheets: { data: worksheet },
|
|
||||||
SheetNames: ["data"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const excelBuffer: any = XLSX.write(workbook, {
|
|
||||||
bookType: "xlsx",
|
|
||||||
type: "array",
|
|
||||||
});
|
|
||||||
this.saveAsExcelFile(excelBuffer, excelFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public exportAsExcelFileCostManage(
|
|
||||||
json: any[],
|
|
||||||
excelFileName: string,
|
|
||||||
columns: string[]
|
|
||||||
): void {
|
|
||||||
// Filter the json data based on the columns
|
|
||||||
const filteredJson = json.map((item) => {
|
|
||||||
const filteredItem = {};
|
|
||||||
columns.forEach((column) => {
|
|
||||||
filteredItem[column] = item[column];
|
|
||||||
});
|
|
||||||
return filteredItem;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Calculate totals for estimation_cost and total_use
|
|
||||||
const totalEstimationCost = filteredJson.reduce(
|
|
||||||
(sum, item) => sum + (item["estimation_cost"] || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const totalUse = filteredJson.reduce(
|
|
||||||
(sum, item) => sum + (item["total_use"] || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create the worksheet
|
|
||||||
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(filteredJson);
|
|
||||||
const columnWidths = [
|
|
||||||
{ wch: 40 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
];
|
|
||||||
worksheet["!cols"] = columnWidths;
|
|
||||||
|
|
||||||
// Add header
|
|
||||||
const header = [
|
|
||||||
"Building",
|
|
||||||
"Room",
|
|
||||||
"Category",
|
|
||||||
"Total Use",
|
|
||||||
"Estimation Cost",
|
|
||||||
"Date",
|
|
||||||
];
|
|
||||||
XLSX.utils.sheet_add_aoa(worksheet, [header]);
|
|
||||||
|
|
||||||
// Add totals row
|
|
||||||
const totalsRow = [
|
|
||||||
"Totals",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
`Total: ${totalUse} Kwh`,
|
|
||||||
`Total: ${totalEstimationCost}`,
|
|
||||||
"",
|
|
||||||
];
|
|
||||||
XLSX.utils.sheet_add_aoa(worksheet, [totalsRow], { origin: -1 });
|
|
||||||
|
|
||||||
// Create the workbook
|
|
||||||
const workbook: XLSX.WorkBook = {
|
|
||||||
Sheets: { data: worksheet },
|
|
||||||
SheetNames: ["data"],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Write the workbook and save it
|
|
||||||
const excelBuffer: any = XLSX.write(workbook, {
|
|
||||||
bookType: "xlsx",
|
|
||||||
type: "array",
|
|
||||||
});
|
|
||||||
this.saveAsExcelFile(excelBuffer, excelFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public exportAsExcelFileManageDetail(
|
|
||||||
json: any[],
|
|
||||||
excelFileName: string,
|
|
||||||
columns: string[]
|
|
||||||
): void {
|
|
||||||
const filteredJson = json.map((item) => {
|
|
||||||
const filteredItem = {};
|
|
||||||
columns.forEach((column) => {
|
|
||||||
filteredItem[column] = item[column];
|
|
||||||
});
|
|
||||||
return filteredItem;
|
|
||||||
});
|
|
||||||
|
|
||||||
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(filteredJson);
|
|
||||||
const columnWidths = [
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 40 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
{ wch: 20 },
|
|
||||||
];
|
|
||||||
worksheet["!cols"] = columnWidths;
|
|
||||||
|
|
||||||
const header = [
|
|
||||||
"Periode",
|
|
||||||
"Device",
|
|
||||||
"Room",
|
|
||||||
"Category",
|
|
||||||
"Estimation Cost",
|
|
||||||
"Total Kwh",
|
|
||||||
"Watt",
|
|
||||||
"Duration",
|
|
||||||
"Price Kwh",
|
|
||||||
];
|
|
||||||
XLSX.utils.sheet_add_aoa(worksheet, [header]);
|
|
||||||
|
|
||||||
const workbook: XLSX.WorkBook = {
|
|
||||||
Sheets: { data: worksheet },
|
|
||||||
SheetNames: ["data"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const excelBuffer: any = XLSX.write(workbook, {
|
|
||||||
bookType: "xlsx",
|
|
||||||
type: "array",
|
|
||||||
});
|
|
||||||
this.saveAsExcelFile(excelBuffer, excelFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public exportAsExcelFileMonitoringDetail(
|
|
||||||
json: any[],
|
|
||||||
excelFileName: string,
|
|
||||||
columns: string[],
|
|
||||||
mode: any
|
|
||||||
): void {
|
|
||||||
const filteredJson = json.map((item) => {
|
|
||||||
const filteredItem = {};
|
|
||||||
columns.forEach((column) => {
|
|
||||||
filteredItem[column] = item[column];
|
|
||||||
});
|
|
||||||
return filteredItem;
|
|
||||||
});
|
|
||||||
|
|
||||||
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(filteredJson);
|
|
||||||
let columnWidths = [];
|
|
||||||
if (mode === "building") {
|
|
||||||
columnWidths = [
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 40 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
];
|
|
||||||
} else if (mode === "floor") {
|
|
||||||
columnWidths = [
|
|
||||||
{ wch: 40 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
{ wch: 30 },
|
|
||||||
];
|
|
||||||
} else if (mode === "room") {
|
|
||||||
columnWidths = [{ wch: 30 }, { wch: 30 }, { wch: 30 }, { wch: 30 }];
|
|
||||||
}
|
|
||||||
|
|
||||||
worksheet["!cols"] = columnWidths;
|
|
||||||
|
|
||||||
let header = [];
|
|
||||||
if (mode === "building") {
|
|
||||||
header = [
|
|
||||||
"Floor",
|
|
||||||
"Room",
|
|
||||||
"Device",
|
|
||||||
"Duration",
|
|
||||||
"Price Kwh",
|
|
||||||
"Estimation Cost",
|
|
||||||
];
|
|
||||||
} else if (mode === "floor") {
|
|
||||||
header = ["Room", "Device", "Duration", "Price Kwh", "Estimation Cost"];
|
|
||||||
} else if (mode === "room") {
|
|
||||||
header = ["Device", "Duration", "Price Kwh", "Estimation Cost"];
|
|
||||||
}
|
|
||||||
|
|
||||||
XLSX.utils.sheet_add_aoa(worksheet, [header]);
|
|
||||||
|
|
||||||
const workbook: XLSX.WorkBook = {
|
|
||||||
Sheets: { data: worksheet },
|
|
||||||
SheetNames: ["data"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const excelBuffer: any = XLSX.write(workbook, {
|
|
||||||
bookType: "xlsx",
|
|
||||||
type: "array",
|
|
||||||
});
|
|
||||||
this.saveAsExcelFile(excelBuffer, excelFileName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,7 @@ export class AppComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.title && this.router.url !== '/') {
|
if (this.title && this.router.url !== '/') {
|
||||||
this.titleService.setTitle(this.title);
|
this.titleService.setTitle(this.title + ' - ' + this._themeSettingsConfig.defaultTitleSuffix);
|
||||||
// this.titleService.setTitle(this.title + ' - ' + this._themeSettingsConfig.defaultTitleSuffix);
|
|
||||||
} else {
|
} else {
|
||||||
if ((this.router.url === '/' || this.router.url === '/login' || this.router.url === '/register') &&
|
if ((this.router.url === '/' || this.router.url === '/login' || this.router.url === '/register') &&
|
||||||
!localStorage.getItem('remember')) {
|
!localStorage.getItem('remember')) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
HammerGestureConfig
|
HammerGestureConfig
|
||||||
} from '@angular/platform-browser';
|
} from '@angular/platform-browser';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import {
|
import {
|
||||||
NgbModule,
|
NgbModule,
|
||||||
NgbCarouselConfig,
|
NgbCarouselConfig,
|
||||||
|
@ -67,8 +67,7 @@ import { FullLayoutComponent } from './_layout/full-layout/full-layout.component
|
||||||
import { ToastrModule } from 'ngx-toastr';
|
import { ToastrModule } from 'ngx-toastr';
|
||||||
import { UserService } from './_api/user/user.service';
|
import { UserService } from './_api/user/user.service';
|
||||||
import { PrivacyPolicyComponent } from './login/privacy-policy/privacy-policy.component';
|
import { PrivacyPolicyComponent } from './login/privacy-policy/privacy-policy.component';
|
||||||
import { TermsConditionComponent } from './login/terms-condition/terms-condition.component';
|
import { TermsConditionComponent } from './login/terms-condition/terms-condition.component';;
|
||||||
import { HttpErrorInterceptorService } from './interceptors/http-error-interceptor.service';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -94,7 +93,7 @@ import { HttpErrorInterceptorService } from './interceptors/http-error-intercept
|
||||||
LoadingBarRouterModule,
|
LoadingBarRouterModule,
|
||||||
BlockUIModule.forRoot({
|
BlockUIModule.forRoot({
|
||||||
template: BlockTemplateComponent
|
template: BlockTemplateComponent
|
||||||
}),
|
})
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
@ -118,7 +117,7 @@ import { HttpErrorInterceptorService } from './interceptors/http-error-intercept
|
||||||
BlockTemplateComponent,
|
BlockTemplateComponent,
|
||||||
FullLayoutComponent,
|
FullLayoutComponent,
|
||||||
PrivacyPolicyComponent,
|
PrivacyPolicyComponent,
|
||||||
TermsConditionComponent
|
TermsConditionComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
AuthGuard,
|
AuthGuard,
|
||||||
|
@ -137,7 +136,6 @@ import { HttpErrorInterceptorService } from './interceptors/http-error-intercept
|
||||||
},
|
},
|
||||||
NgbCarouselConfig,
|
NgbCarouselConfig,
|
||||||
NgbModalConfig,
|
NgbModalConfig,
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptorService, multi: true }
|
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent],
|
bootstrap: [AppComponent],
|
||||||
exports: [RouterModule]
|
exports: [RouterModule]
|
||||||
|
|
|
@ -48,38 +48,6 @@ const appRoutes: Routes = [
|
||||||
children: [
|
children: [
|
||||||
{ path: 'logout', component: LoginComponent, canActivate: [AuthGuard] },
|
{ path: 'logout', component: LoginComponent, canActivate: [AuthGuard] },
|
||||||
{ path: 'changelog', component: ChangelogComponent, canActivate: [AuthGuard] },
|
{ path: 'changelog', component: ChangelogComponent, canActivate: [AuthGuard] },
|
||||||
{
|
|
||||||
path: 'monitoring', loadChildren: () => import('../app/content/hemat-app/monitoring/monitoring.module').then(m => m.MonitoringModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'calculator', loadChildren: () => import('../app/content/hemat-app/calculator/calculator.module').then(m => m.CalculatorModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'list-monitoring', loadChildren: () => import('../app/content/hemat-app/list-monitoring/list-monitoring.module').then(m => m.ListMonitoringModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'device', loadChildren: () => import('../app/content/hemat-app/device/device.module').then(m => m.DeviceModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'cost-management', loadChildren: () => import('../app/content/hemat-app/cost-management/cost-management.module').then(m => m.CostManagementModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'user-access', loadChildren: () => import('../app/content/hemat-app/user-access/user-access.module').then(m => m.UserAccessModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'master', loadChildren: () => import('../app/content/hemat-app/master/master.module').then(m => m.MasterModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'user-profil', loadChildren: () => import('../app/content/hemat-app/user-profile/user-profile.module').then(m => m.UserProfileModule)
|
|
||||||
, canActivate: [AuthGuard]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'dashboard', loadChildren: () => import('../app/content/dashboard/dashboard.module').then(m => m.DashboardModule)
|
path: 'dashboard', loadChildren: () => import('../app/content/dashboard/dashboard.module').then(m => m.DashboardModule)
|
||||||
, canActivate: [AuthGuard]
|
, canActivate: [AuthGuard]
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<div class="app-content content">
|
<div class="app-content content">
|
||||||
<div class="content-overlay"></div>
|
<div class="content-overlay"></div>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="content-header row"></div>
|
<div class="content-header row">
|
||||||
<div class="content-body">
|
</div>
|
||||||
<!-- Hospital Info cards -->
|
<div class="content-body"><!-- Hospital Info cards -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
||||||
<div class="card pull-up">
|
<div class="card pull-up">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -21,8 +21,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
||||||
<div class="card pull-up">
|
<div class="card pull-up">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -38,8 +38,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
||||||
<div class="card pull-up">
|
<div class="card pull-up">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -55,8 +55,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
<div class="col-xl-3 col-lg-6 col-md-6 col-12">
|
||||||
<div class="card pull-up">
|
<div class="card pull-up">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -72,34 +72,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Hospital Info cards Ends -->
|
<!-- Hospital Info cards Ends -->
|
||||||
|
|
||||||
<!-- Appointment Bar Line Chart -->
|
<!-- Appointment Bar Line Chart -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<section id="chartjs-bar-charts">
|
<section id="chartjs-bar-charts">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12" *blockUI="'barCharts'; message: 'Loading'">
|
<div class="col-12" *blockUI="'barCharts'; message: 'Loading'">
|
||||||
<m-card
|
<m-card [options]="options" (reloadFunction)="reloadBarCharts($event)">
|
||||||
[options]="options"
|
<ng-container mCardHeaderTitle>
|
||||||
(reloadFunction)="reloadBarCharts($event)"
|
Appointment
|
||||||
>
|
</ng-container>
|
||||||
<ng-container mCardHeaderTitle> Appointment </ng-container>
|
|
||||||
<ng-container mCardBody>
|
<ng-container mCardBody>
|
||||||
<div class="z">
|
<div class="z">
|
||||||
<canvas
|
<canvas class="barchart" height="328" baseChart [datasets]="barChartData" [labels]="barChartLabels"
|
||||||
class="barchart"
|
[options]="barChartOptions" [legend]="barChartLegend"
|
||||||
height="328"
|
[chartType]="barChartType"></canvas>
|
||||||
baseChart
|
|
||||||
[datasets]="barChartData"
|
|
||||||
[labels]="barChartLabels"
|
|
||||||
[options]="barChartOptions"
|
|
||||||
[legend]="barChartLegend"
|
|
||||||
[chartType]="barChartType"
|
|
||||||
></canvas>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</m-card>
|
</m-card>
|
||||||
|
@ -107,80 +99,58 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Appointment Bar Line Chart Ends -->
|
<!-- Appointment Bar Line Chart Ends -->
|
||||||
|
|
||||||
<!-- Appointment Table -->
|
<!-- Appointment Table -->
|
||||||
<div class="row" matchHeight="card">
|
<div class="row" matchHeight="card">
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h4 class="card-title">Doctors Available</h4>
|
<h4 class="card-title">Doctors Available</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table
|
<table id="recent-orders" class="table table-hover table-xl mb-0">
|
||||||
id="recent-orders"
|
|
||||||
class="table table-hover table-xl mb-0"
|
|
||||||
>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let doctor of doctors">
|
<tr *ngFor = "let doctor of doctors ">
|
||||||
<td class="text-truncate p-1 border-top-0">
|
<td class="text-truncate p-1 border-top-0">
|
||||||
<div class="avatar avatar-md">
|
<div class="avatar avatar-md">
|
||||||
<img
|
<img class="media-object rounded-circle" [src]= doctor.image
|
||||||
class="media-object rounded-circle"
|
alt="Avatar">
|
||||||
[src]="doctor.image"
|
|
||||||
alt="Avatar"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-truncate pl-0 border-top-0">
|
<td class="text-truncate pl-0 border-top-0">
|
||||||
<div class="name">{{ doctor.name }}</div>
|
<div class="name">{{doctor.name}}</div>
|
||||||
<div class="designation text-light font-small-2">
|
<div class="designation text-light font-small-2">Dentist</div>
|
||||||
Dentist
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right border-top-0">
|
<td class="text-right border-top-0">
|
||||||
<a
|
<a href="hospital-book-appointment.html" class="btn btn-sm btn-outline-success">Book Appointment</a>
|
||||||
href="hospital-book-appointment.html"
|
|
||||||
class="btn btn-sm btn-outline-success"
|
|
||||||
>Book Appointment</a
|
|
||||||
>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="recent-appointments" class="col-12 col-md-8">
|
<div id="recent-appointments" class="col-12 col-md-8">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h4 class="card-title">Recent Appointments</h4>
|
<h4 class="card-title">Recent Appointments</h4>
|
||||||
<a class="heading-elements-toggle"
|
<a class="heading-elements-toggle"><i class="la la-ellipsis-v font-medium-3"></i></a>
|
||||||
><i class="la la-ellipsis-v font-medium-3"></i
|
|
||||||
></a>
|
|
||||||
<div class="heading-elements">
|
<div class="heading-elements">
|
||||||
<ul class="list-inline mb-0">
|
<ul class="list-inline mb-0">
|
||||||
<li>
|
<li><a class="btn btn-sm btn-danger box-shadow-2 round btn-min-width pull-right" href="hospital-book-appointment.html"
|
||||||
<a
|
target="_blank">View all</a></li>
|
||||||
class="btn btn-sm btn-danger box-shadow-2 round btn-min-width pull-right"
|
|
||||||
href="hospital-book-appointment.html"
|
|
||||||
target="_blank"
|
|
||||||
>View all</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content mt-1">
|
<div class="card-content mt-1">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table
|
<table id="recent-orders-doctors" class="table table-hover table-xl mb-0">
|
||||||
id="recent-orders-doctors"
|
|
||||||
class="table table-hover table-xl mb-0"
|
|
||||||
>
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="border-top-0">Doctor</th>
|
<th class="border-top-0">Doctor</th>
|
||||||
|
@ -192,50 +162,35 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="pull-up" *ngFor="let doctor of doctorList">
|
<tr class="pull-up" *ngFor="let doctor of doctorList">
|
||||||
<td class="text-truncate">{{ doctor.name }}</td>
|
<td class="text-truncate">{{doctor.name}}</td>
|
||||||
<td class="text-truncate p-1">
|
<td class="text-truncate p-1">
|
||||||
<ul class="list-unstyled users-list m-0">
|
<ul class="list-unstyled users-list m-0">
|
||||||
<li
|
<li data-toggle="tooltip" data-popup="tooltip-custom" data-original-title="Kimberly Simmons" class="avatar avatar-sm pull-up" *ngFor="let imageUrl of doctor.image">
|
||||||
data-toggle="tooltip"
|
<img class="media-object rounded-circle" [src]="imageUrl" alt="Avatar">
|
||||||
data-popup="tooltip-custom"
|
|
||||||
data-original-title="Kimberly Simmons"
|
|
||||||
class="avatar avatar-sm pull-up"
|
|
||||||
*ngFor="let imageUrl of doctor.image"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="media-object rounded-circle"
|
|
||||||
[src]="imageUrl"
|
|
||||||
alt="Avatar"
|
|
||||||
/>
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="avatar avatar-sm">
|
<li class="avatar avatar-sm">
|
||||||
<span class="badge badge-info">{{
|
<span class="badge badge-info">{{doctor.bagde}}</span>
|
||||||
doctor.bagde
|
|
||||||
}}</span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button type="button" class="btn btn-sm btn-outline-{{doctor.type}} round">{{doctor.designation}}</button>
|
||||||
type="button"
|
|
||||||
class="btn btn-sm btn-outline-{{ doctor.type }} round"
|
|
||||||
>
|
|
||||||
{{ doctor.designation }}
|
|
||||||
</button>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="text-truncate">{{ doctor.time }}</td>
|
<td class="text-truncate">{{doctor.time}}</td>
|
||||||
<td class="text-truncate">{{ doctor.amount }}</td>
|
<td class="text-truncate">{{doctor.amount}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Appointment Table Ends -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- END: Content-->
|
</div>
|
||||||
|
<!-- Appointment Table Ends -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END: Content-->
|
|
@ -52,7 +52,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart2 .ct-series-b .ct-slice-donut {
|
:host ::ng-deep .donut-chart2 .ct-series-b .ct-slice-donut {
|
||||||
stroke: #7949ff;
|
stroke: #ff4961;
|
||||||
stroke-width: 5.5px !important;
|
stroke-width: 5.5px !important;
|
||||||
}
|
}
|
||||||
:host ::ng-deep .donut-chart2 {
|
:host ::ng-deep .donut-chart2 {
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div class="row py-2">
|
<div class="row py-2">
|
||||||
<div class="col-12 col-sm-6 col-md-6 mb-1">
|
<div class="col-12 col-sm-6 col-md-6 mb-1">
|
||||||
<a [routerLink]="['/monitoring']" class="btn btn-primary btn-block"><i class="feather ft-home"></i>
|
<a [routerLink]="['/dashboard/sales']" class="btn btn-primary btn-block"><i class="feather ft-home"></i>
|
||||||
Home</a>
|
Home</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-6 col-md-6 mb-1">
|
<div class="col-12 col-sm-6 col-md-6 mb-1">
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="card border-grey border-lighten-3 px-1 py-1 box-shadow-3 m-0">
|
<div class="card border-grey border-lighten-3 px-1 py-1 box-shadow-3 m-0">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<span class="card-title text-center">
|
<span class="card-title text-center">
|
||||||
<img src="../../../../../assets/images/logo/smart.png" class="img-fluid mx-auto d-block pt-2"
|
<img src="../../../../../assets/images/logo/logo-dark-lg.png" class="img-fluid mx-auto d-block pt-2"
|
||||||
width="250" alt="logo">
|
width="250" alt="logo">
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="col-12 d-flex align-items-center justify-content-center">
|
<div class="col-12 d-flex align-items-center justify-content-center">
|
||||||
<div class="col-lg-6 col-10">
|
<div class="col-lg-6 col-10">
|
||||||
<img class="img-fluid mx-auto d-block pb-3 pt-4 width-65-per"
|
<img class="img-fluid mx-auto d-block pb-3 pt-4 width-65-per"
|
||||||
src="../../../../../assets/images/logo/smart.png" alt="Modern Search">
|
src="../../../../../assets/images/logo/logo-dark-lg.png" alt="Modern Search">
|
||||||
<fieldset class="form-group position-relative">
|
<fieldset class="form-group position-relative">
|
||||||
<input type="text" class="form-control form-control-xl input-xl" id="iconLeft1"
|
<input type="text" class="form-control form-control-xl input-xl" id="iconLeft1"
|
||||||
placeholder="Explore Modern ...">
|
placeholder="Explore Modern ...">
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<app-coming-soon></app-coming-soon>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CalculationComponent } from './calculation.component';
|
|
||||||
|
|
||||||
describe('CalculationComponent', () => {
|
|
||||||
let component: CalculationComponent;
|
|
||||||
let fixture: ComponentFixture<CalculationComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CalculationComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(CalculationComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-calculation',
|
|
||||||
templateUrl: './calculation.component.html',
|
|
||||||
styleUrls: ['./calculation.component.css']
|
|
||||||
})
|
|
||||||
export class CalculationComponent {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
<p>calculator works!</p>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CalculatorComponent } from './calculator.component';
|
|
||||||
|
|
||||||
describe('CalculatorComponent', () => {
|
|
||||||
let component: CalculatorComponent;
|
|
||||||
let fixture: ComponentFixture<CalculatorComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CalculatorComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(CalculatorComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-calculator',
|
|
||||||
templateUrl: './calculator.component.html',
|
|
||||||
styleUrls: ['./calculator.component.css']
|
|
||||||
})
|
|
||||||
export class CalculatorComponent {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { CalculationComponent } from './calculation/calculation.component';
|
|
||||||
import { ReductionComponent } from './reduction/reduction.component';
|
|
||||||
import { CardModule } from '../../partials/general/card/card.module';
|
|
||||||
import { BreadcrumbModule } from 'src/app/_layout/breadcrumb/breadcrumb.module';
|
|
||||||
import { NgSelectModule } from '@ng-select/ng-select';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { ClipboardModule } from 'ngx-clipboard';
|
|
||||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
|
||||||
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
|
||||||
import { BlockUIModule } from 'ng-block-ui';
|
|
||||||
import { BlockTemplateComponent } from 'src/app/_layout/blockui/block-template.component';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { ComingSoonComponent } from '../coming-soon/coming-soon.component';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
CalculationComponent,
|
|
||||||
ReductionComponent,
|
|
||||||
ComingSoonComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
CardModule,
|
|
||||||
BreadcrumbModule,
|
|
||||||
NgSelectModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
ClipboardModule,
|
|
||||||
PerfectScrollbarModule,
|
|
||||||
NgxDatatableModule,
|
|
||||||
BlockUIModule.forRoot({
|
|
||||||
template: BlockTemplateComponent
|
|
||||||
}),
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: 'calculation',
|
|
||||||
component: CalculationComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'reduction',
|
|
||||||
component: ReductionComponent
|
|
||||||
},
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class CalculatorModule { }
|
|
|
@ -1 +0,0 @@
|
||||||
<app-coming-soon></app-coming-soon>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ReductionComponent } from './reduction.component';
|
|
||||||
|
|
||||||
describe('ReductionComponent', () => {
|
|
||||||
let component: ReductionComponent;
|
|
||||||
let fixture: ComponentFixture<ReductionComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ReductionComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ReductionComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-reduction',
|
|
||||||
templateUrl: './reduction.component.html',
|
|
||||||
styleUrls: ['./reduction.component.css']
|
|
||||||
})
|
|
||||||
export class ReductionComponent {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
.bg-maintenance-image {
|
|
||||||
background-size: cover;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered-card {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
<div class="app-content content bg-maintenance-image">
|
|
||||||
<div class="content-wrapper">
|
|
||||||
<div class="content-body">
|
|
||||||
<section class="flexbox-container">
|
|
||||||
<div class="centered-card">
|
|
||||||
<div class="card box-shadow-3">
|
|
||||||
<div class="card-body">
|
|
||||||
<span class="card-title text-center">
|
|
||||||
<img
|
|
||||||
src="assets/images/logo/smart.png"
|
|
||||||
class="img-fluid mx-auto d-block pt-2"
|
|
||||||
width="250"
|
|
||||||
alt="logo"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body text-center">
|
|
||||||
<h3 style="font-weight: 600; color: #000000">Coming Soon</h3>
|
|
||||||
<p style="color: #000000">
|
|
||||||
We're working hard to bring you this page. <br />
|
|
||||||
Please check back later.
|
|
||||||
</p>
|
|
||||||
<div class="mt-2">
|
|
||||||
<i class="la la-cog spinner font-large-2"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ComingSoonComponent } from './coming-soon.component';
|
|
||||||
|
|
||||||
describe('ComingSoonComponent', () => {
|
|
||||||
let component: ComingSoonComponent;
|
|
||||||
let fixture: ComponentFixture<ComingSoonComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ComingSoonComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ComingSoonComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-coming-soon',
|
|
||||||
templateUrl: './coming-soon.component.html',
|
|
||||||
styleUrls: ['./coming-soon.component.css']
|
|
||||||
})
|
|
||||||
export class ComingSoonComponent {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
:host ::ng-deep .ng-select .ng-select-container {
|
|
||||||
/* color: #ffffff !important; */
|
|
||||||
/* background-color: #252525 !important; */
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
<ng-select
|
|
||||||
[items]="icons"
|
|
||||||
bindLabel="name"
|
|
||||||
(change)="onSelect($event)"
|
|
||||||
[(ngModel)]="selectedIcon"
|
|
||||||
bindValue="icon"
|
|
||||||
placeholder="Select an icon"
|
|
||||||
>
|
|
||||||
<ng-template ng-option-tmp let-item="item">
|
|
||||||
<i [ngClass]="item.icon"></i> {{ item.name }}
|
|
||||||
</ng-template>
|
|
||||||
</ng-select>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { SelectIconComponent } from './select-icon.component';
|
|
||||||
|
|
||||||
describe('SelectIconComponent', () => {
|
|
||||||
let component: SelectIconComponent;
|
|
||||||
let fixture: ComponentFixture<SelectIconComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ SelectIconComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(SelectIconComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,35 +0,0 @@
|
||||||
import { Component, EventEmitter, Input, Output } from "@angular/core";
|
|
||||||
import { MasterService } from "../../service/master-api.service";
|
|
||||||
interface Icon {
|
|
||||||
name: string;
|
|
||||||
icon: string;
|
|
||||||
}
|
|
||||||
@Component({
|
|
||||||
selector: "app-select-icon",
|
|
||||||
templateUrl: "./select-icon.component.html",
|
|
||||||
styleUrls: ["./select-icon.component.css"],
|
|
||||||
})
|
|
||||||
export class SelectIconComponent {
|
|
||||||
// @Output() iconSelected: EventEmitter<string> = new EventEmitter<string>();
|
|
||||||
@Output() iconSelected = new EventEmitter<string>();
|
|
||||||
@Input() selectedIcon = undefined;
|
|
||||||
icons: any[] = [];
|
|
||||||
constructor(private masterService: MasterService) {}
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.masterService.getIconData().subscribe((res) => {
|
|
||||||
this.icons = res.rows;
|
|
||||||
});
|
|
||||||
if (!this.selectedIcon) {
|
|
||||||
this.selectedIcon = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(icon: Icon): void {
|
|
||||||
if (icon) {
|
|
||||||
this.iconSelected.emit(icon.icon);
|
|
||||||
} else {
|
|
||||||
this.iconSelected.emit(undefined);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
import { NgModule } from "@angular/core";
|
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { SelectIconComponent } from "./select-icon.component";
|
|
||||||
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { NgSelectModule } from "@ng-select/ng-select";
|
|
||||||
import { FormsModule } from "@angular/forms";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [SelectIconComponent],
|
|
||||||
imports: [CommonModule, NgbModule, NgSelectModule, FormsModule],
|
|
||||||
exports: [
|
|
||||||
SelectIconComponent
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class SelectIconModule {}
|
|
|
@ -1,443 +0,0 @@
|
||||||
:host ::ng-deep .progress-bar {
|
|
||||||
background-color: #bef264 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
: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 {
|
|
||||||
stroke: #bef264;
|
|
||||||
stroke-width: 20px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart2 .ct-label {
|
|
||||||
fill: #ffffff;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
: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 {
|
|
||||||
stroke: #bef264;
|
|
||||||
}
|
|
||||||
|
|
||||||
: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 {
|
|
||||||
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: #bef264;
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart3 .ct-series-b .ct-bar {
|
|
||||||
stroke: #bef264;
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart3 .ct-label {
|
|
||||||
fill: #ffffff;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1;
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ct-label.ct-horizontal {
|
|
||||||
font-size: 12px; /* Adjust font size */
|
|
||||||
transform: rotate(-45deg); /* Rotate labels if needed for better fit */
|
|
||||||
text-anchor: end;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ct-chart-bar .ct-labels .ct-label.ct-horizontal {
|
|
||||||
margin-right: 20px; /* Adjust margin for labels */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.chart-title {
|
|
||||||
font-size: 18px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Hide the default calendar icon */
|
|
||||||
input[type="month"]::-webkit-calendar-picker-indicator {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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: #37A647;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
margin-top: -1px;
|
|
||||||
overflow: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-header {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
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
|
|
||||||
.ngx-datatable
|
|
||||||
.datatable-footer
|
|
||||||
.selected-count
|
|
||||||
.datatable-pager {
|
|
||||||
flex: 0 0 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable {
|
|
||||||
display: -webkit-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container {
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
height: 40px !important;
|
|
||||||
border-radius: 12px !important;
|
|
||||||
box-shadow: 0 2px 4px rgba(36, 34, 34, 0.2) !important; /* Bayangan lebih tipis */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input {
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row {
|
|
||||||
background-color: #FBFBFB; /* Black color for table rows */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row:hover {
|
|
||||||
background-color: #DDE1E6; /* Darker black for hover effect */
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-data{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.style-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
|
@ -1,411 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #FBFBFB !important">
|
|
||||||
<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">
|
|
||||||
<section>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 col-sm-6 col-md-6 col-lg-6">
|
|
||||||
<div class="card" style="background-color: #DDE1E6 !important">
|
|
||||||
<div
|
|
||||||
class="card-header"
|
|
||||||
style="background-color: #DDE1E6 !important"
|
|
||||||
>
|
|
||||||
<h4
|
|
||||||
class="card-title text-center text-custom-label"
|
|
||||||
>
|
|
||||||
Comparison of Previous Month Costs
|
|
||||||
</h4>
|
|
||||||
<hr
|
|
||||||
style="
|
|
||||||
border-top: 4px solid #242222;
|
|
||||||
border-color: #242222 !important;
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div
|
|
||||||
echarts
|
|
||||||
[options]="chartOption"
|
|
||||||
class="echart-container"
|
|
||||||
style="height: 150% !important"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 col-sm-6 col-md-6 col-lg-6">
|
|
||||||
<div class="card" style="background-color: #DDE1E6 !important">
|
|
||||||
<div
|
|
||||||
class="card-header"
|
|
||||||
style="background-color: #DDE1E6 !important"
|
|
||||||
>
|
|
||||||
<h4
|
|
||||||
class="card-title text-center text-custom-label"
|
|
||||||
>
|
|
||||||
Comparison of Actual Costs and Estimated Costs
|
|
||||||
</h4>
|
|
||||||
<hr
|
|
||||||
style="
|
|
||||||
border-top: 4px solid #242222;
|
|
||||||
border-color: #242222 !important;
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div
|
|
||||||
echarts
|
|
||||||
[options]="chartOption2"
|
|
||||||
class="echart-container"
|
|
||||||
style="height: 150% !important"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section id="configuration">
|
|
||||||
<div class="card" style="background-color: #FBFBFB !important">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-6 col-sm-3 col-md-3 col-lg-3 col-xl-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-6 col-sm-3 col-md-3 col-lg-3 col-xl-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<input
|
|
||||||
type="month"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="dateSelected"
|
|
||||||
id="month12"
|
|
||||||
(focus)="focusElement('month12')"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-sm-3 col-md-3 col-lg-3 col-xl-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-6 col-sm-3 col-md-3 col-lg-3 col-xl-3">
|
|
||||||
<div class="d-flex">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-outline-success"
|
|
||||||
(click)="doFilter()"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff;
|
|
||||||
"
|
|
||||||
[disabled]="spinnerFilterActive"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-search"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
*ngIf="!spinnerFilterActive"
|
|
||||||
></i>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
*ngIf="spinnerFilterActive"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
placeholder="Kwh"
|
|
||||||
[(ngModel)]="kwhTerm"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="input-group-append"
|
|
||||||
style="background-color: #FBFBFB !important"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="input-group-text"
|
|
||||||
style="
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
color: #242222;
|
|
||||||
height: 40px !important;
|
|
||||||
"
|
|
||||||
>Kwh</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
placeholder="Cost"
|
|
||||||
mask="separator"
|
|
||||||
thousandSeparator="."
|
|
||||||
[(ngModel)]="costTerm"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="input-group-append"
|
|
||||||
style="background-color: #FBFBFB !important"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="input-group-text"
|
|
||||||
style="
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
color: #242222;
|
|
||||||
height: 40px !important;
|
|
||||||
"
|
|
||||||
>IDR</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-6">
|
|
||||||
<div class="d-flex justify-content-end">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary mr-2"
|
|
||||||
style="
|
|
||||||
width: 100%;
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
(click)="export()"
|
|
||||||
[disabled]="spinnerExportActive"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
*ngIf="spinnerExportActive"
|
|
||||||
></i>
|
|
||||||
<i class="ri-export-line" *ngIf="!spinnerExportActive"></i
|
|
||||||
>
|
|
||||||
<span>Export</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary mr-2"
|
|
||||||
style="
|
|
||||||
width: 100%;
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
(click)="syncData()"
|
|
||||||
[disabled]="spinnerActive"
|
|
||||||
>
|
|
||||||
<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%;
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
(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]="10"
|
|
||||||
[rows]="data_cost"
|
|
||||||
[columnMode]="'force'"
|
|
||||||
[headerHeight]="50"
|
|
||||||
[footerHeight]="50"
|
|
||||||
[rowHeight]="50"
|
|
||||||
fxFlex="auto"
|
|
||||||
[scrollbarH]="true"
|
|
||||||
>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="#"
|
|
||||||
[flexGrow]="0.5"
|
|
||||||
[minWidth]="30"
|
|
||||||
>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-rowIndex="rowIndex"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{ rowIndex + 1 }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="building"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Building</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="categoryName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Category</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="roomName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Room</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="estimationCost"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label"
|
|
||||||
>Estimation Cost</span
|
|
||||||
>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{
|
|
||||||
value.toLocaleString("id-ID", {
|
|
||||||
style: "currency",
|
|
||||||
currency: "IDR"
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="totalUse"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Total Kwh</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
kWh
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<!-- <ngx-datatable-column
|
|
||||||
name="endDate"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Tanggal</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{ value | date : "MM/yyyy" }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column> -->
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="status_id"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Status</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template ngx-datatable-cell-template let-value="value">
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{ value === 2 ? "Aktif" : "Tidak Aktif" }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="Actions"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="150"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Actions</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-rowIndex="rowIndex"
|
|
||||||
let-row="row"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-warning mr-1"
|
|
||||||
style="
|
|
||||||
background-color: #DDE1E6 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
"
|
|
||||||
(click)="viewRow(row)"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="ficon ri-export-line"
|
|
||||||
style="color: #37A647 !important"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
</ngx-datatable>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CostManagementComponent } from './cost-management.component';
|
|
||||||
|
|
||||||
describe('CostManagementComponent', () => {
|
|
||||||
let component: CostManagementComponent;
|
|
||||||
let fixture: ComponentFixture<CostManagementComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ CostManagementComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(CostManagementComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,473 +0,0 @@
|
||||||
import { Component, OnInit } from "@angular/core";
|
|
||||||
import { BuildingService } from "../service/monitoring-api.service";
|
|
||||||
import { CostManagementService } from "../service/cost-management.service";
|
|
||||||
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { ModalAddActualComponent } from "./modal-add-actual/modal-add-actual.component";
|
|
||||||
import "chartist-plugin-tooltips";
|
|
||||||
import { ModalExportComponent } from "./modal-export/modal-export.component";
|
|
||||||
import { TableexcelService } from "src/app/_services/tableexcel.service";
|
|
||||||
import { ToastrService } from "ngx-toastr";
|
|
||||||
import { LoginService } from "../service/login.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-cost-management",
|
|
||||||
templateUrl: "./cost-management.component.html",
|
|
||||||
styleUrls: ["./cost-management.component.css"],
|
|
||||||
})
|
|
||||||
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;
|
|
||||||
spinnerFilterActive = false;
|
|
||||||
barChart: any;
|
|
||||||
|
|
||||||
dateSelected: any;
|
|
||||||
buildingSelected: any;
|
|
||||||
categorySelected: any;
|
|
||||||
dataCompPrev: any;
|
|
||||||
dataCompAct: any;
|
|
||||||
storedData: any;
|
|
||||||
|
|
||||||
chartOption: any;
|
|
||||||
chartOption2: any;
|
|
||||||
|
|
||||||
spinnerExportActive = false;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private costService: CostManagementService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private tableexcelService: TableexcelService,
|
|
||||||
private toastr: ToastrService,
|
|
||||||
private authService: LoginService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Cost Management",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Cost Management",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
this.storedData = JSON.parse(localStorage.getItem("currentUser"));
|
|
||||||
this.buildingSelected = this.storedData.buildingId;
|
|
||||||
const currentDate = new Date();
|
|
||||||
this.dateSelected = currentDate.toISOString().slice(0, 7);
|
|
||||||
|
|
||||||
this.fetchData(
|
|
||||||
this.storedData.buildingId,
|
|
||||||
this.dateSelected,
|
|
||||||
this.categorySelected
|
|
||||||
);
|
|
||||||
this.dataListMaster();
|
|
||||||
this.dataListBuilding();
|
|
||||||
|
|
||||||
this.dataCompPrevMonthCost(this.storedData.buildingId);
|
|
||||||
this.dataCompActEstCost(this.storedData.buildingId);
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchData(id, period, category) {
|
|
||||||
this.costService
|
|
||||||
.getCostManagement(id, period, category)
|
|
||||||
.subscribe((response) => {
|
|
||||||
this.data = response.results.data;
|
|
||||||
this.filteredRows = this.data;
|
|
||||||
let kwhData = parseFloat(response.results.kwh);
|
|
||||||
this.kwhTerm = kwhData.toFixed(1);
|
|
||||||
|
|
||||||
this.costTerm = response.results.cost;
|
|
||||||
|
|
||||||
this.data_cost = this.filteredRows.map((item) => ({
|
|
||||||
building: item.name,
|
|
||||||
roomName: item.room_name,
|
|
||||||
categoryName: item.category_name,
|
|
||||||
estimationCost: item.estimation_cost,
|
|
||||||
totalUse: item.total_use.toFixed(1),
|
|
||||||
endDate: this.convertToUTC7(item.end_date),
|
|
||||||
// endDate: item.end_date,
|
|
||||||
statusId: item.status_id,
|
|
||||||
categoryId: item.category_id,
|
|
||||||
roomId: item.room_id,
|
|
||||||
}));
|
|
||||||
console.log(this.data_cost);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
convertToUTC7(dateString: string): string {
|
|
||||||
const date = new Date(dateString);
|
|
||||||
const utc7Offset = 7 * 60; // UTC+7 in minutes
|
|
||||||
const localOffset = date.getTimezoneOffset();
|
|
||||||
const totalOffset = utc7Offset - localOffset;
|
|
||||||
const utc7Date = new Date(date.getTime() + totalOffset * 60 * 1000);
|
|
||||||
return utc7Date.toISOString();
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListMaster() {
|
|
||||||
this.monitoringApiService.getMasterListData().subscribe((data) => {
|
|
||||||
const dataCategory = data.data.find(
|
|
||||||
(item) => item.name === "master_category"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterCategori = dataCategory.filter(
|
|
||||||
(item) => item.statusName.toLowerCase() === "aktif"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListBuilding() {
|
|
||||||
this.monitoringApiService.getBuildingList().subscribe((data) => {
|
|
||||||
this.dataBuildingList = data.data.filter(
|
|
||||||
(item) => item.statusName.toLowerCase() === "aktif"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataCompPrevMonthCost(buildingId) {
|
|
||||||
this.costService.getCompPrevMonthCost(buildingId).subscribe((data) => {
|
|
||||||
this.dataCompPrev = data.data;
|
|
||||||
this.chartOption = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: "axis",
|
|
||||||
axisPointer: {
|
|
||||||
type: "shadow",
|
|
||||||
},
|
|
||||||
formatter: function (params) {
|
|
||||||
var tar = params[1];
|
|
||||||
return tar.name + "<br/>" + tar.seriesName + " : " + tar.value;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
grid: {
|
|
||||||
left: "25%",
|
|
||||||
right: "25%",
|
|
||||||
top: "20%",
|
|
||||||
bottom: "20%",
|
|
||||||
},
|
|
||||||
color: ["#37A647"],
|
|
||||||
xAxis: {
|
|
||||||
type: "category",
|
|
||||||
splitLine: { show: false },
|
|
||||||
data: [this.dataCompPrev[0].name, this.dataCompPrev[1].name],
|
|
||||||
axisLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#37A647",
|
|
||||||
width: 7,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
yAxis: {
|
|
||||||
type: "value",
|
|
||||||
axisLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
series: [
|
|
||||||
// {
|
|
||||||
// name: "Placeholder",
|
|
||||||
// type: "bar",
|
|
||||||
// stack: "Total",
|
|
||||||
// itemStyle: {
|
|
||||||
// borderColor: "transparent",
|
|
||||||
// color: "transparent",
|
|
||||||
// },
|
|
||||||
// emphasis: {
|
|
||||||
// itemStyle: {
|
|
||||||
// borderColor: "transparent",
|
|
||||||
// color: "transparent",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// data: [1000, 1000],
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
name: "Cost",
|
|
||||||
type: "bar",
|
|
||||||
stack: "Total",
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: "top",
|
|
||||||
color: "#242222",
|
|
||||||
formatter: function (params) {
|
|
||||||
return `Rp. ${params.value.toLocaleString()}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// barWidth: "50%",
|
|
||||||
data: [this.dataCompPrev[0].rupiah, this.dataCompPrev[1].rupiah],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataCompActEstCost(buildingId) {
|
|
||||||
this.costService.getCompActEstCost(buildingId).subscribe((data) => {
|
|
||||||
this.dataCompAct = data.data[0];
|
|
||||||
this.chartOption2 = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: "axis",
|
|
||||||
axisPointer: {
|
|
||||||
type: "shadow",
|
|
||||||
},
|
|
||||||
formatter: function (params) {
|
|
||||||
var tar = params[1];
|
|
||||||
return tar.name + "<br/>" + tar.seriesName + " : " + tar.value;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
grid: {
|
|
||||||
left: "25%",
|
|
||||||
right: "25%",
|
|
||||||
top: "20%",
|
|
||||||
bottom: "20%",
|
|
||||||
},
|
|
||||||
color: ["#37A647"],
|
|
||||||
xAxis: {
|
|
||||||
type: "category",
|
|
||||||
splitLine: { show: false },
|
|
||||||
data: ["Estimation Cost", "Actual Cost"],
|
|
||||||
axisLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#37A647",
|
|
||||||
width: 7,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
yAxis: {
|
|
||||||
type: "value",
|
|
||||||
axisLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
series: [
|
|
||||||
// {
|
|
||||||
// name: "Placeholder",
|
|
||||||
// type: "bar",
|
|
||||||
// stack: "Total",
|
|
||||||
// itemStyle: {
|
|
||||||
// borderColor: "transparent",
|
|
||||||
// color: "transparent",
|
|
||||||
// },
|
|
||||||
// emphasis: {
|
|
||||||
// itemStyle: {
|
|
||||||
// borderColor: "transparent",
|
|
||||||
// color: "transparent",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// data: [2500, 2500],
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
name: "Cost",
|
|
||||||
type: "bar",
|
|
||||||
stack: "Total",
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
position: "top",
|
|
||||||
color: "#242222",
|
|
||||||
formatter: function (params) {
|
|
||||||
return `Rp. ${params.value.toLocaleString()}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// barWidth: "50%",
|
|
||||||
data: [this.dataCompAct.est_cost, this.dataCompAct.real_cost],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
syncData() {
|
|
||||||
const dataDate = {
|
|
||||||
buildingId: this.buildingSelected,
|
|
||||||
periode: this.dateSelected,
|
|
||||||
};
|
|
||||||
this.spinnerActive = true;
|
|
||||||
this.costService.getSyncCost(dataDate).subscribe((data) => {
|
|
||||||
this.dataCompPrevMonthCost(this.storedData.buildingId);
|
|
||||||
this.dataCompActEstCost(this.storedData.buildingId);
|
|
||||||
});
|
|
||||||
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() {
|
|
||||||
if (this.dateSelected) {
|
|
||||||
this.spinnerFilterActive = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.spinnerFilterActive = false;
|
|
||||||
this.fetchData(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.dateSelected,
|
|
||||||
this.categorySelected
|
|
||||||
);
|
|
||||||
}, 3000);
|
|
||||||
} else {
|
|
||||||
this.toastr.error("Warning", "Format date tidak valid.", {
|
|
||||||
timeOut: 5000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addFieldValue() {
|
|
||||||
const modalRef = this.modalService.open(ModalAddActualComponent, {
|
|
||||||
size: "sm",
|
|
||||||
centered: true,
|
|
||||||
});
|
|
||||||
modalRef.componentInstance.buildingId = this.buildingSelected;
|
|
||||||
modalRef.componentInstance.periode = this.dateSelected;
|
|
||||||
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
this.rows.push(result);
|
|
||||||
this.rows = [...this.rows];
|
|
||||||
this.dataCompActEstCost(this.buildingSelected);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
focusElement(focucedElement: any) {
|
|
||||||
this.focucedElement = focucedElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
filterRows() {
|
|
||||||
if (!this.searchTerm) {
|
|
||||||
this.filteredRows = [...this.data.rows];
|
|
||||||
} else {
|
|
||||||
this.filteredRows = this.data.rows.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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewRow(row) {
|
|
||||||
const modalRef = this.modalService.open(ModalExportComponent, {
|
|
||||||
size: "xl",
|
|
||||||
centered: true,
|
|
||||||
});
|
|
||||||
modalRef.componentInstance.buildingId = this.buildingSelected;
|
|
||||||
modalRef.componentInstance.dataRow = row;
|
|
||||||
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
this.rows.push(result);
|
|
||||||
this.rows = [...this.rows];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export() {
|
|
||||||
this.spinnerExportActive = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
const columnsToExport = [
|
|
||||||
"building",
|
|
||||||
"roomName",
|
|
||||||
"categoryName",
|
|
||||||
"totalUse",
|
|
||||||
"estimationCost",
|
|
||||||
"endDate",
|
|
||||||
];
|
|
||||||
this.tableexcelService.exportAsExcelFileCostManage(
|
|
||||||
this.data_cost,
|
|
||||||
"Smart_building_cost_management",
|
|
||||||
columnsToExport
|
|
||||||
);
|
|
||||||
this.spinnerExportActive = false;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
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';
|
|
||||||
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
|
||||||
import { BlockUIModule } from 'ng-block-ui';
|
|
||||||
import { BlockTemplateComponent } from 'src/app/_layout/blockui/block-template.component';
|
|
||||||
import { CardModule } from '../../partials/general/card/card.module';
|
|
||||||
import { NgSelectModule } from '@ng-select/ng-select';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { ClipboardModule } from 'ngx-clipboard';
|
|
||||||
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';
|
|
||||||
import { NgxMaskModule, IConfig } from 'ngx-mask';
|
|
||||||
import { ModalExportComponent } from './modal-export/modal-export.component'
|
|
||||||
import { NgxEchartsModule } from 'ngx-echarts';
|
|
||||||
export const options: Partial<null|IConfig> | (() => Partial<IConfig>) = null;
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
CostManagementComponent,
|
|
||||||
ModalAddActualComponent,
|
|
||||||
ModalExportComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
CardModule,
|
|
||||||
BreadcrumbModule,
|
|
||||||
NgSelectModule,
|
|
||||||
FormsModule,
|
|
||||||
NgbModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
ClipboardModule,
|
|
||||||
PerfectScrollbarModule,
|
|
||||||
NgxDatatableModule,
|
|
||||||
NgChartsModule,
|
|
||||||
ChartistModule,
|
|
||||||
MatchHeightModule,
|
|
||||||
NgxEchartsModule.forRoot({
|
|
||||||
echarts: () => import('echarts')
|
|
||||||
}),
|
|
||||||
NgxMaskModule.forRoot(),
|
|
||||||
BlockUIModule.forRoot({
|
|
||||||
template: BlockTemplateComponent
|
|
||||||
}),
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: CostManagementComponent
|
|
||||||
}
|
|
||||||
])
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
DatePipe // Add DatePipe to providers
|
|
||||||
],
|
|
||||||
})
|
|
||||||
export class CostManagementModule { }
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
<div class="modal-body" style="background-color: #FBFBFB !important">
|
|
||||||
<h4 style="color: #242222">Input the actual cost of your expenses</h4>
|
|
||||||
<p style="color: #242222">Building : {{ buildingName }}</p>
|
|
||||||
<p style="color: #242222">Periode : {{ formattedDate }}</p>
|
|
||||||
<form [formGroup]="myForm">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="input-group">
|
|
||||||
<div
|
|
||||||
class="input-group-prepend"
|
|
||||||
style="background-color: #FBFBFB !important"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="input-group-text"
|
|
||||||
id="basic-addon1"
|
|
||||||
style="
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
color: #242222;
|
|
||||||
height: calc(1.5em + 0.75rem + 2px) !important;
|
|
||||||
"
|
|
||||||
>Rp</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="real_cost"
|
|
||||||
aria-describedby="basic-addon1"
|
|
||||||
formControlName="real_cost"
|
|
||||||
placeholder="..............."
|
|
||||||
mask="separator"
|
|
||||||
thousandSeparator="."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer justify-content-between" style="background-color: #FBFBFB !important; border-style: none !important;">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn"
|
|
||||||
style="
|
|
||||||
color: #242222;
|
|
||||||
width: 25%;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
border-color: #FBFBFB !important;
|
|
||||||
border-radius: 10px;
|
|
||||||
"
|
|
||||||
(click)="activeModal.dismiss('Cross click')"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn"
|
|
||||||
style="
|
|
||||||
color: #242222 !important;
|
|
||||||
width: 25%;
|
|
||||||
background-color: #DDE1E6 !important;
|
|
||||||
border-color: #DDE1E6 !important;
|
|
||||||
border-radius: 10px;
|
|
||||||
"
|
|
||||||
(click)="addRow()"
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,100 +0,0 @@
|
||||||
import { Component, Input } from "@angular/core";
|
|
||||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
|
||||||
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { CostManagementService } from "../../service/cost-management.service";
|
|
||||||
import { LoginService } from "../../service/login.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-modal-add-actual",
|
|
||||||
templateUrl: "./modal-add-actual.component.html",
|
|
||||||
styleUrls: ["./modal-add-actual.component.css"],
|
|
||||||
})
|
|
||||||
export class ModalAddActualComponent {
|
|
||||||
@Input() buildingId: number;
|
|
||||||
@Input() periode: any;
|
|
||||||
|
|
||||||
myForm: FormGroup;
|
|
||||||
dateCurrent: any;
|
|
||||||
dataCost: any;
|
|
||||||
formattedDate: any;
|
|
||||||
formattedDate2: any;
|
|
||||||
buildingName: any;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private costService: CostManagementService,
|
|
||||||
private authService: LoginService
|
|
||||||
) {
|
|
||||||
this.createForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
const currentDate = new Date();
|
|
||||||
this.dateCurrent = currentDate.toISOString().slice(0, 7);
|
|
||||||
this.dateFormat();
|
|
||||||
this.getBuildingById();
|
|
||||||
this.datalistcost();
|
|
||||||
}
|
|
||||||
|
|
||||||
dateFormat() {
|
|
||||||
let year = this.periode.slice(0, 4);
|
|
||||||
let month = this.periode.slice(5, 7);
|
|
||||||
let monthNames = [
|
|
||||||
"Januari",
|
|
||||||
"Februari",
|
|
||||||
"Maret",
|
|
||||||
"April",
|
|
||||||
"Mei",
|
|
||||||
"Juni",
|
|
||||||
"Juli",
|
|
||||||
"Agustus",
|
|
||||||
"September",
|
|
||||||
"Oktober",
|
|
||||||
"November",
|
|
||||||
"Desember",
|
|
||||||
];
|
|
||||||
let monthName = monthNames[parseInt(month) - 1];
|
|
||||||
this.formattedDate = `${monthName} ${year}`;
|
|
||||||
this.formattedDate2 = `${year}-${month}`;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
createForm() {
|
|
||||||
this.myForm = this.fb.group({
|
|
||||||
real_cost: ["", Validators.required],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getBuildingById() {
|
|
||||||
this.costService.getBUildingById(this.buildingId).subscribe((data) => {
|
|
||||||
this.buildingName = data.data.name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
datalistcost() {
|
|
||||||
this.costService
|
|
||||||
.getRealCostByBuildingId(this.buildingId, this.formattedDate2)
|
|
||||||
.subscribe((data) => {
|
|
||||||
this.dataCost = data.data[0];
|
|
||||||
this.myForm.patchValue({
|
|
||||||
real_cost: data.data[0].real_cost ? data.data[0].real_cost : 0,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addRow() {
|
|
||||||
if (this.myForm.valid) {
|
|
||||||
this.costService
|
|
||||||
.putRealCost(this.myForm.value, this.dataCost.id)
|
|
||||||
.subscribe((data) => {
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
this.activeModal.close(this.myForm.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,444 +0,0 @@
|
||||||
:host ::ng-deep .progress-bar {
|
|
||||||
background-color: #bef264 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
: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 {
|
|
||||||
stroke: #bef264;
|
|
||||||
stroke-width: 20px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart2 .ct-label {
|
|
||||||
fill: #ffffff;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
: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 {
|
|
||||||
stroke: #bef264;
|
|
||||||
}
|
|
||||||
|
|
||||||
: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 {
|
|
||||||
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: #bef264;
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart3 .ct-series-b .ct-bar {
|
|
||||||
stroke: #bef264;
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .donut-chart3 .ct-label {
|
|
||||||
fill: #ffffff;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1;
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ct-label.ct-horizontal {
|
|
||||||
font-size: 12px; /* Adjust font size */
|
|
||||||
transform: rotate(-45deg); /* Rotate labels if needed for better fit */
|
|
||||||
text-anchor: end;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ct-chart-bar .ct-labels .ct-label.ct-horizontal {
|
|
||||||
margin-right: 20px; /* Adjust margin for labels */
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-title {
|
|
||||||
font-size: 18px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide the default calendar icon */
|
|
||||||
input[type="month"]::-webkit-calendar-picker-indicator {
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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: #252525;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
margin-top: -1px;
|
|
||||||
overflow: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-header {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
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
|
|
||||||
.ngx-datatable
|
|
||||||
.datatable-footer
|
|
||||||
.selected-count
|
|
||||||
.datatable-pager {
|
|
||||||
flex: 0 0 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable {
|
|
||||||
display: -webkit-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container {
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
height: 40px !important;
|
|
||||||
border-radius: 12px !important;
|
|
||||||
box-shadow: 0 2px 4px rgba(36, 34, 34, 0.2) !important; /* Bayangan lebih tipis */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input {
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row {
|
|
||||||
background-color: #FBFBFB; /* Black color for table rows */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row:hover {
|
|
||||||
background-color: #DDE1E6; /* Darker black for hover effect */
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-data{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.style-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .modal-backdrop.show {
|
|
||||||
z-index: auto !important;
|
|
||||||
}
|
|
|
@ -1,156 +0,0 @@
|
||||||
<div class="modal-body" style="background-color: #FBFBFB !important">
|
|
||||||
<h4 style="color: #242222; margin-bottom: 20px !important">
|
|
||||||
Comparison of Water and Electricity Costs > {{ dataRow.building }}
|
|
||||||
</h4>
|
|
||||||
<p style="color: #242222">Room : {{ dataRow?.roomName }}</p>
|
|
||||||
<p style="color: #242222">Category : {{ dataRow?.categoryName }}</p>
|
|
||||||
|
|
||||||
<div class="card-dashboard">
|
|
||||||
<ngx-datatable
|
|
||||||
class="bootstrap table-bordered"
|
|
||||||
[limit]="10"
|
|
||||||
[rows]="data_cost"
|
|
||||||
[columnMode]="'force'"
|
|
||||||
[headerHeight]="50"
|
|
||||||
[footerHeight]="50"
|
|
||||||
[rowHeight]="50"
|
|
||||||
fxFlex="auto"
|
|
||||||
[scrollbarH]="true"
|
|
||||||
>
|
|
||||||
<ngx-datatable-column name="#" [flexGrow]="0.5" [minWidth]="30">
|
|
||||||
<ng-template ngx-datatable-cell-template let-rowIndex="rowIndex">
|
|
||||||
<p style="color: #242222 !important">
|
|
||||||
{{ rowIndex + 1 }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="periode" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Tanggal</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">
|
|
||||||
{{ value | date : "dd/MM/yyyy" }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="deviceName" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Device</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="roomName" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Room</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="categoryName" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Category</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="estimationCost"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Estimation Cost</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">
|
|
||||||
{{
|
|
||||||
value.toLocaleString("id-ID", {
|
|
||||||
style: "currency",
|
|
||||||
currency: "IDR"
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="totalKwh" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Total Kwh</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="watt" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Watt</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="duration" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Duration</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="priceKwh" [flexGrow]="1" [minWidth]="90">
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #242222 !important">Price Kwh</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template let-value="value" ngx-datatable-cell-template>
|
|
||||||
<p style="color: #242222 !important">
|
|
||||||
{{
|
|
||||||
value.toLocaleString("id-ID", {
|
|
||||||
style: "currency",
|
|
||||||
currency: "IDR"
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
</ngx-datatable>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="modal-footer justify-content-between"
|
|
||||||
style="background-color: #FBFBFB !important; border-style: none !important"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn"
|
|
||||||
style="
|
|
||||||
color: #242222;
|
|
||||||
width: 25%;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
border-color: #242222 !important;
|
|
||||||
border-radius: 10px;
|
|
||||||
"
|
|
||||||
(click)="activeModal.dismiss('Cross click')"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn"
|
|
||||||
style="
|
|
||||||
color: #242222 !important;
|
|
||||||
width: 25%;
|
|
||||||
background-color: #DDE1E6 !important;
|
|
||||||
border-color: #DDE1E6 !important;
|
|
||||||
border-radius: 10px;
|
|
||||||
"
|
|
||||||
[disabled]="spinnerExportActive"
|
|
||||||
(click)="export()"
|
|
||||||
>
|
|
||||||
<i class="la la-spinner spinner" *ngIf="spinnerExportActive"></i>
|
|
||||||
Export
|
|
||||||
</button>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ModalExportComponent } from './modal-export.component';
|
|
||||||
|
|
||||||
describe('ModalExportComponent', () => {
|
|
||||||
let component: ModalExportComponent;
|
|
||||||
let fixture: ComponentFixture<ModalExportComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ModalExportComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ModalExportComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,103 +0,0 @@
|
||||||
import { Component, Input } from "@angular/core";
|
|
||||||
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { DeviceService } from "../../service/device.service";
|
|
||||||
import { CostManagementService } from "../../service/cost-management.service";
|
|
||||||
import { TableexcelService } from "src/app/_services/tableexcel.service";
|
|
||||||
import { LoginService } from "../../service/login.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-modal-export",
|
|
||||||
templateUrl: "./modal-export.component.html",
|
|
||||||
styleUrls: ["./modal-export.component.css"],
|
|
||||||
})
|
|
||||||
export class ModalExportComponent {
|
|
||||||
@Input() buildingId: number;
|
|
||||||
@Input() dataRow: any;
|
|
||||||
data: any;
|
|
||||||
filteredRows: any[];
|
|
||||||
data_device: any[];
|
|
||||||
kwhTerm: string = "";
|
|
||||||
costTerm: string = "";
|
|
||||||
data_cost: any;
|
|
||||||
dataExport: any;
|
|
||||||
formattedEndDate: any;
|
|
||||||
spinnerExportActive = false;
|
|
||||||
constructor(
|
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private costService: CostManagementService,
|
|
||||||
private tableexcelService: TableexcelService,
|
|
||||||
private authService: LoginService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
const dateRow = this.convertToUTC7(this.dataRow.endDate)
|
|
||||||
this.formattedEndDate = dateRow.slice(0, 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
|
||||||
console.log(this.dataRow);
|
|
||||||
this.fetchData(
|
|
||||||
this.dataRow.categoryId,
|
|
||||||
this.dataRow.roomId,
|
|
||||||
this.formattedEndDate
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchData(category, room, period) {
|
|
||||||
this.costService
|
|
||||||
.getCostDetail(category, room, period)
|
|
||||||
.subscribe((response) => {
|
|
||||||
this.dataExport = response.data;
|
|
||||||
console.log(this.dataExport);
|
|
||||||
this.data_cost = response.data.map((item) => ({
|
|
||||||
deviceName: item.device_name,
|
|
||||||
roomName: item.room_name,
|
|
||||||
categoryName: item.category_name,
|
|
||||||
estimationCost: item.estimation_cost,
|
|
||||||
totalKwh: item.total_kwh,
|
|
||||||
watt: item.watt,
|
|
||||||
duration: item.duration,
|
|
||||||
priceKwh: item.price_kwh,
|
|
||||||
// periode: item.periode,
|
|
||||||
periode: this.convertToUTC7(item.periode)
|
|
||||||
}));
|
|
||||||
console.log(this.data_cost);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
convertToUTC7(dateString: string): string {
|
|
||||||
const date = new Date(dateString);
|
|
||||||
const utc7Offset = 7 * 60; // UTC+7 in minutes
|
|
||||||
const localOffset = date.getTimezoneOffset();
|
|
||||||
const totalOffset = utc7Offset - localOffset;
|
|
||||||
const utc7Date = new Date(date.getTime() + totalOffset * 60 * 1000);
|
|
||||||
return utc7Date.toISOString();
|
|
||||||
}
|
|
||||||
|
|
||||||
export() {
|
|
||||||
this.spinnerExportActive = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
const columnsToExport = [
|
|
||||||
"periode",
|
|
||||||
"deviceName",
|
|
||||||
"roomName",
|
|
||||||
"categoryName",
|
|
||||||
"estimationCost",
|
|
||||||
"totalKwh",
|
|
||||||
"watt",
|
|
||||||
"duration",
|
|
||||||
"priceKwh",
|
|
||||||
];
|
|
||||||
this.tableexcelService.exportAsExcelFileManageDetail(
|
|
||||||
this.data_cost,
|
|
||||||
"export_detail_cost_management",
|
|
||||||
columnsToExport
|
|
||||||
);
|
|
||||||
this.spinnerExportActive = false;
|
|
||||||
this.activeModal.close("Export completed");
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
.form-control.is-invalid {
|
|
||||||
border-color: #CACFE7;
|
|
||||||
background-image: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.div.basicInfoCard {
|
|
||||||
height: 700px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .block-ui-wrapper {
|
|
||||||
background: rgba(255, 249, 249, 0.5) !important;
|
|
||||||
}
|
|
||||||
:host ::ng-deep .block-ui-wrapper {
|
|
||||||
background: rgba(255, 249, 249, 0.5) !important;
|
|
||||||
}
|
|
||||||
:host ::ng-deep .btn-light:not(:disabled):not(.disabled):active {
|
|
||||||
color: unset !important;
|
|
||||||
background-color: unset !important;
|
|
||||||
border-color: #d3d9df !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .btn-light:hover:not(.disabled):active {
|
|
||||||
background-color: #e2e6ea !important;
|
|
||||||
border-color: #dae0e5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .btn-light {
|
|
||||||
color: unset !important;
|
|
||||||
background-color: unset !important;
|
|
||||||
border-color: unset !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .bg-primary {
|
|
||||||
background-color: #007bff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .text-white {
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .custom-day {
|
|
||||||
text-align: center;
|
|
||||||
padding: .185rem .25rem;
|
|
||||||
display: inline-block;
|
|
||||||
height: 2rem;
|
|
||||||
width: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .custom-day:active {
|
|
||||||
color: #6d7183 !important;
|
|
||||||
background-color: #fff !important;
|
|
||||||
border-block-color: rgb(2, 117, 216) !important;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-light {
|
|
||||||
background-color: #f8f9fa !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .hidden {
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-dp-weekday {
|
|
||||||
color: #17a2b8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-dp-week-number,
|
|
||||||
.ngb-dp-weekday {
|
|
||||||
line-height: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-datepicker-month-view {
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small {
|
|
||||||
font-size: 80%;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-dp-day {
|
|
||||||
cursor: pointer !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-dp-month {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-light:hover {
|
|
||||||
color: #212529 !important;
|
|
||||||
background-color: #e2e6ea !important;
|
|
||||||
border-color: #dae0e5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-datepicker-month-view {
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngb-dp-header {
|
|
||||||
background-color: var(--light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngb-dp-weekdays {
|
|
||||||
background-color: var(--light);
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngb-dp-month-name {
|
|
||||||
background-color: var(--light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-dp-header {
|
|
||||||
border-bottom: 0;
|
|
||||||
border-radius: .25rem .25rem 0 0;
|
|
||||||
padding-top: .25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ngb-dp-day,
|
|
||||||
.ngb-dp-week-number,
|
|
||||||
.ngb-dp-weekday {
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-day {
|
|
||||||
text-align: center;
|
|
||||||
padding: 0.185rem 0.25rem;
|
|
||||||
display: inline-block;
|
|
||||||
height: 2rem;
|
|
||||||
width: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-day.focused {
|
|
||||||
background-color: #e6e6e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-day.range,
|
|
||||||
.custom-day:hover {
|
|
||||||
background-color: rgb(2, 117, 216);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-day.faded {
|
|
||||||
background-color: rgba(2, 117, 216, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .block-ui-wrapper {
|
|
||||||
background: rgba(255, 249, 249, 0.5) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,294 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #fbfbfb !important">
|
|
||||||
<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">
|
|
||||||
<section id="basic-form-layouts">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12" *blockUI="'projectInfo'; message: 'Loading'">
|
|
||||||
<div class="card" style="background-color: #fbfbfb !important">
|
|
||||||
<div class="card-content">
|
|
||||||
<div
|
|
||||||
class="card-header"
|
|
||||||
style="background-color: #fbfbfb !important"
|
|
||||||
>
|
|
||||||
<h2 style="color: #242222">
|
|
||||||
{{
|
|
||||||
isEditMode()
|
|
||||||
? "Edit Device"
|
|
||||||
: isViewMode()
|
|
||||||
? "View Device"
|
|
||||||
: "Add New Device"
|
|
||||||
}}
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form
|
|
||||||
[formGroup]="projectInfo"
|
|
||||||
(ngSubmit)="onProjectInfoSubmit()"
|
|
||||||
>
|
|
||||||
<div class="form-body">
|
|
||||||
<h4 class="form-section" style="color: #242222">
|
|
||||||
<i class="feather ft-user" style="color: #242222"></i>
|
|
||||||
General Information
|
|
||||||
</h4>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="name" style="color: #242222"
|
|
||||||
>Device Name *</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
id="name"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="name"
|
|
||||||
placeholder="Device Name"
|
|
||||||
maxlength="50"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.name.errors
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<small
|
|
||||||
class="form-text text-muted danger"
|
|
||||||
*ngIf="submitted && f.name.errors"
|
|
||||||
class="invalid-feedback"
|
|
||||||
>
|
|
||||||
<div *ngIf="f.name.errors.required">
|
|
||||||
Device Name is required
|
|
||||||
</div>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="categoryId" style="color: #242222"
|
|
||||||
>Category *</label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
id="categoryId"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="categoryId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.categoryId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataMasterCategori"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
*ngIf="
|
|
||||||
projectInfo.get('categoryId').invalid &&
|
|
||||||
projectInfo.get('categoryId').touched
|
|
||||||
"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
<small class="text-danger"
|
|
||||||
>Category is required.</small
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="voltageId" style="color: #242222"
|
|
||||||
>Voltage *</label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
id="voltageId"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="voltageId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.voltageId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataMasterVoltage"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
*ngIf="
|
|
||||||
projectInfo.get('voltageId').invalid &&
|
|
||||||
projectInfo.get('voltageId').touched
|
|
||||||
"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
<small class="text-danger"
|
|
||||||
>Voltage is required.</small
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="typeId" style="color: #242222"
|
|
||||||
>Type *</label
|
|
||||||
>
|
|
||||||
<select
|
|
||||||
id="typeId"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="typeId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.typeId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataMasterType"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<small
|
|
||||||
class="form-text text-muted danger"
|
|
||||||
*ngIf="submitted && f.typeId.errors"
|
|
||||||
class="invalid-feedback"
|
|
||||||
>
|
|
||||||
<div *ngIf="f.typeId.errors.required">
|
|
||||||
Type is required
|
|
||||||
</div>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="durationId" style="color: #242222"
|
|
||||||
>Duration Use *</label
|
|
||||||
>
|
|
||||||
<select
|
|
||||||
id="durationId"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="durationId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.durationId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataMasterDuration"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<small
|
|
||||||
class="form-text text-muted danger"
|
|
||||||
*ngIf="submitted && f.durationId.errors"
|
|
||||||
class="invalid-feedback"
|
|
||||||
>
|
|
||||||
<div *ngIf="f.durationId.errors.required">
|
|
||||||
Duration is required
|
|
||||||
</div>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="roomBuildingId" style="color: #242222"
|
|
||||||
>Location Room *</label
|
|
||||||
>
|
|
||||||
<select
|
|
||||||
id="roomBuildingId"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="roomBuildingId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid':
|
|
||||||
submitted && f.roomBuildingId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataBuildingRoomList"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<small
|
|
||||||
class="form-text text-muted danger"
|
|
||||||
*ngIf="submitted && f.roomBuildingId.errors"
|
|
||||||
class="invalid-feedback"
|
|
||||||
>
|
|
||||||
<div *ngIf="f.roomBuildingId.errors.required">
|
|
||||||
location room is required
|
|
||||||
</div>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="watt" style="color: #242222"
|
|
||||||
>Watt *</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
id="watt"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="watt"
|
|
||||||
maxlength="10"
|
|
||||||
placeholder="Watt"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.watt.errors
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
*ngIf="
|
|
||||||
projectInfo.get('watt').invalid &&
|
|
||||||
projectInfo.get('watt').touched
|
|
||||||
"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
<small class="text-danger">Please enter a valid Watt.</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-actions">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-warning mr-1"
|
|
||||||
style="
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #fbfbfb !important;
|
|
||||||
border-color: #fbfbfb !important;
|
|
||||||
"
|
|
||||||
(click)="cancel()"
|
|
||||||
>
|
|
||||||
<i *ngIf="mode === 'edit'" class="feather ft-x"></i>
|
|
||||||
<i *ngIf="mode === 'view'" class="la la-arrow-left"></i>
|
|
||||||
{{ mode === "edit" ? "Cancel" : "Back" }}
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
(click)="saveEdit()"
|
|
||||||
*ngIf="mode === 'edit'"
|
|
||||||
>
|
|
||||||
<i class="la la-check"></i> Save
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AddEditDeviceComponent } from './add-edit-device.component';
|
|
||||||
|
|
||||||
describe('AddEditDeviceComponent', () => {
|
|
||||||
let component: AddEditDeviceComponent;
|
|
||||||
let fixture: ComponentFixture<AddEditDeviceComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ AddEditDeviceComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AddEditDeviceComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,308 +0,0 @@
|
||||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
|
||||||
import { FormBuilder, FormGroup, NgForm, Validators } from "@angular/forms";
|
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
|
||||||
import { BlockUI, NgBlockUI } from "ng-block-ui";
|
|
||||||
import { BuildingService } from "../../service/monitoring-api.service";
|
|
||||||
import { LoginService } from "../../service/login.service";
|
|
||||||
import Swal from "sweetalert2";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-add-edit-device",
|
|
||||||
templateUrl: "./add-edit-device.component.html",
|
|
||||||
styleUrls: ["./add-edit-device.component.css"],
|
|
||||||
})
|
|
||||||
export class AddEditDeviceComponent implements OnInit {
|
|
||||||
@ViewChild("f", { read: true }) userProfileForm: NgForm;
|
|
||||||
dataMasterCategori: any;
|
|
||||||
dataMasterVoltage: any;
|
|
||||||
dataMasterType: any;
|
|
||||||
dataMasterDuration: any;
|
|
||||||
dataMasterStatus: any;
|
|
||||||
dataBuildingRoomList: any;
|
|
||||||
deviceId: any;
|
|
||||||
|
|
||||||
model: any = {};
|
|
||||||
dataDevice: any;
|
|
||||||
mode: string;
|
|
||||||
|
|
||||||
@BlockUI("projectInfo") blockUIProjectInfo: NgBlockUI;
|
|
||||||
|
|
||||||
public breadcrumb: any;
|
|
||||||
|
|
||||||
projectInfo: FormGroup;
|
|
||||||
|
|
||||||
submitted = false;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private formBuilder: FormBuilder,
|
|
||||||
private router: Router,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private authService: LoginService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.route.params.subscribe((params) => {
|
|
||||||
const id = params["id"];
|
|
||||||
this.deviceId = id;
|
|
||||||
if (id) {
|
|
||||||
this.loadDevice(id);
|
|
||||||
this.dataListMaster();
|
|
||||||
this.dataListRoomBuilding();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.setBreadcrumb();
|
|
||||||
this.route.data.subscribe((data) => {
|
|
||||||
this.mode = data.mode;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.projectInfo = this.formBuilder.group({
|
|
||||||
name: ["", Validators.required],
|
|
||||||
categoryId: ["", Validators.required],
|
|
||||||
voltageId: ["", Validators.required],
|
|
||||||
typeId: ["", Validators.required],
|
|
||||||
durationId: ["", Validators.required],
|
|
||||||
roomBuildingId: ["", Validators.required],
|
|
||||||
watt: ["", [Validators.required, Validators.maxLength(15), Validators.pattern(/^[0-9]{1,7}$/)]],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
loadDevice(deviceId: string) {
|
|
||||||
this.monitoringApiService.getDeviceById(deviceId).subscribe((data) => {
|
|
||||||
this.dataDevice = data;
|
|
||||||
console.log(this.dataDevice);
|
|
||||||
|
|
||||||
this.formGetDevice(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListMaster() {
|
|
||||||
this.monitoringApiService.getMasterListData().subscribe((data) => {
|
|
||||||
const dataCategory = data.data.find(
|
|
||||||
(item) => item.name === "master_category"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterCategori = dataCategory.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" ||
|
|
||||||
item.status.toLowerCase() === "71"
|
|
||||||
);
|
|
||||||
|
|
||||||
const dataVoltage = data.data.find(
|
|
||||||
(item) => item.name === "master_voltage"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterVoltage = dataVoltage.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" ||
|
|
||||||
item.status.toLowerCase() === "71"
|
|
||||||
);
|
|
||||||
|
|
||||||
const dataType = data.data.find(
|
|
||||||
(item) => item.name === "master_type"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterType = dataType.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" ||
|
|
||||||
item.status.toLowerCase() === "71"
|
|
||||||
);
|
|
||||||
|
|
||||||
const dataDuration = data.data.find(
|
|
||||||
(item) => item.name === "master_duration"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterDuration = dataDuration.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" ||
|
|
||||||
item.status.toLowerCase() === "71"
|
|
||||||
);
|
|
||||||
|
|
||||||
const dataStatus = data.data.find(
|
|
||||||
(item) => item.name === "master_status"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterStatus = dataStatus.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" ||
|
|
||||||
item.status.toLowerCase() === "71"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListRoomBuilding() {
|
|
||||||
this.monitoringApiService.getBuildingRoomList().subscribe((data) => {
|
|
||||||
const newArray = data.results.data.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
name: `${item.buildingEntity.name} (${item.roomEntity.name})`,
|
|
||||||
}));
|
|
||||||
this.dataBuildingRoomList = newArray;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
formGetDevice(data) {
|
|
||||||
this.projectInfo.patchValue({
|
|
||||||
name: data.data.name,
|
|
||||||
categoryId: data.data.categoryId,
|
|
||||||
voltageId: data.data.voltageId,
|
|
||||||
typeId: data.data.typeId,
|
|
||||||
durationId: data.data.durationId,
|
|
||||||
roomBuildingId: data.data.roomBuildingId,
|
|
||||||
watt: data.data.watt,
|
|
||||||
});
|
|
||||||
if (this.mode === "view") {
|
|
||||||
this.formDisable();
|
|
||||||
}
|
|
||||||
if (this.projectInfo.get("roomBuildingId").value) {
|
|
||||||
this.projectInfo.get("roomBuildingId").disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formDisable() {
|
|
||||||
this.projectInfo.get("name").disable();
|
|
||||||
this.projectInfo.get("categoryId").disable();
|
|
||||||
this.projectInfo.get("voltageId").disable();
|
|
||||||
this.projectInfo.get("typeId").disable();
|
|
||||||
this.projectInfo.get("durationId").disable();
|
|
||||||
this.projectInfo.get("roomBuildingId").disable();
|
|
||||||
this.projectInfo.get("watt").disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
setBreadcrumb() {
|
|
||||||
if (this.isAddMode()) {
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Device",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Add new device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
} else if (this.isEditMode()) {
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Device",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Edit new device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
} else if (this.isViewMode()) {
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Device",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "View new device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isEditMode() {
|
|
||||||
return this.mode === "edit";
|
|
||||||
}
|
|
||||||
|
|
||||||
isViewMode() {
|
|
||||||
return this.mode === "view";
|
|
||||||
}
|
|
||||||
|
|
||||||
isAddMode() {
|
|
||||||
return this.mode === "add";
|
|
||||||
}
|
|
||||||
|
|
||||||
get f() {
|
|
||||||
return this.projectInfo.controls;
|
|
||||||
}
|
|
||||||
|
|
||||||
onProjectInfoSubmit() {
|
|
||||||
this.submitted = true;
|
|
||||||
if (this.projectInfo.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keyPress(event: any) {
|
|
||||||
const pattern = /[0-9\+\-\ ]/;
|
|
||||||
const inputChar = String.fromCharCode(event.charCode);
|
|
||||||
if (event.keyCode !== 8 && !pattern.test(inputChar)) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
saveEdit() {
|
|
||||||
if (this.projectInfo.valid) {
|
|
||||||
if (this.dataDevice.data.roomBuildingId) {
|
|
||||||
this.monitoringApiService
|
|
||||||
.putDevice(this.projectInfo.value, this.deviceId)
|
|
||||||
.subscribe((data) => {
|
|
||||||
this.router.navigate(["/device"]);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Apakah kamu yakin?",
|
|
||||||
text: "Data lokasi device tidak dapat diubah!",
|
|
||||||
icon: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: "#37a647",
|
|
||||||
cancelButtonColor: "#d33",
|
|
||||||
confirmButtonText: "Yes, save it!",
|
|
||||||
allowOutsideClick: false,
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
this.monitoringApiService
|
|
||||||
.putDevice(this.projectInfo.value, this.deviceId)
|
|
||||||
.subscribe((data) => {
|
|
||||||
this.router.navigate(["/device"]);
|
|
||||||
});
|
|
||||||
Swal.fire({
|
|
||||||
title: "Saved!",
|
|
||||||
text: "Data berhasil disimpan.",
|
|
||||||
icon: "success",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.markFormGroupTouched(this.projectInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
markFormGroupTouched(formGroup: FormGroup) {
|
|
||||||
(Object as any).values(formGroup.controls).forEach((control) => {
|
|
||||||
control.markAsTouched();
|
|
||||||
if (control.controls) {
|
|
||||||
this.markFormGroupTouched(control);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.router.navigate(["/device"]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
::ng-deep .modal-backdrop.show {
|
|
||||||
z-index: auto !important;
|
|
||||||
}
|
|
|
@ -1,144 +0,0 @@
|
||||||
<div class="modal-header" style="background-color: #fbfbfb !important">
|
|
||||||
<h4 class="modal-title" style="color: #242222">{{ labelModal }}</h4>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="close"
|
|
||||||
aria-label="Close"
|
|
||||||
(click)="activeModal.dismiss('Cross click')"
|
|
||||||
>
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body" style="background-color: #fbfbfb !important">
|
|
||||||
<form [formGroup]="myForm">
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="name" style="color: #242222">Name:</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="name"
|
|
||||||
formControlName="name"
|
|
||||||
maxlength="50"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
*ngIf="myForm.get('name').touched && myForm.get('name').invalid"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
Name is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="timeset" style="color: #242222">Time</label>
|
|
||||||
<input
|
|
||||||
type="time"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="timeset"
|
|
||||||
id="timeset"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
*ngIf="myForm.get('timeset').touched && myForm.get('timeset').invalid"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
Time On is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="switch" style="color: #242222">Switch:</label>
|
|
||||||
<select
|
|
||||||
id="switch"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="switch"
|
|
||||||
>
|
|
||||||
<option *ngFor="let data of dataSwitch" [value]="data.value">
|
|
||||||
{{ data.label }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<div
|
|
||||||
*ngIf="myForm.get('switch').touched && myForm.get('switch').invalid"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
Switch is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Checkbox for Days of the Week -->
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label style="color: #242222">Select Days:</label>
|
|
||||||
<div *ngFor="let day of daysOfWeek">
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
class="form-check-input"
|
|
||||||
[formControlName]="day.value"
|
|
||||||
(change)="onDayChange(day.value, $event.target.checked)"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" style="color: #242222">{{
|
|
||||||
day.label
|
|
||||||
}}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="myForm.hasError('noDaySelected') && myForm.touched" class="text-danger">
|
|
||||||
Please select at least one day.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Checkbox for Repeat -->
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label style="color: #242222">Repeat:</label>
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
class="form-check-input"
|
|
||||||
formControlName="recurring"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" style="color: #242222">Yes</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- <div class="form-group col-md-12">
|
|
||||||
<label for="active" style="color: #242222">Active:</label>
|
|
||||||
<select
|
|
||||||
id="active"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="active"
|
|
||||||
>
|
|
||||||
<option *ngFor="let data of dataActive" [value]="data.value">
|
|
||||||
{{ data.label }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<div
|
|
||||||
*ngIf="myForm.get('active').touched && myForm.get('active').invalid"
|
|
||||||
class="text-danger"
|
|
||||||
>
|
|
||||||
Active is required.
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer" style="background-color: #fbfbfb !important">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-secondary"
|
|
||||||
style="
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #fbfbfb !important;
|
|
||||||
border-color: #fbfbfb !important;
|
|
||||||
"
|
|
||||||
(click)="activeModal.dismiss('Cross click')"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
style="color: #ffffff !important; background-color: #37a647 !important"
|
|
||||||
class="btn btn-primary"
|
|
||||||
(click)="save()"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ControlSchedulerComponent } from './control-scheduler.component';
|
|
||||||
|
|
||||||
describe('ControlSchedulerComponent', () => {
|
|
||||||
let component: ControlSchedulerComponent;
|
|
||||||
let fixture: ComponentFixture<ControlSchedulerComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ControlSchedulerComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ControlSchedulerComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,175 +0,0 @@
|
||||||
import { Component, Input } from "@angular/core";
|
|
||||||
import {
|
|
||||||
FormBuilder,
|
|
||||||
FormControl,
|
|
||||||
FormGroup,
|
|
||||||
Validators,
|
|
||||||
} from "@angular/forms";
|
|
||||||
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { DeviceService } from "../../service/device.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-control-scheduler",
|
|
||||||
templateUrl: "./control-scheduler.component.html",
|
|
||||||
styleUrls: ["./control-scheduler.component.css"],
|
|
||||||
})
|
|
||||||
export class ControlSchedulerComponent {
|
|
||||||
@Input() deviceId: any;
|
|
||||||
@Input() data: any;
|
|
||||||
@Input() mode: any;
|
|
||||||
labelModal: string = "";
|
|
||||||
myForm: FormGroup;
|
|
||||||
dataSwitch = [
|
|
||||||
{
|
|
||||||
label: "On",
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Off",
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
dataActive = [
|
|
||||||
{
|
|
||||||
label: "Active",
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Non Active",
|
|
||||||
value: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
daysOfWeek = [
|
|
||||||
{ label: "Monday", value: "monday" },
|
|
||||||
{ label: "Tuesday", value: "tuesday" },
|
|
||||||
{ label: "Wednesday", value: "wednesday" },
|
|
||||||
{ label: "Thursday", value: "thursday" },
|
|
||||||
{ label: "Friday", value: "friday" },
|
|
||||||
{ label: "Saturday", value: "saturday" },
|
|
||||||
{ label: "Sunday", value: "sunday" },
|
|
||||||
];
|
|
||||||
|
|
||||||
selectedDays: string[] = [];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private deviceService: DeviceService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.createForm();
|
|
||||||
if (this.mode === "add") {
|
|
||||||
this.labelModal = "Add Scheduler";
|
|
||||||
} else if (this.mode === "edit") {
|
|
||||||
this.editForm();
|
|
||||||
this.labelModal = "Edit Scheduler";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createForm() {
|
|
||||||
const controls = {
|
|
||||||
name: ["", Validators.required],
|
|
||||||
timeset: ["", Validators.required],
|
|
||||||
active: [true],
|
|
||||||
switch: [false],
|
|
||||||
recurring: [true], // Default value for repeat checkbox
|
|
||||||
device_id: this.deviceId,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize checkboxes for each day of the week
|
|
||||||
this.daysOfWeek.forEach((day) => {
|
|
||||||
controls[day.value] = [false]; // Each day starts as unchecked
|
|
||||||
});
|
|
||||||
|
|
||||||
this.myForm = this.fb.group(controls);
|
|
||||||
this.myForm.setValidators(this.atLeastOneDaySelectedValidator());
|
|
||||||
}
|
|
||||||
|
|
||||||
editForm() {
|
|
||||||
this.selectedDays = this.data.days || [];
|
|
||||||
this.myForm.patchValue({
|
|
||||||
name: this.data.name,
|
|
||||||
timeset: this.data.timeset,
|
|
||||||
recurring: this.data.recurring,
|
|
||||||
active: this.data.active,
|
|
||||||
switch: this.data.switch,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Patch the form with the selected days
|
|
||||||
this.selectedDays.forEach((day) => {
|
|
||||||
this.myForm.patchValue({
|
|
||||||
[day]: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
atLeastOneDaySelectedValidator() {
|
|
||||||
return (formGroup: FormGroup) => {
|
|
||||||
const selectedDays = this.daysOfWeek.some(
|
|
||||||
(day) => formGroup.get(day.value)?.value
|
|
||||||
);
|
|
||||||
return selectedDays ? null : { noDaySelected: true };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onDayChange(day: string, isChecked: boolean) {
|
|
||||||
if (isChecked) {
|
|
||||||
this.selectedDays.push(day);
|
|
||||||
} else {
|
|
||||||
this.selectedDays = this.selectedDays.filter((d) => d !== day);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save() {
|
|
||||||
if (this.myForm.valid) {
|
|
||||||
const formValues = this.myForm.value;
|
|
||||||
|
|
||||||
// Collect selected days' labels
|
|
||||||
const selectedDays = this.daysOfWeek
|
|
||||||
.filter((day) => formValues[day.value])
|
|
||||||
.map((day) => day.value);
|
|
||||||
|
|
||||||
// Construct the final output
|
|
||||||
let result = {};
|
|
||||||
|
|
||||||
if (this.mode === "add") {
|
|
||||||
result = {
|
|
||||||
name: formValues.name,
|
|
||||||
device_id: formValues.device_id,
|
|
||||||
timeset: formValues.timeset,
|
|
||||||
recurring: formValues.recurring,
|
|
||||||
active: formValues.active,
|
|
||||||
switch: formValues.switch,
|
|
||||||
days: selectedDays,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
result = {
|
|
||||||
id: this.data.id,
|
|
||||||
name: formValues.name,
|
|
||||||
device_id: formValues.device_id,
|
|
||||||
timeset: formValues.timeset,
|
|
||||||
recurring: formValues.recurring,
|
|
||||||
active: formValues.active,
|
|
||||||
switch: formValues.switch,
|
|
||||||
days: selectedDays,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.activeModal.close(result);
|
|
||||||
} else {
|
|
||||||
this.markFormGroupTouched(this.myForm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
markFormGroupTouched(formGroup: FormGroup) {
|
|
||||||
(Object as any).values(formGroup.controls).forEach((control) => {
|
|
||||||
control.markAsTouched();
|
|
||||||
if (control.controls) {
|
|
||||||
this.markFormGroupTouched(control);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
:host ::ng-deep .ng-select .ng-select-container {
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
height: 40px !important;
|
|
||||||
border-radius: 12px !important;
|
|
||||||
box-shadow: 0 2px 4px rgba(36, 34, 34, 0.2) !important; /* Bayangan lebih tipis */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.background-round {
|
|
||||||
background-color: #252525 !important;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 2px solid #BEF264;
|
|
||||||
border-color: #BEF264 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-name{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-category{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-popup {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 30px;
|
|
||||||
background-color: white;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
border-radius: 5px;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-popup ul {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-popup ul li {
|
|
||||||
padding: 10px 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-popup ul li:hover {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
}
|
|
|
@ -1,208 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #fbfbfb !important">
|
|
||||||
<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">
|
|
||||||
<section id="configuration">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div
|
|
||||||
class="card"
|
|
||||||
style="
|
|
||||||
background-color: #fbfbfb !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<ng-select
|
|
||||||
class="select-custom"
|
|
||||||
[items]="dataBuildingList"
|
|
||||||
[searchable]="true"
|
|
||||||
bindLabel="name"
|
|
||||||
bindValue="id"
|
|
||||||
placeholder="Select Building"
|
|
||||||
[(ngModel)]="buildingSelected"
|
|
||||||
style="width: 100% !important"
|
|
||||||
>
|
|
||||||
</ng-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<ng-select
|
|
||||||
class="select-custom"
|
|
||||||
[items]="dataMasterCategori"
|
|
||||||
[searchable]="true"
|
|
||||||
bindLabel="name"
|
|
||||||
bindValue="id"
|
|
||||||
placeholder="Select Category"
|
|
||||||
[(ngModel)]="categorySelected"
|
|
||||||
>
|
|
||||||
</ng-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<ng-select
|
|
||||||
class="select-custom"
|
|
||||||
[items]="dataMasterStatus"
|
|
||||||
[searchable]="true"
|
|
||||||
bindLabel="name"
|
|
||||||
bindValue="id"
|
|
||||||
placeholder="Select Status"
|
|
||||||
[(ngModel)]="statusSelected"
|
|
||||||
>
|
|
||||||
</ng-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 text-left">
|
|
||||||
<div class="d-flex">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn ml-2"
|
|
||||||
(click)="doFilter()"
|
|
||||||
style="
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
border-color: #ffffff !important;
|
|
||||||
border-radius: 12px;
|
|
||||||
color: #ffffff;
|
|
||||||
"
|
|
||||||
[disabled]="spinnerFilterActive"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-search"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
*ngIf="!spinnerFilterActive"
|
|
||||||
></i>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
*ngIf="spinnerFilterActive"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-outline-success ml-2"
|
|
||||||
(click)="doCancelFilter()"
|
|
||||||
style="
|
|
||||||
background-color: #fbfbfb !important;
|
|
||||||
border-color: #6b6b6b !important;
|
|
||||||
color: #6b6b6b;
|
|
||||||
border-radius: 12px;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section id="configuration">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12" *ngIf="filteredRows?.length === 0">
|
|
||||||
<div
|
|
||||||
class="card"
|
|
||||||
style="
|
|
||||||
background-color: #fbfbfb !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="text-center" style="color: #242222">
|
|
||||||
No data available
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-12" *ngFor="let item of filteredDeviceRows">
|
|
||||||
<div
|
|
||||||
class="card"
|
|
||||||
style="background-color: #dde1e6; position: relative"
|
|
||||||
>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="media d-flex">
|
|
||||||
<div class="align-self-center">
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
background-color: #37a647;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="{{
|
|
||||||
item.category_icon
|
|
||||||
}} font-large-1 blue-grey d-block"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div style="margin-top: 10px">
|
|
||||||
<span class="text-custom-name">{{ item.name }}</span>
|
|
||||||
<br />
|
|
||||||
<span class="text-custom-category">{{
|
|
||||||
item.category_name
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="position: absolute; top: 10px; right: 10px">
|
|
||||||
<button
|
|
||||||
(click)="toggleMenu(item.id)"
|
|
||||||
class="btn"
|
|
||||||
style="
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
font-size: 20px;
|
|
||||||
padding: 0;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
⋮
|
|
||||||
</button>
|
|
||||||
<div *ngIf="item.menuOpen" class="menu-popup">
|
|
||||||
<ul>
|
|
||||||
<li (click)="schedulerItem(item)">scheduler</li>
|
|
||||||
</ul>
|
|
||||||
</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(55, 166, 71)"
|
|
||||||
size="small"
|
|
||||||
[checked]="item.status_id === 2"
|
|
||||||
(change)="switchChanged($event, item)"
|
|
||||||
></ui-switch>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { DeviceControlComponent } from './device-control.component';
|
|
||||||
|
|
||||||
describe('DeviceControlComponent', () => {
|
|
||||||
let component: DeviceControlComponent;
|
|
||||||
let fixture: ComponentFixture<DeviceControlComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ DeviceControlComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(DeviceControlComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,213 +0,0 @@
|
||||||
import { Component, HostListener } from "@angular/core";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
import { BuildingService } from "../../service/monitoring-api.service";
|
|
||||||
import { DeviceService } from "../../service/device.service";
|
|
||||||
import { ToastrService } from "ngx-toastr";
|
|
||||||
import { LoginService } from "../../service/login.service";
|
|
||||||
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { ControlSchedulerComponent } from "../control-scheduler/control-scheduler.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-device-control",
|
|
||||||
templateUrl: "./device-control.component.html",
|
|
||||||
styleUrls: ["./device-control.component.css"],
|
|
||||||
})
|
|
||||||
export class DeviceControlComponent {
|
|
||||||
data: any;
|
|
||||||
|
|
||||||
filteredRows: any[];
|
|
||||||
filteredDeviceRows: any[];
|
|
||||||
searchTerm: string = "";
|
|
||||||
buildingSelected: any;
|
|
||||||
statusSelected: any;
|
|
||||||
categorySelected: any;
|
|
||||||
dataMasterCategori: any;
|
|
||||||
dataBuildingList: any;
|
|
||||||
dataMasterStatus: any;
|
|
||||||
storedData: any;
|
|
||||||
spinnerFilterActive = false;
|
|
||||||
switchState: boolean;
|
|
||||||
public breadcrumb: any;
|
|
||||||
spinnerActive: boolean = false;
|
|
||||||
singlebasicSelected: any;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private deviceService: DeviceService,
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private toastr: ToastrService,
|
|
||||||
private authService: LoginService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Device",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
link: "/dashboard/sales",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
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(buildingSelected, categorySelected, statusSelected) {
|
|
||||||
this.deviceService
|
|
||||||
.getDeviceData(buildingSelected, categorySelected, statusSelected)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.data = res;
|
|
||||||
this.filteredRows = this.data.results.data;
|
|
||||||
this.filteredDeviceRows = this.filterDevices(this.filteredRows);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
filterDevices(devices: any[]): any[] {
|
|
||||||
return devices.filter((device) =>
|
|
||||||
device.mapping.some(
|
|
||||||
(map) => map.code.startsWith("switch") && map.type === "Boolean"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.statusName.toLowerCase() === "aktif"
|
|
||||||
);
|
|
||||||
this.dataMasterStatus = dataStatus.filter((item) => item.statusName.toLowerCase() === "aktif");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListBuilding() {
|
|
||||||
this.monitoringApiService.getBuildingList().subscribe((data) => {
|
|
||||||
this.dataBuildingList = data.data.filter((item) => item.statusName.toLowerCase() === "aktif");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
doFilter() {
|
|
||||||
if (!this.buildingSelected) {
|
|
||||||
this.toastr.error("Warning", "Filter Building tidak boleh kosong.", {
|
|
||||||
timeOut: 5000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.spinnerFilterActive = true;
|
|
||||||
this.fetchData(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.categorySelected,
|
|
||||||
this.statusSelected
|
|
||||||
);
|
|
||||||
setTimeout(() => {
|
|
||||||
this.spinnerFilterActive = false;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doCancelFilter() {
|
|
||||||
this.storedData = JSON.parse(localStorage.getItem("currentUser"));
|
|
||||||
this.buildingSelected = this.storedData.buildingId;
|
|
||||||
this.categorySelected = undefined;
|
|
||||||
this.statusSelected = undefined;
|
|
||||||
this.fetchData(this.buildingSelected, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
switchChanged(ev, data) {
|
|
||||||
const requestData = {
|
|
||||||
id: data.id,
|
|
||||||
code: data.mapping[0].code,
|
|
||||||
value: ev,
|
|
||||||
command_type: "on_off",
|
|
||||||
};
|
|
||||||
this.deviceService.deviceSwitch(requestData).subscribe((res) => {
|
|
||||||
console.log(res);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleMenu(itemId) {
|
|
||||||
this.filteredDeviceRows.forEach(item => {
|
|
||||||
if (item.id === itemId) {
|
|
||||||
item.menuOpen = !item.menuOpen;
|
|
||||||
} else {
|
|
||||||
item.menuOpen = false; // Close other menus
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
schedulerItem(row) {
|
|
||||||
console.log(row);
|
|
||||||
|
|
||||||
this.router.navigate(["/device/scheduler", row.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// schedulerItem(item) {
|
|
||||||
// const modalRef = this.modalService.open(ControlSchedulerComponent, {
|
|
||||||
// size: "md",
|
|
||||||
// backdrop: "static",
|
|
||||||
// keyboard: false,
|
|
||||||
// centered: true
|
|
||||||
// });
|
|
||||||
|
|
||||||
// modalRef.componentInstance.device = item;
|
|
||||||
// modalRef.result.then(
|
|
||||||
// (result) => {
|
|
||||||
// if (result) {
|
|
||||||
// console.log(result);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// (reason) => {
|
|
||||||
// console.log(`Dismissed: ${reason}`);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// // Handle edit action
|
|
||||||
// }
|
|
||||||
|
|
||||||
@HostListener('document:click', ['$event'])
|
|
||||||
clickout(event) {
|
|
||||||
if (!event.target.closest('.menu-popup') && !event.target.closest('.btn')) {
|
|
||||||
this.filteredDeviceRows.forEach(item => {
|
|
||||||
item.menuOpen = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,350 +0,0 @@
|
||||||
: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: #37A647;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
margin-top: -1px;
|
|
||||||
overflow: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-header {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
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
|
|
||||||
.ngx-datatable
|
|
||||||
.datatable-footer
|
|
||||||
.selected-count
|
|
||||||
.datatable-pager {
|
|
||||||
flex: 0 0 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable {
|
|
||||||
display: -webkit-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container {
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
height: 40px !important;
|
|
||||||
border-radius: 12px !important;
|
|
||||||
box-shadow: 0 2px 4px rgba(36, 34, 34, 0.2) !important; /* Bayangan lebih tipis */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input {
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row {
|
|
||||||
background-color: #FBFBFB; /* Black color for table rows */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row:hover {
|
|
||||||
background-color: #DDE1E6; /* Darker black for hover effect */
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-data{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.style-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
|
@ -1,516 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #FBFBFB !important">
|
|
||||||
<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">
|
|
||||||
<section id="configuration">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-4 col-12">
|
|
||||||
<div class="card" style="background-color: #DDE1E6 !important; box-shadow: none !important;">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="media d-flex">
|
|
||||||
<div class="media-body text-left">
|
|
||||||
<h6 class="text-custom-label">
|
|
||||||
Total Device
|
|
||||||
</h6>
|
|
||||||
<h3 class="text-custom-data">
|
|
||||||
{{ summaryTotal?.length }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="align-self-center">
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
background-color: #37A647;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="ri-device-line primary font-large-1 float-right"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-12">
|
|
||||||
<div class="card" style="background-color: #DDE1E6 !important; box-shadow: none !important;">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="media d-flex">
|
|
||||||
<div class="media-body text-left">
|
|
||||||
<h6 class="text-custom-label">
|
|
||||||
Total Device Active
|
|
||||||
</h6>
|
|
||||||
<h3 class="text-custom-data">{{ totalOn }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="align-self-center">
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
background-color: #37A647;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="feather ft-wifi primary font-large-1 float-right"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4 col-12">
|
|
||||||
<div class="card" style="background-color: #DDE1E6 !important; box-shadow: none !important;">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="media d-flex">
|
|
||||||
<div class="media-body text-left">
|
|
||||||
<h6 class="text-custom-label">
|
|
||||||
Total Device Non-Active
|
|
||||||
</h6>
|
|
||||||
<h3 class="text-custom-data">{{ totalOff }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="align-self-center">
|
|
||||||
<div
|
|
||||||
style="
|
|
||||||
background-color: #37A647;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="feather ft-wifi-off primary font-large-1 float-right"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="configuration">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="card" style="background-color: #FBFBFB !important; box-shadow: none;">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="col-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<ng-select
|
|
||||||
class="select-custom"
|
|
||||||
[items]="dataBuildingList"
|
|
||||||
[searchable]="true"
|
|
||||||
[disabled]="newDeviceActive"
|
|
||||||
bindLabel="name"
|
|
||||||
bindValue="id"
|
|
||||||
placeholder="Select Building"
|
|
||||||
[(ngModel)]="buildingSelected"
|
|
||||||
>
|
|
||||||
</ng-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<ng-select
|
|
||||||
class="select-custom"
|
|
||||||
[items]="dataMasterCategori"
|
|
||||||
[searchable]="true"
|
|
||||||
[disabled]="newDeviceActive"
|
|
||||||
bindLabel="name"
|
|
||||||
bindValue="id"
|
|
||||||
placeholder="Select Category"
|
|
||||||
[(ngModel)]="categorySelected"
|
|
||||||
>
|
|
||||||
</ng-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3">
|
|
||||||
<div class="form-group">
|
|
||||||
<ng-select
|
|
||||||
class="select-custom"
|
|
||||||
[items]="dataMasterStatus"
|
|
||||||
[searchable]="true"
|
|
||||||
[disabled]="newDeviceActive"
|
|
||||||
bindLabel="name"
|
|
||||||
bindValue="id"
|
|
||||||
placeholder="Select Status"
|
|
||||||
[(ngModel)]="statusSelected"
|
|
||||||
>
|
|
||||||
</ng-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 text-left">
|
|
||||||
<div class="d-flex">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn ml-2"
|
|
||||||
(click)="doFilter()"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
border-radius: 12px;
|
|
||||||
color: #ffffff;
|
|
||||||
"
|
|
||||||
[disabled]="spinnerFilterActive || newDeviceActive"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-search"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
*ngIf="!spinnerFilterActive"
|
|
||||||
></i>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
style="color: #ffffff !important"
|
|
||||||
*ngIf="spinnerFilterActive"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn ml-2"
|
|
||||||
(click)="doCancelFilter()"
|
|
||||||
style="
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
border-color: #242222 !important;
|
|
||||||
color: #242222;
|
|
||||||
border-radius: 12px;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="col-6 col-md-3 mb-2">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary btn-block"
|
|
||||||
[disabled]="spinnerActive"
|
|
||||||
(click)="addDevice()"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
*ngIf="spinnerActive"
|
|
||||||
></i>
|
|
||||||
<i class="feather ft-plus" *ngIf="!spinnerActive"></i>
|
|
||||||
|
|
||||||
<span style="font-weight: 600">Synchronization</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-md-3 mb-2">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary btn-block"
|
|
||||||
[disabled]="spinnerExportActive"
|
|
||||||
(click)="exportDevice()"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
*ngIf="spinnerExportActive"
|
|
||||||
></i>
|
|
||||||
<i
|
|
||||||
class="ri-export-fill"
|
|
||||||
*ngIf="!spinnerExportActive"
|
|
||||||
></i>
|
|
||||||
|
|
||||||
<span style="font-weight: 600">Export</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-6 col-md-3 mb-2">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary btn-block"
|
|
||||||
*ngIf="!newDeviceActive"
|
|
||||||
[disabled]="spinnerNewDeviceActive"
|
|
||||||
(click)="newDevice()"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
*ngIf="spinnerNewDeviceActive"
|
|
||||||
></i>
|
|
||||||
<i
|
|
||||||
class="ri-sticky-note-add-fill"
|
|
||||||
*ngIf="!spinnerNewDeviceActive"
|
|
||||||
></i>
|
|
||||||
|
|
||||||
<span style="font-weight: 600">New Device</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary btn-block"
|
|
||||||
*ngIf="newDeviceActive"
|
|
||||||
[disabled]="spinnerNewDeviceActive"
|
|
||||||
(click)="allDevice()"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="la la-spinner spinner"
|
|
||||||
*ngIf="spinnerNewDeviceActive"
|
|
||||||
></i>
|
|
||||||
<i
|
|
||||||
class="ri-arrow-left-circle-line"
|
|
||||||
*ngIf="!spinnerNewDeviceActive"
|
|
||||||
></i>
|
|
||||||
|
|
||||||
<span style="font-weight: 600">All Device</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-dashboard">
|
|
||||||
<ngx-datatable
|
|
||||||
class="bootstrap table-bordered"
|
|
||||||
[limit]="5"
|
|
||||||
[rows]="data_device"
|
|
||||||
[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="icon"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="20"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Image</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template ngx-datatable-cell-template let-row="row">
|
|
||||||
<span class="avatar avatar-sm rounded-circle">
|
|
||||||
<img [src]="row.icon" /><i></i
|
|
||||||
></span>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="Name"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="150"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label"
|
|
||||||
>Device Name</span
|
|
||||||
>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
let-value="value"
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="buildingName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label"
|
|
||||||
>Building</span
|
|
||||||
>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
let-value="value"
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="categoryName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label"
|
|
||||||
>Category</span
|
|
||||||
>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{ value }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="watt"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Watt</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="typeName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Type</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{ value }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="voltageName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Voltage</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">
|
|
||||||
{{ value }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<!-- <ngx-datatable-column
|
|
||||||
name="statusName"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span style="color: #ffffff !important">Status</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p style="color: #ffffff !important">
|
|
||||||
{{ value }}
|
|
||||||
</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column> -->
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="Actions"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="150"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Actions</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-rowIndex="rowIndex"
|
|
||||||
let-row="row"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-info mr-1"
|
|
||||||
style="
|
|
||||||
background-color: #DDE1E6 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
"
|
|
||||||
(click)="viewRow(row)"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="ficon feather ft-eye"
|
|
||||||
style="color: #37A647 !important"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-warning mr-1"
|
|
||||||
style="
|
|
||||||
background-color: #DDE1E6 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
"
|
|
||||||
(click)="editRow(row)"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="ficon feather ft-edit"
|
|
||||||
style="color: #37A647 !important"
|
|
||||||
></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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { DeviceComponent } from './device.component';
|
|
||||||
|
|
||||||
describe('DeviceComponent', () => {
|
|
||||||
let component: DeviceComponent;
|
|
||||||
let fixture: ComponentFixture<DeviceComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ DeviceComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(DeviceComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,303 +0,0 @@
|
||||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
|
||||||
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { TableApiService } from "src/app/_services/table-api.service";
|
|
||||||
import { ModalAddEditComponent } from "./modal-add-edit/modal-add-edit.component";
|
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
|
||||||
import { BuildingService } from "../service/monitoring-api.service";
|
|
||||||
import { DeviceService } from "../service/device.service";
|
|
||||||
import { ToastrService } from "ngx-toastr";
|
|
||||||
import * as FileSaver from "file-saver";
|
|
||||||
import * as XLSX from "xlsx";
|
|
||||||
import { TableexcelService } from "src/app/_services/tableexcel.service";
|
|
||||||
import { LoginService } from "../service/login.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-device",
|
|
||||||
templateUrl: "./device.component.html",
|
|
||||||
styleUrls: ["./device.component.css"],
|
|
||||||
})
|
|
||||||
export class DeviceComponent implements OnInit {
|
|
||||||
data: any;
|
|
||||||
totalOn: any;
|
|
||||||
totalOff: any;
|
|
||||||
filteredRows: any[];
|
|
||||||
summaryTotal: any[];
|
|
||||||
searchTerm: string = "";
|
|
||||||
buildingSelected: any;
|
|
||||||
statusSelected: any;
|
|
||||||
categorySelected: any;
|
|
||||||
dataMasterCategori: any;
|
|
||||||
dataBuildingList: any;
|
|
||||||
dataMasterStatus: any;
|
|
||||||
data_device: any;
|
|
||||||
spinnerFilterActive = false;
|
|
||||||
storedData: any;
|
|
||||||
|
|
||||||
rows: any = [];
|
|
||||||
public breadcrumb: any;
|
|
||||||
spinnerActive: boolean = false;
|
|
||||||
spinnerExportActive: boolean = false;
|
|
||||||
spinnerNewDeviceActive: boolean = false;
|
|
||||||
newDeviceActive: boolean = false;
|
|
||||||
|
|
||||||
singlebasicSelected: any;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private router: Router,
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private deviceService: DeviceService,
|
|
||||||
private toastr: ToastrService,
|
|
||||||
private tableexcelService: TableexcelService,
|
|
||||||
private authService: LoginService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Device",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
link: "/dashboard/sales",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
this.storedData = JSON.parse(localStorage.getItem("currentUser"));
|
|
||||||
this.buildingSelected = this.storedData.buildingId;
|
|
||||||
|
|
||||||
if (this.newDeviceActive === true) {
|
|
||||||
}
|
|
||||||
this.fetchData(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.categorySelected,
|
|
||||||
this.statusSelected
|
|
||||||
);
|
|
||||||
this.summaryDevice(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.categorySelected,
|
|
||||||
this.statusSelected
|
|
||||||
);
|
|
||||||
this.dataListMaster();
|
|
||||||
this.dataListBuilding();
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchData(buildingSelected, categorySelected, statusSelected) {
|
|
||||||
this.newDeviceActive = false;
|
|
||||||
this.buildingSelected = buildingSelected;
|
|
||||||
this.deviceService
|
|
||||||
.getDeviceData(buildingSelected, categorySelected, statusSelected)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.data = res;
|
|
||||||
this.filteredRows = this.data.results.data;
|
|
||||||
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,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
summaryDevice(buildingSelected, categorySelected, statusSelected) {
|
|
||||||
this.deviceService
|
|
||||||
.getDeviceData(buildingSelected, categorySelected, statusSelected)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.summaryTotal = res.results.data;
|
|
||||||
this.totalOn = res.results.data.filter(
|
|
||||||
(row) => row.status_id === 2
|
|
||||||
).length;
|
|
||||||
this.totalOff = res.results.data.filter(
|
|
||||||
(row) => row.status_id === 3
|
|
||||||
).length;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
newDevice() {
|
|
||||||
this.spinnerNewDeviceActive = true;
|
|
||||||
this.newDeviceActive = true;
|
|
||||||
this.deviceService.getDeviceData(0, 0, 0).subscribe((res) => {
|
|
||||||
this.data = res;
|
|
||||||
this.filteredRows = this.data.results.data;
|
|
||||||
this.spinnerNewDeviceActive = false;
|
|
||||||
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,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
allDevice() {
|
|
||||||
this.fetchData(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.categorySelected,
|
|
||||||
this.statusSelected
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.statusName.toLowerCase() === "aktif"
|
|
||||||
);
|
|
||||||
this.dataMasterStatus = dataStatus.filter((item) => item.statusName.toLowerCase() === "aktif");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListBuilding() {
|
|
||||||
this.monitoringApiService.getBuildingList().subscribe((data) => {
|
|
||||||
this.dataBuildingList = data.data.filter((item) => item.statusName.toLowerCase() === "aktif");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
doFilter() {
|
|
||||||
if (!this.buildingSelected) {
|
|
||||||
this.toastr.error("Warning", "Filter Building tidak boleh kosong.", {
|
|
||||||
timeOut: 5000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.spinnerFilterActive = true;
|
|
||||||
this.fetchData(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.categorySelected,
|
|
||||||
this.statusSelected
|
|
||||||
);
|
|
||||||
setTimeout(() => {
|
|
||||||
this.spinnerFilterActive = false;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doCancelFilter() {
|
|
||||||
this.storedData = JSON.parse(localStorage.getItem("currentUser"));
|
|
||||||
this.buildingSelected = this.storedData.buildingId;
|
|
||||||
this.categorySelected = undefined;
|
|
||||||
this.statusSelected = undefined;
|
|
||||||
this.fetchData(this.buildingSelected, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
|
||||||
const modalRef = this.modalService.open(ModalAddEditComponent, {
|
|
||||||
size: "lg",
|
|
||||||
});
|
|
||||||
modalRef.componentInstance.newAttribute = {
|
|
||||||
id: null,
|
|
||||||
name: "",
|
|
||||||
position: "",
|
|
||||||
office: "",
|
|
||||||
age: "",
|
|
||||||
salary: "",
|
|
||||||
startdate: "",
|
|
||||||
};
|
|
||||||
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
this.rows.push(result);
|
|
||||||
this.rows = [...this.rows];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewRow(row) {
|
|
||||||
this.router.navigate(["/device/view", row.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
editRow(row) {
|
|
||||||
this.router.navigate(["/device/edit", row.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteRow(row) {
|
|
||||||
console.log("Delete row:", row);
|
|
||||||
}
|
|
||||||
|
|
||||||
addDevice(): void {
|
|
||||||
// Aktifkan spinner
|
|
||||||
this.spinnerActive = true;
|
|
||||||
this.deviceService.getSyncDeviceData().subscribe((res) => {
|
|
||||||
console.log(res);
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.spinnerActive = false;
|
|
||||||
this.toastr.success("Success", "Sync Completed.", {
|
|
||||||
timeOut: 2000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
this.fetchData(
|
|
||||||
this.buildingSelected,
|
|
||||||
this.categorySelected,
|
|
||||||
this.statusSelected
|
|
||||||
);
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
exportDevice() {
|
|
||||||
this.spinnerExportActive = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
const columnsToExport = [
|
|
||||||
"name",
|
|
||||||
"building_name",
|
|
||||||
"room_name",
|
|
||||||
"watt",
|
|
||||||
"category_name",
|
|
||||||
"status_name",
|
|
||||||
"type_name",
|
|
||||||
"voltage_name",
|
|
||||||
];
|
|
||||||
this.tableexcelService.exportAsExcelFileDevice(
|
|
||||||
this.filteredRows,
|
|
||||||
"Smart_building_list_device",
|
|
||||||
columnsToExport
|
|
||||||
);
|
|
||||||
this.spinnerExportActive = false;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { DeviceComponent } from './device.component';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
|
||||||
|
|
||||||
import { NgSelectModule } from '@ng-select/ng-select';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { ClipboardModule } from 'ngx-clipboard';
|
|
||||||
import { CardModule } from '../../partials/general/card/card.module';
|
|
||||||
import { BreadcrumbModule } from 'src/app/_layout/breadcrumb/breadcrumb.module';
|
|
||||||
import { BlockUIModule } from 'ng-block-ui';
|
|
||||||
import { BlockTemplateComponent } from '../../../_layout/blockui/block-template.component';
|
|
||||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
|
||||||
import { AddEditDeviceComponent } from './add-edit-device/add-edit-device.component';
|
|
||||||
import { ModalAddEditComponent } from './modal-add-edit/modal-add-edit.component';
|
|
||||||
import { DeviceControlComponent } from './device-control/device-control.component';
|
|
||||||
import { UiSwitchModule } from 'ngx-ui-switch';
|
|
||||||
import { ControlSchedulerComponent } from './control-scheduler/control-scheduler.component';
|
|
||||||
import { SchedulerListComponent } from './scheduler-list/scheduler-list.component';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
DeviceComponent,
|
|
||||||
AddEditDeviceComponent,
|
|
||||||
ModalAddEditComponent,
|
|
||||||
DeviceControlComponent,
|
|
||||||
ControlSchedulerComponent,
|
|
||||||
SchedulerListComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
CardModule,
|
|
||||||
BreadcrumbModule,
|
|
||||||
NgSelectModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
ClipboardModule,
|
|
||||||
PerfectScrollbarModule,
|
|
||||||
UiSwitchModule,
|
|
||||||
NgxDatatableModule,
|
|
||||||
BlockUIModule.forRoot({
|
|
||||||
template: BlockTemplateComponent
|
|
||||||
}),
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: DeviceComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'control-device',
|
|
||||||
component: DeviceControlComponent,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'add-row',
|
|
||||||
component: AddEditDeviceComponent,
|
|
||||||
data: { mode: 'add' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'edit/:id',
|
|
||||||
component: AddEditDeviceComponent,
|
|
||||||
data: { mode: 'edit' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'view/:id',
|
|
||||||
component: AddEditDeviceComponent,
|
|
||||||
data: { mode: 'view' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'scheduler/:id',
|
|
||||||
component: SchedulerListComponent,
|
|
||||||
data: { mode: 'scheduler' }
|
|
||||||
}
|
|
||||||
]),
|
|
||||||
|
|
||||||
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class DeviceModule { }
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* 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;
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
<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-row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="name">Name:</label>
|
|
||||||
<input type="text" class="form-control" id="name" formControlName="name">
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="position">Position:</label>
|
|
||||||
<input type="text" class="form-control" id="position" formControlName="position">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="age">Age:</label>
|
|
||||||
<input type="number" class="form-control" id="age" formControlName="age">
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="department">Department:</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<select class="form-control" formControlName="department">
|
|
||||||
<option>IT</option>
|
|
||||||
<option>HR</option>
|
|
||||||
<option>Finance</option>
|
|
||||||
</select>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" type="button" (click)="addDepartment()">+</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ModalAddEditComponent } from './modal-add-edit.component';
|
|
||||||
|
|
||||||
describe('ModalAddEditComponent', () => {
|
|
||||||
let component: ModalAddEditComponent;
|
|
||||||
let fixture: ComponentFixture<ModalAddEditComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ModalAddEditComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ModalAddEditComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,41 +0,0 @@
|
||||||
import { Component, Input } from "@angular/core";
|
|
||||||
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-modal-add-edit",
|
|
||||||
templateUrl: "./modal-add-edit.component.html",
|
|
||||||
styleUrls: ["./modal-add-edit.component.css"],
|
|
||||||
})
|
|
||||||
export class ModalAddEditComponent {
|
|
||||||
@Input() newAttribute: any = {};
|
|
||||||
myForm: FormGroup;
|
|
||||||
|
|
||||||
constructor(public activeModal: NgbActiveModal, private fb: FormBuilder) {
|
|
||||||
this.createForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
createForm() {
|
|
||||||
this.myForm = this.fb.group({
|
|
||||||
name: ['', Validators.required],
|
|
||||||
position: ['', Validators.required],
|
|
||||||
age: [null, [Validators.required, Validators.min(18)]],
|
|
||||||
department: ['', Validators.required]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addRow() {
|
|
||||||
if (this.myForm.valid) {
|
|
||||||
this.activeModal.close(this.myForm.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addDepartment() {
|
|
||||||
// Example function to simulate adding a department
|
|
||||||
let newDept = prompt("Enter new department name:");
|
|
||||||
if (newDept) {
|
|
||||||
// Normally you would add to a database or a service
|
|
||||||
alert(`Department ${newDept} added! (simulated)`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
.app-content {
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
border-radius: 15px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
padding: 1.5rem;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-body {
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item {
|
|
||||||
background-color: #f7f8fa;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item h5 {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item .btn-outline-secondary,
|
|
||||||
.list-group-item .btn-outline-danger {
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 0.25rem 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-light {
|
|
||||||
background-color: #e8eaf6;
|
|
||||||
color: #3f51b5;
|
|
||||||
border: none;
|
|
||||||
border-radius: 20px;
|
|
||||||
padding: 0.5rem 1.25rem;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-light:hover {
|
|
||||||
background-color: #d1d9ff;
|
|
||||||
color: #303f9f;
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #fbfbfb !important">
|
|
||||||
<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">
|
|
||||||
<section id="basic-form-layouts">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-6" *blockUI="'projectInfo'; message: 'Loading'">
|
|
||||||
<div class="card" style="background-color: #fbfbfb !important">
|
|
||||||
<div class="card-content">
|
|
||||||
<div
|
|
||||||
class="card-header d-flex justify-content-between align-items-center"
|
|
||||||
style="background-color: #fbfbfb !important"
|
|
||||||
>
|
|
||||||
<h4 class="form-section m-0" style="color: #242222">
|
|
||||||
<i class="feather ft-calendar" style="color: #242222"></i>
|
|
||||||
{{ deviceName ? deviceName : '' }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="btn"
|
|
||||||
style="
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
(click)="addSchedulerItem()"
|
|
||||||
>
|
|
||||||
<span style="font-weight: 600">Add Schedule</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="form-body">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div *ngIf="schedules.length > 0; else noSchedules">
|
|
||||||
<ul class="list-group">
|
|
||||||
<li
|
|
||||||
class="list-group-item d-flex justify-content-between align-items-center mb-3"
|
|
||||||
*ngFor="let schedule of listScheduler"
|
|
||||||
>
|
|
||||||
<!-- Tambahkan checkbox di sini -->
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="mr-2">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
[(ngModel)]="schedule.selected"
|
|
||||||
(change)="checkSelected()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div (click)="editSchedule(schedule)">
|
|
||||||
<h5 style="color: #242222">
|
|
||||||
{{ schedule.name }} ({{
|
|
||||||
schedule.switch ? "On" : "Off"
|
|
||||||
}})
|
|
||||||
</h5>
|
|
||||||
<h2 class="mb-0" style="color: #242222">
|
|
||||||
{{ schedule.timeset }}
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ui-switch
|
|
||||||
style="border-color: #bef264 !important"
|
|
||||||
class="switchery"
|
|
||||||
switchColor="white"
|
|
||||||
color="rgb(55, 166, 71)"
|
|
||||||
size="small"
|
|
||||||
[checked]="schedule.active"
|
|
||||||
(change)="switchChanged($event, schedule)"
|
|
||||||
></ui-switch>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Tambahkan tombol delete di sini -->
|
|
||||||
<div class="d-flex justify-content-center">
|
|
||||||
<button
|
|
||||||
*ngIf="hasSelected"
|
|
||||||
class="btn btn-danger mt-2"
|
|
||||||
(click)="deleteSelectedSchedules()"
|
|
||||||
style="
|
|
||||||
background-color: transparent !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="ficon la la-trash"
|
|
||||||
style="color: #37a647 !important"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ng-template #noSchedules>
|
|
||||||
<div class="alert alert-info text-center">
|
|
||||||
<strong>No schedules available.</strong> Click the
|
|
||||||
"Add Schedule" button to create one.
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { SchedulerListComponent } from './scheduler-list.component';
|
|
||||||
|
|
||||||
describe('SchedulerListComponent', () => {
|
|
||||||
let component: SchedulerListComponent;
|
|
||||||
let fixture: ComponentFixture<SchedulerListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ SchedulerListComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(SchedulerListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,192 +0,0 @@
|
||||||
import { Component } from "@angular/core";
|
|
||||||
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { ControlSchedulerComponent } from "../control-scheduler/control-scheduler.component";
|
|
||||||
import { ActivatedRoute } from "@angular/router";
|
|
||||||
import { DeviceService } from "../../service/device.service";
|
|
||||||
import Swal from "sweetalert2";
|
|
||||||
@Component({
|
|
||||||
selector: "app-scheduler-list",
|
|
||||||
templateUrl: "./scheduler-list.component.html",
|
|
||||||
styleUrls: ["./scheduler-list.component.css"],
|
|
||||||
})
|
|
||||||
export class SchedulerListComponent {
|
|
||||||
public breadcrumb: any;
|
|
||||||
listScheduler: any;
|
|
||||||
deviceId: any;
|
|
||||||
deviceName: any;
|
|
||||||
hasSelected: boolean = false;
|
|
||||||
schedules = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: "Lampu Depan ON",
|
|
||||||
time: "08:55",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: "Lampu Depan OFF",
|
|
||||||
time: "09:50",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private deviceService: DeviceService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.route.params.subscribe((params) => {
|
|
||||||
const id = params["id"];
|
|
||||||
this.deviceId = id;
|
|
||||||
if (id) {
|
|
||||||
this.dataListScheduler(id);
|
|
||||||
this.dataDevice(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "Scheduler List",
|
|
||||||
linkBack: "/device/control-device",
|
|
||||||
isLinkBack: true,
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
link: "/dashboard/sales",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Control Device",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Scheduler List",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListScheduler(id) {
|
|
||||||
this.deviceService.getDeviceScheduler(id).subscribe((data) => {
|
|
||||||
this.listScheduler = data.results;
|
|
||||||
console.log(this.listScheduler);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataDevice(id) {
|
|
||||||
this.deviceService.getDeviceByid(id).subscribe((data) => {
|
|
||||||
this.deviceName = data.data.name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
switchChanged(e, item) {
|
|
||||||
const data = {
|
|
||||||
id: item.id,
|
|
||||||
active: e,
|
|
||||||
};
|
|
||||||
this.deviceService.putDeviceSchedulerActive(data, item.id).subscribe((res) => {
|
|
||||||
this.dataListScheduler(this.deviceId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addSchedulerItem() {
|
|
||||||
const modalRef = this.modalService.open(ControlSchedulerComponent, {
|
|
||||||
size: "md",
|
|
||||||
backdrop: "static",
|
|
||||||
keyboard: false,
|
|
||||||
centered: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
modalRef.componentInstance.deviceId = this.deviceId;
|
|
||||||
modalRef.componentInstance.mode = "add";
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
this.deviceService.postDeviceScheduler(result).subscribe((res) => {
|
|
||||||
this.dataListScheduler(this.deviceId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Handle edit action
|
|
||||||
}
|
|
||||||
|
|
||||||
editSchedule(data) {
|
|
||||||
const modalRef = this.modalService.open(ControlSchedulerComponent, {
|
|
||||||
size: "md",
|
|
||||||
backdrop: "static",
|
|
||||||
keyboard: false,
|
|
||||||
centered: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
modalRef.componentInstance.deviceId = this.deviceId;
|
|
||||||
modalRef.componentInstance.data = data;
|
|
||||||
modalRef.componentInstance.mode = "edit";
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
this.deviceService
|
|
||||||
.putDeviceScheduler(result, data.id)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.dataListScheduler(this.deviceId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkSelected() {
|
|
||||||
this.hasSelected = this.listScheduler.some((schedule) => schedule.selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteSelectedSchedules() {
|
|
||||||
const selectedSchedules = this.listScheduler.filter(
|
|
||||||
(schedule) => schedule.selected
|
|
||||||
);
|
|
||||||
|
|
||||||
if (selectedSchedules.length > 0) {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Apakah kamu yakin ingin menghapus jadwal yang dipilih?",
|
|
||||||
text: "Tindakan ini tidak dapat dibatalkan.",
|
|
||||||
icon: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: "#37a647",
|
|
||||||
cancelButtonColor: "#d33",
|
|
||||||
confirmButtonText: "Ya, hapus!",
|
|
||||||
cancelButtonText: "Batal",
|
|
||||||
allowOutsideClick: false,
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
selectedSchedules.forEach((schedule) => {
|
|
||||||
this.deleteSchedule(schedule.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
Swal.fire({
|
|
||||||
title: "Terhapus!",
|
|
||||||
text: "Jadwal yang dipilih berhasil dihapus.",
|
|
||||||
icon: "success",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Tidak ada jadwal yang dipilih!",
|
|
||||||
text: "Pilih setidaknya satu jadwal untuk dihapus.",
|
|
||||||
icon: "info",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteSchedule(id) {
|
|
||||||
this.deviceService.deleteDeviceScheduler(id).subscribe(() => {
|
|
||||||
this.dataListScheduler(this.deviceId);
|
|
||||||
this.hasSelected = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,280 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #fbfbfb !important">
|
|
||||||
<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">
|
|
||||||
<section id="basic-form-layouts">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12" *blockUI="'projectInfo'; message: 'Loading'">
|
|
||||||
<div class="card" style="background-color: #fbfbfb !important">
|
|
||||||
<div class="card-content">
|
|
||||||
<div
|
|
||||||
class="card-header"
|
|
||||||
style="background-color: #fbfbfb !important"
|
|
||||||
>
|
|
||||||
<h2 style="color: #242222">
|
|
||||||
{{
|
|
||||||
isEditMode()
|
|
||||||
? "Edit List Monitoring"
|
|
||||||
: isViewMode()
|
|
||||||
? "View List Monitoring"
|
|
||||||
: "Add New List Monitoring"
|
|
||||||
}}
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<form
|
|
||||||
[formGroup]="projectInfo"
|
|
||||||
(ngSubmit)="onProjectInfoSubmit()"
|
|
||||||
>
|
|
||||||
<div class="form-body">
|
|
||||||
<!-- <h4 class="form-section" style="color: #242222">
|
|
||||||
<i class="feather ft-user" style="color: #242222"></i>
|
|
||||||
General Information
|
|
||||||
</h4> -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="buildingId" style="color: #242222"
|
|
||||||
>Building *</label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
id="buildingId"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="buildingId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.buildingId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataBuildingList"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<button
|
|
||||||
class="btn btn-danger ml-2"
|
|
||||||
type="button"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
(click)="modalAddBuilding()"
|
|
||||||
>
|
|
||||||
<i class="feather ft-plus"> New Building</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="projectInfo.get('buildingId').touched && projectInfo.get('buildingId').invalid" class="text-danger">
|
|
||||||
Building is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="floorId" style="color: #242222"
|
|
||||||
>Floor *</label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
id="floorId"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="floorId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.floorId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataFloorList"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<button
|
|
||||||
class="btn btn-danger ml-2"
|
|
||||||
type="button"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
(click)="modalAddFloor()"
|
|
||||||
>
|
|
||||||
<i class="feather ft-plus"> New Floor</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="projectInfo.get('floorId').touched && projectInfo.get('floorId').invalid" class="text-danger">
|
|
||||||
Floor is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="form-group" *ngIf="mode === 'add'">
|
|
||||||
<div class="" formArrayName="userArray">
|
|
||||||
<div
|
|
||||||
class=""
|
|
||||||
*ngFor="
|
|
||||||
let userForm of userFormGroup.controls;
|
|
||||||
let i = index
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div [formGroupName]="i" class="">
|
|
||||||
<div class="input-group mb-1">
|
|
||||||
<select
|
|
||||||
id="roomId{{i}}"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="roomId"
|
|
||||||
(change)="validateDouble($event, i)"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid':
|
|
||||||
submitted && f.roomId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let list of dataRoomList; trackBy: trackByFn"
|
|
||||||
[value]="list.id"
|
|
||||||
>
|
|
||||||
{{ list.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<button
|
|
||||||
class="btn btn-danger"
|
|
||||||
type="button"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #a64f37 !important;
|
|
||||||
background-color: #a64f37 !important;
|
|
||||||
"
|
|
||||||
(click)="removePhone(i)"
|
|
||||||
>
|
|
||||||
<i class="feather ft-x"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-primary"
|
|
||||||
[disabled]="disableButton"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
(click)="addPhone()"
|
|
||||||
>
|
|
||||||
<i class="feather ft-plus"></i> Add Room
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-primary ml-2"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
(click)="modalAddNewRoom()"
|
|
||||||
>
|
|
||||||
New Room
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="form-group" *ngIf="mode !== 'add'">
|
|
||||||
<label for="roomId">Room *</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
id="roomId"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="roomId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.roomId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataRoomList"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<small
|
|
||||||
class="form-text text-muted danger"
|
|
||||||
*ngIf="submitted && f.roomId.errors"
|
|
||||||
class="invalid-feedback"
|
|
||||||
>
|
|
||||||
<div *ngIf="f.roomId.errors.required">
|
|
||||||
Status is required
|
|
||||||
</div>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="statusId" style="color: #242222"
|
|
||||||
>Status *</label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<select
|
|
||||||
id="statusId"
|
|
||||||
class="form-control"
|
|
||||||
formControlName="statusId"
|
|
||||||
[ngClass]="{
|
|
||||||
'is-invalid': submitted && f.statusId.errors
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
*ngFor="let data of dataMasterStatus"
|
|
||||||
[value]="data.id"
|
|
||||||
>
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="projectInfo.get('statusId').touched && projectInfo.get('statusId').invalid" class="text-danger">
|
|
||||||
Status is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-actions">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-warning mr-1"
|
|
||||||
style="
|
|
||||||
color: #242222 !important;
|
|
||||||
border-color: #242222 !important;
|
|
||||||
background-color: #fbfbfb !important;
|
|
||||||
"
|
|
||||||
(click)="cancel()"
|
|
||||||
>
|
|
||||||
<i class="feather ft-x"></i> Cancel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary"
|
|
||||||
[disabled]="disableButtonSave"
|
|
||||||
style="
|
|
||||||
color: #ffffff !important;
|
|
||||||
border-color: #37a647 !important;
|
|
||||||
background-color: #37a647 !important;
|
|
||||||
"
|
|
||||||
(click)="save()"
|
|
||||||
>
|
|
||||||
<i class="la la-check"></i> Save
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AddEditListComponent } from './add-edit-list.component';
|
|
||||||
|
|
||||||
describe('AddEditListComponent', () => {
|
|
||||||
let component: AddEditListComponent;
|
|
||||||
let fixture: ComponentFixture<AddEditListComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ AddEditListComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AddEditListComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,465 +0,0 @@
|
||||||
import { Component, ViewChild } from "@angular/core";
|
|
||||||
import {
|
|
||||||
FormArray,
|
|
||||||
FormBuilder,
|
|
||||||
FormGroup,
|
|
||||||
NgForm,
|
|
||||||
Validators,
|
|
||||||
} from "@angular/forms";
|
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
|
||||||
import { BlockUI, NgBlockUI } from "ng-block-ui";
|
|
||||||
import { BuildingService } from "../../service/monitoring-api.service";
|
|
||||||
import { LoginService } from "../../service/login.service";
|
|
||||||
import { ToastrService } from "ngx-toastr";
|
|
||||||
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { AddEditMasterBuildingComponent } from "../../master/master-building/add-edit-master-building/add-edit-master-building.component";
|
|
||||||
import { AddEditMasterComponent } from "../../master/add-edit-master/add-edit-master.component";
|
|
||||||
import { AddEditMasterRoomComponent } from "../../master/master-room/add-edit-master-room/add-edit-master-room.component";
|
|
||||||
import Swal from "sweetalert2";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-add-edit-list",
|
|
||||||
templateUrl: "./add-edit-list.component.html",
|
|
||||||
styleUrls: ["./add-edit-list.component.css"],
|
|
||||||
})
|
|
||||||
export class AddEditListComponent {
|
|
||||||
// @ViewChild("f", { read: true }) userProfileForm: NgForm;
|
|
||||||
|
|
||||||
model: any = {};
|
|
||||||
mode: string;
|
|
||||||
public breadcrumb: any;
|
|
||||||
projectInfo: FormGroup;
|
|
||||||
submitted = false;
|
|
||||||
|
|
||||||
dataBuildingList: any;
|
|
||||||
dataRoomList: any;
|
|
||||||
dataRoomListSementara: any;
|
|
||||||
dataFloorList: any;
|
|
||||||
dataMasterStatus: any;
|
|
||||||
roombuildingId: any;
|
|
||||||
dataRoomBuilding: any;
|
|
||||||
disableButton: boolean = true;
|
|
||||||
disableButtonSave: boolean = true;
|
|
||||||
lewatModal: boolean = false;
|
|
||||||
// userProfileForm: FormGroup;
|
|
||||||
public userList: FormArray;
|
|
||||||
|
|
||||||
@BlockUI("projectInfo") blockUIProjectInfo: NgBlockUI;
|
|
||||||
get userFormGroup() {
|
|
||||||
return this.projectInfo.get("userArray") as FormArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private formBuilder: FormBuilder,
|
|
||||||
private router: Router,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private authService: LoginService,
|
|
||||||
private toastr: ToastrService,
|
|
||||||
private modalService: NgbModal
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.route.data.subscribe((data) => {
|
|
||||||
this.mode = data.mode;
|
|
||||||
});
|
|
||||||
this.route.params.subscribe((params) => {
|
|
||||||
const id = params["id"];
|
|
||||||
this.roombuildingId = id;
|
|
||||||
if (id) {
|
|
||||||
this.loadRoomBuilding(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.setBreadcrumb();
|
|
||||||
|
|
||||||
|
|
||||||
this.projectInfo = this.formBuilder.group({
|
|
||||||
buildingId: ["", Validators.required],
|
|
||||||
roomId: [""],
|
|
||||||
statusId: ["", Validators.required],
|
|
||||||
floorId: ["", Validators.required],
|
|
||||||
userArray: this.formBuilder.array([this.createRoom()]),
|
|
||||||
});
|
|
||||||
this.userList = this.projectInfo.get("userArray") as FormArray;
|
|
||||||
|
|
||||||
this.dataListBuilding();
|
|
||||||
this.dataListRoom();
|
|
||||||
this.dataListMaster();
|
|
||||||
this.dataListFloor();
|
|
||||||
}
|
|
||||||
|
|
||||||
createRoom(): FormGroup {
|
|
||||||
return this.formBuilder.group({
|
|
||||||
roomId: ["", Validators.required],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addPhone() {
|
|
||||||
this.userList.push(this.createRoom());
|
|
||||||
this.disableButton = true;
|
|
||||||
this.disableButtonSave = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
removePhone(index) {
|
|
||||||
this.userList.removeAt(index);
|
|
||||||
this.isRoomDuplicate(index);
|
|
||||||
if (this.userList.value.length === 0) {
|
|
||||||
this.disableButtonSave = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
validateDouble(event: any, index: number) {
|
|
||||||
const selectedRoomId = (event.target as HTMLSelectElement).value;
|
|
||||||
if (this.isRoomDuplicate(index)) {
|
|
||||||
this.disableButton = true;
|
|
||||||
this.disableButtonSave = true;
|
|
||||||
this.toastr.error("Room", "Data yang ada masukan double!", {
|
|
||||||
timeOut: 2000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.disableButton = false;
|
|
||||||
this.disableButtonSave = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
isRoomDuplicate(index: number): boolean {
|
|
||||||
const selectedRooms = this.userFormGroup.value.map((room) => room.roomId);
|
|
||||||
const currentRoomId = selectedRooms[index];
|
|
||||||
const roomOccurrences = selectedRooms.filter(
|
|
||||||
(roomId) => roomId === currentRoomId
|
|
||||||
).length;
|
|
||||||
if (roomOccurrences === 0) {
|
|
||||||
this.disableButton = false;
|
|
||||||
this.disableButtonSave = false;
|
|
||||||
}
|
|
||||||
return roomOccurrences > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
setBreadcrumb() {
|
|
||||||
if (this.isAddMode()) {
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "List Monitoring",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "List Monitoring",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Add New List Monitoring",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
} else if (this.isEditMode()) {
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "List Monitoring",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "List Monitoring",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Edit New List Monitoring",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loadRoomBuilding(deviceId: string) {
|
|
||||||
this.monitoringApiService
|
|
||||||
.getRoomBuildingById(deviceId)
|
|
||||||
.subscribe((data) => {
|
|
||||||
this.dataRoomBuilding = data;
|
|
||||||
this.formGetDevice(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
formGetDevice(data) {
|
|
||||||
this.projectInfo.patchValue({
|
|
||||||
buildingId: data.data.buildingId,
|
|
||||||
roomId: data.data.roomId,
|
|
||||||
floorId: data.data.floorId,
|
|
||||||
statusId: data.data.statusId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.mode === "view") {
|
|
||||||
this.formDisable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formDisable() {
|
|
||||||
this.projectInfo.get("buildingId").disable();
|
|
||||||
this.projectInfo.get("roomId").disable();
|
|
||||||
this.projectInfo.get("statusId").disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
isEditMode() {
|
|
||||||
return this.mode === "edit";
|
|
||||||
}
|
|
||||||
|
|
||||||
isViewMode() {
|
|
||||||
return this.mode === "view";
|
|
||||||
}
|
|
||||||
|
|
||||||
isAddMode() {
|
|
||||||
return this.mode === "add";
|
|
||||||
}
|
|
||||||
|
|
||||||
get f() {
|
|
||||||
return this.projectInfo.controls;
|
|
||||||
}
|
|
||||||
|
|
||||||
onProjectInfoSubmit() {
|
|
||||||
this.submitted = true;
|
|
||||||
if (this.projectInfo.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keyPress(event: any) {
|
|
||||||
const pattern = /[0-9\+\-\ ]/;
|
|
||||||
const inputChar = String.fromCharCode(event.charCode);
|
|
||||||
if (event.keyCode !== 8 && !pattern.test(inputChar)) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListBuilding() {
|
|
||||||
this.monitoringApiService.getBuildingList().subscribe((data) => {
|
|
||||||
this.dataBuildingList = data.data
|
|
||||||
.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" || item.status_id === 71
|
|
||||||
)
|
|
||||||
.sort((a, b) => b.id - a.id);
|
|
||||||
|
|
||||||
if (this.lewatModal) {
|
|
||||||
this.projectInfo.patchValue({
|
|
||||||
buildingId: this.dataBuildingList[0],
|
|
||||||
});
|
|
||||||
this.lewatModal = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListRoom() {
|
|
||||||
this.monitoringApiService.getListRoomDataUnmap().subscribe((data) => {
|
|
||||||
const newArray = data.data.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
name: `${item.name} (${item.code})`,
|
|
||||||
})).sort((a, b) => b.id - a.id);
|
|
||||||
this.dataRoomList = newArray;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
trackByFn(index: number, option: any): any {
|
|
||||||
return option.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListFloor() {
|
|
||||||
this.monitoringApiService.getListFloorDataUnmap(6).subscribe((data) => {
|
|
||||||
const newArray = data.data.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
name: `${item.name} (${item.code})`,
|
|
||||||
status: item.status_name
|
|
||||||
})).sort((a, b) => b.id - a.id);
|
|
||||||
this.dataFloorList = newArray.filter((item) => item.status.toLowerCase() === "aktif");
|
|
||||||
if (this.lewatModal) {
|
|
||||||
this.projectInfo.patchValue({
|
|
||||||
floorId: this.dataFloorList[0],
|
|
||||||
});
|
|
||||||
this.lewatModal = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListMaster() {
|
|
||||||
this.monitoringApiService.getMasterListData().subscribe((data) => {
|
|
||||||
const dataStatus = data.data.find(
|
|
||||||
(item) => item.name === "master_status"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterStatus = dataStatus.filter(
|
|
||||||
(item) =>
|
|
||||||
item.statusName.toLowerCase() === "aktif" ||
|
|
||||||
item.status.toLowerCase() === "71"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
save() {
|
|
||||||
if (this.mode === "add") {
|
|
||||||
if (this.projectInfo.invalid) {
|
|
||||||
this.markFormGroupTouched(this.projectInfo)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const formData = this.projectInfo.value;
|
|
||||||
const transformedData = {
|
|
||||||
buildingId: formData.buildingId,
|
|
||||||
roomId: formData.userArray.map((room) => room.roomId),
|
|
||||||
statusId: formData.statusId,
|
|
||||||
floorId: formData.floorId,
|
|
||||||
};
|
|
||||||
this.monitoringApiService
|
|
||||||
.postBatchBuilding(transformedData)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.router.navigate(["/list-monitoring"]);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
delete this.projectInfo.value.userArray;
|
|
||||||
this.monitoringApiService
|
|
||||||
.putBuildingRoom(this.projectInfo.value, this.roombuildingId)
|
|
||||||
.subscribe((data) => {
|
|
||||||
this.router.navigate(["/list-monitoring"]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
markFormGroupTouched(formGroup: FormGroup) {
|
|
||||||
(Object as any).values(formGroup.controls).forEach((control) => {
|
|
||||||
control.markAsTouched();
|
|
||||||
if (control.controls) {
|
|
||||||
this.markFormGroupTouched(control);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
if (this.projectInfo.dirty) { // Check if form has unsaved changes
|
|
||||||
Swal.fire({
|
|
||||||
title: 'Are you sure?',
|
|
||||||
text: "You have unsaved changes. Do you really want to leave?",
|
|
||||||
icon: 'warning',
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: '#37a647',
|
|
||||||
cancelButtonColor: '#d33',
|
|
||||||
confirmButtonText: 'Yes, leave',
|
|
||||||
cancelButtonText: 'No, stay'
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
this.router.navigate(["/list-monitoring"]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.router.navigate(["/list-monitoring"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
modalAddBuilding() {
|
|
||||||
const modalRef = this.modalService.open(AddEditMasterBuildingComponent, {
|
|
||||||
size: "lg",
|
|
||||||
backdrop: "static",
|
|
||||||
keyboard: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
modalRef.componentInstance.mode = "add";
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
if (
|
|
||||||
this.dataBuildingList.some(
|
|
||||||
(value) =>
|
|
||||||
value.name.trim().toLowerCase() ===
|
|
||||||
result.name.trim().toLowerCase()
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
this.toastr.error("Warning", "Data yang anda masukan double.", {
|
|
||||||
timeOut: 5000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.monitoringApiService
|
|
||||||
.postMasterBuildingParam(result)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.dataListBuilding();
|
|
||||||
this.lewatModal = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
modalAddFloor() {
|
|
||||||
const modalRef = this.modalService.open(AddEditMasterComponent, {
|
|
||||||
size: "lg",
|
|
||||||
backdrop: "static",
|
|
||||||
keyboard: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
modalRef.componentInstance.headerId = 6;
|
|
||||||
modalRef.componentInstance.mode = "add";
|
|
||||||
modalRef.componentInstance.floor = true;
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
this.monitoringApiService
|
|
||||||
.postHeaderDetailParam(result)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.dataListFloor();
|
|
||||||
this.lewatModal = true;
|
|
||||||
if (res.status === 400) {
|
|
||||||
this.toastr.error("Warning", "Data yang anda masukan double.", {
|
|
||||||
timeOut: 5000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
modalAddNewRoom(){
|
|
||||||
const modalRef = this.modalService.open(AddEditMasterRoomComponent, {
|
|
||||||
size: "lg",
|
|
||||||
backdrop: "static",
|
|
||||||
keyboard: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
modalRef.componentInstance.mode = "add";
|
|
||||||
modalRef.result.then(
|
|
||||||
(result) => {
|
|
||||||
if (result) {
|
|
||||||
const filteredData = {
|
|
||||||
name: result.name,
|
|
||||||
code: result.code.trim(),
|
|
||||||
description: result.description,
|
|
||||||
};
|
|
||||||
this.monitoringApiService
|
|
||||||
.postMasterRoomParam(filteredData)
|
|
||||||
.subscribe((res) => {
|
|
||||||
this.dataListRoom();
|
|
||||||
}, (error) => {
|
|
||||||
this.toastr.error("Error", error.error.message, {
|
|
||||||
timeOut: 2000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
console.log(`Dismissed: ${reason}`);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,350 +0,0 @@
|
||||||
: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: #37A647;
|
|
||||||
font-weight: bold;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-footer {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
margin-top: -1px;
|
|
||||||
overflow: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-header {
|
|
||||||
background: #DDE1E6;
|
|
||||||
color: #242222;
|
|
||||||
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
|
|
||||||
.ngx-datatable
|
|
||||||
.datatable-footer
|
|
||||||
.selected-count
|
|
||||||
.datatable-pager {
|
|
||||||
flex: 0 0 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable {
|
|
||||||
display: -webkit-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container {
|
|
||||||
color: #242222 !important;
|
|
||||||
background-color: #FBFBFB !important;
|
|
||||||
height: 40px !important;
|
|
||||||
border-radius: 12px !important;
|
|
||||||
box-shadow: 0 2px 4px rgba(36, 34, 34, 0.2) !important; /* Bayangan lebih tipis */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ng-select .ng-select-container .ng-value-container .ng-input>input {
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row {
|
|
||||||
background-color: #FBFBFB; /* Black color for table rows */
|
|
||||||
}
|
|
||||||
|
|
||||||
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row:hover {
|
|
||||||
background-color: #DDE1E6; /* Darker black for hover effect */
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-custom-data{
|
|
||||||
color: #242222 !important;
|
|
||||||
font-family: "Open Sans", sans-serif !important;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.style-custom-label{
|
|
||||||
color: #242222 !important;
|
|
||||||
}
|
|
|
@ -1,172 +0,0 @@
|
||||||
<div class="app-content content" style="background-color: #FBFBFB !important">
|
|
||||||
<div class="content-wrapper" style="height: 900px !important;">
|
|
||||||
<div class="content-header row mb-1">
|
|
||||||
<app-breadcrumb class="col-12" [breadcrumb]="breadcrumb"></app-breadcrumb>
|
|
||||||
</div>
|
|
||||||
<div class="content-body">
|
|
||||||
<section id="configuration">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="card" style="background-color: #FBFBFB !important">
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="row mb-2">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
placeholder="Search..."
|
|
||||||
[(ngModel)]="searchTerm"
|
|
||||||
(input)="filterRows()"
|
|
||||||
(touchstart)="onTouchStart($event)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 text-right">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary"
|
|
||||||
[routerLink]="['/list-monitoring/add-row']"
|
|
||||||
style="
|
|
||||||
background-color: #37A647 !important;
|
|
||||||
border-color: #37A647 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i class="feather ft-plus" style="color: #ffffff"></i
|
|
||||||
>
|
|
||||||
<span style="font-weight: 600">Add new data</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-dashboard">
|
|
||||||
<ngx-datatable
|
|
||||||
class="bootstrap table-bordered"
|
|
||||||
[limit]="10"
|
|
||||||
[rows]="filteredRows"
|
|
||||||
[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"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ rowIndex + 1 }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="buildingEntity"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Building</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
let-value="value"
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value.name }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="roomEntity"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Room</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value.name }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="floorEntity"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Floor</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value.name }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="statusEntity"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="90"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Status</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-value="value"
|
|
||||||
>
|
|
||||||
<p class="style-custom-label">{{ value.name }}</p>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<ngx-datatable-column
|
|
||||||
name="Actions"
|
|
||||||
[flexGrow]="1"
|
|
||||||
[minWidth]="150"
|
|
||||||
>
|
|
||||||
<ng-template ngx-datatable-header-template>
|
|
||||||
<span class="style-custom-label">Actions</span>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template
|
|
||||||
ngx-datatable-cell-template
|
|
||||||
let-rowIndex="rowIndex"
|
|
||||||
let-row="row"
|
|
||||||
>
|
|
||||||
<!-- <button
|
|
||||||
class="btn btn-sm btn-warning mr-1"
|
|
||||||
style="background-color: #FBFBFB !important; border-color: #37A647 !important;"
|
|
||||||
(click)="editRow(row)"
|
|
||||||
>
|
|
||||||
<i class="ficon feather ft-edit" style="color: #37A647 !important;"></i>
|
|
||||||
</button> -->
|
|
||||||
<button
|
|
||||||
class="btn btn-sm btn-danger"
|
|
||||||
style="
|
|
||||||
color: #37a647 !important;
|
|
||||||
border-color: #DDE1E6 !important;
|
|
||||||
background-color: #DDE1E6 !important;
|
|
||||||
"
|
|
||||||
(click)="deleteRow(row)"
|
|
||||||
>
|
|
||||||
<i class="ficon feather ft-trash-2" style="color: #37A647 !important;"></i>
|
|
||||||
</button>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
</ngx-datatable>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ListMonitoringComponent } from './list-monitoring.component';
|
|
||||||
|
|
||||||
describe('ListMonitoringComponent', () => {
|
|
||||||
let component: ListMonitoringComponent;
|
|
||||||
let fixture: ComponentFixture<ListMonitoringComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ListMonitoringComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ListMonitoringComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,108 +0,0 @@
|
||||||
import { Component } 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 Swal from "sweetalert2";
|
|
||||||
import { LoginService } from "../service/login.service";
|
|
||||||
import { ToastrService } from "ngx-toastr";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-list-monitoring",
|
|
||||||
templateUrl: "./list-monitoring.component.html",
|
|
||||||
styleUrls: ["./list-monitoring.component.css"],
|
|
||||||
})
|
|
||||||
export class ListMonitoringComponent {
|
|
||||||
public breadcrumb: any;
|
|
||||||
data: any;
|
|
||||||
filteredRows: any[];
|
|
||||||
searchTerm: string = "";
|
|
||||||
rows: any = [];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private authService: LoginService,
|
|
||||||
private toastr: ToastrService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.breadcrumb = {
|
|
||||||
mainlabel: "List Monitoring",
|
|
||||||
links: [
|
|
||||||
{
|
|
||||||
name: "Home",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "List Monitoring",
|
|
||||||
isLink: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
this.fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchData() {
|
|
||||||
this.monitoringApiService.getBuildingRoomList().subscribe((res) => {
|
|
||||||
this.data = res;
|
|
||||||
// this.filteredRows = this.data.results.data;
|
|
||||||
this.filteredRows = this.data.results.data.sort((a, b) => b.id - a.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
filterRows() {
|
|
||||||
if (!this.searchTerm) {
|
|
||||||
this.filteredRows = [...this.data.results.data];
|
|
||||||
} else {
|
|
||||||
const searchTermLC = this.searchTerm.toLowerCase();
|
|
||||||
this.filteredRows = this.data.results.data.filter((row) =>
|
|
||||||
this.rowContainsSearchTerm(row, searchTermLC)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rowContainsSearchTerm(row: any, searchTermLC: string): boolean {
|
|
||||||
return (
|
|
||||||
row.buildingEntity.name.toLowerCase().includes(searchTermLC) ||
|
|
||||||
row.roomEntity.name.toLowerCase().includes(searchTermLC) ||
|
|
||||||
row.statusEntity.name.toLowerCase().includes(searchTermLC) ||
|
|
||||||
row.floorEntity?.name.toLowerCase().includes(searchTermLC)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewRow(row) {
|
|
||||||
this.router.navigate(["/list-monitoring/view", row.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
editRow(row) {
|
|
||||||
this.router.navigate(["/list-monitoring/edit", row.id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteRow(row) {
|
|
||||||
const confirmDelete = confirm("Are you sure you want to delete this item?");
|
|
||||||
if (confirmDelete) {
|
|
||||||
this.monitoringApiService.deleteRoomBuilding(row.id).subscribe(
|
|
||||||
(res) => {
|
|
||||||
this.fetchData();
|
|
||||||
this.toastr.success("Success", "Delete Completed.", {
|
|
||||||
timeOut: 2000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.error(error);
|
|
||||||
this.toastr.error("Error", "Data sedang digunakan!", {
|
|
||||||
timeOut: 2000,
|
|
||||||
closeButton: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onTouchStart(event: Event) {
|
|
||||||
event.preventDefault(); // Add this if necessary
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
|
||||||
|
|
||||||
import { NgSelectModule } from '@ng-select/ng-select';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { ClipboardModule } from 'ngx-clipboard';
|
|
||||||
import { CardModule } from '../../partials/general/card/card.module';
|
|
||||||
import { BreadcrumbModule } from 'src/app/_layout/breadcrumb/breadcrumb.module';
|
|
||||||
import { BlockUIModule } from 'ng-block-ui';
|
|
||||||
import { BlockTemplateComponent } from '../../../_layout/blockui/block-template.component';
|
|
||||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
|
||||||
import { ListMonitoringComponent } from './list-monitoring.component';
|
|
||||||
import { AddEditListComponent } from './add-edit-list/add-edit-list.component';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
ListMonitoringComponent,
|
|
||||||
AddEditListComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
CardModule,
|
|
||||||
BreadcrumbModule,
|
|
||||||
NgSelectModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
ClipboardModule,
|
|
||||||
PerfectScrollbarModule,
|
|
||||||
NgxDatatableModule,
|
|
||||||
BlockUIModule.forRoot({
|
|
||||||
template: BlockTemplateComponent
|
|
||||||
}),
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: ListMonitoringComponent
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'add-row',
|
|
||||||
component: AddEditListComponent,
|
|
||||||
data: { mode: 'add' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'edit/:id',
|
|
||||||
component: AddEditListComponent,
|
|
||||||
data: { mode: 'edit' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'view/:id',
|
|
||||||
component: AddEditListComponent,
|
|
||||||
data: { mode: 'view' }
|
|
||||||
}
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class ListMonitoringModule { }
|
|
|
@ -1,54 +0,0 @@
|
||||||
/* 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;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .form-control {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .input-group select,
|
|
||||||
::ng-deep .input-group .input-group-append .btn {
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .input-group .form-control {
|
|
||||||
margin-right: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
} */
|
|
|
@ -1,79 +0,0 @@
|
||||||
<div class="modal-header" style="background-color: #FBFBFB !important">
|
|
||||||
<h4 class="modal-title" style="color: #242222">{{labelModal}}</h4>
|
|
||||||
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body" style="background-color: #FBFBFB !important">
|
|
||||||
<form [formGroup]="myForm">
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="name" style="color: #242222">Name:</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="name"
|
|
||||||
formControlName="name"
|
|
||||||
maxlength="50"
|
|
||||||
/>
|
|
||||||
<div *ngIf="myForm.get('name').touched && myForm.get('name').invalid" class="text-danger">
|
|
||||||
Name is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-6" *ngIf="floor">
|
|
||||||
<label for="code" style="color: #242222">Code:</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="code"
|
|
||||||
formControlName="code"
|
|
||||||
maxlength="10"
|
|
||||||
(input)="toUppercase($event)"
|
|
||||||
/>
|
|
||||||
<div *ngIf="myForm.get('code').touched && myForm.get('code').invalid" class="text-danger">
|
|
||||||
code is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-6" *ngIf="category">
|
|
||||||
<label for="icon" style="color: #242222">Icon:</label>
|
|
||||||
<app-select-icon [selectedIcon]="selectedIcon" (iconSelected)="onIconSelected($event)"></app-select-icon>
|
|
||||||
<div *ngIf="myForm.get('icon').touched && myForm.get('icon').invalid" class="text-danger">
|
|
||||||
Icon is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="status" style="color: #242222">Status:</label>
|
|
||||||
<select
|
|
||||||
id="projectinput5"
|
|
||||||
class="form-control custom-select"
|
|
||||||
formControlName="status"
|
|
||||||
>
|
|
||||||
<option *ngFor="let data of dataMasterStatus" [value]="data.id">
|
|
||||||
{{ data.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<div *ngIf="myForm.get('status').touched && myForm.get('status').invalid" class="text-danger">
|
|
||||||
Status is required.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer" style="background-color: #FBFBFB !important">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-secondary"
|
|
||||||
style="color: #242222 !important; background-color: #FBFBFB !important; border-color: #FBFBFB !important;"
|
|
||||||
(click)="activeModal.dismiss('Cross click')"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
style="color: #ffffff !important; background-color: #37A647 !important"
|
|
||||||
class="btn btn-primary"
|
|
||||||
(click)="addRow()"
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
</div>
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AddEditMasterComponent } from './add-edit-master.component';
|
|
||||||
|
|
||||||
describe('AddEditMasterComponent', () => {
|
|
||||||
let component: AddEditMasterComponent;
|
|
||||||
let fixture: ComponentFixture<AddEditMasterComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ AddEditMasterComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AddEditMasterComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,127 +0,0 @@
|
||||||
import { Component, Input, OnInit } from "@angular/core";
|
|
||||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
|
||||||
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|
||||||
import { BuildingService } from "../../service/monitoring-api.service";
|
|
||||||
import { LoginService } from "../../service/login.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-add-edit-master",
|
|
||||||
templateUrl: "./add-edit-master.component.html",
|
|
||||||
styleUrls: ["./add-edit-master.component.css"],
|
|
||||||
})
|
|
||||||
export class AddEditMasterComponent implements OnInit {
|
|
||||||
@Input() headerId: number;
|
|
||||||
@Input() dataRow: any;
|
|
||||||
@Input() mode: any;
|
|
||||||
@Input() category: boolean = false;
|
|
||||||
@Input() floor: boolean = false;
|
|
||||||
myForm: FormGroup;
|
|
||||||
dataMasterStatus: any;
|
|
||||||
selectedIcon: string = '';
|
|
||||||
labelModal: string = '';
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private monitoringApiService: BuildingService,
|
|
||||||
private authService: LoginService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.authService.startTokenCheck();
|
|
||||||
this.authService.startTrackingActivity();
|
|
||||||
this.createForm();
|
|
||||||
this.dataListMaster();
|
|
||||||
if (this.mode === "add") {
|
|
||||||
this.labelModal = "Add Row"
|
|
||||||
} else {
|
|
||||||
this.labelModal = "Edit Row"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.dataRow) {
|
|
||||||
this.editForm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createForm() {
|
|
||||||
const formControls = {
|
|
||||||
name: ["", Validators.required],
|
|
||||||
status: ["", Validators.required],
|
|
||||||
headerId: this.headerId
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.category) {
|
|
||||||
formControls['icon'] = [undefined, Validators.required];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.floor) {
|
|
||||||
formControls['code'] = ['', Validators.required];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.myForm = this.fb.group(formControls);
|
|
||||||
}
|
|
||||||
|
|
||||||
toUppercase(event: Event) {
|
|
||||||
const input = event.target as HTMLInputElement;
|
|
||||||
input.value = input.value.toUpperCase();
|
|
||||||
this.myForm.get('code').setValue(input.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
editForm() {
|
|
||||||
const formControls = {
|
|
||||||
id: this.dataRow.id,
|
|
||||||
name: [this.dataRow.name, Validators.required],
|
|
||||||
status: [this.dataRow.status, Validators.required],
|
|
||||||
headerId: this.dataRow.header_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.category) {
|
|
||||||
formControls['icon'] = [this.dataRow.icon || undefined , Validators.required];
|
|
||||||
this.selectedIcon = this.dataRow.icon || undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.floor) {
|
|
||||||
formControls['code'] = [this.dataRow.code || '' , Validators.required];
|
|
||||||
}
|
|
||||||
this.myForm = this.fb.group(formControls);
|
|
||||||
}
|
|
||||||
|
|
||||||
dataListMaster() {
|
|
||||||
this.monitoringApiService.getMasterListData().subscribe((data) => {
|
|
||||||
const dataCategory = data.data.find(
|
|
||||||
(item) => item.name === "master_status"
|
|
||||||
).headerDetailParam;
|
|
||||||
this.dataMasterStatus = dataCategory.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71" || item.status.toLowerCase() === "71");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addRow() {
|
|
||||||
if (this.myForm.valid) {
|
|
||||||
this.activeModal.close(this.myForm.value);
|
|
||||||
} else {
|
|
||||||
this.markFormGroupTouched(this.myForm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
markFormGroupTouched(formGroup: FormGroup) {
|
|
||||||
(Object as any).values(formGroup.controls).forEach((control) => {
|
|
||||||
control.markAsTouched();
|
|
||||||
if (control.controls) {
|
|
||||||
this.markFormGroupTouched(control);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addDepartment() {
|
|
||||||
let newDept = prompt("Enter new department name:");
|
|
||||||
if (newDept) {
|
|
||||||
alert(`Department ${newDept} added! (simulated)`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onIconSelected(icon: string): void {
|
|
||||||
this.selectedIcon = icon;
|
|
||||||
this.myForm.get('icon').setValue(icon); // Set nilai icon ke dalam form
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .no-arrow::-webkit-inner-spin-button,
|
|
||||||
.no-arrow::-webkit-outer-spin-button {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .no-arrow {
|
|
||||||
-moz-appearance: textfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add this CSS to style invalid form controls */
|
|
||||||
.is-invalid {
|
|
||||||
border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-danger {
|
|
||||||
color: #dc3545;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue