diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js
index 4148a4a055..11fb86416e 100644
--- a/e2e/helpers/extensions.js
+++ b/e2e/helpers/extensions.js
@@ -6,7 +6,7 @@ import config from './config.js';
let currentUser;
-let asyncActions = {
+let actions = {
// Generic extensions
clickIfExists: async function(selector) {
@@ -15,16 +15,16 @@ let asyncActions = {
return exists;
},
- hasClass: async function(selector, className) {
- return await this.evaluate((selector, className) => {
- document.querySelector(selector).classList.contains(className);
- }, selector, className);
- },
-
parsedUrl: async function() {
return new URL(await this.url());
},
+ waitUntilNotPresent: async function(selector) {
+ await this.wait(selector => {
+ return document.querySelector(selector) == null;
+ }, selector);
+ },
+
// Salix specific extensions
changeLanguageToEnglish: async function() {
@@ -116,31 +116,21 @@ let asyncActions = {
}, selector, time);
},
- isDisabled: async function(selector) {
- return await this.hasClass(selector, 'disabled');
- }
-};
-
-let actions = {
- clearTextarea: function(selector, done) {
- this.wait(selector)
+ clearTextarea: function(selector) {
+ return this.wait(selector)
.evaluate(inputSelector => {
return document.querySelector(inputSelector).value = '';
- }, selector)
- .then(done)
- .catch(done);
+ }, selector);
},
- clearInput: function(selector, done) {
- this.wait(selector)
+ clearInput: function(selector) {
+ return this.wait(selector)
.evaluate(selector => {
let $ctrl = document.querySelector(selector).closest('.vn-field').$ctrl;
$ctrl.field = null;
$ctrl.$.$apply();
$ctrl.input.dispatchEvent(new Event('change'));
- }, selector)
- .then(done)
- .catch(done);
+ }, selector);
},
getProperty: function(selector, property, done) {
@@ -149,47 +139,39 @@ let actions = {
}, done, selector, property);
},
- waitPropertyLength: function(selector, property, minLength, done) {
- this.wait((selector, property, minLength) => {
+ waitPropertyLength: function(selector, property, minLength) {
+ return this.wait((selector, property, minLength) => {
const element = document.querySelector(selector);
return element && element[property] != null && element[property] !== '' && element[property].length >= minLength;
}, selector, property, minLength)
- .getProperty(selector, property)
- .then(result => done(null, result), done);
+ .getProperty(selector, property);
},
- waitPropertyValue: function(selector, property, status, done) {
- this.wait(selector)
+ waitPropertyValue: function(selector, property, status) {
+ return this.wait(selector)
.wait((selector, property, status) => {
const element = document.querySelector(selector);
return element[property] === status;
- }, selector, property, status)
- .then(done)
- .catch(done);
+ }, selector, property, status);
},
- waitToGetProperty: function(selector, property, done) {
- this.wait((selector, property) => {
+ waitToGetProperty: function(selector, property) {
+ return this.wait((selector, property) => {
const element = document.querySelector(selector);
return element && element[property] != null && element[property] !== '';
}, selector, property)
- .getProperty(selector, property)
- .then(result => done(null, result), done);
+ .getProperty(selector, property);
},
- write: function(selector, text, done) {
- this.wait(selector)
- .type(selector, text)
- .then(done)
- .catch(done);
+ write: function(selector, text) {
+ return this.wait(selector)
+ .type(selector, text);
},
- waitToClick: function(selector, done) {
- this.wait(selector)
- .click(selector)
- .then(done)
- .catch(done);
+ waitToClick: function(selector) {
+ return this.wait(selector)
+ .click(selector);
},
focusElement: function(selector, done) {
@@ -197,9 +179,7 @@ let actions = {
.evaluate_now(selector => {
let element = document.querySelector(selector);
element.focus();
- }, done, selector)
- .then(done)
- .catch(done);
+ }, done, selector);
},
isVisible: function(selector, done) {
@@ -245,29 +225,23 @@ let actions = {
}, done, selector);
},
- waitImgLoad: function(selector, done) {
- this.wait(selector)
+ waitImgLoad: function(selector) {
+ return this.wait(selector)
.wait(selector => {
const imageReady = document.querySelector(selector).complete;
return imageReady;
- }, selector)
- .then(done)
- .catch(() => {
- done(new Error(`image ${selector}, load timed out`));
- });
+ }, selector);
},
- clickIfVisible: function(selector, done) {
- this.wait(selector)
+ clickIfVisible: function(selector) {
+ return this.wait(selector)
.isVisible(selector)
.then(visible => {
if (visible)
return this.click(selector);
throw new Error(`invisible selector: ${selector}`);
- })
- .then(done)
- .catch(done);
+ });
},
countElement: function(selector, done) {
@@ -276,56 +250,40 @@ let actions = {
}, done, selector);
},
- waitForNumberOfElements: function(selector, count, done) {
- this.wait((selector, count) => {
+ waitForNumberOfElements: function(selector, count) {
+ return this.wait((selector, count) => {
return document.querySelectorAll(selector).length === count;
- }, selector, count)
- .then(done)
- .catch(() => {
- done(new Error(`.waitForNumberOfElements() for ${selector}, count ${count} timed out`));
- });
+ }, selector, count);
},
- waitForClassNotPresent: function(selector, className, done) {
- this.wait(selector)
+ waitForClassNotPresent: function(selector, className) {
+ return this.wait(selector)
.wait((selector, className) => {
if (!document.querySelector(selector).classList.contains(className))
return true;
- }, selector, className)
- .then(done)
- .catch(() => {
- done(new Error(`.waitForClassNotPresent() for ${selector}, class ${className} timed out`));
- });
+ }, selector, className);
},
- waitForClassPresent: function(selector, className, done) {
- this.wait(selector)
+ waitForClassPresent: function(selector, className) {
+ return this.wait(selector)
.wait((elementSelector, targetClass) => {
if (document.querySelector(elementSelector).classList.contains(targetClass))
return true;
- }, selector, className)
- .then(done)
- .catch(() => {
- done(new Error(`.waitForClassPresent() for ${selector}, class ${className} timed out`));
- });
+ }, selector, className);
},
- waitForTextInElement: function(selector, text, done) {
- this.wait(selector)
+ waitForTextInElement: function(selector, text) {
+ return this.wait(selector)
.wait((selector, text) => {
return document.querySelector(selector).innerText.toLowerCase().includes(text.toLowerCase());
- }, selector, text)
- .then(done)
- .catch(done);
+ }, selector, text);
},
- waitForTextInInput: function(selector, text, done) {
- this.wait(selector)
+ waitForTextInInput: function(selector, text) {
+ return this.wait(selector)
.wait((selector, text) => {
return document.querySelector(selector).value.toLowerCase().includes(text.toLowerCase());
- }, selector, text)
- .then(done)
- .catch(done);
+ }, selector, text);
},
waitForInnerText: function(selector, done) {
@@ -339,20 +297,16 @@ let actions = {
}, done, selector);
},
- waitForEmptyInnerText: function(selector, done) {
- this.wait(selector => {
+ waitForEmptyInnerText: function(selector) {
+ return this.wait(selector => {
return document.querySelector(selector).innerText == '';
- }, selector)
- .then(done)
- .catch(done);
+ }, selector);
},
- waitForURL: function(hashURL, done) {
- this.wait(hash => {
+ waitForURL: function(hashURL) {
+ return this.wait(hash => {
return document.location.hash.includes(hash);
- }, hashURL)
- .then(done)
- .catch(done);
+ }, hashURL);
},
waitForShapes: function(selector, done) {
@@ -368,11 +322,9 @@ let actions = {
return shapesList;
}, done, selector);
},
- waitForSnackbar: function(done) {
- this.wait(500).waitForShapes('vn-snackbar .shape .text')
- .then(shapes => {
- done(null, shapes);
- }).catch(done);
+ waitForSnackbar: function() {
+ return this.wait(500)
+ .waitForShapes('vn-snackbar .shape .text');
},
waitForLastShape: function(selector, done) {
@@ -384,15 +336,13 @@ let actions = {
}, done, selector);
},
- waitForLastSnackbar: function(done) {
- this.wait(500).waitForLastShape('vn-snackbar .shape .text')
- .then(shapes => {
- done(null, shapes);
- }).catch(done);
+ waitForLastSnackbar: function() {
+ return this.wait(500)
+ .waitForLastShape('vn-snackbar .shape .text');
},
- accessToSearchResult: function(searchValue, done) {
- this.clearInput('vn-searchbar input')
+ accessToSearchResult: function(searchValue) {
+ return this.clearInput('vn-searchbar input')
.write('vn-searchbar input', searchValue)
.click('vn-searchbar vn-icon[icon="search"]')
.wait(100)
@@ -405,13 +355,11 @@ let actions = {
return this.waitToClick('ui-view vn-card vn-td');
return this.waitToClick('ui-view vn-card a');
- })
- .then(done)
- .catch(done);
+ });
},
- accessToSection: function(sectionRoute, done) {
- this.wait(`vn-left-menu`)
+ accessToSection: function(sectionRoute) {
+ return this.wait(`vn-left-menu`)
.evaluate(sectionRoute => {
return document.querySelector(`vn-left-menu ul li ul li > a[ui-sref="${sectionRoute}"]`) != null;
}, sectionRoute)
@@ -422,45 +370,35 @@ let actions = {
return this.waitToClick('vn-left-menu .collapsed')
.wait('vn-left-menu .expanded')
.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
- })
- .then(done)
- .catch(done);
+ });
},
- autocompleteSearch: function(autocompleteSelector, searchValue, done) {
- this.waitToClick(`${autocompleteSelector} input`)
- .write(`.vn-popover.shown .vn-drop-down input`, searchValue)
- .waitToClick(`.vn-popover.shown .vn-drop-down li.active`)
+ autocompleteSearch: function(autocompleteSelector, searchValue) {
+ return this.waitToClick(`${autocompleteSelector} input`)
+ .write(`.vn-drop-down.shown input`, searchValue)
+ .waitToClick(`.vn-drop-down.shown li.active`)
.wait((autocompleteSelector, searchValue) => {
return document.querySelector(`${autocompleteSelector} input`).value
.toLowerCase()
.includes(searchValue.toLowerCase());
- }, autocompleteSelector, searchValue)
- .then(done)
- .catch(() => {
- done(new Error(`.autocompleteSearch() for value ${searchValue} in ${autocompleteSelector} timed out`));
- });
+ }, autocompleteSelector, searchValue);
},
- reloadSection: function(sectionRoute, done) {
- this.waitToClick('vn-icon[icon="desktop_windows"]')
+ reloadSection: function(sectionRoute) {
+ return this.waitToClick('vn-icon[icon="desktop_windows"]')
.wait('vn-card.summary')
- .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`)
- .then(done)
- .catch(done);
+ .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
},
- forceReloadSection: function(sectionRoute, done) {
- this.waitToClick('vn-icon[icon="desktop_windows"]')
+ forceReloadSection: function(sectionRoute) {
+ return this.waitToClick('vn-icon[icon="desktop_windows"]')
.waitToClick('button[response="ACCEPT"]')
.wait('vn-card.summary')
- .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`)
- .then(done)
- .catch(done);
+ .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
},
- checkboxState: function(selector, done) {
- this.wait(selector)
+ checkboxState: function(selector) {
+ return this.wait(selector)
.evaluate(selector => {
let checkbox = document.querySelector(selector);
switch (checkbox.$ctrl.field) {
@@ -471,40 +409,38 @@ let actions = {
default:
return 'unchecked';
}
- }, selector)
- .then(res => done(null, res))
- .catch(done);
+ }, selector);
},
- isDisabled: function(selector, done) {
- this.wait(selector)
+ isDisabled: function(selector) {
+ return this.wait(selector)
.evaluate(selector => {
let element = document.querySelector(selector);
return element.$ctrl.disabled;
- }, selector)
- .then(res => done(null, res))
- .catch(done);
+ }, selector);
},
- waitForSpinnerLoad: function(done) {
- let spinnerSelector = 'vn-spinner > div';
- this.waitForClassNotPresent(spinnerSelector, 'is-active')
- .then(done)
- .catch(done);
+ waitForSpinnerLoad: function() {
+ return this.waitForClassNotPresent('vn-spinner > div', 'is-active');
},
};
-for (let name in asyncActions) {
- let fn = asyncActions[name];
-
+for (let name in actions) {
Nightmare.action(name, function(...args) {
let done = args[args.length - 1];
- fn.apply(this, args)
- .then(res => done(null, res), done);
+ let promise = actions[name].apply(this, args);
+
+ if (promise) {
+ promise
+ .then(res => done(null, res))
+ .catch(err => {
+ let errArgs = args.slice(0, args.length - 1);
+ errArgs = errArgs
+ .map(i => JSON.stringify(i))
+ .join(', ');
+
+ done(new Error(`.${name}(${errArgs}) failed: ${err.message}`));
+ });
+ }
});
}
-
-Object.keys(actions).forEach(function(name) {
- let fn = actions[name];
- Nightmare.action(name, fn);
-});
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index 2b9caacd55..13b87f3499 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -18,7 +18,7 @@ export default {
userConfigFirstAutocompleteClear: '#localWarehouse .icons > vn-icon[icon=clear]',
userConfigSecondAutocompleteClear: '#localBank .icons > vn-icon[icon=clear]',
userConfigThirdAutocompleteClear: '#localCompany .icons > vn-icon[icon=clear]',
- acceptButton: 'vn-confirm button[response=ACCEPT]'
+ acceptButton: '.vn-confirm.shown button[response=ACCEPT]'
},
clientsIndex: {
searchClientInput: `vn-textfield input`,
@@ -44,7 +44,7 @@ export default {
},
clientDescriptor: {
moreMenu: 'vn-client-descriptor vn-icon-menu[icon=more_vert]',
- simpleTicketButton: '.vn-popover.shown .vn-drop-down li'
+ simpleTicketButton: '.vn-drop-down.shown li'
},
clientBasicData: {
basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]',
@@ -62,7 +62,7 @@ export default {
socialNameInput: `vn-textfield input[name="socialName"]`,
fiscalIdInput: `vn-textfield input[name="fi"]`,
equalizationTaxCheckbox: 'vn-check[ng-model="$ctrl.client.isEqualizated"]',
- acceptPropagationButton: 'vn-client-fiscal-data > vn-confirm button[response=ACCEPT]',
+ acceptPropagationButton: '.vn-confirm.shown button[response=ACCEPT]',
addressInput: `vn-textfield input[name="street"]`,
postcodeInput: `vn-textfield input[name="postcode"]`,
cityInput: `vn-textfield input[name="city"]`,
@@ -87,10 +87,10 @@ export default {
swiftBicAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.bankEntityFk"]',
clearswiftBicButton: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.bankEntityFk"] .icons > vn-icon[icon=clear]',
newBankEntityButton: 'vn-client-billing-data vn-icon-button[vn-tooltip="New bank entity"] > button',
- newBankEntityName: 'vn-client-billing-data > vn-dialog vn-textfield[label="Name"] input',
- newBankEntityBIC: 'vn-client-billing-data > vn-dialog vn-textfield[label="Swift / BIC"] input',
- newBankEntityCode: 'vn-client-billing-data > vn-dialog vn-textfield[label="Entity Code"] input',
- acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]',
+ newBankEntityName: '.vn-dialog.shown vn-textfield[label="Name"] input',
+ newBankEntityBIC: '.vn-dialog.shown vn-textfield[label="Swift / BIC"] input',
+ newBankEntityCode: '.vn-dialog.shown vn-textfield[label="Entity Code"] input',
+ acceptBankEntityButton: '.vn-dialog.shown button[response="ACCEPT"]',
saveButton: `button[type=submit]`
},
clientAddresses: {
@@ -163,9 +163,9 @@ export default {
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyFk"]',
newPaymentButton: `vn-float-button`,
- newPaymentBank: 'vn-client-balance-create vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
- newPaymentAmountInput: 'vn-client-balance-create vn-input-number[ng-model="$ctrl.receipt.amountPaid"] input',
- saveButton: 'vn-client-balance-create vn-button[label="Save"]',
+ newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
+ newPaymentAmountInput: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"] input',
+ saveButton: '.vn-dialog.shown vn-button[label="Save"]',
firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)'
},
@@ -177,7 +177,7 @@ export default {
deleteFileButton: 'vn-client-dms-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
firstDocWorker: 'vn-client-dms-index vn-td:nth-child(8) > span',
firstDocWorkerDescriptor: '.vn-popover.shown vn-worker-descriptor',
- acceptDeleteButton: 'vn-client-dms-index > vn-confirm button[response="ACCEPT"]'
+ acceptDeleteButton: '.vn-confirm.shown button[response="ACCEPT"]'
},
itemsIndex: {
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
@@ -185,26 +185,26 @@ export default {
searchResult: 'vn-item-index a.vn-tr',
searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]',
searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]',
- acceptClonationAlertButton: 'vn-item-index [vn-id="clone"] [response="ACCEPT"]',
+ acceptClonationAlertButton: '.vn-confirm.shown [response="ACCEPT"]',
searchItemInput: 'vn-searchbar vn-textfield input',
searchButton: 'vn-searchbar vn-icon[icon="search"]',
- closeItemSummaryPreview: 'vn-item-index [vn-id="preview"] button.close',
+ closeItemSummaryPreview: '.vn-popup.shown',
fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="menu"]',
- fieldsToShowForm: 'vn-item-index vn-table > div > div > vn-dialog > div > form',
+ fieldsToShowForm: '.vn-dialog.shown form',
firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1)',
firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)',
- idCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(2) > vn-check',
- stemsCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(3) > vn-check',
- sizeCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(4) > vn-check',
- nicheCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(5) > vn-check',
- typeCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(6) > vn-check',
- categoryCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(7) > vn-check',
- intrastadCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(8) > vn-check',
- originCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(9) > vn-check',
- buyerCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(10) > vn-check',
- destinyCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(11) > vn-check',
- taxClassCheckbox: 'vn-item-index vn-dialog form vn-horizontal:nth-child(12) > vn-check',
- saveFieldsButton: 'vn-item-index vn-dialog vn-horizontal:nth-child(16) > vn-button > button'
+ idCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(2) > vn-check',
+ stemsCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(3) > vn-check',
+ sizeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(4) > vn-check',
+ nicheCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(5) > vn-check',
+ typeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(6) > vn-check',
+ categoryCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(7) > vn-check',
+ intrastadCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(8) > vn-check',
+ originCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(9) > vn-check',
+ buyerCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(10) > vn-check',
+ destinyCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(11) > vn-check',
+ taxClassCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(12) > vn-check',
+ saveFieldsButton: '.vn-dialog.shown vn-horizontal:nth-child(16) > vn-button > button'
},
itemCreateView: {
temporalName: `vn-textfield input[name="provisionalName"]`,
@@ -217,11 +217,11 @@ export default {
itemDescriptor: {
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
moreMenu: 'vn-item-descriptor vn-icon-menu[icon=more_vert]',
- moreMenuRegularizeButton: '.vn-popover.shown .vn-drop-down li[name="Regularize stock"]',
- regularizeQuantityInput: 'vn-item-descriptor vn-dialog tpl-body > div > vn-textfield input',
- regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
+ moreMenuRegularizeButton: '.vn-drop-down.shown li[name="Regularize stock"]',
+ regularizeQuantityInput: '.vn-dialog.shown tpl-body > div > vn-textfield input',
+ regularizeWarehouseAutocomplete: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]',
- regularizeSaveButton: 'vn-item-descriptor > vn-dialog > div > form > div.buttons > tpl-buttons > button',
+ regularizeSaveButton: '.vn-dialog.shown tpl-buttons > button',
inactiveIcon: 'vn-item-descriptor vn-icon[icon="icon-unavailable"]',
navigateBackToIndex: 'vn-item-descriptor vn-icon[icon="chevron_left"]'
},
@@ -336,11 +336,11 @@ export default {
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
searchWeeklyButton: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon="search"]',
moreMenu: 'vn-ticket-index vn-icon-menu[icon=more_vert]',
- moreMenuWeeklyTickets: '.vn-popover.shown .vn-drop-down li:nth-child(2)',
+ moreMenuWeeklyTickets: '.vn-drop-down.shown li:nth-child(2)',
sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[ng-model="weekly.weekDay"] input',
weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr',
firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
- acceptDeleteTurn: 'vn-ticket-weekly-index > vn-confirm[vn-id="deleteWeekly"] button[response="ACCEPT"]'
+ acceptDeleteTurn: '.vn-confirm.shown button[response="ACCEPT"]'
},
createTicketView: {
clientAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.clientFk"]',
@@ -355,24 +355,24 @@ export default {
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
moreMenu: 'vn-ticket-descriptor vn-icon-menu[icon=more_vert]',
- moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]',
- moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]',
- moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]',
- moreMenuDeleteTicket: '.vn-popover.shown .vn-drop-down li[name="Delete ticket"]',
- moreMenuMakeInvoice: '.vn-popover.shown .vn-drop-down li[name="Make invoice"]',
- moreMenuChangeShippedHour: '.vn-popover.shown .vn-drop-down li[name="Change shipped hour"]',
- changeShippedHourDialog: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"]',
- changeShippedHourInput: 'vn-dialog[vn-id="changeShippedDialog"] [ng-model="$ctrl.newShipped"]',
- addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
+ moreMenuAddStowaway: '.vn-drop-down.shown li[name="Add stowaway"]',
+ moreMenuDeleteStowawayButton: '.vn-drop-down.shown li[name="Remove stowaway"]',
+ moreMenuAddToTurn: '.vn-drop-down.shown li[name="Add turn"]',
+ moreMenuDeleteTicket: '.vn-drop-down.shown li[name="Delete ticket"]',
+ moreMenuMakeInvoice: '.vn-drop-down.shown li[name="Make invoice"]',
+ moreMenuChangeShippedHour: '.vn-drop-down.shown li[name="Change shipped hour"]',
+ changeShippedHourDialog: '.vn-dialog.shown',
+ changeShippedHourInput: '.vn-dialog.shown [ng-model="$ctrl.newShipped"]',
+ addStowawayDialogFirstTicket: '.vn-dialog.shown vn-table vn-tbody vn-tr',
shipButton: 'vn-ticket-descriptor vn-icon[icon="icon-stowaway"]',
- thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
- saturdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(6)',
- closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
- acceptDeleteButton: 'vn-ticket-descriptor button[response="ACCEPT"]',
- acceptChangeHourButton: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"] button[response="ACCEPT"]',
+ thursdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(4)',
+ saturdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(6)',
+ closeStowawayDialog: '.vn-dialog.shown button[class="close"]',
+ acceptDeleteButton: '.vn-dialog.shown button[response="ACCEPT"]',
+ acceptChangeHourButton: '.vn-dialog.shown button[response="ACCEPT"]',
descriptorDeliveryDate: 'vn-ticket-descriptor > div > div.body > div.attributes > vn-label-value:nth-child(6) > section > span',
- acceptInvoiceOutButton: 'vn-ticket-descriptor vn-confirm[vn-id="makeInvoiceConfirmation"] button[response="ACCEPT"]',
- acceptDeleteStowawayButton: 'vn-ticket-descriptor > vn-remove-stowaway button[response="ACCEPT"]'
+ acceptInvoiceOutButton: '.vn-confirm.shown button[response="ACCEPT"]',
+ acceptDeleteStowawayButton: '.vn-dialog.shown button[response="ACCEPT"]'
},
ticketNotes: {
firstNoteRemoveButton: 'vn-icon[icon="delete"]',
@@ -384,7 +384,7 @@ export default {
ticketExpedition: {
expeditionButton: 'vn-left-menu a[ui-sref="ticket.card.expedition"]',
secondExpeditionRemoveButton: 'vn-ticket-expedition vn-table div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button[icon="delete"]',
- acceptDeleteRowButton: 'vn-ticket-expedition > vn-confirm[vn-id="delete-expedition"] button[response=ACCEPT]',
+ acceptDeleteRowButton: '.vn-confirm.shown button[response=ACCEPT]',
expeditionRow: 'vn-ticket-expedition vn-table vn-tbody > vn-tr'
},
ticketPackages: {
@@ -405,11 +405,11 @@ export default {
newItemFromCatalogButton: 'vn-ticket-sale vn-float-button[icon="add"]',
newItemButton: 'vn-ticket-sale > vn-vertical > vn-card > vn-vertical > vn-one > vn-icon-button > button > vn-icon > i',
moreMenu: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] > div > button',
- moreMenuCreateClaim: '.vn-popover.shown .vn-drop-down li[name="Add claim"]',
- moreMenuReserve: '.vn-popover.shown .vn-drop-down li[name="Mark as reserved"]',
- moreMenuUnmarkReseved: '.vn-popover.shown .vn-drop-down li[name="Unmark as reserved"]',
- moreMenuUpdateDiscount: '.vn-popover.shown .vn-drop-down li[name="Update discount"]',
- moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog form vn-ticket-sale-edit-discount vn-input-number[ng-model="$ctrl.newDiscount"] input',
+ moreMenuCreateClaim: '.vn-drop-down.shown li[name="Add claim"]',
+ moreMenuReserve: '.vn-drop-down.shown li[name="Mark as reserved"]',
+ moreMenuUnmarkReseved: '.vn-drop-down.shown li[name="Unmark as reserved"]',
+ moreMenuUpdateDiscount: '.vn-drop-down.shown li[name="Update discount"]',
+ moreMenuUpdateDiscountInput: '.vn-dialog.shown form vn-ticket-sale-edit-discount vn-input-number[ng-model="$ctrl.newDiscount"] input',
transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]',
@@ -421,7 +421,7 @@ export default {
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)',
firstSaleQuantityClearInput: 'vn-textfield[ng-model="sale.quantity"] div.suffix > i',
firstSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete',
- idAutocompleteFirstResult: '.vn-popover.shown .vn-drop-down li',
+ idAutocompleteFirstResult: '.vn-drop-down.shown li',
firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
firstSalePriceInput: '.vn-popover.shown vn-input-number input',
firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(8) > span',
@@ -453,8 +453,8 @@ export default {
moveToTicketInputClearButton: '.vn-popover.shown i[title="Clear"]',
moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]',
moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]',
- acceptDeleteLineButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]',
- acceptDeleteTicketButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-ticket"] button[response=ACCEPT]',
+ acceptDeleteLineButton: '.vn-confirm.shown button[response=ACCEPT]',
+ acceptDeleteTicketButton: '.vn-confirm.shown button[response=ACCEPT]',
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]'
},
ticketTracking: {
@@ -504,10 +504,10 @@ export default {
firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input',
firstVatTypeAutocomplete: 'vn-ticket-service vn-autocomplete[label="Tax class"]',
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]',
- newDescriptionInput: 'vn-ticket-service > vn-dialog vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
+ newDescriptionInput: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
serviceLine: 'vn-ticket-service > form > vn-card > vn-one:nth-child(2) > vn-horizontal',
saveServiceButton: `button[type=submit]`,
- saveDescriptionButton: 'vn-ticket-service > vn-dialog[vn-id="createServiceTypeDialog"] > div > form > div.buttons > tpl-buttons > button'
+ saveDescriptionButton: '.vn-dialog.shown tpl-buttons > button'
},
createStateView: {
stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
@@ -522,8 +522,8 @@ export default {
},
claimDescriptor: {
moreMenu: 'vn-claim-descriptor vn-icon-menu[icon=more_vert]',
- moreMenuDeleteClaim: '.vn-popover.shown .vn-drop-down li[name="Delete claim"]',
- acceptDeleteClaim: 'vn-claim-descriptor > vn-confirm[vn-id="confirm-delete-claim"] button[response="ACCEPT"]'
+ moreMenuDeleteClaim: '.vn-drop-down.shown li[name="Delete claim"]',
+ acceptDeleteClaim: '.vn-confirm.shown button[response="ACCEPT"]'
},
claimSummary: {
header: 'vn-claim-summary > vn-card > h5',
@@ -549,7 +549,7 @@ export default {
discountInput: '.vn-popover.shown vn-input-number[ng-model="$ctrl.newDiscount"] input',
discoutPopoverMana: '.vn-popover.shown .content > div > vn-horizontal > h5',
addItemButton: 'vn-claim-detail a vn-float-button',
- firstClaimableSaleFromTicket: 'vn-claim-detail > vn-dialog vn-tbody > vn-tr',
+ firstClaimableSaleFromTicket: '.vn-dialog.shown vn-tbody > vn-tr',
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr',
firstItemQuantityInput: 'vn-claim-detail vn-tr:nth-child(1) vn-input-number[ng-model="saleClaimed.quantity"] input',
totalClaimed: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-horizontal > div > vn-label-value:nth-child(2) > section > span',
@@ -589,7 +589,7 @@ export default {
},
orderDescriptor: {
returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]',
- acceptNavigationButton: 'vn-order-basic-data vn-confirm button[response=ACCEPT]'
+ acceptNavigationButton: '.vn-confirm.shown button[response=ACCEPT]'
},
createOrderView: {
clientAutocomplete: 'vn-autocomplete[label="Client"]',
@@ -618,13 +618,13 @@ export default {
agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
observationInput: 'vn-textarea[label="Observation"] textarea',
saveButton: `button[type=submit]`,
- acceptButton: 'vn-order-basic-data vn-confirm[vn-id="confirm"] button[response="ACCEPT"]'
+ acceptButton: '.vn-confirm.shown button[response="ACCEPT"]'
},
orderLine: {
- orderSubtotal: 'vn-order-line vn-horizontal.header p:nth-child(1)',
+ orderSubtotal: 'vn-order-line .header :first-child',
firstLineDeleteButton: 'vn-order-line vn-tbody > vn-tr:nth-child(1) vn-icon[icon="delete"]',
- confirmOrder: 'vn-order-line > vn-vertical > vn-button-bar > vn-button > button',
- confirmButton: 'vn-order-line > vn-confirm button[response="ACCEPT"]',
+ confirmOrder: 'vn-order-line vn-float-button',
+ confirmButton: '.vn-confirm.shown button[response="ACCEPT"]',
},
routeIndex: {
addNewRouteButton: 'vn-route-index > a[ui-sref="route.create"]'
@@ -663,7 +663,7 @@ export default {
firstTicketCheckbox: 'vn-route-tickets vn-tr:nth-child(1) vn-check',
buscamanButton: 'vn-route-tickets vn-button[icon="icon-buscaman"]',
firstTicketDeleteButton: 'vn-route-tickets vn-tr:nth-child(1) vn-icon[icon="delete"]',
- confirmButton: 'vn-route-tickets > vn-confirm button[response="ACCEPT"]'
+ confirmButton: '.vn-confirm.shown button[response="ACCEPT"]'
},
workerPbx: {
extensionInput: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"] input',
@@ -678,7 +678,7 @@ export default {
fridayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(5) > vn-icon-button',
saturdayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(6) > vn-icon-button',
sundayAddTimeButton: 'vn-worker-time-control vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(7) > vn-icon-button',
- confirmButton: 'vn-worker-time-control > vn-dialog > div > form > div.buttons > tpl-buttons > button',
+ confirmButton: '.vn-dialog.shown tpl-buttons > button',
firstEntryOfMonday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(1) > section:nth-child(1) > span',
firstEntryOfTuesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > section:nth-child(1) > span',
firstEntryOfWednesday: 'vn-worker-time-control vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3) > section:nth-child(1) > span',
@@ -726,11 +726,11 @@ export default {
},
invoiceOutDescriptor: {
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[icon=more_vert]',
- moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]',
- moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]',
- moreMenuShowInvoiceOutPdf: '.vn-popover.shown .vn-drop-down li[name="Show invoice PDF"]',
- acceptDeleteButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="deleteConfirmation"] button[response="ACCEPT"]',
- acceptBookingButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="bookConfirmation"] button[response="ACCEPT"]'
+ moreMenuDeleteInvoiceOut: '.vn-drop-down.shown li[name="Delete Invoice"]',
+ moreMenuBookInvoiceOut: '.vn-drop-down.shown li[name="Book invoice"]',
+ moreMenuShowInvoiceOutPdf: '.vn-drop-down.shown li[name="Show invoice PDF"]',
+ acceptDeleteButton: '.vn-confirm.shown button[response="ACCEPT"]',
+ acceptBookingButton: '.vn-confirm.shown button[response="ACCEPT"]'
},
invoiceOutSummary: {
bookedLabel: 'vn-invoice-out-summary > vn-card > vn-horizontal > vn-one > vn-label-value:nth-child(4) > section > span'
diff --git a/e2e/paths/01-login/01_login.spec.js b/e2e/paths/01-login/01_login.spec.js
index 03acc98a85..e9e64c3115 100644
--- a/e2e/paths/01-login/01_login.spec.js
+++ b/e2e/paths/01-login/01_login.spec.js
@@ -6,6 +6,7 @@ describe('Login path', () => {
it('should receive an error when the username is incorrect', async() => {
const result = await nightmare
.doLogin('badUser', null)
+ .waitUntilNotPresent('body', 'jose')
.waitForLastSnackbar();
expect(result.length).toBeGreaterThan(0);
diff --git a/e2e/paths/02-client-module/05_add_address.spec.js b/e2e/paths/02-client-module/05_add_address.spec.js
index f4e68634a5..9134642a8f 100644
--- a/e2e/paths/02-client-module/05_add_address.spec.js
+++ b/e2e/paths/02-client-module/05_add_address.spec.js
@@ -110,7 +110,7 @@ describe('Client Add address path', () => {
it(`should go back to the addreses section by clicking the cancel button`, async() => {
const url = await nightmare
.waitToClick(selectors.clientAddresses.cancelEditAddressButton)
- .waitToClick('vn-confirm button[response="ACCEPT"]')
+ .waitToClick('.vn-confirm.shown button[response="ACCEPT"]')
.waitForURL('address/index')
.parsedUrl();
diff --git a/e2e/paths/04-item-module/01_summary.spec.js b/e2e/paths/04-item-module/01_summary.spec.js
index 25e442feb5..bd06ebef4d 100644
--- a/e2e/paths/04-item-module/01_summary.spec.js
+++ b/e2e/paths/04-item-module/01_summary.spec.js
@@ -21,16 +21,12 @@ describe('Item summary path', () => {
});
it(`should click on the search result summary button to open the item summary popup`, async() => {
- const isVisibleBefore = await nightmare
+ const isVisible = await nightmare
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon longbow 2m')
- .isVisible(selectors.itemSummary.basicData);
-
- const isVisibleAfter = await nightmare
.waitToClick(selectors.itemsIndex.searchResultPreviewButton)
.isVisible(selectors.itemSummary.basicData);
- expect(isVisibleBefore).toBeFalsy();
- expect(isVisibleAfter).toBeTruthy();
+ expect(isVisible).toBeTruthy();
});
it(`should check the item summary preview shows fields from basic data`, async() => {
@@ -75,8 +71,9 @@ describe('Item summary path', () => {
it(`should close the summary popup`, async() => {
const result = await nightmare
- .waitToClick(selectors.itemsIndex.closeItemSummaryPreview)
- .isVisible(selectors.itemSummary.basicData);
+ .mousedown(selectors.itemsIndex.closeItemSummaryPreview)
+ .waitUntilNotPresent(selectors.itemSummary.basicData)
+ .visible(selectors.itemSummary.basicData);
expect(result).toBeFalsy();
});
@@ -94,17 +91,13 @@ describe('Item summary path', () => {
});
it(`should now click on the search result summary button to open the item summary popup`, async() => {
- const isVisibleBefore = await nightmare
+ const isVisible = await nightmare
.waitForTextInElement(selectors.itemsIndex.searchResult, 'Melee weapon combat fist 15cm')
- .isVisible(selectors.itemSummary.basicData);
-
- const isVisibleAfter = await nightmare
.waitToClick(selectors.itemsIndex.searchResultPreviewButton)
.isVisible(selectors.itemSummary.basicData);
- expect(isVisibleBefore).toBeFalsy();
- expect(isVisibleAfter).toBeTruthy();
+ expect(isVisible).toBeTruthy();
});
it(`should now check the item summary preview shows fields from basic data`, async() => {
@@ -149,8 +142,9 @@ describe('Item summary path', () => {
it(`should now close the summary popup`, async() => {
const result = await nightmare
- .waitToClick(selectors.itemsIndex.closeItemSummaryPreview)
- .isVisible(selectors.itemSummary.basicData);
+ .mousedown(selectors.itemsIndex.closeItemSummaryPreview)
+ .waitUntilNotPresent(selectors.itemSummary.basicData)
+ .visible(selectors.itemSummary.basicData);
expect(result).toBeFalsy();
});
diff --git a/e2e/paths/05-ticket-module/13_services.spec.js b/e2e/paths/05-ticket-module/13_services.spec.js
index 7172ab5a6d..dbce6ea6e0 100644
--- a/e2e/paths/05-ticket-module/13_services.spec.js
+++ b/e2e/paths/05-ticket-module/13_services.spec.js
@@ -65,7 +65,7 @@ describe('Ticket services path', () => {
it('should click on the add new description to open the dialog', async() => {
const result = await nightmare
.waitToClick(selectors.ticketService.firstAddDescriptionButton)
- .waitForClassPresent('vn-ticket-service > vn-dialog', 'shown')
+ .wait('.vn-dialog.shown')
.isVisible(selectors.ticketService.newDescriptionInput);
expect(result).toBeTruthy();
diff --git a/front/core/components/array-model/array-model.js b/front/core/components/array-model/array-model.js
index 3697abc3ba..5b0b94cdcb 100644
--- a/front/core/components/array-model/array-model.js
+++ b/front/core/components/array-model/array-model.js
@@ -100,7 +100,7 @@ export default class ArrayModel extends ModelProxy {
addFilter(user, params) {
this.userFilter = this.mergeFilters(user, this.userFilter);
- Object.assign(this.userParams, params);
+ this.userParams = Object.assign({}, this.userParams, params);
return this.refresh();
}
diff --git a/front/core/components/autocomplete/index.html b/front/core/components/autocomplete/index.html
index b51090f487..725d389770 100755
--- a/front/core/components/autocomplete/index.html
+++ b/front/core/components/autocomplete/index.html
@@ -26,7 +26,7 @@
ng-click="$ctrl.onClear($event)">
diff --git a/front/core/components/autocomplete/index.js b/front/core/components/autocomplete/index.js
index d2fdce16aa..9808fd6670 100755
--- a/front/core/components/autocomplete/index.js
+++ b/front/core/components/autocomplete/index.js
@@ -17,14 +17,9 @@ import './style.scss';
* @event change Thrown when value is changed
*/
export default class Autocomplete extends Field {
- constructor($element, $scope, $compile, $http, $transclude, $translate, $interpolate) {
- super($element, $scope, $compile);
- Object.assign(this, {
- $http,
- $interpolate,
- $transclude,
- $translate
- });
+ constructor($element, $, $compile, $transclude) {
+ super($element, $, $compile);
+ this.$transclude = $transclude;
this._selection = null;
this.input = this.element.querySelector('input');
@@ -48,7 +43,6 @@ export default class Autocomplete extends Field {
set field(value) {
super.field = value;
this.refreshSelection();
- this.emit('change', {value});
}
get model() {
@@ -121,7 +115,6 @@ export default class Autocomplete extends Field {
return;
const selection = this.fetchSelection();
-
this.selection = selection;
}
@@ -206,7 +199,7 @@ export default class Autocomplete extends Field {
onDropDownSelect(item) {
const value = item[this.valueField];
this.selection = item;
- this.field = value;
+ this.change(value);
}
onDropDownClose() {
@@ -216,7 +209,7 @@ export default class Autocomplete extends Field {
onContainerKeyDown(event) {
if (event.defaultPrevented) return;
- switch (event.code) {
+ switch (event.key) {
case 'ArrowUp':
case 'ArrowDown':
case 'Enter':
@@ -241,12 +234,13 @@ export default class Autocomplete extends Field {
assignDropdownProps() {
if (!this.$.dropDown) return;
+ this.$.dropDown.copySlot('tplItem', this.$transclude);
+
assignProps(this, this.$.dropDown, [
'valueField',
'showField',
'showFilter',
'multiple',
- '$transclude',
'translateFields',
'model',
'data',
@@ -277,7 +271,7 @@ export default class Autocomplete extends Field {
this.refreshSelection();
}
}
-Autocomplete.$inject = ['$element', '$scope', '$compile', '$http', '$transclude', '$translate', '$interpolate'];
+Autocomplete.$inject = ['$element', '$scope', '$compile', '$transclude'];
ngModule.vnComponent('vnAutocomplete', {
template: require('./index.html'),
diff --git a/front/core/components/autocomplete/style.scss b/front/core/components/autocomplete/style.scss
index 6be42c3bcc..19e8362d58 100755
--- a/front/core/components/autocomplete/style.scss
+++ b/front/core/components/autocomplete/style.scss
@@ -1,6 +1,6 @@
@import "effects";
-vn-autocomplete.vn-field {
+.vn-autocomplete {
overflow: hidden;
& > .container {
diff --git a/front/core/components/button-menu/index.js b/front/core/components/button-menu/index.js
index e9fb8d5652..946e1fd7fb 100644
--- a/front/core/components/button-menu/index.js
+++ b/front/core/components/button-menu/index.js
@@ -55,12 +55,13 @@ export default class ButtonMenu extends Button {
}
showDropDown() {
+ this.$.dropDown.copySlot('tplItem', this.$transclude);
+
assignProps(this, this.$.dropDown, [
'valueField',
'showField',
'showFilter',
'multiple',
- '$transclude',
'translateFields',
'model',
'data',
diff --git a/front/core/components/button-menu/style.scss b/front/core/components/button-menu/style.scss
index 1cd995b15e..cbb6129bd3 100644
--- a/front/core/components/button-menu/style.scss
+++ b/front/core/components/button-menu/style.scss
@@ -1,3 +1,3 @@
-vn-button-menu {
+.vn-button-menu {
position: relative;
}
\ No newline at end of file
diff --git a/front/core/components/button/index.js b/front/core/components/button/index.js
index 19b1022740..17710967a0 100644
--- a/front/core/components/button/index.js
+++ b/front/core/components/button/index.js
@@ -7,7 +7,6 @@ export default class Button extends FormInput {
super($element, $scope);
this.design = 'colored';
this.initTabIndex();
- this.classList.add('vn-button');
this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e));
}
@@ -19,8 +18,8 @@ export default class Button extends FormInput {
onKeyup(event) {
if (event.defaultPrevented) return;
- switch (event.code) {
- case 'Space':
+ switch (event.key) {
+ case ' ':
case 'Enter':
return this.element.click();
}
diff --git a/front/core/components/calendar/index.js b/front/core/components/calendar/index.js
index 6a56ed86ad..4afec0a9a9 100644
--- a/front/core/components/calendar/index.js
+++ b/front/core/components/calendar/index.js
@@ -129,7 +129,7 @@ export default class Calendar extends FormInput {
*/
select(day) {
if (!this.editable) return;
- this.field = day;
+ this.change(day);
this.emit('selection', {
$days: [day],
$type: 'day'
diff --git a/front/core/components/calendar/style.scss b/front/core/components/calendar/style.scss
index b00c40648a..8492d09f16 100644
--- a/front/core/components/calendar/style.scss
+++ b/front/core/components/calendar/style.scss
@@ -1,6 +1,6 @@
@import "variables";
-vn-calendar {
+.vn-calendar {
display: block;
& > div {
diff --git a/front/core/components/check/index.js b/front/core/components/check/index.js
index b9bd1bb2fb..78b1807a5a 100644
--- a/front/core/components/check/index.js
+++ b/front/core/components/check/index.js
@@ -49,18 +49,19 @@ export default class Check extends Toggle {
onClick(event) {
if (super.onClick(event)) return;
+ let value;
if (this.tripleState) {
if (this.field == null)
- this.field = true;
+ value = true;
else if (this.field)
- this.field = false;
+ value = false;
else
- this.field = null;
+ value = null;
} else
- this.field = !this.field;
+ value = !this.field;
- this.changed();
+ this.change(value);
}
}
diff --git a/front/core/components/check/style.scss b/front/core/components/check/style.scss
index f292e45f9a..31715a2cdb 100644
--- a/front/core/components/check/style.scss
+++ b/front/core/components/check/style.scss
@@ -1,6 +1,6 @@
@import "variables";
-vn-check {
+.vn-check {
& > .btn {
border-radius: 2px;
transition: background 250ms;
@@ -12,8 +12,13 @@ vn-check {
border-width: 0;
}
}
+ & > vn-icon {
+ margin-left: 5px;
+ color: $color-font-secondary;
+ vertical-align: middle;
+ }
&.checked > .btn {
- border-color: $color-main;
+ border-color: transparent;
background-color: $color-main;
& > .mark {
@@ -35,9 +40,7 @@ vn-check {
height: 2px;
border-bottom: 2px solid #666;
}
- & > vn-icon {
- margin-left: 5px;
- color: $color-font-secondary;
- vertical-align: middle;
+ &.disabled.checked > .btn {
+ background-color: $color-font-secondary;
}
}
diff --git a/front/core/components/chip/index.js b/front/core/components/chip/index.js
index 6a945559b8..6cffecc2b3 100644
--- a/front/core/components/chip/index.js
+++ b/front/core/components/chip/index.js
@@ -9,7 +9,7 @@ export default class Chip extends Component {
}
Chip.$inject = ['$element', '$scope', '$transclude'];
-ngModule.component('vnChip', {
+ngModule.vnComponent('vnChip', {
template: require('./index.html'),
controller: Chip,
transclude: true,
diff --git a/front/core/components/confirm/confirm.js b/front/core/components/confirm/confirm.js
index 8b27d82955..9d53df7986 100644
--- a/front/core/components/confirm/confirm.js
+++ b/front/core/components/confirm/confirm.js
@@ -7,13 +7,8 @@ export default class Confirm extends Dialog {
super($element, $, $transclude);
let $template = angular.element(template);
- let slots = $transclude.$$boundTransclude.$$slots;
-
- let bodyLinkFn = this.$compile($template.find('tpl-body'));
- slots.body = this.createBoundTranscludeFn(bodyLinkFn);
-
- let buttonsLinkFn = this.$compile($template.find('tpl-buttons'));
- slots.buttons = this.createBoundTranscludeFn(buttonsLinkFn);
+ this.fillSlot('body', $template.find('tpl-body'));
+ this.fillSlot('buttons', $template.find('tpl-buttons'));
}
}
diff --git a/front/core/components/crud-model/crud-model.js b/front/core/components/crud-model/crud-model.js
index 41b5390a75..9a260a690c 100644
--- a/front/core/components/crud-model/crud-model.js
+++ b/front/core/components/crud-model/crud-model.js
@@ -95,7 +95,7 @@ export default class CrudModel extends ModelProxy {
*/
addFilter(filter, params) {
this.userFilter = mergeFilters(filter, this.userFilter);
- Object.assign(this.userParams, params);
+ this.userParams = Object.assign({}, this.userParams, params);
return this.refresh();
}
diff --git a/front/core/components/date-picker/index.js b/front/core/components/date-picker/index.js
index b667674fac..17ce194063 100644
--- a/front/core/components/date-picker/index.js
+++ b/front/core/components/date-picker/index.js
@@ -1,12 +1,9 @@
import ngModule from '../../module';
import Field from '../field';
-import './style.scss';
class DatePicker extends Field {
- constructor($element, $scope, $compile, $translate, $filter) {
+ constructor($element, $scope, $compile) {
super($element, $scope, $compile);
- this.$translate = $translate;
- this.$filter = $filter;
this.input = $compile(``)($scope)[0];
this.input.addEventListener('change', () => this.onValueUpdate());
@@ -46,7 +43,7 @@ class DatePicker extends Field {
this.input.value = this.$filter('date')(value, 'yyyy-MM-dd');
}
}
-DatePicker.$inject = ['$element', '$scope', '$compile', '$translate', '$filter'];
+DatePicker.$inject = ['$element', '$scope', '$compile'];
ngModule.vnComponent('vnDatePicker', {
controller: DatePicker,
diff --git a/front/core/components/date-picker/style.scss b/front/core/components/date-picker/style.scss
deleted file mode 100644
index 6af4580f65..0000000000
--- a/front/core/components/date-picker/style.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@import "variables";
-
-.flatpickr-months .flatpickr-month,
-.flatpickr-weekdays,
-span.flatpickr-weekday {
- background-color: $color-main;
-}
diff --git a/front/core/components/dialog/index.js b/front/core/components/dialog/index.js
index 8bc3dfc85e..5415a906b1 100644
--- a/front/core/components/dialog/index.js
+++ b/front/core/components/dialog/index.js
@@ -12,16 +12,14 @@ import './style.scss';
export default class Dialog extends Popup {
constructor($element, $, $transclude) {
super($element, $, $transclude);
-
- let linkFn = this.$compile(template);
- $transclude.$$boundTransclude = this.createBoundTranscludeFn(linkFn);
+ this.fillDefaultSlot(template);
}
/**
* Hides the dialog calling the response handler.
*/
hide() {
- // this.fireResponse();
+ this.fireResponse();
super.hide();
}
diff --git a/front/core/components/dialog/index.spec.js b/front/core/components/dialog/index.spec.js
index b889f1bc01..ce75823992 100644
--- a/front/core/components/dialog/index.spec.js
+++ b/front/core/components/dialog/index.spec.js
@@ -4,31 +4,12 @@ describe('Component vnDialog', () => {
beforeEach(ngModule('vnCore'));
- beforeEach(angular.mock.inject($componentController => {
- $element = angular.element('');
- controller = $componentController('vnDialog', {$element, $transclude: null});
+ beforeEach(angular.mock.inject(($rootScope, $compile) => {
+ $element = $compile('Body')($rootScope);
+ controller = $element.controller('vnDialog');
controller.emit = jasmine.createSpy('emit');
}));
- describe('show()', () => {
- it(`should do nothing if controller.shown is defined`, () => {
- controller.element = {style: {display: 'none'}};
- controller.shown = true;
- controller.show();
-
- expect(controller.element.style.display).toEqual('none');
- expect(controller.emit).not.toHaveBeenCalledWith('open');
- });
-
- it(`should set shown on the controller, set style.display on the element and emit onOpen() event`, () => {
- controller.show();
-
- expect(controller.element.style.display).toEqual('flex');
- expect(controller.shown).toBeTruthy();
- expect(controller.emit).toHaveBeenCalledWith('open');
- });
- });
-
describe('hide()', () => {
describe('fireResponse()', () => {
it(`should call onResponse() if it's defined in the controller`, () => {
@@ -51,23 +32,5 @@ describe('Component vnDialog', () => {
expect(responseRet).toEqual(false);
});
});
-
- describe('realHide()', () => {
- it(`should do nothing if controller.shown is not defined`, () => {
- controller.element = {style: {display: 'not none'}};
- controller.hide();
-
- expect(controller.element.style.display).toEqual('not none');
- });
-
- it(`should set lastEvent, shown and element.style.display to their expected values`, () => {
- controller.shown = true;
- controller.hide();
-
- expect(controller.lastEvent).toBeFalsy();
- expect(controller.shown).toBeFalsy();
- expect(controller.element.style.display).toEqual('none');
- });
- });
});
});
diff --git a/front/core/components/drop-down/drop-down.html b/front/core/components/drop-down/drop-down.html
deleted file mode 100755
index 2e4db921d5..0000000000
--- a/front/core/components/drop-down/drop-down.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{$ctrl.statusText}}
-
-
-
-
diff --git a/front/core/components/drop-down/index.html b/front/core/components/drop-down/index.html
new file mode 100755
index 0000000000..5366d9d90e
--- /dev/null
+++ b/front/core/components/drop-down/index.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ {{$ctrl.statusText}}
+
+
\ No newline at end of file
diff --git a/front/core/components/drop-down/drop-down.js b/front/core/components/drop-down/index.js
similarity index 85%
rename from front/core/components/drop-down/drop-down.js
rename to front/core/components/drop-down/index.js
index 84313814c6..163553aeb6 100755
--- a/front/core/components/drop-down/drop-down.js
+++ b/front/core/components/drop-down/index.js
@@ -1,6 +1,7 @@
import './style.scss';
import ngModule from '../../module';
-import Component from '../../lib/component';
+import Popover from '../popover';
+import template from './index.html';
import ArrayModel from '../array-model/array-model';
import CrudModel from '../crud-model/crud-model';
import {mergeWhere} from 'vn-loopback/util/filter';
@@ -9,34 +10,17 @@ import {mergeWhere} from 'vn-loopback/util/filter';
* @event select Thrown when model item is selected
* @event change Thrown when model data is ready
*/
-export default class DropDown extends Component {
- constructor($element, $scope, $transclude, $timeout, $translate, $http, $q, $filter) {
- super($element, $scope);
- this.$transclude = $transclude;
- this.$timeout = $timeout;
- this.$translate = $translate;
- this.$http = $http;
- this.$q = $q;
- this.$filter = $filter;
-
+export default class DropDown extends Popover {
+ constructor($element, $, $transclude) {
+ super($element, $, $transclude);
this.valueField = 'id';
this.showField = 'name';
this._search = undefined;
this._activeOption = -1;
this.showLoadMore = true;
this.showFilter = true;
- }
-
- $postLink() {
- super.$postLink();
- }
-
- get shown() {
- return this.$.popover && this.$.popover.shown;
- }
-
- set shown(value) {
- this.$.popover.shown = value;
+ this.searchDelay = 300;
+ this.fillDefaultSlot(template);
}
get search() {
@@ -64,7 +48,7 @@ export default class DropDown extends Component {
this.searchTimeout = this.$timeout(() => {
this.refreshModel();
this.searchTimeout = null;
- }, 350);
+ }, value != null ? this.searchDelay : 0);
} else
this.refreshModel();
}
@@ -103,16 +87,37 @@ export default class DropDown extends Component {
*/
show(parent, search) {
this._activeOption = -1;
- this.$.popover.show(parent || this.parent);
+ super.show(parent);
+
+ this.list = this.popup.querySelector('.list');
+ this.ul = this.popup.querySelector('ul');
+
+ this.docKeyDownHandler = e => this.onDocKeyDown(e);
+ this.document.addEventListener('keydown', this.docKeyDownHandler);
+
+ this.listScrollHandler = e => this.onScroll(e);
+ this.list.addEventListener('scroll', this.listScrollHandler);
+ this.list.scrollTop = 0;
+
this.search = search;
this.buildList();
+
+ let input = this.popup.querySelector('input');
+ setTimeout(() => input.focus());
}
- /**
- * Hides the drop-down.
- */
- hide() {
- this.$.popover.hide();
+ onClose() {
+ this.document.removeEventListener('keydown', this.docKeyDownHandler);
+ this.docKeyDownHandler = null;
+
+ this.list.removeEventListener('scroll', this.listScrollHandler);
+ this.listScrollHandler = null;
+
+ this.list = null;
+ this.ul = null;
+
+ this.destroyList();
+ super.onClose();
}
/**
@@ -123,7 +128,7 @@ export default class DropDown extends Component {
moveToOption(option) {
this.activateOption(option);
- let list = this.$.list;
+ let list = this.list;
let li = this.activeLi;
if (!li) return;
@@ -150,7 +155,7 @@ export default class DropDown extends Component {
let data = this.modelData;
if (option >= 0 && data && option < data.length) {
- this.activeLi = this.$.ul.children[option];
+ this.activeLi = this.ul.children[option];
this.activeLi.className = 'active';
}
}
@@ -184,29 +189,7 @@ export default class DropDown extends Component {
}
if (!this.multiple)
- this.$.popover.hide();
- }
-
- onOpen() {
- this.docKeyDownHandler = e => this.onDocKeyDown(e);
- this.document.addEventListener('keydown', this.docKeyDownHandler);
-
- this.listScrollHandler = e => this.onScroll(e);
- this.$.list.addEventListener('scroll', this.listScrollHandler);
- this.$.list.scrollTop = 0;
-
- setTimeout(() => this.$.input.focus());
- this.emit('open');
- }
-
- onClose() {
- this.document.removeEventListener('keydown', this.docKeyDownHandler);
- this.docKeyDownHandler = null;
-
- this.$.list.removeEventListener('scroll', this.listScrollHandler);
- this.listScrollHandler = null;
-
- this.emit('close');
+ this.hide();
}
onClearClick() {
@@ -214,7 +197,7 @@ export default class DropDown extends Component {
}
onScroll() {
- let list = this.$.list;
+ let list = this.list;
let shouldLoad =
list.scrollTop + list.clientHeight >= (list.scrollHeight - 40)
&& !this.model.isLoading;
@@ -230,9 +213,8 @@ export default class DropDown extends Component {
onContainerClick(event) {
if (event.defaultPrevented) return;
- let index = getPosition(this.$.ul, event);
- if (index != -1)
- this.selectOption(index);
+ let index = getPosition(this.ul, event);
+ if (index != -1) this.selectOption(index);
}
onDocKeyDown(event) {
@@ -242,23 +224,23 @@ export default class DropDown extends Component {
let option = this.activeOption;
let nOpts = data ? data.length - 1 : 0;
- switch (event.keyCode) {
- case 9: // Tab
+ switch (event.key) {
+ case 'Tab':
this.selectOption(option);
return;
- case 13: // Enter
+ case 'Enter':
this.selectOption(option);
break;
- case 38: // Up
+ case 'ArrowUp':
this.moveToOption(option <= 0 ? nOpts : option - 1);
break;
- case 40: // Down
+ case 'ArrowDown':
this.moveToOption(option >= nOpts ? 0 : option + 1);
break;
- case 35: // End
+ case 'End':
this.moveToOption(nOpts);
break;
- case 36: // Start
+ case 'Home':
this.moveToOption(0);
break;
default:
@@ -315,13 +297,14 @@ export default class DropDown extends Component {
}
}
- this.$.ul.appendChild(fragment);
+ this.ul.appendChild(fragment);
this.activateOption(this._activeOption);
- this.$.$applyAsync(() => this.$.popover.relocate());
+ this.$.$applyAsync(() => this.relocate());
}
destroyList() {
- this.$.ul.innerHTML = '';
+ if (this.ul)
+ this.ul.innerHTML = '';
if (this.scopes) {
for (let scope of this.scopes)
@@ -344,10 +327,6 @@ export default class DropDown extends Component {
return fields;
}
- $onDestroy() {
- this.destroyList();
- }
-
// Model related code
onDataChange() {
@@ -436,7 +415,6 @@ export default class DropDown extends Component {
return {[this.showField]: scope.$search};
}
}
-DropDown.$inject = ['$element', '$scope', '$transclude', '$timeout', '$translate', '$http', '$q', '$filter'];
/**
* Gets the position of an event element relative to a parent.
@@ -463,9 +441,11 @@ function getPosition(parent, event) {
return -1;
}
-ngModule.component('vnDropDown', {
- template: require('./drop-down.html'),
+ngModule.vnComponent('vnDropDown', {
controller: DropDown,
+ transclude: {
+ tplItem: '?tplItem'
+ },
bindings: {
field: '=?',
selection: '=?',
@@ -482,9 +462,7 @@ ngModule.component('vnDropDown', {
where: '',
order: '@?',
limit: '',
- searchFunction: '&?'
- },
- transclude: {
- tplItem: '?tplItem'
+ searchFunction: '&?',
+ searchDelay: ''
}
});
diff --git a/front/core/components/drop-down/drop-down.spec.js b/front/core/components/drop-down/index.spec.js
similarity index 100%
rename from front/core/components/drop-down/drop-down.spec.js
rename to front/core/components/drop-down/index.spec.js
diff --git a/front/core/components/drop-down/style.scss b/front/core/components/drop-down/style.scss
index ce26c85087..fb346135f0 100755
--- a/front/core/components/drop-down/style.scss
+++ b/front/core/components/drop-down/style.scss
@@ -1,7 +1,7 @@
@import "effects";
@import "variables";
-.vn-drop-down {
+.vn-drop-down > .window > .content {
display: flex;
flex-direction: column;
height: inherit;
diff --git a/front/core/components/field/index.html b/front/core/components/field/index.html
index c2e7a02c22..8d12ddd77f 100644
--- a/front/core/components/field/index.html
+++ b/front/core/components/field/index.html
@@ -19,7 +19,7 @@
ng-click="$ctrl.onClear($event)">
diff --git a/front/core/components/field/index.js b/front/core/components/field/index.js
index 9382aaa95f..cd9da4cecc 100644
--- a/front/core/components/field/index.js
+++ b/front/core/components/field/index.js
@@ -11,7 +11,6 @@ export default class Field extends FormInput {
this.suffix = null;
this.control = this.element.querySelector('.control');
- this.classList.add('vn-field');
this.element.addEventListener('click', e => this.onClick(e));
this.container = this.element.querySelector('.container');
@@ -25,9 +24,7 @@ export default class Field extends FormInput {
this.input.addEventListener('focus', () => this.onFocus(true));
this.input.addEventListener('blur', () => this.onFocus(false));
- this.input.addEventListener('change', e => {
- this.emit('change', {event: e});
- });
+ this.input.addEventListener('change', () => this.onChange());
}
set field(value) {
@@ -172,6 +169,7 @@ export default class Field extends FormInput {
onClear(event) {
if (event.defaultPrevented) return;
+ event.preventDefault();
this.field = null;
this.input.dispatchEvent(new Event('change'));
}
@@ -193,6 +191,10 @@ export default class Field extends FormInput {
this.inputError = error;
this.refreshHint();
}
+
+ onChange() {
+ this.emit('change', {value: this.field});
+ }
}
Field.$inject = ['$element', '$scope', '$compile'];
diff --git a/front/core/components/field/style.scss b/front/core/components/field/style.scss
index e57b27912e..add3a3228f 100644
--- a/front/core/components/field/style.scss
+++ b/front/core/components/field/style.scss
@@ -35,7 +35,7 @@
& > .fix {
padding-top: 24px;
line-height: 24px;
- font-size: $font-size;
+ font-size: 1rem;
opacity: 0;
transition: opacity 200ms ease-in-out;
@@ -58,7 +58,7 @@
border: none;
font-family: Arial, sans-serif;
display: block;
- font-size: $font-size;
+ font-size: 1rem;
width: 100%;
background: 0;
color: inherit;
diff --git a/front/core/components/form-input/index.js b/front/core/components/form-input/index.js
index 3d22b290ce..0395922c79 100644
--- a/front/core/components/form-input/index.js
+++ b/front/core/components/form-input/index.js
@@ -12,6 +12,7 @@ export default class FormInput extends Component {
constructor($element, $scope) {
super($element, $scope);
this.classList = this.element.classList;
+ this.classList.add(...this.constructor.$classNames);
}
$onInit() {
@@ -104,6 +105,12 @@ export default class FormInput extends Component {
refreshTabIndex() {
this.inputEl.tabIndex = this.disabled ? -1 : this.tabIndex;
}
+
+ change(value) {
+ this.field = value;
+ this.element.dispatchEvent(new Event('change'));
+ this.emit('change', {value: this.field});
+ }
}
ngModule.vnComponent('vnFormInput', {
diff --git a/front/core/components/icon-button/style.scss b/front/core/components/icon-button/style.scss
index c73580ad94..1126c5e6de 100644
--- a/front/core/components/icon-button/style.scss
+++ b/front/core/components/icon-button/style.scss
@@ -1,6 +1,6 @@
@import "effects";
-vn-icon-button {
+.vn-icon-button {
@extend %clickable-light;
color: $color-main;
diff --git a/front/core/components/icon-menu/index.js b/front/core/components/icon-menu/index.js
index 0549149a8a..6dd3d683a5 100644
--- a/front/core/components/icon-menu/index.js
+++ b/front/core/components/icon-menu/index.js
@@ -2,8 +2,8 @@ import ngModule from '../../module';
import ButtonMenu from '../button-menu';
export default class IconMenu extends ButtonMenu {
- constructor($element, $scope) {
- super($element, $scope);
+ constructor($element, $scope, $transclude) {
+ super($element, $scope, $transclude);
this.element.classList.add('flat');
}
}
diff --git a/front/core/components/index.js b/front/core/components/index.js
index d59da46ea4..bc19db6429 100644
--- a/front/core/components/index.js
+++ b/front/core/components/index.js
@@ -9,8 +9,6 @@ import './subtitle/subtitle';
import './spinner/spinner';
import './snackbar/snackbar';
import './tooltip/tooltip';
-import './popover/popover';
-import './drop-down/drop-down';
import './menu/menu';
import './multi-check/multi-check';
import './card/card';
@@ -26,6 +24,7 @@ import './check';
import './chip';
import './data-viewer';
import './date-picker';
+import './drop-down';
import './debug-info';
import './dialog';
import './field';
@@ -39,6 +38,7 @@ import './input-time';
import './input-file';
import './label';
import './list';
+import './popover';
import './popup';
import './radio';
import './submit';
diff --git a/front/core/components/input-number/index.html b/front/core/components/input-number/index.html
index ee6f503977..2c6f7d824b 100644
--- a/front/core/components/input-number/index.html
+++ b/front/core/components/input-number/index.html
@@ -19,7 +19,7 @@
ng-click="$ctrl.onClear($event)">
diff --git a/front/core/components/menu/menu.js b/front/core/components/menu/menu.js
index ff54d55d4a..3eb169926e 100755
--- a/front/core/components/menu/menu.js
+++ b/front/core/components/menu/menu.js
@@ -1,20 +1,13 @@
import ngModule from '../../module';
-import Popover from '../popover/popover';
+import Popover from '../popover';
export default class Menu extends Popover {
- $postLink() {
- super.$postLink();
- this.popover.addEventListener('click',
- () => this.hide());
+ show(parent) {
+ super.show(parent);
+ this.windowEl.addEventListener('click', () => this.hide());
}
}
-ngModule.component('vnMenu', {
- template: require('../popover/popover.html'),
- controller: Menu,
- transclude: true,
- bindings: {
- onOpen: '&?',
- onClose: '&?'
- }
+ngModule.vnComponent('vnMenu', {
+ controller: Menu
});
diff --git a/front/core/components/multi-check/style.scss b/front/core/components/multi-check/style.scss
index b1e3d94324..bc6a0e8c5c 100644
--- a/front/core/components/multi-check/style.scss
+++ b/front/core/components/multi-check/style.scss
@@ -1,5 +1,5 @@
vn-multi-check {
- vn-check {
+ .vn-check {
margin-bottom: 0.8em
}
}
\ No newline at end of file
diff --git a/front/core/components/popover/index.html b/front/core/components/popover/index.html
new file mode 100644
index 0000000000..de916e3b4a
--- /dev/null
+++ b/front/core/components/popover/index.html
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/front/core/components/popover/index.js b/front/core/components/popover/index.js
new file mode 100644
index 0000000000..413f4d85fc
--- /dev/null
+++ b/front/core/components/popover/index.js
@@ -0,0 +1,101 @@
+import ngModule from '../../module';
+import Popup from '../popup';
+import template from './index.html';
+import isMobile from '../../lib/is-mobile';
+import './style.scss';
+
+/**
+ * A simple popover.
+ *
+ * @property {HTMLElement} parent The parent element to show drop down relative to
+ *
+ * @event open Thrown when popover is displayed
+ * @event close Thrown when popover is hidden
+ */
+export default class Popover extends Popup {
+ constructor($element, $, $transclude) {
+ super($element, $, $transclude);
+ this.displayMode = isMobile ? 'centered' : 'relative';
+ this.template = template;
+ }
+
+ /**
+ * Shows the popover emitting the open signal. If a parent is specified
+ * it is shown in a visible relative position to it.
+ *
+ * @param {HTMLElement} parent Overrides the parent property
+ */
+ show(parent) {
+ if (parent) this.parent = parent;
+ super.show();
+ this.content = this.popup.querySelector('.content');
+ this.$timeout(() => this.relocate(), 10);
+ }
+
+ hide() {
+ this.content = null;
+ super.hide();
+ }
+
+ /**
+ * Repositions the popover to a correct location relative to the parent.
+ */
+ relocate() {
+ if (!(this.parent && this._shown && this.displayMode == 'relative'))
+ return;
+
+ let margin = 10;
+ let arrow = this.popup.querySelector('.arrow');
+
+ let style = this.windowEl.style;
+ style.width = '';
+ style.height = '';
+
+ let arrowStyle = arrow.style;
+ arrowStyle.top = '';
+ arrowStyle.bottom = '';
+
+ let parentRect = this.parent.getBoundingClientRect();
+ let popoverRect = this.windowEl.getBoundingClientRect();
+ let arrowRect = arrow.getBoundingClientRect();
+ let clamp = (value, min, max) => Math.min(Math.max(value, min), max);
+
+ let arrowHeight = Math.floor(arrowRect.height / 2);
+ let arrowOffset = arrowHeight + margin / 2;
+
+ let docEl = this.document.documentElement;
+ let maxRight = Math.min(window.innerWidth, docEl.clientWidth) - margin;
+ let maxBottom = Math.min(window.innerHeight, docEl.clientHeight) - margin;
+ let maxWith = maxRight - margin;
+ let maxHeight = maxBottom - margin - arrowHeight;
+
+ let width = clamp(popoverRect.width, parentRect.width, maxWith);
+ let height = popoverRect.height;
+
+ let left = parentRect.left + parentRect.width / 2 - width / 2;
+ left = clamp(left, margin, maxRight - width);
+
+ let top = parentRect.top + parentRect.height + arrowOffset;
+ let showTop = top + height > maxBottom;
+ if (showTop) top = parentRect.top - height - arrowOffset;
+ top = Math.max(top, margin);
+
+ if (showTop)
+ arrowStyle.bottom = `0`;
+ else
+ arrowStyle.top = `0`;
+
+ let arrowLeft = (parentRect.left - left) + parentRect.width / 2;
+ arrowLeft = clamp(arrowLeft, arrowHeight, width - arrowHeight);
+ arrowStyle.left = `${arrowLeft}px`;
+
+ style.top = `${top}px`;
+ style.left = `${left}px`;
+ style.width = `${width}px`;
+ if (height > maxHeight) style.height = `${maxHeight}px`;
+ }
+}
+
+ngModule.vnComponent('vnPopover', {
+ controller: Popover
+});
diff --git a/front/core/components/popover/popover.spec.js b/front/core/components/popover/index.spec.js
similarity index 100%
rename from front/core/components/popover/popover.spec.js
rename to front/core/components/popover/index.spec.js
diff --git a/front/core/components/popover/popover.html b/front/core/components/popover/popover.html
deleted file mode 100644
index 7a29ba817f..0000000000
--- a/front/core/components/popover/popover.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
\ No newline at end of file
diff --git a/front/core/components/popover/popover.js b/front/core/components/popover/popover.js
deleted file mode 100644
index 16969acbe0..0000000000
--- a/front/core/components/popover/popover.js
+++ /dev/null
@@ -1,201 +0,0 @@
-import ngModule from '../../module';
-import Component from '../../lib/component';
-import template from './popover.html';
-import './style.scss';
-
-/**
- * A simple popover.
- *
- * @property {HTMLElement} parent The parent element to show drop down relative to
- *
- * @event open Thrown when popover is displayed
- * @event close Thrown when popover is hidden
- */
-export default class Popover extends Component {
- constructor($element, $scope, $timeout, $transitions, $transclude, $compile) {
- super($element, $scope);
- this.$timeout = $timeout;
- this.$transitions = $transitions;
- this._shown = false;
-
- this.element = $compile(template)($scope)[0];
-
- this.popover = this.element.querySelector('.popover');
- this.popover.addEventListener('mousedown', e => this.onMouseDown(e));
-
- this.arrow = this.element.querySelector('.arrow');
- this.content = this.element.querySelector('.content');
-
- $transclude($scope.$parent,
- clone => angular.element(this.content).append(clone));
- }
-
- $onDestroy() {
- this.hide();
- }
-
- /**
- * @type {HTMLElement} The popover child.
- */
- get child() {
- return this.content.firstChild;
- }
-
- set child(value) {
- this.content.innerHTML = '';
- this.content.appendChild(value);
- }
-
- /**
- * @type {Boolean} Wether to show or hide the popover.
- */
- get shown() {
- return this._shown;
- }
-
- set shown(value) {
- if (value)
- this.show();
- else
- this.hide();
- }
-
- /**
- * Shows the popover emitting the open signal. If a parent is specified
- * it is shown in a visible relative position to it.
- *
- * @param {HTMLElement} parent Overrides the parent property
- */
- show(parent) {
- if (this._shown) return;
-
- if (parent) this.parent = parent;
-
- this._shown = true;
-
- if (!this.showTimeout) {
- this.document.body.appendChild(this.element);
- this.element.style.display = 'block';
- }
-
- this.$timeout.cancel(this.showTimeout);
- this.showTimeout = this.$timeout(() => {
- this.showTimeout = null;
- this.element.classList.add('shown');
- }, 30);
-
- this.docKeyDownHandler = e => this.onDocKeyDown(e);
- this.document.addEventListener('keydown', this.docKeyDownHandler);
-
- this.bgMouseDownHandler = e => this.onBgMouseDown(e);
- this.element.addEventListener('mousedown', this.bgMouseDownHandler);
-
- this.deregisterCallback = this.$transitions.onStart({}, () => this.hide());
- this.relocate();
- this.emit('open');
- }
-
- /**
- * Hides the popover emitting the close signal.
- */
- hide() {
- if (!this._shown) return;
-
- this._shown = false;
- this.element.classList.remove('shown');
-
- this.$timeout.cancel(this.showTimeout);
- this.showTimeout = this.$timeout(() => {
- this.showTimeout = null;
- this.element.style.display = 'none';
- this.document.body.removeChild(this.element);
- this.emit('close');
- }, 250);
-
- this.document.removeEventListener('keydown', this.docKeyDownHandler);
- this.docKeyDownHandler = null;
-
- this.element.removeEventListener('mousedown', this.bgMouseDownHandler);
- this.bgMouseDownHandler = null;
-
- if (this.deregisterCallback) this.deregisterCallback();
- this.emit('closeStart');
- }
-
- /**
- * Repositions the popover to a correct location relative to the parent.
- */
- relocate() {
- if (!(this.parent && this._shown)) return;
-
- let margin = 10;
-
- let style = this.popover.style;
- style.width = '';
- style.height = '';
-
- let arrowStyle = this.arrow.style;
- arrowStyle.top = '';
- arrowStyle.bottom = '';
-
- let parentRect = this.parent.getBoundingClientRect();
- let popoverRect = this.popover.getBoundingClientRect();
- let arrowRect = this.arrow.getBoundingClientRect();
- let clamp = (value, min, max) => Math.min(Math.max(value, min), max);
-
- let arrowHeight = Math.floor(arrowRect.height / 2);
- let arrowOffset = arrowHeight + margin / 2;
-
- let docEl = this.document.documentElement;
- let maxRight = Math.min(window.innerWidth, docEl.clientWidth) - margin;
- let maxBottom = Math.min(window.innerHeight, docEl.clientHeight) - margin;
- let maxWith = maxRight - margin;
- let maxHeight = maxBottom - margin - arrowHeight;
-
- let width = clamp(popoverRect.width, parentRect.width, maxWith);
- let height = popoverRect.height;
-
- let left = parentRect.left + parentRect.width / 2 - width / 2;
- left = clamp(left, margin, maxRight - width);
-
- let top = parentRect.top + parentRect.height + arrowOffset;
- let showTop = top + height > maxBottom;
- if (showTop) top = parentRect.top - height - arrowOffset;
- top = Math.max(top, margin);
-
- if (showTop)
- arrowStyle.bottom = `0`;
- else
- arrowStyle.top = `0`;
-
- let arrowLeft = (parentRect.left - left) + parentRect.width / 2;
- arrowLeft = clamp(arrowLeft, arrowHeight, width - arrowHeight);
- arrowStyle.left = `${arrowLeft}px`;
-
- style.top = `${top}px`;
- style.left = `${left}px`;
- style.width = `${width}px`;
- if (height > maxHeight) style.height = `${maxHeight}px`;
- }
-
- onDocKeyDown(event) {
- if (event.defaultPrevented) return;
- if (event.code == 'Escape')
- this.hide();
- }
-
- onMouseDown(event) {
- this.lastMouseEvent = event;
- }
-
- onBgMouseDown(event) {
- if (event == this.lastMouseEvent || event.defaultPrevented) return;
- this.hide();
- }
-}
-Popover.$inject = ['$element', '$scope', '$timeout', '$transitions', '$transclude', '$compile'];
-
-ngModule.component('vnPopover', {
- controller: Popover,
- transclude: true
-});
diff --git a/front/core/components/popover/style.scss b/front/core/components/popover/style.scss
index cc8199134a..decfc47337 100644
--- a/front/core/components/popover/style.scss
+++ b/front/core/components/popover/style.scss
@@ -1,7 +1,6 @@
@import "variables";
.vn-popover {
- display: none;
z-index: 20;
position: fixed;
top: 0;
@@ -20,7 +19,7 @@
transform: translateY(0);
opacity: 1;
}
- & > .popover {
+ & > .window {
position: absolute;
box-shadow: 0 .1em .4em $color-shadow;
z-index: 0;
diff --git a/front/core/components/popup/index.js b/front/core/components/popup/index.js
index 1d22adff1c..dfafcd7d48 100644
--- a/front/core/components/popup/index.js
+++ b/front/core/components/popup/index.js
@@ -12,6 +12,7 @@ export default class Popup extends Component {
this.$transclude = $transclude;
this._shown = false;
this.displayMode = 'centered';
+ this.template = template;
}
$onDestroy() {
@@ -39,11 +40,12 @@ export default class Popup extends Component {
if (this.shown) return;
this._shown = true;
- let linkFn = this.$compile(template);
+ let linkFn = this.$compile(this.template);
this.$contentScope = this.$.$new();
this.popup = linkFn(this.$contentScope, null,
{parentBoundTranscludeFn: this.$transclude}
)[0];
+ this.windowEl = this.popup.querySelector('.window');
let classList = this.popup.classList;
classList.add(this.displayMode);
@@ -84,22 +86,26 @@ export default class Popup extends Component {
this.popup.classList.remove('shown');
this.$timeout.cancel(this.transitionTimeout);
- this.transitionTimeout = this.$timeout(() => {
- this.transitionTimeout = null;
- this.document.body.removeChild(this.popup);
-
- this.$contentScope.$destroy();
- this.popup.remove();
- this.popup = null;
-
- this.emit('close');
- }, 200);
+ this.transitionTimeout = this.$timeout(
+ () => this.onClose(), 200);
this.lastEvent = null;
this._shown = false;
this.emit('closeStart');
}
+ onClose() {
+ this.transitionTimeout = null;
+ this.document.body.removeChild(this.popup);
+
+ this.$contentScope.$destroy();
+ this.popup.remove();
+ this.popup = null;
+ this.windowEl = null;
+
+ this.emit('close');
+ }
+
onWindowMouseDown(event) {
this.lastEvent = event;
}
diff --git a/front/core/components/popup/style.scss b/front/core/components/popup/style.scss
index 9611e13e76..42d69141d0 100644
--- a/front/core/components/popup/style.scss
+++ b/front/core/components/popup/style.scss
@@ -30,7 +30,7 @@
overflow: auto;
box-sizing: border-box;
max-height: 100%;
- transform: scale3d(.5, .5, .5);
+ transform: scale3d(.9, .9, .9);
transition: transform 200ms ease-in-out;
}
&.shown > .window {
diff --git a/front/core/components/radio/style.scss b/front/core/components/radio/style.scss
index dd1555b7f5..787c0986e5 100644
--- a/front/core/components/radio/style.scss
+++ b/front/core/components/radio/style.scss
@@ -1,6 +1,6 @@
@import "variables";
-vn-radio {
+.vn-radio {
& > .btn {
border-radius: 50%;
@@ -22,4 +22,7 @@ vn-radio {
background-color: $color-main;
}
}
+ &.disabled.checked > .btn > .mark {
+ background-color: $color-font-secondary;
+ }
}
diff --git a/front/core/components/range/style.scss b/front/core/components/range/style.scss
index 878035f3a3..a370b4c39c 100644
--- a/front/core/components/range/style.scss
+++ b/front/core/components/range/style.scss
@@ -35,7 +35,7 @@
}
}
-vn-range {
+.vn-range {
& > label {
font-size: 12px;
diff --git a/front/core/components/searchbar/search-panel.js b/front/core/components/searchbar/search-panel.js
index 96dc67ed54..f473c2b049 100644
--- a/front/core/components/searchbar/search-panel.js
+++ b/front/core/components/searchbar/search-panel.js
@@ -1,6 +1,6 @@
import Component from '../../lib/component';
-export default class extends Component {
+export default class SearchPanel extends Component {
set filter(value) {
this.$.filter = value;
}
@@ -13,6 +13,6 @@ export default class extends Component {
if (!this.onSubmit)
throw new Error('SearchPanel::onSubmit() method not defined');
- this.onSubmit(this.filter);
+ this.onSubmit({$filter: this.filter});
}
}
diff --git a/front/core/components/searchbar/searchbar.js b/front/core/components/searchbar/searchbar.js
index f3db40a93a..d74a4e7a65 100644
--- a/front/core/components/searchbar/searchbar.js
+++ b/front/core/components/searchbar/searchbar.js
@@ -65,23 +65,24 @@ export default class Controller extends Component {
openPanel(event) {
if (event.defaultPrevented) return;
+ this.$.popover.show(this.element);
this.$panelScope = this.$.$new();
- this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);
- let panel = this.$panel[0].$ctrl;
+ this.panelEl = this.$compile(`<${this.panel}/>`)(this.$panelScope)[0];
+ let panel = this.panelEl.$ctrl;
if (this.shownFilter)
panel.filter = JSON.parse(JSON.stringify(this.shownFilter));
- panel.onSubmit = filter => this.onPanelSubmit(filter);
+ panel.onSubmit = filter => this.onPanelSubmit(filter.$filter);
- this.$.popover.parent = this.element;
- this.$.popover.child = this.$panel[0];
- this.$.popover.show();
+ this.$.popover.content.appendChild(this.panelEl);
}
onPopoverClose() {
this.$panelScope.$destroy();
- this.$panel.remove();
- this.$panel = null;
+ this.$panelScope = null;
+
+ this.panelEl.remove();
+ this.panelEl = null;
}
onPanelSubmit(filter) {
diff --git a/front/core/components/searchbar/searchbar.spec.js b/front/core/components/searchbar/searchbar.spec.js
index 92883c47b1..4cd7ec74a6 100644
--- a/front/core/components/searchbar/searchbar.spec.js
+++ b/front/core/components/searchbar/searchbar.spec.js
@@ -8,11 +8,11 @@ describe('Component vnSearchbar', () => {
beforeEach(ngModule('vnCore'));
- beforeEach(angular.mock.inject(($componentController, _$state_, $rootScope, $compile) => {
+ beforeEach(angular.mock.inject(($componentController, _$state_, $rootScope) => {
$scope = $rootScope.$new();
$state = _$state_;
$element = angular.element(``);
- controller = $componentController('vnSearchbar', {$element, $state, $scope, $compile});
+ controller = $componentController('vnSearchbar', {$element, $scope});
controller.panel = 'vn-client-search-panel';
}));
@@ -39,7 +39,7 @@ describe('Component vnSearchbar', () => {
describe('onStateChange()', () => {
it(`should set a formated _filter in the controller`, () => {
spyOn(controller, 'doSearch');
- Object.assign(controller.$state.params, {q: '{"id": 999}'});
+ Object.assign($state.params, {q: '{"id": 999}'});
controller.onStateChange();
@@ -71,27 +71,11 @@ describe('Component vnSearchbar', () => {
describe('filter() setter', () => {
it(`should call $state.go() to replace the current state location instead of creating a new one`, () => {
controller._filter = {};
- spyOn(controller.$state, 'go');
+ spyOn($state, 'go');
controller.filter = {expected: 'filter'};
expect(controller._filter).toEqual(controller.filter);
- expect(controller.$state.go).toHaveBeenCalledWith('.', Object({q: '{"expected":"filter"}'}), Object({location: 'replace'}));
- });
- });
-
- describe('onPopoverClose()', () => {
- it(`should get rid of $panel and $panelScope`, () => {
- controller.$panel = {
- I: 'should disappear',
- remove: () => {}
- };
-
- controller.$panelScope = {$destroy: jasmine.createSpy('$destroy')};
-
- controller.onPopoverClose();
-
- expect(controller.$panelScope.$destroy).toHaveBeenCalledWith();
- expect(controller.$panel).toBeNull();
+ expect($state.go).toHaveBeenCalledWith('.', Object({q: '{"expected":"filter"}'}), Object({location: 'replace'}));
});
});
diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss
index 839e1a7bbd..a3fd4513b9 100644
--- a/front/core/components/table/style.scss
+++ b/front/core/components/table/style.scss
@@ -169,11 +169,11 @@ vn-table {
}
}
}
- vn-textfield {
+ .vn-textfield {
float: right;
margin: 0!important;
}
- vn-check {
+ .vn-check {
margin: 0;
}
}
\ No newline at end of file
diff --git a/front/core/components/toggle/index.js b/front/core/components/toggle/index.js
index 70698ede86..bc3851bbca 100644
--- a/front/core/components/toggle/index.js
+++ b/front/core/components/toggle/index.js
@@ -11,13 +11,12 @@ export default class Toggle extends FormInput {
constructor($element, $) {
super($element, $);
this.initTabIndex();
- this.classList.add('vn-toggle');
this.element.addEventListener('click', e => this.onClick(e));
this.element.addEventListener('keydown', e => this.onKeydown(e));
}
onKeydown(event) {
- if (!event.defaultPrevented && event.code == 'Space')
+ if (!event.defaultPrevented && event.key == ' ')
this.element.click();
}
@@ -26,10 +25,9 @@ export default class Toggle extends FormInput {
return true;
}
- changed() {
+ change(value) {
this.$.$applyAsync();
- this.element.dispatchEvent(new Event('change'));
- this.emit('change', {value: this.field});
+ super.change(value);
}
}
diff --git a/front/core/components/toggle/style.scss b/front/core/components/toggle/style.scss
index a373b6f4c5..af3dc3ae5e 100644
--- a/front/core/components/toggle/style.scss
+++ b/front/core/components/toggle/style.scss
@@ -7,11 +7,8 @@
align-items: center;
outline: none;
- &.disabled {
- cursor: inherit;
- }
& > span {
- font-size: $font-size;
+ font-size: 1rem;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
@@ -28,13 +25,6 @@
margin-right: .6em;
border: 2px solid #666;
}
- &.checked > .btn {
- border-color: $color-main;
-
- & > .focus-mark {
- background-color: rgba($color-main, .15);
- }
- }
& > .btn > .focus-mark {
position: absolute;
top: 50%;
@@ -49,6 +39,23 @@
transition: transform 250ms;
background-color: rgba(0, 0, 0, .1);
}
+ &.checked > .btn {
+ border-color: $color-main;
+
+ & > .focus-mark {
+ background-color: rgba($color-main, .15);
+ }
+ }
+ &.disabled {
+ cursor: inherit;
+
+ &.checked > .btn {
+ border-color: $color-font-secondary;
+ }
+ }
+ &.readonly {
+ cursor: inherit;
+ }
&:focus:not(.disabled) > .btn > .focus-mark {
transform: scale3d(1, 1, 1);
}
diff --git a/front/core/components/wday-picker/style.scss b/front/core/components/wday-picker/style.scss
index c50b207183..c6899ad6aa 100644
--- a/front/core/components/wday-picker/style.scss
+++ b/front/core/components/wday-picker/style.scss
@@ -1,6 +1,6 @@
@import "effects";
-vn-wday-picker {
+.vn-wday-picker {
text-align: center;
&:focus {
diff --git a/front/core/directives/focus.js b/front/core/directives/focus.js
index b9527479be..28535430a3 100644
--- a/front/core/directives/focus.js
+++ b/front/core/directives/focus.js
@@ -1,7 +1,5 @@
import ngModule from '../module';
-
-const regex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i;
-export const isMobile = regex.test(navigator.userAgent);
+import isMobile from '../lib/is-mobile';
export function focus($scope, input) {
if (isMobile) return;
diff --git a/front/core/directives/popover.js b/front/core/directives/popover.js
index ad147e9c0f..5d86665baf 100644
--- a/front/core/directives/popover.js
+++ b/front/core/directives/popover.js
@@ -1,5 +1,5 @@
import ngModule from '../module';
-import Popover from '../components/popover/popover';
+import Popover from '../components/popover';
import {kebabToCamel} from '../lib/string';
/**
@@ -15,10 +15,8 @@ export function directive() {
if (event.defaultPrevented) return;
let popoverKey = kebabToCamel($attrs.vnPopover);
let popover = $scope[popoverKey];
- if (popover instanceof Popover) {
- popover.parent = $element[0];
- popover.show();
- }
+ if (popover instanceof Popover)
+ popover.show($element[0]);
});
}
};
diff --git a/front/core/directives/specs/dialog.spec.js b/front/core/directives/specs/dialog.spec.js
index 670b28128e..4d5a02e315 100644
--- a/front/core/directives/specs/dialog.spec.js
+++ b/front/core/directives/specs/dialog.spec.js
@@ -17,9 +17,9 @@ describe('Directive dialog', () => {
});
};
- beforeEach(angular.mock.inject($componentController => {
- $element = angular.element('');
- controller = $componentController('vnDialog', {$element: $element, $transclude: null});
+ beforeEach(angular.mock.inject(($rootScope, $compile) => {
+ $element = $compile('')($rootScope);
+ controller = $element.controller('vnDialog');
}));
it('should call show() function if dialog is a instance of vnDialog', () => {
diff --git a/front/core/directives/zoom-image.js b/front/core/directives/zoom-image.js
index 574a6e5492..607dbe3378 100644
--- a/front/core/directives/zoom-image.js
+++ b/front/core/directives/zoom-image.js
@@ -25,7 +25,7 @@ export function directive($timeout) {
}
function onKeyDown(event) {
- if (event.keyCode === 27)
+ if (event.key === 'Escape')
destroyContainers();
}
diff --git a/front/core/lib/component.js b/front/core/lib/component.js
index 173a46e9f5..979420b22f 100644
--- a/front/core/lib/component.js
+++ b/front/core/lib/component.js
@@ -39,6 +39,7 @@ export default class Component extends EventEmitter {
get window() {
return this.document.defaultView;
}
+
/**
* The component owner document.
*/
@@ -57,21 +58,16 @@ export default class Component extends EventEmitter {
return this.$translate.instant(string, params);
}
- createBoundTranscludeFn(transcludeFn) {
+ createBoundTranscludeFn(linkFn) {
let scope = this.$;
let previousBoundTranscludeFn = this.$transclude.$$boundTransclude;
- function vnBoundTranscludeFn(
- transcludedScope,
- cloneFn,
- controllers,
- futureParentElement,
- containingScope) {
+ function vnBoundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
if (!transcludedScope) {
transcludedScope = scope.$new(false, containingScope);
transcludedScope.$$transcluded = true;
}
- return transcludeFn(transcludedScope, cloneFn, {
+ return linkFn(transcludedScope, cloneFn, {
parentBoundTranscludeFn: previousBoundTranscludeFn,
transcludeControllers: controllers,
futureParentElement: futureParentElement
@@ -81,10 +77,37 @@ export default class Component extends EventEmitter {
return vnBoundTranscludeFn;
}
+
+ fillDefaultSlot(template) {
+ let linkFn = this.$compile(template);
+ this.$transclude.$$boundTransclude = this.createBoundTranscludeFn(linkFn);
+ }
+
+ fillSlot(slot, template) {
+ let slots = this.$transclude.$$boundTransclude.$$slots;
+ let linkFn = this.$compile(template);
+ slots[slot] = this.createBoundTranscludeFn(linkFn);
+ }
+
+ copySlot(slot, $transclude) {
+ this.$transclude.$$boundTransclude.$$slots[slot] =
+ $transclude.$$boundTransclude.$$slots[slot];
+ }
}
Component.$inject = ['$element', '$scope'];
-function runFn($translate, $q, $http, $state, $stateParams, $timeout, $transitions, $compile, vnApp) {
+function runFn(
+ $translate,
+ $q,
+ $http,
+ $state,
+ $stateParams,
+ $timeout,
+ $transitions,
+ $compile,
+ $filter,
+ $interpolate,
+ vnApp) {
Object.assign(Component.prototype, {
$translate,
$q,
@@ -94,6 +117,8 @@ function runFn($translate, $q, $http, $state, $stateParams, $timeout, $transitio
$timeout,
$transitions,
$compile,
+ $filter,
+ $interpolate,
vnApp
});
}
@@ -106,6 +131,8 @@ runFn.$inject = [
'$timeout',
'$transitions',
'$compile',
+ '$filter',
+ '$interpolate',
'vnApp'
];
diff --git a/front/core/lib/event-emitter.js b/front/core/lib/event-emitter.js
index 022e4e98c2..83e3612532 100644
--- a/front/core/lib/event-emitter.js
+++ b/front/core/lib/event-emitter.js
@@ -51,17 +51,17 @@ export default class EventEmitter {
* Emits an event.
*
* @param {String} eventName The event name
- * @param {...*} args Arguments to pass to the callbacks
+ * @param {Object} args Arguments to pass to the callbacks
*/
- emit(eventName) {
+ emit(eventName, args) {
if (!this.$events || !this.$events[eventName])
return;
- let args = Array.prototype.slice.call(arguments, 1);
+ args = Object.assign({$this: this}, args);
let callbacks = this.$events[eventName];
for (let callback of callbacks)
- callback.callback.apply(callback.thisArg, args);
+ callback.callback.call(callback.thisArg, args);
}
/**
diff --git a/front/core/lib/is-mobile.js b/front/core/lib/is-mobile.js
new file mode 100644
index 0000000000..5fae749dfc
--- /dev/null
+++ b/front/core/lib/is-mobile.js
@@ -0,0 +1,4 @@
+
+const regex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i;
+const isMobile = regex.test(navigator.userAgent);
+export default isMobile;
diff --git a/front/core/locale/es.yml b/front/core/locale/es.yml
index 1fcd12b986..1e1e4da4c9 100644
--- a/front/core/locale/es.yml
+++ b/front/core/locale/es.yml
@@ -11,7 +11,6 @@ Hide: Ocultar
Next: Siguiente
Finalize: Finalizar
Previous: Anterior
-Load more: Cargar más
Auto-scroll interrupted, please adjust the search: Auto-scroll interrumpido, por favor ajusta la búsqueda
Value can't be empty: El valor no puede estar vacío
Value should be empty: El valor debe estar vacío
@@ -60,3 +59,7 @@ No records found: No se han encontrado elementos
Day: Día
Days: Días
Go up: Ir arriba
+Loading...: Cargando...
+No results found: Sin resultados
+No data: Sin datos
+Load more: Cargar más
\ No newline at end of file
diff --git a/front/salix/components/login/style.scss b/front/salix/components/login/style.scss
index ea894d62e8..e098fbdb4e 100644
--- a/front/salix/components/login/style.scss
+++ b/front/salix/components/login/style.scss
@@ -30,10 +30,10 @@ vn-login {
padding-bottom: 1em;
}
& > form {
- & > vn-textfield {
+ & > .vn-textfield {
width: 100%;
}
- & > vn-check {
+ & > .vn-check {
display: block;
.md-label {
white-space: inherit;
diff --git a/front/salix/locale/es.yml b/front/salix/locale/es.yml
index 898728363e..a7f1dc93ab 100644
--- a/front/salix/locale/es.yml
+++ b/front/salix/locale/es.yml
@@ -52,3 +52,4 @@ List: Listado
# Misc
Phone: Teléfono
+Id: Id
diff --git a/front/salix/styles/misc.scss b/front/salix/styles/misc.scss
index 82f4615c9b..0ae30becd7 100644
--- a/front/salix/styles/misc.scss
+++ b/front/salix/styles/misc.scss
@@ -3,22 +3,22 @@
form vn-horizontal {
align-items: center;
+ min-height: 2.8em;
& > * {
box-sizing: border-box;
- min-height: 2.8em;
- padding: 0 $spacing-sm;
+ margin: 0 $spacing-xs;
&:first-child {
- padding-left: 0;
- padding-right: $spacing-xs;
+ margin-left: 0;
+ margin-right: $spacing-sm;
}
&:last-child {
- padding-left: $spacing-xs;
- padding-right: 0;
+ margin-left: $spacing-sm;
+ margin-right: 0;
}
&:first-child:last-child {
- padding: 0;
+ margin: 0;
}
}
@@ -30,7 +30,7 @@ form vn-horizontal {
&,
&:first-child,
&:last-child {
- padding: 0;
+ margin: 0;
}
}
}
diff --git a/front/salix/styles/modal-form.scss b/front/salix/styles/modal-form.scss
index e0318c9d28..0f728178da 100644
--- a/front/salix/styles/modal-form.scss
+++ b/front/salix/styles/modal-form.scss
@@ -16,7 +16,7 @@ vn-dialog.modal-form {
& > div {
padding: 0 !important;
}
- vn-textfield {
+ .vn-textfield {
width: 100%;
}
.buttons {
diff --git a/modules/agency/front/calendar/style.scss b/modules/agency/front/calendar/style.scss
index f48c7d6b67..3fe23278e6 100644
--- a/modules/agency/front/calendar/style.scss
+++ b/modules/agency/front/calendar/style.scss
@@ -23,7 +23,7 @@ vn-zone-calendar {
flex-wrap: wrap;
justify-content: space-evenly;
- & > vn-calendar {
+ & > .vn-calendar {
max-width: 18em;
.day {
diff --git a/modules/agency/front/location/style.scss b/modules/agency/front/location/style.scss
index d1597e4609..d03701e421 100644
--- a/modules/agency/front/location/style.scss
+++ b/modules/agency/front/location/style.scss
@@ -1,14 +1,14 @@
@import "variables";
vn-treeview-child {
- .content > vn-check:not(.indeterminate) {
+ .content > .vn-check:not(.indeterminate) {
color: $color-main;
& > .btn {
border-color: $color-main;
}
}
- .content > vn-check.checked {
+ .content > .vn-check.checked {
color: $color-main;
}
}
\ No newline at end of file
diff --git a/modules/claim/front/action/style.scss b/modules/claim/front/action/style.scss
index 0124b716bd..aef8d2cfd7 100644
--- a/modules/claim/front/action/style.scss
+++ b/modules/claim/front/action/style.scss
@@ -9,7 +9,7 @@ vn-claim-action {
flex: 1
}
- vn-check {
+ .vn-check {
flex: none;
}
}
diff --git a/modules/claim/front/detail/style.scss b/modules/claim/front/detail/style.scss
index e555cb3052..2b5727d48b 100644
--- a/modules/claim/front/detail/style.scss
+++ b/modules/claim/front/detail/style.scss
@@ -1,7 +1,7 @@
@import "variables";
vn-claim-detail {
- vn-textfield {
+ .vn-textfield {
margin: 0!important;
max-width: 100px;
}
diff --git a/modules/client/front/dms/create/style.scss b/modules/client/front/dms/create/style.scss
index b47544b120..73f136fc15 100644
--- a/modules/client/front/dms/create/style.scss
+++ b/modules/client/front/dms/create/style.scss
@@ -1,5 +1,5 @@
vn-ticket-request {
- vn-textfield {
+ .vn-textfield {
margin: 0!important;
max-width: 100px;
}
diff --git a/modules/client/front/dms/edit/style.scss b/modules/client/front/dms/edit/style.scss
index b47544b120..73f136fc15 100644
--- a/modules/client/front/dms/edit/style.scss
+++ b/modules/client/front/dms/edit/style.scss
@@ -1,5 +1,5 @@
vn-ticket-request {
- vn-textfield {
+ .vn-textfield {
margin: 0!important;
max-width: 100px;
}
diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json
index 78396793b9..7e2a93e115 100644
--- a/modules/item/back/models/item.json
+++ b/modules/item/back/models/item.json
@@ -14,53 +14,68 @@
"id": {
"type": "Number",
"id": true,
- "description": "Identifier"
+ "description": "Id"
},
"name": {
- "type": "String"
+ "type": "String",
+ "description": "Name"
},
"size": {
- "type": "Number"
+ "type": "Number",
+ "description": "Size"
},
"category": {
- "type": "String"
+ "type": "String",
+ "description": "Category"
},
"typeFk": {
"type": "Number",
+ "description": "Type",
"required": true
},
"stems": {
- "type": "Number"
+ "type": "Number",
+ "description": "Stems"
},
"description": {
- "type": "String"
+ "type": "String",
+ "description": "Description"
},
"isOnOffer": {
- "type": "Boolean"
+ "type": "Boolean",
+ "description": "Offer"
},
"isBargain": {
- "type": "Boolean"
+ "type": "Boolean",
+ "description": "Bargain"
},
"isActive": {
- "type": "Boolean"
+ "type": "Boolean",
+ "description": "Active"
},
"comment": {
- "type": "String"
+ "type": "String",
+ "description": "Comment"
},
"relevancy": {
- "type": "Number"
+ "type": "Number",
+ "description": "Relevancy"
},
"density": {
- "type": "Number"
+ "type": "Number",
+ "description": "Density"
},
"image": {
- "type": "String"
+ "type": "String",
+ "description": "Image"
},
"longName": {
- "type": "String"
+ "type": "String",
+ "description": "Long name"
},
"subName": {
- "type": "String"
+ "type": "String",
+ "description": "Subname"
},
"tag5": {
"type": "String"
@@ -99,7 +114,8 @@
"type": "String"
},
"hasKgPrice": {
- "type": "Boolean"
+ "type": "Boolean",
+ "description": "Price per Kg"
}
},
"relations": {
diff --git a/modules/item/front/descriptor/style.scss b/modules/item/front/descriptor/style.scss
index 257e46e1ca..c4847bead5 100644
--- a/modules/item/front/descriptor/style.scss
+++ b/modules/item/front/descriptor/style.scss
@@ -8,7 +8,7 @@ vn-item-descriptor {
display: block;
}
vn-dialog[vn-id=regularize]{
- vn-textfield{
+ .vn-textfield{
width: 100%
}
}
diff --git a/modules/item/front/search-panel/index.html b/modules/item/front/search-panel/index.html
index e8209df831..ea0d854f51 100644
--- a/modules/item/front/search-panel/index.html
+++ b/modules/item/front/search-panel/index.html
@@ -22,8 +22,9 @@
@@ -42,13 +43,17 @@
label="Buyer">
-
-
-
+
+
+ Tags
+
+
+
-
+
+
+ More fields
+
+ ng-click="$ctrl.fieldFilters.push({})">
-
-
- More fields
-
-
-
+
+ ng-model="fieldFilter.name"
+ data="$ctrl.moreFields"
+ value-field="name"
+ show-field="label"
+ show-filter="false"
+ translate-fields="['label']"
+ selection="info"
+ on-change="fieldFilter.value = null">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
diff --git a/modules/item/front/search-panel/index.js b/modules/item/front/search-panel/index.js
index 098ec80422..6b3e7786d9 100644
--- a/modules/item/front/search-panel/index.js
+++ b/modules/item/front/search-panel/index.js
@@ -2,19 +2,37 @@ import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel';
class Controller extends SearchPanel {
- constructor($scope, $element) {
- super($scope, $element);
- this.$ = $scope;
- this.moreFields = [
- {field: 'id'},
- {field: 'description'},
- {field: 'name'}
- ];
+ constructor($element, $) {
+ super($element, $);
+ let model = 'Item';
+ let moreFields = ['id', 'description', 'name', 'isActive'];
+
+ let properties;
+ let validations = window.validations;
+
+ if (validations && validations[model])
+ properties = validations[model].properties;
+ else
+ properties = {};
+
+ this.moreFields = [];
+ for (let field of moreFields) {
+ let prop = properties[field];
+ this.moreFields.push({
+ name: field,
+ label: prop ? prop.description : field,
+ type: prop ? prop.type : null
+ });
+ }
}
- initializeMoreFields() {
- if (!this.$.filter.moreFields || !this.$.filter.moreFields.length)
- this.$.filter.moreFields = [{}];
+ get filter() {
+ let filter = this.$.filter;
+
+ for (let fieldFilter of this.fieldFilters)
+ filter[fieldFilter.name] = fieldFilter.value;
+
+ return filter;
}
set filter(value) {
@@ -23,28 +41,20 @@ class Controller extends SearchPanel {
if (!value.tags)
value.tags = [{}];
+ this.fieldFilters = [];
+ for (let field of this.moreFields) {
+ if (value[field.name] != undefined) {
+ this.fieldFilters.push({
+ name: field.name,
+ value: value[field.name],
+ info: field
+ });
+ }
+ }
+
this.$.filter = value;
}
- get itemTypes() {
- if (this.$.filter) {
- if (!this.$.filter.categoryFk)
- return 'ItemTypes';
- return `ItemCategories/${this.$.filter.categoryFk}/itemTypes`;
- }
- }
-
- get filter() {
- if (this.$.filter.moreFields) {
- this.$.filter.moreFields.forEach(element => {
- this.$.filter[element.field] = element.value;
- });
- }
- let filter = Object.assign({}, this.$.filter);
- delete filter.moreFields;
- return filter;
- }
-
getSourceTable(selection) {
if (!selection || selection.isFree === true)
return null;
@@ -56,6 +66,11 @@ class Controller extends SearchPanel {
} else if (selection.sourceTable == null)
return `ItemTags/filterItemTags/${selection.id}`;
}
+
+ removeField(index, field) {
+ this.fieldFilters.splice(index, 1);
+ this.$.filter[field] = undefined;
+ }
}
ngModule.component('vnItemSearchPanel', {
diff --git a/modules/item/front/search-panel/locale/es.yml b/modules/item/front/search-panel/locale/es.yml
index 660991827b..197da0695c 100644
--- a/modules/item/front/search-panel/locale/es.yml
+++ b/modules/item/front/search-panel/locale/es.yml
@@ -3,6 +3,6 @@ Origin: Origen
Producer: Productor.
With visible: Con visible
Field: Campo
-More fields: Mas campos
+More fields: Más campos
Add field: Añadir campo
Remove field: Quitar campo
\ No newline at end of file
diff --git a/modules/order/front/catalog-search-panel/index.js b/modules/order/front/catalog-search-panel/index.js
index 6ad88c9785..7d5f1bfd1c 100644
--- a/modules/order/front/catalog-search-panel/index.js
+++ b/modules/order/front/catalog-search-panel/index.js
@@ -3,5 +3,8 @@ import SearchPanel from 'core/components/searchbar/search-panel';
ngModule.component('vnOrderCatalogSearchPanel', {
template: require('./index.html'),
- controller: SearchPanel
+ controller: SearchPanel,
+ bindings: {
+ onSubmit: '&?'
+ }
});
diff --git a/modules/order/front/catalog/index.html b/modules/order/front/catalog/index.html
index aee1b1ec63..37ef1fd90b 100644
--- a/modules/order/front/catalog/index.html
+++ b/modules/order/front/catalog/index.html
@@ -1,111 +1,69 @@
-
-
-
-
-
-
-
-
-
- Enter a new search
-
-
- No results
-
-
+
-
-
-
-
![]()
+
+
+
+
![]()
+
+
+
+ {{::item.name}}
+
+
+ {{::item.subName}}
+
+
+
+
+
+
+
+
-
-
- {{::item.name}}
-
-
- {{::item.subName}}
-
-
-
-
-
-
-
-
+
+
+
-
-
+
diff --git a/modules/order/front/catalog/index.js b/modules/order/front/catalog/index.js
index 758c56f0e7..adb66171ed 100644
--- a/modules/order/front/catalog/index.js
+++ b/modules/order/front/catalog/index.js
@@ -8,20 +8,19 @@ class Controller {
this.$stateParams = $state.params;
// Static autocomplete data
- this.wayList = [
+ this.orderWays = [
{way: 'ASC', name: 'Ascendant'},
{way: 'DESC', name: 'Descendant'},
];
- this.defaultFieldList = [
- {field: 'relevancy DESC, name', name: 'Default'},
+ this.defaultOrderFields = [
+ {field: 'relevancy DESC, name', name: 'Relevancy'},
{field: 'showOrder, price', name: 'Color'},
{field: 'name', name: 'Name'},
{field: 'price', name: 'Price'}
];
- this.fieldList = [];
- this.fieldList = this.fieldList.concat(this.defaultFieldList);
- this._way = this.wayList[0].way;
- this._field = this.fieldList[0].field;
+ this.orderFields = [].concat(this.defaultOrderFields);
+ this._orderWay = this.orderWays[0].way;
+ this._orderField = this.orderFields[0].field;
}
/**
@@ -51,43 +50,41 @@ class Controller {
});
// Add default filters - Replaces tags with same name
- this.defaultFieldList.forEach(defaultField => {
+ this.defaultOrderFields.forEach(orderField => {
const index = newFilterList.findIndex(newfield => {
- return newfield.name == defaultField.name;
+ return newfield.name == orderField.name;
});
if (index > -1)
- newFilterList[index] = defaultField;
+ newFilterList[index] = orderField;
else
- newFilterList.push(defaultField);
+ newFilterList.push(orderField);
});
- this.fieldList = newFilterList;
+ this.orderFields = newFilterList;
}
/**
* Get order way ASC/DESC
*/
- get way() {
- return this._way;
+ get orderWay() {
+ return this._orderWay;
}
- set way(value) {
- this._way = value;
-
+ set orderWay(value) {
+ this._orderWay = value;
if (value) this.applyOrder();
}
/**
* Get order fields
*/
- get field() {
- return this._field;
+ get orderField() {
+ return this._orderField;
}
- set field(value) {
- this._field = value;
-
+ set orderField(value) {
+ this._orderField = value;
if (value) this.applyOrder();
}
@@ -97,16 +94,11 @@ class Controller {
* @return {Object} - Order param
*/
getOrderBy() {
- let field = this.$scope.field;
- let args = {
- field: this.field,
- way: this.way
+ return {
+ field: this.orderField,
+ way: this.orderWay,
+ isTag: !!(this.orderSelection && this.orderSelection.isTag)
};
-
- if (field.selection && field.selection.isTag)
- args.isTag = true;
-
- return args;
}
/**
@@ -129,10 +121,6 @@ class Controller {
if (this.order && this.order.isConfirmed)
this.$state.go('order.card.line');
}
-
- get isRefreshing() {
- return this.$scope.model && this.$scope.model.status == 'loading';
- }
}
Controller.$inject = ['$scope', '$state'];
diff --git a/modules/order/front/catalog/index.spec.js b/modules/order/front/catalog/index.spec.js
index 98494b3cad..b6e70bb4a4 100644
--- a/modules/order/front/catalog/index.spec.js
+++ b/modules/order/front/catalog/index.spec.js
@@ -25,17 +25,21 @@ describe('Order', () => {
let unexpectedResult = [{tagFk: 5, name: 'Color'}];
controller.onDataChange();
- expect(controller.fieldList.length).toEqual(5);
- expect(controller.fieldList).toEqual(jasmine.arrayContaining(expectedResult));
- expect(controller.fieldList).not.toEqual(jasmine.arrayContaining(unexpectedResult));
+ expect(controller.orderFields.length).toEqual(5);
+ expect(controller.orderFields).toEqual(jasmine.arrayContaining(expectedResult));
+ expect(controller.orderFields).not.toEqual(jasmine.arrayContaining(unexpectedResult));
});
});
describe('getOrderBy()', () => {
it(`should return an object with order params`, () => {
- controller.field = 'relevancy DESC, name';
- controller.way = 'DESC';
- let expectedResult = {field: 'relevancy DESC, name', way: 'DESC'};
+ controller.orderField = 'relevancy DESC, name';
+ controller.orderWay = 'DESC';
+ let expectedResult = {
+ field: 'relevancy DESC, name',
+ way: 'DESC',
+ isTag: false
+ };
let result = controller.getOrderBy();
expect(result).toEqual(expectedResult);
diff --git a/modules/order/front/descriptor/index.js b/modules/order/front/descriptor/index.js
index bf197e0700..96cee0bbd0 100644
--- a/modules/order/front/descriptor/index.js
+++ b/modules/order/front/descriptor/index.js
@@ -1,5 +1,4 @@
import ngModule from '../module';
-import './style.scss';
class Controller {
constructor($translate, $scope, vnApp, $http, $state) {
diff --git a/modules/order/front/descriptor/style.scss b/modules/order/front/descriptor/style.scss
deleted file mode 100644
index 469020e504..0000000000
--- a/modules/order/front/descriptor/style.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-vn-label-value[label=Total]{
- padding-top: 10px;
- display: block;
- font-size: 1.2em;
-}
\ No newline at end of file
diff --git a/modules/order/front/filter/index.html b/modules/order/front/filter/index.html
index 3f2d2094b7..68691e0a74 100644
--- a/modules/order/front/filter/index.html
+++ b/modules/order/front/filter/index.html
@@ -7,19 +7,20 @@
-
-
+
+
-
-
+
- search
+
-
-
- keyboard_arrow_down
-
-
-
-
+
+
+
+
+
+
+
+ More than {{model.limit}} results
+
+
+
@@ -58,21 +77,24 @@
label="Search tag"
ng-model="$ctrl.value">
- search
+
-
- keyboard_arrow_down
-
+
+
-
+
+
{
+ this.$.$applyAsync(() => {
let category;
let type;
@@ -111,7 +111,7 @@ class Controller {
this.tags.push({
value: this.value,
});
- this.$scope.search.value = null;
+ this.$.search.value = null;
this.applyFilters();
}
@@ -149,29 +149,16 @@ class Controller {
if (event.defaultPrevented) return;
event.preventDefault();
- this.$panelScope = this.$scope.$new();
- this.$panel = this.$compile(``)(this.$panelScope);
- const panel = this.$panel[0].$ctrl;
- panel.filter = this.filter;
- panel.onSubmit = filter => this.onPanelSubmit(filter);
-
- this.$scope.popover.parent = this.$scope.search.element;
- this.$scope.popover.child = this.$panel[0];
- this.$scope.popover.show();
+ this.panelFilter = {};
+ this.$.popover.show(this.$.search.element);
}
onPanelSubmit(filter) {
- this.$scope.popover.hide();
+ this.$.popover.hide();
this.tags.push(filter);
this.applyFilters();
}
- onPopoverClose() {
- this.$panelScope.$destroy();
- this.$panel.remove();
- this.$panel = null;
- }
-
/**
* Updates url state params from filter values
*/
diff --git a/modules/order/front/filter/index.spec.js b/modules/order/front/filter/index.spec.js
index 0b3be5a6c3..8fb4baecad 100644
--- a/modules/order/front/filter/index.spec.js
+++ b/modules/order/front/filter/index.spec.js
@@ -31,13 +31,10 @@ describe('Order', () => {
describe('order() setter', () => {
it(`should call scope $applyAsync() method and apply filters from state params`, () => {
$httpBackend.expect('GET', `Orders/4/getItemTypeAvailable?itemCategoryId=1`).respond();
- spyOn(controller.$scope, '$applyAsync').and.callThrough();
controller.order = {id: 4};
- expect(controller.$scope.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
$scope.$apply();
-
expect(controller.category).toEqual({id: 1, value: 'My Category'});
expect(controller.type).toEqual({id: 1, value: 'My type'});
});
diff --git a/modules/order/front/line/index.html b/modules/order/front/line/index.html
index cdff9b35c9..9204f32156 100644
--- a/modules/order/front/line/index.html
+++ b/modules/order/front/line/index.html
@@ -2,77 +2,83 @@
vn-id="watcher"
data="$ctrl.rows">
-
-
-
-
-
-
-
-
- Id
- Description
- Warehouse
- Shipped
- Quantity
- Price
-
-
-
-
-
-
-
-
-
-
- {{::row.itemFk | zeroFill:6}}
-
-
-
-
-
-
- {{::row.warehouse.name}}
- {{::row.shipped | date: 'dd/MM/yyyy'}}
- {{::row.quantity}}
-
- {{::row.price | currency: 'EUR':2}}
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+ Id
+ Description
+ Warehouse
+ Shipped
+ Quantity
+ Price
+
+
+
+
+
+
+
+
+
+
+ {{::row.itemFk | zeroFill:6}}
+
+
+
+
+
+
+ {{::row.warehouse.name}}
+ {{::row.shipped | date: 'dd/MM/yyyy'}}
+ {{::row.quantity}}
+
+ {{::row.price | currency: 'EUR':2}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/order/front/line/style.scss b/modules/order/front/line/style.scss
index ceef14fa17..4da941a2c9 100644
--- a/modules/order/front/line/style.scss
+++ b/modules/order/front/line/style.scss
@@ -8,20 +8,11 @@ vn-order-line {
height: 50px;
}
}
- .taxes {
- max-width: 10em;
- border: $border-thin-light;
+ .header {
text-align: right;
- padding: .5em !important;
-
- & > p {
- font-size: 1.2em;
- margin: .2em;
+ & > div {
+ margin-bottom: $spacing-xs;
}
}
- vn-horizontal.header {
- justify-content: flex-end;
- margin-bottom: 0.5em;
- }
}
\ No newline at end of file
diff --git a/modules/order/front/prices-popover/index.html b/modules/order/front/prices-popover/index.html
index a88e027ac6..2a6f978fb8 100644
--- a/modules/order/front/prices-popover/index.html
+++ b/modules/order/front/prices-popover/index.html
@@ -1,5 +1,5 @@
-
+
-
-
- {{$ctrl.item.id}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Wrong quantity
-
-
-
-
-
-
-
-
-
-
-
+
+
+
{{$ctrl.item.name}}
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/order/front/prices-popover/index.js b/modules/order/front/prices-popover/index.js
index 3ce4050ce4..40590b8bb8 100644
--- a/modules/order/front/prices-popover/index.js
+++ b/modules/order/front/prices-popover/index.js
@@ -1,24 +1,23 @@
import ngModule from '../module';
+import Component from 'core/lib/component';
import './style.scss';
-class Controller {
- constructor($scope, $http, $timeout, $element, $translate, vnApp) {
- this.$ = $scope;
- this.$timeout = $timeout;
- this.$http = $http;
- this.$element = $element;
- this.$translate = $translate;
- this.vnApp = vnApp;
+class Controller extends Component {
+ constructor($element, $) {
+ super($element, $);
this.totalBasquet = 0;
}
+
set prices(value) {
this._prices = value;
if (value && value[0].grouping)
this.calculateTotal();
}
+
get prices() {
return this._prices;
}
+
getTags() {
let filter = {
where: {itemFk: this.item.id,
@@ -40,6 +39,7 @@ class Controller {
});
});
}
+
show(event, item) {
this.item = JSON.parse(JSON.stringify(item));
this.prices = this.item.prices;
@@ -48,15 +48,18 @@ class Controller {
this.$.popover.show();
this.$.popover.relocate();
}
+
clear() {
this.item = {};
this.tags = {};
this._prices = {};
this.total = 0;
}
+
calculateMax() {
this.max = this.item.available - this.total;
}
+
calculateTotal() {
this.total = 0;
@@ -73,7 +76,9 @@ class Controller {
this.validate();
}
+
validate() {
+ /*
this.$timeout(() => {
this.calculateTotal();
let inputs = this.$element[0].querySelectorAll('vn-input-number[name="quantity"] div.infix:not(.validated)');
@@ -91,7 +96,9 @@ class Controller {
else
this.$element[0].querySelector('vn-vertical.prices').classList.remove('invalid');
});
+ */
}
+
getFilledLines() {
let filledLines = [];
let match;
@@ -110,6 +117,7 @@ class Controller {
});
return filledLines;
}
+
submit() {
this.calculateTotal();
let filledLines = this.getFilledLines();
@@ -128,14 +136,14 @@ class Controller {
this.$http.post(`OrderRows/addToOrder`, params).then(res => {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
this.$.popover.hide();
- this.card.reload();
+
+ if (this.card)
+ this.card.reload();
});
});
}
}
-Controller.$inject = ['$scope', '$http', '$timeout', '$element', '$translate', 'vnApp'];
-
ngModule.component('vnOrderPricesPopover', {
template: require('./index.html'),
controller: Controller,
@@ -143,6 +151,6 @@ ngModule.component('vnOrderPricesPopover', {
order: '<'
},
require: {
- card: '^vnOrderCard'
+ card: '?^vnOrderCard'
}
});
diff --git a/modules/order/front/prices-popover/style.scss b/modules/order/front/prices-popover/style.scss
index a904d16422..150c2296a6 100644
--- a/modules/order/front/prices-popover/style.scss
+++ b/modules/order/front/prices-popover/style.scss
@@ -1,79 +1,44 @@
@import "variables";
-vn-order-prices-popover {
- width: 150px;
+.vn-order-prices-popover {
display: block;
+
img[ng-src] {
height: 100%;
width: 100%;
}
-
- .prices, .data{
- width: 18em;
- }
-
- vn-vertical.data{
+ vn-vertical.data {
padding-right: 16px;
border-right: 1px solid $color-main;
}
-
- vn-vertical.prices{
- padding-left: 16px;
- &.invalid {
- vn-one.error {
- display: block;
- padding-top: 10px;
- color: #d50000;
- text-align: center!important;
+ .prices {
+ vn-table {
+ .warehouse {
+ width: 3em;
+ max-width: 3em;
+ }
+ .price-kg {
+ color: $color-font-secondary;
+ font-size: .8em
+ }
+ .vn-input-number {
+ width: 3.5em;
}
}
+ .footer {
+ text-align: center;
- vn-tr {
- border-bottom: 0
+ .error {
+ display: none;
+ }
+ &.invalid {
+ .error {
+ display: block;
+ padding-top: 10px;
+ color: $color-alert;
+ text-align: center;
+ }
+ }
}
-
- vn-tr > vn-td:first-child {
- vertical-align: top
- }
-
- vn-tr > vn-td:nth-child(3) {
- vertical-align: top;
- padding-top: 0
- }
-
- .priceKg {
- color: $color-font-secondary;
- font-size: .8em
- }
- }
-
- vn-input-number{
- margin: 0!important;
-
- label {
- display: none;
- }
- }
-
- vn-one.number {
- text-align: right;
- padding-right: 8px;
- }
- vn-one.text{
- padding-top:10px!important;
- }
- vn-horizontal.buttons-bar{
- padding-top: 16px;
- text-align: center;
- }
- .quicklinks vn-icon {
- font-size: 1.8em !important;
- padding: 0 !important;
- & > i {
- line-height: 36px
- }
- }
- vn-one.error{
- display: none;
}
}
\ No newline at end of file
diff --git a/modules/order/front/volume/index.html b/modules/order/front/volume/index.html
index e10b366fb2..9dc1b811f0 100644
--- a/modules/order/front/volume/index.html
+++ b/modules/order/front/volume/index.html
@@ -1,59 +1,60 @@
-
+ data="rows"
+ on-data-change="$ctrl.onDataChange()">
-
+
-
+
+
+
+
+ Item
+ Description
+ Quantity
+ m³ per quantity
+
+
+
+
+
+
+ {{::row.itemFk}}
+
+
+
+
+
+
+ {{::row.quantity}}
+ {{::row.volume | number:3}}
+
+
+
+
+
+
+
diff --git a/modules/order/front/volume/style.scss b/modules/order/front/volume/style.scss
index baeabf3833..da13eca0df 100644
--- a/modules/order/front/volume/style.scss
+++ b/modules/order/front/volume/style.scss
@@ -1,8 +1,12 @@
@import "./variables";
-.totalBox {
- border: $border-thin-light;
- text-align: left;
- align-self: flex-end;
+vn-order-volume {
+ .header {
+ text-align: right;
+
+ & > div {
+ margin-bottom: $spacing-xs;
+ }
+ }
}
diff --git a/modules/ticket/front/descriptor/style.scss b/modules/ticket/front/descriptor/style.scss
index 72cb801433..e0abcbc501 100644
--- a/modules/ticket/front/descriptor/style.scss
+++ b/modules/ticket/front/descriptor/style.scss
@@ -20,7 +20,7 @@ vn-dialog.modal-form {
& > div {
padding: 0 !important;
}
- vn-textfield {
+ .vn-textfield {
width: 100%;
}
.buttons {
diff --git a/modules/ticket/front/dms/create/index.js b/modules/ticket/front/dms/create/index.js
index 39c372c9dd..cb39be7dca 100644
--- a/modules/ticket/front/dms/create/index.js
+++ b/modules/ticket/front/dms/create/index.js
@@ -1,5 +1,4 @@
import ngModule from '../../module';
-import './style.scss';
class Controller {
constructor($scope, $http, $state, $translate, vnApp, vnConfig) {
diff --git a/modules/ticket/front/dms/create/style.scss b/modules/ticket/front/dms/create/style.scss
deleted file mode 100644
index b47544b120..0000000000
--- a/modules/ticket/front/dms/create/style.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-vn-ticket-request {
- vn-textfield {
- margin: 0!important;
- max-width: 100px;
- }
-}
-
diff --git a/modules/ticket/front/dms/edit/index.js b/modules/ticket/front/dms/edit/index.js
index 31e797b9c1..9ff9678169 100644
--- a/modules/ticket/front/dms/edit/index.js
+++ b/modules/ticket/front/dms/edit/index.js
@@ -1,5 +1,4 @@
import ngModule from '../../module';
-import './style.scss';
class Controller {
constructor($scope, $http, $state, $translate, vnApp) {
diff --git a/modules/ticket/front/dms/edit/style.scss b/modules/ticket/front/dms/edit/style.scss
deleted file mode 100644
index b47544b120..0000000000
--- a/modules/ticket/front/dms/edit/style.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-vn-ticket-request {
- vn-textfield {
- margin: 0!important;
- max-width: 100px;
- }
-}
-
diff --git a/modules/ticket/front/request/create/style.scss b/modules/ticket/front/request/create/style.scss
index b47544b120..73f136fc15 100644
--- a/modules/ticket/front/request/create/style.scss
+++ b/modules/ticket/front/request/create/style.scss
@@ -1,5 +1,5 @@
vn-ticket-request {
- vn-textfield {
+ .vn-textfield {
margin: 0!important;
max-width: 100px;
}
diff --git a/modules/ticket/front/sale/style.scss b/modules/ticket/front/sale/style.scss
index 2a18e09205..1eb7556e97 100644
--- a/modules/ticket/front/sale/style.scss
+++ b/modules/ticket/front/sale/style.scss
@@ -29,7 +29,7 @@ vn-ticket-sale {
&>div{
padding: 0!important;
}
- vn-textfield {
+ .vn-textfield {
width: 100%;
}
.buttons{
@@ -55,7 +55,7 @@ vn-ticket-sale {
}
}
.vn-popover .transfer {
- vn-textfield {
+ .vn-textfield {
margin: 0
}
vn-horizontal {
diff --git a/modules/ticket/front/services/index.html b/modules/ticket/front/services/index.html
index d9059e8e51..17b7eaebad 100644
--- a/modules/ticket/front/services/index.html
+++ b/modules/ticket/front/services/index.html
@@ -82,7 +82,8 @@
+ ng-model="$ctrl.newServiceType.name"
+ vn-focus>
diff --git a/modules/ticket/front/services/index.js b/modules/ticket/front/services/index.js
index d070740f6c..3082878a6d 100644
--- a/modules/ticket/front/services/index.js
+++ b/modules/ticket/front/services/index.js
@@ -42,8 +42,6 @@ class Controller {
onNewServiceTypeOpen() {
this.newServiceType = {};
- this.nameInput = this.$element[0].querySelector('.edit input');
- this.nameInput.focus();
}
newServiceTypeDialog(elementIndex, event) {