diff --git a/client/client/src/greuge-list/greuge-list.html b/client/client/src/greuge-list/greuge-list.html index 5122006e8d..ea91180a35 100644 --- a/client/client/src/greuge-list/greuge-list.html +++ b/client/client/src/greuge-list/greuge-list.html @@ -14,11 +14,11 @@ <vn-horizontal class="list list-element text-center" pad-small-bottom - ng-repeat="greuge in index.model.instances track by greuge.id"> - <vn-one pad-medium-h>{{::greuge.shipped | date:'dd/MM/yyyy HH:mm' }}</vn-one> - <vn-two pad-medium-h>{{::greuge.description}}</vn-two> - <vn-one pad-medium-h>{{::greuge.amount | number:2}} €</vn-one> - <vn-one pad-medium-h>{{::greuge.greugeType.name}}</vn-one> + ng-repeat="greuge in $ctrl.instances track by $index"> + <vn-one pad-medium-h>{{greuge.shipped | date:'dd/MM/yyyy HH:mm' }}</vn-one> + <vn-two pad-medium-h>{{greuge.description}}</vn-two> + <vn-one pad-medium-h>{{greuge.amount | number:2}} €</vn-one> + <vn-one pad-medium-h>{{greuge.greugeType.name}}</vn-one> </vn-horizontal> </vn-one> <vn-one class="text-center pad-small-v" ng-if="index.model.count === 0" translate>No results</vn-one> @@ -28,7 +28,8 @@ <vn-one pad-medium-h ng-if="index.model.count > 0">{{edit.model.sumAmount | number:2}} €</vn-one> <vn-one pad-medium-h></vn-one> </vn-horizontal> - <vn-paging margin-large-top vn-one index="index" total="index.model.count"></vn-paging> + <!--<vn-paging margin-large-top vn-one index="index" total="index.model.count"></vn-paging>--> + <vn-auto-paging margin-large-top vn-one index="index" total="index.model.count" items="$ctrl.instances"></vn-auto-paging> </vn-vertical> </vn-card> </vn-vertical> diff --git a/client/core/src/components/auto-paging/auto-paging.html b/client/core/src/components/auto-paging/auto-paging.html new file mode 100644 index 0000000000..eee5ec1f44 --- /dev/null +++ b/client/core/src/components/auto-paging/auto-paging.html @@ -0,0 +1,7 @@ +<vn-horizontal margin-medium-top> + <vn-one></vn-one> + <vn-auto> + <vn-spinner enable="$ctrl.watchScroll"></vn-spinner> + </vn-auto> + <vn-one></vn-one> +</vn-horizontal> \ No newline at end of file diff --git a/client/core/src/components/auto-paging/auto-paging.js b/client/core/src/components/auto-paging/auto-paging.js new file mode 100644 index 0000000000..5b8c85ce93 --- /dev/null +++ b/client/core/src/components/auto-paging/auto-paging.js @@ -0,0 +1,118 @@ +import ngModule from '../../module'; +import getWatchers from '../../lib/get-watchers'; + +class AutoPaging { + constructor($http, $window, $element, $timeout, vnApp, $translate) { + this.$http = $http; + this.$window = $window; + this.$element = $element; + this.$timeout = $timeout; + this.vnApp = vnApp; + this.$translate = $translate; + + this.numPerPage = null; + this.maxItems = 0; + this.watchScroll = false; + this.waitingNewPage = false; + + this.handlerScroll = this.onScroll.bind(this); + } + + get numPages() { + return this.numPerPage ? Math.ceil(this.maxItems / this.numPerPage) : 0; + } + + loadNewPage() { + this.index.filter.page++; + this.waitingNewPage = true; + + this.index.accept().then(res => { + this.$timeout(() => { + res.instances.forEach(item => { + this.items.push(item); + }); + this.checkWatchers(); + }); + if (this.index.filter.page == this.numPages) { + this.cancelScroll(); + } + this.waitingNewPage = false; + }); + } + + checkPosition() { + let element = this.$element[0].querySelector('vn-spinner'); + let position = element.getBoundingClientRect(); + if (this.currentPage < this.numPages && position.y < document.body.offsetHeight + 150 && !this.waitingNewPage) { + this.loadNewPage(); + } + } + + onScroll() { + this.checkPosition(); + } + + startScroll() { + this.watchScroll = true; + this.checkPosition(); + angular.element(this.$window).bind("wheel", this.handlerScroll); + } + + cancelScroll() { + this.watchScroll = false; + angular.element(this.$window).unbind("wheel", this.handlerScroll); + } + + checkScroll() { + if (this.numPages > this.currentPage && !this.watchScroll) { + this.startScroll(); + } else if (this.numPages <= this.currentPage && this.watchScroll) { + this.cancelScroll(); + } + } + + checkWatchers() { + let watchers = getWatchers(); + if (watchers > 3000 && this.watchScroll) { + this.cancelScroll(); + this.vnApp.showMessage( + this.$translate.instant('Auto-scroll interrupted, please adjust the search') + ); + } + } + + $onChanges(changes) { + if (!this.index) return; + + this.numPerPage = this.index.filter.size; + this.currentPage = this.index.filter.page; + this.currentInstances = this.items; + if (changes.total) + this.maxItems = changes.total.currentValue; + + this.checkScroll(); + } + + $postLink() { + this.checkScroll(); + } + + $doCheck() { + if (this.index && this.index.filter && this.index.filter.page && this.index.filter.page != this.currentPage) { + this.currentPage = this.index.filter.page; + this.checkScroll(); + } + } +} + +AutoPaging.$inject = ['$http', '$window', '$element', '$timeout', 'vnApp', '$translate']; + +ngModule.component('vnAutoPaging', { + template: require('./auto-paging.html'), + bindings: { + index: '<', + total: '<', + items: '<' + }, + controller: AutoPaging +}); diff --git a/client/core/src/components/auto-paging/auto-paging.spec.js b/client/core/src/components/auto-paging/auto-paging.spec.js new file mode 100644 index 0000000000..e5070ffbb8 --- /dev/null +++ b/client/core/src/components/auto-paging/auto-paging.spec.js @@ -0,0 +1,61 @@ +import './auto-paging.js'; +import template from './auto-paging.html'; + +describe('Component vnAutoPaging', () => { + let $http; + let $window; + let $element; + let $timeout; + let controller; + + beforeEach(() => { + angular.mock.module('client'); + }); + + beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_, _$window_, _$timeout_) => { + $http = _$httpBackend_; + $window = _$window_; + $timeout = _$timeout_; + $element = angular.element(`<div>${template}</div>`); + + controller = _$componentController_('vnAutoPaging', {$http, $window, $element, $timeout}); + })); + + describe('onChanges: actions when index object changes', () => { + beforeEach(() => { + controller.index = { + filter: { + size: 5, + page: 1 + } + }; + controller.items = [1, 2, 3, 4, 5]; + }); + + it('call startScroll() if there are pages to load', () => { + let changes = { + total: { + currentValue: 20 + } + }; + spyOn(controller, 'startScroll'); + + controller.$onChanges(changes); + + expect(controller.startScroll).toHaveBeenCalled(); + }); + + it('call stopScroll() if there are not pages to load', () => { + let changes = { + total: { + currentValue: 5 + } + }; + controller.watchScroll = true; + spyOn(controller, 'cancelScroll'); + controller.$onChanges(changes); + + expect(controller.cancelScroll).toHaveBeenCalled(); + }); + }); +}); diff --git a/client/core/src/components/index.js b/client/core/src/components/index.js index 2da08fd15f..44a41911c1 100644 --- a/client/core/src/components/index.js +++ b/client/core/src/components/index.js @@ -31,3 +31,4 @@ import './switch/switch'; import './float-button/float-button'; import './step-control/step-control'; import './label-value/label-value'; +import './auto-paging/auto-paging'; diff --git a/client/core/src/lib/filter-list.js b/client/core/src/lib/filter-list.js index 1c63414d70..d3f5d2963e 100644 --- a/client/core/src/lib/filter-list.js +++ b/client/core/src/lib/filter-list.js @@ -9,6 +9,7 @@ export default class FilterList { this.waitingMgCrud = 0; this.modelId = $state.params.id; + this.instances = []; } onOrder(field, order) { this.filter(`${field} ${order}`); @@ -27,7 +28,9 @@ export default class FilterList { this.$.index.filter.order = order; } - this.$.index.accept(); + this.$.index.accept().then(res => { + this.instances = res.instances; + }); } else if (!this.modelId || !this.modelName) { throw new Error('Error: model not found'); } else if (this.waitingMgCrud > 3) { diff --git a/client/core/src/lib/index.js b/client/core/src/lib/index.js index 9df4b69116..77904844ce 100644 --- a/client/core/src/lib/index.js +++ b/client/core/src/lib/index.js @@ -12,3 +12,4 @@ import './copy'; import './equals'; import './modified'; import './key-codes'; +import './get-watchers'; diff --git a/client/core/src/locale/en.yml b/client/core/src/locale/en.yml index 1c72342ddf..3a06f2bd02 100644 --- a/client/core/src/locale/en.yml +++ b/client/core/src/locale/en.yml @@ -10,4 +10,5 @@ No more results: No more results Hide: Hide Next: Next Finalize: Finalize -Previous: Back \ No newline at end of file +Previous: Back +Auto-scroll interrupted, please adjust the search: Auto-scroll interrupted, please adjust the search \ No newline at end of file diff --git a/client/core/src/locale/es.yml b/client/core/src/locale/es.yml index 0f6d87d9f3..4e826330bb 100644 --- a/client/core/src/locale/es.yml +++ b/client/core/src/locale/es.yml @@ -10,4 +10,5 @@ No more results: No hay más resultados Hide: Ocultar Next: Siguiente Finalize: Finalizar -Previous: Anterior \ No newline at end of file +Previous: Anterior +Auto-scroll interrupted, please adjust the search: Auto-scroll interrumpido, por favor ajusta la búsqueda \ No newline at end of file diff --git a/client/item/src/list/list.html b/client/item/src/list/list.html index 50a35b930c..a981f37169 100644 --- a/client/item/src/list/list.html +++ b/client/item/src/list/list.html @@ -15,11 +15,12 @@ </vn-card> <vn-card margin-medium-top> <vn-item-product - ng-repeat="item in index.model.instances" + ng-repeat="item in $ctrl.items track by $index" item="item"> </vn-item-product> </vn-card> - <vn-paging index="index" total="index.model.count"></vn-paging> + <!-- <vn-paging index="index" total="index.model.count"></vn-paging> --> + <vn-auto-paging index="index" total="index.model.count" items="$ctrl.items"></vn-auto-paging> </div> </div> <a ui-sref="item.create" vn-bind="+" fixed-bottom-right> diff --git a/client/item/src/list/list.js b/client/item/src/list/list.js index 43d2a95e4d..2f6a8819f7 100644 --- a/client/item/src/list/list.js +++ b/client/item/src/list/list.js @@ -9,9 +9,12 @@ class ItemList { this.$scope = $scope; this.model = {}; this.itemSelected = null; + this.items = []; } search(index) { - index.accept(); + index.accept().then(res => { + this.items = res.instances; + }); } cloneItem(item) { this.itemSelected = item; diff --git a/client/ticket/src/volume/ticket-volume.spec.js b/client/ticket/src/volume/ticket-volume.spec.js index 7679167e14..bd367ee6ca 100644 --- a/client/ticket/src/volume/ticket-volume.spec.js +++ b/client/ticket/src/volume/ticket-volume.spec.js @@ -16,8 +16,12 @@ describe('ticket', () => { $componentController = _$componentController_; $httpBackend = _$httpBackend_; $scope = $rootScope.$new(); - $scope.index = {model: {instances: [{id: 1}, {id: 2}]}, accept: () => {}}; - $state = _$state_; + $scope.index = {model: {instances: [{id: 1}, {id: 2}]}, accept: () => { + return { + then: () => {} + }; + }}; + $state = _$state_; $state.params.id = 101; controller = $componentController('vnTicketVolume', {$scope: $scope}, {$httpBackend: $httpBackend}, {$state: $state}); })); diff --git a/services/client/common/methods/greuge/filter.js b/services/client/common/methods/greuge/filter.js index dba4e8ef68..0f3a71cef5 100644 --- a/services/client/common/methods/greuge/filter.js +++ b/services/client/common/methods/greuge/filter.js @@ -6,9 +6,9 @@ module.exports = Self => { where: { clientFk: params.clientFk }, - skip: (params.page - 1) * params.size, - limit: params.size, - order: params.order || 'shipped DESC', + skip: (params.page - 1) * parseInt(params.size), + limit: parseInt(params.size), + order: `${params.order}, id ASC` || 'shipped DESC', include: { relation: "greugeType", scope: { diff --git a/services/loopback/common/methods/item/filter.js b/services/loopback/common/methods/item/filter.js index 72720ef459..f6170d6f4c 100644 --- a/services/loopback/common/methods/item/filter.js +++ b/services/loopback/common/methods/item/filter.js @@ -6,7 +6,7 @@ module.exports = Self => { where: {}, skip: (params.page - 1) * params.size, limit: params.size, - order: params.order || 'name, relevancy DESC', + order: params.order || 'name ASC', // name, relevancy DESC include: { relation: 'itemType', scope: {