Ver código fonte

changes in api, added management views

onunez 6 anos atrás
pai
commit
16e5cb541d
62 arquivos alterados com 1330 adições e 206 exclusões
  1. 10 0
      package-lock.json
  2. 2 0
      package.json
  3. 0 4
      src/app/app.module.ts
  4. 2 1
      src/app/app.routing.ts
  5. 3 3
      src/app/components/assets/assets.component.html
  6. 4 1
      src/app/components/assets/assets.component.scss
  7. 10 10
      src/app/components/dashboard/dashboard.component.html
  8. 17 17
      src/app/components/dashboard/dashboard.component.ts
  9. 20 0
      src/app/components/login/login.component.html
  10. 46 0
      src/app/components/login/login.component.ts
  11. 22 0
      src/app/components/organizations/edit-organization/edit-organization.component.html
  12. 0 0
      src/app/components/organizations/edit-organization/edit-organization.component.scss
  13. 25 0
      src/app/components/organizations/edit-organization/edit-organization.component.spec.ts
  14. 15 0
      src/app/components/organizations/edit-organization/edit-organization.component.ts
  15. 76 0
      src/app/components/organizations/new-organization/new-organization.component.html
  16. 5 0
      src/app/components/organizations/new-organization/new-organization.component.scss
  17. 25 0
      src/app/components/organizations/new-organization/new-organization.component.spec.ts
  18. 18 0
      src/app/components/organizations/new-organization/new-organization.component.ts
  19. 19 0
      src/app/components/organizations/organization/organization.component.html
  20. 0 0
      src/app/components/organizations/organization/organization.component.scss
  21. 25 0
      src/app/components/organizations/organization/organization.component.spec.ts
  22. 16 0
      src/app/components/organizations/organization/organization.component.ts
  23. 26 36
      src/app/components/organizations/organizations.component.html
  24. 4 0
      src/app/components/organizations/organizations.component.scss
  25. 20 66
      src/app/components/organizations/organizations.component.ts
  26. 22 0
      src/app/components/plants/edit-plant/edit-plant.component.html
  27. 0 0
      src/app/components/plants/edit-plant/edit-plant.component.scss
  28. 25 0
      src/app/components/plants/edit-plant/edit-plant.component.spec.ts
  29. 15 0
      src/app/components/plants/edit-plant/edit-plant.component.ts
  30. 68 0
      src/app/components/plants/new-plant/new-plant.component.html
  31. 0 0
      src/app/components/plants/new-plant/new-plant.component.scss
  32. 25 0
      src/app/components/plants/new-plant/new-plant.component.spec.ts
  33. 16 0
      src/app/components/plants/new-plant/new-plant.component.ts
  34. 73 0
      src/app/components/plants/plants.component.html
  35. 0 0
      src/app/components/plants/plants.component.scss
  36. 25 0
      src/app/components/plants/plants.component.spec.ts
  37. 56 0
      src/app/components/plants/plants.component.ts
  38. 2 2
      src/app/components/plugins/plugins.module.ts
  39. 2 2
      src/app/components/plugins/weather-card/weather-card.component.html
  40. 3 2
      src/app/components/shared/navbar/navbar.component.ts
  41. 14 38
      src/app/components/shared/sidebar/sidebar.component.html
  42. 0 1
      src/app/components/shared/sidebar/sidebar.component.scss
  43. 25 4
      src/app/components/shared/sidebar/sidebar.component.ts
  44. 1 0
      src/app/components/users/new-user/new-user.component.html
  45. 0 0
      src/app/components/users/new-user/new-user.component.scss
  46. 25 0
      src/app/components/users/new-user/new-user.component.spec.ts
  47. 15 0
      src/app/components/users/new-user/new-user.component.ts
  48. 74 0
      src/app/components/users/users.component.html
  49. 0 0
      src/app/components/users/users.component.scss
  50. 25 0
      src/app/components/users/users.component.spec.ts
  51. 56 0
      src/app/components/users/users.component.ts
  52. 2 1
      src/app/layouts/admin/admin.component.html
  53. 20 0
      src/app/layouts/admin/admin.module.ts
  54. 78 16
      src/app/layouts/admin/admin.routing.ts
  55. 4 0
      src/app/models/token.ts
  56. 22 0
      src/app/services/auth.guard.ts
  57. 96 0
      src/app/services/auth2.service.ts
  58. 9 0
      src/app/services/organizations.service.ts
  59. 1 1
      src/app/services/plants.service.ts
  60. 59 0
      src/app/services/token.interceptor.ts
  61. 61 0
      src/assets/scss/material-dashboard.scss
  62. 1 1
      src/environments/environment.ts

+ 10 - 0
package-lock.json

@@ -1356,6 +1356,11 @@
       "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.8.5.tgz",
       "integrity": "sha512-CohUDPD3f5e/sGI8SUs1zaUnS38MMA+4WDDxBoudQIKVqNj4LJG2P+Z0WXB+vT4jkDpc7itXYoNIZq1f1MpulA=="
     },
+    "@types/crypto-js": {
+      "version": "3.1.43",
+      "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-3.1.43.tgz",
+      "integrity": "sha512-EHe/YKctU3IYNBsDmSOPX/7jLHPRlx8WaiDKSY9JCTnJ8XJeM4c0ZJvx+9Gxmr2s2ihI92R+3U/gNL1sq5oRuQ=="
+    },
     "@types/datatables.net": {
       "version": "1.10.17",
       "resolved": "https://registry.npmjs.org/@types/datatables.net/-/datatables.net-1.10.17.tgz",
@@ -3272,6 +3277,11 @@
         "randomfill": "^1.0.3"
       }
     },
+    "crypto-js": {
+      "version": "3.1.9-1",
+      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz",
+      "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg="
+    },
     "css-parse": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",

+ 2 - 0
package.json

@@ -25,6 +25,7 @@
     "@asymmetrik/ngx-leaflet": "^6.0.1",
     "@ng-bootstrap/ng-bootstrap": "^5.1.0",
     "@swimlane/ngx-datatable": "^15.0.2",
+    "@types/crypto-js": "^3.1.43",
     "@types/googlemaps": "^3.37.4",
     "angular-bootstrap-md": "^8.1.1",
     "angular-datatables": "^8.0.0",
@@ -34,6 +35,7 @@
     "bootstrap-material-design": "^4.1.2",
     "c": "^0.1.0",
     "chart.js": "^2.8.0",
+    "crypto-js": "^3.1.9-1",
     "datatables.net": "^1.10.19",
     "datatables.net-dt": "^1.10.19",
     "font-awesome": "^4.7.0",

+ 0 - 4
src/app/app.module.ts

@@ -27,18 +27,14 @@ 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 { PluginsModule } from './components/plugins/plugins.module';
 import { LoginComponent } from './components/login/login.component';
 
 
-//import { DashboardComponent } from './dashboard/dashboard.component';
-
 @NgModule({
   declarations: [
     AppComponent,

+ 2 - 1
src/app/app.routing.ts

@@ -6,7 +6,8 @@ import { AdminModule } from './layouts/admin/admin.module';
 
 import { AdminComponent } from './layouts/admin/admin.component';
 import { LoginComponent } from './components/login/login.component';
-import { AuthGuard } from './services/authentication.service';
+//import { AuthGuard } from './services/authentication.service';
+import { AuthGuard } from './services/auth.guard';
 import { Role } from './models/role';
 
 const routes: Routes =[

+ 3 - 3
src/app/components/assets/assets.component.html

@@ -16,9 +16,9 @@
         </div>
       </div>
       <div class="row">
-        <div class="col-lg-6">
-            <div class="widget energy-stats">
-                <div class="mini-stats ">
+        <div class="col-lg-12">
+            <div class="widget environment-meters">
+                <div class="mini-stats">
                   <span class="dark-yellow-skin"><i class="fa fa-bolt"></i></span>
                   <h5 *ngIf="listEnergyProduced">
                     {{listEnergyProduced.thisWeek.total_energy_kWh/1000 | number}}

+ 4 - 1
src/app/components/assets/assets.component.scss

@@ -57,6 +57,10 @@ table {
   height: 122px;
 }
 
+.enviroment-meter {
+  height: 60px;
+}
+
 .widget {
   background: #ffffff none repeat scroll 0 0;
   float: left;
@@ -108,7 +112,6 @@ table {
       font-size: 2rem;
       font-weight: 400;
     }
-
   }
 
   .enviroment-stats {

+ 10 - 10
src/app/components/dashboard/dashboard.component.html

@@ -11,7 +11,7 @@
             <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">{{listData.length}}</h2>
+            <h2 class="mb-3" *ngIf="listData">{{listData.length}}</h2>
           </div>
         </div>
       </div>
@@ -26,10 +26,10 @@
           </div>
         </div>
       </div>
-  
-  
+
+
     </div>
-    
+
     <div class="row ">
       <div *ngIf="error; then showAlert"></div>
       <ng-template #showAlert>
@@ -52,7 +52,7 @@
               (leafletMapReady)='onMapReady($event)'>
             </div>
           </div>
-        </div> 
+        </div>
       </div>
       <div class="col-md-4">
 
@@ -60,22 +60,22 @@
             <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: {{selectedPlant.installedCapacity_kW}} kW</p>
-                
+
                 <button class="btn bg-yellow btn-flat" (click)="goToAsset(selectedPlant.id)">Ir a Planta</button>
               </div>
-                  
+
             </div>
           </div>
-            
+
       </div>
     </div>
     <br>
-      
+
 
   </div>
   <br>

+ 17 - 17
src/app/components/dashboard/dashboard.component.ts

@@ -58,7 +58,7 @@ export class DashboardComponent implements OnInit {
     'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
     { maxZoom: 18,
       attribution: '&copy; OpenStreetMap contributors'
-    } 
+    }
   );
 
   // Values to bind to Leaflet Directive
@@ -67,11 +67,11 @@ export class DashboardComponent implements OnInit {
     zoom: 10,
     center: latLng([13.661714, -89.251530])
   };
-  
+
   constructor(
-    private plantsService: PlantsService, 
-    private route: ActivatedRoute, 
-    private orgService: OrganizationsService, 
+    private plantsService: PlantsService,
+    private route: ActivatedRoute,
+    private orgService: OrganizationsService,
     private router: Router,
     private zone: NgZone) {
 
@@ -123,12 +123,12 @@ export class DashboardComponent implements OnInit {
     else {
       this.totalMetersInstalled = localStorage.getItem("installedCapacityTotal_kW");
     }*/
-    
+
   }
 
 
   ngOnInit(): void {
-    
+
     var responsiveOptions: any[] = [
       ['screen and (max-width: 640px)', {
         seriesBarDistance: 5,
@@ -139,13 +139,13 @@ export class DashboardComponent implements OnInit {
         }
       }]
     ];
-    
+
     setTimeout(()=>{
 
       if (this.listData != undefined){
         this.addMarkers();
       }
-  
+
       Swal.close();
     }, 2500);
 
@@ -155,7 +155,7 @@ export class DashboardComponent implements OnInit {
     return observableOf(this.listData.find(e => e.id === id));
   }
 
-  
+
   addMarkers() {
     let lat, long, address, name2;
 
@@ -172,7 +172,7 @@ export class DashboardComponent implements OnInit {
         address = plant.address;
         name2 = plant.name;
       }
-      
+
       const newMarker = marker(
         [lat, long],
         {icon: this.icon})
@@ -209,15 +209,15 @@ export class DashboardComponent implements OnInit {
     }, 0);
 
     const bounds = latLngBounds(this.points);
-    map.fitBounds(bounds, {
-      padding: point(24, 24),
-      maxZoom: 9.5,
-      animate: true
-    });
+    //map.fitBounds(bounds, {
+    //  padding: point(24, 24),
+    //  maxZoom: 9.5,
+    //  animate: true
+    //});
   }
 
   goToAsset(id: string){
-    this.router.navigate(['/assets'], { queryParams: { id: id } }); 
+    this.router.navigate(['/assets'], { queryParams: { id: id } });
   }
 
 

+ 20 - 0
src/app/components/login/login.component.html

@@ -10,6 +10,26 @@
             <p class="lead">Iniciar sesión con tu cuenta</p>
           </div>
           <div class="body">
+              <form [formGroup]="loginForm" (ngSubmit)="login()">
+                  <div class="form-group">
+                      <label for="email">Correo electrónico</label>
+                      
+                      <input type="text" name="email" class="form-control"
+                      formControlName="email" required email />
+      
+                    </div>
+                    <div class="form-group">
+                      <label for="password">Contraseña</label>
+                      <input type="password" name="password"  class="form-control"
+                      formControlName="password" required minlength="6" />
+                    </div>
+      
+                  <button class="btn btn-primary" type="submit" [disabled]="!loginForm.valid"> 
+                      Iniciar sesión
+                    </button>
+
+                
+            <!--
             <form class="form-auth-small ng-untouched ng-pristine ng-valid" (ngSubmit)="login(f)" #f="ngForm" >
               <div class="form-group">
                 <label for="email">Correo electrónico</label>

+ 46 - 0
src/app/components/login/login.component.ts

@@ -1,4 +1,49 @@
 import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder } from '@angular/forms';
+import { Router } from '@angular/router';
+import { AuthService } from '@app/services/auth2.service';
+
+@Component({
+  selector: 'app-login',
+  templateUrl: './login.component.html',
+  styleUrls: ['./login.component.scss']
+})
+export class LoginComponent implements OnInit {
+
+  loginForm: FormGroup;
+
+  constructor(private authService: AuthService, private formBuilder: FormBuilder, private router: Router) { }
+
+  ngOnInit() {
+    this.loginForm = this.formBuilder.group({
+      email: [''],
+      password: ['']
+    });
+  }
+
+  get f() { return this.loginForm.controls; }
+
+  login() {
+    console.log("enter login");
+    this.authService.login(
+      {
+        email: this.f.email.value,
+        password: this.f.password.value
+      }
+    )
+    .subscribe(success => {
+      if (success) {
+        console.log(success);
+        console.log("success");
+        //window.location.href="";
+        //this.router.navigate(['/secret-random-number']);
+      }
+    });
+  }
+
+}
+
+/* import { Component, OnInit } from '@angular/core';
 import { Location } from '@angular/common';
 
 import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
@@ -86,3 +131,4 @@ export class LoginComponent implements OnInit {
   }
 
 }
+*/

+ 22 - 0
src/app/components/organizations/edit-organization/edit-organization.component.html

@@ -0,0 +1,22 @@
+<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]="['/organizations']">Organizaciones</a></li>
+              <li class="breadcrumb-item">Editar organización</li>
+            </ol>
+          </nav>
+        </div>
+
+      </div>
+
+    </div>          
+  </div>
+</div>

+ 0 - 0
src/app/components/organizations/edit-organization/edit-organization.component.scss


+ 25 - 0
src/app/components/organizations/edit-organization/edit-organization.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditOrganizationComponent } from './edit-organization.component';
+
+describe('EditOrganizationComponent', () => {
+  let component: EditOrganizationComponent;
+  let fixture: ComponentFixture<EditOrganizationComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ EditOrganizationComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(EditOrganizationComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
src/app/components/organizations/edit-organization/edit-organization.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-edit-organization',
+  templateUrl: './edit-organization.component.html',
+  styleUrls: ['./edit-organization.component.scss']
+})
+export class EditOrganizationComponent implements OnInit {
+  title:string = "Editar organización"; 
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 76 - 0
src/app/components/organizations/new-organization/new-organization.component.html

@@ -0,0 +1,76 @@
+<h2 class="floating-title">{{title}}</h2>
+
+<div class="main-content">
+  <div class="container-fluid">
+
+    <div class="row">
+      <div class="col-12">
+
+        <nav aria-label="breadcrumb">
+          <ol class="breadcrumb">
+            <li class="breadcrumb-item"><a [routerLink]="['/']">Dashboard</a></li>
+            <li class="breadcrumb-item"><a [routerLink]="['/organizations']">Organizaciones</a></li>
+            <li class="breadcrumb-item">Nueva organización</li>
+          </ol>
+        </nav>
+      </div>
+    </div>
+    <br>
+    <div class="row justify-content-center">
+      
+      <div class="col-8">
+        <div class="align-container">
+
+          <div class="card">
+            <div class="card-header card-header-icon card-header-rose">
+              <div class="card-icon"><i class="material-icons">map</i></div>
+              <h4 class="card-title">Nueva organización - <small class="category">Complete la información básica</small></h4>
+            </div>
+            <div class="card-body">              
+              <div class="align-container">
+                <form class="form-auth-small ng-untouched ng-pristine ng-valid" >
+                  <div class="form-group">
+                    <label for="name">Nombre de la organización: </label>
+                    <input type="text" name="name" class="form-control" required />
+                  </div>
+
+                  <div class="form-group">
+                    <label for="country">País: </label>
+                    <input type="text" name="country" class="form-control" required />
+                  </div>
+                  
+                  <div class="form-group">
+                    <label for="city">Ciudad: </label>
+                    <input type="text" name="city" class="form-control" required />
+                  </div>      
+                  
+                  <div class="form-group">
+                    <label for="contactName">Nombre contacto: </label>
+                    <input type="text" name="contactName" class="form-control" required />
+                  </div>
+
+                  <div class="form-group">
+                    <label for="contactNumber">Teléfono contacto: </label>
+                    <input type="text" name="contactNumber" class="form-control" required />
+                  </div>
+                  
+                  <div class="form-group">
+                    <label for="address">Dirección: </label>
+                    <textarea name="address" class="form-control" rows="2" required ></textarea>
+                  </div>
+                  <br>
+                  <button class="btn btn-primary">
+                    Crear organización
+                  </button>
+                  <!--<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>-->
+                </form>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+
+    </div>          
+  </div>
+</div>

+ 5 - 0
src/app/components/organizations/new-organization/new-organization.component.scss

@@ -0,0 +1,5 @@
+.card-icon {
+  background-color: #F4A822;
+  color: #fff;
+}
+

+ 25 - 0
src/app/components/organizations/new-organization/new-organization.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NewOrganizationComponent } from './new-organization.component';
+
+describe('NewOrganizationComponent', () => {
+  let component: NewOrganizationComponent;
+  let fixture: ComponentFixture<NewOrganizationComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ NewOrganizationComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(NewOrganizationComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 18 - 0
src/app/components/organizations/new-organization/new-organization.component.ts

@@ -0,0 +1,18 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-new-organization',
+  templateUrl: './new-organization.component.html',
+  styleUrls: ['./new-organization.component.scss']
+})
+export class NewOrganizationComponent implements OnInit {
+  title:string = "Nueva organización"; 
+
+  constructor() {
+    console.log("new");
+  }
+
+  ngOnInit() {
+  }
+
+}

+ 19 - 0
src/app/components/organizations/organization/organization.component.html

@@ -0,0 +1,19 @@
+<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">
+
+          <button class="btn btn-primary">
+            Nuevo registro
+          </button>
+        </div>
+      </div>
+
+
+    </div>          
+  </div>
+</div>

+ 0 - 0
src/app/components/organizations/organization/organization.component.scss


+ 25 - 0
src/app/components/organizations/organization/organization.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { OrganizationComponent } from './organization.component';
+
+describe('OrganizationComponent', () => {
+  let component: OrganizationComponent;
+  let fixture: ComponentFixture<OrganizationComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ OrganizationComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(OrganizationComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 16 - 0
src/app/components/organizations/organization/organization.component.ts

@@ -0,0 +1,16 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-organization',
+  templateUrl: './organization.component.html',
+  styleUrls: ['./organization.component.scss']
+})
+export class OrganizationComponent implements OnInit {
+  title:string = "Detalle de organización"; 
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 26 - 36
src/app/components/organizations/organizations.component.html

@@ -3,36 +3,26 @@
 <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">Organizaciones</li>
+            </ol>
+          </nav>
+
+          <a class="btn btn-primary" [routerLink]="['/organizations/new']">
+            Nuevo registro
+          </a>
+        </div>
+      </div>
+
       <div class="col-12">
           <div class="align-container">
 
-            <div class="input-box-container">
-              <input class="input-box" placeholder="Click to select a date" 
-                angular-mydatepicker name="mydate" (click)="dp.toggleCalendar()" 
-                [(ngModel)]="model" [options]="myDpOptions" 
-                #dp="angular-mydatepicker"/>
-            </div>
-
-            <!--
-              <ngb-datepicker #dp (select)="onDateSelection($event)" [displayMonths]="2" [dayTemplate]="t">
-                </ngb-datepicker>
-                
-                <ng-template #t let-date let-focused="focused">
-                  <span class="custom-day"
-                        [class.focused]="focused"
-                        [class.range]="isRange(date)"
-                        [class.faded]="isHovered(date) || isInside(date)"
-                        (mouseenter)="hoveredDate = date"
-                        (mouseleave)="hoveredDate = null">
-                    {{ date.day }}
-                  </span>
-                </ng-template>
-                
-                <hr>
-                <pre>From: {{ fromDate | json }} </pre>
-                <pre>To: {{ toDate | json }} </pre>
-                
--->
             <h4><b>Listado de organizaciones</b></h4>
             <div class="example-container mat-elevation-z8">
               <div class="example-table-container">
@@ -47,29 +37,29 @@
           
                   <!-- State Column -->
                   <ng-container matColumnDef="contactName">
-                    <th mat-header-cell *matHeaderCellDef>Nombre de Contacto</th>
+                    <th mat-header-cell *matHeaderCellDef>Nombre de contacto</th>
                     <td mat-cell *matCellDef="let row">{{row.contactName}}</td>
                   </ng-container>
 
+                  <!-- City Column -->
+                  <ng-container matColumnDef="contactNumber">
+                    <th mat-header-cell *matHeaderCellDef>Número de contacto</th>
+                    <td mat-cell *matCellDef="let row">{{row.contactNumber}}</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>
-                  
-                  <!-- City 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">
-                      <button class="btn btn-primary btn-sm">
+                      <a class="btn btn-primary btn-sm" [routerLink]="['/organization', row.id, 'edit']"  >
                         Editar
-                      </button>
+                      </a>
                     </td>
                   </ng-container>
           

+ 4 - 0
src/app/components/organizations/organizations.component.scss

@@ -37,3 +37,7 @@ table {
   //max-height: 400px;
   overflow: auto;
 }
+
+.align-right {
+  text-align: right;
+}

+ 20 - 66
src/app/components/organizations/organizations.component.ts

@@ -23,27 +23,13 @@ import {AngularMyDatePickerDirective,IAngularMyDpOptions, IMyDateModel} from 'an
 })
 export class OrganizationsComponent implements OnInit {
 
-  myDpOptions: IAngularMyDpOptions = {
-    dateRange: true,
-    dateFormat: 'dd/mm/yyyy'
-    // other options are here...
-  };
-
-  myDateInit: boolean = true;
-  model: IMyDateModel = null;
-
-
-  title:string = "Organizaciones";
-  hoveredDate: NgbDate;
-
-  fromDate: NgbDate;
-  toDate: NgbDate;
-  
-  
-  displayedColumns: string[] = ['name','contactName', 'country', 'city', 'id'];
+  title:string = "Organizaciones";  
+ 
+  displayedColumns: string[] = ['name','contactName', 'contactNumber', 'country', 'id'];
   //displayedColumns: string[] = ['state'];
 
   listData: Organization[] = [];
+  listOrganization:any;
   dataSource = new MatTableDataSource(this.listData);
 
   resultsLength = 0;
@@ -55,61 +41,29 @@ export class OrganizationsComponent implements OnInit {
 
 
   constructor(
-    private orgService: OrganizationsService,
-    private calendar: NgbCalendar) {
-      this.fromDate = calendar.getToday();
-      this.toDate = calendar.getNext(calendar.getToday(), 'd', 10);
-    }
+    private orgService: OrganizationsService) {}
 
   ngOnInit() {
     this.orgService.getListOrganizations().subscribe(res =>
       this.listData = res
     );
-    this.dataSource.data = this.listData;
-    this.dataSource.paginator = this.paginator;
-    this.dataSource.sort = this.sort;
-
-    if (this.myDateInit) {
-      // Initialize to specific date range with IMyDate object. 
-      // Begin date = today. End date = today + 3.
-      let begin: Date = new Date();
-      let end: Date = new Date();
-      end.setDate(end.getDate() + 3);
-
-      this.model = {
-        isRange: true, 
-        singleDate: null, 
-        dateRange: {
-          beginDate: {
-            year: begin.getFullYear(), month: begin.getMonth() + 1, day: begin.getDate()
-          },
-          endDate: {
-            year: end.getFullYear(), month: end.getMonth() + 1, day: end.getDate()
-          }
-        }
-      };
-    }
-    else {
-      // Initialize to specific date range with a javascript date object. 
-      // Begin date = today. End date = today + 3.
-      let begin: Date = new Date();
-      let end: Date = new Date();
-      end.setDate(end.getDate() + 3);
-
-      this.model = {
-        isRange: true, 
-        singleDate: null, 
-        dateRange: {
-          beginJsDate: begin,
-          endJsDate: end
-        }
-      };
-    }
+    console.log(this.listData);
+    
+    this.orgService.getAllOrganizations().subscribe(ans => {
+      this.listOrganization = ans["data"];
+      console.log(this.listOrganization);
+      this.dataSource.data = this.listOrganization;
+      this.dataSource.paginator = this.paginator;
+      this.dataSource.sort = this.sort;
+      
+    });
+
+      
+    
+    
+    
   }
 
-
-  
-
   applyFilter(filterValue: string) {
     this.dataSource.filter = filterValue.trim().toLowerCase();
     if (this.dataSource.paginator) {

+ 22 - 0
src/app/components/plants/edit-plant/edit-plant.component.html

@@ -0,0 +1,22 @@
+<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]="['/organizations']">Plantas</a></li>
+              <li class="breadcrumb-item">Editar planta</li>
+            </ol>
+          </nav>
+        </div>
+
+      </div>
+
+    </div>          
+  </div>
+</div>

+ 0 - 0
src/app/components/plants/edit-plant/edit-plant.component.scss


+ 25 - 0
src/app/components/plants/edit-plant/edit-plant.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditPlantComponent } from './edit-plant.component';
+
+describe('EditPlantComponent', () => {
+  let component: EditPlantComponent;
+  let fixture: ComponentFixture<EditPlantComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ EditPlantComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(EditPlantComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
src/app/components/plants/edit-plant/edit-plant.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-edit-plant',
+  templateUrl: './edit-plant.component.html',
+  styleUrls: ['./edit-plant.component.scss']
+})
+export class EditPlantComponent implements OnInit {
+  title:string = "Editar planta"; 
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 68 - 0
src/app/components/plants/new-plant/new-plant.component.html

@@ -0,0 +1,68 @@
+<p>new-plant works!</p>
+<h2 class="floating-title">{{title}}</h2>
+
+<div class="main-content">
+  <div class="container-fluid">
+
+    <div class="row">
+      <div class="col-12">
+
+        <nav aria-label="breadcrumb">
+          <ol class="breadcrumb">
+            <li class="breadcrumb-item"><a [routerLink]="['/']">Dashboard</a></li>
+            <li class="breadcrumb-item"><a [routerLink]="['/plants']">Plantas</a></li>
+            <li class="breadcrumb-item">Nueva planta</li>
+          </ol>
+        </nav>
+      </div>
+    </div>
+    <br>
+    <div class="row justify-content-center">
+      
+      <div class="col-8">
+        <div class="align-container">
+
+          <div class="card">
+            <div class="card-header card-header-icon card-header-rose">
+              <div class="card-icon"><i class="material-icons">map</i></div>
+              <h4 class="card-title">Nueva planta - <small class="category">Complete la información básica</small></h4>
+            </div>
+            <div class="card-body">              
+              <div class="align-container">
+                <form class="form-auth-small ng-untouched ng-pristine ng-valid" >
+                  <div class="form-group">
+                    <label for="name">Nombre de la planta: </label>
+                    <input type="text" name="name" class="form-control" required />
+                  </div>
+
+                  <div class="form-group">
+                    <label for="country">País: </label>
+                    <input type="text" name="country" class="form-control" required />
+                  </div>
+                  
+                  <div class="form-group">
+                    <label for="city">Ciudad: </label>
+                    <input type="text" name="city" class="form-control" required />
+                  </div>      
+                  
+                  <div class="form-group">
+                    <label for="address">Dirección: </label>
+                    <input type="text" name="address" class="form-control" required />
+                  </div>
+
+                  <br>
+                  <button class="btn btn-primary">
+                    Crear organización
+                  </button>
+                  <!--<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>-->
+                </form>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+
+    </div>          
+  </div>
+</div>

+ 0 - 0
src/app/components/plants/new-plant/new-plant.component.scss


+ 25 - 0
src/app/components/plants/new-plant/new-plant.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NewPlantComponent } from './new-plant.component';
+
+describe('NewPlantComponent', () => {
+  let component: NewPlantComponent;
+  let fixture: ComponentFixture<NewPlantComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ NewPlantComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(NewPlantComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 16 - 0
src/app/components/plants/new-plant/new-plant.component.ts

@@ -0,0 +1,16 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-new-plant',
+  templateUrl: './new-plant.component.html',
+  styleUrls: ['./new-plant.component.scss']
+})
+export class NewPlantComponent implements OnInit {
+  title:string = "Nueva planta"; 
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 73 - 0
src/app/components/plants/plants.component.html

@@ -0,0 +1,73 @@
+<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">Plantas</li>
+            </ol>
+          </nav>
+
+          <a class="btn btn-primary" [routerLink]="['/plants/new']">
+            Nuevo registro
+          </a>
+        </div>
+      </div>
+
+      <div class="col-12">
+          <div class="align-container">
+
+            <h4><b>Listado de organizaciones</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="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">
+                      <a class="btn btn-primary btn-sm" [routerLink]="['/plant', row.id, 'edit']"  >
+                        Editar
+                      </a>
+                    </td>
+                  </ng-container>
+          
+                  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+                  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+                </table>
+                <mat-paginator [pageSizeOptions]="[5, 10, 25]"></mat-paginator>
+              </div>
+            </div>
+          </div>
+      
+      </div>
+      <br>
+      
+    </div>          
+  </div>
+</div>

+ 0 - 0
src/app/components/plants/plants.component.scss


+ 25 - 0
src/app/components/plants/plants.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PlantsComponent } from './plants.component';
+
+describe('PlantsComponent', () => {
+  let component: PlantsComponent;
+  let fixture: ComponentFixture<PlantsComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ PlantsComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(PlantsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 56 - 0
src/app/components/plants/plants.component.ts

@@ -0,0 +1,56 @@
+import { Component, ViewChild, OnInit } from '@angular/core';
+
+import {HttpClient} from '@angular/common/http';
+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 {merge, Observable, of as observableOf} from 'rxjs';
+import {catchError, map, startWith, switchMap} from 'rxjs/operators';
+import {MatTableDataSource} from '@angular/material/table';
+
+@Component({
+  selector: 'app-plants',
+  templateUrl: './plants.component.html',
+  styleUrls: ['./plants.component.scss']
+})
+export class PlantsComponent implements OnInit {
+
+  title:string = "Plantas";
+ 
+  displayedColumns: string[] = ['name', 'country', 'city', 'id'];
+  //displayedColumns: string[] = ['state'];
+
+  listData: Plant[] = [];
+  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;
+
+
+  constructor(
+    private orgService: PlantsService) {}
+
+  ngOnInit() {
+    this.orgService.getAllAssets().subscribe(ans => {
+      this.listPlant = ans["data"];
+      console.log(this.listPlant);
+      this.dataSource.data = this.listPlant;
+      this.dataSource.paginator = this.paginator;
+      this.dataSource.sort = this.sort;
+    });
+  }
+
+  applyFilter(filterValue: string) {
+    this.dataSource.filter = filterValue.trim().toLowerCase();
+    if (this.dataSource.paginator) {
+      this.dataSource.paginator.firstPage();
+    }
+  }
+
+}

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

@@ -29,6 +29,7 @@ import { PolarChartComponent } from './polar-chart/polar-chart.component';
 import { DoughnutChartComponent } from './doughnut-chart/doughnut-chart.component';
 import { OrganizationCardsComponent } from './organization-cards/organization-cards.component';
 
+
 /*import { BoxModule } from "angular-admin-lte";
 import { LineChartComponent } from "./line-chart/line-chart.component";
 import { ChartsModule } from "ng2-charts";
@@ -77,8 +78,7 @@ export const MQTT_SERVICE_OPTIONS: IMqttServiceOptions = {
     WeatherCardComponent,
     BarChartComponent,
     PolarChartComponent,
-    OrganizationCardsComponent
-    
+    OrganizationCardsComponent,
   ]
 })
 export class PluginsModule {}

+ 2 - 2
src/app/components/plugins/weather-card/weather-card.component.html

@@ -1,6 +1,6 @@
 <div class="widget">
   <div class="row">
-    <div class="col-lg-7 col-md-6 col-xs-12">
+    <div class="col-lg-6 col-md-6 col-xs-12">
       <div class="date">
         {{currentDate}}
       </div>
@@ -11,7 +11,7 @@
         {{state}}
       </div>
     </div>
-    <div class="col-lg-5 col-md-6 col-xs-12">
+    <div class="col-lg-6 col-md-6 col-xs-12">
       <div class="temp">
          <img src="assets/img/{{icon}}.png" alt="" width="60">
          <span>{{temp}}°</span>

+ 3 - 2
src/app/components/shared/navbar/navbar.component.ts

@@ -4,7 +4,7 @@ import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common'
 import { Router, ActivatedRoute } from '@angular/router';
 //import { AuthenticationService } from 'src/app/services/authentication.service';
 import { AdminLayoutRoutes } from 'src/app/layouts/admin/admin.routing';
-import { AuthService } from '../../../services/auth.service';
+import { AuthService } from '../../../services/auth2.service';
 
 @Component({
   selector: 'app-navbar',
@@ -144,8 +144,9 @@ export class NavbarComponent implements OnInit {
     };
 
     logout() {
+      console.log("i clicked logout");
       this.auth.logout();
-      window.location.href="";
+      //window.location.href="";
 
       //this.router.navigateByUrl("login");
     }

+ 14 - 38
src/app/components/shared/sidebar/sidebar.component.html

@@ -21,17 +21,6 @@
         </div>
       </span>
     </form> -->
-    <ul class="nav navbar-nav nav-mobile-menu">
-      <li class="nav-item">
-          <a class="nav-link" href="javascript:void(0)">
-              <i class="material-icons">person</i>
-              <p>
-                  <span class="d-lg-none d-md-block">Account</span>
-              </p>
-          </a>
-      </li>
-      <hr>
-    </ul>
   </div>
     <ul class="nav">
       <li routerLinkActive="active" *ngFor="let menuItem of menuItems" class="{{menuItem.class}} nav-item">
@@ -40,35 +29,22 @@
           <p>{{menuItem.title}}</p>
         </a>
       </li>
-      <!--
-      <li class="nav-item" routerlinkactive="active">
-        
-        <a class="nav-link collapsed" data-toggle="collapse" href="#components" aria-expanded="false">
-          <i class="material-icons">business</i>
-          <p>Plantas<b class="caret"></b></p>
+      
+      <hr>
+    </ul>
+    <ul *ngIf="adminMenu" class="nav">
+      <li class="nav-item">
+        <a class="nav-link" href="javascript:void(0)">
+          <i class="material-icons">settings_application</i>
+          <p>Administración</p>
+        </a>
+      </li>
+      <li routerLinkActive="active" *ngFor="let menuItem of adminMenuItems" class="{{menuItem.class}} nav-item">
+        <a class="nav-link" [routerLink]="[menuItem.path]"> <!--*ngIf="menuItem.role.includes(admin_role)"-->
+          <i class="material-icons">{{menuItem.icon}}</i>
+          <p>{{menuItem.title}}</p>
         </a>
-        <div class="collapse" id="components" style="">
-          <ul class="nav">
-            <li class="nav-item" routerlinkactive="active">
-              <a class="nav-link" href="#/components/buttons"><span class="sidebar-mini">B</span><span class="sidebar-normal">COCESNA ESTACION<br> EL SALVADOR</span></a>
-            </li>
-            <li class="nav-item" routerlinkactive="active">
-              <a class="nav-link" href="#/components/grid"><span class="sidebar-mini">GS</span><span class="sidebar-normal">COCESNA ICCAE</span></a>
-            </li>
-            <li class="nav-item" routerlinkactive="active">
-              <a class="nav-link" href="#/components/panels"><span class="sidebar-mini">P</span><span class="sidebar-normal">CONDUSAL</span></a>
-            </li>
-            <li class="nav-item" routerlinkactive="active">
-              <a class="nav-link" href="#/components/sweet-alert"><span class="sidebar-mini">SA</span><span class="sidebar-normal">NZEB</span></a>
-            </li>
-            <li class="nav-item" routerlinkactive="active">
-              <a class="nav-link" href="#/components/notifications"><span class="sidebar-mini">N</span><span class="sidebar-normal">SIGET GERENCIA<br> ELECTRICIDAD</span></a>
-            </li>
-          </ul>
-        </div>
       </li>
-      -->
-      <hr>
     </ul>
   <div *ngIf="isMobileMenu()">
     <ul class="nav navbar-nav nav-mobile-menu-bottom">

+ 0 - 1
src/app/components/shared/sidebar/sidebar.component.scss

@@ -1,5 +1,4 @@
 ul.nav.navbar-nav.nav-mobile-menu-bottom {
   bottom: 0;
-  position: fixed;
   width: 100%;
 }

+ 25 - 4
src/app/components/shared/sidebar/sidebar.component.ts

@@ -1,6 +1,7 @@
 import { Component, OnInit } from '@angular/core';
-import { AuthService } from '../../../services/auth.service';
+import { AuthService } from '../../../services/auth2.service';
 import { Router } from '@angular/router';
+import * as CryptoJS from 'crypto-js';
 
 declare const $: any;
 declare interface RouteInfo {
@@ -8,12 +9,11 @@ declare interface RouteInfo {
     title: string;
     icon: string;
     class: string;
+    allowed_roles?:any;
 }
 export const ROUTES: RouteInfo[] = [
     { path: '/dashboard', title: 'Dashboard',  icon: 'dashboard', class: '' },
-    { path: '/organizations', title: 'Organizaciones',  icon:'location_city', class: '' },
     { path: '/assets', title: 'Plantas',  icon: 'wb_sunny', class: '' },
-    //{ path: '/reports', title: 'Reportes',  icon: 'assignment', class: '' },
     { path: '/profile', title: 'Perfil',  icon: 'person', class: '' },
     //{ path: '/profile', title: 'Perfil',  icon:'person', class: '' },
     /*{ path: '/table-list', title: 'Table List',  icon:'content_paste', class: '' },
@@ -24,6 +24,13 @@ export const ROUTES: RouteInfo[] = [
     { path: '/upgrade', title: 'Upgrade to PRO',  icon:'unarchive', class: 'active-pro' },*/
 ];
 
+// Extra options to show to the admin
+export const ADMIN_ROUTES: RouteInfo[] = [
+    { path: '/organizations', title: 'Organizaciones',  icon:'location_city', class: '', allowed_roles: [3] },
+    { path: '/plants', title: 'Plantas',  icon: 'poll', class: '', allowed_roles: [2, 3] },
+    { path: '/users', title: 'Usuarios',  icon: 'people', class: '', allowed_roles: [3] },
+];
+
 @Component({
   selector: 'app-sidebar',
   templateUrl: './sidebar.component.html',
@@ -31,11 +38,25 @@ export const ROUTES: RouteInfo[] = [
 })
 export class SidebarComponent implements OnInit {
   menuItems: any[];
+  adminMenuItems: any[];
+  adminMenu:boolean = false;
+  role_number:any;
 
-  constructor(private auth: AuthService, private router: Router) { }
+  constructor(private auth: AuthService, private router: Router) {
+    console.log(localStorage.getItem("USER_MENU"));
+    var bytes  = CryptoJS.AES.decrypt(localStorage.getItem("USER_MENU"), 'soma-inverlec-2019');
+    this.role_number = bytes.toString(CryptoJS.enc.Utf8);
+  }
 
   ngOnInit() {
     this.menuItems = ROUTES.filter(menuItem => menuItem);
+    this.adminMenuItems = ADMIN_ROUTES.filter(menuItem => menuItem);
+
+    // must be changed for the method that returns if it is an admin
+    if (this.auth.isLoggedIn() == true) {
+      this.adminMenu = true;
+    }
+
   }
   
   isMobileMenu() {

+ 1 - 0
src/app/components/users/new-user/new-user.component.html

@@ -0,0 +1 @@
+<p>new-user works!</p>

+ 0 - 0
src/app/components/users/new-user/new-user.component.scss


+ 25 - 0
src/app/components/users/new-user/new-user.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NewUserComponent } from './new-user.component';
+
+describe('NewUserComponent', () => {
+  let component: NewUserComponent;
+  let fixture: ComponentFixture<NewUserComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ NewUserComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(NewUserComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
src/app/components/users/new-user/new-user.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-new-user',
+  templateUrl: './new-user.component.html',
+  styleUrls: ['./new-user.component.scss']
+})
+export class NewUserComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 74 - 0
src/app/components/users/users.component.html

@@ -0,0 +1,74 @@
+<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">Usuarios</li>
+            </ol>
+          </nav>
+
+          <a class="btn btn-primary" [routerLink]="['/users/new']">
+            Nuevo registro
+          </a>
+        </div>
+      </div>
+
+      <div class="col-12">
+          <div class="align-container">
+
+            <h4><b>Listado de usuarios</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="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">
+                      <a class="btn btn-primary btn-sm" [routerLink]="['/plant', row.id, 'edit']"  >
+                        Editar
+                      </a>
+                    </td>
+                  </ng-container>
+          
+          
+                  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+                  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+                </table>
+                <mat-paginator [pageSizeOptions]="[5, 10, 25]"></mat-paginator>
+              </div>
+            </div>
+          </div>
+      
+      </div>
+      <br>
+      
+    </div>          
+  </div>
+</div>

+ 0 - 0
src/app/components/users/users.component.scss


+ 25 - 0
src/app/components/users/users.component.spec.ts

@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UsersComponent } from './users.component';
+
+describe('UsersComponent', () => {
+  let component: UsersComponent;
+  let fixture: ComponentFixture<UsersComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ UsersComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(UsersComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 56 - 0
src/app/components/users/users.component.ts

@@ -0,0 +1,56 @@
+import { Component, ViewChild, OnInit } from '@angular/core';
+
+import {HttpClient} from '@angular/common/http';
+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';
+
+
+
+@Component({
+  selector: 'app-users',
+  templateUrl: './users.component.html',
+  styleUrls: ['./users.component.scss']
+})
+export class UsersComponent implements OnInit {
+
+  title:string = "Plantas";
+ 
+  displayedColumns: string[] = ['name', 'country', 'city', 'id'];
+  //displayedColumns: string[] = ['state'];
+
+  listData: Plant[] = [];
+  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;
+
+
+  constructor(
+    private orgService: PlantsService) {}
+
+  ngOnInit() {
+    this.orgService.getAllAssets().subscribe(ans => {
+      this.listPlant = ans["data"];
+      console.log(this.listPlant);
+      this.dataSource.data = this.listPlant;
+      this.dataSource.paginator = this.paginator;
+      this.dataSource.sort = this.sort;
+    });
+  }
+
+  applyFilter(filterValue: string) {
+    this.dataSource.filter = filterValue.trim().toLowerCase();
+    if (this.dataSource.paginator) {
+      this.dataSource.paginator.firstPage();
+    }
+  }
+
+}

+ 2 - 1
src/app/layouts/admin/admin.component.html

@@ -7,6 +7,7 @@
         <app-navbar></app-navbar>
         <router-outlet></router-outlet>
     </div>
+    <!--
     <div class="fixed-plugin">
         <div class="dropdown show-dropdown">
             <a href="#" data-toggle="dropdown" aria-expanded="true">
@@ -49,5 +50,5 @@
                 </li>
             </ul>
         </div>
-    </div>
+    </div> -->
 </div>

+ 20 - 0
src/app/layouts/admin/admin.module.ts

@@ -16,6 +16,15 @@ import { DashboardComponent } from '../../components/dashboard/dashboard.compone
 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 { 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';
 
@@ -34,6 +43,9 @@ import {
 
 } from '@angular/material';
 
+import { BreadcrumbModule, IconsModule } from 'angular-bootstrap-md'
+
+
 @NgModule({
   imports: [
     CommonModule,
@@ -62,6 +74,14 @@ import {
     ProfileComponent,
     AssetsComponent,
     OrganizationsComponent,
+    OrganizationComponent,
+    NewOrganizationComponent,
+    EditOrganizationComponent,
+    PlantsComponent,
+    EditPlantComponent,
+    NewPlantComponent,
+    UsersComponent,
+    NewUserComponent
   ]
 })
 

+ 78 - 16
src/app/layouts/admin/admin.routing.ts

@@ -3,15 +3,17 @@ import { Routes } from '@angular/router';
 import { DashboardComponent } from '../../components/dashboard/dashboard.component';
 import { ProfileComponent } from '../../components/profile/profile.component';
 import { AssetsComponent } from '@app/components/assets/assets.component';
+import { PlantsComponent } from '@app/components/plants/plants.component';
+
 import { OrganizationsComponent } from '@app/components/organizations/organizations.component';
+import { OrganizationComponent } from '@app/components/organizations/organization/organization.component';
+import { NewOrganizationComponent } from '@app/components/organizations/new-organization/new-organization.component';
+import { EditOrganizationComponent } from '@app/components/organizations/edit-organization/edit-organization.component';
+import { EditPlantComponent } from '@app/components/plants/edit-plant/edit-plant.component';
+import { NewPlantComponent } from '@app/components/plants/new-plant/new-plant.component';
+import { UsersComponent } from '@app/components/users/users.component';
+import { NewUserComponent } from '@app/components/users/new-user/new-user.component';
 
-/*
-import { TableListComponent } from '../../table-list/table-list.component';
-import { TypographyComponent } from '../../typography/typography.component';
-import { IconsComponent } from '../../icons/icons.component';
-import { MapsComponent } from '../../maps/maps.component';
-import { NotificationsComponent } from '../../notifications/notifications.component';
-import { UpgradeComponent } from '../../upgrade/upgrade.component';*/
 
 export const AdminLayoutRoutes: Routes = [
   { path: 'dashboard',
@@ -26,15 +28,75 @@ export const AdminLayoutRoutes: Routes = [
     component: AssetsComponent,
     data: {title: "Listado de plantas"}
   },
+  // General management
+  { path: 'plants', 
+    component: PlantsComponent,
+    data: {
+      title: "Listado de plantas",
+      breadcrumb: "Plantas"
+    },
+  },
+  { path: 'plants/new', 
+    component: NewPlantComponent,
+    data: {
+      title: "Nueva planta",
+      breadcrumb: "Nueva planta"
+    },
+  },
+  { path: 'plant/:id/edit', 
+    component: EditPlantComponent,
+    data: {
+      title: "Editar planta",
+      breadcrumb: "Editar planta"
+    },
+  },
+  
+  { path: 'users', 
+    component: UsersComponent,
+    data: {
+      title: "Listado de usuarios",
+      breadcrumb: "Usuarios"
+    },
+  },
+    
+  { path: 'users/new', 
+    component: NewUserComponent,
+    data: {
+      title: "Nuevo usuario",
+      breadcrumb: "Nuevo usuario"
+    },
+  },
+
+  // Organizations actions
   { path: 'organizations', 
     component: OrganizationsComponent,
-    data: {title: "Listado de organizaciones"}
-  }
-  /*
-  { path: 'table-list',     component: TableListComponent },
-  { path: 'typography',     component: TypographyComponent },
-  { path: 'icons',          component: IconsComponent },
-  { path: 'maps',           component: MapsComponent },
-  { path: 'notifications',  component: NotificationsComponent },
-  { path: 'upgrade',        component: UpgradeComponent },*/
+    data: {
+      title: "Listado de organizaciones",
+      breadcrumb: "Organizaciones"
+    },
+  },
+  {
+    path: 'organizations/new',
+    component: NewOrganizationComponent,
+    data: {
+      title: 'Nueva organización',
+      breadcrumb:'Nueva organización'
+    }
+  },
+  {
+    path: 'organization/:id',
+    component: OrganizationComponent,
+    data: {
+      title: 'Organización'
+    }
+  },
+  {
+    path: 'organization/:id/edit',
+    component: EditOrganizationComponent,
+    data: {
+      title: 'Editar organización',
+      
+    }
+  },
+
 ];

+ 4 - 0
src/app/models/token.ts

@@ -0,0 +1,4 @@
+export class Token {
+  jwt: string;
+  refreshToken: string;
+}

+ 22 - 0
src/app/services/auth.guard.ts

@@ -0,0 +1,22 @@
+import { Injectable } from '@angular/core';
+import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { AuthService } from '../services/auth2.service';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AuthGuard implements CanActivate {
+
+  constructor(private authService: AuthService, private router: Router) { }
+
+  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
+    
+    if (this.authService.isLoggedIn()) {
+      return true
+    }
+    else {
+      this.router.navigate(['login'], { queryParams: { returnUrl: state.url }});
+      return !this.authService.isLoggedIn();
+    }
+  }
+}

+ 96 - 0
src/app/services/auth2.service.ts

@@ -0,0 +1,96 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { of, Observable } from 'rxjs';
+import { catchError, mapTo, tap } from 'rxjs/operators';
+import { Token } from '@app/models/token';
+import { environment } from '@environments/environment';
+import * as CryptoJS from 'crypto-js';
+
+@Injectable({
+  providedIn: 'root'
+})
+
+export class AuthService {
+
+  private readonly JWT_TOKEN = 'JWT_TOKEN';
+  private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
+  private readonly USER_MENU = 'USER_MENU';
+  private loggedUser: string;
+
+  constructor(private http: HttpClient) {}
+
+  login(user: { email: string, password: string}): Observable<boolean> {
+    return this.http.post<any>(`${environment.productionApiUrl}/auth/login`, user)
+      .pipe(
+        tap(tokens => this.doLoginUser(user.email, tokens)),
+        mapTo(true),
+        catchError(error => {
+          alert(error.error);
+          return of(false);
+        }));
+  }
+
+  logout() {
+    console.log("enter function");
+    return this.http.post<any>(`${environment.productionApiUrl}/auth/logout`, {
+      'refreshToken': this.getRefreshToken()
+    }).pipe(
+      tap(() => this.doLogoutUser()),
+      mapTo(true),
+      catchError(error => {
+        console.log(error.error);
+        return of(false);
+      }));
+  }
+
+  isLoggedIn() {
+    return !!this.getJwtToken();
+  }
+
+  refreshToken() {
+    return this.http.post<any>(`${environment.productionApiUrl}/auth/refresh`, {
+      'refreshToken': this.getRefreshToken()
+    }).pipe(tap((tokens: Token) => {
+      this.storeJwtToken(tokens["data"]["user"].token);
+    }));
+  }
+
+  getJwtToken() {
+    return localStorage.getItem(this.JWT_TOKEN);
+  }
+
+  private doLoginUser(email: string, tokens: Token) {
+    console.log("tokens");
+    console.log(tokens["data"]["user"].role);
+    this.loggedUser = email;
+    this.storeTokens(tokens);
+  }
+
+  private doLogoutUser() {
+    console.log("loggin out");
+    this.loggedUser = null;
+    this.removeTokens();
+  }
+
+  private getRefreshToken() {
+    return localStorage.getItem(this.REFRESH_TOKEN);
+  }
+
+  private storeJwtToken(jwt: string) {
+    localStorage.setItem(this.JWT_TOKEN, jwt);
+  }
+
+  private storeTokens(tokens: Token) {
+    localStorage.clear();
+    //console.log(CryptoJS.AES.encrypt(this.JWT_TOKEN, tokens["data"]["user"].role.toString(), 'soma-inverlec-2019').toString());
+    localStorage.setItem(this.USER_MENU, CryptoJS.AES.encrypt(tokens["data"]["user"].role.toString(), 'soma-inverlec-2019').toString())
+    localStorage.setItem(this.JWT_TOKEN, tokens["data"]["user"].token); 
+    localStorage.setItem(this.REFRESH_TOKEN, tokens["data"]["user"].refresh);
+  }
+
+  private removeTokens() {
+    localStorage.removeItem(this.USER_MENU);
+    localStorage.removeItem(this.JWT_TOKEN);
+    localStorage.removeItem(this.REFRESH_TOKEN);
+  }
+}

+ 9 - 0
src/app/services/organizations.service.ts

@@ -38,6 +38,15 @@ export class OrganizationsService {
       catchError(this.errorHandl)
     )
   }
+
+  getAllOrganizations() {
+    return this.http.get(`${environment.productionApiUrl}/organizations`)
+    .pipe(
+      map(response => {
+        return response;
+      }),
+      catchError(this.errorHandl)
+    )  }
   
   errorHandl(error) {
     let errorMessage = '';

+ 1 - 1
src/app/services/plants.service.ts

@@ -35,7 +35,7 @@ export class PlantsService extends PlantData {
   }
 
   getAllAssets(){
-    return this.http.get(`${environment.productionApiUrl}/asset`)
+    return this.http.get(`${environment.productionApiUrl}/assets`)
     .pipe(
       map(response => {
         return response;

+ 59 - 0
src/app/services/token.interceptor.ts

@@ -0,0 +1,59 @@
+import { Injectable } from '@angular/core';
+import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
+import { AuthService } from '@app/services/auth2.service';
+import { Observable, throwError, BehaviorSubject } from 'rxjs';
+import { catchError, filter, take, switchMap } from 'rxjs/operators';
+
+@Injectable()
+export class TokenInterceptor implements HttpInterceptor {
+
+  private isRefreshing = false;
+  private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
+
+  constructor(public authService: AuthService) { }
+
+  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
+
+    if (this.authService.getJwtToken()) {
+      request = this.addToken(request, this.authService.getJwtToken());
+    }
+
+    return next.handle(request).pipe(catchError(error => {
+      if (error instanceof HttpErrorResponse && error.status === 401) {
+        return this.handle401Error(request, next);
+      } else {
+        return throwError(error);
+      }
+    }));
+  }
+
+  private addToken(request: HttpRequest<any>, token: string) {
+    return request.clone({
+      setHeaders: {
+        'Authorization': `Bearer ${token}`
+      }
+    });
+  }
+
+  private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
+    if (!this.isRefreshing) {
+      this.isRefreshing = true;
+      this.refreshTokenSubject.next(null);
+
+      return this.authService.refreshToken().pipe(
+        switchMap((token: any) => {
+          this.isRefreshing = false;
+          this.refreshTokenSubject.next(token.jwt);
+          return next.handle(this.addToken(request, token.jwt));
+        }));
+
+    } else {
+      return this.refreshTokenSubject.pipe(
+        filter(token => token != null),
+        take(1),
+        switchMap(jwt => {
+          return next.handle(this.addToken(request, jwt));
+        }));
+    }
+  }
+}

+ 61 - 0
src/assets/scss/material-dashboard.scss

@@ -99,4 +99,65 @@
 .floating-title {
   font-size: 1.2rem;
   margin: 21px 65px 10px;
+}
+
+.card-icon {
+  border-radius: 3px;
+  background-color: #999;
+  padding: 15px;
+  margin-top: -30px;
+  margin-right: 15px;
+  float: left;
+  width: 60px;
+  height: 60px;
+  line-height: 40px;
+  text-align: center;
+}
+
+.breadcrumb {
+  background-color: #fff;
+}
+
+table {
+  width: 100%;
+}
+
+.mat-form-field {
+  font-size: 14px;
+  width: 100%;
+}
+
+.example-loading-shade {
+  position: absolute;
+  top: 0;
+  left: 0;
+  bottom: 56px;
+  right: 0;
+  background: rgba(0, 0, 0, 0.15);
+  z-index: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.example-rate-limit-reached {
+  color: #980000;
+  max-width: 360px;
+  text-align: center;
+}
+
+/* Structure */
+.example-container {
+  position: relative;
+  min-height: 200px;
+}
+
+.example-table-container {
+  position: relative;
+  //max-height: 400px;
+  overflow: auto;
+}
+
+.align-right {
+  text-align: right;
 }

+ 1 - 1
src/environments/environment.ts

@@ -4,7 +4,7 @@
 
 export const environment = {
     production: false,
-    apiUrl: 'http://192.168.98.140:8000',
+    apiUrl: 'https://192.168.98.140:8000',
     productionApiUrl: 'http://192.168.98.10:8888',
     appID: '55899b9ea53834f2736b65a3582b734b',
     gKey: '',