Commit 88149dfd0f7078f132684804678a66a44f00ca7f
Exists in
master
Merge branch 'master' into 'master'
Master(mpuebla) See merge request !64
Showing
6 changed files
 
Show diff stats
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,85 @@ | 
| 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.imagen}}"> | |
| 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">×</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 | + previousText="‹" | |
| 96 | + nextText="›" | |
| 97 | + firstText="«" | |
| 98 | + lastText="»" | |
| 99 | + ></pagination> | |
| 100 | + </div> | |
| 101 | + </div> | |
| 102 | + | |
| 48 | 103 | </div> | 
src/app/components/amb-imagenes/amb-imagenes.component.scss
src/app/components/amb-imagenes/amb-imagenes.component.ts
| ... | ... | @@ -16,51 +16,62 @@ export class AmbImagenesComponent implements OnInit { | 
| 16 | 16 | articulos: Producto[] = []; | 
| 17 | 17 | private auxProductos: Producto[] = []; | 
| 18 | 18 | private searchTerm: string = ''; | 
| 19 | + private paginationData: any; | |
| 19 | 20 | |
| 20 | - constructor(private productoService: ProductoService, private http: HttpClient) {} | |
| 21 | + constructor(private productoService: ProductoService, private http: HttpClient) { } | |
| 21 | 22 | |
| 22 | 23 | ngOnInit() { | 
| 23 | 24 | |
| 24 | - this.productoService.getAll().subscribe((productos: Producto[]) => { | |
| 25 | - this.articulos = productos; | |
| 26 | - this.filterItems(); | |
| 27 | - }); | |
| 28 | - } | |
| 25 | + this.productoService.getAllWithPaginator() | |
| 26 | + .subscribe((res) => { | |
| 29 | 27 | |
| 30 | - onFileSelected(event, articulo) { | |
| 28 | + this.articulos = res.data; | |
| 29 | + this.paginationData = res.pagination; | |
| 30 | + this.filterItems(); | |
| 31 | + }, error => console.error(error)); | |
| 32 | + } | |
| 31 | 33 | |
| 32 | - let file: File = event.target.files[0]; | |
| 34 | + onFileSelected(event, articulo: Producto) { | |
| 33 | 35 | |
| 34 | - this.onLoad(file) | |
| 35 | - .then(result => { | |
| 36 | + let auxFiles: FileList = event.target.files; | |
| 37 | + Array.from(auxFiles).forEach(file => { | |
| 36 | 38 | |
| 37 | - articulo.imagenes = []; | |
| 39 | + this.onLoad(file) | |
| 40 | + .then(result => { | |
| 38 | 41 | |
| 39 | - document.getElementById(articulo.CodSec + articulo.CodArt)['src'] = result; | |
| 42 | + articulo.imagenes.push({ | |
| 43 | + name: file.name, | |
| 44 | + fromGallery: true, | |
| 45 | + imagen: result, | |
| 46 | + id_articulo: articulo.id | |
| 47 | + }); | |
| 40 | 48 | |
| 41 | - this.saveInBase({ | |
| 42 | - name: file.name, | |
| 43 | - base64: result, | |
| 44 | - codigo: articulo.CodArt, | |
| 45 | - sector: articulo.CodSec | |
| 49 | + this.saveInBase({ | |
| 50 | + name: file.name, | |
| 51 | + base64: result, | |
| 52 | + codigo: articulo.CodArt, | |
| 53 | + sector: articulo.CodSec | |
| 54 | + }); | |
| 46 | 55 | }); | 
| 47 | - }); | |
| 56 | + }) | |
| 48 | 57 | } | 
| 49 | 58 | |
| 50 | 59 | filterItems() { | 
| 51 | 60 | |
| 52 | 61 | this.auxProductos = this.articulos.filter(x => { | 
| 53 | - return x.DET_LAR.toLowerCase().includes(this.searchTerm.toLowerCase()) | |
| 62 | + return x.DET_LAR.toLowerCase().includes(this.searchTerm.toLowerCase()) || | |
| 63 | + x.CodArt.toString().includes(this.searchTerm.toLowerCase()) || | |
| 64 | + x.CodSec.toString().includes(this.searchTerm.toLowerCase()); | |
| 54 | 65 | }); | 
| 55 | 66 | } | 
| 56 | 67 | |
| 57 | 68 | |
| 58 | 69 | saveInBase(img) { | 
| 59 | 70 | |
| 60 | - this.http.post(`${appSettings.apiUrl}/imagenes/guardar`, img) | |
| 71 | + this.productoService.saveInBase(img) | |
| 61 | 72 | .subscribe(data => { | 
| 62 | - console.log(data); | |
| 63 | - }); | |
| 73 | + | |
| 74 | + }, error => console.error(error)); | |
| 64 | 75 | } | 
| 65 | 76 | |
| 66 | 77 | onLoad(file) { | 
| ... | ... | @@ -69,7 +80,7 @@ export class AmbImagenesComponent implements OnInit { | 
| 69 | 80 | |
| 70 | 81 | var fr = new FileReader(); | 
| 71 | 82 | |
| 72 | - fr.onload = function() { | |
| 83 | + fr.onload = function () { | |
| 73 | 84 | |
| 74 | 85 | resolve(fr.result); | 
| 75 | 86 | }; | 
| ... | ... | @@ -78,4 +89,30 @@ export class AmbImagenesComponent implements OnInit { | 
| 78 | 89 | }); | 
| 79 | 90 | |
| 80 | 91 | } | 
| 92 | + | |
| 93 | + deleteImage(imagenes, index: number) { | |
| 94 | + | |
| 95 | + if (!imagenes[index].name) { | |
| 96 | + imagenes[index].name = imagenes[index].imagen; | |
| 97 | + } | |
| 98 | + | |
| 99 | + this.productoService.deleteImage(imagenes[index]) | |
| 100 | + .subscribe(res => { | |
| 101 | + | |
| 102 | + if (res) { | |
| 103 | + imagenes.splice(index, 1); | |
| 104 | + } | |
| 105 | + }, error => console.error(error)); | |
| 106 | + } | |
| 107 | + | |
| 108 | + pageChanged(event: any): void { | |
| 109 | + this.productoService.getAllWithPaginator(event.page) | |
| 110 | + .subscribe((res) => { | |
| 111 | + | |
| 112 | + this.articulos = res.data; | |
| 113 | + this.paginationData = res.pagination; | |
| 114 | + this.filterItems(); | |
| 115 | + }, error => console.error(error)); | |
| 116 | + } | |
| 117 | + | |
| 81 | 118 | } | 
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 | } |