mgCrud v1
This commit is contained in:
parent
72a9068c80
commit
c694f00644
|
@ -1,4 +1,4 @@
|
|||
<form name="form" ng-submit="form.$valid && addressData.onSubmit()" pad-medium>
|
||||
<form name="form" ng-submit="addressData.onSubmit()" pad-medium>
|
||||
<vn-card >
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Consignatario</vn-title>
|
||||
|
@ -41,5 +41,6 @@
|
|||
vn-id="watcher"
|
||||
url="/client/api/Addresses"
|
||||
id-field="id"
|
||||
data="addressData.address">
|
||||
data="addressData.address"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<form name="form" ng-submit="form.$valid && addressData.onSubmit()" pad-medium>
|
||||
<form name="form" ng-submit="addressData.onSubmit()" pad-medium>
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Consignatario</vn-title>
|
||||
|
@ -43,5 +43,6 @@
|
|||
get="true"
|
||||
url="/client/api/Addresses"
|
||||
id-field="id"
|
||||
data="addressData.address">
|
||||
data="addressData.address"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<mg-ajax path="/client/api/Clients/{{index.params.id}}/Addresses" options="vnIndex"></mg-ajax>
|
||||
<vn-vertical pad-medium>
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-horizontal>
|
||||
<vn-title vn-one>Consignatario</vn-title>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal ng-repeat="i in address.addresses" class="pad-medium-top" style="align-items: center;">
|
||||
<vn-auto style="border-radius: .5em;" class="pad-small border-solid" ng-class="{'bg-dark-item': i.default,'bg-opacity-item': !i.enabled && !i.default}">
|
||||
<vn-horizontal ng-repeat="i in index.model" class="pad-medium-top" style="align-items: center;">
|
||||
<vn-auto style="border-radius: .5em;" class="pad-small border-solid"
|
||||
ng-class="{'bg-dark-item': i.default,'bg-opacity-item': !i.enabled && !i.default}">
|
||||
<vn-horizontal style="align-items: center;">
|
||||
<vn-auto>
|
||||
<div><b>{{i.consignee}}</b></div>
|
||||
|
@ -13,30 +15,18 @@
|
|||
<div>{{i.city}}, {{i.province}}</div>
|
||||
<div>{{i.phone}}, {{i.mobile}}</div>
|
||||
</vn-auto>
|
||||
<a vn-empty ui-sref="clientCard.addressEdit({ addressId: {{i.id}} })">
|
||||
<a vn-empty ui-sref="clientCard.addressEdit({addressId: {{i.id}}})">
|
||||
<vn-icon-button icon="edit"></vn-icon-button>
|
||||
</a>
|
||||
</vn-horizontal>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
<vn-horizontal>
|
||||
<vn-one style="text-align:center;">
|
||||
<paging page="address.currentPage"
|
||||
page-size="address.numPerPage"
|
||||
total="address.numPages"
|
||||
show-prev-next="true"
|
||||
show-first-last="true"
|
||||
ul-class="pagination"
|
||||
active-class="active"
|
||||
ng-click="address.figureOutToDisplay()">
|
||||
</paging>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-paging index="index"></vn-paging>
|
||||
<vn-float-button
|
||||
fixed-bottom-right
|
||||
ng-click="address.newAddress()"
|
||||
ng-click="$ctrl.onNewAddressClick()"
|
||||
icon="add">
|
||||
</vn-float-button>
|
||||
</vn-vertical>
|
||||
|
|
|
@ -1,63 +1,20 @@
|
|||
import {module} from '../module';
|
||||
|
||||
export const NAME = 'vnClientAddresses';
|
||||
export const COMPONENT = {
|
||||
class Controller {
|
||||
constructor($state) {
|
||||
this.$state = $state;
|
||||
}
|
||||
onNewAddressClick() {
|
||||
this.$state.go('clientCard.addressCreate', {id: this.client.id});
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$state'];
|
||||
|
||||
export const component = {
|
||||
template: require('./index.html'),
|
||||
controllerAs: 'address',
|
||||
bindings: {
|
||||
client: '<'
|
||||
},
|
||||
controller: controller
|
||||
controller: Controller
|
||||
};
|
||||
module.component(NAME, COMPONENT);
|
||||
|
||||
controller.$inject = ['$http', '$state'];
|
||||
function controller($http, $state) {
|
||||
var self = this;
|
||||
let numPerPage = 5;
|
||||
let numRecords = 0;
|
||||
|
||||
this.$onChanges = function(changes) {
|
||||
if (this.client) {
|
||||
self.client = this.client;
|
||||
this.getAddresses();
|
||||
}
|
||||
};
|
||||
this.getAddresses = () => {
|
||||
var json = JSON.stringify({client: self.client.id});
|
||||
$http.get(`/client/api/Addresses/count?where=${json}`).then(
|
||||
json => {
|
||||
numRecords = json.data.count;
|
||||
self.getNumPages();
|
||||
self.figureOutToDisplay();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.getNumPages = () => {
|
||||
var nPages = numRecords / numPerPage;
|
||||
self.numPages = Math.ceil(nPages);
|
||||
};
|
||||
|
||||
this.figureOutToDisplay = () => {
|
||||
var begin = ((self.currentPage - 1) * numPerPage);
|
||||
self.getAddress(begin);
|
||||
};
|
||||
|
||||
this.getAddress = function(end) {
|
||||
var json = JSON.stringify({where: {client: self.client.id}, limit: numPerPage, skip: end});
|
||||
$http.get(`/client/api/Addresses?filter=${json}`).then(
|
||||
json => {
|
||||
self.addresses = json.data;
|
||||
self.filteredTodos = self.addresses;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.pageChanged = () => {
|
||||
self.figureOutToDisplay();
|
||||
};
|
||||
this.newAddress = () => {
|
||||
$state.go("clientCard.addressCreate", {id: self.client.id});
|
||||
};
|
||||
}
|
||||
module.component('vnClientAddresses', component);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<form name="form" ng-submit="form.$valid && watcher.submit()" pad-medium>
|
||||
<mg-ajax path="/client/api/Clients/{{put.params.id}}" options="vnPut"></mg-ajax>
|
||||
<vn-watcher vn-id="watcher" data="$ctrl.client" form="form" save="put"></vn-watcher>
|
||||
<form name="form" ng-submit="watcher.submit()" pad-medium>
|
||||
<vn-card >
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Datos básicos</vn-title>
|
||||
|
@ -29,9 +31,3 @@
|
|||
<vn-submit label="Guardar"></vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="/client/api/Clients"
|
||||
id-field="id"
|
||||
data="$ctrl.client">
|
||||
</vn-watcher>
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import './style.css';
|
||||
import template from './card.html';
|
||||
import {module} from '../module';
|
||||
import './style.css';
|
||||
|
||||
const _NAME = 'clientClient';
|
||||
// export const NAME = module.getName(_NAME);
|
||||
export const NAME = "vnClientCard";
|
||||
export const NAME = 'vnClientCard';
|
||||
export const COMPONENT = {
|
||||
template: template,
|
||||
template: require('./index.html'),
|
||||
controllerAs: 'card',
|
||||
controller: function($http, $stateParams) {
|
||||
this.client = null;
|
|
@ -1,34 +1,25 @@
|
|||
export * from './module';
|
||||
|
||||
export {NAME as CLIENT_CARD,
|
||||
COMPONENT as CLIENT_CARD_COMPONENT} from './card/card';
|
||||
export {NAME as CLIENT_BASIC_DATA_INDEX,
|
||||
COMPONENT as CLIENT_BASIC_DATA_INDEX_COMPONENT} from './basic-data/index';
|
||||
export {NAME as CLIENT_ADDRESSES,
|
||||
COMPONENT as CLIENT_ADDRESSES_COMPONENT} from './addresses/index';
|
||||
COMPONENT as CLIENT_CARD_COMPONENT} from './card/index';
|
||||
export {NAME as CLIENTS,
|
||||
COMPONENT as CLIENTS_COMPONENT} from './index/index';
|
||||
export {NAME as CLIENT_FISCAL_DATA_INDEX,
|
||||
COMPONENT as CLIENT_FISCAL_DATA_INDEX_COMPONENT} from './fiscal-data/index';
|
||||
export {NAME as CLIENT_DESCRIPTOR,
|
||||
COMPONENT as CLIENT_DESCRIPTOR_COMPONENT} from './descriptor/descriptor';
|
||||
COMPONENT as CLIENT_DESCRIPTOR_COMPONENT} from './descriptor/index';
|
||||
export {NAME as CLIENT_NOTES,
|
||||
COMPONENT as CLIENT_NOTES_COMPONENT} from './notes/index';
|
||||
export {NAME as CLIENT_SEARCH_PANEL,
|
||||
COMPONENT as CLIENT_SEARCH_PANEL_COMPONENT} from './search-panel/search-panel';
|
||||
export {NAME as CLIENT_ITEM,
|
||||
COMPONENT as CLIENT_ITEM_COMPONENT} from './index/item-client';
|
||||
COMPONENT as CLIENT_SEARCH_PANEL_COMPONENT} from './search-panel/index';
|
||||
export {NAME as CLIENT_CREATE,
|
||||
COMPONENT as CLIENT_CREATE_COMPONENT} from './create/index';
|
||||
export {NAME as CLIENT_ADDRESS_CREATE_INDEX,
|
||||
COMPONENT as CLIENT_ADDRESS_CREATE_INDEX_COMPONENT} from './address-create/index';
|
||||
export {NAME as CLIENT_ADDRESS_EDIT_INDEX,
|
||||
COMPONENT as CLIENT_ADDRESS_EDIT_INDEX_COMPONENT} from './address-edit/index';
|
||||
export {NAME as CLIENT_CONFIRM_INDEX,
|
||||
COMPONENT as CLIENT_CONFIRM_INDEX_COMPONENT} from './confirm/index';
|
||||
export {NAME as NEW_NOTE_INDEX,
|
||||
COMPONENT as NEW_NOTE_INDEX_COMPONENT} from './new-note/index';
|
||||
export {NAME as CLIENT_PAGING,
|
||||
COMPONENT as CLIENT_PAGING_COMPONENT} from './index/index-paging';
|
||||
|
||||
import './addresses/index';
|
||||
import './address-create/index';
|
||||
import './basic-data/index';
|
||||
import './web-access/index';
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<dialog class="mdl-dialog ">
|
||||
<vn-vertical class="mdl-dialog__content">
|
||||
<h6 class="dialog-title">
|
||||
¿Seguro que quieres salir sin guardar?
|
||||
</h6>
|
||||
<h6>
|
||||
Los cambios que no hayas guardado se perderán
|
||||
</h6>
|
||||
</vn-vertical>
|
||||
<vn-horizontal class="mdl-dialog__actions mdl-dialog__actions--full-width">
|
||||
<button vn-one type="button" class="mdl-button close" ng-click="dialogConfirm.cancel()">Cancelar</button>
|
||||
<button vn-one type="button" class="mdl-button" ng-click="dialogConfirm.accept()">Aceptar</button>
|
||||
</vn-horizontal>
|
||||
</dialog>
|
||||
<vn-confirm id="confirm-changes" on-response="$ctrl.onConfirm(response)"
|
||||
title="Are you sure exit without saving?"
|
||||
message="Unsaved changes will be lost">
|
||||
</vn-confirm>
|
|
@ -1,30 +0,0 @@
|
|||
import template from './index.html';
|
||||
import {module} from '../module';
|
||||
|
||||
require('./style.css');
|
||||
|
||||
export const NAME = 'vnDialogConfirm';
|
||||
export const COMPONENT = {
|
||||
template: template,
|
||||
controllerAs: 'dialogConfirm',
|
||||
bindings: {
|
||||
state: '<',
|
||||
object: '=',
|
||||
objectOld: "="
|
||||
},
|
||||
controller: function($state, $element, copyObject) {
|
||||
var dialog = $element.find('dialog')[0];
|
||||
|
||||
this.accept = function() {
|
||||
copyObject(this.objectOld, this.object);
|
||||
$state.go(this.state);
|
||||
dialog.close();
|
||||
};
|
||||
|
||||
this.cancel = function() {
|
||||
dialog.close();
|
||||
};
|
||||
}
|
||||
};
|
||||
COMPONENT.controller.$inject = ['$state', '$element', 'copyObject'];
|
||||
module.component(NAME, COMPONENT);
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
.dialog-title{
|
||||
color:#424242;
|
||||
font-family: raleway-bold;
|
||||
}
|
|
@ -1,21 +1,22 @@
|
|||
<div margin-medium>
|
||||
<form name="form" ng-submit="form.$valid && create.onSubmit()" style="max-width: 70em; margin: 0 auto;">
|
||||
<mg-ajax path="/client/api/Clients/{{put.params.id}}" options="vnPost"></mg-ajax>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" style="max-width: 70em; margin: 0 auto;">
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Crear Cliente</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Nombre" field="create.client.name" vn-focus></vn-textfield>
|
||||
<vn-textfield vn-one label="NIF/CIF" field="create.client.fi"></vn-textfield>
|
||||
<vn-textfield vn-one label="Nombre" field="$ctrl.client.name" vn-focus></vn-textfield>
|
||||
<vn-textfield vn-one label="NIF/CIF" field="$ctrl.client.fi"></vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Razón social" field="create.client.socialName"></vn-textfield>
|
||||
<vn-textfield vn-one label="Razón social" field="$ctrl.client.socialName"></vn-textfield>
|
||||
<vn-one></vn-one>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Crear y continuar"></vn-submit>
|
||||
<vn-button label="Crear" ng-click="create.onCreate()"></vn-button>
|
||||
<vn-button label="Crear" ng-click="$ctrl.onCreate()"></vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -23,5 +24,6 @@
|
|||
vn-id="watcher"
|
||||
url="/client/api/Clients"
|
||||
id-field="id"
|
||||
data="create.client">
|
||||
data="$ctrl.client"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
|
|
|
@ -22,10 +22,8 @@ class Controller {
|
|||
}
|
||||
Controller.$inject = ['$scope', '$state', '$window'];
|
||||
|
||||
export const NAME = 'vnClientCreate';
|
||||
export const COMPONENT = {
|
||||
export const component = {
|
||||
template: require('./index.html'),
|
||||
controllerAs: 'create',
|
||||
controller: Controller
|
||||
};
|
||||
module.component(NAME, COMPONENT);
|
||||
module.component('vnClientCreate', component);
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import './style.css';
|
||||
import template from './descriptor.html';
|
||||
import {module} from '../module';
|
||||
import './style.css';
|
||||
|
||||
export const NAME = 'vnDescriptor';
|
||||
export const COMPONENT = {
|
||||
template: template,
|
||||
template: require('./index.html'),
|
||||
controllerAs: 'descriptor',
|
||||
bindings: {
|
||||
client: '<'
|
|
@ -1,4 +1,4 @@
|
|||
<form name="form" ng-submit="form.$valid && watcher.submit()" pad-medium>
|
||||
<form name="form" ng-submit="watcher.submit()" pad-medium>
|
||||
<vn-card margin-small-bottom>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Datos fiscales y de facturación</vn-title>
|
||||
|
@ -69,5 +69,7 @@
|
|||
vn-id="watcher"
|
||||
url="/client/api/Clients"
|
||||
id-field="id"
|
||||
data="fiscal.client">
|
||||
form="form"
|
||||
data="fiscal.client"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<div vn-horizontal>
|
||||
<vn-one style="text-align:center;">
|
||||
<paging page="pagingClient.currentPage"
|
||||
page-size="pagingClient.numPerPage"
|
||||
total="pagingClient.numPages"
|
||||
show-prev-next="true"
|
||||
show-first-last="true"
|
||||
ul-class="pagination"
|
||||
active-class="active"
|
||||
ng-click="pagingClient.figureOutToDisplay()">
|
||||
</paging>
|
||||
</vn-one>
|
||||
</div>
|
|
@ -1,64 +0,0 @@
|
|||
import template from './index-paging.html';
|
||||
import {module} from '../module';
|
||||
|
||||
export const NAME = 'vnPagingClient';
|
||||
export const COMPONENT = {
|
||||
template: template,
|
||||
bindings: {
|
||||
filter: '<',
|
||||
clients: '='
|
||||
},
|
||||
controllerAs: 'pagingClient',
|
||||
controller: function($http) {
|
||||
var self = this;
|
||||
let queryStr = '/client/api/Clients';
|
||||
let where = this.filter;
|
||||
let numPerPage = 3;
|
||||
|
||||
this.$onChanges = function(changes) {
|
||||
if (Object.keys(self.filter).length > 0){
|
||||
where = self.filter;
|
||||
this.getClients();
|
||||
this.getNumPages();
|
||||
}
|
||||
else {
|
||||
where = "";
|
||||
this.currentPage = 1;
|
||||
this.getAllClients();
|
||||
}
|
||||
this.figureOutToDisplay();
|
||||
};
|
||||
|
||||
this.getNumPages = () => {
|
||||
var nPages = self.clients.length / numPerPage;
|
||||
this.numPages = Math.ceil(nPages);
|
||||
};
|
||||
|
||||
this.figureOutToDisplay = () => {
|
||||
var begin = ((this.currentPage - 1) * numPerPage);
|
||||
this.getClients(begin);
|
||||
};
|
||||
|
||||
this.getAllClients = () => {
|
||||
$http.get(queryStr).then(
|
||||
json => {
|
||||
self.clients = json.data;
|
||||
this.getNumPages();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.getClients = function(end) {
|
||||
var json = JSON.stringify({where: where, limit: numPerPage, skip: end});
|
||||
self.queryStr = `${queryStr}?filter=${json}`;
|
||||
$http.get(self.queryStr).then(
|
||||
json => {
|
||||
self.clients = json.data;
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
COMPONENT.controller.$inject = ['$http'];
|
||||
module.component(NAME, COMPONENT);
|
|
@ -1,25 +1,21 @@
|
|||
|
||||
<!--
|
||||
<mg-ajax path="/client/api/Clients" options="mgIndex as index"></mg-ajax>
|
||||
<button ng-click="index.accept()"></button>
|
||||
<span ng-repeat="client in index.model">{{client}}</span>
|
||||
-->
|
||||
<mg-ajax path="/client/api/Clients/filter" options="vnIndex"></mg-ajax>
|
||||
<div margin-medium>
|
||||
<div style="max-width: 40em; margin: 0 auto;">
|
||||
<vn-card>
|
||||
<vn-horizontal pad-medium>
|
||||
<vn-searchbar
|
||||
vn-auto model="search.filter"
|
||||
search="search.find()"
|
||||
vn-auto
|
||||
index="index"
|
||||
on-search="index.accept()"
|
||||
advanced="true"
|
||||
popover="vn-client-search-panel">
|
||||
</vn-searchbar>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-card margin-medium-top>
|
||||
<vn-item-client ng-repeat="client in search.clients" title="View client" client="client"></vn-item-client>
|
||||
<vn-item-client ng-repeat="client in index.model" title="View client" client="client"></vn-item-client>
|
||||
</vn-card>
|
||||
<vn-paging-client clients="search.clients" filter="search.filter"></vn-paging-client>
|
||||
<vn-paging index="index"></vn-paging>
|
||||
</div>
|
||||
<a ui-sref="create" fixed-bottom-right>
|
||||
<vn-float-button icon="person_add"></vn-float-button>
|
||||
|
|
|
@ -1,47 +1,9 @@
|
|||
import template from './index.html';
|
||||
import {module} from '../module';
|
||||
require('./style.css');
|
||||
import './style.css';
|
||||
import './item-client';
|
||||
|
||||
export const NAME = 'vnClientIndex';
|
||||
export const COMPONENT = {
|
||||
template: template,
|
||||
controllerAs: 'search',
|
||||
controller: function($http) {
|
||||
var self = this;
|
||||
this.find = function() {
|
||||
var where = {};
|
||||
var filter = this.filter;
|
||||
var search = filter.search;
|
||||
if (search)
|
||||
where = {name: {ilike: search}};
|
||||
|
||||
var params = filter.params;
|
||||
if (params) {
|
||||
where = {};
|
||||
let partials = {
|
||||
alias: true,
|
||||
name: true,
|
||||
socialName: true,
|
||||
city: true,
|
||||
email: true
|
||||
};
|
||||
for (let param in params)
|
||||
if (params[param]) {
|
||||
if (partials[param])
|
||||
where[param] = {ilike: params[param]};
|
||||
else
|
||||
where[param] = params[param];
|
||||
}
|
||||
filter.params = undefined;
|
||||
}
|
||||
|
||||
if (where) {
|
||||
self.filter = where;
|
||||
}
|
||||
};
|
||||
this.filter = {};
|
||||
this.find();
|
||||
}
|
||||
template: require('./index.html')
|
||||
};
|
||||
COMPONENT.controller.$inject = ['$http'];
|
||||
module.component(NAME, COMPONENT);
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import template from './item-client.html';
|
||||
import {module} from '../module';
|
||||
|
||||
export const NAME = 'vnItemClient';
|
||||
export const COMPONENT = {
|
||||
template: template,
|
||||
template: require('./item-client.html'),
|
||||
controllerAs: 'itemClient',
|
||||
bindings: {
|
||||
client: '<'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<form name="form" ng-submit="form.$valid && newNote.onSubmit()" pad-medium>
|
||||
<form name="form" ng-submit="newNote.onSubmit()" pad-medium>
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Nueva nota</vn-title>
|
||||
|
@ -13,5 +13,6 @@
|
|||
vn-id="watcher"
|
||||
url="/client/api/ClientObservations"
|
||||
id-field="id"
|
||||
data="newNote.note">
|
||||
data="newNote.note"
|
||||
form="form">
|
||||
</vn-watcher>
|
|
@ -1,5 +1,5 @@
|
|||
<div pad-large style="min-width: 30em;" ng-show="$ctrl.formVisibility">
|
||||
<form name="form" ng-submit="form.$valid && $ctrl.onSubmit()" ng-keyup="$ctrl.getKeyPressed($event)">
|
||||
<form name="form" ng-submit="form.$valid && $ctrl.onSubmit($ctrl.filter)" ng-keyup="$ctrl.getKeyPressed($event)">
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Id Cliente" model="$ctrl.filter.id" vn-focus></vn-textfield>
|
||||
<vn-textfield vn-one label="NIF/CIF" model="$ctrl.filter.fi"></vn-textfield>
|
|
@ -2,7 +2,7 @@ import {module} from '../module';
|
|||
|
||||
export const NAME = 'vnClientSearchPanel';
|
||||
export const COMPONENT = {
|
||||
template: require('./search-panel.html'),
|
||||
template: require('./index.html'),
|
||||
controller: function($scope) {
|
||||
this.formVisibility = true;
|
||||
this.onSubmit = function() {};
|
|
@ -1,4 +1,4 @@
|
|||
<form name="form" ng-submit="form.$valid && watcher.submit()" pad-medium>
|
||||
<form name="form" ng-submit="watcher.submit()" pad-medium>
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Web access</vn-title>
|
||||
|
@ -16,7 +16,8 @@
|
|||
id-field="id"
|
||||
url="/client/api/Accounts"
|
||||
watch="$ctrl.client.account"
|
||||
to="$ctrl.account">
|
||||
to="$ctrl.account"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<vn-dialog
|
||||
vn-id="change-pass"
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
<div class="mdl-textfield mdl-js-textfield *[className]*">
|
||||
<input
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input type="text"
|
||||
class="mdl-textfield__input"
|
||||
type="text"
|
||||
rule="*[rule]*"
|
||||
*[enabled]*
|
||||
*[focus]*
|
||||
ng-keydown="$ctrl.onKeydown($event)"
|
||||
ng-click="$ctrl.onClick($event)"
|
||||
ng-keyup="$ctrl.onKeyup($event)"
|
||||
ng-focus="$ctrl.onFocus($event)"
|
||||
ng-blur="$ctrl.onBlur($event)"/>
|
||||
<label class="mdl-textfield__label" translate>*[label]*</label>
|
||||
<label class="mdl-textfield__label">{{$ctrl.label | translate}}</label>
|
||||
</div>
|
|
@ -1,7 +1,5 @@
|
|||
import {module} from '../module';
|
||||
import template from '../lib/template';
|
||||
import Component from '../lib/component';
|
||||
import './index.mdl';
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
|
@ -9,7 +7,7 @@ import './style.scss';
|
|||
* features.
|
||||
*/
|
||||
export default class Autocomplete extends Component {
|
||||
constructor($element, $attrs, $scope, $http, $parse, vnPopover) {
|
||||
constructor($element, $scope, $http, vnPopover) {
|
||||
super($element);
|
||||
this.input = $element[0].querySelector('input');
|
||||
this.item = null;
|
||||
|
@ -26,22 +24,20 @@ export default class Autocomplete extends Component {
|
|||
this.requestDelay = 350;
|
||||
this.locked = false;
|
||||
this.$http = $http;
|
||||
this.$attrs = $attrs;
|
||||
this.$scope = $scope;
|
||||
this.$parse = $parse;
|
||||
this.vnPopover = vnPopover;
|
||||
|
||||
$scope.$watch('$ctrl.model', newValue => {
|
||||
if(!this.locked) {
|
||||
this.locked = true;
|
||||
this.setValue(newValue);
|
||||
this.locked = false;
|
||||
}
|
||||
});
|
||||
|
||||
componentHandler.upgradeElement($element[0].firstChild);
|
||||
this.requestItem();
|
||||
}
|
||||
set field(value) {
|
||||
this.locked = true;
|
||||
this.setValue(value);
|
||||
this.locked = false;
|
||||
}
|
||||
get field() {
|
||||
return this.value;
|
||||
}
|
||||
mdlUpdate() {
|
||||
let mdlField = this.element.firstChild.MaterialTextfield;
|
||||
if (mdlField)
|
||||
|
@ -251,10 +247,10 @@ export default class Autocomplete extends Component {
|
|||
this.putItem(this.item);
|
||||
}
|
||||
requestItem() {
|
||||
if(!this.model) return;
|
||||
if(!this.value) return;
|
||||
|
||||
let where = {};
|
||||
where[this.valueField] = this.model;
|
||||
where[this.valueField] = this.value;
|
||||
|
||||
let filter = {
|
||||
fields: this.getRequestFields(),
|
||||
|
@ -307,6 +303,8 @@ export default class Autocomplete extends Component {
|
|||
this.activeOption = index;
|
||||
}
|
||||
setValue(value) {
|
||||
this.value = value;
|
||||
|
||||
if(value) {
|
||||
let data = this.data;
|
||||
|
||||
|
@ -336,7 +334,7 @@ export default class Autocomplete extends Component {
|
|||
let value = item ? item[this.valueField] : undefined;
|
||||
|
||||
if(!this.locked) {
|
||||
this.model = value;
|
||||
this.value = value;
|
||||
setTimeout (
|
||||
() => this.$scope.$apply());
|
||||
}
|
||||
|
@ -347,15 +345,16 @@ export default class Autocomplete extends Component {
|
|||
this.mdlUpdate();
|
||||
}
|
||||
}
|
||||
Autocomplete.$inject = ['$element', '$attrs', '$scope', '$http', '$parse', 'vnPopover'];
|
||||
Autocomplete.$inject = ['$element', '$scope', '$http', 'vnPopover'];
|
||||
|
||||
module.component('vnAutocomplete', {
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
url: '@',
|
||||
showField: '@',
|
||||
valueField: '@',
|
||||
model: '='
|
||||
field: '=',
|
||||
label: '@'
|
||||
},
|
||||
template: template,
|
||||
controller: Autocomplete
|
||||
});
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import {module} from '../module';
|
||||
|
||||
export function factory() {
|
||||
return {
|
||||
template: require('./index.mdl.html'),
|
||||
default: {
|
||||
className: 'mdl-textfield--floating-label'
|
||||
}
|
||||
}
|
||||
}
|
||||
module.factory('vnAutocompleteMdlFactory', factory);
|
|
@ -1,6 +1,7 @@
|
|||
import './mdl-override.css';
|
||||
|
||||
import './watcher/index';
|
||||
import './paging/index';
|
||||
import './icon/index';
|
||||
import './autocomplete/index';
|
||||
import './popover/index';
|
||||
|
@ -8,6 +9,7 @@ import './dialog/index';
|
|||
import './confirm/index';
|
||||
import './title/index';
|
||||
import './subtitle/index';
|
||||
import './spinner/index';
|
||||
|
||||
export {NAME as BUTTON, directive as ButtonDirective} from './button/button';
|
||||
export {NAME as BUTTON_MDL, factory as buttonMdl} from './button/button.mdl';
|
||||
|
@ -29,8 +31,6 @@ export {NAME as SUBMIT, directive as SubmitDirective} from './submit/submit';
|
|||
export {NAME as SUBMIT_MDL, factory as submitMdl} from './submit/submit.mdl';
|
||||
export {NAME as SNACKBAR, directive as SnackbarDirective} from './snackbar/snackbar';
|
||||
export {NAME as SNACKBAR_MDL, factory as snackbarMdl} from './snackbar/snackbar.mdl';
|
||||
export {NAME as SPINNER, directive as SpinnerDirective} from './spinner/spinner';
|
||||
export {NAME as SPINNER_MDL, factory as spinnerMdl} from './spinner/spinner.mdl';
|
||||
export {NAME as COMBO, directive as ComboDirective} from './combo/combo';
|
||||
export {NAME as COMBO_MDL, factory as comboMdl} from './combo/combo.mdl';
|
||||
export {NAME as DATE_PICKER, directive as DatePickerDirective} from './date-picker/date-picker';
|
||||
|
|
|
@ -8,7 +8,6 @@ import {kebabToCamel} from '../lib/string';
|
|||
export function directive() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: [],
|
||||
link: function($scope, $element, $attrs) {
|
||||
let id = kebabToCamel($attrs.vnId);
|
||||
let controller = $element[0].$ctrl;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import {module} from '../module';
|
||||
|
||||
index.$inject = ['mgIndex'];
|
||||
function index(mgIndex) {
|
||||
return angular.extend(mgIndex, {
|
||||
init: 'index.filter={page: 1, size: 4}'
|
||||
});
|
||||
}
|
||||
module.factory('vnIndex', index);
|
||||
|
||||
successFactoryCreate.$inject = ['mgSuccessFactoryCreate'];
|
||||
function successFactoryCreate(create) {
|
||||
return angular.extend(create, {
|
||||
back: undefined
|
||||
});
|
||||
}
|
||||
module.factory('vnSuccessFactoryCreate', successFactoryCreate);
|
||||
|
||||
put.$inject = ['mgPut'];
|
||||
function put(mgPut) {
|
||||
return angular.extend(mgPut, {
|
||||
success: 'vnSuccessFactoryCreate'
|
||||
});
|
||||
}
|
||||
module.factory('vnPut', put);
|
||||
|
||||
post.$inject = ['mgCreate'];
|
||||
function post(mgCreate) {
|
||||
return angular.extend(mgCreate, {
|
||||
success: 'vnSuccessFactoryCreate'
|
||||
});
|
||||
}
|
||||
module.factory('vnPost', post);
|
|
@ -0,0 +1,7 @@
|
|||
import {kebabToCamel} from './string';
|
||||
|
||||
getTemplate.$inject = ['$element', '$attrs', 'vnResolveDefaultComponent'];
|
||||
export default function getTemplate($element, $attrs, resolve) {
|
||||
let templateName = kebabToCamel($element[0].tagName.toLowerCase().substr(3));
|
||||
return resolve.getTemplate(templateName, $attrs);
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
import './moduleLoader';
|
||||
import './crud';
|
||||
import './template';
|
||||
import './getTemplate';
|
||||
|
||||
export * from './util';
|
||||
export {default as splitingRegister} from './splitingRegister';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/**
|
||||
* Transforms a kebab-case string to camelCase. A kebab-case string
|
||||
* is a string with hyphen character as word separator.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<paging
|
||||
page="$ctrl.currentPage"
|
||||
page-size="$ctrl.numPerPage"
|
||||
total="$ctrl.numItems"
|
||||
show-prev-next="true"
|
||||
show-first-last="false"
|
||||
active-class="active"
|
||||
ng-click="$ctrl.figureOutToDisplay()"
|
||||
paging-action="$ctrl.onPageChange(page)">
|
||||
</paging>
|
|
@ -0,0 +1,43 @@
|
|||
import {module} 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() {
|
||||
if(!this.index) return;
|
||||
this.numPerPage = this.index.filter.size;
|
||||
}
|
||||
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;
|
||||
this.index.accept();
|
||||
}
|
||||
}
|
||||
Paging.$inject = ['$http', '$scope'];
|
||||
|
||||
export const NAME = 'vnPaging';
|
||||
export const COMPONENT = {
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
index: '<'
|
||||
},
|
||||
controller: Paging
|
||||
};
|
||||
module.component(NAME, COMPONENT);
|
|
@ -0,0 +1,38 @@
|
|||
vn-paging {
|
||||
display: block;
|
||||
text-align: center;
|
||||
|
||||
ul {
|
||||
box-shadow: 0 0 .4em rgba(1,1,1,.4);
|
||||
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: #3c393b;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
<div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner">
|
||||
</div>
|
|
@ -0,0 +1,57 @@
|
|||
import {module} from '../module';
|
||||
import Component from '../lib/component';
|
||||
|
||||
/**
|
||||
* A spinner to inform the user about loading process.
|
||||
*/
|
||||
export default class Spinner extends Component {
|
||||
constructor($element, $scope) {
|
||||
super($element);
|
||||
this._enable = false;
|
||||
this.spinner = $element[0].firstChild;
|
||||
componentHandler.upgradeElement(this.spinner);
|
||||
}
|
||||
/**
|
||||
* Enables/disables the spinner.
|
||||
*
|
||||
* @param {Boolean} %true to enable, %false to disable
|
||||
*/
|
||||
set enable(value) {
|
||||
if (value)
|
||||
this.start();
|
||||
else
|
||||
this.stop();
|
||||
}
|
||||
/**
|
||||
* Returns the current spinner state.
|
||||
*
|
||||
* @return {Boolean} %true if it's enabled, %false otherwise
|
||||
*/
|
||||
get enable() {
|
||||
return this._enable;
|
||||
}
|
||||
/**
|
||||
* Activates the spinner.
|
||||
*/
|
||||
start() {
|
||||
this.spinner.MaterialSpinner.start();
|
||||
this._enable = true;
|
||||
}
|
||||
/**
|
||||
* Deactivates the spinner.
|
||||
*/
|
||||
stop() {
|
||||
this.spinner.MaterialSpinner.stop();
|
||||
this._enable = false;
|
||||
}
|
||||
}
|
||||
Spinner.$inject = ['$element', '$scope'];
|
||||
|
||||
export const component = {
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
enable: '='
|
||||
},
|
||||
controller: Spinner
|
||||
};
|
||||
module.component('vnSpinner', component);
|
|
@ -1,41 +0,0 @@
|
|||
import {module} from '../module';
|
||||
import * as resolveFactory from '../lib/resolveDefaultComponents';
|
||||
import * as util from '../lib/util';
|
||||
|
||||
const _NAME = 'spinner';
|
||||
export const NAME = util.getName(_NAME);
|
||||
|
||||
directive.$inject = [resolveFactory.NAME];
|
||||
export function directive(resolve) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
enable: '='
|
||||
},
|
||||
template: function(element, attrs) {
|
||||
return resolve.getTemplate(_NAME, attrs);
|
||||
},
|
||||
controller: controller
|
||||
}
|
||||
}
|
||||
module.directive(NAME, directive);
|
||||
|
||||
controller.$inject = ['$scope', '$element'];
|
||||
function controller($scope, $element) {
|
||||
let spinner = $element[0].firstChild;
|
||||
componentHandler.upgradeElement (spinner);
|
||||
|
||||
this.start = function() {
|
||||
spinner.MaterialSpinner.start();
|
||||
};
|
||||
this.stop = function() {
|
||||
spinner.MaterialSpinner.stop();
|
||||
};
|
||||
|
||||
$scope.$watch('enable', newValue => {
|
||||
if (newValue)
|
||||
this.start();
|
||||
else
|
||||
this.stop();
|
||||
});
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<div
|
||||
class="mdl-spinner mdl-spinner--single-color mdl-js-spinner"
|
||||
*[foo]*>
|
||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||
import {module} from '../module';
|
||||
|
||||
export const NAME = 'vnSpinnerMdlFactory';
|
||||
export function factory() {
|
||||
return {
|
||||
template: require('./spinner.mdl.html')
|
||||
}
|
||||
}
|
||||
module.factory(NAME, factory);
|
|
@ -47,15 +47,31 @@ export default class Watcher extends Component {
|
|||
});
|
||||
}
|
||||
submit() {
|
||||
if (!this.dataChanged()) {
|
||||
this.vnAppLogger.showMessage(
|
||||
this.$translate.instant('No changes to save')
|
||||
if(this.form && !this.form.$valid) {
|
||||
return new Promise (
|
||||
(resolve, reject) => this.invalidForm(reject)
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!this.dataChanged()) {
|
||||
return new Promise (
|
||||
(resolve, reject) => this.noChanges(reject)
|
||||
);
|
||||
}
|
||||
let changedData = getModifiedData(this.data, this.orgData);
|
||||
|
||||
if(this.save) {
|
||||
this.save.model = changedData;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.save.accept().then(
|
||||
json => this.writeData({data: json}, resolve),
|
||||
json => reject(json)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// XXX: Alternative when mgCrud is not used
|
||||
|
||||
let id = this.orgData[this.idField];
|
||||
let changedData = getModifiedData(this.data, this.orgData);
|
||||
|
||||
if(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -79,6 +95,18 @@ export default class Watcher extends Component {
|
|||
this.copyData();
|
||||
resolve(json);
|
||||
}
|
||||
noChanges(resolve) {
|
||||
this.vnAppLogger.showMessage(
|
||||
this.$translate.instant('No changes to save')
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
invalidForm(resolve) {
|
||||
this.vnAppLogger.showMessage(
|
||||
this.$translate.instant('Some fields are invalid')
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
copyData() {
|
||||
this.orgData = copyObject(this.data);
|
||||
}
|
||||
|
@ -112,6 +140,8 @@ module.component('vnWatcher', {
|
|||
url: '@?',
|
||||
idField: '@?',
|
||||
data: '<',
|
||||
form: '<',
|
||||
save: '<',
|
||||
get: '=?'
|
||||
},
|
||||
controller: Watcher
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"Are you sure exit without saving?": "¿Seguro que quieres salir sin guardar?",
|
||||
"Unsaved changes will be lost": "Los cambios que no hayas guardado se perderán",
|
||||
"No changes to save": "No hay cambios que guardar"
|
||||
"No changes to save": "No hay cambios que guardar",
|
||||
"Some fields are invalid": "Algunos campos no son válidos"
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<form ng-submit="$ctrl.search()">
|
||||
<form ng-submit="$ctrl.onSubmit()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Search" model="$ctrl.model.search"></vn-textfield>
|
||||
<vn-icon
|
||||
|
|
|
@ -1,34 +1,46 @@
|
|||
import {module} from '../../module';
|
||||
require('./style.css');
|
||||
|
||||
class Controller {
|
||||
constructor($element, $scope, $document, $compile, vnPopover) {
|
||||
this.element = $element[0];
|
||||
this.$scope = $scope;
|
||||
this.$document = $document;
|
||||
this.$compile = $compile;
|
||||
this.vnPopover = vnPopover;
|
||||
}
|
||||
onClick(event) {
|
||||
var child = this.$document[0].createElement(this.popover);
|
||||
this.$compile(child)(this.$scope);
|
||||
this.vnPopover.show(child, this.element);
|
||||
|
||||
// XXX: ¿Existe una forma más adecuada de acceder al controlador de un componente?
|
||||
var childCtrl = angular.element(child).isolateScope().$ctrl;
|
||||
childCtrl.onSubmit = (filter) => this.onChildSubmit(filter);
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
onChildSubmit(filter) {
|
||||
this.vnPopover.hide();
|
||||
this.index.filter = filter;
|
||||
this.onSubmit();
|
||||
}
|
||||
onSubmit() {
|
||||
if(this.onSearch)
|
||||
this.onSearch();
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', '$document', '$compile', 'vnPopover'];
|
||||
|
||||
export const NAME = 'vnSearchbar'
|
||||
export const COMPONENT = {
|
||||
template: require('./searchbar.html'),
|
||||
bindings: {
|
||||
model: '<',
|
||||
search: '&',
|
||||
index: '<',
|
||||
onSearch: '&',
|
||||
advanced: '=',
|
||||
popover: '@'
|
||||
},
|
||||
controller: controller
|
||||
controller: Controller
|
||||
};
|
||||
module.component(NAME, COMPONENT);
|
||||
|
||||
controller.$inject = ['$element', '$scope', '$document', '$compile', 'vnPopover'];
|
||||
function controller($element, $scope, $document, $compile, popover) {
|
||||
this.onClick = function(event) {
|
||||
var child = $document[0].createElement(this.popover);
|
||||
$compile(child)($scope);
|
||||
popover.show(child, $element[0]);
|
||||
|
||||
// XXX: ¿Existe una forma más adecuada de acceder al controlador de un componente?
|
||||
var childCtrl = angular.element(child).isolateScope().$ctrl;
|
||||
childCtrl.onSubmit = () => {
|
||||
popover.hide();
|
||||
this.model.params = childCtrl.filter;
|
||||
this.search();
|
||||
};
|
||||
|
||||
event.preventDefault();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,52 +1,15 @@
|
|||
.display-block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*angular-paging*/
|
||||
.well {
|
||||
min-height: 20px;
|
||||
padding: 19px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.pagination {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.pagination > li > a,
|
||||
.pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
margin-left: -1px;
|
||||
line-height: 1.42857143;
|
||||
color: #337ab7;
|
||||
text-decoration: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.pagination > li:first-child > a,
|
||||
.pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
min-height: 20px;
|
||||
padding: 19px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.pagination>li.active>a {
|
||||
background: #4f94ce;
|
||||
color: #fff;
|
||||
}
|
||||
ul.pagination li a:hover:not(.active) {background-color: #ddd;}
|
||||
/* fin angular-paging*/
|
||||
|
|
16
db.json
16
db.json
|
@ -2,10 +2,10 @@
|
|||
"ids": {
|
||||
"User": 2,
|
||||
"AccessToken": 2,
|
||||
"Client": 20,
|
||||
"Client": 22,
|
||||
"PaymentMethod": 4,
|
||||
"SalesPerson": 11,
|
||||
"Address": 83,
|
||||
"Address": 86,
|
||||
"Country": 10,
|
||||
"Province": 44,
|
||||
"Agency": 4,
|
||||
|
@ -20,11 +20,12 @@
|
|||
"NUf7o684TmteojFX9KmPOpaDLthjP5Def4wuy83Yjv31i43HHiWgV3FyBp6pX8Ue": "{\"id\":\"NUf7o684TmteojFX9KmPOpaDLthjP5Def4wuy83Yjv31i43HHiWgV3FyBp6pX8Ue\",\"ttl\":1209600,\"created\":\"2016-11-21T11:06:11.113Z\",\"userId\":1}"
|
||||
},
|
||||
"Client": {
|
||||
"12": "{\"name\":\"Verdnatura\",\"id\":12,\"fi\":\"B97367486\",\"salesPerson\":8,\"telefono\":\"963242100\",\"socialName\":\"Verdnatura Levante SL\",\"active\":true,\"user\":\"verdnatura\",\"fax\":\"963242100\",\"phone\":\"963242101\",\"email\":\"informatica@verdnatura.es\",\"surcharge\":true,\"cyc\":321,\"credit\":1000,\"iban\":\"456\",\"street\":\"Avenida Espioca, 100\",\"city\":\"Silla\",\"postcode\":\"12345678\",\"mobile\":\"654654654\",\"dueDay\":321,\"gestdoc\":23452343,\"province\":1,\"country\":1,\"modify\":\"BasicData\",\"navigate\":true,\"payMethod\":\"1\",\"coreVnh\":true,\"coreVnl\":true,\"invoiceByEmail\":true}",
|
||||
"14": "{\"name\":\"Leopoldo\",\"id\":14,\"street\":\"Casa\",\"fi\":\"1234567890A\",\"socialName\":\"Leopoldo\",\"fax\":\"963242100\",\"dischargeDate\":\"01/01/2017\",\"telefono\":\"963242100\",\"salesPerson\":\"2\",\"email\":\"informatica@verdnatura.es\",\"city\":\"Benicull\",\"postcode\":\"123\",\"phone\":\"963215469\",\"mobile\":\"667985632\",\"credit\":2345,\"cyc\":56,\"iban\":\"asdf\",\"dueDay\":345,\"gestdoc\":2435,\"surcharge\":true,\"navigate\":true,\"province\":6,\"country\":2,\"payMethod\":1}",
|
||||
"12": "{\"name\":\"Verdnatura\",\"id\":12,\"fi\":\"B97367486\",\"salesPerson\":8,\"telefono\":\"963242100\",\"socialName\":\"Verdnatura Levante SL\",\"active\":true,\"user\":\"verdnatura\",\"fax\":\"963242100\",\"phone\":\"963242101\",\"email\":\"informatica@verdnatura.es\",\"surcharge\":true,\"cyc\":321,\"credit\":1000,\"iban\":\"456\",\"street\":\"Avenida Espioca, 100\",\"city\":\"Silla\",\"postcode\":\"1234567\",\"mobile\":\"654654654\",\"dueDay\":321,\"gestdoc\":23452343,\"province\":3,\"country\":1,\"modify\":\"BasicData\",\"navigate\":true,\"payMethod\":\"1\",\"coreVnh\":true,\"coreVnl\":true,\"invoiceByEmail\":true}",
|
||||
"14": "{\"name\":\"Leopoldo Martin\",\"id\":14,\"street\":\"Casa\",\"fi\":\"1234567890A\",\"socialName\":\"Leopoldo\",\"fax\":\"963242100\",\"dischargeDate\":\"01/01/2017\",\"telefono\":\"963242100\",\"salesPerson\":\"2\",\"email\":\"leomartin@verdnatura.es\",\"city\":\"Benicull\",\"postcode\":\"123\",\"phone\":\"963215469\",\"mobile\":\"667985632\",\"credit\":2345,\"cyc\":56,\"iban\":\"asdf\",\"dueDay\":345,\"gestdoc\":2435,\"surcharge\":true,\"navigate\":true,\"province\":6,\"country\":2,\"payMethod\":1}",
|
||||
"15": "{\"name\":\"Florsiteria Pepa\",\"fi\":\"12341234rasf\",\"socialName\":\"asdfasd\",\"dueDay\":5,\"id\":15,\"payMethod\":\"2\",\"salesPerson\":\"1\",\"modify\":\"BasicData\",\"iban\":\"sdfgsdfgsdfg\",\"email\":\"pepa@flores.es\",\"phone\":\"963242101\",\"city\":\"Alfarp\",\"postcode\":\"46985\"}",
|
||||
"16": "{\"name\":\"Floristeria Antonieta\",\"fi\":\"2345234523d\",\"socialName\":\"23452345assdfgsdfgt\",\"active\":true,\"dueDay\":5,\"id\":16,\"modify\":\"FiscalData\",\"email\":\"antonieta@gmail.com\",\"phone\":\"654654654\",\"mobile\":\"654456456\",\"fax\":\"456456456\",\"street\":\"asdfasdf\",\"salesPerson\":8,\"city\":\"Albalat de la Ribera\",\"postcode\":\"46532\"}",
|
||||
"19": "{\"name\":\"Planticas Eustaquio\",\"fi\":\"789456123B\",\"socialName\":\"Eustaquio Martinez\",\"active\":true,\"dueDay\":5,\"id\":19,\"email\":\"peustaquio@hotmail.es\",\"city\":\"Polinya\",\"postcode\":\"46231\",\"phone\":\"963215486\"}"
|
||||
"19": "{\"name\":\"Planticas Eustaquio\",\"fi\":\"789456123B\",\"socialName\":\"Eustaquio Martinez\",\"active\":true,\"dueDay\":5,\"id\":19,\"email\":\"peustaquio@hotmail.es\",\"city\":\"Polinya\",\"postcode\":\"46231\",\"phone\":\"963215486\"}",
|
||||
"21": "{\"name\":\"Ramos Antonieta\",\"fi\":\"B89564289\",\"socialName\":\"Antonia SL\",\"active\":true,\"dueDay\":5,\"id\":21,\"email\":\"ramos@rantonieta.es\",\"salesPerson\":8,\"phone\":\"986574232\"}"
|
||||
},
|
||||
"PaymentMethod": {
|
||||
"1": "{\"name\":\"Tarjeta\",\"id\":1}",
|
||||
|
@ -54,7 +55,10 @@
|
|||
"79": "{\"street\":\"a\",\"consignee\":\"a\",\"city\":\"a\",\"enabled\":true,\"id\":79}",
|
||||
"80": "{\"street\":\"b\",\"consignee\":\"a\",\"city\":\"c\",\"enabled\":true,\"id\":80}",
|
||||
"81": "{\"street\":\"street\",\"consignee\":\"consignee\",\"city\":\"city\",\"enabled\":true,\"id\":81}",
|
||||
"82": "{\"street\":\"Polígono\",\"consignee\":\"Verdnatura Levante SL\",\"city\":\"Picasent\",\"enabled\":true,\"client\":12,\"id\":82,\"province\":1,\"agency\":2,\"phone\":\"963242100\"}"
|
||||
"82": "{\"street\":\"Polígono\",\"consignee\":\"Verdnatura Levante SL\",\"city\":\"Picasent\",\"enabled\":true,\"client\":12,\"id\":82,\"province\":1,\"agency\":2,\"phone\":\"963242100\",\"mobile\":\"698357618\"}",
|
||||
"83": "{\"street\":\"San Nicolau de Bari, 6\",\"consignee\":\"Casa\",\"city\":\"Algemesi\",\"postcode\":\"46680\",\"enabled\":true,\"phone\":\"962480949\",\"client\":12,\"province\":1,\"agency\":1,\"id\":83,\"mobile\":\"658965745\"}",
|
||||
"84": "{\"street\":\"Poligono\",\"consignee\":\"Madrid\",\"city\":\"Madrid\",\"enabled\":true,\"client\":12,\"id\":84,\"postcode\":\"46001\",\"province\":2,\"agency\":2,\"phone\":\"912356489\",\"mobile\":\"654236589\"}",
|
||||
"85": "{\"street\":\"Avenida la Parra, 43\",\"consignee\":\"Ramos Antonienta\",\"city\":\"Llombai\",\"enabled\":true,\"client\":21,\"province\":1,\"id\":85,\"phone\":\"965874583\",\"mobile\":\"675418958\",\"postcode\":\"46985\",\"agency\":2,\"default\":true}"
|
||||
},
|
||||
"Country": {
|
||||
"1": "{\"id\":1,\"name\":\"Spain\"}",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
module.exports = function(Address) {
|
||||
|
||||
Address.validate('default',isEnabled,{message: 'No se puede poner predeterminado un consignatario desactivado'});
|
||||
function isEnabled(err) {
|
||||
if (!this.enabled && this.default) err();
|
||||
|
@ -52,14 +51,11 @@ module.exports = function(Address) {
|
|||
Address.update({client: cl}, {default: false});
|
||||
}
|
||||
|
||||
|
||||
function generateErrorDefaultAddress(){
|
||||
var error = new Error();
|
||||
error.message = "No se puede desmarcar el consignatario predeterminado";
|
||||
error.status = 500;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -37,10 +37,15 @@
|
|||
}
|
||||
},
|
||||
"relations": {
|
||||
"country":{
|
||||
"country": {
|
||||
"type": "belongsTo",
|
||||
"model": "Country",
|
||||
"foreignKey": "id"
|
||||
},
|
||||
"client": {
|
||||
"type": "hasOne",
|
||||
"model": "Client",
|
||||
"foreignKey": "id"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
let installMethod = require('../util.js');
|
||||
|
||||
module.exports = function(Client) {
|
||||
// Validations
|
||||
|
||||
|
@ -73,87 +75,34 @@ module.exports = function(Client) {
|
|||
})
|
||||
};
|
||||
|
||||
// Filters
|
||||
// Basic filter
|
||||
|
||||
let Model = Client;
|
||||
let fields = {
|
||||
id: false,
|
||||
fi: false,
|
||||
name: true,
|
||||
socialName: true,
|
||||
city: true,
|
||||
postcode: false,
|
||||
email: true,
|
||||
phone: false
|
||||
};
|
||||
|
||||
Model.remoteMethod('filter', {
|
||||
description: 'List items using a filter',
|
||||
accessType: 'READ',
|
||||
accepts: {
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
description: 'Filter defining where'
|
||||
},
|
||||
returns: {
|
||||
arg: 'data',
|
||||
type: 'Client',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: '/filter',
|
||||
verb: 'get'
|
||||
}
|
||||
});
|
||||
|
||||
Model.filter = function(filter, cb) {
|
||||
filter = removeEmpty(filter);
|
||||
let where = {};
|
||||
|
||||
if(filter)
|
||||
for (let field in fields)
|
||||
if(filter[field]) {
|
||||
if(fields[field])
|
||||
where[field] = {ilike: filter[field]};
|
||||
else
|
||||
where[field] = filter[field];
|
||||
}
|
||||
|
||||
Model.find({where: where}, function(err, instances) {
|
||||
if(!err) {
|
||||
cb(null, instances);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
function removeEmpty(o) {
|
||||
if(Array.isArray(o)) {
|
||||
let array = [];
|
||||
for(let item of o) {
|
||||
let i = removeEmpty(item);
|
||||
if(!isEmpty(item))
|
||||
array.push(item);
|
||||
};
|
||||
if(array.length > 0)
|
||||
return array;
|
||||
}
|
||||
else if (typeof o === 'object') {
|
||||
let object = {};
|
||||
for(let key in o) {
|
||||
let i = removeEmpty(o[key]);
|
||||
if(!isEmpty(i))
|
||||
object[key] = i;
|
||||
}
|
||||
if(Object.keys(object).length > 0)
|
||||
return object;
|
||||
}
|
||||
else if (!isEmpty(o))
|
||||
return o;
|
||||
|
||||
return undefined;
|
||||
installMethod(Client, 'filter', filterClients);
|
||||
function filterClients(p){
|
||||
return {
|
||||
where: {
|
||||
id: p.id,
|
||||
name: {ilike: p.name},
|
||||
cif: p.cif,
|
||||
socialName: {ilike: p.socialName},
|
||||
city: {ilike: p.city},
|
||||
postcode: p.postcode,
|
||||
email: {ilike: p.email},
|
||||
phone: p.phone
|
||||
},
|
||||
skip: (p.page - 1) * p.size,
|
||||
limit: p.size
|
||||
};
|
||||
}
|
||||
|
||||
function isEmpty(value) {
|
||||
return value === undefined || value === "";
|
||||
installMethod(Client, 'filter', filterAddresses);
|
||||
function filterAddresses(p){
|
||||
return {
|
||||
where: {
|
||||
client: p.client,
|
||||
},
|
||||
skip: (p.page - 1) * p.size,
|
||||
limit: p.size
|
||||
};
|
||||
}
|
||||
};
|
|
@ -86,6 +86,11 @@
|
|||
"type": "hasOne",
|
||||
"model": "Account",
|
||||
"foreignKey": "id"
|
||||
},
|
||||
"addresses": {
|
||||
"type": "hasMany",
|
||||
"model": "Address",
|
||||
"foreignKey": "client"
|
||||
}
|
||||
},
|
||||
"scopes": {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
module.exports = installMethod;
|
||||
|
||||
function installMethod(Model, methodName, filterCb) {
|
||||
Model.remoteMethod(methodName, {
|
||||
description: 'List items using a filter',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
required: true,
|
||||
description: 'Filter defining where',
|
||||
http: function(ctx) {
|
||||
return ctx.req.query;
|
||||
}
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
arg: 'data',
|
||||
type: [Model.modelName],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/${methodName}`,
|
||||
verb: 'get'
|
||||
}
|
||||
});
|
||||
|
||||
Model.filter = function(params, cb) {
|
||||
let filter = removeEmpty(filterCb(params));
|
||||
Model.find(filter, function(err, instances) {
|
||||
if(!err) {
|
||||
cb(null, instances);
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function removeEmpty(o) {
|
||||
if(Array.isArray(o)) {
|
||||
let array = [];
|
||||
for(let item of o) {
|
||||
let i = removeEmpty(item);
|
||||
if(!isEmpty(item))
|
||||
array.push(item);
|
||||
};
|
||||
if(array.length > 0)
|
||||
return array;
|
||||
}
|
||||
else if (typeof o === 'object') {
|
||||
let object = {};
|
||||
for(let key in o) {
|
||||
let i = removeEmpty(o[key]);
|
||||
if(!isEmpty(i))
|
||||
object[key] = i;
|
||||
}
|
||||
if(Object.keys(object).length > 0)
|
||||
return object;
|
||||
}
|
||||
else if (!isEmpty(o))
|
||||
return o;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isEmpty(value) {
|
||||
return value === undefined || value === "";
|
||||
}
|
Loading…
Reference in New Issue