Преглед изворни кода

Merge branch 'features' of onunez/soma-frontend into development

Oscar José Nuñez Chávez пре 6 година
родитељ
комит
5512416310

+ 0 - 4
angular.json

@@ -30,7 +30,6 @@
             "styles": [
               "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
               "node_modules/font-awesome/scss/font-awesome.scss",
-              "node_modules/perfect-scrollbar/css/perfect-scrollbar.css",
               "src/assets/scss/material-dashboard.scss",
               "node_modules/leaflet/dist/leaflet.css",
               "src/styles.scss",
@@ -41,7 +40,6 @@
               "node_modules/popper.js/dist/umd/popper.js",
               "node_modules/arrive/src/arrive.js",
               "node_modules/moment/moment.js",
-              "node_modules/perfect-scrollbar/dist/perfect-scrollbar.min.js",
               "node_modules/datatables.net/js/jquery.dataTables.js",
               "node_modules/bootstrap-material-design/dist/js/bootstrap-material-design.min.js",
               "node_modules/bootstrap-select/dist/js/bootstrap-select.min.js"
@@ -110,7 +108,6 @@
             "styles": [
               "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
               "node_modules/font-awesome/scss/font-awesome.scss",
-              "node_modules/perfect-scrollbar/css/perfect-scrollbar.css",
               "src/assets/scss/material-dashboard.scss",
               "node_modules/leaflet/dist/leaflet.css",
               "src/styles.scss",
@@ -121,7 +118,6 @@
               "node_modules/popper.js/dist/umd/popper.js",
               "node_modules/arrive/src/arrive.js",
               "node_modules/moment/moment.js",
-              "node_modules/perfect-scrollbar/dist/perfect-scrollbar.min.js",
               "node_modules/datatables.net/js/jquery.dataTables.js",
               "node_modules/chart.js/src/chart.js",
               "node_modules/bootstrap-material-design/dist/js/bootstrap-material-design.min.js",

+ 0 - 1
package.json

@@ -52,7 +52,6 @@
     "ngx-animating-datepicker": "^1.2.1",
     "ngx-bootstrap": "^5.1.1",
     "ngx-daterangepicker": "^1.1.1",
-    "perfect-scrollbar": "^1.4.0",
     "popper.js": "^1.15.0",
     "print-js": "^1.0.63",
     "rxjs": "6.5.2",

+ 27 - 31
src/app/app.module.ts

@@ -1,50 +1,46 @@
-import { BrowserModule } from '@angular/platform-browser';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-
-import { NgModule } from '@angular/core';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
-import { registerLocaleData, DatePipe } from '@angular/common';
-import { RouterModule } from '@angular/router';
-
+import { BrowserModule } from "@angular/platform-browser";
+import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
 
+import { NgModule } from "@angular/core";
+import { FormsModule, ReactiveFormsModule } from "@angular/forms";
+import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
+import { registerLocaleData, DatePipe } from "@angular/common";
+import { RouterModule } from "@angular/router";
 
 // Internationalization i18n
-import localeEs from '@angular/common/locales/es';
-import localeEsExtra from '@angular/common/locales/extra/es';
-registerLocaleData(localeEs, 'es-Es', localeEsExtra);
+import localeEs from "@angular/common/locales/es";
+import localeEsExtra from "@angular/common/locales/extra/es";
+registerLocaleData(localeEs, "es-Es", localeEsExtra);
 
 // used to create fake backend
 //import { fakeBackendProvider } from './helpers';
 //import { JwtInterceptor, ErrorInterceptor } from './helpers';
 
+import { AppRoutingModule } from "./app.routing";
+import { AppComponent } from "./app.component";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { ChartsModule } from "ng2-charts";
+import { SharedModule } from "./components/shared/shared.module";
 
-import { AppRoutingModule } from './app.routing';
-import { AppComponent } from './app.component';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { ChartsModule } from 'ng2-charts';
-import { SharedModule } from './components/shared/shared.module';
-
-import { AdminComponent } from './layouts/admin/admin.component';
-
-import { NgxDatatableModule } from '@swimlane/ngx-datatable';
-import { MatSelectModule } from '@angular/material/select';
-import { AngularMyDatePickerModule } from 'angular-mydatepicker';
+import { AdminComponent } from "./layouts/admin/admin.component";
 
-import { PluginsModule } from './components/plugins/plugins.module';
-import { LoginComponent } from './components/login/login.component';
+import { NgxDatatableModule } from "@swimlane/ngx-datatable";
+import { MatSelectModule } from "@angular/material/select";
+import { AngularMyDatePickerModule } from "angular-mydatepicker";
 
-import { TokenInterceptor } from '@app/services/token.interceptor';
-import { ConfirmAccountComponent } from './components/confirm-account/confirm-account.component';
-import { MatPasswordStrengthModule } from '@angular-material-extensions/password-strength';
+import { PluginsModule } from "./components/plugins/plugins.module";
+import { LoginComponent } from "./components/login/login.component";
 
+import { TokenInterceptor } from "@app/services/token.interceptor";
+import { ConfirmAccountComponent } from "./components/confirm-account/confirm-account.component";
+import { MatPasswordStrengthModule } from "@angular-material-extensions/password-strength";
 
 @NgModule({
   declarations: [
     AppComponent,
     AdminComponent,
     LoginComponent,
-    ConfirmAccountComponent,
+    ConfirmAccountComponent
   ],
   imports: [
     BrowserModule,
@@ -61,7 +57,7 @@ import { MatPasswordStrengthModule } from '@angular-material-extensions/password
     NgxDatatableModule,
     MatSelectModule,
     AngularMyDatePickerModule,
-    MatPasswordStrengthModule.forRoot(),
+    MatPasswordStrengthModule.forRoot()
   ],
   providers: [
     { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
@@ -74,4 +70,4 @@ import { MatPasswordStrengthModule } from '@angular-material-extensions/password
   ],
   bootstrap: [AppComponent]
 })
-export class AppModule { }
+export class AppModule {}

+ 398 - 229
src/app/components/assets/assets.component.html

@@ -1,278 +1,447 @@
-<h2 class="floating-title">{{title}}</h2>
+<h2 class="floating-title">{{ title }}</h2>
 <div class="main-content">
-  <div class="row align-container">
-    <div class="col-12">    
-      <label for="sel3">Plantas</label>
+  <div class="container-fluid">
+    <div class="row align-container">
+      <div class="col-12">
+        <label for="sel3">Plantas</label>
+      </div>
     </div>
-  </div>
-  <div class="row align-container" >
-    <div class="col-lg-6 col-sm-6 p-1">
-      <div class="row">
-        <div class="col-lg-12 col-sm-12">
-          <select class="custom-select" (change)="onChangeObj($event)" name="sel3">
-            <option *ngFor="let item of listAssets" [selected]="item.id===assetID" [value]="item.id" >{{item.name}}</option>
-          </select>
-        
+    <div class="row align-container">
+      <div class="col-lg-6 col-sm-6 p-1">
+        <div class="row">
+          <div class="col-lg-12 col-sm-12">
+            <select
+              class="custom-select"
+              (change)="onChangeObj($event)"
+              name="sel3"
+            >
+              <option
+                *ngFor="let item of listAssets"
+                [selected]="item.id === assetID"
+                [value]="item.id"
+                >{{ userLevel == 0 ? "PLANTA INVERLEC" : item.name }}</option
+              >
+            </select>
+          </div>
         </div>
-      </div>
 
-    <div class="row">
-      <div class="col-lg-12">
-        <div class="widget environment-meters">
-          <div class="mini-stats">
-            <!--<i class="fas fa-money-check-alt"></i> <i class="fas fa-hand-holding-usd"></i>-->
-            <span class="savings-skin"><i class="fas fa-money-check-alt"></i></span>
-            <div class="savings">
-              <h4>Ahorro total </h4>
-              <h3 *ngIf="eProduced">
-                 ${{total_savings}}
-              </h3>
-            </div>
-            <div class="savings-last-24h">
-              <i class="material-icons">
-                trending_up
-              </i>
-              Ahorro últimas 24hrs. <span>${{last_day_savings}}</span>
+        <div class="row">
+          <div class="col-lg-12">
+            <div class="widget environment-meters">
+              <div class="mini-stats">
+                <!--<i class="fas fa-money-check-alt"></i> <i class="fas fa-hand-holding-usd"></i>-->
+                <span class="savings-skin"
+                  ><i class="fas fa-money-check-alt"></i
+                ></span>
+                <div class="savings">
+                  <h4>Ahorro total</h4>
+                  <h3 *ngIf="eProduced">${{ total_savings }}</h3>
+                </div>
+                <div class="savings-last-24h">
+                  <i class="material-icons">
+                    trending_up
+                  </i>
+                  Ahorro últimas 24hrs. <span>${{ last_day_savings }}</span>
+                </div>
+              </div>
             </div>
           </div>
         </div>
       </div>
+      <!-- Weather card -->
+      <div class="col-lg-6 col-sm-6 p-1">
+        <div class="row">
+          <div class="col-lg-12">
+            <app-weather-card [city]="city"></app-weather-card>
+          </div>
+        </div>
+      </div>
     </div>
 
-    </div>
-    <!-- Weather card -->
-    <div class="col-lg-6 col-sm-6 p-1">
-      <div class="row">
-        <div class="col-lg-12">
-          <app-weather-card [city]="city"></app-weather-card>
+    <div class="row align-container" *ngIf="!metersInstalled">
+      <div class="col-12 p-1">
+        <br />
+        <div class="alert alert-danger" role="alert">
+          <h4 class="card-text">
+            <i class="fas fa-exclamation-circle"></i>
+            La planta no tiene medidores asignados
+          </h4>
         </div>
       </div>
     </div>
 
-  </div>
+    <!-- Basic stats cards -->
+    <div class="row align-container" *ngIf="metersInstalled">
+      <div class="col-sm-12 col-md-6">
+        <div class="row p-0">
+          <div class="col-xl-6 col-md-6 col-sm-12 p-1">
+            <div class="widget energy-stats">
+              <div class="mini-stats ">
+                <span class="sky-skin"><i class="fa fa-bolt"></i></span>
+                <h3 *ngIf="eProduced">
+                  {{ energyDay }}
+                  <small>kWh</small>
+                </h3>
+                <p>Ultimo dia</p>
+              </div>
+            </div>
+          </div>
 
-  <div class="row align-container" *ngIf="!metersInstalled">
-    <div class="col-12 p-1">
-      <br>
-      <div class="alert alert-danger" role="alert">
-        <h4 class="card-text">
-          <i class="fas fa-exclamation-circle"></i>
-          La planta no tiene medidores asignados
-        </h4>
-      </div>
-    </div>
-  </div>
+          <div class="col-xl-6 col-md-6 col-sm-12 p-1">
+            <div class="widget energy-stats">
+              <div class="mini-stats ">
+                <span class="dark-yellow-skin"><i class="fa fa-bolt"></i></span>
+                <h3 *ngIf="eProduced">
+                  {{ energyWeek }}
+                  <small>MWh</small>
+                </h3>
+                <p>Ultima semana</p>
+              </div>
+            </div>
+          </div>
 
-  <!-- Basic stats cards -->
-  <div class="row align-container" *ngIf="metersInstalled">
+          <div class="col-xl-6 col-md-6 col-sm-12 p-1">
+            <div class="widget energy-stats">
+              <div class="mini-stats ">
+                <span class="yellow-skin"><i class="fa fa-bolt"></i></span>
+                <h3 *ngIf="eProduced">
+                  {{ energyMonth }}
+                  <small>MWh</small>
+                </h3>
+                <p>Ultimos 30 días</p>
+              </div>
+            </div>
+          </div>
 
-    <div class="col-xl-3 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget energy-stats">
-        <div class="mini-stats ">
-          <span class="sky-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="eProduced">
-            {{energyDay}}
-            <small>kWh</small>
-          </h3>
-          <p>Ultimo dia</p>
-        </div>
-      </div>
-    </div>
-    
-    <div class="col-xl-3 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget energy-stats">
-        <div class="mini-stats ">
-          <span class="dark-yellow-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="eProduced">
-            {{energyWeek}}
-            <small>MWh</small>
-          </h3>
-          <p>Ultima semana</p>
-        </div>
-      </div>
-    </div>
-    
-    <div class="col-xl-3 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget energy-stats">
-        <div class="mini-stats ">
-          <span class="yellow-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="eProduced">
-            {{energyMonth}}
-            <small>MWh</small>
-          </h3>
-          <p>Ultimos 30 días</p>
+          <div class="col-xl-6 col-md-6 col-sm-12 p-1">
+            <div class="widget energy-stats">
+              <div class="mini-stats ">
+                <span class="green-skin"><i class="fa fa-bolt"></i></span>
+                <h3 *ngIf="eProduced">
+                  {{ energyYear }}
+                  <small>MWh</small>
+                </h3>
+                <p>Total</p>
+              </div>
+            </div>
+          </div>
         </div>
       </div>
-    </div>
-
-    <div class="col-xl-3 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget energy-stats">
-        <div class="mini-stats ">
-          <span class="green-skin"><i class="fa fa-bolt"></i></span>
-          <h3 *ngIf="eProduced">
-            {{energyYear}}
-            <small>MWh</small>
-          </h3>
-          <p>Total</p>
+      <div class="col-sm-12 col-md-6">
+        <div class="row p-0">
+          <div class="col-12 p-1">
+            <div class="certification-stats">
+              <span class="cert-skin">
+                <img src="assets/img/medal.png" alt="Certificate" />
+              </span>
+              <div class="cert-title">
+                <h2>Certificados de origen - CdO</h2>
+              </div>
+              <div class="cdo-items">
+                <i class="material-icons">
+                  check_box
+                </i>
+                Total de certificados de origen:
+                <span class="cdo-total">{{ totalCertificates }}</span>
+              </div>
+              <div class="cdo-items">
+                <i class="material-icons">
+                  offline_bolt
+                </i>
+                Fecha de último CdO generado:
+                <span class="cdo-date">
+                  {{ lastGeneratedDateCertificate }}
+                </span>
+              </div>
+              <div class="cdo-items">
+                <i class="material-icons ">
+                  money
+                </i>
+                Monto total por CdO generados:
+                <span class="cdo-money">${{ totalCertificatesValue }}</span>
+              </div>
+            </div>
+          </div>
         </div>
       </div>
     </div>
 
-  </div>
+    <!-- Chartjs potency generation graphic -->
+    <div class="row align-container">
+      <div class="col-lg-12 col-md-12 col-sm-12 p-1">
+        <div class="widget">
+          <div class="mini-stats">
+            <div class="row" *ngIf="metersInstalled">
+              <div class="col-12">
+                <p class="align-right">
+                  Seleccione un rango y un tipo de visualización
+                </p>
 
-  <!-- Chartjs potency generation graphic -->
-  <div class="row align-container">
-    <div class="col-lg-12 col-md-12 col-sm-12 p-1">
-      <div class="widget">
-        <div class="mini-stats">
+                <div class="visualization">
+                  <div class=" action-buttons">
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[0]"
+                      (click)="getMeasureRangeChart('day')"
+                    >
+                      1D
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[1]"
+                      (click)="getMeasureRangeChart('week')"
+                    >
+                      7D
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[2]"
+                      (click)="getMeasureRangeChart('WTD')"
+                    >
+                      WTD
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[3]"
+                      (click)="getMeasureRangeChart('month')"
+                    >
+                      1M
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[4]"
+                      (click)="getMeasureRangeChart('MTD')"
+                    >
+                      MTD
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[5]"
+                      (click)="getMeasureRangeChart('3m')"
+                    >
+                      3M
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[6]"
+                      (click)="getMeasureRangeChart('12m')"
+                    >
+                      12M
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[7]"
+                      (click)="getMeasureRangeChart('YTD')"
+                    >
+                      YTD
+                    </button>
+                    <button
+                      class="btn btn-link"
+                      [class.btn-success]="isActive[8]"
+                      (click)="getMeasureRangeChart('total')"
+                    >
+                      TOTAL
+                    </button>
 
-          <div class="row" *ngIf="metersInstalled">
-            <div class="col-12">
-              <p class="align-right">Seleccione un rango y un tipo de visualización</p>
-                
-              <div class="visualization">
-                <div class=" action-buttons">
-                  <button class="btn btn-link" [class.btn-success]='isActive[0]' (click)="getMeasureRangeChart('day')">1D</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[1]' (click)="getMeasureRangeChart('week')">7D</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[2]' (click)="getMeasureRangeChart('WTD')">WTD</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[3]' (click)="getMeasureRangeChart('month')">1M</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[4]' (click)="getMeasureRangeChart('MTD')">MTD</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[5]' (click)="getMeasureRangeChart('3m')">3M</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[6]' (click)="getMeasureRangeChart('12m')">12M</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[7]' (click)="getMeasureRangeChart('YTD')">YTD</button>
-                  <button class="btn btn-link" [class.btn-success]='isActive[8]' (click)="getMeasureRangeChart('total')">TOTAL</button>
-               
-                  
-                  <div class="input-box-container">
-                    <div>
-                      <p>
-                        <i class="far fa-calendar" aria-hidden="true"></i>
-                      </p>
-                      <input class="input-box form-control" placeholder="Seleccione una fecha" 
-                        angular-mydatepicker name="mydate" (click)="dp.toggleCalendar()" 
-                        [(ngModel)]="model" [options]="myDpOptions" (dateChanged)="onDateChanged($event)" 
-                        #dp="angular-mydatepicker"/>
+                    <div class="input-box-container">
+                      <div>
+                        <p>
+                          <i class="far fa-calendar" aria-hidden="true"></i>
+                        </p>
+                        <input
+                          class="input-box form-control"
+                          placeholder="Seleccione una fecha"
+                          angular-mydatepicker
+                          name="mydate"
+                          (click)="dp.toggleCalendar()"
+                          [(ngModel)]="model"
+                          [options]="myDpOptions"
+                          (dateChanged)="onDateChanged($event)"
+                          #dp="angular-mydatepicker"
+                        />
+                      </div>
                     </div>
                   </div>
-                </div>
-                <div class=" action-buttons">
-                  <button title="Barra" [ngClass]="[chartActive[0]==true ? 'btn  btn-success' : 'btn btn-dark']"  (click)="changeGraphicType('bar')"> 
-                    <i class="fa fa-chart-bar"></i>
-                  </button>
-                  <button title="Línea" [ngClass]="[chartActive[1]==true ? 'btn  btn-success' : 'btn btn-dark']" (click)="changeGraphicType('line')"> 
-                    <i class="fa fa-chart-area"></i>
-                  </button>
-                  <!--
-                  <button title="Area" [ngClass]="[chartActive[2]==true ? 'btn  btn-success' : 'btn btn-dark']" (click)="changeGraphicType('radar')"> 
-                    <i class="fa fa-chart-area"></i>
-                  </button>-->
-                  <button title="Tabla" [ngClass]="[chartActive[3]==true ? 'btn  btn-success' : 'btn btn-dark']" (click)="changeToTable()"> 
-                    <i class="fa fa-table"></i>
-                  </button>
+                  <div class=" action-buttons">
+                    <button
+                      title="Barra"
+                      [ngClass]="[
+                        chartActive[0] == true
+                          ? 'btn  btn-success'
+                          : 'btn btn-dark'
+                      ]"
+                      (click)="changeGraphicType('bar')"
+                    >
+                      <i class="fa fa-chart-bar"></i>
+                    </button>
+                    <button
+                      title="Línea"
+                      [ngClass]="[
+                        chartActive[1] == true
+                          ? 'btn  btn-success'
+                          : 'btn btn-dark'
+                      ]"
+                      (click)="changeGraphicType('line')"
+                    >
+                      <i class="fa fa-chart-area"></i>
+                    </button>
+                    <!--
+                    <button title="Area" [ngClass]="[chartActive[2]==true ? 'btn  btn-success' : 'btn btn-dark']" (click)="changeGraphicType('radar')"> 
+                      <i class="fa fa-chart-area"></i>
+                    </button>-->
+                    <button
+                      title="Tabla"
+                      [ngClass]="[
+                        chartActive[3] == true
+                          ? 'btn  btn-success'
+                          : 'btn btn-dark'
+                      ]"
+                      (click)="changeToTable()"
+                    >
+                      <i class="fa fa-table"></i>
+                    </button>
+                  </div>
                 </div>
               </div>
             </div>
-          </div>
-
-          <div class="chart-container" id="chart-wrapper">
-            <canvas id="canvas">{{ chart1 }}</canvas>
-          </div>
-          <div class="no-data">
-            <h2>
-              Información no disponible
-            </h2>
-          </div>
-          <div id="toogleTable">
-            <ng-container class="example-container mat-elevation-z8" *ngIf="showTable" >
-              <div class="example-table-container">
-          
-                <div class="action-buttons">
-                  <button class="btn btn-primary btn-sm" mat-raised-button (click)="exporter.exportTable(exportExcel, ExcelOptions)">
-                    <i class="fas fa-file-excel"></i>
-                    EXCEL
-                  </button>
-                  <button class="btn btn-primary btn-sm" mat-raised-button (click)="exporter.exportTable(exportCSV, CSVOptions)">
-                    <i class="fas fa-file-csv"></i>
-                    CSV
-                  </button>
-                  <button class="btn btn-primary btn-sm" mat-raised-button (click)="exporter.exportTable(exportJSON, JSONOptions)">
-                    <i class="fas fa-file-alt"></i>
-                    JSON
-                  </button>
-                  <button class="btn btn-primary btn-sm" mat-raised-button (click)="printTable()">
-                    <i class="fas fa-file-alt"></i>
-                    IMPRIMIR
-                  </button>
-                </div>
 
-                <mat-table  matTableExporter #table [dataSource]="dataSource"  #exporter="matTableExporter" id="measuresTable">
-                  <div *ngFor="let disCol of displayedColumns; let colIndex = index" matColumnDef="{{disCol}}">
-                    <mat-header-cell *matHeaderCellDef>{{disCol}}</mat-header-cell>
-                    <mat-cell *matCellDef="let element"> {{element[colIndex]}}
-                    </mat-cell>
+            <div class="chart-container" id="chart-wrapper">
+              <canvas id="canvas">{{ chart1 }}</canvas>
+            </div>
+            <div class="no-data">
+              <h2>
+                Información no disponible
+              </h2>
+            </div>
+            <div id="toogleTable">
+              <ng-container
+                class="example-container mat-elevation-z8"
+                *ngIf="showTable"
+              >
+                <div class="example-table-container">
+                  <div class="action-buttons">
+                    <button
+                      class="btn btn-primary btn-sm"
+                      mat-raised-button
+                      (click)="exporter.exportTable(exportExcel, ExcelOptions)"
+                    >
+                      <i class="fas fa-file-excel"></i>
+                      EXCEL
+                    </button>
+                    <button
+                      class="btn btn-primary btn-sm"
+                      mat-raised-button
+                      (click)="exporter.exportTable(exportCSV, CSVOptions)"
+                    >
+                      <i class="fas fa-file-csv"></i>
+                      CSV
+                    </button>
+                    <button
+                      class="btn btn-primary btn-sm"
+                      mat-raised-button
+                      (click)="exporter.exportTable(exportJSON, JSONOptions)"
+                    >
+                      <i class="fas fa-file-alt"></i>
+                      JSON
+                    </button>
+                    <button
+                      class="btn btn-primary btn-sm"
+                      mat-raised-button
+                      (click)="printTable()"
+                    >
+                      <i class="fas fa-file-alt"></i>
+                      IMPRIMIR
+                    </button>
                   </div>
-          
-                  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
-                  <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
-                </mat-table>
-              </div>
-            </ng-container>
-            <mat-paginator class="hiddenonload" [pageSizeOptions]="[5, 10, 25, dataSource.data.length] " [length]="dataSource.data.length" [pageIndex]="0" [pageSize]="10"></mat-paginator>
-          </div>
 
+                  <mat-table
+                    matTableExporter
+                    #table
+                    [dataSource]="dataSource"
+                    #exporter="matTableExporter"
+                    id="measuresTable"
+                  >
+                    <div
+                      *ngFor="
+                        let disCol of displayedColumns;
+                        let colIndex = index
+                      "
+                      matColumnDef="{{ disCol }}"
+                    >
+                      <mat-header-cell *matHeaderCellDef>{{
+                        disCol
+                      }}</mat-header-cell>
+                      <mat-cell *matCellDef="let element">
+                        {{ element[colIndex] }}
+                      </mat-cell>
+                    </div>
+
+                    <mat-header-row
+                      *matHeaderRowDef="displayedColumns"
+                    ></mat-header-row>
+                    <mat-row
+                      *matRowDef="let row; columns: displayedColumns"
+                    ></mat-row>
+                  </mat-table>
+                </div>
+              </ng-container>
+              <mat-paginator
+                class="hiddenonload"
+                [pageSizeOptions]="[5, 10, 25, dataSource.data.length]"
+                [length]="dataSource.data.length"
+                [pageIndex]="0"
+                [pageSize]="10"
+              ></mat-paginator>
+            </div>
+          </div>
         </div>
       </div>
-
     </div>
-  </div>
-  
-  <!-- Enviromental cool stats cards -->
-  <div class="row align-container" *ngIf="metersInstalled">
 
-    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget">
-        <div class="enviroment-stats">
-          <div class="enviromental-icon">
-            <img src="assets/img/barrels2.png" alt="">
-          </div>
-          <div class="enviromental-text">
-            <span>{{environmentFuel}}</span>
-            Barriles de petróleo crudo producidos.
+    <!-- Enviromental cool stats cards -->
+    <div class="row align-container" *ngIf="metersInstalled">
+      <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
+        <div class="widget">
+          <div class="enviroment-stats">
+            <div class="enviromental-icon">
+              <img src="assets/img/barrels2.png" alt="" />
+            </div>
+            <div class="enviromental-text">
+              <span>{{ environmentFuel }}</span>
+              Barriles de petróleo crudo producidos.
+            </div>
           </div>
         </div>
       </div>
-    </div>
-    
-    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget">
-        <div class="enviroment-stats">
-          <div class="enviromental-icon">
-            <img src="assets/img/car2-icon.png" alt="">
-          </div>
-          <div class="enviromental-text">
-            <span>{{environmentCO2}}Kg.</span>
-            De gases CO2 evitados.
+
+      <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
+        <div class="widget">
+          <div class="enviroment-stats">
+            <div class="enviromental-icon">
+              <img src="assets/img/car2-icon.png" alt="" />
+            </div>
+            <div class="enviromental-text">
+              <span>{{ environmentCO2 }}Kg.</span>
+              De gases CO2 evitados.
+            </div>
           </div>
         </div>
       </div>
-    </div>
-    
-    <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
-      <div class="widget">
-        <div class="enviroment-stats">
-          <div class="enviromental-icon">
-            <img src="assets/img/poweredhouse.png" alt="">
-          </div>
-          <div class="enviromental-text">
-            La energía que demandan 
-            <span>{{environmentHouse}}</span>
-            hogares durante 1 año.
+
+      <div class="col-xl-4 col-lg-6 col-md-6 col-sm-6 p-1">
+        <div class="widget">
+          <div class="enviroment-stats">
+            <div class="enviromental-icon">
+              <img src="assets/img/poweredhouse.png" alt="" />
+            </div>
+            <div class="enviromental-text">
+              La energía que demandan
+              <span>{{ environmentHouse }}</span>
+              hogares durante 1 año.
+            </div>
           </div>
-           
         </div>
       </div>
     </div>
-
   </div>
-
 </div>

+ 123 - 25
src/app/components/assets/assets.component.scss

@@ -12,7 +12,7 @@ h4.card-text {
   position: relative;
   border-collapse: separate;
   max-width: 130px;
-  
+
   input {
     margin: 5px 0 0;
     font-family: inherit;
@@ -21,15 +21,14 @@ h4.card-text {
     max-width: inherit;
   }
 
-  p{
+  p {
     position: absolute;
     margin-left: 5px;
     height: 25px;
     display: flex;
     align-items: center;
-    left: 5px
+    left: 5px;
   }
-
 }
 
 .savings-wrapper {
@@ -103,7 +102,75 @@ table {
 }
 
 .energy-stats {
-  height: 122px;
+  height: 90px;
+  margin-top: 9px !important;
+}
+
+.certification-stats {
+  height: 198px;
+  background-color: #fff;
+  margin-top: 9px;
+  position: relative;
+  width: 100%;
+  border-radius: 5px;
+  position: relative;
+  padding: 10px 15px;
+}
+
+.cdo-items {
+  line-height: 1.5;
+  font-size: 1rem;
+  padding: 3px 0;
+  @media screen and (max-width: 800px) {
+    font-size: 0.9rem;
+  }
+
+  i.material-icons {
+    font-size: 16px;
+  }
+
+  span.cdo-money {
+    font-size: 1.3rem;
+    color: #47a44b;
+  }
+  span.cdo-total {
+    font-size: 1.3rem;
+    color: #0d3b66;
+  }
+  span.cdo-date {
+    font-size: 1.2rem;
+    color: #ee964b;
+  }
+  span {
+    font-weight: bold;
+    @media screen and (max-width: 420px) {
+      font-size: 1rem !important;
+    }
+  }
+}
+
+.cert-title {
+  h2 {
+    font-size: 1.5rem;
+    margin: 0 0 12px;
+    @media screen and (max-width: 800px) {
+      font-size: 1.3rem;
+    }
+    @media screen and (max-width: 420px) {
+      font-size: 1rem;
+      font-weight: bold;
+    }
+  }
+}
+
+.cert-skin {
+  position: absolute;
+  right: 15px;
+  top: 10px;
+  @media screen and (max-width: 420px) {
+    right: 5px;
+    top: 5px;
+  }
 }
 
 .environment-meters {
@@ -149,14 +216,33 @@ table {
       border-radius: 50%;
       color: #fff;
       //float: left;
-      font-size: 35px;
-      height: 60px;
-      line-height: 60px;
+      font-size: 30px;
+      height: 53px;
+      line-height: 53px;
       text-align: center;
-      width: 60px;
+      width: 53px;
       position: absolute;
-      right: 20px;
+      right: 15px;
       bottom: 15px;
+      @media screen and (max-width: 960px) {
+        height: 48px;
+        width: 48px;
+        line-height: 48px;
+        font-size: 24px;
+      }
+      @media screen and (max-width: 800px) {
+        height: 44px;
+        width: 44px;
+        line-height: 44px;
+        font-size: 24px;
+        right: 10px;
+      }
+      @media screen and (min-width: 960px) and (max-width: 1024px) {
+        height: 48px;
+        width: 48px;
+        line-height: 48px;
+        font-size: 24px;
+      }
       //display: block;
     }
 
@@ -166,18 +252,39 @@ table {
       border: none;
       font-size: 48px;
       line-height: 50px;
+      width: 64px;
+      position: absolute;
+
+      @media screen and (max-width: 960px) {
+        top: 0;
+        width: 50px;
+        i {
+          font-size: 36px;
+        }
+      }
     }
 
     h3 {
-      margin: 10px 0 0;
-      font-size: 2rem;
+      margin: 0;
+      font-size: 1.8rem;
+      @media screen and (max-width: 1152px) {
+        font-size: 1.5rem;
+      }
+      @media screen and (min-width: 960px) and (max-width: 1024px) {
+        font-size: 1.3rem;
+      }
+      @media screen and (max-width: 800px) {
+        font-size: 1.4rem;
+      }
       font-weight: 400;
     }
 
     .savings {
       width: 100%;
       margin-bottom: 5px;
-      h4, h3, h2 {
+      h4,
+      h3,
+      h2 {
         display: inline-block;
         width: auto;
       }
@@ -208,8 +315,6 @@ table {
         font-weight: bold;
       }
     }
-
-
   }
 
   .enviroment-stats {
@@ -243,10 +348,7 @@ table {
         vertical-align: middle;
       }
     }
-
   }
-
-
 }
 
 .btn {
@@ -254,15 +356,14 @@ table {
 }
 
 .chart-container {
-  display: block; 
-  height:48vh; 
+  display: block;
+  height: 48vh;
   @media screen and (max-width: 960px) {
-    height:350px; 
+    height: 350px;
   }
   position: relative;
 }
 
-
 .no-data {
   text-align: center;
   z-index: 20;
@@ -273,15 +374,12 @@ table {
   visibility: hidden;
 }
 
-
 @media screen and (min-width: 960px) {
   .mini-stats {
-    
     p,
     span,
     h3 {
       display: block;
     }
-
   }
 }

Разлика између датотеке није приказан због своје велике величине
+ 637 - 386
src/app/components/assets/assets.component.ts


+ 70 - 50
src/app/components/dashboard/dashboard.component.html

@@ -1,40 +1,51 @@
-<h2 class="floating-title">{{title}}</h2>
+<h2 class="floating-title">{{ title }}</h2>
 
 <div class="main-content">
   <div class="container-fluid">
-
     <div class="row">
       <div class="col-lg-6 col-md-6 col-sm-6">
-        <div class="card dark-yellow-skin bg-gradient-danger card-img-holder text-white">
+        <div
+          class="card dark-yellow-skin bg-gradient-danger card-img-holder text-white"
+        >
           <div class="card-body">
-            <img alt="circle-image" class="card-img-absolute" src="assets/img/waves-opt.png">
-            <h4 class="font-weight-normal mb-3">Total de plantas instaladas
+            <img
+              alt="circle-image"
+              class="card-img-absolute"
+              src="assets/img/waves-opt.png"
+            />
+            <h4 class="font-weight-normal mb-3">
+              Total de plantas instaladas
               <i class="mdi mdi-chart-line mdi-24px float-right"></i>
             </h4>
-            <h2 class="mb-3" *ngIf="listAssets">{{listAssets.length}}</h2>
+            <h2 class="mb-3" *ngIf="listAssets">{{ totalAssetsInstalled }}</h2>
           </div>
         </div>
       </div>
       <div class="col-lg-6 col-md-6 col-sm-6">
-        <div class="card sky-skin bg-gradient-danger card-img-holder text-white">
+        <div
+          class="card sky-skin bg-gradient-danger card-img-holder text-white"
+        >
           <div class="card-body">
-            <img alt="circle-image" class="card-img-absolute" src="assets/img/waves-opt.png">
-            <h4 class="font-weight-normal mb-3">Capacidad instalada total
+            <img
+              alt="circle-image"
+              class="card-img-absolute"
+              src="assets/img/waves-opt.png"
+            />
+            <h4 class="font-weight-normal mb-3">
+              Capacidad instalada total
               <i class="mdi mdi-chart-line mdi-24px float-right"></i>
             </h4>
-            <h2 class="mb-3">{{sumarize}} kW</h2>
+            <h2 class="mb-3">{{ sumarize }} kW</h2>
           </div>
         </div>
       </div>
-
-
     </div>
 
     <div class="row ">
       <div *ngIf="error; then showAlert"></div>
       <ng-template #showAlert>
         <div class="col-lg-12">
-          <div class= 'card border-danger'>
+          <div class="card border-danger">
             <div class="card-body">
               Error en el servidor, no se pudo obtener el listado de plantas
             </div>
@@ -42,89 +53,98 @@
         </div>
       </ng-template>
     </div>
-    <br>
+    <br />
 
     <div class="row">
       <div class="col-md-8">
-        <div class= 'card border-success'>
+        <div class="card border-success">
           <div class="card-body">
-            <div style="height: 350px;" leaflet [leafletOptions]="options" [leafletLayers]="markers"
-              (leafletMapReady)='onMapReady($event)'>
-            </div>
+            <div
+              style="height: 350px;"
+              leaflet
+              [leafletOptions]="options"
+              [leafletLayers]="markers"
+              (leafletMapReady)="onMapReady($event)"
+            ></div>
           </div>
         </div>
       </div>
       <div class="col-md-4">
-
-          <div class='plant-detail' *ngIf=selectedPlant>
-            <div class= 'card border-success' style="height: 390px;">
-              <div class="card-body">
-                <h3><i class="fa fa-bolt"></i> {{selectedPlant.name}} </h3>
-
-                <p class='h4'>País: {{selectedPlant.country}}</p>
-                <p class='h4'>Ciudad: {{selectedPlant.city}}</p>
-                <p class='h4'>Dirección: {{selectedPlant.address}}</p>
-                <p class='h4'>Capacidad Instalada: {{totalInstalled}} kW</p>
-
-                <button class="btn bg-yellow btn-flat" (click)="goToAsset(selectedPlant.id)">Ir a Planta</button>
-              </div>
-
+        <div class="plant-detail" *ngIf="selectedPlant">
+          <div class="card border-success" style="height: 390px;">
+            <div class="card-body">
+              <h3><i class="fa fa-bolt"></i> {{ selectedPlant.name }}</h3>
+
+              <p class="h4">País: {{ selectedPlant.country }}</p>
+              <p class="h4">Ciudad: {{ selectedPlant.city }}</p>
+              <p class="h4">Dirección: {{ selectedPlant.address }}</p>
+              <p class="h4">Capacidad Instalada: {{ totalInstalled }} kW</p>
+
+              <button
+                class="btn bg-yellow btn-flat"
+                (click)="goToAsset(selectedPlant.id)"
+              >
+                Ir a Planta
+              </button>
             </div>
           </div>
-
+        </div>
       </div>
     </div>
-    <br>
+    <br />
 
     <div class="row">
       <div class="col-12">
         <div class="example-container mat-elevation-z8">
           <div class="example-table-container">
-      
             <table mat-table [dataSource]="dataSource" class="example-table">
-      
               <!-- Name Column -->
               <ng-container matColumnDef="name">
                 <th mat-header-cell *matHeaderCellDef>Planta</th>
-                <td mat-cell *matCellDef="let row">{{row.name}}</td>
+                <td mat-cell *matCellDef="let row">{{ row.name }}</td>
               </ng-container>
 
               <!-- Country Column -->
               <ng-container matColumnDef="country">
                 <th mat-header-cell *matHeaderCellDef>País</th>
-                <td mat-cell *matCellDef="let row">{{row.country}}</td>
+                <td mat-cell *matCellDef="let row">{{ row.country }}</td>
               </ng-container>
 
               <!-- Country Column -->
               <ng-container matColumnDef="city">
                 <th mat-header-cell *matHeaderCellDef>Ciudad</th>
-                <td mat-cell *matCellDef="let row">{{row.city}}</td>
+                <td mat-cell *matCellDef="let row">{{ row.city }}</td>
               </ng-container>
-              
+
               <!--  Column -->
               <ng-container matColumnDef="id">
                 <th mat-header-cell *matHeaderCellDef>&nbsp;</th>
                 <td mat-cell *matCellDef="let row">
-
                   <div class="action-buttons">
-                    <a class="btn btn-primary btn-sm" (click)="goToAsset(row.id)" href="javascript:void(0)">
+                    <a
+                      class="btn btn-primary btn-sm"
+                      (click)="goToAsset(row.id)"
+                      href="javascript:void(0)"
+                    >
                       Ir a planta
                     </a>
-                  
                   </div>
                 </td>
               </ng-container>
-      
+
               <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-              <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+              <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
             </table>
-            <mat-paginator [pageSizeOptions]="[5, 10, 20]" [pageIndex]="0" [pageSize]="5"></mat-paginator>
+
+            <mat-paginator
+              [pageSizeOptions]="[5, 10, 20]"
+              [pageIndex]="0"
+              [pageSize]="5"
+            ></mat-paginator>
           </div>
         </div>
       </div>
     </div>
-
-
   </div>
-  <br>
-</div>
+  <br />
+</div>

+ 164 - 106
src/app/components/dashboard/dashboard.component.ts

@@ -1,53 +1,60 @@
-import { ActivatedRoute, Router } from '@angular/router';
-import { Component, OnInit, Input, Output, EventEmitter, OnDestroy, NgZone, ViewChild } from '@angular/core';
-import { Plant } from 'src/app/models/plant';
-import { PlantsService } from 'src/app/services/plants.service';
-import { OrganizationsService } from 'src/app/services/organizations.service';
-import { latLng, tileLayer, marker, Layer, icon, Map, latLngBounds, LatLng, point } from 'leaflet';
-
-import {MatPaginator} from '@angular/material/paginator';
-import {MatSort} from '@angular/material/sort';
-import {MatTableDataSource} from '@angular/material/table';
-
-import { of as observableOf, Observable, throwError, from } from 'rxjs';
-
-import * as moment from 'moment';
-import Swal from 'sweetalert2';
-
+import { ActivatedRoute, Router } from "@angular/router";
+import { Component, OnInit, NgZone, ViewChild } from "@angular/core";
+import { Plant } from "src/app/models/plant";
+import { PlantsService } from "src/app/services/plants.service";
+import { OrganizationsService } from "src/app/services/organizations.service";
+import {
+  latLng,
+  tileLayer,
+  marker,
+  Layer,
+  icon,
+  Map,
+  latLngBounds,
+  LatLng,
+  point
+} from "leaflet";
+
+import { MatPaginator } from "@angular/material/paginator";
+import { MatSort } from "@angular/material/sort";
+import { MatTableDataSource } from "@angular/material/table";
+import { AuthService } from "@app/services/auth2.service";
+
+import { of as observableOf, Observable, throwError, from } from "rxjs";
+
+import * as moment from "moment";
+import Swal from "sweetalert2";
 
 @Component({
-  selector: 'app-dashboard',
-  templateUrl: './dashboard.component.html',
-  styleUrls: ['./dashboard.component.scss']
+  selector: "app-dashboard",
+  templateUrl: "./dashboard.component.html",
+  styleUrls: ["./dashboard.component.scss"]
 })
 export class DashboardComponent implements OnInit {
-
   title = "Dashboard";
 
-
-  listData:any;
+  listData: any;
   rows = [];
   markers: Layer[] = [];
   points: LatLng[] = [];
 
-
   listAssets: any;
   dataSource = new MatTableDataSource(this.listAssets);
-  displayedColumns: string[] = ['name', 'country', 'city', 'id'];
+  displayedColumns: string[] = ["name", "country", "city", "id"];
 
-  error:boolean;
+  error: boolean;
   listOrganizations: any;
   plantId: string;
   plant: any;
   sub: any;
   plantNotFound: boolean;
   selectedPlant: any;
-  meterKeys:any;
-  meterKeys2:any;
-  assetKeys:any;
+  meterKeys: any;
+  meterKeys2: any;
+  assetKeys: any;
 
-  sumarize:number = 0;
-  totalInstalled:number = 0;
+  sumarize: number = 0;
+  totalInstalled: number = 0;
 
   totalMetersInstalled: string;
 
@@ -58,114 +65,148 @@ export class DashboardComponent implements OnInit {
   icon = icon({
     iconSize: [25, 41],
     iconAnchor: [13, 41],
-    iconUrl: 'assets/img/marker-icon.png',
+    iconUrl: "assets/img/marker-icon.png"
     //shadowUrl: 'marker-shadow.png'
   });
 
   // Open Street Map definitions
-  LAYER_OSM = tileLayer(
-    'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
-    {
-      maxZoom: 18,
-      attribution: '&copy; OpenStreetMap contributors'
-    }
-  );
+  LAYER_OSM = tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
+    maxZoom: 18,
+    attribution: "&copy; OpenStreetMap contributors"
+  });
 
   // Values to bind to Leaflet Directive
   options = {
     layers: [this.LAYER_OSM],
     zoom: 10,
-    center: latLng([13.661714, -89.251530])
+    center: latLng([13.661714, -89.25153])
   };
-  
-  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
-  @ViewChild(MatSort, {static: true}) sort: MatSort;
+
+  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
+  @ViewChild(MatSort, { static: true }) sort: MatSort;
+  userLevel: number;
+  totalAssetsInstalled: any;
 
   constructor(
     private plantsService: PlantsService,
     private route: ActivatedRoute,
     private orgService: OrganizationsService,
     private router: Router,
-    private zone: NgZone) {
+    private zone: NgZone,
+    private authService: AuthService
+  ) {
+    //DEMO
+    this.userLevel = +this.authService.getUserLevel();
 
     Swal.fire({
       allowOutsideClick: false,
-      type: 'info',
-      text: 'Espere por favor...'
+      type: "info",
+      text: "Espere por favor..."
     });
     Swal.showLoading();
-    
-    this.plantsService.getAllAssets().subscribe(res => {
-      this.listAssets = res["data"]["assets"];
-      this.dataSource.data = this.listAssets;
-      this.dataSource.paginator = this.paginator;
-      this.dataSource.sort = this.sort;
-      this.assetKeys = Object.keys(this.listAssets);
-      for (let prop in this.assetKeys){
-        this.meterKeys2 = Object.keys(this.listAssets.map(item => item["meters_installed"])[prop]);
-        if (this.meterKeys2.length > 0){
-          for (let prop2 in this.meterKeys2){
-            this.sumarize += this.listAssets.map(item => item["meters_installed"])[prop].map(response => response["installedCapacity_kW"])[prop2];
-            //this.totalMetersInstalled = this.sumarize.toString();
-            //localStorage.setItem("installedCapacityTotal_kW", this.totalMetersInstalled);
+
+    this.plantsService.getAllAssets().subscribe(
+      res => {
+        this.listAssets = res["data"]["assets"];
+        this.dataSource.data = this.listAssets;
+        this.dataSource.paginator = this.paginator;
+        this.dataSource.sort = this.sort;
+        this.assetKeys = Object.keys(this.listAssets);
+
+        //DEMO
+        if (this.userLevel == 0) {
+          this.sumarize = 320;
+          this.totalAssetsInstalled = 1;
+        } else {
+          this.totalAssetsInstalled = this.listAssets.length || 0;
+          for (let prop in this.assetKeys) {
+            this.meterKeys2 = Object.keys(
+              this.listAssets.map(item => item["meters_installed"])[prop]
+            );
+            if (this.meterKeys2.length > 0) {
+              for (let prop2 in this.meterKeys2) {
+                this.sumarize += this.listAssets
+                  .map(item => item["meters_installed"])
+                  [prop].map(response => response["installedCapacity_kW"])[
+                  prop2
+                ];
+                //this.totalMetersInstalled = this.sumarize.toString();
+                //localStorage.setItem("installedCapacityTotal_kW", this.totalMetersInstalled);
+              }
+            }
           }
-  
         }
-      }      
-    }, (err) => {
-      Swal.fire({
-        type: 'error',
-        title: 'Error en el servidor',
-        text: err.message
-      });
-    });
-  
+
+        setTimeout(() => {
+          if (this.listAssets != undefined) {
+            this.addMarkers();
+            this.sendPlantId(this.listAssets[0].id);
+          }
+          Swal.close();
+        }, 1800);
+      },
+      err => {
+        Swal.fire({
+          type: "error",
+          title: "Error en el servidor",
+          text: err.message
+        });
+      }
+    );
   }
 
-  ngOnInit(): void {
-    
+  ngOnInit() {
+    setTimeout(() => {
+      Swal.close();
+    }, 3000);
 
     var responsiveOptions: any[] = [
-      ['screen and (max-width: 640px)', {
-        seriesBarDistance: 5,
-        axisX: {
-          labelInterpolationFnc: function (value) {
-            return value[0];
+      [
+        "screen and (max-width: 640px)",
+        {
+          seriesBarDistance: 5,
+          axisX: {
+            labelInterpolationFnc: function(value) {
+              return value[0];
+            }
           }
         }
-      }]
+      ]
     ];
+  }
 
-    setTimeout(() => {
-       if (this.listAssets != undefined) {
-        this.addMarkers();
-        this.sendPlantId(this.listAssets[0].id);
-      }
-      Swal.close();
-    }, 1800);
-
+  ngOnChanges(): void {
+    if (this.listAssets != undefined) {
+      this.addMarkers();
+      this.sendPlantId(this.listAssets[0].id);
+    }
   }
 
   getAsset(id: string) {
     return observableOf(this.listAssets.find(e => e.id === id));
   }
 
-
   addMarkers() {
     let lat, long, address, name2;
-
     for (const plant of this.listAssets) {
-      if (plant["meters_installed"].length > 0){
-        lat = plant["meters_installed"][0].gpsLat;
-        long = plant["meters_installed"][0].gpsLong;
-        address = plant.address;
-        name2 = plant.name;
-      
-        const newMarker = marker(
-          [lat, long],
-          { icon: this.icon })
-          .bindPopup('<b>' + name2 + '</b><br>Dirección: ' + address)
-          .on('click', () => {
+      if (plant["meters_installed"].length > 0) {
+        // DEMO
+        if (this.userLevel == 0) {
+          lat = "13.6613819";
+          long = "-89.2514334";
+          address =
+            "Urbanización Madre Selva Calle Llama del Bosque, Edificio Avante, Local 4-5/4-6, Antiguo Cuscatlán";
+          name2 = "Inversiones MERELEC S.A de C.V";
+        } else {
+          lat = plant["meters_installed"][0].gpsLat;
+          long = plant["meters_installed"][0].gpsLong;
+          address = plant.address;
+          name2 = plant.name;
+        }
+
+        const newMarker = marker([lat, long], { icon: this.icon })
+          .bindPopup("<b>" + name2 + "</b><br>Dirección: " + address)
+          .on("click", () => {
             this.zone.run(() => {
               this.sendPlantId(plant.id);
             });
@@ -178,11 +219,30 @@ export class DashboardComponent implements OnInit {
 
   sendPlantId(id: string) {
     this.plantId = id;
-    this.totalInstalled = 0;
-    this.selectedPlant = this.listAssets.find(e => e.id === this.plantId);
-    let keys = Object.keys(this.selectedPlant.meters_installed.map(item => item["meters_installed"]));
-    for (let prop2 in keys){
-      this.totalInstalled += this.selectedPlant.meters_installed.map(response => response["installedCapacity_kW"])[prop2];
+    // DEMO
+    if (this.userLevel == 0) {
+      this.selectedPlant = {
+        name: "Inversiones MERELEC S.A de C.V",
+        country: "El Salvador",
+        city: "La Libertad",
+        address:
+          "Urbanización Madre Selva Calle Llama del Bosque, Edificio Avante, Local 4-5/4-6, Antiguo Cuscatlán",
+        installedCapacity_kW: 300
+      };
+      this.totalInstalled = 320;
+    } else {
+      this.totalInstalled = 0;
+      this.selectedPlant = this.listAssets.find(e => e.id === this.plantId);
+      let keys = Object.keys(
+        this.selectedPlant.meters_installed.map(
+          item => item["meters_installed"]
+        )
+      );
+      for (let prop2 in keys) {
+        this.totalInstalled += this.selectedPlant.meters_installed.map(
+          response => response["installedCapacity_kW"]
+        )[prop2];
+      }
     }
   }
 
@@ -200,8 +260,6 @@ export class DashboardComponent implements OnInit {
   }
 
   goToAsset(id: string) {
-    this.router.navigate(['/assets'], { queryParams: { id: id } });
+    this.router.navigate(["/assets"], { queryParams: { id: id } });
   }
-
-
 }

+ 68 - 54
src/app/components/plants/plants.component.html

@@ -1,84 +1,98 @@
-<h2 class="floating-title">{{title}}</h2>
+<h2 class="floating-title">{{ title }}</h2>
 
 <div class="main-content">
   <div class="container-fluid">
     <div class="row">
-      
       <div class="col-12 align-right">
         <div class="align-container">
-          
           <nav aria-label="breadcrumb">
             <ol class="breadcrumb">
-              <li class="breadcrumb-item"><a [routerLink]="['/']">Dashboard</a></li>
+              <li class="breadcrumb-item">
+                <a [routerLink]="['/']">Dashboard</a>
+              </li>
               <li class="breadcrumb-item">Plantas</li>
             </ol>
           </nav>
 
-          <a class="btn btn-primary" [routerLink]="['/plants/new']" *ngIf="allowedUser()">
+          <a
+            class="btn btn-primary"
+            [routerLink]="['/plants/new']"
+            *ngIf="allowedAdminUser()"
+          >
             Nuevo registro
           </a>
         </div>
       </div>
 
       <div class="col-12">
-          <div class="align-container">
+        <div class="align-container">
+          <h4><b>Listado de plantas</b></h4>
+          <div class="example-container mat-elevation-z8">
+            <div class="example-table-container">
+              <table mat-table [dataSource]="dataSource" class="example-table">
+                <!-- Name Column -->
+                <ng-container matColumnDef="name">
+                  <th mat-header-cell *matHeaderCellDef>Planta</th>
+                  <td mat-cell *matCellDef="let row">{{ row.name }}</td>
+                </ng-container>
 
-            <h4><b>Listado de plantas</b></h4>
-            <div class="example-container mat-elevation-z8">
-              <div class="example-table-container">
-          
-                <table mat-table [dataSource]="dataSource" class="example-table">
-          
-                  <!-- Name Column -->
-                  <ng-container matColumnDef="name">
-                    <th mat-header-cell *matHeaderCellDef>Planta</th>
-                    <td mat-cell *matCellDef="let row">{{row.name}}</td>
-                  </ng-container>
+                <!-- Country Column -->
+                <ng-container matColumnDef="country">
+                  <th mat-header-cell *matHeaderCellDef>País</th>
+                  <td mat-cell *matCellDef="let row">{{ row.country }}</td>
+                </ng-container>
 
-                  <!-- Country Column -->
-                  <ng-container matColumnDef="country">
-                    <th mat-header-cell *matHeaderCellDef>País</th>
-                    <td mat-cell *matCellDef="let row">{{row.country}}</td>
-                  </ng-container>
+                <!-- Country Column -->
+                <ng-container matColumnDef="city">
+                  <th mat-header-cell *matHeaderCellDef>Ciudad</th>
+                  <td mat-cell *matCellDef="let row">{{ row.city }}</td>
+                </ng-container>
 
-                  <!-- Country Column -->
-                  <ng-container matColumnDef="city">
-                    <th mat-header-cell *matHeaderCellDef>Ciudad</th>
-                    <td mat-cell *matCellDef="let row">{{row.city}}</td>
-                  </ng-container>
-                  
-                  <!--  Column -->
-                  <ng-container matColumnDef="id">
-                    <th mat-header-cell *matHeaderCellDef>&nbsp;</th>
-                    <td mat-cell *matCellDef="let row">
+                <!--  Column -->
+                <ng-container matColumnDef="id">
+                  <th mat-header-cell *matHeaderCellDef>&nbsp;</th>
+                  <td mat-cell *matCellDef="let row">
+                    <div class="action-buttons">
+                      <a
+                        class="btn btn-dark btn-sm"
+                        [routerLink]="['/plant', row.id]"
+                        *ngIf="allowedUser()"
+                      >
+                        Ver detalles
+                      </a>
+                      <a
+                        class="btn btn-primary btn-sm"
+                        [routerLink]="['/plant', row.id, 'edit']"
+                        *ngIf="allowedAdminUser()"
+                      >
+                        Editar
+                      </a>
 
-                      <div class="action-buttons">
-                        <a class="btn btn-dark btn-sm" [routerLink]="['/plant', row.id]" *ngIf="allowedUser()" >
-                          Ver detalles
-                        </a>
-                        <a class="btn btn-primary btn-sm" [routerLink]="['/plant', row.id, 'edit']" *ngIf="allowedUser()" >
-                          Editar
-                        </a>
-                        
-                        <!--
+                      <!--
                         <a class="btn btn-danger btn-sm" (click)="delete_organization(row.id)" *ngIf="allowedUser()" >
                           Eliminar
                         </a>-->
-                      </div>
-                    </td>
-                  </ng-container>
-          
-                  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-                  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
-                </table>
-                <mat-paginator [pageSizeOptions]="[10, 15, 25]" [pageIndex]="0" [pageSize]="10"></mat-paginator>
-              </div>
+                    </div>
+                  </td>
+                </ng-container>
+
+                <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+                <tr
+                  mat-row
+                  *matRowDef="let row; columns: displayedColumns"
+                ></tr>
+              </table>
+
+              <mat-paginator
+                [pageSizeOptions]="[10, 15, 25]"
+                [pageIndex]="0"
+                [pageSize]="10"
+              ></mat-paginator>
             </div>
           </div>
-      
+        </div>
       </div>
-      <br>
-      
-    </div>          
+      <br />
+    </div>
   </div>
 </div>

+ 37 - 28
src/app/components/plants/plants.component.ts

@@ -1,44 +1,45 @@
-import { Component, ViewChild, OnInit } from '@angular/core';
+import { Component, ViewChild, OnInit } from "@angular/core";
 
-import { Plant } from 'src/app/models/plant';
-import { PlantsService } from 'src/app/services/plants.service';
-import {MatPaginator} from '@angular/material/paginator';
-import {MatSort} from '@angular/material/sort';
+import { Plant } from "src/app/models/plant";
+import { PlantsService } from "src/app/services/plants.service";
+import { MatPaginator } from "@angular/material/paginator";
+import { MatSort } from "@angular/material/sort";
 
-import {MatTableDataSource} from '@angular/material/table';
-import Swal from 'sweetalert2';
-import { UserService } from '@app/services/user.service';
-import { AuthService } from '@app/services/auth2.service';
+import { MatTableDataSource } from "@angular/material/table";
+import Swal from "sweetalert2";
+import { UserService } from "@app/services/user.service";
+import { AuthService } from "@app/services/auth2.service";
 
 @Component({
-  selector: 'app-plants',
-  templateUrl: './plants.component.html',
-  styleUrls: ['./plants.component.scss']
+  selector: "app-plants",
+  templateUrl: "./plants.component.html",
+  styleUrls: ["./plants.component.scss"]
 })
 export class PlantsComponent implements OnInit {
+  title: string = "Plantas";
 
-  title:string = "Plantas";
- 
-  displayedColumns: string[] = ['name', 'country', 'city', 'id'];
+  displayedColumns: string[] = ["name", "country", "city", "id"];
   //displayedColumns: string[] = ['state'];
 
   listData: Plant[] = [];
-  listPlant:any;
+  listPlant: any;
   dataSource = new MatTableDataSource(this.listPlant);
 
   resultsLength = 0;
   isLoadingResults = true;
   isRateLimitReached = false;
 
-  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
-  @ViewChild(MatSort, {static: true}) sort: MatSort;
+  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
+  @ViewChild(MatSort, { static: true }) sort: MatSort;
 
-
-  constructor(private orgService: PlantsService, private authService: AuthService) {
+  constructor(
+    private orgService: PlantsService,
+    private authService: AuthService
+  ) {
     Swal.fire({
       allowOutsideClick: false,
-      type: 'info',
-      text: 'Espere por favor...'
+      type: "info",
+      text: "Espere por favor..."
     });
     Swal.showLoading();
   }
@@ -51,7 +52,7 @@ export class PlantsComponent implements OnInit {
       this.dataSource.sort = this.sort;
     });
 
-    setTimeout(()=>{
+    setTimeout(() => {
       Swal.close();
     }, 1000);
   }
@@ -63,15 +64,23 @@ export class PlantsComponent implements OnInit {
     }
   }
 
-  allowedUser(){
+  allowedUser() {
     let is_allowed: boolean;
-    if(+this.authService.getUserLevel() < 2){
+    if (+this.authService.getUserLevel() < 2) {
       is_allowed = false;
-    }
-    else {
+    } else {
       is_allowed = true;
     }
-    return is_allowed
+    return is_allowed;
   }
 
+  allowedAdminUser() {
+    let is_allowed: boolean;
+    if (+this.authService.getUserLevel() < 3) {
+      is_allowed = false;
+    } else {
+      is_allowed = true;
+    }
+    return is_allowed;
+  }
 }

+ 0 - 2
src/app/components/plugins/plugins.module.ts

@@ -11,7 +11,6 @@ import {
   MatInputModule,
   MatRippleModule,
   MatFormFieldModule,
-  MatTooltipModule,
   MatSelectModule,
   MatExpansionModule,
   MatTableModule,
@@ -60,7 +59,6 @@ export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
     MatFormFieldModule,
     MatInputModule,
     MatSelectModule,
-    MatTooltipModule,
     MatExpansionModule,
     MatTableModule,
     MatPaginatorModule,

+ 10 - 5
src/app/components/shared/footer/footer.component.html

@@ -1,8 +1,13 @@
-<div class="row align-container">
-  <div class="col-12">
-    <div class="card">
-      <div class="card-body">
-        <p class="card-text">&copy; 2019-2020 - INVERLEC. <a href="#/terms">Términos y condiciones.</a> </p>
+<div class="container-fluid">
+  <div class="row align-container">
+    <div class="col-12">
+      <div class="card">
+        <div class="card-body">
+          <p class="card-text">
+            &copy; 2019-2020 - INVERLEC.
+            <a href="#/terms">Términos y condiciones.</a>
+          </p>
+        </div>
       </div>
     </div>
   </div>

+ 29 - 10
src/app/components/terms/terms.component.html

@@ -1,19 +1,38 @@
-<h2 class="floating-title">{{title}}</h2>
+<h2 class="floating-title">{{ title }}</h2>
 
 <div class="main-content">
-  
   <div class="container-fluid">
-
-    <div class="row">
+    <div class="row align-container">
       <div class="col-lg-12 col-md-12 col-sm-12 p-1">
         <div class="card card-img-holder">
           <div class="card-body">
-              The information and data above is confidential data of INVERLEC, intended for the exclusive use of its DENMARK customers and not for distribution 
-              to any third parties for any purpose whatsoever. By accessing and using such information and data, you agree to use it only for your internal analysis and other similar 
-              internal business purposes, not to transfer or disclose such information or data to any person, company or other entity, except to colleagues within your employer who 
-              have a need to know such information or data to carry out those internal business purposes, and to destroy such information and data and any copies or duplicates as soon 
-              as your use thereof for those purposes has concluded. Your foregoing agreement is subject to the terms, conditions and exceptions relating to confidentiality contained 
-              in the Terms of Use of DENMARK, to which have separately agreed.
+            La información y los datos arriba mencionados son datos
+            confidenciales de INVERLEC, destinados al uso exclusivo de sus
+            clientes de DENMARK y no para su distribución a terceros para
+            cualquier propósito. <br />Al acceder y utilizar dicha información y
+            datos, usted se compromete a utilizarlos sólo para su análisis
+            interno y otros fines comerciales internos similares, a no
+            transferir o revelar dicha información o datos a ninguna persona,
+            empresa u otra entidad, excepto a los colegas dentro de su empresa
+            que tengan necesidad de conocer dicha información o datos para
+            llevar a cabo esos fines comerciales internos, y a destruir dicha
+            información y datos y cualquier copia o duplicado tan pronto como
+            haya concluido su uso para dichos fines. <br />Su acuerdo anterior
+            está sujeto a los términos, condiciones y excepciones relativos a la
+            confidencialidad contenidos en las Condiciones de Uso de DENMARK,
+            que han sido acordadas por separado. <br /><br />Los cálculos
+            realizados sobre las equivalencias entre emisiones de CO2, consumo
+            energético en el hogar, y barriles de petroleo consumidos, se
+            obtienen de la metodología de cálculo utilizada por la Agencia de
+            Protección Ambiental (EPA, por sus siglas en ingles) de los Estados
+            Unidos de America. Para mayor referencia de los calculos visitar el
+            sitio web
+            <a
+              href="https://www.epa.gov/energy/greenhouse-gases-equivalencies-calculator-calculations-and-references"
+              target="_blank"
+            >
+              https://www.epa.gov/energy/greenhouse-gases-equivalencies-calculator-calculations-and-references</a
+            >.
           </div>
         </div>
       </div>

+ 38 - 42
src/app/components/users/users.component.ts

@@ -1,88 +1,84 @@
-import { Component, ViewChild, OnInit } from '@angular/core';
-
-import {HttpClient} from '@angular/common/http';
-import { User } from 'src/app/models/user';
-import { UserService } from 'src/app/services/user.service';
-import {MatPaginator} from '@angular/material/paginator';
-import {MatSort} from '@angular/material/sort';
-import {MatTableDataSource} from '@angular/material/table';
-import Swal from 'sweetalert2';
+import { Component, ViewChild, OnInit } from "@angular/core";
 
+import { HttpClient } from "@angular/common/http";
+import { User } from "src/app/models/user";
+import { UserService } from "src/app/services/user.service";
+import { MatPaginator } from "@angular/material/paginator";
+import { MatSort } from "@angular/material/sort";
+import { MatTableDataSource } from "@angular/material/table";
+import Swal from "sweetalert2";
 
 @Component({
-  selector: 'app-users',
-  templateUrl: './users.component.html',
-  styleUrls: ['./users.component.scss']
+  selector: "app-users",
+  templateUrl: "./users.component.html",
+  styleUrls: ["./users.component.scss"]
 })
 export class UsersComponent implements OnInit {
+  title: string = "Usuarios";
 
-  title:string = "Usuarios";
- 
-  displayedColumns: string[] = ['email', 'first_name', 'last_name', 'role'];
+  displayedColumns: string[] = ["email", "first_name", "last_name", "role"];
   //displayedColumns: string[] = ['state'];
 
   listData: User[] = [];
-  listUsers:any;
+  listUsers: any;
   dataSource = new MatTableDataSource(this.listUsers);
 
   resultsLength = 0;
   isLoadingResults = true;
   isRateLimitReached = false;
 
-  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
-  @ViewChild(MatSort, {static: true}) sort: MatSort;
+  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
+  @ViewChild(MatSort, { static: true }) sort: MatSort;
   role_number: any;
 
-
   constructor(private userService: UserService) {
-
     Swal.fire({
       allowOutsideClick: false,
-      type: 'info',
-      text: 'Espere por favor...'
+      type: "info",
+      text: "Espere por favor..."
     });
     Swal.showLoading();
   }
 
   ngOnInit() {
-    this.userService.getAllUsers().subscribe(ans => {
-      this.listUsers = ans["data"]["users"];
-      this.dataSource.data = this.listUsers;
-      this.dataSource.paginator = this.paginator;
-      this.dataSource.sort = this.sort;
-    }, (err) => {
-      Swal.fire({
-        type: 'error',
-        title: 'Error en el servidor',
-        text: err.message
-      });
-    });
-
-    setTimeout(()=>{
+    this.userService.getAllUsers().subscribe(
+      ans => {
+        this.listUsers = ans["data"]["users"];
+        this.dataSource.data = this.listUsers;
+        this.dataSource.paginator = this.paginator;
+        this.dataSource.sort = this.sort;
+      },
+      err => {
+        Swal.fire({
+          type: "error",
+          title: "Error en el servidor",
+          text: err.message
+        });
+      }
+    );
+
+    setTimeout(() => {
       Swal.close();
     }, 1200);
-
   }
 
-  userType(userRole:any){
-    switch (+userRole){
+  userType(userRole: any) {
+    switch (+userRole) {
       case 0:
         return "Invitado";
       case 1:
         return "Usuario";
       case 2:
-        return "Administrador";      
+        return "Administrador";
       case 3:
         return "Super Admin";
     }
   }
 
-
   applyFilter(filterValue: string) {
     this.dataSource.filter = filterValue.trim().toLowerCase();
     if (this.dataSource.paginator) {
       this.dataSource.paginator.firstPage();
     }
   }
-
 }

+ 119 - 123
src/app/layouts/admin/admin.component.ts

@@ -1,161 +1,157 @@
-import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
-import { Location, LocationStrategy, PathLocationStrategy, PopStateEvent } from '@angular/common';
-import { filter, map } from 'rxjs/operators';
-import { Subscription } from 'rxjs/Subscription';
+import { Component, OnInit, ViewChild, AfterViewInit } from "@angular/core";
+import {
+  Location,
+  LocationStrategy,
+  PathLocationStrategy,
+  PopStateEvent
+} from "@angular/common";
+import { filter, map } from "rxjs/operators";
+import { Subscription } from "rxjs/Subscription";
 
 //import { NavbarComponent } from '../../components/navbar/navbar.component';
-import { Router, NavigationEnd, NavigationStart } from '@angular/router';
-import PerfectScrollbar from 'perfect-scrollbar';
+import { Router, NavigationEnd, NavigationStart } from "@angular/router";
 import * as $ from "jquery";
 
 @Component({
-  selector: 'app-admin',
-  templateUrl: './admin.component.html',
-  styleUrls: ['./admin.component.scss']
+  selector: "app-admin",
+  templateUrl: "./admin.component.html",
+  styleUrls: ["./admin.component.scss"]
 })
 export class AdminComponent implements OnInit {
   private _router: Subscription;
   private lastPoppedUrl: string;
   private yScrollStack: number[] = [];
 
-  constructor( public location: Location, private router: Router) {}
+  constructor(public location: Location, private router: Router) {}
 
   ngOnInit() {
-      const isWindows = navigator.platform.indexOf('Win') > -1 ? true : false;
-
-      if (isWindows && !document.getElementsByTagName('body')[0].classList.contains('sidebar-mini')) {
-          // if we are on windows OS we activate the perfectScrollbar function
-
-          document.getElementsByTagName('body')[0].classList.add('perfect-scrollbar-on');
-      } else {
-          document.getElementsByTagName('body')[0].classList.remove('perfect-scrollbar-off');
+    const isWindows = navigator.platform.indexOf("Win") > -1 ? true : false;
+
+    const elemMainPanel = <HTMLElement>document.querySelector(".main-panel");
+    const elemSidebar = <HTMLElement>(
+      document.querySelector(".sidebar .sidebar-wrapper")
+    );
+
+    this.location.subscribe((ev: PopStateEvent) => {
+      this.lastPoppedUrl = ev.url;
+    });
+    this.router.events.subscribe((event: any) => {
+      if (event instanceof NavigationStart) {
+        if (event.url != this.lastPoppedUrl)
+          this.yScrollStack.push(window.scrollY);
+      } else if (event instanceof NavigationEnd) {
+        if (event.url == this.lastPoppedUrl) {
+          this.lastPoppedUrl = undefined;
+          window.scrollTo(0, this.yScrollStack.pop());
+        } else window.scrollTo(0, 0);
       }
-      const elemMainPanel = <HTMLElement>document.querySelector('.main-panel');
-      const elemSidebar = <HTMLElement>document.querySelector('.sidebar .sidebar-wrapper');
-
-      this.location.subscribe((ev:PopStateEvent) => {
-          this.lastPoppedUrl = ev.url;
-      });
-       this.router.events.subscribe((event:any) => {
-          if (event instanceof NavigationStart) {
-             if (event.url != this.lastPoppedUrl)
-                 this.yScrollStack.push(window.scrollY);
-         } else if (event instanceof NavigationEnd) {
-             if (event.url == this.lastPoppedUrl) {
-                 this.lastPoppedUrl = undefined;
-                 window.scrollTo(0, this.yScrollStack.pop());
-             } else
-                 window.scrollTo(0, 0);
-         }
-      });
+    });
 
-      this._router = this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => {
-           elemMainPanel.scrollTop = 0;
-           elemSidebar.scrollTop = 0;
+    this._router = this.router.events
+      .pipe(filter(event => event instanceof NavigationEnd))
+      .subscribe((event: NavigationEnd) => {
+        elemMainPanel.scrollTop = 0;
+        elemSidebar.scrollTop = 0;
       });
-      if (window.matchMedia(`(min-width: 960px)`).matches && !this.isMac()) {
-          let ps = new PerfectScrollbar(elemMainPanel);
-          ps = new PerfectScrollbar(elemSidebar);
-      }
-
-      const window_width = $(window).width();
-      let $sidebar = $('.sidebar');
-      let $sidebar_responsive = $('body > .navbar-collapse');
-      let $sidebar_img_container = $sidebar.find('.sidebar-background');
-
 
-      if(window_width > 767){
-          if($('.fixed-plugin .dropdown').hasClass('show-dropdown')){
-              $('.fixed-plugin .dropdown').addClass('open');
-          }
+    const window_width = $(window).width();
+    let $sidebar = $(".sidebar");
+    let $sidebar_responsive = $("body > .navbar-collapse");
+    let $sidebar_img_container = $sidebar.find(".sidebar-background");
 
+    if (window_width > 767) {
+      if ($(".fixed-plugin .dropdown").hasClass("show-dropdown")) {
+        $(".fixed-plugin .dropdown").addClass("open");
       }
+    }
 
-      $('.fixed-plugin a').click(function(event){
-        // Alex if we click on switch, stop propagation of the event, so the dropdown will not be hide, otherwise we set the  section active
-          if($(this).hasClass('switch-trigger')){
-              if(event.stopPropagation){
-                  event.stopPropagation();
-              }
-              else if(window.event){
-                 window.event.cancelBubble = true;
-              }
-          }
-      });
-
-      $('.fixed-plugin .badge').click(function(){
-          let $full_page_background = $('.full-page-background');
-
-
-          $(this).siblings().removeClass('active');
-          $(this).addClass('active');
-
-          var new_color = $(this).data('color');
-
-          if($sidebar.length !== 0){
-              $sidebar.attr('data-color', new_color);
-          }
-
-          if($sidebar_responsive.length != 0){
-              $sidebar_responsive.attr('data-color',new_color);
-          }
-      });
-
-      $('.fixed-plugin .img-holder').click(function(){
-          let $full_page_background = $('.full-page-background');
+    $(".fixed-plugin a").click(function(event) {
+      // Alex if we click on switch, stop propagation of the event, so the dropdown will not be hide, otherwise we set the  section active
+      if ($(this).hasClass("switch-trigger")) {
+        if (event.stopPropagation) {
+          event.stopPropagation();
+        } else if (window.event) {
+          window.event.cancelBubble = true;
+        }
+      }
+    });
 
-          $(this).parent('li').siblings().removeClass('active');
-          $(this).parent('li').addClass('active');
+    $(".fixed-plugin .badge").click(function() {
+      let $full_page_background = $(".full-page-background");
 
+      $(this)
+        .siblings()
+        .removeClass("active");
+      $(this).addClass("active");
 
-          //var new_image = $(this).find("img").attr('src');
+      var new_color = $(this).data("color");
 
-          if($sidebar_img_container.length !=0 ){
-              $sidebar_img_container.fadeOut('fast', function(){
-                 //$sidebar_img_container.css('background-image','url("' + new_image + '")');
-                 $sidebar_img_container.fadeIn('fast');
-              });
-          }
+      if ($sidebar.length !== 0) {
+        $sidebar.attr("data-color", new_color);
+      }
 
-          if($full_page_background.length != 0){
+      if ($sidebar_responsive.length != 0) {
+        $sidebar_responsive.attr("data-color", new_color);
+      }
+    });
+
+    $(".fixed-plugin .img-holder").click(function() {
+      let $full_page_background = $(".full-page-background");
+
+      $(this)
+        .parent("li")
+        .siblings()
+        .removeClass("active");
+      $(this)
+        .parent("li")
+        .addClass("active");
+
+      //var new_image = $(this).find("img").attr('src');
+
+      if ($sidebar_img_container.length != 0) {
+        $sidebar_img_container.fadeOut("fast", function() {
+          //$sidebar_img_container.css('background-image','url("' + new_image + '")');
+          $sidebar_img_container.fadeIn("fast");
+        });
+      }
 
-              $full_page_background.fadeOut('fast', function(){
-                 //$full_page_background.css('background-image','url("' + new_image + '")');
-                 $full_page_background.fadeIn('fast');
-              });
-          }
+      if ($full_page_background.length != 0) {
+        $full_page_background.fadeOut("fast", function() {
+          //$full_page_background.css('background-image','url("' + new_image + '")');
+          $full_page_background.fadeIn("fast");
+        });
+      }
 
-          if($sidebar_responsive.length != 0){
-              //$sidebar_responsive.css('background-image','url("' + new_image + '")');
-          }
-      });
+      if ($sidebar_responsive.length != 0) {
+        //$sidebar_responsive.css('background-image','url("' + new_image + '")');
+      }
+    });
   }
   ngAfterViewInit() {
-      this.runOnRouteChange();
+    this.runOnRouteChange();
   }
-  isMaps(path){
-      var titlee = this.location.prepareExternalUrl(this.location.path());
-      titlee = titlee.slice( 1 );
-      if(path == titlee){
-          return false;
-      }
-      else {
-          return true;
-      }
+  isMaps(path) {
+    var titlee = this.location.prepareExternalUrl(this.location.path());
+    titlee = titlee.slice(1);
+    if (path == titlee) {
+      return false;
+    } else {
+      return true;
+    }
   }
   runOnRouteChange(): void {
     if (window.matchMedia(`(min-width: 960px)`).matches && !this.isMac()) {
-      const elemMainPanel = <HTMLElement>document.querySelector('.main-panel');
-      const ps = new PerfectScrollbar(elemMainPanel);
-      ps.update();
+      const elemMainPanel = <HTMLElement>document.querySelector(".main-panel");
     }
   }
   isMac(): boolean {
-      let bool = false;
-      if (navigator.platform.toUpperCase().indexOf('MAC') >= 0 || navigator.platform.toUpperCase().indexOf('IPAD') >= 0) {
-          bool = true;
-      }
-      return bool;
+    let bool = false;
+    if (
+      navigator.platform.toUpperCase().indexOf("MAC") >= 0 ||
+      navigator.platform.toUpperCase().indexOf("IPAD") >= 0
+    ) {
+      bool = true;
+    }
+    return bool;
   }
-
 }

+ 28 - 34
src/app/layouts/admin/admin.module.ts

@@ -1,50 +1,46 @@
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { NgModule } from '@angular/core';
-import { RouterModule } from '@angular/router';
-import { CommonModule } from '@angular/common';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
+import { NgModule } from "@angular/core";
+import { RouterModule } from "@angular/router";
+import { CommonModule } from "@angular/common";
+import { FormsModule, ReactiveFormsModule } from "@angular/forms";
 import { LeafletModule } from "@asymmetrik/ngx-leaflet";
-import { ChartsModule } from 'ng2-charts';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { AngularMyDatePickerModule } from 'angular-mydatepicker';
+import { ChartsModule } from "ng2-charts";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { AngularMyDatePickerModule } from "angular-mydatepicker";
 
-import { AdminLayoutRoutes } from './admin.routing';
-import { DashboardComponent } from '../../components/dashboard/dashboard.component';
-import { ProfileComponent } from '../../components/profile/profile.component';
-import { AssetsComponent } from '../../components/assets/assets.component';
-import { OrganizationsComponent } from '../../components/organizations/organizations.component';
-import { OrganizationComponent } from '../../components/organizations/organization/organization.component';
-import { NewOrganizationComponent } from '../../components/organizations/new-organization/new-organization.component';
-import { EditOrganizationComponent } from '../../components/organizations/edit-organization/edit-organization.component';
-import { PlantsComponent } from '@app/components/plants/plants.component';
-import { EditPlantComponent } from '@app/components/plants/edit-plant/edit-plant.component';
-import { NewPlantComponent } from '@app/components/plants/new-plant/new-plant.component';
-import { PlantComponent } from '@app/components/plants/plant/plant.component';
-import { UsersComponent } from '@app/components/users/users.component';
-import { NewUserComponent } from '@app/components/users/new-user/new-user.component';
+import { AdminLayoutRoutes } from "./admin.routing";
+import { DashboardComponent } from "../../components/dashboard/dashboard.component";
+import { ProfileComponent } from "../../components/profile/profile.component";
+import { AssetsComponent } from "../../components/assets/assets.component";
+import { OrganizationsComponent } from "../../components/organizations/organizations.component";
+import { OrganizationComponent } from "../../components/organizations/organization/organization.component";
+import { NewOrganizationComponent } from "../../components/organizations/new-organization/new-organization.component";
+import { EditOrganizationComponent } from "../../components/organizations/edit-organization/edit-organization.component";
+import { PlantsComponent } from "@app/components/plants/plants.component";
+import { EditPlantComponent } from "@app/components/plants/edit-plant/edit-plant.component";
+import { NewPlantComponent } from "@app/components/plants/new-plant/new-plant.component";
+import { PlantComponent } from "@app/components/plants/plant/plant.component";
+import { UsersComponent } from "@app/components/users/users.component";
+import { NewUserComponent } from "@app/components/users/new-user/new-user.component";
 
+import { PluginsModule } from "../../components/plugins/plugins.module";
 
-import { PluginsModule } from '../../components/plugins/plugins.module';
-
-import { MatTableExporterModule } from 'mat-table-exporter';
+import { MatTableExporterModule } from "mat-table-exporter";
 import {
   MatButtonModule,
   MatInputModule,
   MatRippleModule,
   MatFormFieldModule,
-  MatTooltipModule,
   MatSelectModule,
   MatExpansionModule,
   MatTableModule,
   MatPaginatorModule,
   MatProgressSpinnerModule,
   MatSortModule
-
-} from '@angular/material';
-import { MatPasswordStrengthModule } from '@angular-material-extensions/password-strength';
-import { BreadcrumbModule, IconsModule } from 'angular-bootstrap-md'
-import { TermsComponent } from '@app/components/terms/terms.component';
-
+} from "@angular/material";
+import { MatPasswordStrengthModule } from "@angular-material-extensions/password-strength";
+import { BreadcrumbModule, IconsModule } from "angular-bootstrap-md";
+import { TermsComponent } from "@app/components/terms/terms.component";
 
 @NgModule({
   imports: [
@@ -57,7 +53,6 @@ import { TermsComponent } from '@app/components/terms/terms.component';
     MatFormFieldModule,
     MatInputModule,
     MatSelectModule,
-    MatTooltipModule,
     MatExpansionModule,
     MatTableModule,
     MatPaginatorModule,
@@ -88,5 +83,4 @@ import { TermsComponent } from '@app/components/terms/terms.component';
     TermsComponent
   ]
 })
-
 export class AdminModule {}

+ 69 - 52
src/app/services/logs.service.ts

@@ -1,80 +1,97 @@
-import { Injectable } from '@angular/core';
-import { Organization } from '../models/organization';
-import { Plant } from '../models/plant';
+import { Injectable } from "@angular/core";
+import { Organization } from "../models/organization";
+import { Plant } from "../models/plant";
 
-import { of as observableOf, Observable, throwError } from 'rxjs';
-import { HttpClient, HttpHeaders } from '@angular/common/http';
-import { retry, catchError, map, timeout } from 'rxjs/operators';
+import { of as observableOf, Observable, throwError } from "rxjs";
+import { HttpClient, HttpHeaders } from "@angular/common/http";
+import { retry, catchError, map, timeout } from "rxjs/operators";
 
-import { environment } from '@environments/environment';
+import { environment } from "@environments/environment";
 
 @Injectable({
-  providedIn: 'root'
+  providedIn: "root"
 })
 export class LogsService {
+  time: number = 6000;
 
-  time:number = 6000;
+  constructor(private http: HttpClient) {}
 
-  constructor(private http: HttpClient) {
+  getEnergyProducedByParams(id: string, interval: string, date: string) {
+    return this.http
+      .get(
+        `${environment.productionApiUrl}/asset/${id}/energy-produced/${interval}/${date}`
+      )
+      .pipe(
+        timeout(this.time),
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
   }
 
-  getEnergyProducedByParams(id:string, interval:string, date:string) {
-    return this.http.get(`${environment.productionApiUrl}/asset/${id}/energy-produced/${interval}/${date}`)
-    .pipe(
-      timeout(this.time),
-      map(response =>{
-        return response;
-      }),
-      catchError(this.errorHandl)
-    )
+  getEnergySavingsProducedByAsset(id: string, interval: string, date: string) {
+    return this.http
+      .get(
+        `${environment.productionApiUrl}/asset/${id}/historical-savings/${interval}/${date}`
+      )
+      .pipe(
+        timeout(this.time),
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
   }
 
-
-  getEnergySavingsProducedByAsset(id:string, interval:string, date:string) {
-    return this.http.get(`${environment.productionApiUrl}/asset/${id}/historical-savings/${interval}/${date}`)
-    .pipe(
-      timeout(this.time),
-      map(response => {
-        return response;
-      }),
-      catchError(this.errorHandl)
-    )
+  getEnergySummaryByAsset(id: string) {
+    return this.http
+      .get(`${environment.productionApiUrl}/asset/${id}/energy-stats`)
+      .pipe(
+        timeout(this.time),
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
   }
-  
 
-  getEnergySummaryByAsset(id:string){
-    return this.http.get(`${environment.productionApiUrl}/asset/${id}/energy-stats`)
-    .pipe(
-      timeout(this.time),
-      map(response =>{
-        return response;
-      }),
-      catchError(this.errorHandl)
-    )
+  getAssetEnviromentalStats(id: string) {
+    return this.http
+      .get(`${environment.productionApiUrl}/asset/${id}/environmentals`)
+      .pipe(
+        timeout(this.time),
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
   }
 
-  getAssetEnviromentalStats(id:string){
-    return this.http.get(`${environment.productionApiUrl}/asset/${id}/environmentals`)
-    .pipe(
-      timeout(this.time),
-      map(response =>{
-        return response;
-      }),
-      catchError(this.errorHandl)
-    )
+  getAssetCertificates(id: string) {
+    return this.http
+      .get(
+        `${environment.productionApiUrl}/asset/${id}/origin-certificates-info`
+      )
+      .pipe(
+        timeout(this.time),
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
   }
 
   //if(error.error instanceof ErrorEvent) {
   errorHandl(error) {
-    let errorMessage = '';
-    if(error.error) {
+    let errorMessage = "";
+    if (error.error) {
       // Get client-side error
       errorMessage = error.error;
     } else {
       // Get server-side error
-      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;      
+      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
     }
     return throwError(errorMessage);
   }
-  
 }

BIN
src/assets/img/_new_logo.png


BIN
src/assets/img/medal.png


+ 0 - 69
src/assets/img/sound.svg

@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 469.333 469.333" style="enable-background:new 0 0 469.333 469.333;" xml:space="preserve">
-<g>
-	<path style="fill:#F44336;" d="M10.667,298.667C4.779,298.667,0,293.888,0,288V181.333c0-5.888,4.779-10.667,10.667-10.667
-		s10.667,4.779,10.667,10.667V288C21.333,293.888,16.555,298.667,10.667,298.667z"/>
-	<path style="fill:#F44336;" d="M74.667,384C68.779,384,64,379.221,64,373.333V96c0-5.888,4.779-10.667,10.667-10.667
-		S85.333,90.112,85.333,96v277.333C85.333,379.221,80.555,384,74.667,384z"/>
-	<path style="fill:#F44336;" d="M138.667,469.333c-5.888,0-10.667-4.779-10.667-10.667v-448C128,4.779,132.779,0,138.667,0
-		s10.667,4.779,10.667,10.667v448C149.333,464.555,144.555,469.333,138.667,469.333z"/>
-	<path style="fill:#F44336;" d="M202.667,448c-5.888,0-10.667-4.779-10.667-10.667V32c0-5.888,4.779-10.667,10.667-10.667
-		S213.333,26.112,213.333,32v405.333C213.333,443.221,208.555,448,202.667,448z"/>
-	<path style="fill:#F44336;" d="M266.667,362.667c-5.888,0-10.667-4.779-10.667-10.667V117.333c0-5.888,4.779-10.667,10.667-10.667
-		s10.667,4.779,10.667,10.667V352C277.333,357.888,272.555,362.667,266.667,362.667z"/>
-	<path style="fill:#F44336;" d="M330.667,448c-5.888,0-10.667-4.779-10.667-10.667V32c0-5.888,4.779-10.667,10.667-10.667
-		c5.888,0,10.667,4.779,10.667,10.667v405.333C341.333,443.221,336.555,448,330.667,448z"/>
-	<path style="fill:#F44336;" d="M394.667,362.667c-5.888,0-10.667-4.779-10.667-10.667V117.333c0-5.888,4.779-10.667,10.667-10.667
-		c5.888,0,10.667,4.779,10.667,10.667V352C405.333,357.888,400.555,362.667,394.667,362.667z"/>
-	<path style="fill:#F44336;" d="M458.667,298.667c-5.888,0-10.667-4.779-10.667-10.667V181.333c0-5.888,4.779-10.667,10.667-10.667
-		c5.888,0,10.667,4.779,10.667,10.667V288C469.333,293.888,464.555,298.667,458.667,298.667z"/>
-</g>
-<path d="M10.667,298.667C4.779,298.667,0,293.888,0,288V181.333c0-5.888,4.779-10.667,10.667-10.667s10.667,4.779,10.667,10.667V288
-	C21.333,293.888,16.555,298.667,10.667,298.667z"/>
-<path d="M74.667,384C68.779,384,64,379.221,64,373.333V96c0-5.888,4.779-10.667,10.667-10.667S85.333,90.112,85.333,96v277.333
-	C85.333,379.221,80.555,384,74.667,384z"/>
-<path d="M138.667,469.333c-5.888,0-10.667-4.779-10.667-10.667v-448C128,4.779,132.779,0,138.667,0s10.667,4.779,10.667,10.667v448
-	C149.333,464.555,144.555,469.333,138.667,469.333z"/>
-<path d="M202.667,448c-5.888,0-10.667-4.779-10.667-10.667V32c0-5.888,4.779-10.667,10.667-10.667S213.333,26.112,213.333,32
-	v405.333C213.333,443.221,208.555,448,202.667,448z"/>
-<path d="M266.667,362.667c-5.888,0-10.667-4.779-10.667-10.667V117.333c0-5.888,4.779-10.667,10.667-10.667
-	s10.667,4.779,10.667,10.667V352C277.333,357.888,272.555,362.667,266.667,362.667z"/>
-<path d="M330.667,448c-5.888,0-10.667-4.779-10.667-10.667V32c0-5.888,4.779-10.667,10.667-10.667
-	c5.888,0,10.667,4.779,10.667,10.667v405.333C341.333,443.221,336.555,448,330.667,448z"/>
-<path d="M394.667,362.667c-5.888,0-10.667-4.779-10.667-10.667V117.333c0-5.888,4.779-10.667,10.667-10.667
-	c5.888,0,10.667,4.779,10.667,10.667V352C405.333,357.888,400.555,362.667,394.667,362.667z"/>
-<path d="M458.667,298.667c-5.888,0-10.667-4.779-10.667-10.667V181.333c0-5.888,4.779-10.667,10.667-10.667
-	c5.888,0,10.667,4.779,10.667,10.667V288C469.333,293.888,464.555,298.667,458.667,298.667z"/>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-</svg>

BIN
src/assets/img/tim_80x80.png


+ 455 - 454
src/assets/scss/core/_sidebar-and-main-panel.scss

@@ -1,538 +1,539 @@
-.wrapper{
-    position: relative;
-    top: 0;
-    height: 100vh;
+.wrapper {
+  position: relative;
+  top: 0;
+  height: 100vh;
 }
 
 .sidebar {
-    position: fixed;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    z-index: 2;
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 2;
+  width: 260px;
+  background: $white-color;
+  @include shadow-big();
+
+  .caret {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    margin-left: 2px;
+    vertical-align: middle;
+    border-top: 4px dashed;
+    border-top: 4px solid\9;
+    border-right: 4px solid transparent;
+    border-left: 4px solid transparent;
+  }
+
+  &[data-background-color="black"] {
+    background-color: #191919;
+  }
+  .logo-img {
+    width: 35px;
+    display: block;
+    max-height: 30px;
+    margin-left: 13px;
+    margin-right: 15px;
+
+    img {
+      width: 35px;
+      top: 33px;
+      position: absolute;
+    }
+  }
+  .sidebar-wrapper {
+    position: relative;
+    height: calc(100vh - 75px);
+    overflow: auto;
     width: 260px;
-    background: $white-color;
-    @include shadow-big();
+    z-index: 4;
 
-    .caret{
-      display: inline-block;
-      width: 0;
-      height: 0;
-      margin-left: 2px;
-      vertical-align: middle;
-      border-top: 4px dashed;
-      border-top: 4px solid\9;
-      border-right: 4px solid transparent;
-      border-left: 4px solid transparent;
-    }
+    padding-bottom: 30px;
 
-    &[data-background-color="black"]{
-        background-color: #191919;
+    .dropdown .dropdown-backdrop {
+      display: none !important;
     }
-    .logo-img{
-        width: 35px;
-        display: block;
-        max-height: 30px;
-        margin-left: 13px;
-        margin-right: 15px;
-
-        img{
-            width: 35px;
-            top: 33px;
-            position: absolute;
-        }
-    }
-    .sidebar-wrapper{
-        position: relative;
-        height: calc(100vh - 75px);
-        overflow: auto;
-        width: 260px;
-        z-index: 4;
 
-        padding-bottom: 30px;
+    .navbar-form {
+      border: none;
+      box-shadow: none;
 
-        .dropdown .dropdown-backdrop{
-            display: none !important;
-        }
+      .input-group {
+        font-size: 1.7em;
+        height: 36px;
+        width: 78%;
+        padding-left: 17px;
+      }
+    }
 
-        .navbar-form{
-            border: none;
-            box-shadow: none;
+    > .nav,
+    .user .user-info {
+      [data-toggle="collapse"] ~ div > ul > li > a {
+        span {
+          display: inline-block;
+          @extend .animation-transition-general;
+        }
 
-          .input-group {
-            font-size: 1.7em;
-            height: 36px;
-            width: 78%;
-            padding-left: 17px;
-          }
+        .sidebar-normal {
+          margin: 0;
+          position: relative;
+          transform: translateX(0px);
+          opacity: 1;
+          white-space: nowrap;
+          display: block;
         }
 
-        > .nav,
-        .user .user-info{
-            [data-toggle="collapse"] ~ div > ul > li > a{
-                span{
-                    display: inline-block;
-                    @extend .animation-transition-general;
-                }
-
-                .sidebar-normal{
-                    margin: 0;
-                    position: relative;
-                    transform: translateX(0px);
-                    opacity: 1;
-                    white-space: nowrap;
-                    display: block;
-
-                }
-
-                .sidebar-mini{
-                    text-transform: uppercase;
-                    width: 30px;
-                    margin-right: 15px;
-                    text-align: center;
-                    letter-spacing: 1px;
-                    position: relative;
-                    float: left;
-                    display: inherit;
-                }
-
-                i{
-                    font-size: 17px;
-                    line-height: 20px;
-                    width: 26px;
-                }
-            }
+        .sidebar-mini {
+          text-transform: uppercase;
+          width: 30px;
+          margin-right: 15px;
+          text-align: center;
+          letter-spacing: 1px;
+          position: relative;
+          float: left;
+          display: inherit;
         }
-    }
 
-    .logo-tim{
-        border-radius: 50%;
-        border: 1px solid #333;
-        display: block;
-        height: 61px;
-        width: 61px;
-        float: left;
-        overflow: hidden;
-
-        img{
-            width: 60px;
-            height: 60px;
+        i {
+          font-size: 17px;
+          line-height: 20px;
+          width: 26px;
         }
+      }
     }
+  }
 
-    .nav{
-        margin-top: 20px;
-        display: block;
+  .logo-tim {
+    border-radius: 50%;
+    border: 1px solid #333;
+    display: block;
+    height: 61px;
+    width: 61px;
+    float: left;
+    overflow: hidden;
 
-        .caret{
-            margin-top: 13px;
-            position: absolute;
-            right: 6px;
-        }
+    img {
+      width: 60px;
+      height: 60px;
+    }
+  }
 
-        li{
-            > a, span{
-              &:hover,
-              &:focus{
-                  background-color: transparent;
-                  outline: none;
-              }
-            }
-
-            &:first-child > a{
-                margin: 0 15px;
-            }
-
-            &:hover > a,
-            & .dropdown-menu a:hover,
-            & .dropdown-menu a:focus,
-            &.active > [data-toggle="collapse"]{
-                background-color: rgba(200, 200, 200, 0.2);
-                color: $black-color;
-                box-shadow: none;
-            }
-
-            &.active > [data-toggle="collapse"]{
-                i{
-                    color: #a9afbb;
-                }
-            }
-
-            &.active > a,
-            &.active > a i{
-                color: $white-color;
-            }
-
-            &.separator{
-                margin: 15px 0;
-
-                &:after{
-                    width: calc(100% - 30px);
-                    content: "";
-                    position: absolute;
-                    height: 1px;
-                    left: 15px;
-                    background-color: rgba(180,180,180, .3);
-                }
-
-                & + li {
-                    margin-top: 31px;
-                }
-            }
-        }
+  .nav {
+    margin-top: 20px;
+    display: block;
 
-        p{
-            margin: 0;
-            line-height: 30px;
-            font-size: 14px;
-            position: relative;
-            display: block;
-            height: auto;
-            white-space: nowrap;
-        }
+    .caret {
+      margin-top: 13px;
+      position: absolute;
+      right: 6px;
+    }
 
-        i{
-            font-size: 24px;
-            float: left;
-            margin-right: 15px;
-            line-height: 30px;
-            width: 30px;
-            text-align: center;
-            color: #a9afbb;
+    li {
+      > a,
+      span {
+        &:hover,
+        &:focus {
+          background-color: transparent;
+          outline: none;
         }
-    }
+      }
 
-    .nav li a,
-    .nav li .dropdown-menu a{
-          margin: 10px 15px 0;
-          border-radius: $border-radius-base;
-          color: $black-color;
-          padding-left: 10px;
-          padding-right: 10px;
-          text-transform: capitalize;
-          font-size: $font-paragraph - 1;
-          padding: 10px 12px;
-    }
+      &:first-child > a {
+        margin: 0 15px;
+      }
 
+      &:hover > a,
+      & .dropdown-menu a:hover,
+      & .dropdown-menu a:focus,
+      &.active > [data-toggle="collapse"] {
+        background-color: rgba(200, 200, 200, 0.2);
+        color: $black-color;
+        box-shadow: none;
+      }
 
-    .sidebar-background{
-        position: absolute;
-        z-index: 1;
-        height: 100%;
-        width: 100%;
-        display: block;
-        top: 0;
-        left: 0;
-        background-size: cover;
-        background-position: center center;
-
-        &:after{
-            position: absolute;
-            z-index: 3;
-            width: 100%;
-            height: 100%;
-            content: "";
-            display: block;
-            background: #FFFFFF;
-            opacity: .93;
+      &.active > [data-toggle="collapse"] {
+        i {
+          color: #a9afbb;
         }
-    }
+      }
 
-    .logo{
-        padding: 15px 0px;
-        margin: 0;
-        display: block;
-        position: relative;
-        z-index: 4;
-
-        &:after{
-            content: '';
-            position: absolute;
-            bottom: 0;
-            right: 15px;
-            height: 1px;
-            width: calc(100% - 30px);
-            background-color: rgba(180,180,180, .3);
+      &.active > a,
+      &.active > a i {
+        color: $white-color;
+      }
 
-        }
+      &.separator {
+        margin: 15px 0;
 
-        p{
-            float: left;
-            font-size: 20px;
-            margin: 10px 10px;
-            color: $white-color;
-            line-height: 20px;
-        }
-
-        .simple-text{
-            text-transform: uppercase;
-            padding: $padding-small-vertical $padding-zero;
-            display: inline-block;
-            font-size: 18px;
-            color: $black-color;
-            white-space: nowrap;
-            font-weight: $font-weight-default;
-            line-height: 30px;
-            overflow: hidden;
-            text-align: center;
-            display: block;
+        &:after {
+          width: calc(100% - 30px);
+          content: "";
+          position: absolute;
+          height: 1px;
+          left: 15px;
+          background-color: rgba(180, 180, 180, 0.3);
         }
-    }
 
-    .logo-tim{
-        border-radius: 50%;
-        border: 1px solid #333;
-        display: block;
-        height: 61px;
-        width: 61px;
-        float: left;
-        overflow: hidden;
-
-        img{
-            width: 60px;
-            height: 60px;
+        & + li {
+          margin-top: 31px;
         }
+      }
     }
 
+    p {
+      margin: 0;
+      line-height: 30px;
+      font-size: 14px;
+      position: relative;
+      display: block;
+      height: auto;
+      white-space: nowrap;
+    }
+
+    i {
+      font-size: 24px;
+      float: left;
+      margin-right: 15px;
+      line-height: 30px;
+      width: 30px;
+      text-align: center;
+      color: #a9afbb;
+    }
+  }
+
+  .nav li a,
+  .nav li .dropdown-menu a {
+    margin: 10px 15px 0;
+    border-radius: $border-radius-base;
+    color: $black-color;
+    padding-left: 10px;
+    padding-right: 10px;
+    text-transform: capitalize;
+    font-size: $font-paragraph - 1;
+    padding: 10px 12px;
+  }
+
+  .sidebar-background {
+    position: absolute;
+    z-index: 1;
+    height: 100%;
+    width: 100%;
+    display: block;
+    top: 0;
+    left: 0;
+    background-size: cover;
+    background-position: center center;
+
+    &:after {
+      position: absolute;
+      z-index: 3;
+      width: 100%;
+      height: 100%;
+      content: "";
+      display: block;
+      background: #ffffff;
+      opacity: 0.93;
+    }
+  }
+
+  .logo {
+    padding: 15px 0px;
+    margin: 0;
+    display: block;
+    position: relative;
+    z-index: 4;
 
-    &[data-background-color="black"]{
-        @include sidebar-background-color($gray-base, $white-color);
-
-        .nav li .dropdown-menu .dropdown-item{
-          color: $white-color;
-        }
+    &:after {
+      content: "";
+      position: absolute;
+      bottom: 0;
+      right: 15px;
+      height: 1px;
+      width: calc(100% - 30px);
+      background-color: rgba(180, 180, 180, 0.3);
     }
 
-    &[data-color="purple"]{
-        @include set-background-color-button($brand-primary);
-    }
-    &[data-color="azure"]{
-        @include set-background-color-button($brand-info);
-    }
-    &[data-color="green"]{
-        @include set-background-color-button($brand-success);
-    }
-    &[data-color="orange"]{
-        @include set-background-color-button($brand-warning);
-    }
-    &[data-color="danger"]{
-        @include set-background-color-button($brand-danger);
-    }
-    &[data-color="rose"]{
-        @include set-background-color-button($brand-rose);
-    }
-    &[data-color="black"]{
-      @include set-background-color-button($black)
-    }
-    &[data-color="gray"]{
-      @include set-background-color-button($gray-custom)
-    }
-    &[data-color="yellow"]{
-      @include set-background-color-button($yellow-custom)
-    }
-    &[data-color="blue"]{
-      @include set-background-color-button($blue-custom)
-    }
-    &[data-color="white"]{
-        @include set-background-color-button($white-color);
-        @include sidebar-active-color($black-color);
+    p {
+      float: left;
+      font-size: 20px;
+      margin: 10px 10px;
+      color: $white-color;
+      line-height: 20px;
     }
 
-    &[data-background-color="gray"]{
-        @include sidebar-background-color($gray-custom, $white-color);
-
-        .user,
-        .logo,
-        .nav li.separator{
-            &:after{
-                background-color: rgba(255,255,255, .3);
-            }
-        }
-
-        .nav{
-            li:hover:not(.active) > a,
-            li.active > [data-toggle="collapse"]{
-                background-color: rgba(255, 255, 255, 0.1);
-            }
-        }
+    .simple-text {
+      text-transform: uppercase;
+      padding: $padding-small-vertical $padding-zero;
+      display: inline-block;
+      font-size: 18px;
+      color: $black-color;
+      white-space: nowrap;
+      font-weight: $font-weight-default;
+      line-height: 30px;
+      overflow: hidden;
+      text-align: center;
+      display: block;
+    }
+  }
+
+  .logo-tim {
+    border-radius: 50%;
+    border: 1px solid #333;
+    display: block;
+    height: 61px;
+    width: 61px;
+    float: left;
+    overflow: hidden;
+
+    img {
+      width: 60px;
+      height: 60px;
+    }
+  }
+
+  &[data-background-color="black"] {
+    @include sidebar-background-color($gray-base, $white-color);
+
+    .nav li .dropdown-menu .dropdown-item {
+      color: $white-color;
+    }
+  }
+
+  &[data-color="purple"] {
+    @include set-background-color-button($brand-primary);
+  }
+  &[data-color="azure"] {
+    @include set-background-color-button($brand-info);
+  }
+  &[data-color="green"] {
+    @include set-background-color-button($brand-success);
+  }
+  &[data-color="orange"] {
+    @include set-background-color-button($brand-warning);
+  }
+  &[data-color="danger"] {
+    @include set-background-color-button($brand-danger);
+  }
+  &[data-color="rose"] {
+    @include set-background-color-button($brand-rose);
+  }
+  &[data-color="black"] {
+    @include set-background-color-button($black);
+  }
+  &[data-color="gray"] {
+    @include set-background-color-button($gray-custom);
+  }
+  &[data-color="yellow"] {
+    @include set-background-color-button($yellow-custom);
+  }
+  &[data-color="blue"] {
+    @include set-background-color-button($blue-custom);
+  }
+  &[data-color="white"] {
+    @include set-background-color-button($white-color);
+    @include sidebar-active-color($black-color);
+  }
+
+  &[data-background-color="gray"] {
+    @include sidebar-background-color($gray-custom, $white-color);
+
+    .user,
+    .logo,
+    .nav li.separator {
+      &:after {
+        background-color: rgba(255, 255, 255, 0.3);
+      }
     }
 
-    &[data-image]:after,
-    &.has-image:after{
-        opacity: .77;
+    .nav {
+      li:hover:not(.active) > a,
+      li.active > [data-toggle="collapse"] {
+        background-color: rgba(255, 255, 255, 0.1);
+      }
     }
+  }
 
-    &[data-background-color="red"]{
-        @include sidebar-background-color($brand-danger, $white-color);
+  &[data-image]:after,
+  &.has-image:after {
+    opacity: 0.77;
+  }
 
-        .user,
-        .logo,
-        .nav li.separator{
-            &:after{
-                background-color: rgba(255,255,255, .3);
-            }
-        }
+  &[data-background-color="red"] {
+    @include sidebar-background-color($brand-danger, $white-color);
 
-        .nav{
-            li:hover:not(.active) > a,
-            li.active > [data-toggle="collapse"]{
-                background-color: rgba(255, 255, 255, 0.1);
-            }
-        }
+    .user,
+    .logo,
+    .nav li.separator {
+      &:after {
+        background-color: rgba(255, 255, 255, 0.3);
+      }
     }
 
-    &[data-image]:after,
-    &.has-image:after{
-        opacity: .77;
+    .nav {
+      li:hover:not(.active) > a,
+      li.active > [data-toggle="collapse"] {
+        background-color: rgba(255, 255, 255, 0.1);
+      }
     }
+  }
+
+  &[data-image]:after,
+  &.has-image:after {
+    opacity: 0.77;
+  }
 }
 
-.off-canvas-sidebar .navbar-collapse{
-    .nav {
-        > li > a,
-        > li > a:hover{
-            color: $white-color;
-            margin: 0 15px;
-        }
+.off-canvas-sidebar .navbar-collapse {
+  .nav {
+    > li > a,
+    > li > a:hover {
+      color: $white-color;
+      margin: 0 15px;
+    }
 
-        > li > a:focus,
-        > li > a:hover{
-            background: rgba(200, 200, 200, 0.2);
-        }
+    > li > a:focus,
+    > li > a:hover {
+      background: rgba(200, 200, 200, 0.2);
     }
+  }
 }
 
+.main-panel {
+  position: relative;
+  float: right;
+  width: $sidebar-width;
+  @include transition(0.33s, cubic-bezier(0.685, 0.0473, 0.346, 1));
 
-.main-panel{
-    position: relative;
-    float: right;
-    width: $sidebar-width;
-    @include transition (0.33s, cubic-bezier(0.685, 0.0473, 0.346, 1));
-
-     .main-content{
-        margin-top: 30px;
-        padding: 20px 10px;
-        min-height: calc(100vh - 123px);
-    }
+  .main-content {
+    margin-top: 30px;
+    padding: 20px 10px;
+    min-height: calc(100vh - 123px);
+  }
 
-     .footer{
-        border-top: 1px solid #e7e7e7;
-    }
+  .footer {
+    border-top: 1px solid #e7e7e7;
+  }
 
-     .navbar{
-        margin-bottom: 0;
-    }
+  .navbar {
+    margin-bottom: 0;
+  }
 
-    .header{
-        margin-bottom: 30px;
+  .header {
+    margin-bottom: 30px;
 
-        .title{
-            margin-top: 10px;
-            margin-bottom: 10px;
-        }
+    .title {
+      margin-top: 10px;
+      margin-bottom: 10px;
     }
+  }
 }
 
-.perfect-scrollbar-on{
-    .sidebar,
-    .main-panel{
-        height: 100%;
-        max-height: 100%;
-    }
-}
-
-
 .sidebar,
 .main-panel,
-.sidebar-wrapper{
-    -webkit-transition-property: top,bottom,width;
-    transition-property: top,bottom, width;
-    -webkit-transition-duration: .2s,.2s, .35s;
-    transition-duration: .2s,.2s, .35s;
-    -webkit-transition-timing-function: linear,linear,ease;
-    transition-timing-function: linear,linear,ease;
-    -webkit-overflow-scrolling: touch;
+.sidebar-wrapper {
+  -webkit-transition-property: top, bottom, width;
+  transition-property: top, bottom, width;
+  -webkit-transition-duration: 0.2s, 0.2s, 0.35s;
+  transition-duration: 0.2s, 0.2s, 0.35s;
+  -webkit-transition-timing-function: linear, linear, ease;
+  transition-timing-function: linear, linear, ease;
+  -webkit-overflow-scrolling: touch;
 }
 
-.visible-on-sidebar-regular{
-    display: inline-block !important;
+.visible-on-sidebar-regular {
+  display: inline-block !important;
 }
-.visible-on-sidebar-mini{
-    display: none !important;
+.visible-on-sidebar-mini {
+  display: none !important;
 }
 
 @media (min-width: 991px) {
-    .sidebar-mini{
-        .visible-on-sidebar-regular{
-            display: none !important;
-        }
-        .visible-on-sidebar-mini{
-            display: inline-block !important;
-        }
+  .sidebar-mini {
+    .visible-on-sidebar-regular {
+      display: none !important;
+    }
+    .visible-on-sidebar-mini {
+      display: inline-block !important;
+    }
 
-        .sidebar,
-        .sidebar .sidebar-wrapper{
-            width: 80px;
+    .sidebar,
+    .sidebar .sidebar-wrapper {
+      width: 80px;
+    }
+
+    .main-panel {
+      width: $sidebar-mini-width;
+    }
+
+    .sidebar {
+      display: block;
+      font-weight: 200;
+      z-index: 9999;
+
+      .logo {
+        a.logo-normal {
+          opacity: 0;
+          @include transform-translate-x(-25px);
         }
+      }
 
-        .main-panel{
-            width: $sidebar-mini-width;
+      .sidebar-wrapper {
+        > .nav [data-toggle="collapse"] ~ div > ul > li > a .sidebar-normal,
+        .user
+          .user-info
+          [data-toggle="collapse"]
+          ~ div
+          > ul
+          > li
+          > a
+          .sidebar-normal,
+        .user .user-info > a > span,
+        > .nav li > a p {
+          @include transform-translate-x(-25px);
+          opacity: 0;
         }
+      }
+    }
+
+    .sidebar:hover {
+      width: 260px;
 
-        .sidebar{
-            display: block;
-            font-weight: 200;
-            z-index: 9999;
-
-            .logo{
-                a.logo-normal{
-                    opacity: 0;
-                    @include transform-translate-x(-25px);
-                }
-            }
-
-            .sidebar-wrapper{
-                > .nav [data-toggle="collapse"] ~ div > ul > li > a .sidebar-normal,
-                .user .user-info [data-toggle="collapse"] ~ div > ul > li > a .sidebar-normal,
-                .user .user-info > a > span,
-                > .nav li > a p{
-                    @include transform-translate-x(-25px);
-                    opacity: 0;
-                }
-            }
+      .logo {
+        a.logo-normal {
+          opacity: 1;
+          @include transform-translate-x(0px);
         }
+      }
+
+      .sidebar-wrapper {
+        width: 260px;
 
-        .sidebar:hover{
-            width: 260px;
-
-            .logo{
-                a.logo-normal{
-                    opacity: 1;
-                    @include transform-translate-x(0px);
-                }
-            }
-
-            .sidebar-wrapper{
-                width: 260px;
-
-                > .nav li > a p,
-                > .nav [data-toggle="collapse"] ~ div > ul > li > a .sidebar-normal,
-                .user .user-info [data-toggle="collapse"] ~ div > ul > li > a .sidebar-normal,
-                .user .user-info > a > span{
-                    @include transform-translate-x(0px);
-                    opacity: 1;
-                }
-            }
+        > .nav li > a p,
+        > .nav [data-toggle="collapse"] ~ div > ul > li > a .sidebar-normal,
+        .user
+          .user-info
+          [data-toggle="collapse"]
+          ~ div
+          > ul
+          > li
+          > a
+          .sidebar-normal,
+        .user .user-info > a > span {
+          @include transform-translate-x(0px);
+          opacity: 1;
         }
+      }
     }
+  }
 
-    .sidebar {
-      .nav .nav-item {
-        &.active-pro {
-          position: absolute;
-          width: 100%;
-          bottom: 13px;
-        }
+  .sidebar {
+    .nav .nav-item {
+      &.active-pro {
+        position: absolute;
+        width: 100%;
+        bottom: 13px;
       }
     }
+  }
 }

+ 0 - 113
src/assets/scss/core/plugins/_perfect-scrollbar.scss

@@ -1,113 +0,0 @@
-/* perfect-scrollbar v0.6.13 */
-.ps-container {
-  -ms-touch-action: auto;
-  touch-action: auto;
-  overflow: hidden !important;
-  -ms-overflow-style: none; }
-  @supports (-ms-overflow-style: none) {
-    .ps-container {
-      overflow: auto !important; } }
-  @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
-    .ps-container {
-      overflow: auto !important; } }
-  .ps-container.ps-active-x > .ps-scrollbar-x-rail,
-  .ps-container.ps-active-y > .ps-scrollbar-y-rail {
-    display: block;
-    background-color: transparent; }
-  .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
-    background-color: #eee;
-    opacity: 0.9; }
-    .ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
-      background-color: #999;
-      height: 11px; }
-  .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
-    background-color: #eee;
-    opacity: 0.9; }
-    .ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
-      background-color: #999;
-      width: 11px; }
-  .ps-container > .ps-scrollbar-x-rail {
-    display: none;
-    position: absolute;
-    /* please don't change 'position' */
-    opacity: 0;
-    -webkit-transition: background-color .2s linear, opacity .2s linear;
-    -o-transition: background-color .2s linear, opacity .2s linear;
-    -moz-transition: background-color .2s linear, opacity .2s linear;
-    transition: background-color .2s linear, opacity .2s linear;
-    bottom: 0px;
-    /* there must be 'bottom' for ps-scrollbar-x-rail */
-    height: 15px; }
-    .ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
-      position: absolute;
-      /* please don't change 'position' */
-      background-color: #aaa;
-      -webkit-border-radius: 6px;
-      -moz-border-radius: 6px;
-      border-radius: 6px;
-      -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
-      transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
-      -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-      -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
-      transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-      transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
-      bottom: 2px;
-      /* there must be 'bottom' for ps-scrollbar-x */
-      height: 6px; }
-    .ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
-      height: 11px; }
-  .ps-container > .ps-scrollbar-y-rail {
-    display: none;
-    position: absolute;
-    /* please don't change 'position' */
-    opacity: 0;
-    -webkit-transition: background-color .2s linear, opacity .2s linear;
-    -o-transition: background-color .2s linear, opacity .2s linear;
-    -moz-transition: background-color .2s linear, opacity .2s linear;
-    transition: background-color .2s linear, opacity .2s linear;
-    right: 0;
-    /* there must be 'right' for ps-scrollbar-y-rail */
-    width: 15px; }
-    .ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
-      position: absolute;
-      /* please don't change 'position' */
-      background-color: #aaa;
-      -webkit-border-radius: 6px;
-      -moz-border-radius: 6px;
-      border-radius: 6px;
-      -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
-      transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
-      -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-      -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
-      transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-      transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
-      right: 2px;
-      /* there must be 'right' for ps-scrollbar-y */
-      width: 6px; }
-    .ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
-      width: 11px; }
-  .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
-    background-color: #eee;
-    opacity: 0.9; }
-    .ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
-      background-color: #999;
-      height: 11px; }
-  .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
-    background-color: #eee;
-    opacity: 0.9; }
-    .ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
-      background-color: #999;
-      width: 11px; }
-  .ps-container:hover > .ps-scrollbar-x-rail,
-  .ps-container:hover > .ps-scrollbar-y-rail {
-    opacity: 0.6; }
-  .ps-container:hover > .ps-scrollbar-x-rail:hover {
-    background-color: #eee;
-    opacity: 0.9; }
-    .ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
-      background-color: #999; }
-  .ps-container:hover > .ps-scrollbar-y-rail:hover {
-    background-color: #eee;
-    opacity: 0.9; }
-    .ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
-      background-color: #999; }

+ 39 - 44
src/assets/scss/material-dashboard.scss

@@ -15,47 +15,42 @@
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 
 */
- @import "~@angular/material/prebuilt-themes/indigo-pink.css";
-
- @import "core/variables";
- @import "core/mixins";
- @import "~bootstrap/scss/bootstrap";
-
-
- @import "core/buttons";
- @import "core/checkboxes";
- @import "core/radios";
- @import "core/forms";
- @import "core/input-group";
-
-
- // Core Components
- @import "core/images";
- @import "core/navbar";
- @import "core/alerts";
- @import "core/type";
- @import "core/tabs";
- @import "core/tooltip";
- @import "core/popover";
- @import "core/dropdown";
- @import "core/togglebutton";
- @import "core/ripples";
- @import "core/footers";
- @import "core/sidebar-and-main-panel";
- @import "core/fixed-plugin";
- @import "core/tables";
- @import "core/misc";
-
-
- //plugin scss
- @import "core/plugins/animate";
- @import "core/plugins/chartist";
- @import "core/plugins/perfect-scrollbar";
- @import "core/responsive";
+@import "~@angular/material/prebuilt-themes/indigo-pink.css";
+
+@import "core/variables";
+@import "core/mixins";
+@import "~bootstrap/scss/bootstrap";
+
+@import "core/buttons";
+@import "core/checkboxes";
+@import "core/radios";
+@import "core/forms";
+@import "core/input-group";
+
+// Core Components
+@import "core/images";
+@import "core/navbar";
+@import "core/alerts";
+@import "core/type";
+@import "core/tabs";
+@import "core/tooltip";
+@import "core/popover";
+@import "core/dropdown";
+@import "core/togglebutton";
+@import "core/ripples";
+@import "core/footers";
+@import "core/sidebar-and-main-panel";
+@import "core/fixed-plugin";
+@import "core/tables";
+@import "core/misc";
+
+//plugin scss
+@import "core/plugins/animate";
+@import "core/plugins/chartist";
+@import "core/responsive";
 
 @import "core/angular-modal.scss";
 
-
 // Defaults
 
 .sky-skin {
@@ -170,13 +165,15 @@ table {
   text-align: right;
 }
 
-
-.was-validated .form-control:invalid, .form-control.is-invalid {
+.was-validated .form-control:invalid,
+.form-control.is-invalid {
   border-bottom: 1px solid #f44336;
 }
 
-
-.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid, input.form-control:invalid, input.form-control.is-invalid {
+.was-validated textarea.form-control:invalid,
+textarea.form-control.is-invalid,
+input.form-control:invalid,
+input.form-control.is-invalid {
   background-size: 18px;
 }
 
@@ -192,7 +189,6 @@ table {
   }
 }
 
-
 .form-check .form-check-input {
   opacity: 1;
   height: 20px;
@@ -202,4 +198,3 @@ table {
   color: black;
   z-index: 1;
 }
-

+ 11 - 11
src/environments/environment.ts

@@ -4,19 +4,19 @@
 
 export const environment = {
   production: false,
-  apiUrl: 'https://api.inverlec.solar',
+  apiUrl: "https://api.inverlec.solar",
   //productionApiUrl: 'http://192.168.98.10:8888/api/v1',
-  productionApiUrl: 'http://192.168.98.24:5000/api/v1',
-  //productionApiUrl: 'https://denmark.inverlec.solar/api/v1',
-  appID: '55899b9ea53834f2736b65a3582b734b',
-  gKey: '',
+  productionApiUrl: "http://192.168.98.24:5000/api/v1",
+  //productionApiUrl: "https://denmark.inverlec.solar/api/v1",
+  appID: "55899b9ea53834f2736b65a3582b734b",
+  gKey: "",
   config: {
-    apiKey: '',
-    authDomain: '',
-    databaseURL: '',
-    projectId: '',
-    storageBucket: '',
-    messagingSenderId: ''
+    apiKey: "",
+    authDomain: "",
+    databaseURL: "",
+    projectId: "",
+    storageBucket: "",
+    messagingSenderId: ""
   }
 };
 

+ 63 - 23
src/index.html

@@ -1,32 +1,72 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
-<head>
-    <base href=''>
+  <head>
+    <base href="" />
     <meta charset="utf-8" />
-    <link rel="icon" type="image/x-icon" href="favicon.ico">
+    <link rel="icon" type="image/x-icon" href="favicon.ico" />
 
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
 
-    <title>DENMARK - Aplicación para visualizar sistemas fotovoltaicos @Inverlec</title>
+    <title>
+      DENMARK - Aplicación para visualizar sistemas fotovoltaicos @Inverlec
+    </title>
 
-    <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
-    <meta name="viewport" content="width=device-width" />
+    <meta
+      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
+      name="viewport"
+    />
+    <meta
+      name="viewport"
+      content="height=device-height,width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,minimal-ui"
+    />
+    <meta name="HandheldFriendly" content="True" />
+    <meta name="MSThemeCompatible" content="no" />
+    <meta name="apple-mobile-web-app-capable" content="yes" />
+    <meta
+      name="apple-mobile-web-app-status-bar-style"
+      content="translucent black"
+    />
+    <meta name="msapplication-navbutton-color" content="translucent black" />
+    <meta name="mssmarttagspreventparsing" content="true" />
 
     <!--     Fonts and icons     -->
-    <link href='https://fonts.googleapis.com/css?family=Roboto:400,700,300|Material+Icons' rel='stylesheet' type='text/css'>
-    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDJ2_cgrOMUZ9v3UgDYQrpBYKjO7h70N9E"></script>
-    <script src="https://kit.fontawesome.com/22ac039de1.js" crossorigin="anonymous"></script>
-    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
-    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
-
-</head>
-<body>
-  <app-root>
-    <div class="loader">
-      <svg class="circular" viewBox="25 25 50 50">
-          <circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
-      </svg>
-    </div>
-  </app-root>
-</body>
+    <link
+      href="https://fonts.googleapis.com/css?family=Roboto:400,700,300|Material+Icons"
+      rel="stylesheet"
+      type="text/css"
+    />
+    <script
+      type="text/javascript"
+      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDJ2_cgrOMUZ9v3UgDYQrpBYKjO7h70N9E"
+    ></script>
+    <script
+      src="https://kit.fontawesome.com/22ac039de1.js"
+      crossorigin="anonymous"
+    ></script>
+    <link
+      href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap"
+      rel="stylesheet"
+    />
+    <link
+      href="https://fonts.googleapis.com/icon?family=Material+Icons"
+      rel="stylesheet"
+    />
+  </head>
+  <body>
+    <app-root>
+      <div class="loader">
+        <svg class="circular" viewBox="25 25 50 50">
+          <circle
+            class="path"
+            cx="50"
+            cy="50"
+            r="20"
+            fill="none"
+            stroke-width="2"
+            stroke-miterlimit="10"
+          />
+        </svg>
+      </div>
+    </app-root>
+  </body>
 </html>

+ 0 - 128
src/material-dashboard.css

@@ -13144,11 +13144,6 @@ h2.title {
       margin-top: 10px;
       margin-bottom: 10px; }
 
-.perfect-scrollbar-on .sidebar,
-.perfect-scrollbar-on .main-panel {
-  height: 100%;
-  max-height: 100%; }
-
 .sidebar,
 .main-panel,
 .sidebar-wrapper {
@@ -15334,126 +15329,3 @@ Copyright (c) 2015 Daniel Eden
 .ct-chart .ct-series-c .ct-area {
   fill: #ff9800; }
 
-/* perfect-scrollbar v0.6.13 */
-.ps-container {
-  -ms-touch-action: auto;
-  touch-action: auto;
-  overflow: hidden !important;
-  -ms-overflow-style: none; }
-
-@supports (-ms-overflow-style: none) {
-  .ps-container {
-    overflow: auto !important; } }
-
-@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
-  .ps-container {
-    overflow: auto !important; } }
-
-.ps-container.ps-active-x > .ps-scrollbar-x-rail,
-.ps-container.ps-active-y > .ps-scrollbar-y-rail {
-  display: block;
-  background-color: transparent; }
-
-.ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
-  background-color: #eee;
-  opacity: 0.9; }
-
-.ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
-  background-color: #999;
-  height: 11px; }
-
-.ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
-  background-color: #eee;
-  opacity: 0.9; }
-
-.ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
-  background-color: #999;
-  width: 11px; }
-
-.ps-container > .ps-scrollbar-x-rail {
-  display: none;
-  position: absolute;
-  /* please don't change 'position' */
-  opacity: 0;
-  -webkit-transition: background-color .2s linear, opacity .2s linear;
-  transition: background-color .2s linear, opacity .2s linear;
-  bottom: 0px;
-  /* there must be 'bottom' for ps-scrollbar-x-rail */
-  height: 15px; }
-
-.ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
-  position: absolute;
-  /* please don't change 'position' */
-  background-color: #aaa;
-  border-radius: 6px;
-  -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
-  -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-  transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-  bottom: 2px;
-  /* there must be 'bottom' for ps-scrollbar-x */
-  height: 6px; }
-
-.ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
-  height: 11px; }
-
-.ps-container > .ps-scrollbar-y-rail {
-  display: none;
-  position: absolute;
-  /* please don't change 'position' */
-  opacity: 0;
-  -webkit-transition: background-color .2s linear, opacity .2s linear;
-  transition: background-color .2s linear, opacity .2s linear;
-  right: 0;
-  /* there must be 'right' for ps-scrollbar-y-rail */
-  width: 15px; }
-
-.ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
-  position: absolute;
-  /* please don't change 'position' */
-  background-color: #aaa;
-  border-radius: 6px;
-  -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
-  -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-  transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
-  right: 2px;
-  /* there must be 'right' for ps-scrollbar-y */
-  width: 6px; }
-
-.ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
-  width: 11px; }
-
-.ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
-  background-color: #eee;
-  opacity: 0.9; }
-
-.ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
-  background-color: #999;
-  height: 11px; }
-
-.ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
-  background-color: #eee;
-  opacity: 0.9; }
-
-.ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
-  background-color: #999;
-  width: 11px; }
-
-.ps-container:hover > .ps-scrollbar-x-rail,
-.ps-container:hover > .ps-scrollbar-y-rail {
-  opacity: 0.6; }
-
-.ps-container:hover > .ps-scrollbar-x-rail:hover {
-  background-color: #eee;
-  opacity: 0.9; }
-
-.ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
-  background-color: #999; }
-
-.ps-container:hover > .ps-scrollbar-y-rail:hover {
-  background-color: #eee;
-  opacity: 0.9; }
-
-.ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
-  background-color: #999; }
-
-/*# sourceMappingURL=material-dashboard.css.map */

+ 11 - 2
src/styles.scss

@@ -1,8 +1,17 @@
 /* You can add global styles to this file, and also import other style files */
 
-html, body { height: 100%; }
-body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
+html,
+body {
+  height: 100%;
+}
+body {
+  margin: 0;
+  font-family: Roboto, "Helvetica Neue", sans-serif;
+}
 
 .align-container {
   padding: 0 14px;
+  @media screen and (max-width: 480px) {
+    padding: 0;
+  }
 }

Неке датотеке нису приказане због велике количине промена