ModelProxy.status, Paging removed, locale fixes
gitea/salix/dev This commit looks good Details

This commit is contained in:
Juan Ferrer 2019-10-03 19:34:24 +02:00
parent a8f2000f3f
commit c6e8498281
20 changed files with 60 additions and 228 deletions

View File

@ -207,8 +207,8 @@ export default class CrudModel extends ModelProxy {
sendRequest(filter, append) { sendRequest(filter, append) {
this.cancelRequest(); this.cancelRequest();
this.canceler = this.$q.defer(); this.canceler = this.$q.defer();
this.isRefreshing = !append;
this.isPaging = append; this.isPaging = append;
if (!append) this.status = 'loading';
let params = Object.assign( let params = Object.assign(
{filter}, {filter},
@ -221,9 +221,8 @@ export default class CrudModel extends ModelProxy {
return this.$http.get(this._url, options).then( return this.$http.get(this._url, options).then(
json => this.onRemoteDone(json, filter, append), json => this.onRemoteDone(json, filter, append),
json => this.onRemoteError(json) json => this.onRemoteError(json, append)
).finally(() => { ).finally(() => {
this.isRefreshing = false;
this.isPaging = false; this.isPaging = false;
}); });
} }
@ -243,7 +242,12 @@ export default class CrudModel extends ModelProxy {
this.onRequestEnd(); this.onRequestEnd();
} }
onRemoteError(err) { onRemoteError(err, append) {
if (!append) {
this.clear();
this.status = 'error';
}
this.onRequestEnd(); this.onRequestEnd();
throw err; throw err;
} }

View File

@ -1,22 +1,28 @@
<div ng-if="$ctrl.hasData"> <div ng-if="$ctrl.isReady">
<div ng-transclude></div> <div ng-transclude></div>
<vn-pagination <vn-pagination
model="$ctrl.model"> model="$ctrl.model"
pad-medium-top>
</vn-pagination> </vn-pagination>
</div> </div>
<div <div
class="empty-rows" class="empty-rows"
ng-if="!$ctrl.hasData" ng-if="!$ctrl.isReady"
ng-switch="$ctrl.status"> ng-switch="$ctrl.status">
<vn-spinner <vn-spinner
ng-switch-when="loading" ng-switch-when="loading"
enable="true"> enable="::true">
</vn-spinner> </vn-spinner>
<span <span
ng-switch-when="clear" ng-switch-when="clear"
translate> translate>
Enter a new search Enter a new search
</span> </span>
<span
ng-switch-when="error"
translate>
Ups! It seems there was an error
</span>
<span <span
ng-switch-when="empty" ng-switch-when="empty"
translate> translate>

View File

@ -2,28 +2,22 @@ import ngModule from '../../module';
import './style.scss'; import './style.scss';
export default class DataViewer { export default class DataViewer {
get computedData() { get isReady() {
return this.data || (this.model && this.model.data); return this.status == 'ready';
}
get computedLoading() {
return this.isLoading || (this.model && this.model.isRefreshing);
}
get hasData() {
let data = this.computedData;
return data && data.length;
} }
get status() { get status() {
if (this.hasData) if (this.model)
return null; return this.model.status;
if (this.computedLoading)
if (this.isLoading)
return 'loading'; return 'loading';
if (this.computedData) if (!this.data)
return 'empty';
else
return 'clear'; return 'clear';
if (this.data.length)
return 'ready';
else
return 'empty';
} }
} }

View File

@ -26,7 +26,6 @@ import './card/card';
import './float-button/float-button'; import './float-button/float-button';
import './step-control/step-control'; import './step-control/step-control';
import './label-value/label-value'; import './label-value/label-value';
import './paging/paging';
import './pagination/pagination'; import './pagination/pagination';
import './searchbar/searchbar'; import './searchbar/searchbar';
import './scroll-up/scroll-up'; import './scroll-up/scroll-up';

View File

@ -57,6 +57,7 @@ export default class ModelProxy extends DataModel {
constructor($element, $scope) { constructor($element, $scope) {
super($element, $scope); super($element, $scope);
this.resetChanges(); this.resetChanges();
this.status = 'clear';
} }
get orgData() { get orgData() {
@ -90,6 +91,14 @@ export default class ModelProxy extends DataModel {
set data(value) { set data(value) {
this._data = value; this._data = value;
if (value == null)
this.status = 'clear';
else if (value.length)
this.status = 'ready';
else
this.status = 'empty';
this.emit('dataChange'); this.emit('dataChange');
this.emit('dataUpdate'); this.emit('dataUpdate');
} }
@ -109,8 +118,12 @@ export default class ModelProxy extends DataModel {
this.removed.push(item); this.removed.push(item);
this.isChanged = true; this.isChanged = true;
if (!this.data.length)
this.status = 'empty';
this.emit('rowRemove', index); this.emit('rowRemove', index);
this.emit('dataUpdate'); this.emit('dataUpdate');
if (this.autoSave) if (this.autoSave)
this.save(); this.save();
} }
@ -131,8 +144,11 @@ export default class ModelProxy extends DataModel {
this.data.push(newRow); this.data.push(newRow);
this.isChanged = true; this.isChanged = true;
this.status = 'ready';
this.emit('rowInsert', index); this.emit('rowInsert', index);
this.emit('dataUpdate'); this.emit('dataUpdate');
return index; return index;
} }
@ -322,10 +338,10 @@ export class Paginable {
} }
/** /**
* @type {Boolean} Whether the model is refreshing. * @type {ready|loading|clear|empty|error} The current model status.
*/ */
get isRefreshing() { get status() {
return false; return null;
} }
/** /**

View File

@ -1,13 +1,12 @@
<div <div ng-if="$ctrl.model.moreRows">
ng-if="$ctrl.model.moreRows">
<vn-icon-button <vn-icon-button
ng-if="!$ctrl.model.isLoading" ng-if="!$ctrl.model.isPaging"
icon="more_horiz" icon="more_horiz"
vn-tooltip="Load more" vn-tooltip="Load more"
ng-click="$ctrl.onLoadClick()"> ng-click="$ctrl.onLoadClick()">
</vn-icon-button> </vn-icon-button>
<vn-spinner <vn-spinner
ng-if="$ctrl.model.isLoading" ng-if="$ctrl.model.isPaging"
enable="$ctrl.model.isLoading"> enable="::true">
</vn-spinner> </vn-spinner>
</div> </div>

View File

@ -3,7 +3,8 @@ vn-pagination {
display: block; display: block;
text-align: center; text-align: center;
& > div > vn-icon-button { & > div > vn-icon-button {
font-size: 2em; font-size: 2em;
padding: 0;
} }
} }

View File

@ -1,11 +0,0 @@
<paging
page="$ctrl.currentPage"
page-size="$ctrl.numPerPage"
ng-if="$ctrl.numPages>1"
total="$ctrl.numItems"
show-prev-next="true"
show-first-last="false"
active-class="active"
ng-click="$ctrl.figureOutToDisplay()"
paging-action="$ctrl.onPageChange(page)">
</paging>

View File

@ -1,58 +0,0 @@
import ngModule from '../../module';
import './style.scss';
export default class Paging {
get numPages() {
return Math.ceil(this.numItems / this.numPerPage);
}
constructor($http, $scope) {
this.$http = $http;
this.$scope = $scope;
this.where = this.filter;
this.numPerPage = null;
this.numItems = 0;
$scope.$watch('$ctrl.index.model.length', () => this.onModelUpdated());
}
$onChanges(changes) {
if (!this.index) return;
this.numPerPage = this.index.filter.size;
this.currentPage = this.index.filter.page;
if (changes.total)
this.numItems = changes.total.currentValue;
}
onModelUpdated() {
let index = this.index;
let filter = index.filter;
if (filter.page >= this.numPages && index.model.length >= this.numPerPage)
this.numItems = filter.page * filter.size + 1;
}
onPageChange(page) {
this.index.filter.page = page;
if (typeof this.pageChange === 'undefined') {
this.index.accept();
} else {
this.pageChange();
}
}
$doCheck() {
if (this.index && this.index.filter && this.index.filter.page && this.index.filter.page != this.currentPage) {
this.currentPage = this.index.filter.page;
}
}
}
Paging.$inject = ['$http', '$scope'];
ngModule.component('vnPaging', {
template: require('./paging.html'),
bindings: {
index: '<',
pageChange: '&?',
total: '<'
},
controller: Paging
});

View File

@ -1,65 +0,0 @@
import './paging.js';
describe('Component vnPaging', () => {
let $scope;
let controller;
beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(angular.mock.inject(($componentController, $rootScope) => {
$scope = $rootScope.$new();
controller = $componentController('vnPaging', {$scope});
}));
describe('$onChanges()', () => {
it(`should define numberPage and currentPage based on index.filter properties`, () => {
controller.index = {filter: {size: 'something', page: 'something else'}};
controller.$onChanges({index: 'simpleChange', currentValue: 'current value', previousValue: 'previous value'});
expect(controller.numPerPage).toBe(controller.index.filter.size);
expect(controller.currentPage).toEqual(controller.index.filter.page);
});
it(`should define numItems based on changes.total.currentValue`, () => {
controller.index = {filter: {size: 'something', page: 'something else'}};
controller.$onChanges({total: {currentValue: 'current value'}});
expect(controller.numItems).toEqual('current value');
});
});
describe('onModelUpdated()', () => {
it(`should define controllers numItems as the result of page times size plus one`, () => {
controller.numPerPage = 2;
controller.index = {
filter: {size: 10, page: 10},
model: ['one mother..', 'another model..', 'last model..']
};
controller.onModelUpdated();
expect(controller.numItems).toBe(101);
});
});
describe('onPageChange()', () => {
it(`should call accept() since pageChange property is undefined`, () => {
controller.index = {accept: () => {}, filter: {page: 0}};
spyOn(controller.index, 'accept');
controller.onPageChange(100);
expect(controller.index.accept).toHaveBeenCalledWith();
});
it(`should call pageChange() since pageChange property isn't undefined`, () => {
controller.index = {accept: () => {}, filter: {page: 0}};
controller.pageChange = true;
spyOn(controller, 'pageChange');
controller.onPageChange(100);
expect(controller.pageChange).toHaveBeenCalledWith();
});
});
});

View File

@ -1,40 +0,0 @@
@import "variables";
vn-paging {
display: block;
text-align: center;
ul {
box-shadow: 0 0 .4em $color-shadow;
background-color: #fff;
display: inline-block;
margin: 20px 0;
border-radius: .1em;
padding: 0;
}
li {
display: inline;
&:first-child > a,
&:first-child > span {
margin-left: 0;
}
&.active > a {
background: $color-active;
color: #fff;
}
& > a,
& > span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: inherit;
text-decoration: none;
}
&:not(.active) > a:hover {
background-color: #ddd;
}
}
}

View File

@ -180,11 +180,8 @@ export default class Popover extends Component {
onDocKeyDown(event) { onDocKeyDown(event) {
if (event.defaultPrevented) return; if (event.defaultPrevented) return;
if (event.code == 'Escape')
if (event.keyCode == 27) { // Esc
event.preventDefault();
this.hide(); this.hide();
}
} }
onMouseDown(event) { onMouseDown(event) {

View File

@ -24,6 +24,9 @@ Value should be %s characters long: El valor debe ser de %s carácteres de longi
Value should have a length between %s and %s: El valor debe tener una longitud de entre %s y %s Value should have a length between %s and %s: El valor debe tener una longitud de entre %s y %s
Value should have at least %s characters: El valor debe tener al menos %s carácteres Value should have at least %s characters: El valor debe tener al menos %s carácteres
Value should have at most %s characters: El valor debe tener un máximo de %s carácteres Value should have at most %s characters: El valor debe tener un máximo de %s carácteres
Enter a new search: Introduce una nueva búsqueda
No results: Sin resultados
Ups! It seems there was an error: ¡Vaya! Parece que ha habido un error
General search: Busqueda general General search: Busqueda general
January: Enero January: Enero
February: Febrero February: Febrero

View File

@ -7,10 +7,6 @@ import 'angular-translate-loader-partial';
import '@uirouter/angularjs'; import '@uirouter/angularjs';
import 'mg-crud'; import 'mg-crud';
import 'oclazyload'; import 'oclazyload';
/*
import 'angular-material';
import 'angular-material/modules/scss/angular-material.scss';
*/
import 'angular-moment'; import 'angular-moment';
export const ngDeps = [ export const ngDeps = [
@ -18,7 +14,6 @@ export const ngDeps = [
'ui.router', 'ui.router',
'mgCrud', 'mgCrud',
'oc.lazyLoad', 'oc.lazyLoad',
// 'ngMaterial',
'angularMoment' 'angularMoment'
]; ];

View File

@ -14,8 +14,6 @@ Push on applications menu: Para abrir un módulo pulsa en el menú de aplicacion
Return to module index: Volver a la página principal del módulo Return to module index: Volver a la página principal del módulo
What is new: Novedades de la versión What is new: Novedades de la versión
Settings: Ajustes Settings: Ajustes
Enter a new search: Introduce una nueva búsqueda
No results: Sin resultados
# Actions # Actions

View File

@ -1,3 +1,2 @@
Since : Desde Since : Desde
Employee : Empleado Employee : Empleado
No results: Sin resultados

View File

@ -1,5 +1,4 @@
Since: Desde Since: Desde
Employee: Empleado Employee: Empleado
No results: Sin resultados
To: Hasta To: Hasta
Finish that recovery period: Terminar el recobro Finish that recovery period: Terminar el recobro

View File

@ -33,8 +33,6 @@ Remove niche: Quitar nicho
Add barcode: Añadir código de barras Add barcode: Añadir código de barras
Remove barcode: Quitar código de barras Remove barcode: Quitar código de barras
Buyer: Comprador Buyer: Comprador
No results: Sin resultados
Enter a new search: Introduce una nueva búsqueda
Tag: Etiqueta Tag: Etiqueta
Worker: Trabajador Worker: Trabajador
Available: Disponible Available: Disponible

View File

@ -131,7 +131,7 @@ class Controller {
} }
get isRefreshing() { get isRefreshing() {
return this.$scope.model && this.$scope.model.isRefreshing; return this.$scope.model && this.$scope.model.status == 'loading';
} }
} }

View File

@ -3,8 +3,6 @@ Catalog: Catálogo
from: desde from: desde
results: resultados results: resultados
More than: Más de More than: Más de
No results: Sin resultados
Enter a new search: Introduce una nueva búsqueda
Plant: Planta Plant: Planta
Flower: Flor Flower: Flor
Handmade: Confección Handmade: Confección