Commit c6f805b12e01eeb7e74c6904a3f095416f8dd4c5
1 parent
83489bb986
Exists in
master
First commit
Showing
24 changed files
with
948 additions
and
25 deletions
Show diff stats
.gitignore
angular.json
... | ... | @@ -28,9 +28,14 @@ |
28 | 28 | "src/assets" |
29 | 29 | ], |
30 | 30 | "styles": [ |
31 | + "./node_modules/bootstrap/dist/css/bootstrap.min.css", | |
31 | 32 | "src/styles.scss" |
32 | 33 | ], |
33 | - "scripts": [] | |
34 | + "scripts": [ | |
35 | + "node_modules/jquery/dist/jquery.slim.min.js", | |
36 | + "node_modules/popper.js/dist/umd/popper.min.js", | |
37 | + "node_modules/bootstrap/dist/js/bootstrap.min.js" | |
38 | + ] | |
34 | 39 | }, |
35 | 40 | "configurations": { |
36 | 41 | "production": { |
package-lock.json
... | ... | @@ -2191,6 +2191,11 @@ |
2191 | 2191 | "multicast-dns-service-types": "^1.1.0" |
2192 | 2192 | } |
2193 | 2193 | }, |
2194 | + "bootstrap": { | |
2195 | + "version": "4.3.1", | |
2196 | + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz", | |
2197 | + "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==" | |
2198 | + }, | |
2194 | 2199 | "brace-expansion": { |
2195 | 2200 | "version": "1.1.11", |
2196 | 2201 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", |
... | ... | @@ -5372,6 +5377,11 @@ |
5372 | 5377 | "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", |
5373 | 5378 | "dev": true |
5374 | 5379 | }, |
5380 | + "jquery": { | |
5381 | + "version": "3.4.1", | |
5382 | + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", | |
5383 | + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" | |
5384 | + }, | |
5375 | 5385 | "js-tokens": { |
5376 | 5386 | "version": "3.0.2", |
5377 | 5387 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", |
... | ... | @@ -6946,6 +6956,11 @@ |
6946 | 6956 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", |
6947 | 6957 | "dev": true |
6948 | 6958 | }, |
6959 | + "ngx-bootstrap": { | |
6960 | + "version": "5.1.1", | |
6961 | + "resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-5.1.1.tgz", | |
6962 | + "integrity": "sha512-++6+YHbIWTR/3sHH9C0aelIP25KMKhylWSEet6HonZfVr8quzEUjq6xEzTnDbZpnxlly2j58Gg0O9DWXu0UCxA==" | |
6963 | + }, | |
6949 | 6964 | "nice-try": { |
6950 | 6965 | "version": "1.0.5", |
6951 | 6966 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", |
... | ... | @@ -7705,6 +7720,11 @@ |
7705 | 7720 | "find-up": "^3.0.0" |
7706 | 7721 | } |
7707 | 7722 | }, |
7723 | + "popper.js": { | |
7724 | + "version": "1.15.0", | |
7725 | + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz", | |
7726 | + "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==" | |
7727 | + }, | |
7708 | 7728 | "portfinder": { |
7709 | 7729 | "version": "1.0.23", |
7710 | 7730 | "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.23.tgz", |
package.json
... | ... | @@ -19,6 +19,10 @@ |
19 | 19 | "@angular/platform-browser": "~8.2.0", |
20 | 20 | "@angular/platform-browser-dynamic": "~8.2.0", |
21 | 21 | "@angular/router": "~8.2.0", |
22 | + "bootstrap": "^4.3.1", | |
23 | + "jquery": "^3.4.1", | |
24 | + "ngx-bootstrap": "^5.1.1", | |
25 | + "popper.js": "^1.15.0", | |
22 | 26 | "rxjs": "~6.4.0", |
23 | 27 | "tslib": "^1.10.0", |
24 | 28 | "zone.js": "~0.9.1" |
src/app/app-routing.module.ts
1 | 1 | import { NgModule } from '@angular/core'; |
2 | 2 | import { Routes, RouterModule } from '@angular/router'; |
3 | +import { AbmImagenesComponent } from './components/abm-imagenes/abm-imagenes.component'; | |
3 | 4 | |
4 | 5 | |
5 | -const routes: Routes = []; | |
6 | +const routes: Routes = [ | |
7 | + { path: '', component: AbmImagenesComponent }, | |
8 | + { path: 'abm-imagenes', component: AbmImagenesComponent }, | |
9 | + { path: '**', redirectTo: '/home', pathMatch: 'full' }, | |
10 | +]; | |
6 | 11 | |
7 | 12 | @NgModule({ |
8 | 13 | imports: [RouterModule.forRoot(routes)], |
src/app/app.component.html
1 | -<!--The content below is only a placeholder and can be replaced.--> | |
2 | -<div style="text-align:center"> | |
3 | - <h1> | |
4 | - Welcome to {{ title }}! | |
5 | - </h1> | |
6 | - <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="> | |
7 | -</div> | |
8 | -<h2>Here are some links to help you start: </h2> | |
9 | -<ul> | |
10 | - <li> | |
11 | - <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> | |
12 | - </li> | |
13 | - <li> | |
14 | - <h2><a target="_blank" rel="noopener" href="https://angular.io/cli">CLI Documentation</a></h2> | |
15 | - </li> | |
16 | - <li> | |
17 | - <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2> | |
18 | - </li> | |
19 | -</ul> | |
20 | - | |
21 | 1 | <router-outlet></router-outlet> |
src/app/app.module.ts
... | ... | @@ -3,14 +3,20 @@ import { NgModule } from '@angular/core'; |
3 | 3 | |
4 | 4 | import { AppRoutingModule } from './app-routing.module'; |
5 | 5 | import { AppComponent } from './app.component'; |
6 | +import { AbmImagenesComponent } from './components/abm-imagenes/abm-imagenes.component'; | |
7 | +import { PaginationModule } from 'ngx-bootstrap/pagination'; | |
8 | +import { HeaderComponent } from './components/header/header.component'; | |
6 | 9 | |
7 | 10 | @NgModule({ |
8 | 11 | declarations: [ |
9 | - AppComponent | |
12 | + AppComponent, | |
13 | + AbmImagenesComponent, | |
14 | + HeaderComponent | |
10 | 15 | ], |
11 | 16 | imports: [ |
12 | 17 | BrowserModule, |
13 | - AppRoutingModule | |
18 | + AppRoutingModule, | |
19 | + PaginationModule.forRoot() | |
14 | 20 | ], |
15 | 21 | providers: [], |
16 | 22 | bootstrap: [AppComponent] |
src/app/components/abm-imagenes/abm-imagenes.component.html
... | ... | @@ -0,0 +1,105 @@ |
1 | +<p>abm-imagenes works!</p> | |
2 | +<app-header></app-header> | |
3 | + | |
4 | +<div class="container-fluid"> | |
5 | + <div class="row m-3"> | |
6 | + <div class="col"> | |
7 | + <p class="h2">Configuraciรณn de imรกgenes</p> | |
8 | + </div> | |
9 | + </div> | |
10 | + | |
11 | + <div class="row mx-3 search"> | |
12 | + <div class="col"> | |
13 | + <span class="fa fa-search form-control-lg form-control-search pl-3"></span> | |
14 | + <input | |
15 | + type="text" | |
16 | + class="form-control form-control-lg shadow-sm rounded-pill px-5" | |
17 | + placeholder="Bรบsqueda productos" | |
18 | + [(ngModel)]="searchTerm" | |
19 | + (ngModelChange)="filterItems()"> | |
20 | + </div> | |
21 | + </div> | |
22 | + | |
23 | + <div class="row m-3 vh-60 overflow-scroll"> | |
24 | + <div class="col"> | |
25 | + <h5>Productos</h5> | |
26 | + <table class="table table-striped table-hover table-borderless shadow"> | |
27 | + <thead> | |
28 | + <tr class="bg-primary text-center text-white shadow-sm"> | |
29 | + <th>Nombre</th> | |
30 | + <th colspan="2">Imagen</th> | |
31 | + </tr> | |
32 | + </thead> | |
33 | + <tbody> | |
34 | + <tr class="shadow-sm" *ngFor="let articulo of auxProductos"> | |
35 | + <td class="align-middle"> | |
36 | + <p class="m-0">{{articulo.DET_LAR}}</p> | |
37 | + <p class="m-0"><small>Descripciรณn: {{articulo.DET_LAR}}</small></p> | |
38 | + <p class="m-0"><small>Sector: {{articulo.CodSec}}</small></p> | |
39 | + <p class="m-0"><small>Cรณdigo: {{articulo.CodArt}}</small></p> | |
40 | + </td> | |
41 | + <td> | |
42 | + <img | |
43 | + *ngIf="articulo.imagenes.length == 0" | |
44 | + class="fade-in w-100 mx-auto img-fluid" | |
45 | + src="{{apiUrl}}/imagenes/noImage.jpg"> | |
46 | + <carousel [interval]="false"> | |
47 | + <slide *ngFor="let item of articulo.imagenes; let index = index"> | |
48 | + <img | |
49 | + *ngIf="!item.fromGallery" | |
50 | + class="fade-in img-fluid w-100" | |
51 | + src="{{apiUrl}}/imagenes/{{item.imagen}}"> | |
52 | + <img | |
53 | + *ngIf="item.fromGallery" | |
54 | + class="fade-in img-fluid w-100" | |
55 | + src="{{item.base64}}"> | |
56 | + <button | |
57 | + (click)="deleteImage(articulo.imagenes, index)" | |
58 | + type="button" | |
59 | + class="btn btn-light btn-delete-image position-absolute close"> | |
60 | + <span aria-hidden="true">×</span> | |
61 | + </button> | |
62 | + </slide> | |
63 | + </carousel> | |
64 | + </td> | |
65 | + <td class="align-middle text-center"> | |
66 | + <div class="custom-file"> | |
67 | + <input | |
68 | + type="file" | |
69 | + class="custom-file-input" | |
70 | + id="customFileLang" | |
71 | + accept="image/*" | |
72 | + (change)="onFileSelected($event, articulo)" | |
73 | + lang="es" | |
74 | + multiple> | |
75 | + <label class="custom-file-label text-left pr-5" for="customFileLang"> | |
76 | + <small>Seleccionar archivo</small> | |
77 | + </label> | |
78 | + </div> | |
79 | + </td> | |
80 | + </tr> | |
81 | + </tbody> | |
82 | + </table> | |
83 | + </div> | |
84 | + </div> | |
85 | + | |
86 | + <div class="row" *ngIf="paginationData"> | |
87 | + <div class="col"> | |
88 | + <pagination | |
89 | + [rotate]="false" | |
90 | + [(ngModel)]="paginationData.page" | |
91 | + [totalItems]="paginationData.rowCount" | |
92 | + [maxSize]="paginationData.pageCount" | |
93 | + [itemsPerPage]="paginationData.pageSize" | |
94 | + (pageChanged)="pageChanged($event)" | |
95 | + [boundaryLinks]="true" | |
96 | + [disabled]="disabledPaginador" | |
97 | + previousText="‹" | |
98 | + nextText="›" | |
99 | + firstText="«" | |
100 | + lastText="»" | |
101 | + ></pagination> | |
102 | + </div> | |
103 | + </div> | |
104 | + | |
105 | +</div> |
src/app/components/abm-imagenes/abm-imagenes.component.scss
... | ... | @@ -0,0 +1,18 @@ |
1 | +.search .form-control-search { | |
2 | + position: absolute; | |
3 | + z-index: 2; | |
4 | + display: block; | |
5 | + text-align: center; | |
6 | + pointer-events: none; | |
7 | + color: #aaa; | |
8 | + line-height: inherit; | |
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/abm-imagenes/abm-imagenes.component.spec.ts
... | ... | @@ -0,0 +1,25 @@ |
1 | +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { AbmImagenesComponent } from './abm-imagenes.component'; | |
4 | + | |
5 | +describe('AbmImagenesComponent', () => { | |
6 | + let component: AbmImagenesComponent; | |
7 | + let fixture: ComponentFixture<AbmImagenesComponent>; | |
8 | + | |
9 | + beforeEach(async(() => { | |
10 | + TestBed.configureTestingModule({ | |
11 | + declarations: [ AbmImagenesComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + })); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(AbmImagenesComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/components/abm-imagenes/abm-imagenes.component.ts
... | ... | @@ -0,0 +1,124 @@ |
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | +import { appSettings } from 'src/etc/AppSettings'; | |
3 | +import { ImagenesService } from 'src/app/services/imagenes.service'; | |
4 | +import { Producto } from 'src/app/wrappers/producto'; | |
5 | +import { HttpClient } from '@angular/common/http'; | |
6 | + | |
7 | +@Component({ | |
8 | + selector: 'app-amb-imagenes', | |
9 | + templateUrl: './abm-imagenes.component.html', | |
10 | + styleUrls: ['./abm-imagenes.component.scss'] | |
11 | +}) | |
12 | + | |
13 | +export class AbmImagenesComponent implements OnInit { | |
14 | + | |
15 | + apiUrl = appSettings.apiImagenes; | |
16 | + articulos: Producto[] = []; | |
17 | + private auxProductos: Producto[] = []; | |
18 | + private searchTerm: string = ''; | |
19 | + private paginationData: any; | |
20 | + private disabledPaginador: boolean = false; | |
21 | + | |
22 | + constructor(private productoService: ImagenesService, private http: HttpClient) { } | |
23 | + | |
24 | + ngOnInit() { | |
25 | + | |
26 | + this.productoService.getAllWithPaginator() | |
27 | + .subscribe((res) => { | |
28 | + | |
29 | + this.articulos = res.data; | |
30 | + this.paginationData = res.pagination; | |
31 | + this.filterItems(); | |
32 | + }, error => console.error(error)); | |
33 | + } | |
34 | + | |
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); | |
59 | + }); | |
60 | + }) | |
61 | + } | |
62 | + | |
63 | + filterItems() { | |
64 | + | |
65 | + this.auxProductos = this.articulos.filter(x => { | |
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()); | |
69 | + }); | |
70 | + } | |
71 | + | |
72 | + saveInBase(imagenAguardar) { | |
73 | + | |
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)); | |
80 | + } | |
81 | + | |
82 | + onLoad(file) { | |
83 | + | |
84 | + return new Promise((resolve, reject) => { | |
85 | + | |
86 | + var fr = new FileReader(); | |
87 | + | |
88 | + fr.onload = function () { | |
89 | + | |
90 | + resolve(fr.result); | |
91 | + }; | |
92 | + | |
93 | + fr.readAsDataURL(file); | |
94 | + }); | |
95 | + | |
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 | + | |
124 | +} |
src/app/components/header/header.component.html
... | ... | @@ -0,0 +1,8 @@ |
1 | +<div class="row m-0 bg-light p-4 justify-content-between"> | |
2 | + <div class="col-6"> | |
3 | + <img class="w-25 float-left" src="{{apiImagenes}}/imagenes/logoempresa.png"> | |
4 | + </div> | |
5 | + <div class="col-6"> | |
6 | + <img class="w-25 float-right" src="{{apiImagenes}}/imagenes/logodebo.png"> | |
7 | + </div> | |
8 | +</div> |
src/app/components/header/header.component.scss
src/app/components/header/header.component.spec.ts
... | ... | @@ -0,0 +1,25 @@ |
1 | +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { HeaderComponent } from './header.component'; | |
4 | + | |
5 | +describe('HeaderComponent', () => { | |
6 | + let component: HeaderComponent; | |
7 | + let fixture: ComponentFixture<HeaderComponent>; | |
8 | + | |
9 | + beforeEach(async(() => { | |
10 | + TestBed.configureTestingModule({ | |
11 | + declarations: [ HeaderComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + })); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(HeaderComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/components/header/header.component.ts
... | ... | @@ -0,0 +1,18 @@ |
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | +import { appSettings } from 'src/etc/AppSettings'; | |
3 | + | |
4 | +@Component({ | |
5 | + selector: 'app-header', | |
6 | + templateUrl: './header.component.html', | |
7 | + styleUrls: ['./header.component.scss'] | |
8 | +}) | |
9 | +export class HeaderComponent implements OnInit { | |
10 | + | |
11 | + private apiImagenes : string = appSettings.apiImagenes; | |
12 | + | |
13 | + constructor() { } | |
14 | + | |
15 | + ngOnInit() { | |
16 | + } | |
17 | + | |
18 | +} |
src/app/services/imagenes.service.spec.ts
... | ... | @@ -0,0 +1,12 @@ |
1 | +import { TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { ImagenesService } from './imagenes.service'; | |
4 | + | |
5 | +describe('ImagenesService', () => { | |
6 | + beforeEach(() => TestBed.configureTestingModule({})); | |
7 | + | |
8 | + it('should be created', () => { | |
9 | + const service: ImagenesService = TestBed.get(ImagenesService); | |
10 | + expect(service).toBeTruthy(); | |
11 | + }); | |
12 | +}); |
src/app/services/imagenes.service.ts
... | ... | @@ -0,0 +1,28 @@ |
1 | +import { Injectable } from '@angular/core'; | |
2 | +import { HttpClient } from '@angular/common/http'; | |
3 | +import { Observable } from 'rxjs'; | |
4 | +import { appSettings } from 'src/etc/AppSettings'; | |
5 | + | |
6 | +@Injectable({ | |
7 | + providedIn: 'root' | |
8 | +}) | |
9 | +export class ImagenesService { | |
10 | + | |
11 | + constructor(private http: HttpClient) { } | |
12 | + | |
13 | + getAllWithPaginator(page: number = 1): Observable<any> { | |
14 | + | |
15 | + return this.http.get(`${appSettings.apiImagenes}/articulos/${page}`); | |
16 | + } | |
17 | + | |
18 | + saveInBase(body): Observable<any> { | |
19 | + | |
20 | + return this.http.post(`${appSettings.apiImagenes}/imagenes/guardar`, body); | |
21 | + } | |
22 | + | |
23 | + deleteImage(body): Observable<any> { | |
24 | + | |
25 | + return this.http.post(`${appSettings.apiImagenes}/imagen/borrar`, body); | |
26 | + } | |
27 | + | |
28 | +} |
src/app/wrappers/categoria.ts
src/app/wrappers/producto.ts
... | ... | @@ -0,0 +1,98 @@ |
1 | +export interface Producto { | |
2 | + CodSec: number; | |
3 | + CodArt: number; | |
4 | + DetArt: string; | |
5 | + CodRub: number; | |
6 | + Costo: number; | |
7 | + PreNet: number; | |
8 | + ImpInt: number; | |
9 | + UniVen: number; | |
10 | + FecCos: Date; | |
11 | + UltAct: Date; | |
12 | + CodPro: number; | |
13 | + ExiDep: number; | |
14 | + ExiVta: number; | |
15 | + MinDep: number; | |
16 | + MaxDep: number; | |
17 | + MinPVE: number; | |
18 | + MaxPVE: number; | |
19 | + ENTTur: number; | |
20 | + SINTur: number; | |
21 | + SALTur: number; | |
22 | + IvaSN: boolean; | |
23 | + DepSN: boolean; | |
24 | + RubMay: number; | |
25 | + PreVen: number; | |
26 | + IvaCO: number; | |
27 | + TIP: string; | |
28 | + IMPIVA: number; | |
29 | + ENTADM: number; | |
30 | + SALADM: number; | |
31 | + CODIIN: number; | |
32 | + PRO: boolean; | |
33 | + FPP: boolean; | |
34 | + ESS: boolean; | |
35 | + FID: Date; | |
36 | + NID: number; | |
37 | + FIV: Date; | |
38 | + NIV: number; | |
39 | + COO: string; | |
40 | + CAG: string; | |
41 | + CAP: number; | |
42 | + UTL: number; | |
43 | + NHA: boolean; | |
44 | + PID: boolean; | |
45 | + PRV: number; | |
46 | + PRD: number; | |
47 | + ImpInt2: number; | |
48 | + E_HD: string; | |
49 | + C_HD: string; | |
50 | + CLA: number; | |
51 | + UNICAP: number; | |
52 | + ELBPRO: string; | |
53 | + PPP: number; | |
54 | + ALI: number; | |
55 | + BAL_TIPO: string; | |
56 | + PER_MAY: boolean; | |
57 | + ES_MAY: boolean; | |
58 | + CLA_MAY: number; | |
59 | + PME_CMP: string; | |
60 | + USA_BAL: boolean; | |
61 | + DET_LAR: string; | |
62 | + ROTULO: string; | |
63 | + REC_MANUAL: boolean; | |
64 | + E_HD1: string; | |
65 | + C_HD1: string; | |
66 | + ImpInt3: number; | |
67 | + FUA_MAE_YPF: Date; | |
68 | + CPQ: number; | |
69 | + EPQ: string; | |
70 | + BPQ: number; | |
71 | + PUPQ: number; | |
72 | + CORVTO: boolean; | |
73 | + CORVTO_COSTO: number; | |
74 | + UTLFR: number; | |
75 | + FAMILIA: number; | |
76 | + ES_LUB: boolean; | |
77 | + ES_FERT: boolean; | |
78 | + AutoFac: boolean; | |
79 | + LitrosPCD: number; | |
80 | + LisPCD: number; | |
81 | + ImpLey23966: boolean; | |
82 | + es_bio: boolean; | |
83 | + ExpArbaRev: boolean; | |
84 | + ES_AGROQ: boolean; | |
85 | + ES_PLAST: boolean; | |
86 | + es_bio_por: string; | |
87 | + IMP_IMP_INT: boolean; | |
88 | + id: number; | |
89 | + nombreImagen?: any; | |
90 | + categoria_selfservice: number; | |
91 | + cantidad?: number; | |
92 | + esPadre?: boolean; | |
93 | + codigoBarra: string; | |
94 | + idSinonimo?: number; | |
95 | + productos?: Producto[]; | |
96 | + tieneSinonimos?: boolean; | |
97 | + imagenes: object[] | |
98 | +} |
src/app/wrappers/sinonimo.ts
src/assets/scss/animation.scss
... | ... | @@ -0,0 +1,177 @@ |
1 | +.fade-in { | |
2 | + -webkit-animation: fadein 0.6s cubic-bezier(0.39, 0.575, 0.565, 1) both; | |
3 | + animation: fadein 0.6s cubic-bezier(0.39, 0.575, 0.565, 1) both; | |
4 | +} | |
5 | + | |
6 | +@-webkit-keyframes fadein { | |
7 | + 0% { | |
8 | + -webkit-transform: translateZ(80px); | |
9 | + transform: translateZ(80px); | |
10 | + opacity: 0; | |
11 | + } | |
12 | + 100% { | |
13 | + -webkit-transform: translateZ(0); | |
14 | + transform: translateZ(0); | |
15 | + opacity: 1; | |
16 | + } | |
17 | +} | |
18 | + | |
19 | +@keyframes fadein { | |
20 | + 0% { | |
21 | + -webkit-transform: translateZ(80px); | |
22 | + transform: translateZ(80px); | |
23 | + opacity: 0; | |
24 | + } | |
25 | + 100% { | |
26 | + -webkit-transform: translateZ(0); | |
27 | + transform: translateZ(0); | |
28 | + opacity: 1; | |
29 | + } | |
30 | +} | |
31 | + | |
32 | +.fade-right { | |
33 | + animation: faderight 1s; | |
34 | + -moz-animation: faderight 1s; /* Firefox */ | |
35 | + -webkit-animation: faderight 1s; /* Safari and Chrome */ | |
36 | + -o-animation: faderight 1s; /* Opera */ | |
37 | +} | |
38 | + | |
39 | +@keyframes faderight { | |
40 | + from { | |
41 | + opacity: 0; | |
42 | + transform: translateX(-20px); | |
43 | + } | |
44 | + to { | |
45 | + opacity: 1; | |
46 | + transform: translateX(0); | |
47 | + } | |
48 | +} | |
49 | + | |
50 | +@-moz-keyframes faderight { | |
51 | + /* Firefox */ | |
52 | + from { | |
53 | + opacity: 0; | |
54 | + -moz-transform: translateX(-20px); | |
55 | + } | |
56 | + to { | |
57 | + opacity: 1; | |
58 | + -moz-transform: translateX(0); | |
59 | + } | |
60 | +} | |
61 | + | |
62 | +@-webkit-keyframes faderight { | |
63 | + /* Safari and Chrome */ | |
64 | + from { | |
65 | + opacity: 0; | |
66 | + -webkit-transform: translateX(-20px); | |
67 | + } | |
68 | + to { | |
69 | + opacity: 1; | |
70 | + -webkit-transform: translateX(0); | |
71 | + } | |
72 | +} | |
73 | + | |
74 | +.fade-left { | |
75 | + -webkit-animation: fadeleft 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; | |
76 | + animation: fadeleft 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; | |
77 | +} | |
78 | + | |
79 | +@-webkit-keyframes fadeleft { | |
80 | + 0% { | |
81 | + -webkit-transform: scaleX(0); | |
82 | + transform: scaleX(0); | |
83 | + -webkit-transform-origin: 100% 100%; | |
84 | + transform-origin: 100% 100%; | |
85 | + opacity: 1; | |
86 | + } | |
87 | + 100% { | |
88 | + -webkit-transform: scaleX(1); | |
89 | + transform: scaleX(1); | |
90 | + -webkit-transform-origin: 100% 100%; | |
91 | + transform-origin: 100% 100%; | |
92 | + opacity: 1; | |
93 | + } | |
94 | +} | |
95 | + | |
96 | +@keyframes fadeleft { | |
97 | + 0% { | |
98 | + -webkit-transform: scaleX(0); | |
99 | + transform: scaleX(0); | |
100 | + -webkit-transform-origin: 100% 100%; | |
101 | + transform-origin: 100% 100%; | |
102 | + opacity: 1; | |
103 | + } | |
104 | + 100% { | |
105 | + -webkit-transform: scaleX(1); | |
106 | + transform: scaleX(1); | |
107 | + -webkit-transform-origin: 100% 100%; | |
108 | + transform-origin: 100% 100%; | |
109 | + opacity: 1; | |
110 | + } | |
111 | +} | |
112 | + | |
113 | +.fade-bottom { | |
114 | + -webkit-animation: fade-bottom 0.4s cubic-bezier(0.39, 0.575, 0.565, 1) both; | |
115 | + animation: fade-bottom 0.4s cubic-bezier(0.39, 0.575, 0.565, 1) both; | |
116 | +} | |
117 | + | |
118 | +@-webkit-keyframes fade-bottom { | |
119 | + 0% { | |
120 | + -webkit-transform: scaleY(0.4); | |
121 | + transform: scaleY(0.4); | |
122 | + -webkit-transform-origin: 100% 0%; | |
123 | + transform-origin: 100% 0%; | |
124 | + } | |
125 | + 100% { | |
126 | + -webkit-transform: scaleY(1); | |
127 | + transform: scaleY(1); | |
128 | + -webkit-transform-origin: 100% 0%; | |
129 | + transform-origin: 100% 0%; | |
130 | + } | |
131 | +} | |
132 | + | |
133 | +@keyframes fade-bottom { | |
134 | + 0% { | |
135 | + -webkit-transform: scaleY(0.4); | |
136 | + transform: scaleY(0.4); | |
137 | + -webkit-transform-origin: 100% 0%; | |
138 | + transform-origin: 100% 0%; | |
139 | + } | |
140 | + 100% { | |
141 | + -webkit-transform: scaleY(1); | |
142 | + transform: scaleY(1); | |
143 | + -webkit-transform-origin: 100% 0%; | |
144 | + transform-origin: 100% 0%; | |
145 | + } | |
146 | +} | |
147 | + | |
148 | +.slide-in-bl { | |
149 | + -webkit-animation: slide-in-bl 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; | |
150 | + animation: slide-in-bl 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; | |
151 | +} | |
152 | + | |
153 | +@-webkit-keyframes slide-in-bl { | |
154 | + 0% { | |
155 | + -webkit-transform: translateY(1000px) translateX(-1000px); | |
156 | + transform: translateY(1000px) translateX(-1000px); | |
157 | + opacity: 0; | |
158 | + } | |
159 | + 100% { | |
160 | + -webkit-transform: translateY(0) translateX(0); | |
161 | + transform: translateY(0) translateX(0); | |
162 | + opacity: 1; | |
163 | + } | |
164 | +} | |
165 | + | |
166 | +@keyframes slide-in-bl { | |
167 | + 0% { | |
168 | + -webkit-transform: translateY(1000px) translateX(-1000px); | |
169 | + transform: translateY(1000px) translateX(-1000px); | |
170 | + opacity: 0; | |
171 | + } | |
172 | + 100% { | |
173 | + -webkit-transform: translateY(0) translateX(0); | |
174 | + transform: translateY(0) translateX(0); | |
175 | + opacity: 1; | |
176 | + } | |
177 | +} |
src/assets/scss/bootstrap-override.scss
... | ... | @@ -0,0 +1,82 @@ |
1 | +@import "../../../node_modules/bootstrap/scss/functions"; | |
2 | +@import "../../../node_modules/bootstrap/scss/variables"; | |
3 | +@import "../../../node_modules/bootstrap/scss/mixins"; | |
4 | + | |
5 | +$primary: #2872ae; | |
6 | + | |
7 | +$theme-colors: ( | |
8 | + primary: $primary, | |
9 | + light: white | |
10 | +); | |
11 | + | |
12 | +.popover { | |
13 | + transform: translate3d(-425px, 0, -34px) !important; | |
14 | + min-width: 350px !important; | |
15 | + max-width: 425px !important; | |
16 | + border: none !important; | |
17 | + border-radius: 1.5rem !important; | |
18 | + padding: 0 !important; | |
19 | + background-color: $primary !important; | |
20 | + .popover-body { | |
21 | + padding: 0 !important; | |
22 | + } | |
23 | +} | |
24 | + | |
25 | +.bs-popover-left .arrow::after, | |
26 | +.bs-popover-auto[x-placement^="left"] .arrow::after { | |
27 | + border-left-color: $primary !important; | |
28 | +} | |
29 | + | |
30 | +.bs-popover-right .arrow::after, | |
31 | +.bs-popover-auto[x-placement^="right"] .arrow::after { | |
32 | + border-right-color: $primary !important; | |
33 | +} | |
34 | + | |
35 | +.bs-popover-top .arrow::after, | |
36 | +.bs-popover-auto[x-placement^="top"] .arrow::after { | |
37 | + border-top-color: $primary !important; | |
38 | +} | |
39 | + | |
40 | +.bs-popover-bottom .arrow::after, | |
41 | +.bs-popover-auto[x-placement^="bottom"] .arrow::after { | |
42 | + border-bottom-color: $primary !important; | |
43 | +} | |
44 | + | |
45 | +.list-group-item.active { | |
46 | + background-color: $primary !important; | |
47 | + border-color: $primary !important; | |
48 | +} | |
49 | + | |
50 | +.custom-radio .custom-control-label::before { | |
51 | + background-color: $primary !important; | |
52 | + border-color: $white !important; | |
53 | + border-width: 2px !important; | |
54 | +} | |
55 | + | |
56 | +.custom-control-input { | |
57 | + border-color: $white !important; | |
58 | + background-color: $primary !important; | |
59 | + color: $primary !important; | |
60 | + &:checked ~ .custom-control-label::before { | |
61 | + border-color: $white !important; | |
62 | + color: #fff !important; | |
63 | + background-color: $primary !important; | |
64 | + } | |
65 | + &:focus ~ .custom-control-label::before { | |
66 | + border-color: $white !important; | |
67 | + box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.7) !important; | |
68 | + } | |
69 | +} | |
70 | + | |
71 | +.carousel-control { | |
72 | + visibility: hidden !important; | |
73 | +} | |
74 | + | |
75 | +.carousel, .carousel-inner, .item { | |
76 | + height: 100% !important; | |
77 | + &:focus{ | |
78 | + outline: none !important; | |
79 | + } | |
80 | +} | |
81 | + | |
82 | +@import "../../../node_modules/bootstrap/scss/bootstrap"; |
src/etc/AppSettings ejemplo.ts
src/styles.scss
1 | -/* You can add global styles to this file, and also import other style files */ | |
1 | +@import "./assets/scss/animation.scss"; | |
2 | +@import "./assets/scss/bootstrap-override.scss"; | |
3 | +@import "../node_modules/bootstrap/scss/_variables.scss"; | |
4 | + | |
5 | +html, | |
6 | +body { | |
7 | + background-color: #f0f0f0; | |
8 | + font-family: bahnschrift; | |
9 | + overflow: hidden !important; | |
10 | +} | |
11 | + | |
12 | +.disable-user-select { | |
13 | + -webkit-user-select: none; | |
14 | + -moz-user-select: none; | |
15 | + -ms-user-select: none; | |
16 | + user-select: none; | |
17 | +} | |
18 | + | |
19 | +.blue-gradient { | |
20 | + background: linear-gradient(0deg, #ffffff00, $white); | |
21 | +} | |
22 | + | |
23 | +.rounded { | |
24 | + border-radius: 1.5rem !important; | |
25 | +} | |
26 | + | |
27 | +.rounded-top-sm { | |
28 | + border-top-left-radius: 0.75rem !important; | |
29 | + border-top-right-radius: 0.75rem !important; | |
30 | +} | |
31 | + | |
32 | +.rounded-sm { | |
33 | + border-radius: 0.75rem !important; | |
34 | +} | |
35 | + | |
36 | +.card-effect { | |
37 | + &:active { | |
38 | + background-color: #c9c9c9b3 !important; | |
39 | + transition: background-color 0.5s; | |
40 | + } | |
41 | + &:focus { | |
42 | + background-color: #c9c9c9b3 !important; | |
43 | + transition: background-color 0.5s; | |
44 | + } | |
45 | +} | |
46 | + | |
47 | +.overflow-scroll { | |
48 | + overflow-y: auto !important; | |
49 | + overflow-x: hidden !important; | |
50 | + &::-webkit-scrollbar { | |
51 | + width: 1em; | |
52 | + } | |
53 | + &::-webkit-scrollbar-track { | |
54 | + border-radius: 10px; | |
55 | + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.4); | |
56 | + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.4); | |
57 | + background-color: $white; | |
58 | + } | |
59 | + &::-webkit-scrollbar-thumb { | |
60 | + box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7); | |
61 | + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.7); | |
62 | + outline: 1px solid slategrey; | |
63 | + border-radius: 10px; | |
64 | + height: 12px; | |
65 | + &:active { | |
66 | + box-shadow: inset 0 0 8px $primary; | |
67 | + -webkit-box-shadow: inset 0 0 8px $primary; | |
68 | + } | |
69 | + } | |
70 | + &::-webkit-scrollbar-corner { | |
71 | + border-radius: 10px; | |
72 | + } | |
73 | +} | |
74 | + | |
75 | +.bg-gray { | |
76 | + background-color: #e6e6e6; | |
77 | +} | |
78 | + | |
79 | +.bg-primary-gradient { | |
80 | + background: linear-gradient(135deg, rgba(40, 112, 175, 1) 0%, rgba(0, 32, 66, 1) 100%); | |
81 | +} | |
82 | + | |
83 | +.bg-primary-gradient-horizontal { | |
84 | + background: linear-gradient(90deg, rgba(40, 112, 175, 1) 0%, rgba(0, 32, 66, 1) 100%); | |
85 | +} | |
86 | + | |
87 | +.icon-dim { | |
88 | + height: 40px !important; | |
89 | + width: auto !important; | |
90 | + background-color: white !important; | |
91 | +} | |
92 | + | |
93 | +.text-purple { | |
94 | + color: $purple; | |
95 | +} | |
96 | + | |
97 | +.vh-70 { | |
98 | + min-height: auto !important; | |
99 | + max-height: 70vh !important; | |
100 | +} | |
101 | + | |
102 | +.vh-60 { | |
103 | + min-height: auto !important; | |
104 | + max-height: 60vh !important; | |
105 | +} | |
106 | + | |
107 | +.vh-50 { | |
108 | + min-height: auto !important; | |
109 | + max-height: 50vh !important; | |
110 | +} | |
111 | + | |
112 | +.spinner-lg { | |
113 | + width: 3rem !important; | |
114 | + height: 3rem !important; | |
115 | +} | |
116 | + | |
117 | +.sidebar { | |
118 | + right: 0; | |
119 | +} | |
120 | + | |
121 | +.background-image { | |
122 | + background-repeat: no-repeat; | |
123 | + background-size: cover; | |
124 | + position: fixed; | |
125 | +} | |
126 | + | |
127 | +.rounded-bottom-right { | |
128 | + border-bottom-right-radius: 10rem; | |
129 | + &:before { | |
130 | + border-radius: 0 40px 40px 0; | |
131 | + background-color: #fff; | |
132 | + } | |
133 | +} | |
134 | + | |
135 | +.rounded-top-left { | |
136 | + border-top-left-radius: 10rem; | |
137 | +} | |
138 | + | |
139 | +.bg-gray { | |
140 | + background-color: #cccccc; | |
141 | +} | |
142 | + | |
143 | +.cdk-overlay-container { | |
144 | + position: absolute; | |
145 | + top: 65%; | |
146 | + width: 100%; | |
147 | +} | |
148 | + | |
149 | +.min-h-40 { | |
150 | + min-height: 40px; | |
151 | +} | |
152 | + | |
153 | +.min-h-55 { | |
154 | + min-height: 55px; | |
155 | +} | |
156 | + | |
157 | +.pagination { | |
158 | + justify-content: center !important; | |
159 | + display: flex !important; | |
160 | +} |