Added step-control component and basic data step controllers
This commit is contained in:
parent
91a7f5a45c
commit
228239b027
|
@ -29,4 +29,5 @@ import './combo/combo';
|
|||
import './card/card';
|
||||
import './switch/switch';
|
||||
import './float-button/float-button';
|
||||
import './step-control/step-control';
|
||||
import './label-value/label-value';
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<section class="step-control">
|
||||
<section class="steps">
|
||||
<section class="step" ng-repeat="step in $ctrl.steps track by $index">
|
||||
<section class="circle"
|
||||
vn-tooltip="{{::step.name}}"
|
||||
tooltip-position="down"
|
||||
ng-click="$ctrl.currentState = step.state"
|
||||
ng-class="{active: step.state == $ctrl.currentState}">
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section class="buttons">
|
||||
<section class="step">
|
||||
<vn-button
|
||||
ng-if="$ctrl.canMovePrevious()"
|
||||
label="Previous"
|
||||
ng-click="$ctrl.onPreviousClick()">
|
||||
</vn-button>
|
||||
</section>
|
||||
<section class="step">
|
||||
<vn-button
|
||||
ng-if="$ctrl.canMoveNext()"
|
||||
label="Next"
|
||||
ng-click="$ctrl.onNextClick()">
|
||||
</vn-button>
|
||||
<vn-submit
|
||||
ng-if="$ctrl.canFinalize()"
|
||||
label="Finalize"
|
||||
ng-click="$ctrl.onStepEnd()">
|
||||
</vn-submit>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
|
@ -0,0 +1,71 @@
|
|||
import ngModule from '../../module';
|
||||
import './style.scss';
|
||||
|
||||
export default class StepControl {
|
||||
constructor($state) {
|
||||
this.$state = $state;
|
||||
}
|
||||
|
||||
set currentState(state) {
|
||||
let isAllowed = true;
|
||||
|
||||
if (this.onStepChange)
|
||||
isAllowed = this.onStepChange({state});
|
||||
|
||||
if (isAllowed)
|
||||
this.$state.go(state);
|
||||
}
|
||||
|
||||
get totalSteps() {
|
||||
return this.steps.length;
|
||||
}
|
||||
|
||||
get currentState() {
|
||||
return this.$state.current.name;
|
||||
}
|
||||
|
||||
get currentStepIndex() {
|
||||
for (let i = 0; i < this.steps.length; i++) {
|
||||
if (this.steps[i].state == this.$state.current.name)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
onPreviousClick() {
|
||||
let state = this.steps[this.currentStepIndex - 1].state;
|
||||
|
||||
this.currentState = state;
|
||||
}
|
||||
|
||||
onNextClick() {
|
||||
let state = this.steps[this.currentStepIndex + 1].state;
|
||||
|
||||
this.currentState = state;
|
||||
}
|
||||
|
||||
canMovePrevious() {
|
||||
return this.steps[0].state != this.currentState;
|
||||
}
|
||||
|
||||
canFinalize() {
|
||||
let lastStep = this.steps[this.totalSteps - 1];
|
||||
return lastStep.state == this.currentState;
|
||||
}
|
||||
|
||||
canMoveNext() {
|
||||
let lastStep = this.steps[this.totalSteps - 1];
|
||||
return lastStep.state != this.currentState;
|
||||
}
|
||||
}
|
||||
|
||||
StepControl.$inject = ['$state'];
|
||||
|
||||
ngModule.component('vnStepControl', {
|
||||
template: require('./step-control.html'),
|
||||
controller: StepControl,
|
||||
bindings: {
|
||||
steps: '<',
|
||||
onStepChange: '&?',
|
||||
onStepEnd: '&?'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
import './step-control.js';
|
||||
|
||||
describe('Component vnStepControl', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
let $state;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('ticket');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$state_) => {
|
||||
$componentController = _$componentController_;
|
||||
$state = _$state_;
|
||||
controller = $componentController('vnStepControl', {$state: $state});
|
||||
}));
|
||||
|
||||
describe('currentState()', () => {
|
||||
it(`should call the onStepChange method then return false and never call the go method`, () => {
|
||||
controller.onStepChange = jasmine.createSpy(controller, 'onStepChange').and.returnValue(false);
|
||||
spyOn(controller.$state, 'go');
|
||||
|
||||
controller.currentState = "something";
|
||||
|
||||
expect(controller.onStepChange).toHaveBeenCalledWith({state: 'something'});
|
||||
expect(controller.$state.go).not.toHaveBeenCalledWith("something");
|
||||
});
|
||||
|
||||
it(`should call the onStepChange method then return true and finally call the go method`, () => {
|
||||
controller.onStepChange = jasmine.createSpy(controller, 'onStepChange').and.returnValue(true);
|
||||
spyOn(controller.$state, 'go');
|
||||
|
||||
controller.currentState = "something";
|
||||
|
||||
expect(controller.onStepChange).toHaveBeenCalledWith({state: 'something'});
|
||||
expect(controller.$state.go).toHaveBeenCalledWith("something");
|
||||
});
|
||||
});
|
||||
|
||||
describe('currentStepIndex()', () => {
|
||||
it('should get the current state index from an Array of states', () => {
|
||||
controller.$state.current.name = 'iam_a_current_state';
|
||||
controller.steps = [{state: 'iam_not_current_state'}, {state: 'iam_a_current_state'}];
|
||||
|
||||
let result = controller.currentStepIndex;
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,58 @@
|
|||
vn-step-control {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.step-control {
|
||||
border-top: 2px solid rgb(255,152,0);
|
||||
margin-bottom: 15px;
|
||||
|
||||
& > .steps {
|
||||
display: flex;
|
||||
flex-direction: row
|
||||
}
|
||||
|
||||
& > .steps > .step {
|
||||
justify-content: center;
|
||||
min-width: 125px;
|
||||
display: flex;
|
||||
flex: auto
|
||||
}
|
||||
|
||||
& > .steps > .step .circle {
|
||||
border: 2px solid rgb(255,152,0);
|
||||
background-color: #FFF;
|
||||
align-content: center;
|
||||
margin-top: -9.5px;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
height: 15px;
|
||||
width: 15px
|
||||
}
|
||||
|
||||
& > .steps > .step .circle.active {
|
||||
background-color: rgb(255,152,0);
|
||||
}
|
||||
|
||||
& > .buttons {
|
||||
display: flex;
|
||||
flex: auto;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 10px
|
||||
}
|
||||
|
||||
& > .buttons > .step {
|
||||
display: flex
|
||||
}
|
||||
|
||||
& > .buttons > .step > .mdl-button {
|
||||
line-height: 32px;
|
||||
font-size: 12px;
|
||||
padding: 0 12px;
|
||||
height: 32px
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,4 +7,7 @@ Add: Add
|
|||
Search: Search
|
||||
Show More: Show More
|
||||
No more results: No more results
|
||||
Hide: Hide
|
||||
Hide: Hide
|
||||
Next: Next
|
||||
Finalize: Finalize
|
||||
Previous: Back
|
|
@ -7,4 +7,7 @@ Add: Añadir
|
|||
Search: Buscar
|
||||
Show More: Ver más
|
||||
No more results: No hay más resultados
|
||||
Hide: Ocultar
|
||||
Hide: Ocultar
|
||||
Next: Siguiente
|
||||
Finalize: Finalizar
|
||||
Previous: Anterior
|
|
@ -1,4 +1,4 @@
|
|||
<form name="form" ng-submit="$ctrl.onSubmit()" ng-cloak>
|
||||
<form name="form">
|
||||
<vn-card pad-large>
|
||||
<vn-title>Basic data</vn-title>
|
||||
<vn-horizontal>
|
||||
|
@ -19,7 +19,7 @@
|
|||
initial-data="$ctrl.ticket.addressFk">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/AgencyModes/"
|
||||
url="/api/AgencyModes"
|
||||
label="Agency"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
|
@ -48,7 +48,4 @@
|
|||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Next"></vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
|
|
|
@ -1,22 +1,17 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope, $timeout, $state) {
|
||||
constructor($scope) {
|
||||
this.$scope = $scope;
|
||||
this.$timeout = $timeout;
|
||||
this.$state = $state;
|
||||
}
|
||||
onSubmit() {
|
||||
this.$state.go('ticket.card.data.stepTwo');
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$scope', '$timeout', '$state'];
|
||||
Controller.$inject = ['$scope'];
|
||||
|
||||
ngModule.component('vnTicketDataStepOne', {
|
||||
template: require('./step-one.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
ticket: '<'
|
||||
},
|
||||
controller: Controller
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<form name="form">
|
||||
<vn-card pad-large>
|
||||
<vn-title>Step tree</vn-title>
|
||||
<vn-horizontal>
|
||||
Ticket id {{$ctrl.ticket.id}}
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
</form>
|
|
@ -0,0 +1,15 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
class Controller {
|
||||
constructor($scope) {
|
||||
this.$scope = $scope;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTicketDataStepThree', {
|
||||
template: require('./step-three.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
ticket: '<'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
<form name="form">
|
||||
<vn-card pad-large>
|
||||
<vn-title>Price gap</vn-title>
|
||||
<vn-horizontal>
|
||||
<table class="vn-grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th number translate>Item</th>
|
||||
<th translate style="text-align:center">Description</th>
|
||||
<th number translate>Quantity</th>
|
||||
<th number translate>Price</th>
|
||||
<th number translate>New price</th>
|
||||
<th number translate>Price gap</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="sale in $ctrl.ticket.sales track by sale.id">
|
||||
<td number>{{("000000"+sale.itemFk).slice(-6)}}</td>
|
||||
<td><vn-fetched-tags sale="sale"/></td>
|
||||
<td number>{{::sale.quantity}}</td>
|
||||
<td number>{{::sale.price | currency:'€':2}}</td>
|
||||
<td number>-</td>
|
||||
<td number>-</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
</form>
|
|
@ -0,0 +1,28 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
class Controller {
|
||||
constructor($http, $scope) {
|
||||
this.$http = $http;
|
||||
this.$scope = $scope;
|
||||
}
|
||||
|
||||
$onChanges(data) {
|
||||
if (!this.ticket || !this.ticket.id) return;
|
||||
|
||||
let query = `/ticket/api/sales/${this.ticket.id}/priceGap`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data)
|
||||
this.ticket.sales = res.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$http', '$scope'];
|
||||
|
||||
ngModule.component('vnTicketDataStepTwo', {
|
||||
template: require('./step-two.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
ticket: '<'
|
||||
}
|
||||
});
|
|
@ -1,4 +1,5 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/sale/filter')(Self);
|
||||
require('../methods/sale/priceGap')(Self);
|
||||
require('../methods/sale/saleComponentFilter.js')(Self);
|
||||
require('../methods/sale/price-gap')(Self);
|
||||
};
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
{
|
||||
"name": "Sale",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "sale"
|
||||
}
|
||||
"name": "Sale",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "sale"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"concept": {
|
||||
"type": "String"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "Number"
|
||||
},
|
||||
"price": {
|
||||
"type": "Number"
|
||||
},
|
||||
"discount": {
|
||||
"type": "Number"
|
||||
},
|
||||
"reserved": {
|
||||
"type": "Number"
|
||||
},
|
||||
"isPicked": {
|
||||
"type": "Number"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
}
|
||||
"concept": {
|
||||
"type": "String"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "Number"
|
||||
},
|
||||
"price": {
|
||||
"type": "Number"
|
||||
},
|
||||
"discount": {
|
||||
"type": "Number"
|
||||
},
|
||||
"reserved": {
|
||||
"type": "Number"
|
||||
},
|
||||
"isPicked": {
|
||||
"type": "Number"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"item": {
|
||||
|
@ -51,6 +51,11 @@
|
|||
"type": "hasOne",
|
||||
"model": "SaleChecked",
|
||||
"foreignKey": "saleFk"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"type": "hasMany",
|
||||
"model": "SaleComponent",
|
||||
"foreignKey": "saleFk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
module.exports = Self => {
|
||||
Self.installMethod('filter', filterParams);
|
||||
|
||||
function filterParams(params) {
|
||||
return {
|
||||
where: {
|
||||
ticketFk: params.ticketFk
|
||||
},
|
||||
skip: (params.page - 1) * params.size,
|
||||
limit: params.size,
|
||||
order: params.order || 'concept ASC',
|
||||
include: [{
|
||||
relation: "item",
|
||||
scope: {
|
||||
include: {
|
||||
relation: "itemTag",
|
||||
scope: {
|
||||
fields: ["tagFk", "value"],
|
||||
include: {
|
||||
relation: "tag",
|
||||
scope: {
|
||||
fields: ["name"]
|
||||
}
|
||||
},
|
||||
limit: 6
|
||||
}
|
||||
},
|
||||
fields: ["itemFk", "name"]
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: "isChecked",
|
||||
scope: {
|
||||
fields: ["isChecked"]
|
||||
}
|
||||
}]
|
||||
};
|
||||
}
|
||||
};
|
|
@ -1,4 +0,0 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/sale/filter.js')(Self);
|
||||
require('../methods/sale/saleComponentFilter.js')(Self);
|
||||
};
|
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
"name": "Sale",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "sale"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "Number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"concept": {
|
||||
"type": "String"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "Number"
|
||||
},
|
||||
"price": {
|
||||
"type": "Number"
|
||||
},
|
||||
"discount": {
|
||||
"type": "Number"
|
||||
},
|
||||
"reserved": {
|
||||
"type": "Number"
|
||||
},
|
||||
"isPicked": {
|
||||
"type": "Number"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"item": {
|
||||
"type": "belongsTo",
|
||||
"model": "Item",
|
||||
"foreignKey": "itemFk",
|
||||
"required": true
|
||||
},
|
||||
"ticket": {
|
||||
"type": "belongsTo",
|
||||
"model": "Ticket",
|
||||
"foreignKey": "ticketFk",
|
||||
"required": true
|
||||
},
|
||||
"isChecked": {
|
||||
"type": "hasOne",
|
||||
"model": "SaleChecked",
|
||||
"foreignKey": "saleFk"
|
||||
},
|
||||
"components": {
|
||||
"type": "hasMany",
|
||||
"model": "SaleComponent",
|
||||
"foreignKey": "saleFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,6 @@
|
|||
"ObservationType": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Sale": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"TicketTracking": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue