Commit 62dcd0610776754b2ba24568210515a9593ae41c

Authored by Eric Fernandez
Exists in master and in 1 other branch validar_pve

Merge branch 'master' of http://git.focasoftware.com/angular/autoservicio

src/app/app.module.ts
... ... @@ -7,6 +7,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
7 7 import { TooltipModule } from 'ngx-bootstrap/tooltip';
8 8 import { PopoverModule } from 'ngx-bootstrap/popover';
9 9 import { CarouselModule } from 'ngx-bootstrap/carousel';
  10 +import { PaginationModule } from 'ngx-bootstrap/pagination';
10 11 //#endregion
11 12  
12 13 //#region Keyboard
... ... @@ -61,7 +62,8 @@ import { MensajeFinalComponent } from './components/mensaje-final/mensaje-final.
61 62 BrowserAnimationsModule,
62 63 MatKeyboardModule,
63 64 MatButtonModule,
64   - CarouselModule.forRoot()
  65 + CarouselModule.forRoot(),
  66 + PaginationModule.forRoot()
65 67 ],
66 68 providers: [],
67 69 bootstrap: [AppComponent]
src/app/components/amb-imagenes/amb-imagenes.component.html
... ... @@ -3,11 +3,11 @@
3 3 <div class="container-fluid">
4 4 <div class="row m-3">
5 5 <div class="col">
6   - <p class="h2">Configuración imágenes</p>
  6 + <p class="h2">Configuración de imágenes</p>
7 7 </div>
8 8 </div>
9 9  
10   - <div class="row search">
  10 + <div class="row mx-3 search">
11 11 <div class="col">
12 12 <span class="fa fa-search form-control-lg form-control-search pl-3"></span>
13 13 <input
... ... @@ -19,30 +19,86 @@
19 19 </div>
20 20 </div>
21 21  
22   - <div class="row m-3 vh-70 overflow-scroll">
  22 + <div class="row m-3 vh-60 overflow-scroll">
23 23 <div class="col">
24 24 <h5>Productos</h5>
25   - <table class="table">
  25 + <table class="table table-striped table-hover table-borderless shadow">
26 26 <thead>
27   - <tr class="text-center">
  27 + <tr class="bg-primary text-center text-white shadow-sm">
28 28 <th>Nombre</th>
29   - <th>Descripción</th>
30 29 <th colspan="2">Imagen</th>
31 30 </tr>
32 31 </thead>
33 32 <tbody>
34   - <tr *ngFor="let articulo of auxProductos">
35   - <td>{{articulo.DET_LAR}}</td>
36   - <td>{{articulo.DET_LAR}}</td>
  33 + <tr class="shadow-sm" *ngFor="let articulo of auxProductos">
  34 + <td class="align-middle">
  35 + <p class="m-0">{{articulo.DET_LAR}}</p>
  36 + <p class="m-0"><small>Descripción: {{articulo.DET_LAR}}</small></p>
  37 + <p class="m-0"><small>Sector: {{articulo.CodSec}}</small></p>
  38 + <p class="m-0"><small>Código: {{articulo.CodArt}}</small></p>
  39 + </td>
37 40 <td>
38   - <img *ngIf="articulo.imagenes.length" src="{{apiUrl}}/imagenes/{{articulo.imagenes[0].imagen}}">
39   - <img id="{{articulo.CodSec + articulo.CodArt}}" [hidden]="articulo.imagenes.length">
  41 + <img
  42 + *ngIf="articulo.imagenes.length == 0"
  43 + class="fade-in w-100 mx-auto img-fluid"
  44 + src="{{apiUrl}}/imagenes/noImage.jpg">
  45 + <carousel [interval]="false">
  46 + <slide *ngFor="let item of articulo.imagenes; let index = index">
  47 + <img
  48 + *ngIf="!item.fromGallery"
  49 + class="fade-in img-fluid w-100"
  50 + src="{{apiUrl}}/imagenes/{{item.imagen}}">
  51 + <img
  52 + *ngIf="item.fromGallery"
  53 + class="fade-in img-fluid w-100"
  54 + src="{{item.base64}}">
  55 + <button
  56 + (click)="deleteImage(articulo.imagenes, index)"
  57 + type="button"
  58 + class="btn btn-light btn-delete-image position-absolute close">
  59 + <span aria-hidden="true">&times;</span>
  60 + </button>
  61 + </slide>
  62 + </carousel>
  63 + </td>
  64 + <td class="align-middle text-center">
  65 + <div class="custom-file">
  66 + <input
  67 + type="file"
  68 + class="custom-file-input"
  69 + id="customFileLang"
  70 + accept="image/*"
  71 + (change)="onFileSelected($event, articulo)"
  72 + lang="es"
  73 + multiple>
  74 + <label class="custom-file-label text-left pr-5" for="customFileLang">
  75 + <small>Seleccionar archivo</small>
  76 + </label>
  77 + </div>
40 78 </td>
41   - <td><input type="file" accept="image/*" (change)="onFileSelected($event, articulo)"></td>
42 79 </tr>
43 80 </tbody>
44 81 </table>
45 82 </div>
46 83 </div>
47 84  
  85 + <div class="row" *ngIf="paginationData">
  86 + <div class="col">
  87 + <pagination
  88 + [rotate]="false"
  89 + [(ngModel)]="paginationData.page"
  90 + [totalItems]="paginationData.rowCount"
  91 + [maxSize]="paginationData.pageCount"
  92 + [itemsPerPage]="paginationData.pageSize"
  93 + (pageChanged)="pageChanged($event)"
  94 + [boundaryLinks]="true"
  95 + [disabled]="disabledPaginador"
  96 + previousText="&lsaquo;"
  97 + nextText="&rsaquo;"
  98 + firstText="&laquo;"
  99 + lastText="&raquo;"
  100 + ></pagination>
  101 + </div>
  102 + </div>
  103 +
48 104 </div>
src/app/components/amb-imagenes/amb-imagenes.component.scss
... ... @@ -7,3 +7,12 @@
7 7 color: #aaa;
8 8 line-height: inherit;
9 9 }
  10 +
  11 +.custom-file-input:lang(es) ~ .custom-file-label::after {
  12 + content: "Elegir";
  13 +}
  14 +
  15 +.btn-delete-image {
  16 + top: 0;
  17 + left: 95%;
  18 +}
src/app/components/amb-imagenes/amb-imagenes.component.ts
... ... @@ -16,51 +16,67 @@ export class AmbImagenesComponent implements OnInit {
16 16 articulos: Producto[] = [];
17 17 private auxProductos: Producto[] = [];
18 18 private searchTerm: string = '';
  19 + private paginationData: any;
  20 + private disabledPaginador: boolean = false;
19 21  
20   - constructor(private productoService: ProductoService, private http: HttpClient) {}
  22 + constructor(private productoService: ProductoService, private http: HttpClient) { }
21 23  
22 24 ngOnInit() {
23 25  
24   - this.productoService.getAll().subscribe((productos: Producto[]) => {
25   - this.articulos = productos;
26   - this.filterItems();
27   - });
28   - }
29   -
30   - onFileSelected(event, articulo) {
31   -
32   - let file: File = event.target.files[0];
  26 + this.productoService.getAllWithPaginator()
  27 + .subscribe((res) => {
33 28  
34   - this.onLoad(file)
35   - .then(result => {
36   -
37   - articulo.imagenes = [];
38   -
39   - document.getElementById(articulo.CodSec + articulo.CodArt)['src'] = result;
  29 + this.articulos = res.data;
  30 + this.paginationData = res.pagination;
  31 + this.filterItems();
  32 + }, error => console.error(error));
  33 + }
40 34  
41   - this.saveInBase({
42   - name: file.name,
43   - base64: result,
44   - codigo: articulo.CodArt,
45   - sector: articulo.CodSec
  35 + onFileSelected(event, articulo: Producto) {
  36 +
  37 + let auxFiles: FileList = event.target.files;
  38 + Array.from(auxFiles).forEach(file => {
  39 +
  40 + this.onLoad(file)
  41 + .then(result => {
  42 + // articulo.imagenes.push({
  43 + // name: file.name + articulo.CodArt + articulo.CodSec,
  44 + // fromGallery: true,
  45 + // imagen: result,
  46 + // id_articulo: articulo.id
  47 + // });
  48 + let imagenAguardar = {
  49 + imagen: {
  50 + name: `${articulo.CodSec}${articulo.CodArt}${file.name}`,
  51 + base64: result,
  52 + codigo: articulo.CodArt,
  53 + sector: articulo.CodSec,
  54 + id_articulo: articulo.id
  55 + },
  56 + articulo: articulo
  57 + };
  58 + this.saveInBase(imagenAguardar);
46 59 });
47   - });
  60 + })
48 61 }
49 62  
50 63 filterItems() {
51 64  
52 65 this.auxProductos = this.articulos.filter(x => {
53   - return x.DET_LAR.toLowerCase().includes(this.searchTerm.toLowerCase())
  66 + return x.DET_LAR.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
  67 + x.CodArt.toString().includes(this.searchTerm.toLowerCase()) ||
  68 + x.CodSec.toString().includes(this.searchTerm.toLowerCase());
54 69 });
55 70 }
56 71  
  72 + saveInBase(imagenAguardar) {
57 73  
58   - saveInBase(img) {
59   -
60   - this.http.post(`${appSettings.apiUrl}/imagenes/guardar`, img)
61   - .subscribe(data => {
62   - console.log(data);
63   - });
  74 + this.productoService.saveInBase(imagenAguardar.imagen)
  75 + .subscribe(res => {
  76 + imagenAguardar.imagen['id'] = res[0];
  77 + imagenAguardar.imagen['fromGallery'] = true;
  78 + imagenAguardar.articulo.imagenes.push(imagenAguardar.imagen);
  79 + }, error => console.error(error));
64 80 }
65 81  
66 82 onLoad(file) {
... ... @@ -69,7 +85,7 @@ export class AmbImagenesComponent implements OnInit {
69 85  
70 86 var fr = new FileReader();
71 87  
72   - fr.onload = function() {
  88 + fr.onload = function () {
73 89  
74 90 resolve(fr.result);
75 91 };
... ... @@ -78,4 +94,31 @@ export class AmbImagenesComponent implements OnInit {
78 94 });
79 95  
80 96 }
  97 +
  98 + deleteImage(imagenes, index: number) {
  99 +
  100 + if (!imagenes[index].name) {
  101 + imagenes[index].name = imagenes[index].imagen;
  102 + }
  103 +
  104 + this.productoService.deleteImage(imagenes[index])
  105 + .subscribe(res => {
  106 +
  107 + if (res) {
  108 + imagenes.splice(index, 1);
  109 + }
  110 + }, error => console.error(error));
  111 + }
  112 +
  113 + pageChanged(event: any): void {
  114 + this.disabledPaginador = true;
  115 + this.productoService.getAllWithPaginator(event.page)
  116 + .subscribe((res) => {
  117 + this.disabledPaginador = false;
  118 + this.articulos = res.data;
  119 + this.paginationData = res.pagination;
  120 + this.filterItems();
  121 + }, error => console.error(error));
  122 + }
  123 +
81 124 }
src/app/services/producto.service.ts
... ... @@ -21,9 +21,14 @@ export class ProductoService {
21 21 return this.http.get(`${appSettings.apiUrl}/articulos/${id}`);
22 22 }
23 23  
24   - getAll(): Observable<any> {
  24 + getAll(page: number = 1): Observable<any> {
25 25  
26   - return this.http.get(`${appSettings.apiUrl}/articulos`);
  26 + return this.http.get(`${appSettings.apiUrl}/articulos/`);
  27 + }
  28 +
  29 + getAllWithPaginator(page: number = 1): Observable<any> {
  30 +
  31 + return this.http.get(`${appSettings.apiUrl}/articulos/${page}`);
27 32 }
28 33  
29 34 setProductos(producto: Producto) {
... ... @@ -69,10 +74,14 @@ export class ProductoService {
69 74 return this.http.get(url);
70 75 }
71 76  
72   - updateImages(body): Observable<any> {
  77 + saveInBase(body): Observable<any> {
73 78 return this.http.post(`${appSettings.apiUrl}/imagenes/guardar`, body);
74 79 }
75 80  
  81 + deleteImage(body): Observable<any> {
  82 + return this.http.post(`${appSettings.apiUrl}/imagen/borrar`, body);
  83 + }
  84 +
76 85 getCategorias() {
77 86 return this.http.get(`${appSettings.apiUrl}/categorias`);
78 87 }
... ... @@ -158,3 +158,8 @@ body {
158 158 .min-h-55 {
159 159 min-height: 55px;
160 160 }
  161 +
  162 +.pagination {
  163 + justify-content: center !important;
  164 + display: flex !important;
  165 +}