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

adjustments in api endpoints, user register, create organizations

onunez пре 6 година
родитељ
комит
c71668a6cc
29 измењених фајлова са 577 додато и 158 уклоњено
  1. 4 4
      src/app/components/assets/assets.component.ts
  2. 45 8
      src/app/components/confirm-account/confirm-account.component.html
  3. 22 0
      src/app/components/confirm-account/confirm-account.component.scss
  4. 112 1
      src/app/components/confirm-account/confirm-account.component.ts
  5. 6 26
      src/app/components/login/login.component.html
  6. 22 0
      src/app/components/login/login.component.ts
  7. 15 17
      src/app/components/organizations/edit-organization/edit-organization.component.ts
  8. 27 6
      src/app/components/organizations/new-organization/new-organization.component.html
  9. 38 20
      src/app/components/organizations/new-organization/new-organization.component.ts
  10. 8 3
      src/app/components/organizations/organizations.component.html
  11. 1 0
      src/app/components/organizations/organizations.component.scss
  12. 74 19
      src/app/components/organizations/organizations.component.ts
  13. 1 0
      src/app/components/plants/edit-plant/edit-plant.component.ts
  14. 1 0
      src/app/components/plants/new-plant/new-plant.component.ts
  15. 14 5
      src/app/components/plants/plants.component.ts
  16. 0 1
      src/app/components/plugins/plugins.module.ts
  17. 21 0
      src/app/components/plugins/validator/validator.component.ts
  18. 1 1
      src/app/components/shared/sidebar/sidebar.component.ts
  19. 16 4
      src/app/components/users/new-user/new-user.component.html
  20. 20 12
      src/app/components/users/new-user/new-user.component.ts
  21. 22 3
      src/app/components/users/users.component.ts
  22. 29 9
      src/app/layouts/admin/admin.routing.ts
  23. 7 0
      src/app/services/auth.guard.ts
  24. 6 1
      src/app/services/auth2.service.ts
  25. 6 5
      src/app/services/logs.service.ts
  26. 5 4
      src/app/services/organizations.service.ts
  27. 3 3
      src/app/services/plants.service.ts
  28. 28 5
      src/app/services/user.service.ts
  29. 23 1
      src/assets/scss/material-dashboard.scss

+ 4 - 4
src/app/components/assets/assets.component.ts

@@ -105,15 +105,14 @@ export class AssetsComponent implements OnInit {
   ngOnInit() {
 
     // Default date is today and set it on a string var and initialize dateRange plugin
-    this.initialDate = new Date("2019-09-30").toISOString().slice(0, 10);
-    console.log(this.initialDate);
+    this.initialDate = new Date().toISOString().slice(0, 10);
     if (this.myDateInit) {
-      let begin: Date = new Date("2019-09-30");
+      let begin: Date = new Date();
       this.model = {
         isRange: false, 
         singleDate: {
           date: {
-            year: begin.getFullYear(), month: begin.getMonth() + 1, day: begin.getDate() + 1
+            year: begin.getFullYear(), month: begin.getMonth() + 1, day: begin.getDate()
           }
         }
       };
@@ -171,6 +170,7 @@ export class AssetsComponent implements OnInit {
   // Change the date range of the chart, according to the selected view (daily, weekly, ...)
   onDateChanged(event: IMyDateModel) {
     let endDate = `${event.singleDate.date.year}-${event.singleDate.date.month}-${event.singleDate.date.day}`;
+    this.initialDate  = endDate;
     switch (this.view)
     { 
       case "day": 

+ 45 - 8
src/app/components/confirm-account/confirm-account.component.html

@@ -10,43 +10,80 @@
           <div class="header">
             <h1 class="lead">Confirmación de cuenta</h1>
           </div>
-          <div class="body">
-            <form [formGroup]="loginForm" (ngSubmit)="login()">
+          <div class="body" *ngIf="validToken">
+            <form [formGroup]="activateForm" (ngSubmit)="activateAccount()">
 
               <div class="form-group">
                 <label for="email">Correo electrónico</label>
-                <input type="text" name="email" class="form-control"
+                <input type="text" class="form-control"
                 formControlName="email" required email readonly />
               </div>
 
               <div class="form-group">
                 <label for="name">Nombre</label>
-                <input type="text" name="name" class="form-control"
-                formControlName="name" required />
+                <input type="text" class="form-control"
+                formControlName="first_name" required />
               </div>
 
+              
+              <div class="form-group">
+                  <label for="name">Apellido</label>
+                  <input type="text" class="form-control"
+                  formControlName="last_name" required />
+                </div>
+
               <div class="form-group">
                 <label for="password">Contraseña</label>
-                <input type="password" name="password"  class="form-control"
+                <input type="password" class="form-control"
                 formControlName="password" required minlength="6" />
               </div>
 
               <div class="form-group">
                 <label for="confirm_password">Confirmar contraseña</label>
-                <input type="password" name="confirm_password"  class="form-control"
+                <input type="password" class="form-control"
                 formControlName="confirm_password" required minlength="6" />
               </div>
 
               <br>
 
               <div class="div-center">
-                <button class="btn btn-primary" type="submit" [disabled]="!loginForm.valid"> 
+                <button class="btn btn-primary" type="submit" [disabled]="!activateForm.valid"> 
                   Confirmar cuenta
                 </button>
               </div>
 
             </form>
           </div>
+
+          <div class="body" *ngIf="invalidToken">
+            <div class="tokenError">
+              <h3>
+                {{errorMessage}}
+              </h3>
+
+              <div *ngIf="userActivated">
+                <a class="btn btn-primary" [routerLink]="['/login']">
+                  Ir a inicio de sesion
+                </a>
+              </div>
+
+            </div>
+          </div>
+
+          <div class="body" *ngIf="successActivation">
+            <div class="tokenSuccess">
+              <h3>
+                {{activateMessage}}
+              </h3>
+
+              <a class="btn btn-primary" [routerLink]="['/login']">
+                Ir a inicio de sesion
+              </a>
+
+            </div>
+          </div>
+
+
         </div>
       </div>
     </div>

+ 22 - 0
src/app/components/confirm-account/confirm-account.component.scss

@@ -70,6 +70,27 @@
   box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1);
 }
 
+.tokenError,
+.tokenSuccess {
+  padding: 40px 20px;
+  text-align: center;
+  margin-bottom: 20px;
+  font-weight: bold;
+}
+
+.tokenError {
+  color: #f44336;
+}
+
+.tokenSuccess {
+  color: #4caf50;
+}
+
+h3 {
+  font-size: 1.6rem;
+  margin-bottom: 30px;
+}
+
 @media screen and (max-width: 640px) {
   .auth-box {
       width: 90%;
@@ -82,3 +103,4 @@
       margin: 0 auto;
   }
 }
+

+ 112 - 1
src/app/components/confirm-account/confirm-account.component.ts

@@ -1,4 +1,8 @@
 import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { FormGroup, FormBuilder } from '@angular/forms';
+import { UserService } from '@app/services/user.service';
+import Swal from 'sweetalert2';
 
 @Component({
   selector: 'app-confirm-account',
@@ -6,10 +10,117 @@ import { Component, OnInit } from '@angular/core';
   styleUrls: ['./confirm-account.component.scss']
 })
 export class ConfirmAccountComponent implements OnInit {
+  token:string;
+  validToken:boolean;
+  activateForm: FormGroup;
+  errorMessage: string;
+  userActivated: boolean;
+  successActivation: boolean;
+  activateMessage: string;
+  invalidToken: boolean;
 
-  constructor() { }
+  constructor(private formBuilder: FormBuilder, private route: ActivatedRoute, private userService: UserService) {
+    this.route.queryParams.subscribe(params => {
+      console.log(params);
+      this.token = params['token'];
+    });
+  }
 
   ngOnInit() {
+    if (this.token !== null){
+      
+      this.userService.validateUserToken(
+        {
+          token: this.token
+        }
+      ).subscribe(res => {
+        
+        let userData = res.data.user;
+
+        this.validToken = true;
+        this.activateForm = this.formBuilder.group({
+          // Load information
+          email: [(userData.email)],
+          first_name: [(userData.first_name)],
+          last_name: [(userData.last_name)],
+          password: [''],
+          confirm_password: ['']
+        });
+      }, (err) => {
+       
+        this.userActivated = true;
+        this.invalidToken = true;
+        this.errorMessage = err.message;
+      });
+    
+    }
+    else {
+      this.invalidToken = true;
+      this.errorMessage = "No existe el token";
+    }
+  }
+
+  get f() { return this.activateForm.controls; }
+
+
+  activateAccount(){
+    this.userService.activateUser(
+      {
+        email: this.f.email.value,
+        first_name: this.f.first_name.value,
+        last_name: this.f.last_name.value,
+        password: this.f.password.value,
+        confirm_password: this.f.confirm_password.value,
+      }
+    ).subscribe(res => {
+      this.successActivation = true;
+      this.validToken = false;
+      this.activateMessage = "Usuario registrado con exito";
+
+    }, (err) => {
+      this.validToken = false;
+      this.errorMessage = err.message;
+    });
+
+    //
+
   }
 
 }
+
+
+/*
+
+Swal.fire({
+      allowOutsideClick: false,
+      type: 'info',
+      text: 'Espere por favor...'
+    });
+    Swal.showLoading();
+
+    this.authService.login(
+      {
+        email: this.f.email.value,
+        password: this.f.password.value
+      }
+    )
+    .subscribe(success => {
+      if (success) {
+        window.location.href="#/dashboard";
+      }
+      else {
+        Swal.fire({
+          type: 'error',
+          title: 'No se pudo auntenticar',
+          text: "Email o contraseña incorrecta"
+        })  
+      }
+    },(err) => {
+      Swal.fire({
+        type: 'error',
+        title: 'Error en el servidor',
+        text: "No su pudo obtener la informacion"
+      });
+    });
+
+    */

+ 6 - 26
src/app/components/login/login.component.html

@@ -10,43 +10,23 @@
             <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" >
+            <form [formGroup]="loginForm" (ngSubmit)="login()">
               <div class="form-group">
                 <label for="email">Correo electrónico</label>
                 
                 <input type="text" name="email" class="form-control"
-                        [(ngModel)]="user.email"  required email />
-
+                formControlName="email" required email />
+  
               </div>
               <div class="form-group">
                 <label for="password">Contraseña</label>
                 <input type="password" name="password"  class="form-control"
-                        [(ngModel)]="user.password" required minlength="6" />
+                formControlName="password" required minlength="5" />
               </div>
-              <button class="btn btn-primary">
+  
+              <button class="btn btn-primary" type="submit" [disabled]="!loginForm.valid"> 
                 Iniciar sesión
               </button>
-              <!--<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>-->
             </form>
           </div>
         </div>

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

@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
 import { FormGroup, FormBuilder } from '@angular/forms';
 import { Router } from '@angular/router';
 import { AuthService } from '@app/services/auth2.service';
+import Swal from 'sweetalert2';
 
 @Component({
   selector: 'app-login',
@@ -24,6 +25,14 @@ export class LoginComponent implements OnInit {
   get f() { return this.loginForm.controls; }
 
   login() {
+
+    Swal.fire({
+      allowOutsideClick: false,
+      type: 'info',
+      text: 'Espere por favor...'
+    });
+    Swal.showLoading();
+
     this.authService.login(
       {
         email: this.f.email.value,
@@ -34,6 +43,19 @@ export class LoginComponent implements OnInit {
       if (success) {
         window.location.href="#/dashboard";
       }
+      else {
+        Swal.fire({
+          type: 'error',
+          title: 'No se pudo auntenticar',
+          text: "Email o contraseña incorrecta"
+        })  
+      }
+    },(err) => {
+      Swal.fire({
+        type: 'error',
+        title: 'Error en el servidor',
+        text: "No su pudo obtener la informacion"
+      });
     });
   }
 

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

@@ -1,8 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { OrganizationsService } from '@app/services/organizations.service';
-import { FormBuilder, FormGroup } from '@angular/forms';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute } from '@angular/router';
-
 import Swal from 'sweetalert2';
 
 @Component({
@@ -17,18 +16,17 @@ export class EditOrganizationComponent implements OnInit {
   organizationExists:boolean;
   organizationForm: FormGroup;
   organizationId:any;
+  role_number: any;
 
   constructor(private orgService: OrganizationsService, private formBuilder: FormBuilder, private route: ActivatedRoute) {
+
     this.route.params.subscribe(params => {
-      console.log(params);
       this.organizationId = params['id'];
     });
 
     this.orgService.getOrganization(this.organizationId).subscribe(res => {
       this.listOrganization = res["data"]["organization"];
       this.organizationExists = true;
-      console.log(this.listOrganization["name"]);
-      console.log(this.organizationExists);
 
       this.organizationForm = this.formBuilder.group({
         name: [this.listOrganization.name],
@@ -75,29 +73,29 @@ export class EditOrganizationComponent implements OnInit {
   get f() { return this.organizationForm.controls; }
 
   editOrganization() {
-    /*
-      this.orgService.editOrganization(
+      this.orgService.updateOrganization(this.organizationId, 
         {
-          name: this.f.name.value
-          address: this.f.address.value
-          city: this.f.city.value
-          country: this.f.country.value
-          contactName: this.f.contactName.value
-          contactNumber: this.f.contactNumber.value
+          name: this.f.name.value,
+          address: this.f.address.value,
+          city: this.f.city.value,
+          country: this.f.country.value,
+          contactName: this.f.contactName.value,
+          contactNumber: this.f.contactNumber.value,
+          assets: [""],
         }
       )
     .subscribe(success => {
       if (success) {
         Swal.fire({
           allowOutsideClick: false,
-          type: 'info',
-          text: 'Espere por favor...'
+          type: 'success',
+          text: 'Informacion actualizada con exito'
         });
-        window.location.href="#/dashboard";
+        //window.location.href="#/dashboard";
 
       }
       
-    });*/
+    });
   }
 
 

+ 27 - 6
src/app/components/organizations/new-organization/new-organization.component.html

@@ -31,32 +31,53 @@
                 <form class="form-auth-small ng-untouched ng-pristine ng-valid" [formGroup]="organizationForm" (ngSubmit)="createOrganization()">
                   <div class="form-group">
                     <label for="name">Nombre de la organización: </label>
-                    <input type="text" name="name" class="form-control" required />
+                    <input type="text" formControlName="name" class="form-control"  [ngClass]="{ 'is-invalid': submitted && f.name.errors }"/>
+                    <div *ngIf="submitted && f.name.errors" class="invalid-feedback">
+                      <div *ngIf="f.name.errors.required">Campo requerido</div>
+                    </div>
                   </div>
 
+
                   <div class="form-group">
                     <label for="country">País: </label>
-                    <input type="text" name="country" class="form-control" required />
+                    <input type="text" formControlName="country" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.country.errors }"/>
+                    <div *ngIf="submitted && f.country.errors" class="invalid-feedback">
+                      <div *ngIf="f.country.errors.required">Campo requerido</div>
+                    </div>
+
                   </div>
                   
                   <div class="form-group">
                     <label for="city">Ciudad: </label>
-                    <input type="text" name="city" class="form-control" required />
+                    <input type="text" formControlName="city" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.city.errors }"/>
+                    <div *ngIf="submitted && f.city.errors" class="invalid-feedback">
+                      <div *ngIf="f.city.errors.required">Campo requerido</div>
+                    </div>
+
                   </div>      
                   
                   <div class="form-group">
                     <label for="contactName">Nombre contacto: </label>
-                    <input type="text" name="contactName" class="form-control" required />
+                    <input type="text" formControlName="contactName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.contactName.errors }"/>
+                    <div *ngIf="submitted && f.contactName.errors" class="invalid-feedback">
+                      <div *ngIf="f.contactName.errors.required">Campo requerido</div>
+                    </div>
                   </div>
 
                   <div class="form-group">
                     <label for="contactNumber">Teléfono contacto: </label>
-                    <input type="text" name="contactNumber" class="form-control" required />
+                    <input type="text" formControlName="contactNumber" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.contactNumber.errors }"/>
+                    <div *ngIf="submitted && f.contactNumber.errors" class="invalid-feedback">
+                      <div *ngIf="f.contactNumber.errors.required">Campo requerido</div>
+                    </div>
                   </div>
                   
                   <div class="form-group">
                     <label for="address">Dirección: </label>
-                    <textarea name="address" class="form-control" rows="2" required ></textarea>
+                    <textarea formControlName="address" class="form-control" rows="2" [ngClass]="{ 'is-invalid': submitted && f.address.errors }" ></textarea>
+                    <div *ngIf="submitted && f.address.errors" class="invalid-feedback">
+                      <div *ngIf="f.address.errors.required">Campo requerido</div>
+                    </div>
                   </div>
                   <br>
                   <button class="btn btn-primary">

+ 38 - 20
src/app/components/organizations/new-organization/new-organization.component.ts

@@ -1,7 +1,8 @@
 import { Component, OnInit } from '@angular/core';
-import { FormGroup, FormBuilder } from '@angular/forms';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { OrganizationsService } from '@app/services/organizations.service';
 import Swal from 'sweetalert2';
+import * as CryptoJS from 'crypto-js';
 
 @Component({
   selector: 'app-new-organization',
@@ -11,48 +12,65 @@ import Swal from 'sweetalert2';
 export class NewOrganizationComponent implements OnInit {
   title:string = "Nueva organización"; 
   organizationForm: FormGroup;
+  submitted: boolean = false;
+  role_number: any;
 
 
   constructor(private orgService: OrganizationsService, private formBuilder: FormBuilder) {
+
   }
 
   ngOnInit() {
     this.organizationForm = this.formBuilder.group({
-      name: [''],
-      address: [''],
-      city: [''],
-      country: [''],
-      contactName: [''],
-      contactNumber: [''],
+      name: ['', Validators.required],
+      address: ['', Validators.required],
+      city: ['', Validators.required],
+      country: ['', Validators.required],
+      contactName: ['', Validators.required],
+      contactNumber: ['', Validators.required],
     });
   }
 
   get f() { return this.organizationForm.controls; }
 
   createOrganization() {
-    
-      this.orgService.createOrganization(
-        {
-          name: this.f.name.value,
-          address: this.f.address.value,
-          city: this.f.city.value,
-          country: this.f.country.value,
-          contactName: this.f.contactName.value,
-          contactNumber: this.f.contactNumber.value
-        }
-      )
+    this.submitted = true;
+
+    // stop here if form is invalid
+    if (this.organizationForm.invalid) {
+      return;
+    }
+
+    this.orgService.createOrganization(
+      {
+        name: this.f.name.value,
+        address: this.f.address.value,
+        city: this.f.city.value,
+        country: this.f.country.value,
+        contactName: this.f.contactName.value,
+        contactNumber: this.f.contactNumber.value,
+        assets: [""],
+      }
+    )
     .subscribe(success => {
       if (success) {
         Swal.fire({
           allowOutsideClick: false,
-          type: 'info',
-          text: 'Espere por favor...'
+          type: 'success',
+          text: 'Registro agregado con exito'
         });
         //window.location.href="#/dashboard";
 
       }
       
     });
+    Swal.fire({
+      allowOutsideClick: false,
+      type: 'success',
+      text: 'Registro agregado con exito'
+    });
+
+
   }
 
 

+ 8 - 3
src/app/components/organizations/organizations.component.html

@@ -57,9 +57,14 @@
                   <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]="['/organization', row.id, 'edit']"  >
-                        Editar
-                      </a>
+                      <div class="action-buttons">
+                        <a class="btn btn-primary btn-sm" [routerLink]="['/organization', row.id, 'edit']"  >
+                          Editar
+                        </a>
+                        <a class="btn btn-danger btn-sm" (click)="delete_organization(row.id)"  >
+                          Eliminar
+                        </a>
+                      </div>
                     </td>
                   </ng-container>
           

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

@@ -0,0 +1 @@
+

+ 74 - 19
src/app/components/organizations/organizations.component.ts

@@ -1,20 +1,10 @@
 import { Component, ViewChild, OnInit } from '@angular/core';
 import { Organization } from "@app/models/organization";
 import { OrganizationsService } from "@app/services/organizations.service";
-
-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';
-
-import {NgbDate, NgbCalendar} from '@ng-bootstrap/ng-bootstrap';
-
-import {AngularMyDatePickerDirective,IAngularMyDpOptions, IMyDateModel} from 'angular-mydatepicker';
-
+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-organizations',
@@ -31,17 +21,23 @@ export class OrganizationsComponent implements OnInit {
   listData: Organization[] = [];
   listOrganization:any;
   dataSource = new MatTableDataSource(this.listData);
-
   resultsLength = 0;
   isLoadingResults = true;
   isRateLimitReached = false;
 
   @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
   @ViewChild(MatSort, {static: true}) sort: MatSort;
+  role_number: any;
 
 
-  constructor(
-    private orgService: OrganizationsService) {}
+  constructor(private orgService: OrganizationsService) {
+    Swal.fire({
+      allowOutsideClick: false,
+      type: 'info',
+      text: 'Espere por favor...'
+    });
+    Swal.showLoading();
+  }
 
   ngOnInit() {
     this.orgService.getListOrganizations().subscribe(res =>
@@ -53,8 +49,67 @@ export class OrganizationsComponent implements OnInit {
       this.dataSource.data = this.listOrganization;
       this.dataSource.paginator = this.paginator;
       this.dataSource.sort = this.sort;
-      
+    }, (err) => {
+      Swal.fire({
+        type: 'error',
+        title: 'Error en el servidor',
+        text: "No su pudo obtener la informacion"
+      });
     });
+    
+    //this.chartjs = true;
+    setTimeout(()=>{
+      Swal.close();
+    }, 1200);
+
+  }
+
+  delete_organization(id: string){
+    Swal.fire({
+      allowOutsideClick: false,
+      type: 'warning',
+      title: '¿Esta seguro?',
+      text: 'No podrá revertir esta acción',
+      showCancelButton: true,
+      confirmButtonColor: '#3085d6',
+      cancelButtonColor: '#d33',
+      confirmButtonText: 'Borrar registro',
+    })
+    .then((result) => {
+        if (result.value) {
+          this.delete_organization2(id);
+        }
+    });
+  }
+
+  delete_organization2(id: string){
+    this.orgService.deleteOrganization(id)
+    .subscribe(
+      data => {
+        if (data["success"] == true) {
+          //document.getElementById(id).remove();
+          Swal.fire({
+            allowOutsideClick: false,
+            type: 'success',
+            text: 'Registro eliminado con exito'
+          });
+          //window.location.href="#/organizations";
+        }
+        else {
+          Swal.fire({
+            allowOutsideClick: false,
+            type: 'error',
+            text: "No tienes permiso para eliminar el registro"
+          });
+        }  
+      },
+      err => {
+        Swal.fire({
+          type: 'error',
+          title: 'Error en el servidor',
+          text: err.message
+        });
+      });
   }
 
   applyFilter(filterValue: string) {
@@ -64,4 +119,4 @@ export class OrganizationsComponent implements OnInit {
     }
   }
 
-}
+}

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

@@ -1,4 +1,5 @@
 import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 
 @Component({
   selector: 'app-edit-plant',

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

@@ -1,4 +1,5 @@
 import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 
 @Component({
   selector: 'app-new-plant',

+ 14 - 5
src/app/components/plants/plants.component.ts

@@ -1,13 +1,12 @@
 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';
+import Swal from 'sweetalert2';
 
 @Component({
   selector: 'app-plants',
@@ -33,8 +32,14 @@ export class PlantsComponent implements OnInit {
   @ViewChild(MatSort, {static: true}) sort: MatSort;
 
 
-  constructor(
-    private orgService: PlantsService) {}
+  constructor(private orgService: PlantsService) {
+    Swal.fire({
+      allowOutsideClick: false,
+      type: 'info',
+      text: 'Espere por favor...'
+    });
+    Swal.showLoading();
+  }
 
   ngOnInit() {
     this.orgService.getAllAssets().subscribe(ans => {
@@ -43,6 +48,10 @@ export class PlantsComponent implements OnInit {
       this.dataSource.paginator = this.paginator;
       this.dataSource.sort = this.sort;
     });
+
+    setTimeout(()=>{
+      Swal.close();
+    }, 1000);
   }
 
   applyFilter(filterValue: string) {

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

@@ -29,7 +29,6 @@ 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";

+ 21 - 0
src/app/components/plugins/validator/validator.component.ts

@@ -0,0 +1,21 @@
+import { FormGroup } from '@angular/forms';
+
+// custom validator to check that two fields match
+export function ValidatorComponent(controlName: string, matchingControlName: string) {
+    return (formGroup: FormGroup) => {
+        const control = formGroup.controls[controlName];
+        const matchingControl = formGroup.controls[matchingControlName];
+
+        if (matchingControl.errors && !matchingControl.errors.mustMatch) {
+            // return if another validator has already found an error on the matchingControl
+            return;
+        }
+
+        // set error on matchingControl if validation fails
+        if (control.value !== matchingControl.value) {
+            matchingControl.setErrors({ mustMatch: true });
+        } else {
+            matchingControl.setErrors(null);
+        }
+    }
+}

+ 1 - 1
src/app/components/shared/sidebar/sidebar.component.ts

@@ -26,7 +26,7 @@ export const ROUTES: RouteInfo[] = [
 
 // Extra options to show to the admin
 export const ADMIN_ROUTES: RouteInfo[] = [
-    { path: '/organizations', title: 'Organizaciones',  icon:'location_city', class: '', allowed_roles: [3] },
+    { path: '/organizations', title: 'Organizaciones',  icon:'location_city', class: '', allowed_roles: [2,3] },
     { path: '/plants', title: 'Plantas',  icon: 'poll', class: '', allowed_roles: [2, 3] },
     { path: '/users', title: 'Usuarios',  icon: 'people', class: '', allowed_roles: [3] },
 ];

+ 16 - 4
src/app/components/users/new-user/new-user.component.html

@@ -31,22 +31,34 @@
                 <form class="form-auth-small ng-untouched ng-pristine ng-valid" [formGroup]="userForm" (ngSubmit)="createUser()">
                   <div class="form-group">
                     <label for="first_name">Nombre: </label>
-                    <input type="text" name="first_name" class="form-control" required />
+                    <input type="text" formControlName="first_name" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.first_name.errors }"/>
+                    <div *ngIf="submitted && f.first_name.errors" class="invalid-feedback">
+                      <div *ngIf="f.first_name.errors.required">Campo requerido</div>
+                    </div>
                   </div>
 
                   <div class="form-group">
                     <label for="last_name">Apellido: </label>
-                    <input type="text" name="last_name" class="form-control" required />
+                    <input type="text" formControlName="last_name" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.last_name.errors }"/>
+                    <div *ngIf="submitted && f.last_name.errors" class="invalid-feedback">
+                      <div *ngIf="f.last_name.errors.required">Campo requerido</div>
+                    </div>
                   </div>
                   
                   <div class="form-group">
                     <label for="email">Email: </label>
-                    <input type="text" name="email" class="form-control" required />
+                    <input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.email.errors }"/>
+                    <div *ngIf="submitted && f.email.errors" class="invalid-feedback">
+                      <div *ngIf="f.email.errors.required">Campo requerido</div>
+                    </div>
                   </div>      
                   
                   <div class="form-group">
                     <label for="role">Rol: </label>
-                    <input type="text" name="role" class="form-control" required />
+                    <input type="text" formControlName="role" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.role.errors }"/>
+                    <div *ngIf="submitted && f.role.errors" class="invalid-feedback">
+                      <div *ngIf="f.role.errors.required">Campo requerido</div>
+                    </div>
                   </div>
                   <br>
                   <button class="btn btn-primary">

+ 20 - 12
src/app/components/users/new-user/new-user.component.ts

@@ -1,5 +1,5 @@
 import { Component, OnInit } from '@angular/core';
-import { FormGroup, FormBuilder } from '@angular/forms';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
 import { UserService } from '@app/services/user.service';
 import Swal from 'sweetalert2';
 
@@ -10,32 +10,40 @@ import Swal from 'sweetalert2';
 })
 export class NewUserComponent implements OnInit {
   title:string = "Nuevo usuario"; 
-  organizationForm: FormGroup;
+  userForm: FormGroup;
+  submitted: boolean= false;
 
 
   constructor(private userService: UserService, private formBuilder: FormBuilder) {
   }
 
   ngOnInit() {
-    this.organizationForm = this.formBuilder.group({
-      first_name: [''],
-      last_name: [''],
-      email: [''],
-      role: [''],
+
+
+    this.userForm = this.formBuilder.group({
+      first_name: ['', Validators.required],
+      last_name: ['', Validators.required],
+      email: ['', Validators.required],
+      role: ['', Validators.required],
     });
   }
 
-  get f() { return this.organizationForm.controls; }
+  get f() { return this.userForm.controls; }
 
-  createOrganization() {
+  createUser() {
+    this.submitted = true;
+
+    // stop here if form is invalid
+    if (this.userForm.invalid) {
+      return;
+    }
     
       this.userService.createUser(
         {
           first_name: this.f.first_name.value,
           last_name: this.f.last_name.value,
           email: this.f.email.value,
-          role: this.f.role.value,
-
+          role: +this.f.role.value,
         }
       )
     .subscribe(success => {
@@ -43,7 +51,7 @@ export class NewUserComponent implements OnInit {
         Swal.fire({
           allowOutsideClick: false,
           type: 'info',
-          text: 'Espere por favor...'
+          text: 'Usuario creado con exito'
         });
         //window.location.href="#/dashboard";
 

+ 22 - 3
src/app/components/users/users.component.ts

@@ -6,7 +6,7 @@ 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({
@@ -31,10 +31,18 @@ export class UsersComponent implements OnInit {
 
   @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
   @ViewChild(MatSort, {static: true}) sort: MatSort;
+  role_number: any;
+
 
+  constructor(private userService: UserService) {
 
-  constructor(
-    private userService: UserService) {}
+    Swal.fire({
+      allowOutsideClick: false,
+      type: 'info',
+      text: 'Espere por favor...'
+    });
+    Swal.showLoading();
+  }
 
   ngOnInit() {
     this.userService.getAllUsers().subscribe(ans => {
@@ -42,7 +50,18 @@ export class UsersComponent implements OnInit {
       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: "No su pudo obtener la informaci&oacute;n"
+      });
     });
+
+    setTimeout(()=>{
+      Swal.close();
+    }, 1200);
+
   }
 
   applyFilter(filterValue: string) {

+ 29 - 9
src/app/layouts/admin/admin.routing.ts

@@ -13,6 +13,7 @@ import { EditPlantComponent } from '@app/components/plants/edit-plant/edit-plant
 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 { AuthGuard } from '@app/services/auth.guard';
 
 
 export const AdminLayoutRoutes: Routes = [
@@ -31,71 +32,90 @@ export const AdminLayoutRoutes: Routes = [
   // General management
   { path: 'plants', 
     component: PlantsComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: "Listado de plantas",
-      breadcrumb: "Plantas"
+      breadcrumb: "Plantas",
+      roles: [2,3]
     },
   },
   { path: 'plants/new', 
     component: NewPlantComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: "Nueva planta",
-      breadcrumb: "Nueva planta"
+      breadcrumb: "Nueva planta",
+      roles: [3]
     },
   },
   { path: 'plant/:id/edit', 
     component: EditPlantComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: "Editar planta",
-      breadcrumb: "Editar planta"
+      breadcrumb: "Editar planta",
+      roles: [2,3]
     },
   },
   
   { path: 'users', 
     component: UsersComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: "Listado de usuarios",
-      breadcrumb: "Usuarios"
+      breadcrumb: "Usuarios",
+      roles: [3]
     },
   },
     
   { path: 'users/new', 
     component: NewUserComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: "Nuevo usuario",
-      breadcrumb: "Nuevo usuario"
+      breadcrumb: "Nuevo usuario",
+      roles: [3]
     },
   },
 
   // Organizations actions
   { path: 'organizations', 
     component: OrganizationsComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: "Listado de organizaciones",
-      breadcrumb: "Organizaciones"
+      breadcrumb: "Organizaciones",
+      roles: [2,3]
     },
   },
   {
     path: 'organizations/new',
     component: NewOrganizationComponent,
+    canActivate: [AuthGuard], 
     data: {
       title: 'Nueva organización',
-      breadcrumb:'Nueva organización'
+      breadcrumb:'Nueva organización',
+      roles: [3]
     }
   },
   {
     path: 'organization/:id',
     component: OrganizationComponent,
+    canActivate: [AuthGuard], 
     data: {
-      title: 'Organización'
+      title: 'Organización',
+      breadcrumb: 'Detalle',
+      roles: [2,3]
     }
   },
   {
     path: 'organization/:id/edit',
+    canActivate: [AuthGuard], 
     component: EditOrganizationComponent,
     data: {
       title: 'Editar organización',
-      
+      breadcrumb: 'Editar organización',
+      roles: [3]
     }
   },
 

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

@@ -10,7 +10,14 @@ export class AuthGuard implements CanActivate {
   constructor(private authService: AuthService, private router: Router) { }
 
   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
+    
     if (this.authService.isLoggedIn()) {
+      const userLevel = +this.authService.getUserLevel();
+      if (route.data.roles && route.data.roles.indexOf(userLevel) === -1) {
+        // role not authorised so redirect to home page
+        this.router.navigate(['/']);
+        return false;
+      }
       return true
     }
     else {

+ 6 - 1
src/app/services/auth2.service.ts

@@ -25,7 +25,6 @@ export class AuthService {
         tap(tokens => this.doLoginUser(user.email, tokens)),
         mapTo(true),
         catchError(error => {
-          alert(error.error);
           return of(false);
         }));
   }
@@ -44,6 +43,12 @@ export class AuthService {
     return !!this.getJwtToken();
   }
 
+  getUserLevel() {
+    var bytes  = CryptoJS.AES.decrypt(localStorage.getItem("USER_MENU"), 'soma-inverlec-2019');
+    var role_number = bytes.toString(CryptoJS.enc.Utf8);
+    return role_number;
+  }
+
   refreshToken() {
     let refreshToken:string = this.getRefreshToken();
     return this.http.post<any>(`${environment.productionApiUrl}/auth/refresh`, {

+ 6 - 5
src/app/services/logs.service.ts

@@ -84,16 +84,17 @@ export class LogsService {
     )
   }
 
+  //if(error.error instanceof ErrorEvent) {
   errorHandl(error) {
     let errorMessage = '';
-    if(error.error instanceof ErrorEvent) {
+    if(error.error) {
       // Get client-side error
-      errorMessage = error.error.message;
+      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);
- }
-
+  }
+  
 }

+ 5 - 4
src/app/services/organizations.service.ts

@@ -52,7 +52,7 @@ export class OrganizationsService {
 
   createOrganization(organization: { name :string, address :string, 
     city :string, country :string, contactName :string,
-    contactNumber: string}): Observable<boolean> {
+    contactNumber: string, assets:any}): Observable<boolean> {
       return this.http.post<any>(`${environment.productionApiUrl}/organizations`, organization)
       .pipe(
         map(response => {
@@ -64,7 +64,7 @@ export class OrganizationsService {
   
   updateOrganization(id:string, organization: { name :string, address :string, 
     city :string, country :string, contactName :string,
-    contactNumber: string}): Observable<boolean> {
+    contactNumber: string, assets:any}): Observable<boolean> {
       return this.http.put<any>(`${environment.productionApiUrl}/organization/${id}`, organization)
       .pipe(
         map(response => {
@@ -95,12 +95,13 @@ export class OrganizationsService {
   
   errorHandl(error) {
     let errorMessage = '';
-    if(error.error instanceof ErrorEvent) {
+    if(error.error) {
       // Get client-side error
-      errorMessage = error.error.message;
+      errorMessage = error.error;
     } else {
       // Get server-side error
       errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
+      
     }
     return throwError(errorMessage);
  }

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

@@ -105,12 +105,12 @@ export class PlantsService extends PlantData {
   
   errorHandl(error) {
     let errorMessage = '';
-    if(error.error instanceof ErrorEvent) {
+    if(error.error) {
       // Get client-side error
-      errorMessage = error.error.message;
+      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);
  }

+ 28 - 5
src/app/services/user.service.ts

@@ -20,7 +20,7 @@ export class UserService {
   }
 
   createUser(user: { first_name :string, last_name :string, 
-    email :string, role :string }): Observable<boolean> {
+    email :string, role :number }): Observable<boolean> {
       return this.http.post<any>(`${environment.productionApiUrl}/users`, user)
       .pipe(
         map(response => {
@@ -30,15 +30,38 @@ export class UserService {
       )  
   }
 
+  validateUserToken(user: {token :string}): Observable<boolean> {
+      return this.http.post<any>(`${environment.productionApiUrl}/user/tokenvalidation`, user)
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      )  
+  }
+  
+  activateUser(user: { first_name :string, last_name :string, 
+    email :string, password: string, confirm_password :string }): Observable<boolean> {
+      return this.http.post<any>(`${environment.productionApiUrl}/user/activate`, user)
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      )  
+  }
+
+
   errorHandl(error) {
     let errorMessage = '';
-    if(error.error instanceof ErrorEvent) {
+    if(error.error) {
       // Get client-side error
-      errorMessage = error.error.message;
+      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);
-  }
+ }
+
 }

+ 23 - 1
src/assets/scss/material-dashboard.scss

@@ -160,4 +160,26 @@ table {
 
 .align-right {
   text-align: right;
-}
+}
+
+
+.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 {
+  background-size: 18px;
+}
+
+.action-buttons {
+  text-align: right;
+
+  .btn-danger {
+    color: $white !important;
+  }
+
+  a {
+    color: $white;
+  }
+}