Forráskód Böngészése

mejorado la interfaz de carga de productos

robert2206 8 éve
szülő
commit
f702be771f

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

@@ -8,6 +8,7 @@ import { HomePage } from '../pages/home/home';
 
 import { CustomerListPage } from '../pages/customer-list/customer-list';
 import { ProductListPage } from '../pages/product-list/product-list';
+import { ProductOptions } from '../pages/product-list/product-options';
 import { ProductDetailsPage } from '../pages/product-details/product-details';
 import { LeadListPage } from '../pages/lead-list/lead-list';
 import { OpportunityListPage } from '../pages/opportunity-list/opportunity-list';
@@ -39,6 +40,7 @@ import { ChartModule } from 'ng2-chartjs2';
         HomePage,
         CustomerListPage,
         ProductListPage,
+        ProductOptions,
         ProductDetailsPage,
         LeadListPage,
         OpportunityListPage,
@@ -63,6 +65,7 @@ import { ChartModule } from 'ng2-chartjs2';
         HomePage,
         CustomerListPage,
         ProductListPage,
+        ProductOptions,
         ProductDetailsPage,
         LeadListPage,
         OpportunityListPage,

+ 22 - 26
src/defaults/default-listable.ts

@@ -3,46 +3,46 @@ import { IListable } from '../interfaces/listable-interface';
 export abstract class DefaultListable<T> implements IListable<T> {
 
     private isForSearch: boolean;
-    private isForDelete: boolean;
     private _elements: Array<T>;
     private _elementsAux: Array<T>;
-    private _selectedIndex: number;
+    private _visibleElements: Array<T>;
+    private _visibleRange: [number, number] = [0, 50];
 
     constructor(
     ) {
         this.isForSearch = false;
-        this.isForDelete = false;
         this._elements = [];
         this._elementsAux = [];
-        this._selectedIndex = -1;
+        this._visibleElements = [];
     }
 
     /**
      *
      */
     set elements(_elements: Array<T>) {
-        this._elements = _elements; 
+        this._elements = _elements;
+        this.visibleElements = _elements.slice(this._visibleRange[0], this._visibleRange[1]);
     }
 
     /**
      *
      */
-    set selectedIndex(_selectedIndex: number) {
-        this._selectedIndex = _selectedIndex;
+    get elements() {
+        return this._elements;
     }
 
     /**
      *
      */
-    get elements() {
-        return this._elements;
+    set visibleElements(_visibleElements: Array<T>) {
+        this._visibleElements = _visibleElements;
     }
 
     /**
      *
      */
-    get selectedIndex(): number {
-        return this._selectedIndex;
+    get visibleElements() {
+        return this._visibleElements;
     }
 
     /**
@@ -57,7 +57,9 @@ export abstract class DefaultListable<T> implements IListable<T> {
      */
     remove(T: any): void {
         let index = this.elements.indexOf(T);
+        
         this._elements.splice(index, 1);
+        this._visibleElements.splice(index, 1);
     }
 
     /**
@@ -100,19 +102,6 @@ export abstract class DefaultListable<T> implements IListable<T> {
         }
     }
 
-    /**
-     *
-     */
-    toggleDelete(index: number): void {
-        this.selectedIndex = index;
-
-        if (this.selectedIndex != -1) {
-            this.isForDelete = true;
-        } else {
-            this.isForDelete = !this.isForDelete;
-        }    
-    }
-
     /**
      *
      */
@@ -123,7 +112,14 @@ export abstract class DefaultListable<T> implements IListable<T> {
     /**
      *
      */
-    isDeleting(): boolean {
-        return this.isForDelete;
+    seekRange(): void {
+        this._visibleRange[0] = this._visibleRange[1];
+        this._visibleRange[1] = this._visibleRange[1] + 50;
+
+        this._visibleElements = this._visibleElements.concat(this._elements.slice(this._visibleRange[0], this._visibleRange[1]));
+    }
+
+    isToSeek(): boolean {
+        return this._visibleRange[1] >= this.elements.length;
     }
 }

+ 0 - 12
src/interfaces/deletable-interface.ts

@@ -1,12 +0,0 @@
-export interface IDeletable {
-
-    /**
-     *
-     */
-    toggleDelete(index: number): void;
-
-    /**
-     *
-     */
-    isDeleting(): boolean;
-}

+ 1 - 1
src/interfaces/listable-interface.ts

@@ -1,7 +1,7 @@
 import { ISearchable } from './searchable-interface';
 import { IDeletable } from './deletable-interface';
 
-export interface IListable<T> extends ISearchable<T>, IDeletable  {
+export interface IListable<T> extends ISearchable<T> {
 
     /**
      *

+ 1 - 1
src/interfaces/navigable-interface.ts

@@ -1,3 +1,3 @@
 export interface INavigable {
-    goToPage(page: any): void;
+    
 }

+ 12 - 19
src/pages/product-list/product-list.html

@@ -25,34 +25,20 @@
     </ion-buttons>
 </ion-toolbar>
 
-<ion-toolbar color="primary" *ngIf="isDeleting()">
-     <ion-buttons start>
-        <button ion-button (click)="toggleDelete(-1)">
-            <ion-icon name="arrow-back"></ion-icon>
-        </button>
-    </ion-buttons>
-
-    <ion-buttons end>
-        <button ion-button (click)="askIfRemoveItem()">
-            <ion-icon name="trash"></ion-icon>
-        </button>
-    </ion-buttons>
-</ion-toolbar>
-
 <ion-content>
 
-    <ion-card *ngFor="let p of list(); let i = index;" (tap)="openItem(i)" (press)="toggleDelete(i)">
+    <ion-card *ngFor="let p of visibleElements">
         <ion-item>
-            <ion-avatar item-left>
+            <ion-thumbnail item-left>
                 <img src="./assets/images/product.png" *ngIf="!p.image_medium"/>
                 <img [src]="p.image_medium | sanitizeUrl" *ngIf="p.image_medium"/>
-            </ion-avatar>
+            </ion-thumbnail>
 
             <h2>{{ p.name }}</h2>
 
             <p>
                 <strong>Precio:</strong>
-                {{ p.list_price || 0 }}
+                {{ (p.list_price | number) || 0 }}
             </p>
 
             <p>
@@ -60,7 +46,9 @@
                 {{ p.qty_available || 0 }}
             </p>
 
-            <ion-icon name="checkmark-circle" color="primary" item-right *ngIf="i == _selectedIndex"></ion-icon>
+            <button ion-button primary clear item-right (click)="showOptions($event, p)">
+                <ion-icon name="more"></ion-icon>
+            </button>
         </ion-item>
 
         <ion-row>
@@ -73,6 +61,11 @@
         </ion-row>
     </ion-card>
 
+    <ion-infinite-scroll (ionInfinite)="loadMore($event)">
+        <ion-infinite-scroll-content></ion-infinite-scroll-content>
+    </ion-infinite-scroll>
+    
+
     <ion-fab right bottom>
         <button ion-fab color="yellow" (click)="goToPage(null)">
             <ion-icon name="add" color="light"></ion-icon>

+ 7 - 2
src/pages/product-list/product-list.scss

@@ -3,9 +3,14 @@ page-product-list {
         order: 2;
     }
 
-    ion-buttons button span ion-icon {
+    ion-buttons button span ion-icon, ion-item div button span ion-icon {
         padding: 0 6px !important;
-        font-size: 1.5em !important;
+        font-size: 1.8em !important;
+    }
+
+    ion-label h2 {
+        word-break: keep-all;
+        white-space: normal;
     }
 
     ion-card ion-row ion-col button {

+ 55 - 12
src/pages/product-list/product-list.ts

@@ -1,9 +1,10 @@
 import { Component } from '@angular/core';
-import { NavController, AlertController, ToastController, LoadingController } from 'ionic-angular';
+import { NavController, AlertController, ToastController, LoadingController, PopoverController } from 'ionic-angular';
 import { DefaultListable } from '../../defaults/default-listable';
 import { INavigable } from '../../interfaces/navigable-interface';
 import { Product } from '../../models/product';
 import { ProductDetailsPage } from '../product-details/product-details';
+import { ProductOptions } from './product-options';
 import { DataProvider } from '../../providers/data-provider';
 
 @Component({
@@ -12,12 +13,15 @@ import { DataProvider } from '../../providers/data-provider';
 })
 export class ProductListPage extends DefaultListable<Product> implements INavigable {
 
+    popover: any = null;
+
     constructor(
         public navCtrl: NavController,
         public alertCtrl: AlertController,
         public toastCtrl: ToastController,
         public dataProvider: DataProvider,
-        public loadingController: LoadingController
+        public loadingController: LoadingController,
+        public popoverCtrl: PopoverController
     ){
         super();
     }
@@ -44,6 +48,19 @@ export class ProductListPage extends DefaultListable<Product> implements INaviga
         });
     }
 
+    /**
+     *
+     */
+    loadMore(e) {
+        this.seekRange();
+
+        if (this.isToSeek()) {
+            e.enable(false);
+        }
+
+        e.complete();
+    }
+
     /**
      * Goto page
      */
@@ -54,15 +71,42 @@ export class ProductListPage extends DefaultListable<Product> implements INaviga
     /**
      *
      */
-    openItem(index: number) {
-        this.toggleDelete(-1);
-        this.navCtrl.push(ProductDetailsPage, this.elements[index]);
+    showOptions(e, item) {
+        this.popover = this.popoverCtrl.create(ProductOptions, {
+            item: item
+        });
+
+        this.popover.present({
+            ev: e
+        });
+
+        this.popover.onDidDismiss(data => {
+            switch (data.role) {
+                case "open":
+                    this.openItem(data.item);
+                    break;
+                case "delete":
+                    this.askIfRemoveItem(item);
+                    break;
+            
+                default:
+                    break;
+            }
+            
+        });
     }
 
     /**
      *
      */
-    askIfRemoveItem(): void {
+    openItem(item: any) {
+        this.navCtrl.push(ProductDetailsPage, item);
+    }    
+
+    /**
+     *
+     */
+    askIfRemoveItem(item): void {
         this.alertCtrl.create({
             title: "Confirmar",
             message: "Desea borrar este producto?",
@@ -70,13 +114,14 @@ export class ProductListPage extends DefaultListable<Product> implements INaviga
                 {
                     text: "Cancelar",
                     handler: () => {
-                        this.toggleDelete(-1);
+                        console.log("Canceled");
+                        
                     }
                 },
                 {
                     text: "Aceptar",
                     handler: () => {
-                        this.removeItem();
+                        this.removeItem(item);
                     }
                 }
             ]
@@ -86,13 +131,11 @@ export class ProductListPage extends DefaultListable<Product> implements INaviga
     /**
      *
      */
-    removeItem() {
-        let item = this.elements[this.selectedIndex];
+    removeItem(item: any) {
         item.doc_state = "deleted";
-        this.toggleDelete(-1);
         
         this.dataProvider.delete("product", item).then(result => {
-            this.elements.splice(this.selectedIndex, 1);
+            this.remove(item);
         }).catch(() => {
             this.toastCtrl.create({
                 message: "No se pudo eliminar el producto",

+ 8 - 0
src/pages/product-list/product-options.html

@@ -0,0 +1,8 @@
+<ion-list no-lines>
+    <button ion-item (click)="click('open')">
+        Abrir
+    </button>
+    <button ion-item (click)="click('delete')">
+        Eliminar
+    </button>
+</ion-list>

+ 23 - 0
src/pages/product-list/product-options.ts

@@ -0,0 +1,23 @@
+import { Component } from '@angular/core';
+import { NavParams, ViewController } from 'ionic-angular';
+
+@Component({
+    templateUrl: 'product-options.html'
+})
+export class ProductOptions {
+
+    constructor(
+        public nav: NavParams,
+        public viewCtrl: ViewController
+    ) { }
+
+    /**
+     *
+     */
+    click(role: string): void {
+        this.viewCtrl.dismiss({
+            role: role,
+            item: this.nav.data.item
+        });
+    }
+}