Tests fixed

This commit is contained in:
Juan Ferrer 2019-10-18 21:36:30 +02:00
parent dbe6161c69
commit 457034daad
133 changed files with 1259 additions and 1702 deletions

View File

@ -1,6 +0,0 @@
export default {
vnTextfield: 'vn-textfield input',
vnInputNumber: 'vn-input-number input',
vnSubmit: 'vn-submit > input',
vnFloatButton: 'vn-float-button > button'
};

View File

@ -15,6 +15,16 @@ let asyncActions = {
return exists; 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());
},
// Salix specific extensions // Salix specific extensions
changeLanguageToEnglish: async function() { changeLanguageToEnglish: async function() {
@ -28,6 +38,15 @@ let asyncActions = {
await this.autocompleteSearch(langSelector, 'English'); await this.autocompleteSearch(langSelector, 'English');
}, },
doLogin: async function(userName, password) {
if (password == null) password = 'nightmare';
await this.wait(`vn-login [name=user]`)
.clearInput(`vn-login [name=user]`)
.write(`vn-login [name=user]`, userName)
.write(`vn-login [name=password]`, password)
.click(`vn-login button[type=submit]`);
},
login: async function(userName) { login: async function(userName) {
if (currentUser !== userName) { if (currentUser !== userName) {
let logoutClicked = await this.clickIfExists('#logout'); let logoutClicked = await this.clickIfExists('#logout');
@ -47,11 +66,7 @@ let asyncActions = {
this.goto(`${config.url}/#!/login`); this.goto(`${config.url}/#!/login`);
} }
await this.wait(`vn-login input[name=user]`) await this.doLogin(userName, null)
.clearInput(`vn-login input[name=user]`)
.write(`vn-login input[name=user]`, userName)
.write(`vn-login input[name=password]`, 'nightmare')
.click(`vn-login input[type=submit]`)
.waitForURL('#!/') .waitForURL('#!/')
.changeLanguageToEnglish(); .changeLanguageToEnglish();
@ -99,6 +114,10 @@ let asyncActions = {
input.value = time; input.value = time;
input.dispatchEvent(new Event('change')); input.dispatchEvent(new Event('change'));
}, selector, time); }, selector, time);
},
isDisabled: async function(selector) {
return await this.hasClass(selector, 'disabled');
} }
}; };
@ -124,21 +143,6 @@ let actions = {
.catch(done); .catch(done);
}, },
resetLogin: function(done) {
this.then(() => {
currentUser = undefined;
done();
})
.catch(done);
},
parsedUrl: function(done) {
this.url()
.then(url => {
done(null, new URL(url));
}).catch(done);
},
getProperty: function(selector, property, done) { getProperty: function(selector, property, done) {
this.evaluate_now((selector, property) => { this.evaluate_now((selector, property) => {
return document.querySelector(selector)[property].replace(/\s+/g, ' ').trim(); return document.querySelector(selector)[property].replace(/\s+/g, ' ').trim();

View File

@ -1,4 +1,3 @@
import components from './components_selectors.js';
export default { export default {
globalItems: { globalItems: {
@ -22,29 +21,29 @@ export default {
acceptButton: 'vn-confirm button[response=ACCEPT]' acceptButton: 'vn-confirm button[response=ACCEPT]'
}, },
clientsIndex: { clientsIndex: {
searchClientInput: `${components.vnTextfield}`, searchClientInput: `vn-textfield input`,
searchButton: 'vn-searchbar vn-icon[icon="search"]', searchButton: 'vn-searchbar vn-icon[icon="search"]',
searchResult: 'vn-client-index .vn-list-item', searchResult: 'vn-client-index .vn-list-item',
createClientButton: `${components.vnFloatButton}`, createClientButton: `vn-float-button`,
othersButton: 'vn-left-menu li[name="Others"] > a' othersButton: 'vn-left-menu li[name="Others"] > a'
}, },
createClientView: { createClientView: {
name: `${components.vnTextfield}[name="name"]`, name: `vn-textfield input[name="name"]`,
taxNumber: `${components.vnTextfield}[name="fi"]`, taxNumber: `vn-textfield input[name="fi"]`,
socialName: `${components.vnTextfield}[name="socialName"]`, socialName: `vn-textfield input[name="socialName"]`,
street: `${components.vnTextfield}[name="street"]`, street: `vn-textfield input[name="street"]`,
postcode: `${components.vnTextfield}[name="postcode"]`, postcode: `vn-textfield input[name="postcode"]`,
city: `${components.vnTextfield}[name="city"]`, city: `vn-textfield input[name="city"]`,
province: `vn-autocomplete[ng-model="$ctrl.client.provinceFk"]`, province: `vn-autocomplete[ng-model="$ctrl.client.provinceFk"]`,
country: `vn-autocomplete[ng-model="$ctrl.client.countryFk"]`, country: `vn-autocomplete[ng-model="$ctrl.client.countryFk"]`,
userName: `${components.vnTextfield}[name="userName"]`, userName: `vn-textfield input[name="userName"]`,
email: `${components.vnTextfield}[name="email"]`, email: `vn-textfield input[name="email"]`,
salesPersonAutocomplete: `vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]`, salesPersonAutocomplete: `vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]`,
createButton: `${components.vnSubmit}`, createButton: `button[type=submit]`,
cancelButton: 'vn-button[href="#!/client/index"]' cancelButton: 'vn-button[href="#!/client/index"]'
}, },
clientDescriptor: { clientDescriptor: {
moreMenu: 'vn-client-descriptor vn-icon-menu > div > vn-icon', moreMenu: 'vn-client-descriptor vn-icon-menu[icon=more_vert]',
simpleTicketButton: '.vn-popover.shown .vn-drop-down li' simpleTicketButton: '.vn-popover.shown .vn-drop-down li'
}, },
clientBasicData: { clientBasicData: {
@ -56,17 +55,17 @@ export default {
emailInput: 'vn-textfield[ng-model="$ctrl.client.email"] input', emailInput: 'vn-textfield[ng-model="$ctrl.client.email"] input',
salesPersonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]', salesPersonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
channelAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.contactChannelFk"]', channelAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.contactChannelFk"]',
saveButton: `${components.vnSubmit}` saveButton: `button[type=submit]`
}, },
clientFiscalData: { clientFiscalData: {
fiscalDataButton: 'vn-left-menu a[ui-sref="client.card.fiscalData"]', fiscalDataButton: 'vn-left-menu a[ui-sref="client.card.fiscalData"]',
socialNameInput: `${components.vnTextfield}[name="socialName"]`, socialNameInput: `vn-textfield input[name="socialName"]`,
fiscalIdInput: `${components.vnTextfield}[name="fi"]`, fiscalIdInput: `vn-textfield input[name="fi"]`,
equalizationTaxCheckbox: 'vn-check[label="Is equalizated"]', equalizationTaxCheckbox: 'vn-check[label="Is equalizated"]',
acceptPropagationButton: 'vn-client-fiscal-data > vn-confirm button[response=ACCEPT]', acceptPropagationButton: 'vn-client-fiscal-data > vn-confirm button[response=ACCEPT]',
addressInput: `${components.vnTextfield}[name="street"]`, addressInput: `vn-textfield input[name="street"]`,
postcodeInput: `${components.vnTextfield}[name="postcode"]`, postcodeInput: `vn-textfield input[name="postcode"]`,
cityInput: `${components.vnTextfield}[name="city"]`, cityInput: `vn-textfield input[name="city"]`,
provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.provinceFk"]', provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.provinceFk"]',
countryAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.countryFk"]', countryAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.countryFk"]',
activeCheckbox: 'vn-check[label="Active"]', activeCheckbox: 'vn-check[label="Active"]',
@ -76,12 +75,12 @@ export default {
hasToInvoiceCheckbox: 'vn-check[label="Has to invoice"]', hasToInvoiceCheckbox: 'vn-check[label="Has to invoice"]',
invoiceByMailCheckbox: 'vn-check[label="Invoice by mail"]', invoiceByMailCheckbox: 'vn-check[label="Invoice by mail"]',
viesCheckbox: 'vn-check[label="Vies"]', viesCheckbox: 'vn-check[label="Vies"]',
saveButton: `${components.vnSubmit}` saveButton: `button[type=submit]`
}, },
clientBillingData: { clientBillingData: {
payMethodAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.payMethodFk"]', payMethodAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.payMethodFk"]',
IBANInput: `vn-client-billing-data ${components.vnTextfield}[name="iban"]`, IBANInput: `vn-client-billing-data vn-textfield input[name="iban"]`,
dueDayInput: `vn-client-billing-data ${components.vnInputNumber}[name="dueDay"]`, dueDayInput: `vn-client-billing-data vn-input-number input[name="dueDay"]`,
receivedCoreLCRCheckbox: 'vn-client-billing-data vn-check[label="Received LCR"]', receivedCoreLCRCheckbox: 'vn-client-billing-data vn-check[label="Received LCR"]',
receivedCoreVNLCheckbox: 'vn-client-billing-data vn-check[label="Received core VNL"]', receivedCoreVNLCheckbox: 'vn-client-billing-data vn-check[label="Received core VNL"]',
receivedB2BVNLCheckbox: 'vn-client-billing-data vn-check[label="Received B2B VNL"]', receivedB2BVNLCheckbox: 'vn-client-billing-data vn-check[label="Received B2B VNL"]',
@ -92,20 +91,20 @@ export default {
newBankEntityBIC: 'vn-client-billing-data > vn-dialog vn-textfield[label="Swift / BIC"] 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', newBankEntityCode: 'vn-client-billing-data > vn-dialog vn-textfield[label="Entity Code"] input',
acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]', acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]',
saveButton: `${components.vnSubmit}` saveButton: `button[type=submit]`
}, },
clientAddresses: { clientAddresses: {
addressesButton: 'vn-left-menu a[ui-sref="client.card.address.index"]', addressesButton: 'vn-left-menu a[ui-sref="client.card.address.index"]',
createAddress: `vn-client-address-index ${components.vnFloatButton}`, createAddress: `vn-client-address-index vn-float-button`,
defaultCheckboxInput: 'vn-check[label="Default"]', defaultCheckboxInput: 'vn-check[label="Default"]',
consigneeInput: `${components.vnTextfield}[name="nickname"]`, consigneeInput: `vn-textfield input[name="nickname"]`,
streetAddressInput: `${components.vnTextfield}[name="street"]`, streetAddressInput: `vn-textfield input[name="street"]`,
postcodeInput: `${components.vnTextfield}[name="postalCode"]`, postcodeInput: `vn-textfield input[name="postalCode"]`,
cityInput: `${components.vnTextfield}[name="city"]`, cityInput: `vn-textfield input[name="city"]`,
provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.provinceFk"]', provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.provinceFk"]',
agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.agencyModeFk"]', agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.agencyModeFk"]',
phoneInput: `${components.vnTextfield}[name="phone"]`, phoneInput: `vn-textfield input[name="phone"]`,
mobileInput: `${components.vnTextfield}[name="mobile"]`, mobileInput: `vn-textfield input[name="mobile"]`,
defaultAddress: 'vn-client-address-index div:nth-child(1) div[name="street"]', defaultAddress: 'vn-client-address-index div:nth-child(1) div[name="street"]',
secondMakeDefaultStar: 'vn-client-address-index vn-card div:nth-child(2) vn-icon-button[icon="star_border"]', secondMakeDefaultStar: 'vn-client-address-index vn-card div:nth-child(2) vn-icon-button[icon="star_border"]',
firstEditAddress: 'vn-client-address-index div:nth-child(1) > a', firstEditAddress: 'vn-client-address-index div:nth-child(1) > a',
@ -117,34 +116,34 @@ export default {
secondObservationTypeAutocomplete: 'vn-client-address-edit [name=observations] :nth-child(2) [ng-model="observation.observationTypeFk"]', secondObservationTypeAutocomplete: 'vn-client-address-edit [name=observations] :nth-child(2) [ng-model="observation.observationTypeFk"]',
secondObservationDescriptionInput: 'vn-client-address-edit [name=observations] :nth-child(2) [ng-model="observation.description"] input', secondObservationDescriptionInput: 'vn-client-address-edit [name=observations] :nth-child(2) [ng-model="observation.description"] input',
addObservationButton: 'vn-client-address-edit div[name="observations"] vn-icon-button[icon="add_circle"]', addObservationButton: 'vn-client-address-edit div[name="observations"] vn-icon-button[icon="add_circle"]',
saveButton: `${components.vnSubmit}`, saveButton: `button[type=submit]`,
cancelCreateAddressButton: 'button[ui-sref="client.card.address.index"]', cancelCreateAddressButton: 'button[ui-sref="client.card.address.index"]',
cancelEditAddressButton: 'vn-client-address-edit > form > vn-button-bar > vn-button > button' cancelEditAddressButton: 'vn-client-address-edit > form > vn-button-bar > vn-button > button'
}, },
clientWebAccess: { clientWebAccess: {
webAccessButton: 'vn-left-menu a[ui-sref="client.card.webAccess"]', webAccessButton: 'vn-left-menu a[ui-sref="client.card.webAccess"]',
enableWebAccessCheckbox: 'vn-check[label="Enable web access"]', enableWebAccessCheckbox: 'vn-check[label="Enable web access"]',
userNameInput: `${components.vnTextfield}[name="name"]`, userNameInput: `vn-textfield input[name="name"]`,
saveButton: `${components.vnSubmit}` saveButton: `button[type=submit]`
}, },
clientNotes: { clientNotes: {
addNoteFloatButton: `${components.vnFloatButton}`, addNoteFloatButton: `vn-float-button`,
noteInput: 'vn-textarea[label="Note"]', noteInput: 'vn-textarea[label="Note"]',
saveButton: `${components.vnSubmit}`, saveButton: `button[type=submit]`,
firstNoteText: 'vn-client-note .text' firstNoteText: 'vn-client-note .text'
}, },
clientCredit: { clientCredit: {
addCreditFloatButton: `${components.vnFloatButton}`, addCreditFloatButton: `vn-float-button`,
creditInput: `${components.vnInputNumber}[name="credit"]`, creditInput: `vn-input-number input[name="credit"]`,
saveButton: `${components.vnSubmit}`, saveButton: `button[type=submit]`,
firstCreditText: 'vn-client-credit-index vn-card > div vn-table vn-tbody > vn-tr' firstCreditText: 'vn-client-credit-index vn-card > div vn-table vn-tbody > vn-tr'
}, },
clientGreuge: { clientGreuge: {
addGreugeFloatButton: `${components.vnFloatButton}`, addGreugeFloatButton: `vn-float-button`,
amountInput: `${components.vnInputNumber}[name="amount"]`, amountInput: `vn-input-number input[name="amount"]`,
descriptionInput: `${components.vnTextfield}[name="description"]`, descriptionInput: `vn-textfield input[name="description"]`,
typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.greuge.greugeTypeFk"]', typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.greuge.greugeTypeFk"]',
saveButton: `${components.vnSubmit}`, saveButton: `button[type=submit]`,
firstGreugeText: 'vn-client-greuge-index vn-card > div vn-table vn-tbody > vn-tr' firstGreugeText: 'vn-client-greuge-index vn-card > div vn-table vn-tbody > vn-tr'
}, },
clientMandate: { clientMandate: {
@ -163,7 +162,7 @@ export default {
clientBalance: { clientBalance: {
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]', balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyFk"]', companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyFk"]',
newPaymentButton: `${components.vnFloatButton}`, newPaymentButton: `vn-float-button`,
newPaymentBank: 'vn-client-balance-create vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]', 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', newPaymentAmountInput: 'vn-client-balance-create vn-input-number[ng-model="$ctrl.receipt.amountPaid"] input',
saveButton: 'vn-client-balance-create vn-button[label="Save"]', saveButton: 'vn-client-balance-create vn-button[label="Save"]',
@ -182,7 +181,7 @@ export default {
}, },
itemsIndex: { itemsIndex: {
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]', searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
createItemButton: `${components.vnFloatButton}`, createItemButton: `vn-float-button`,
searchResult: 'vn-item-index a.vn-tr', searchResult: 'vn-item-index a.vn-tr',
searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]', searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]',
searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]',
@ -208,16 +207,16 @@ export default {
saveFieldsButton: 'vn-item-index vn-dialog vn-horizontal:nth-child(16) > vn-button > button' saveFieldsButton: 'vn-item-index vn-dialog vn-horizontal:nth-child(16) > vn-button > button'
}, },
itemCreateView: { itemCreateView: {
temporalName: `${components.vnTextfield}[name="provisionalName"]`, temporalName: `vn-textfield input[name="provisionalName"]`,
typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.typeFk"]', typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.typeFk"]',
intrastatAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.intrastatFk"]', intrastatAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.intrastatFk"]',
originAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]', originAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]',
createButton: `${components.vnSubmit}`, createButton: `button[type=submit]`,
cancelButton: 'button[ui-sref="item.index"]' cancelButton: 'vn-button[ui-sref="item.index"]'
}, },
itemDescriptor: { itemDescriptor: {
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]', goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
moreMenu: 'vn-item-descriptor vn-icon-menu > div > vn-icon', moreMenu: 'vn-item-descriptor vn-icon-menu[icon=more_vert]',
moreMenuRegularizeButton: '.vn-popover.shown .vn-drop-down li[name="Regularize stock"]', moreMenuRegularizeButton: '.vn-popover.shown .vn-drop-down li[name="Regularize stock"]',
regularizeQuantityInput: 'vn-item-descriptor vn-dialog tpl-body > div > vn-textfield input', regularizeQuantityInput: 'vn-item-descriptor vn-dialog tpl-body > div > vn-textfield input',
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[ng-model="$ctrl.warehouseFk"]', regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
@ -238,7 +237,7 @@ export default {
longNameInput: 'vn-textfield[ng-model="$ctrl.item.longName"] input', longNameInput: 'vn-textfield[ng-model="$ctrl.item.longName"] input',
isActiveCheckbox: 'vn-check[label="Active"]', isActiveCheckbox: 'vn-check[label="Active"]',
priceInKgCheckbox: 'vn-check[label="Price in kg"]', priceInKgCheckbox: 'vn-check[label="Price in kg"]',
submitBasicDataButton: `${components.vnSubmit}` submitBasicDataButton: `button[type=submit]`
}, },
itemTags: { itemTags: {
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]', goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
@ -257,19 +256,19 @@ export default {
seventhValueInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Value"] input', seventhValueInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Value"] input',
seventhRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Relevancy"] input', seventhRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Relevancy"] input',
addItemTagButton: 'vn-item-tags vn-icon-button[icon="add_circle"]', addItemTagButton: 'vn-item-tags vn-icon-button[icon="add_circle"]',
submitItemTagsButton: `vn-item-tags ${components.vnSubmit}` submitItemTagsButton: `vn-item-tags button[type=submit]`
}, },
itemTax: { itemTax: {
undoChangesButton: 'vn-item-tax vn-button-bar > vn-button[label="Undo changes"]', undoChangesButton: 'vn-item-tax vn-button-bar > vn-button[label="Undo changes"]',
firstClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(1) > vn-autocomplete[ng-model="tax.taxClassFk"]', firstClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(1) > vn-autocomplete[ng-model="tax.taxClassFk"]',
secondClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(2) > vn-autocomplete[ng-model="tax.taxClassFk"]', secondClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(2) > vn-autocomplete[ng-model="tax.taxClassFk"]',
thirdClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="tax.taxClassFk"]', thirdClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="tax.taxClassFk"]',
submitTaxButton: `vn-item-tax ${components.vnSubmit}` submitTaxButton: `vn-item-tax button[type=submit]`
}, },
itemBarcodes: { itemBarcodes: {
addBarcodeButton: 'vn-item-barcode vn-icon[icon="add_circle"]', addBarcodeButton: 'vn-item-barcode vn-icon[icon="add_circle"]',
thirdCodeInput: `vn-item-barcode vn-horizontal:nth-child(3) > ${components.vnTextfield}`, thirdCodeInput: `vn-item-barcode vn-horizontal:nth-child(3) > vn-textfield input`,
submitBarcodesButton: `vn-item-barcode ${components.vnSubmit}`, submitBarcodesButton: `vn-item-barcode button[type=submit]`,
firstCodeRemoveButton: 'vn-item-barcode vn-horizontal vn-none vn-icon[icon="delete"]' firstCodeRemoveButton: 'vn-item-barcode vn-horizontal vn-none vn-icon[icon="delete"]'
}, },
itemNiches: { itemNiches: {
@ -281,13 +280,13 @@ export default {
secondNicheRemoveButton: 'vn-item-niche vn-horizontal:nth-child(2) > vn-none > vn-icon-button[icon="delete"]', secondNicheRemoveButton: 'vn-item-niche vn-horizontal:nth-child(2) > vn-none > vn-icon-button[icon="delete"]',
thirdWarehouseAutocomplete: 'vn-item-niche vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="niche.warehouseFk"]', thirdWarehouseAutocomplete: 'vn-item-niche vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="niche.warehouseFk"]',
thirdCodeInput: 'vn-item-niche vn-horizontal:nth-child(3) > vn-textfield[label="Code"] input', thirdCodeInput: 'vn-item-niche vn-horizontal:nth-child(3) > vn-textfield[label="Code"] input',
submitNichesButton: `vn-item-niche ${components.vnSubmit}` submitNichesButton: `vn-item-niche button[type=submit]`
}, },
itemBotanical: { itemBotanical: {
botanicalInput: `vn-item-botanical vn-horizontal:nth-child(1) > ${components.vnTextfield}`, botanicalInput: `vn-item-botanical vn-horizontal:nth-child(1) > vn-textfield input`,
genusAutocomplete: 'vn-item-botanical vn-autocomplete[ng-model="$ctrl.botanical.genusFk"]', genusAutocomplete: 'vn-item-botanical vn-autocomplete[ng-model="$ctrl.botanical.genusFk"]',
speciesAutocomplete: 'vn-item-botanical vn-autocomplete[ng-model="$ctrl.botanical.specieFk"]', speciesAutocomplete: 'vn-item-botanical vn-autocomplete[ng-model="$ctrl.botanical.specieFk"]',
submitBotanicalButton: `vn-item-botanical ${components.vnSubmit}` submitBotanicalButton: `vn-item-botanical button[type=submit]`
}, },
itemSummary: { itemSummary: {
basicData: 'vn-item-summary [name="basicData"]', basicData: 'vn-item-summary [name="basicData"]',
@ -330,13 +329,13 @@ export default {
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr', searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr', searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr',
searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)', searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)',
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`, searchTicketInput: `vn-ticket-index vn-textfield input`,
searchWeeklyTicketInput: `vn-ticket-weekly-index ${components.vnTextfield}`, searchWeeklyTicketInput: `vn-ticket-weekly-index vn-textfield input`,
searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon=clear]', searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon=clear]',
advancedSearchButton: 'vn-ticket-search-panel vn-submit[label="Search"] input', advancedSearchButton: 'vn-ticket-search-panel button[type=submit]',
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]', searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
searchWeeklyButton: 'vn-ticket-weekly-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[vn-id="more-button"] > div > vn-icon', moreMenu: 'vn-ticket-index vn-icon-menu[icon=more_vert]',
moreMenuWeeklyTickets: '.vn-popover.shown .vn-drop-down li:nth-child(2)', moreMenuWeeklyTickets: '.vn-popover.shown .vn-drop-down li:nth-child(2)',
sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[ng-model="weekly.weekDay"] input', 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', weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr',
@ -349,13 +348,13 @@ export default {
deliveryDateInput: 'vn-ticket-create vn-date-picker[ng-model="$ctrl.landed"]', deliveryDateInput: 'vn-ticket-create vn-date-picker[ng-model="$ctrl.landed"]',
warehouseAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.warehouseFk"]', warehouseAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
agencyAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.ticket.agencyModeFk"]', agencyAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.ticket.agencyModeFk"]',
createButton: `${components.vnSubmit}` createButton: `button[type=submit]`
}, },
ticketDescriptor: { ticketDescriptor: {
idLabelValue: 'vn-ticket-descriptor vn-label-value[label="Id"]', idLabelValue: 'vn-ticket-descriptor vn-label-value[label="Id"]',
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]', stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]', goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
moreMenu: 'vn-ticket-descriptor vn-icon-menu > div > vn-icon', moreMenu: 'vn-ticket-descriptor vn-icon-menu[icon=more_vert]',
moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]', moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]',
moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]', moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]',
moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]', moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]',
@ -365,7 +364,7 @@ export default {
changeShippedHourDialog: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"]', changeShippedHourDialog: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"]',
changeShippedHourInput: 'vn-dialog[vn-id="changeShippedDialog"] [ng-model="$ctrl.newShipped"]', 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', addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]', 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)', 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)', 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"]', closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
@ -380,7 +379,7 @@ export default {
addNoteButton: 'vn-icon[icon="add_circle"]', addNoteButton: 'vn-icon[icon="add_circle"]',
firstNoteTypeAutocomplete: 'vn-autocomplete[ng-model="observation.observationTypeFk"]', firstNoteTypeAutocomplete: 'vn-autocomplete[ng-model="observation.observationTypeFk"]',
firstDescriptionInput: 'vn-textfield[label="Description"] input', firstDescriptionInput: 'vn-textfield[label="Description"] input',
submitNotesButton: `${components.vnSubmit}` submitNotesButton: `button[type=submit]`
}, },
ticketExpedition: { ticketExpedition: {
expeditionButton: 'vn-left-menu a[ui-sref="ticket.card.expedition"]', expeditionButton: 'vn-left-menu a[ui-sref="ticket.card.expedition"]',
@ -395,7 +394,7 @@ export default {
firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]', firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]',
addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]', addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]',
clearPackageAutocompleteButton: 'vn-autocomplete[label="Package"] .icons > vn-icon[icon=clear]', clearPackageAutocompleteButton: 'vn-autocomplete[label="Package"] .icons > vn-icon[icon=clear]',
savePackagesButton: `${components.vnSubmit}` savePackagesButton: `button[type=submit]`
}, },
ticketSales: { ticketSales: {
saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]', saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]',
@ -460,9 +459,9 @@ export default {
}, },
ticketTracking: { ticketTracking: {
trackingButton: 'vn-left-menu a[ui-sref="ticket.card.tracking.index"]', trackingButton: 'vn-left-menu a[ui-sref="ticket.card.tracking.index"]',
createStateButton: `${components.vnFloatButton}`, createStateButton: `vn-float-button`,
stateAutocomplete: 'vn-ticket-tracking-edit vn-autocomplete[ng-model="$ctrl.stateFk"]', stateAutocomplete: 'vn-ticket-tracking-edit vn-autocomplete[ng-model="$ctrl.stateFk"]',
saveButton: `${components.vnSubmit}`, saveButton: `button[type=submit]`,
cancelButton: 'vn-ticket-tracking-edit vn-button[ui-sref="ticket.card.tracking.index"]' cancelButton: 'vn-ticket-tracking-edit vn-button[ui-sref="ticket.card.tracking.index"]'
}, },
ticketBasicData: { ticketBasicData: {
@ -471,8 +470,8 @@ export default {
addressAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.addressFk"]', addressAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.addressFk"]',
agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.agencyModeId"]', agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.agencyModeId"]',
zoneAutocomplete: 'vn-autocomplete[ng-model="$ctrl.zoneId"]', zoneAutocomplete: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
nextStepButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-button', nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
finalizeButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit', finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]',
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)', stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
chargesReasonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.option"]', chargesReasonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.option"]',
}, },
@ -487,7 +486,7 @@ export default {
quantityInput: 'vn-ticket-request-create vn-input-number input[name=quantity]', quantityInput: 'vn-ticket-request-create vn-input-number input[name=quantity]',
priceInput: 'vn-ticket-request-create vn-input-number input[name=price]', priceInput: 'vn-ticket-request-create vn-input-number input[name=price]',
firstRemoveRequestButton: 'vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)', firstRemoveRequestButton: 'vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)',
saveButton: 'vn-ticket-request-create > form > div > vn-button-bar > vn-submit[label="Create"] input', saveButton: 'vn-ticket-request-create button[type=submit]',
firstDescription: 'vn-ticket-request-index vn-table vn-tr:nth-child(1) > vn-td:nth-child(2)', firstDescription: 'vn-ticket-request-index vn-table vn-tr:nth-child(1) > vn-td:nth-child(2)',
}, },
@ -499,7 +498,7 @@ export default {
}, },
ticketService: { ticketService: {
addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button', addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button',
firstAddDescriptionButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"] > button', firstAddDescriptionButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"]',
firstDescriptionAutocomplete: 'vn-ticket-service vn-autocomplete[ng-model="service.description"]', firstDescriptionAutocomplete: 'vn-ticket-service vn-autocomplete[ng-model="service.description"]',
firstQuantityInput: 'vn-ticket-service vn-input-number[label="Quantity"] input', firstQuantityInput: 'vn-ticket-service vn-input-number[label="Quantity"] input',
firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input', firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input',
@ -507,22 +506,22 @@ export default {
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]', 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-ticket-service > vn-dialog vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
serviceLine: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(2) > vn-horizontal', serviceLine: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(2) > vn-horizontal',
saveServiceButton: `${components.vnSubmit}`, saveServiceButton: `button[type=submit]`,
saveDescriptionButton: 'vn-ticket-service > vn-dialog[vn-id="createServiceTypeDialog"] > div > form > div.buttons > tpl-buttons > button' saveDescriptionButton: 'vn-ticket-service > vn-dialog[vn-id="createServiceTypeDialog"] > div > form > div.buttons > tpl-buttons > button'
}, },
createStateView: { createStateView: {
stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]', stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
workerAutocomplete: 'vn-autocomplete[ng-model="$ctrl.workerFk"]', workerAutocomplete: 'vn-autocomplete[ng-model="$ctrl.workerFk"]',
clearStateInputButton: 'vn-autocomplete[ng-model="$ctrl.stateFk"] .icons > vn-icon[icon=clear]', clearStateInputButton: 'vn-autocomplete[ng-model="$ctrl.stateFk"] .icons > vn-icon[icon=clear]',
saveStateButton: `${components.vnSubmit}` saveStateButton: `button[type=submit]`
}, },
claimsIndex: { claimsIndex: {
searchClaimInput: `vn-claim-index ${components.vnTextfield}`, searchClaimInput: `vn-claim-index vn-textfield input`,
searchResult: 'vn-claim-index vn-card > div > vn-table > div > vn-tbody > a', searchResult: 'vn-claim-index vn-card > div > vn-table > div > vn-tbody > a',
searchButton: 'vn-claim-index vn-searchbar vn-icon[icon="search"]' searchButton: 'vn-claim-index vn-searchbar vn-icon[icon="search"]'
}, },
claimDescriptor: { claimDescriptor: {
moreMenu: 'vn-claim-descriptor vn-icon-menu[vn-id="more-button"]', moreMenu: 'vn-claim-descriptor vn-icon-menu[icon=more_vert]',
moreMenuDeleteClaim: '.vn-popover.shown .vn-drop-down li[name="Delete claim"]', 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"]' acceptDeleteClaim: 'vn-claim-descriptor > vn-confirm[vn-id="confirm-delete-claim"] button[response="ACCEPT"]'
}, },
@ -541,9 +540,9 @@ export default {
}, },
claimBasicData: { claimBasicData: {
claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[ng-model="$ctrl.claim.claimStateFk"]', claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[ng-model="$ctrl.claim.claimStateFk"]',
responsabilityInputRange: 'vn-input-range', responsabilityInputRange: 'vn-range',
observationInput: 'vn-textarea[ng-model="$ctrl.claim.observation"] textarea', observationInput: 'vn-textarea[ng-model="$ctrl.claim.observation"] textarea',
saveButton: `${components.vnSubmit}` saveButton: `button[type=submit]`
}, },
claimDetail: { claimDetail: {
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span', secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
@ -569,7 +568,7 @@ export default {
secondClaimResponsibleAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]', secondClaimResponsibleAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
secondClaimWorkerAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.workerFk"]', secondClaimWorkerAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.workerFk"]',
secondClaimRedeliveryAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]', secondClaimRedeliveryAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
saveDevelopmentButton: `${components.vnSubmit}` saveDevelopmentButton: `button[type=submit]`
}, },
claimAction: { claimAction: {
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]', importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
@ -584,9 +583,9 @@ export default {
searchResult: 'vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr', searchResult: 'vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
searchResultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)', searchResultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)',
searchResultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)', searchResultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)',
searchOrderInput: `vn-order-index ${components.vnTextfield}`, searchOrderInput: `vn-order-index vn-textfield input`,
searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]', searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]',
createOrderButton: `${components.vnFloatButton}`, createOrderButton: `vn-float-button`,
}, },
orderDescriptor: { orderDescriptor: {
returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]', returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]',
@ -597,7 +596,7 @@ export default {
addressAutocomplete: 'vn-autocomplete[label="Address"]', addressAutocomplete: 'vn-autocomplete[label="Address"]',
agencyAutocomplete: 'vn-autocomplete[label="Agency"]', agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
landedDatePicker: 'vn-date-picker[label="Landed"]', landedDatePicker: 'vn-date-picker[label="Landed"]',
createButton: `${components.vnSubmit}`, createButton: `button[type=submit]`,
cancelButton: 'vn-button[href="#!/client/index"]' cancelButton: 'vn-button[href="#!/client/index"]'
}, },
orderCatalog: { orderCatalog: {
@ -609,16 +608,16 @@ export default {
openTagSearch: 'vn-catalog-filter > div > vn-vertical > vn-textfield[ng-model="$ctrl.value"] .append i', openTagSearch: 'vn-catalog-filter > div > vn-vertical > vn-textfield[ng-model="$ctrl.value"] .append i',
tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[ng-model="filter.tagFk"]', tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[ng-model="filter.tagFk"]',
tagValueInput: 'vn-order-catalog-search-panel vn-textfield[ng-model="filter.value"] input', tagValueInput: 'vn-order-catalog-search-panel vn-textfield[ng-model="filter.value"] input',
searchTagButton: 'vn-order-catalog-search-panel > div > form > vn-horizontal:nth-child(3) > vn-submit > input', searchTagButton: 'vn-order-catalog-search-panel button[type=submit]',
thirdFilterRemoveButton: 'vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(3) button', thirdFilterRemoveButton: 'vn-catalog-filter .chips > vn-chip:nth-child(3) vn-icon[icon=cancel]',
fourthFilterRemoveButton: 'vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(4) button', fourthFilterRemoveButton: 'vn-catalog-filter .chips > vn-chip:nth-child(4) vn-icon[icon=cancel]',
}, },
orderBasicData: { orderBasicData: {
clientAutocomplete: 'vn-autocomplete[label="Client"]', clientAutocomplete: 'vn-autocomplete[label="Client"]',
addressAutocomplete: 'vn-autocomplete[label="Address"]', addressAutocomplete: 'vn-autocomplete[label="Address"]',
agencyAutocomplete: 'vn-autocomplete[label="Agency"]', agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
observationInput: 'vn-textarea[label="Observation"] textarea', observationInput: 'vn-textarea[label="Observation"] textarea',
saveButton: `${components.vnSubmit}`, saveButton: `button[type=submit]`,
acceptButton: 'vn-order-basic-data vn-confirm[vn-id="confirm"] button[response="ACCEPT"]' acceptButton: 'vn-order-basic-data vn-confirm[vn-id="confirm"] button[response="ACCEPT"]'
}, },
orderLine: { orderLine: {
@ -636,7 +635,7 @@ export default {
vehicleAutoComplete: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.vehicleFk"]', vehicleAutoComplete: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.vehicleFk"]',
agencyAutoComplete: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.agencyModeFk"]', agencyAutoComplete: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.agencyModeFk"]',
descriptionInput: 'vn-route-create vn-textfield[ng-model="$ctrl.route.description"] input', descriptionInput: 'vn-route-create vn-textfield[ng-model="$ctrl.route.description"] input',
submitButton: 'vn-route-create vn-submit > input[type="submit"]' submitButton: 'vn-route-create button[type=submit]'
}, },
routeDescriptor: { routeDescriptor: {
volume: 'vn-route-descriptor vn-label-value[label="Volume"] > section > span' volume: 'vn-route-descriptor vn-label-value[label="Volume"] > section > span'
@ -653,7 +652,7 @@ export default {
createdDateInput: 'vn-route-basic-data vn-date-picker[ng-model="$ctrl.route.created"]', createdDateInput: 'vn-route-basic-data vn-date-picker[ng-model="$ctrl.route.created"]',
startedHourInput: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.started"] input', startedHourInput: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.started"] input',
finishedHourInput: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.finished"] input', finishedHourInput: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.finished"] input',
saveButton: 'vn-route-basic-data vn-submit[label="Save"] input' saveButton: 'vn-route-basic-data button[type=submit]'
}, },
routeTickets: { routeTickets: {
firstTicketPriority: 'vn-route-tickets vn-tr:nth-child(1) vn-textfield[ng-model="ticket.priority"] input', firstTicketPriority: 'vn-route-tickets vn-tr:nth-child(1) vn-textfield[ng-model="ticket.priority"] input',
@ -668,7 +667,7 @@ export default {
}, },
workerPbx: { workerPbx: {
extensionInput: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"] input', extensionInput: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"] input',
saveButton: 'vn-worker-pbx vn-submit[label="Save"] input' saveButton: 'vn-worker-pbx button[type=submit]'
}, },
workerTimeControl: { workerTimeControl: {
timeDialogInput: '.vn-dialog.shown [ng-model="$ctrl.newTime"]', timeDialogInput: '.vn-dialog.shown [ng-model="$ctrl.newTime"]',
@ -720,12 +719,12 @@ export default {
navigateBackToIndex: 'vn-worker-descriptor vn-icon[icon="chevron_left"]' navigateBackToIndex: 'vn-worker-descriptor vn-icon[icon="chevron_left"]'
}, },
invoiceOutIndex: { invoiceOutIndex: {
searchInvoiceOutInput: `vn-invoice-out-index ${components.vnTextfield}`, searchInvoiceOutInput: `vn-invoice-out-index vn-textfield input`,
searchButton: 'vn-invoice-out-index vn-searchbar vn-icon[icon="search"]', searchButton: 'vn-invoice-out-index vn-searchbar vn-icon[icon="search"]',
searchResult: 'vn-invoice-out-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr', searchResult: 'vn-invoice-out-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
}, },
invoiceOutDescriptor: { invoiceOutDescriptor: {
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[vn-id="more-button"]', moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[icon=more_vert]',
moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]', moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]',
moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]', moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]',
moreMenuShowInvoiceOutPdf: '.vn-popover.shown .vn-drop-down li[name="Show invoice PDF"]', moreMenuShowInvoiceOutPdf: '.vn-popover.shown .vn-drop-down li[name="Show invoice PDF"]',

View File

@ -1,56 +1,35 @@
import createNightmare from '../../helpers/nightmare'; import createNightmare from '../../helpers/nightmare';
describe('Login path', () => { describe('Login path', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
it('should receive an error when the username is incorrect', async() => { it('should receive an error when the username is incorrect', async() => {
const username = 'nobody';
const password = 'nightmare';
const result = await nightmare const result = await nightmare
.wait(`vn-login input[name=user]`) .doLogin('badUser', null)
.write(`vn-login input[name=user]`, username)
.write(`vn-login input[name=password]`, password)
.click(`vn-login input[type=submit]`)
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result.length).toBeGreaterThan(0); expect(result.length).toBeGreaterThan(0);
}); });
it('should receive an error when the username is blank', async() => { it('should receive an error when the username is blank', async() => {
const password = 'nightmare';
const result = await nightmare const result = await nightmare
.clearInput(`vn-login input[name=user]`) .doLogin('', null)
.write(`vn-login input[name=password]`, password)
.click(`vn-login input[type=submit]`)
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result.length).toBeGreaterThan(0); expect(result.length).toBeGreaterThan(0);
}); });
it('should receive an error when the password is incorrect', async() => { it('should receive an error when the password is incorrect', async() => {
const username = 'employee';
const password = 'badpassword';
const result = await nightmare const result = await nightmare
.write(`vn-login input[name=user]`, username) .doLogin('employee', 'badPassword')
.write(`vn-login input[name=password]`, password)
.click(`vn-login input[type=submit]`)
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result.length).toBeGreaterThan(0); expect(result.length).toBeGreaterThan(0);
}); });
it('should log in', async() => { it('should log in', async() => {
const username = 'employee';
const password = 'nightmare';
const url = await nightmare const url = await nightmare
.write(`vn-login input[name=user]`, username) .doLogin('employee', null)
.write(`vn-login input[name=password]`, password)
.click(`vn-login input[type=submit]`)
.wait('#logout') .wait('#logout')
.parsedUrl(); .parsedUrl();

View File

@ -42,9 +42,7 @@ describe('Client Edit fiscalData path', () => {
it('should not be able to edit the verified data checkbox', async() => { it('should not be able to edit the verified data checkbox', async() => {
const result = await nightmare const result = await nightmare
.wait(selectors.clientFiscalData.verifiedDataCheckbox) .wait(selectors.clientFiscalData.verifiedDataCheckbox)
.evaluate(selector => { .isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
return document.querySelector(selector).getAttribute('disabled');
}, selectors.clientFiscalData.verifiedDataCheckbox);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });

View File

@ -16,9 +16,7 @@ describe('Client lock verified data path', () => {
const result = await nightmare const result = await nightmare
.wait(200) .wait(200)
.wait(selectors.clientFiscalData.verifiedDataCheckbox) .wait(selectors.clientFiscalData.verifiedDataCheckbox)
.evaluate(selector => { .isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
return document.querySelector(selector).getAttribute('disabled');
}, selectors.clientFiscalData.verifiedDataCheckbox);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });

View File

@ -17,9 +17,7 @@ describe('Ticket services path', () => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.ticketService.addServiceButton) .waitToClick(selectors.ticketService.addServiceButton)
.wait(selectors.ticketService.firstAddDescriptionButton) .wait(selectors.ticketService.firstAddDescriptionButton)
.evaluate(selector => { .isDisabled(selectors.ticketService.firstAddDescriptionButton);
return document.querySelector(selector).disabled;
}, selectors.ticketService.firstAddDescriptionButton);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });

View File

@ -66,7 +66,7 @@ describe('Order catalog', () => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.orderCatalog.fourthFilterRemoveButton) .waitToClick(selectors.orderCatalog.fourthFilterRemoveButton)
.waitToClick(selectors.orderCatalog.thirdFilterRemoveButton) .waitToClick(selectors.orderCatalog.thirdFilterRemoveButton)
.waitForNumberOfElements('section.product', 4) .waitForNumberOfElements('.product', 4)
.countElement('section.product'); .countElement('section.product');
expect(result).toEqual(4); expect(result).toEqual(4);

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare'; import createNightmare from '../../helpers/nightmare';
describe('InvoiceOut descriptor path', () => { fdescribe('InvoiceOut descriptor path', () => {
const nightmare = createNightmare(); const nightmare = createNightmare();
let bookedDate; let bookedDate;

View File

@ -1,13 +0,0 @@
<div class="button-menu">
<button
class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored button-menu__button">
<vn-label vn-none translate>{{::$ctrl.label}}</vn-label>
<vn-icon vn-none icon="{{::$ctrl.icon}}"></vn-icon>
<vn-icon vn-none class="button-menu__arrow_down" icon="keyboard_arrow_down"></vn-icon>
</button>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
ng-click="$ctrl.onDropDownClick($event)">
</vn-drop-down>
</div>

View File

@ -0,0 +1,20 @@
<button>
<span
ng-if="::$ctrl.label"
translate>
{{::$ctrl.label}}
</span>
<vn-icon
ng-if="::$ctrl.icon"
icon="{{::$ctrl.icon}}">
</vn-icon>
<vn-icon
class="button-menu__arrow_down"
icon="keyboard_arrow_down">
</vn-icon>
</button>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
ng-click="$ctrl.onDropDownClick($event)">
</vn-drop-down>

View File

@ -1,17 +1,13 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Input from '../../lib/input'; import Button from '../button';
import assignProps from '../../lib/assign-props'; import assignProps from '../../lib/assign-props';
import './style.scss'; import './style.scss';
export default class ButtonMenu extends Input { export default class ButtonMenu extends Button {
constructor($element, $scope, $transclude) { constructor($element, $scope, $transclude) {
super($element, $scope); super($element, $scope);
this.$transclude = $transclude; this.$transclude = $transclude;
this.input = this.element.querySelector('.mdl-button'); $element.on('click', e => this.onClick(e));
$element.on('click', e => {
if (!this.disabled)
this.onClick(e);
});
} }
get model() { get model() {
@ -46,6 +42,7 @@ export default class ButtonMenu extends Input {
} }
onClick(event) { onClick(event) {
if (this.disabled) return;
if (event.defaultPrevented) return; if (event.defaultPrevented) return;
event.preventDefault(); event.preventDefault();
this.emit('open'); this.emit('open');
@ -85,15 +82,14 @@ export default class ButtonMenu extends Input {
} }
ButtonMenu.$inject = ['$element', '$scope', '$transclude']; ButtonMenu.$inject = ['$element', '$scope', '$transclude'];
ngModule.component('vnButtonMenu', { ngModule.vnComponent('vnButtonMenu', {
template: require('./button-menu.html'), template: require('./index.html'),
controller: ButtonMenu,
bindings: { bindings: {
label: '@',
showField: '@?', showField: '@?',
selection: '<?', selection: '<?',
valueField: '@?', valueField: '@?',
selectFields: '<?', selectFields: '<?',
disabled: '<?',
initialData: '<?', initialData: '<?',
showFilter: '<?', showFilter: '<?',
field: '=?', field: '=?',
@ -104,12 +100,10 @@ ngModule.component('vnButtonMenu', {
limit: '<?', limit: '<?',
multiple: '<?', multiple: '<?',
onChange: '&?', onChange: '&?',
icon: '@?',
translateFields: '<?', translateFields: '<?',
onOpen: '&?' onOpen: '&?'
}, },
transclude: { transclude: {
tplItem: '?tplItem' tplItem: '?tplItem'
}, }
controller: ButtonMenu
}); });

View File

@ -1,19 +1,3 @@
vn-button-menu { vn-button-menu {
position: relative; position: relative;
cursor: pointer;
.button-menu__button {
padding: 0 10px;
}
vn-label {
float: left;
margin-top: 1px;
}
vn-icon {
float: left;
margin-top: 3px;
}
vn-icon.button-menu__arrow_down {
margin: 6px 0 0 5px;
}
} }

View File

@ -1,6 +0,0 @@
<button type="{{::$ctrl.type}}" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
<span translate>{{$ctrl.label}}</span>
<vn-icon
icon="{{::$ctrl.icon}}">
</vn-icon>
</button>

View File

@ -1,34 +0,0 @@
import ngModule from '../../module';
import Input from '../../lib/input';
import './style.scss';
export default class Button extends Input {
constructor($element) {
super($element);
this.$element = $element;
this.input = this.element.querySelector('.mdl-button');
$element[0].addEventListener('click', event => {
if (this.disabled)
event.stopImmediatePropagation();
});
}
$onInit() {
if (!this.type)
this.type = 'button';
}
}
Button.$inject = ['$element'];
ngModule.component('vnButton', {
controller: Button,
template: require('./button.html'),
bindings: {
label: '@?',
disabled: '<?',
icon: '@?',
type: '@?'
}
});

View File

@ -0,0 +1,11 @@
<button type="{{::$ctrl.type}}" tabindex="-1">
<span
ng-if="::$ctrl.label"
translate>
{{::$ctrl.label}}
</span>
<vn-icon
ng-if="::$ctrl.icon"
icon="{{::$ctrl.icon}}">
</vn-icon>
</button>

View File

@ -0,0 +1,46 @@
import ngModule from '../../module';
import FormInput from '../form-input';
import './style.scss';
export default class Button extends FormInput {
constructor($element, $scope) {
super($element, $scope);
this.design = 'colored';
this.input = this.element.querySelector('button');
let element = this.element;
element.tabIndex = 0;
element.classList.add('vn-button');
this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e));
}
$onInit() {
this.element.classList.add(this.design);
if (!this.type) this.type = 'button';
}
onKeyup(event) {
if (event.code == 'Space')
this.onClick(event);
}
onClick(event) {
if (event.defaultPrevented) return;
// event.preventDefault();
// FIXME: Don't stop event propagation
if (this.disabled) event.stopImmediatePropagation();
}
}
Button.$inject = ['$element', '$scope'];
ngModule.vnComponent('vnButton', {
controller: Button,
template: require('./index.html'),
bindings: {
icon: '@?',
type: '@?'
}
});

View File

@ -1,5 +1,83 @@
vn-button { @import "variables";
& > button > vn-icon {
vertical-align: middle; .vn-button {
display: inline-flex;
align-items: center;
justify-content: center;
height: 36px;
border: none;
border-radius: .1em;
font-family: vn-font-bold;
text-transform: uppercase;
font-size: 14px;
cursor: pointer;
box-sizing: border-box;
outline: none;
& > button {
width: 100%;
padding: 0 12px;
box-sizing: border-box;
background-color: transparent;
border: none;
height: inherit;
color: inherit;
font: inherit;
display: block;
text-transform: inherit;
cursor: inherit;
outline: none;
display: flex;
align-items: center;
justify-content: center;
& > vn-icon {
vertical-align: middle;
color: inherit;
font-size: 1.7em;
}
}
&.colored {
color: white;
background-color: $color-main;
box-shadow: 0 .15em .15em 0 rgba(0, 0, 0, .3);
transition: background 200ms ease-in-out;
&:not(.disabled) {
&:hover,
&:focus {
background-color: lighten($color-main, 10%);
}
}
}
&.flat {
color: $color-main;
background-color: transparent;
box-shadow: none;
transition: background 200ms ease-in-out;
&:not(.disabled) {
&:hover,
&:focus {
background-color: $color-hover-cd;
}
}
}
&:hover,
&:focus {
outline: none;
}
&.round {
border-radius: 50%;
height: 3.8em;
width: 3.8em;
& > button > span {
display: none;
}
}
&.disabled {
opacity: .7;
cursor: initial;
} }
} }

View File

@ -7,7 +7,7 @@ export default function directive() {
transclude: true, transclude: true,
template: require('./card.html'), template: require('./card.html'),
link: function($scope, $element, $attrs, $ctrl, $transclude) { link: function($scope, $element, $attrs, $ctrl, $transclude) {
$element.addClass('demo-card-wide mdl-shadow--2dp bg-panel'); $element.addClass('demo-card-wide vn-shadow bg-panel');
$transclude($scope, function(clone) { $transclude($scope, function(clone) {
angular.element($element[0].querySelector('div')).append(clone); angular.element($element[0].querySelector('div')).append(clone);

View File

@ -1,8 +1,7 @@
<vn-one> <div ng-transclude></div>
<span ng-class="{'mdl-chip--deletable': !$ctrl.disabled}" class="mdl-chip"> <vn-icon
<span class="mdl-chip__text ellipsize" ng-transclude></span> ng-click="$ctrl.onRemove()"
<button ng-click="$ctrl.remove()" ng-show="!$ctrl.disabled" type="button" class="mdl-chip__action"> ng-if="$ctrl.removable"
<i class="material-icons">cancel</i> icon="cancel"
</button> tabindex="0">
</span> </vn-icon>
</vn-one>

View File

@ -1,17 +1,12 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss'; import './style.scss';
export default class Chip { export default class Chip extends Component {
onRemove() {
/** if (!this.disabled) this.emit('remove');
* Remove chip event
*/
remove() {
if (this.onRemove)
this.onRemove();
} }
} }
Chip.$inject = ['$element', '$scope', '$transclude']; Chip.$inject = ['$element', '$scope', '$transclude'];
ngModule.component('vnChip', { ngModule.component('vnChip', {
@ -20,6 +15,6 @@ ngModule.component('vnChip', {
transclude: true, transclude: true,
bindings: { bindings: {
disabled: '<?', disabled: '<?',
onRemove: '&?' removable: '<?'
} }
}); });

View File

@ -16,13 +16,13 @@ describe('Component vnChip', () => {
controller = $componentController('vnChip', {$element, $scope, $transclude: () => {}}); controller = $componentController('vnChip', {$element, $scope, $transclude: () => {}});
})); }));
describe('remove()', () => { describe('onRemove()', () => {
it(`should call onRemove()`, () => { it(`should emit remove event`, () => {
controller.onRemove = () => {}; controller.emit = () => {};
spyOn(controller, 'onRemove'); spyOn(controller, 'emit');
controller.remove(); controller.onRemove();
expect(controller.onRemove).toHaveBeenCalledWith(); expect(controller.emit).toHaveBeenCalledWith('remove');
}); });
}); });
}); });

View File

@ -1,18 +1,53 @@
@import "variables"; @import "variables";
vn-chip { vn-chip {
border-radius: 16px;
background-color: $color-bg;
margin: 0 0.5em 0.5em 0; margin: 0 0.5em 0.5em 0;
color: $color-font;
font-size: 14px;
margin: .25em;
display: inline-flex;
align-items: center;
text-overflow: ellipsis;
white-space: nowrap;
height: 28px;
padding: 0 .7em;
overflow: hidden;
.mdl-chip { &.colored {
background-color: rgba($color-main, 0.9); background-color: $color-main;
color: #FFF color: $color-font-dark;
} }
& > div {
.mdl-chip:active { display: flex;
background-color: $color-main align-items: center;
}
& > vn-one > span > span {
max-width: 100%; max-width: 100%;
height: 100%;
& > vn-avatar {
margin-left: -0.7em;
margin-right: .4em;
}
}
& > vn-icon {
margin-left: .2em;
margin-right: -0.3em;
vertical-align: middle;
opacity: .6;
cursor: pointer;
transition: opacity 250ms ease-out;
&:hover,
&:focus {
opacity: 1;
}
} }
} }
vn-avatar {
display: inline-block;
height: 28px;
width: 28px;
border-radius: 50%;
}

View File

@ -1,8 +0,0 @@
<span
ng-class="{'pointer': $ctrl.$attrs['onClick']}"
class="mdl-chip mdl-chip--contact"
ng-repeat="legend in $ctrl.data track by $index"
ng-click="$ctrl.onClick(legend)">
<span class="mdl-chip__contact" ng-style="{backgroundColor: legend.color}"></span>
<span class="mdl-chip__text">{{legend.name}}</span>
</span>

View File

@ -1,24 +0,0 @@
import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';
export default class Controller extends Component {
constructor($element, $scope, $attrs) {
super($element, $scope);
this.$attrs = $attrs;
}
onClick(legend) {
this.emit('click', {legend});
}
}
Controller.$inject = ['$element', '$scope', '$attrs'];
ngModule.component('vnColorLegend', {
template: require('./index.html'),
controller: Controller,
bindings: {
data: '<?'
}
});

View File

@ -1,13 +0,0 @@
@import "variables";
.mdl-chip--contact {
margin-left: 5px;
height: 20px;
line-height: 5px;
float: left
}
.mdl-chip--contact .mdl-chip__contact {
height: 20px;
width: 20px
}

View File

@ -11,7 +11,6 @@ export default class Field extends FormInput {
this.suffix = null; this.suffix = null;
this.control = this.element.querySelector('.control'); this.control = this.element.querySelector('.control');
this.classList = this.element.classList;
this.classList.add('vn-field'); this.classList.add('vn-field');
this.element.addEventListener('click', e => this.onClick(e)); this.element.addEventListener('click', e => this.onClick(e));
@ -43,9 +42,11 @@ export default class Field extends FormInput {
} }
set input(value) { set input(value) {
if (this.input) this.control.removeChild(this.input); if (this.input)
this.control.removeChild(this.input);
this._input = value; this._input = value;
this.control.appendChild(value); if (value)
this.control.appendChild(value);
} }
get input() { get input() {
@ -69,12 +70,10 @@ export default class Field extends FormInput {
} }
set name(value) { set name(value) {
// super.name = value;
this.input.name = value; this.input.name = value;
} }
get name() { get name() {
// return super.name;
return this.input.name; return this.input.name;
} }
@ -86,36 +85,8 @@ export default class Field extends FormInput {
return this.input.placeholder; return this.input.placeholder;
} }
set tabIndex(value) {
this.input.tabIndex = value;
}
get tabIndex() {
return this.input.tabIndex;
}
set disabled(value) {
this._disabled = boolTag(value);
this.input.disabled = this._disabled;
this.classList.toggle('disabled', this._disabled);
}
get disabled() {
return this._disabled;
}
set readonly(value) {
this._readonly = boolTag(value);
this.input.readOnly = this._readonly;
this.classList.toggle('readonly', this._readonly);
}
get readonly() {
return this._readonly;
}
set required(value) { set required(value) {
this._required = boolTag(value); this._required = value;
let required = this.element.querySelector('.required'); let required = this.element.querySelector('.required');
display(required, this._required); display(required, this._required);
} }
@ -182,6 +153,10 @@ export default class Field extends FormInput {
fix.innerText = text || ''; fix.innerText = text || '';
} }
refreshTabIndex() {
this.input.tabIndex = this.disabled ? -1 : this.tabIndex;
}
onClick() { onClick() {
// if (event.defaultPrevented) return; // if (event.defaultPrevented) return;
// event.preventDefault(); // event.preventDefault();
@ -252,15 +227,10 @@ ngModule.vnComponent('vnField', {
suffix: '@?', suffix: '@?',
hint: '@?', hint: '@?',
error: '<?', error: '<?',
tabIndex: '<?',
rule: '@?' rule: '@?'
} }
}); });
function boolTag(value) {
return Boolean(value || value === '');
}
function display(element, display) { function display(element, display) {
element.style.display = display ? 'initial' : 'none'; element.style.display = display ? 'initial' : 'none';
} }

View File

@ -245,7 +245,6 @@
} }
} }
& > .hint { & > .hint {
z-index: -1;
padding: 4px 0; padding: 4px 0;
height: 12px; height: 12px;
color: rgba(0, 0, 0, .4); color: rgba(0, 0, 0, .4);
@ -255,11 +254,12 @@
transition-duration: 200ms; transition-duration: 200ms;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
opacity: 0; opacity: 0;
visibility: hidden;
&.filled { &.filled {
z-index: 0;
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
visibility: visible;
} }
} }
&.invalid { &.invalid {

View File

@ -1,3 +0,0 @@
<button class="mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
<vn-icon icon="{{::$ctrl.icon}}"></vn-icon>
</button>

View File

@ -1,8 +0,0 @@
import ngModule from '../../module';
ngModule.component('vnFloatButton', {
template: require('./float-button.html'),
bindings: {
icon: '@'
}
});

View File

@ -0,0 +1,13 @@
import ngModule from '../../module';
import Button from '../button';
export default class FloatButton extends Button {
constructor($element, $scope) {
super($element, $scope);
this.element.classList.add('round');
}
}
ngModule.vnComponent('vnFloatButton', {
controller: FloatButton
});

View File

@ -9,6 +9,11 @@ import Component from '../../lib/component';
* @property {Boolean} disabled Put component in disabled mode * @property {Boolean} disabled Put component in disabled mode
*/ */
export default class FormInput extends Component { export default class FormInput extends Component {
constructor($element, $scope) {
super($element, $scope);
this.classList = this.element.classList;
}
$onInit() { $onInit() {
// XXX: Compatibility with old inputs // XXX: Compatibility with old inputs
let attrs = this.$element[0].attributes; let attrs = this.$element[0].attributes;
@ -41,6 +46,48 @@ export default class FormInput extends Component {
get name() { get name() {
return this.element.getAttribute('name'); return this.element.getAttribute('name');
} }
set disabled(value) {
this._disabled = boolTag(value);
this.input.disabled = this._disabled;
this.classList.toggle('disabled', this._disabled);
this.refreshTabIndex();
}
get disabled() {
return this._disabled;
}
set readonly(value) {
this._readonly = boolTag(value);
this.input.readOnly = this._readonly;
this.classList.toggle('readonly', this._readonly);
}
get readonly() {
return this._readonly;
}
set tabIndex(value) {
this._tabIndex = value;
this.refreshTabIndex();
}
get tabIndex() {
return this._tabIndex;
}
select() {
this.input.select();
}
focus() {
this.input.focus();
}
refreshTabIndex() {
this.element.tabIndex = this.disabled ? -1 : this.tabIndex;
}
} }
ngModule.vnComponent('vnFormInput', { ngModule.vnComponent('vnFormInput', {
@ -50,9 +97,14 @@ ngModule.vnComponent('vnFormInput', {
field: '=?', field: '=?',
name: '@?', name: '@?',
disabled: '<?', disabled: '<?',
readonly: '<?' readonly: '<?',
tabIndex: '<?'
}, },
require: { require: {
ngModel: '?ngModel' ngModel: '?ngModel'
} }
}); });
function boolTag(value) {
return Boolean(value || value === '');
}

View File

@ -1,3 +0,0 @@
<button type="button" ng-disabled="$ctrl.disabled">
<vn-icon icon="{{::$ctrl.icon}}">
</button>

View File

@ -1,39 +0,0 @@
import ngModule from '../../module';
import './style.scss';
export default class IconButton {
constructor($element) {
this.element = $element[0];
if (this.element.getAttribute('tabindex') == null)
this.element.tabIndex = 0;
this.element.addEventListener('keyup', e => this.onKeyup(e));
this.element.addEventListener('click', e => this.onClick(e));
}
onKeyup(event) {
if (event.code == 'Space')
this.onClick(event);
}
onClick(event) {
if (event.defaultPrevented) return;
event.preventDefault();
// FIXME: Don't use Event.stopPropagation()
let button = this.element.querySelector('button');
if (this.disabled || button.disabled)
event.stopImmediatePropagation();
}
}
IconButton.$inject = ['$element'];
ngModule.component('vnIconButton', {
controller: IconButton,
template: require('./icon-button.html'),
bindings: {
icon: '@',
disabled: '<?'
}
});

View File

@ -0,0 +1,14 @@
import ngModule from '../../module';
import Button from '../button';
import './style.scss';
export default class IconButton extends Button {
constructor($element, $scope) {
super($element, $scope);
this.design = null;
}
}
ngModule.vnComponent('vnIconButton', {
controller: IconButton
});

View File

@ -2,27 +2,12 @@
vn-icon-button { vn-icon-button {
@extend %clickable-light; @extend %clickable-light;
outline: 0;
color: $color-main; color: $color-main;
display: inline-flex;
align-items: center;
font-size: 18pt;
padding: .25em;
& > button { & > button {
background-color: transparent; padding: 0 !important;
display: block; }
color: inherit; &:focus {
border: 0; opacity: .6;
padding: 0;
font-size: inherit;
&:hover {
background-color: initial;
}
& > vn-icon {
display: block;
font-size: inherit;
}
} }
} }

View File

@ -1 +0,0 @@
<vn-icon icon="{{::$ctrl.icon}}"></vn-icon>

View File

@ -1,29 +0,0 @@
import ngModule from '../../module';
import './style.scss';
export default class IconFocusable {
constructor($element) {
$element[0].tabIndex = 0;
$element.on("keyup", event => this.onKeyDown(event, $element));
}
onKeyDown(event, $element) {
if (event.defaultPrevented) return;
if (event.keyCode == 32 || event.keyCode == 13) {
event.preventDefault();
$element.triggerHandler('click');
}
}
}
IconFocusable.$inject = ['$element'];
ngModule.component('vnIconFocusable', {
controller: IconFocusable,
template: require('./icon-focusable.html'),
bindings: {
icon: '@',
className: '@?',
enabled: '<?',
label: '@?'
}
});

View File

@ -1,10 +0,0 @@
vn-icon-focusable {
display: inline-block;
text-align: center;
& > i,
& > i.material-icons {
display: block;
font-size: inherit;
}
}

View File

@ -1,11 +0,0 @@
<div class="icon-menu">
<vn-icon
class="button"
icon="{{::$ctrl.icon}}">
</vn-icon>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
ng-click="$ctrl.onDropDownClick($event)">
</vn-drop-down>
</div>

View File

@ -1,41 +0,0 @@
import ngModule from '../../module';
import ButtonMenu from '../button-menu/button-menu';
import './style.scss';
export default class IconMenu extends ButtonMenu {
constructor($element, $scope, $transclude) {
super($element, $scope);
this.$transclude = $transclude;
this.input = this.element.querySelector('.button');
}
}
IconMenu.$inject = ['$element', '$scope', '$transclude'];
ngModule.component('vnIconMenu', {
template: require('./icon-menu.html'),
bindings: {
label: '@',
showField: '@?',
selection: '<?',
valueField: '@?',
selectFields: '<?',
disabled: '<?',
initialData: '<?',
showFilter: '<?',
field: '=?',
url: '@?',
data: '<?',
where: '@?',
order: '@?',
limit: '<?',
multiple: '<?',
onChange: '&?',
icon: '@?',
translateFields: '<?',
onOpen: '&?'
},
transclude: {
tplItem: '?tplItem'
},
controller: IconMenu
});

View File

@ -0,0 +1,11 @@
<button>
<vn-icon
class="button"
icon="{{::$ctrl.icon}}">
</vn-icon>
</button>
<vn-drop-down
vn-id="drop-down"
on-select="$ctrl.onDropDownSelect(item)"
ng-click="$ctrl.onDropDownClick($event)">
</vn-drop-down>

View File

@ -0,0 +1,14 @@
import ngModule from '../../module';
import ButtonMenu from '../button-menu';
export default class IconMenu extends ButtonMenu {
constructor($element, $scope) {
super($element, $scope);
this.element.classList.add('flat');
}
}
ngModule.vnComponent('vnIconMenu', {
template: require('./index.html'),
controller: IconMenu
});

View File

@ -1,8 +0,0 @@
vn-icon-menu {
cursor: pointer;
vn-drop-down {
font-family: 'vn-font';
outline: 0
}
}

View File

@ -10,36 +10,35 @@ import './subtitle/subtitle';
import './spinner/spinner'; import './spinner/spinner';
import './snackbar/snackbar'; import './snackbar/snackbar';
import './tooltip/tooltip'; import './tooltip/tooltip';
import './icon-menu/icon-menu';
import './button-menu/button-menu';
import './popover/popover'; import './popover/popover';
import './drop-down/drop-down'; import './drop-down/drop-down';
import './menu/menu'; import './menu/menu';
import './multi-check/multi-check'; import './multi-check/multi-check';
import './button/button';
import './icon-button/icon-button';
import './submit/submit';
import './card/card'; import './card/card';
import './float-button/float-button';
import './step-control/step-control'; import './step-control/step-control';
import './label-value/label-value'; import './label-value/label-value';
import './pagination/pagination'; import './pagination/pagination';
import './searchbar/searchbar'; import './searchbar/searchbar';
import './scroll-up/scroll-up'; import './scroll-up/scroll-up';
import './autocomplete'; import './autocomplete';
import './button';
import './button-menu';
import './calendar'; import './calendar';
import './check'; import './check';
import './chip'; import './chip';
import './color-legend';
import './data-viewer'; import './data-viewer';
import './date-picker'; import './date-picker';
import './field'; import './field';
import './float-button';
import './icon-menu';
import './icon-button';
import './input-number'; import './input-number';
import './input-range'; import './range';
import './input-time'; import './input-time';
import './input-file'; import './input-file';
import './list'; import './list';
import './radio'; import './radio';
import './submit';
import './table'; import './table';
import './td-editable'; import './td-editable';
import './textarea'; import './textarea';

View File

@ -1,42 +1,53 @@
<div class="container" <div class="container">
ng-class="{selected: $ctrl.hasFocus}"> <div
<div class="textField"> ng-transclude="prepend"
<div class="leftIcons" ng-transclude="leftIcons"></div> class="prepend">
<div class="infix"> </div>
<section class="value" ng-click="$ctrl.openFileSelector()" translate> <div class="infix">
<div class="fix prefix"></div>
<div class="control">
<section
class="value"
ng-click="$ctrl.openFileSelector()"
translate>
{{$ctrl.value}} {{$ctrl.value}}
</section> </section>
<input <input
class="mdl-textfield__input"
type="file" type="file"
name="{{::$ctrl.name}}"
ng-model="$ctrl.files" ng-model="$ctrl.files"
vn-validation="{{$ctrl.rule}}" accept="{{$ctrl.accept}}">
ng-disabled="$ctrl.disabled" </input>
ng-readonly="$ctrl.readonly"
ng-focus="$ctrl.hasFocus = true"
ng-blur="$ctrl.hasFocus = false"
tabindex="{{$ctrl.input.tabindex}}"
accept="{{$ctrl.accept}}"/>
<label class="label">
<span translate>{{::$ctrl.label}}</span>
<span translate ng-show="::$ctrl.required">*</span>
</label>
</div> </div>
<div class="underline"></div> <div class="fix suffix"></div>
<div class="selected underline"></div> <label>
<div class="suffix"> <span translate>{{::$ctrl.label}}</span>
<i class="material-icons" <span class="required">*</span>
ng-if="::$ctrl.hasInfo" </label>
vn-tooltip="{{::$ctrl.info}}">
info_outline
</i>
<vn-icon-button
icon="cloud_upload"
vn-tooltip="Select a file"
ng-click="$ctrl.openFileSelector()">
</vn-icon-button>
</div>
<div class="rightIcons" ng-transclude="rightIcons"></div>
</div> </div>
<div class="icons pre">
<vn-icon
icon="clear"
translate-attr="{title: 'Clear'}"
ng-click="$ctrl.onClear($event)">
</vn-icon>
<vn-icon
icon="cloud_upload"
vn-tooltip="Select a file"
ng-click="$ctrl.openFileSelector()">
</vn-icon>
<vn-icon
ng-if="::$ctrl.info"
icon="info_outline"
vn-tooltip="{{::$ctrl.info}}">
</vn-icon>
</div>
<div
ng-transclude="append"
class="append">
</div>
<div class="icons post">
</div>
<div class="underline blur"></div>
<div class="underline focus"></div>
</div> </div>
<div class="hint"></div>

View File

@ -1,15 +1,13 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Input from '../../lib/input'; import FormInput from '../form-input';
import './style.scss'; import './style.scss';
export default class InputFile extends Input { export default class InputFile extends FormInput {
constructor($element, $scope) { constructor($element, $scope) {
super($element, $scope); super($element, $scope);
this.element = $element[0];
this.hasFocus = false;
this._multiple = false; this._multiple = false;
this._value = 'Select a file'; this._value = 'Select a file';
this.input = this.element.querySelector('input');
this.registerEvents(); this.registerEvents();
} }
@ -106,26 +104,12 @@ export default class InputFile extends Input {
} }
} }
InputFile.$inject = ['$element', '$scope']; ngModule.vnComponent('vnInputFile', {
ngModule.component('vnInputFile', {
template: require('./index.html'), template: require('./index.html'),
controller: InputFile, controller: InputFile,
transclude: {
leftIcons: '?tLeftIcons',
rightIcons: '?tRightIcons'
},
bindings: { bindings: {
label: '@?',
name: '@?',
disabled: '<?',
multiple: '<?', multiple: '<?',
required: '@?',
accept: '@?', accept: '@?',
rule: '@?', files: '=model'
files: '=model',
validate: '&',
onChange: '&',
onClear: '&'
} }
}); });

View File

@ -7,159 +7,7 @@ vn-input-file {
padding: 4px 0; padding: 4px 0;
outline: 0 outline: 0
} }
input { input[type=file] {
display: none !important display: none;
}
margin: 20px 0;
display: inline-block;
width: 100%;
& > .container {
width: 100%;
position: relative;
padding-bottom: 2px;
display: flex;
& > .textField {
width: 100%;
display: flex;
align-items: center;
position: relative;
padding-top: 4px;
}
}
.leftIcons, .rightIcons, .suffix {
display: flex;
color: $color-font-secondary;
.material-icons {
font-size: 20px !important
}
}
.suffix vn-icon-button {
padding: 0
}
t-left-icons {
padding-right: 0.5em
}
t-right-icons {
padding-left: 0.5em
}
.infix {
position: relative;
display: block;
flex: auto;
width: 100%;
min-width: 0;
}
i.clear {
visibility: hidden;
cursor: pointer;
outline: 0;
&:hover {
color: #222;
}
}
&:hover i.clear {
visibility: visible;
}
i.visible {
visibility: visible;
}
label {
position: absolute;
bottom: 0;
left: 0;
padding: 4px 0!important;
pointer-events: none;
color: $color-font-secondary;
transition-duration: .2s;
transition-timing-function: cubic-bezier(.4,0,.2,1);
}
&.not-empty label{
bottom: 24px;
color: $color-main;
padding: 0;
font-size: 12px;
}
input {
outline: none;
border: none;
font-family: "Helvetica", "Arial", sans-serif;
display: block;
font-size: 16px;
width: 100%;
background: 0 0;
color: inherit;
padding: 4px;
box-sizing: border-box;
border-bottom: 0!important;
&[type=number] {
-moz-appearance: textfield;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
&:invalid {
box-shadow: none;
}
}
.underline {
position: absolute;
bottom: 0;
height: 1px;
content: ' ';
pointer-events: none;
width: 100%;
background-color: $color-input-underline;
}
.selected.underline {
background-color: $color-main;
height: 2px;
left: 50%;
width: 0px !important;
transition-duration: 0.2s;
transition-timing-function: cubic-bezier(.4,0,.2,1);
}
div.selected {
&.container{
border-bottom: 0px;
}
label {
bottom: 24px;
color: $color-main;
font-size: 12px;
}
.selected.underline{
left: 0;
width: 100%!important;
}
}
& > div.container > div.textField > div.infix.invalid {
@extend div.selected;
& > span.mdl-textfield__error {
visibility: visible;
}
& > label {
color: #d50000;
}
}
.infix.invalid + .underline {
background-color: #d50000;
}
label span:nth-child(2) {
color: $color-alert
} }
} }

View File

@ -1,9 +0,0 @@
<div>
<label translate>{{::$ctrl.label}}</label>
<input
name="{{$ctrl.name}}"
class="mdl-slider mdl-js-slider"
type="range"/>
<label class="min-label" translate>Company</label>
<label class="max-label" translate>Sales/Client</label>
</div>

View File

@ -1,79 +0,0 @@
import ngModule from '../../module';
import Input from '../../lib/input';
import './style.scss';
export default class inputRange extends Input {
constructor($element, $scope) {
super($element, $scope);
this.mdlElement = this.element.querySelector('.mdl-slider');
componentHandler.upgradeElement(this.mdlElement);
this.mdlElement.addEventListener('change', () => {
this._value = this.input.value;
this.$.$applyAsync();
if (this._value && this.onChange)
this.emit('change', {value: this._value});
});
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
this.mdlElement.MaterialSlider.change(value);
}
get max() {
return this.input.max;
}
set max(value) {
this.input.max = value;
}
get min() {
return this.input.min;
}
set min(value) {
this.input.min = value;
}
get step() {
return this.input.step;
}
set step(value) {
this.input.step = value;
}
get() {
return this._model;
}
set model(value) {
this._model = value;
}
set disabled(value) {
this.input.disabled = value;
}
}
inputRange.$inject = ['$element', '$scope'];
ngModule.component('vnInputRange', {
template: require('./index.html'),
controller: inputRange,
bindings: {
label: '@?',
disabled: '<?',
min: '<?',
max: '<?',
step: '<?',
value: '=',
model: '=',
onChange: '&'
}
});

View File

@ -1,14 +0,0 @@
@import "variables";
vn-input-range {
label {
color: $color-main;
font-size: 12px;
padding: 0 25px;
}
label.min-label, label.max-label {
color: $color-font;
}
label.max-label {
float: right;
}
}

View File

@ -24,11 +24,10 @@
vn-icon-button { vn-icon-button {
opacity: .4; opacity: .4;
color: $color-main;
margin-left: .5em; margin-left: .5em;
transition: opacity 250ms ease-out; transition: opacity 250ms ease-out;
padding: 0; padding: 0;
font-size: 2em; font-size: 1.2em;
&:hover { &:hover {
opacity: 1; opacity: 1;

View File

@ -1,5 +1,5 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Input from '../../lib/input'; import FormInput from '../form-input';
import './style.scss'; import './style.scss';
/** /**
@ -8,7 +8,7 @@ import './style.scss';
* @param {Array} data List of options shown in drop-down * @param {Array} data List of options shown in drop-down
* @param {Array} models Elements to check / unCheck * @param {Array} models Elements to check / unCheck
*/ */
export default class MultiCheck extends Input { export default class MultiCheck extends FormInput {
constructor($element, $scope) { constructor($element, $scope) {
super($element, $scope); super($element, $scope);
this._checked = false; this._checked = false;

View File

@ -0,0 +1,4 @@
<label class="main" translate>{{::$ctrl.label}}</label>
<input name="{{::$ctrl.name}}" type="range"></input>
<label class="min-label" translate>{{::$ctrl.minLabel}}</label>
<label class="max-label" translate>{{::$ctrl.maxLabel}}</label>

View File

@ -0,0 +1,50 @@
import ngModule from '../../module';
import FormInput from '../form-input';
import './style.scss';
export default class Range extends FormInput {
constructor($element, $scope) {
super($element, $scope);
this.input = this.element.querySelector('input');
}
get max() {
return this.input.max;
}
set max(value) {
this.input.max = value;
}
get min() {
return this.input.min;
}
set min(value) {
this.input.min = value;
}
get step() {
return this.input.step;
}
set step(value) {
this.input.step = value;
}
refreshTabIndex() {
this.input.tabIndex = this.disabled ? -1 : this.tabIndex;
}
}
ngModule.vnComponent('vnRange', {
template: require('./index.html'),
controller: Range,
bindings: {
min: '<?',
max: '<?',
step: '<?',
minLabel: '@?',
maxLabel: '@?'
}
});

View File

@ -0,0 +1,84 @@
@import "variables";
@mixin range($thumb-selector, $track-selector) {
&::#{$thumb-selector} {
-webkit-appearance: none;
margin-top: -5px;
border-radius: 50%;
background: $color-main;
border: none;
height: 12px;
width: 12px;
border-radius: 50%;
transition-property: transform, box-shadow;
transition-duration: 250ms;
transition-timing-function: ease-out;
}
&:focus::#{$thumb-selector} {
box-shadow: 0 0 0 10px rgba($color-main, .2);
}
&:active::#{$thumb-selector} {
transform: scale(1.5);
box-shadow: none;
}
&:disabled::#{$thumb-selector} {
transform: none;
cursor: initial;
}
&::#{$track-selector} {
width: 100%;
height: 3px;
cursor: inherit;
background: $color-secondary;
border-radius: 2px;
border: none;
}
}
vn-range {
& > label {
font-size: 12px;
&.main {
color: $color-main;
}
&.min-label {
float: left;
}
&.max-label {
float: right;
}
}
& > input {
cursor: pointer;
height: 30px;
display: block;
width: 100%;
background: transparent;
border-color: transparent;
-webkit-appearance: none;
margin: .2em 0;
&:focus {
outline: none;
}
&::-moz-focus-outer {
border: 0;
}
@include range(
"-moz-range-thumb",
"-moz-range-track"
);
@include range(
"-webkit-slider-thumb",
"-webkit-slider-runnable-track"
);
@include range(
"-ms-thumb",
"-ms-track"
);
&:disabled {
cursor: initial;
}
}
}

View File

@ -1,5 +1,6 @@
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored" <vn-button
icon="keyboard_arrow_up"
ng-click="$ctrl.goUp()" ng-click="$ctrl.goUp()"
vn-tooltip="Go up"> vn-tooltip="Go up"
<vn-icon icon="keyboard_arrow_up"></vn-icon> class="round">
</button> </vn-button>

View File

@ -1,6 +1,6 @@
vn-scroll-up { vn-scroll-up {
top: 5em; top: 5.5em;
right: 2.5em; right: 2em;
display: none; display: none;
position: fixed; position: fixed;
} }

View File

@ -2,6 +2,7 @@
vn-searchbar { vn-searchbar {
display: block; display: block;
width: 100%;
} }
.search-panel { .search-panel {

View File

@ -1,2 +1,12 @@
<div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner"> <div class="loader">
<svg class="circular" viewBox="25 25 50 50">
<circle
class="path"
cx="50"
cy="50"
r="20"
fill="none"
stroke-miterlimit="10">
</circle>
</svg>
</div> </div>

View File

@ -1,19 +1,18 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Component from '../../lib/component'; import Component from '../../lib/component';
import './style.css'; import './style.scss';
/** /**
* A spinner to inform the user about loading process. * A spinner to inform the user about loading process.
*/ */
export default class Spinner extends Component { export default class Spinner extends Component {
constructor($element, $scope) { constructor($element, $scope) {
super($element); super($element, $scope);
this._enable = false; this._enable = false;
this.spinner = $element[0].firstChild; this.spinner = $element[0].firstChild;
componentHandler.upgradeElement(this.spinner);
} }
/** /**
* Enables/disables the spinner. * Activates/deactivates the spinner.
* *
* @param {Boolean} value %true to enable, %false to disable * @param {Boolean} value %true to enable, %false to disable
*/ */
@ -35,14 +34,14 @@ export default class Spinner extends Component {
* Activates the spinner. * Activates the spinner.
*/ */
start() { start() {
this.spinner.MaterialSpinner.start(); this.spinner.style.display = 'block';
this._enable = true; this._enable = true;
} }
/** /**
* Deactivates the spinner. * Deactivates the spinner.
*/ */
stop() { stop() {
this.spinner.MaterialSpinner.stop(); this.spinner.style.display = 'none';
this._enable = false; this._enable = false;
} }
} }

View File

@ -1,7 +1,6 @@
import './spinner.js'; import './spinner.js';
describe('Component vnSpinner', () => { describe('Component vnSpinner', () => {
let $scope;
let $element; let $element;
let controller; let controller;
@ -9,53 +8,44 @@ describe('Component vnSpinner', () => {
$translateProvider.translations('en', {}); $translateProvider.translations('en', {});
})); }));
beforeEach(angular.mock.inject(($componentController, $rootScope) => { beforeEach(angular.mock.inject(($compile, $rootScope) => {
$scope = $rootScope.$new(); $element = $compile(`<vn-spinner></vn-spinner>`)($rootScope);
$element = angular.element('<div><div></div></div>'); controller = $element.controller('vnSpinner');
controller = $componentController('vnSpinner', {$scope, $element});
})); }));
afterEach(() => {
$element.remove();
});
describe('enable()', () => { describe('enable()', () => {
it(`should call start() based on a boolean value passed as argument`, () => { it(`should call start() when enable is set to true`, () => {
spyOn(controller, 'start'); spyOn(controller, 'start');
spyOn(controller, 'stop');
controller.enable = true; controller.enable = true;
expect(controller.start).toHaveBeenCalledWith(); expect(controller.start).toHaveBeenCalledWith();
expect(controller.stop).not.toHaveBeenCalledWith();
}); });
it(`should call stop() based on a boolean value passed as argument`, () => { it(`should call stop() when enable is set to false`, () => {
spyOn(controller, 'start');
spyOn(controller, 'stop'); spyOn(controller, 'stop');
controller.enable = false; controller.enable = false;
expect(controller.start).not.toHaveBeenCalledWith();
expect(controller.stop).toHaveBeenCalledWith(); expect(controller.stop).toHaveBeenCalledWith();
}); });
}); });
describe('start()', () => { describe('start()', () => {
it(`should call start() on the controller.materialSpinner then set controllers._enable to be truthy`, () => { it(`should set enable to true`, () => {
controller.spinner = {MaterialSpinner: {start: () => {}}};
spyOn(controller.spinner.MaterialSpinner, 'start');
controller._enable = false;
controller.start(); controller.start();
expect(controller.spinner.MaterialSpinner.start).toHaveBeenCalledWith(); expect(controller.enable).toBeTruthy();
expect(controller._enable).toBeTruthy();
}); });
}); });
describe('stop()', () => { describe('stop()', () => {
it(`should call stop() on the controller.materialSpinner then set controllers._enable to be truthy`, () => { it(`should set enable to false`, () => {
controller.spinner = {MaterialSpinner: {stop: () => {}}};
spyOn(controller.spinner.MaterialSpinner, 'stop');
controller._enable = true;
controller.stop(); controller.stop();
expect(controller.spinner.MaterialSpinner.stop).toHaveBeenCalledWith(); expect(controller.enable).toBeFalsy();
expect(controller._enable).toBeFalsy();
}); });
}); });
}); });

View File

@ -1,3 +0,0 @@
vn-spinner {
display: inline-block;
}

View File

@ -0,0 +1,60 @@
@import "variables";
vn-spinner {
display: inline-block;
min-height: 28px;
min-width: 28px;
& > .loader {
position: relative;
margin: 0 auto;
width: 100%;
height: 100%;
&:before {
content: '';
display: block;
padding-top: 100%;
}
& > .circular {
animation: rotate 2s linear infinite;
transform-origin: center center;
height: 100%;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
& > .path {
stroke: $color-main;
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
stroke-linecap: square;
stroke-width: 6px;
animation: dash 1.5s ease-in-out infinite;
}
}
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
}

View File

@ -41,11 +41,5 @@ vn-step-control {
& > .buttons > .step { & > .buttons > .step {
display: flex display: flex
} }
& > .buttons > .step > .mdl-button {
line-height: 32px;
font-size: 12px;
padding: 0 12px;
height: 32px
}
} }
} }

View File

@ -0,0 +1,13 @@
import ngModule from '../../module';
import Button from '../button';
export default class Controller extends Button {
constructor($element, $scope) {
super($element, $scope);
this.type = 'submit';
}
}
ngModule.vnComponent('vnSubmit', {
controller: Controller
});

View File

@ -1,6 +0,0 @@
<input
class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
type="submit"
translate-attr="{value: $ctrl.label}"
value="$ctrl.label">
</input>

View File

@ -1,25 +0,0 @@
import ngModule from '../../module';
import Input from '../../lib/input';
export default class Controller extends Input {
constructor($element, $scope) {
super($element, $scope);
this.$element = $element;
this.input = $element[0].querySelector('input');
}
set disabled(value) {
this.input.disabled = value;
}
}
Controller.$inject = ['$element', '$scope'];
ngModule.component('vnSubmit', {
template: require('./submit.html'),
controller: Controller,
bindings: {
label: '@?',
disabled: '<?',
}
});

View File

@ -1,6 +1,6 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Component from '../../lib/component'; import Component from '../../lib/component';
import Input from '../../lib/input'; import FormInput from '../form-input';
import './style.scss'; import './style.scss';
export default class Controller extends Component { export default class Controller extends Component {
@ -37,7 +37,7 @@ export default class Controller extends Component {
} }
let inputCtrl = this.field[0].firstElementChild.$ctrl; let inputCtrl = this.field[0].firstElementChild.$ctrl;
if (inputCtrl instanceof Input) { if (inputCtrl instanceof FormInput) {
let evt = new MouseEvent('click', { let evt = new MouseEvent('click', {
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,

View File

@ -19,15 +19,24 @@ export default class Toggle extends FormInput {
} }
set disabled(value) { set disabled(value) {
this.element.tabIndex = !value ? 0 : -1;
this.element.classList.toggle('disabled', Boolean(value));
this._disabled = value; this._disabled = value;
this.classList.toggle('disabled', Boolean(value));
this.refreshTabIndex();
} }
get disabled() { get disabled() {
return this._disabled; return this._disabled;
} }
set readonly(value) {
this._readonly = value;
this.classList.toggle('readonly', Boolean(value));
}
get readonly() {
return this._readonly;
}
onKeydown(event) { onKeydown(event) {
if (event.code == 'Space') if (event.code == 'Space')
this.onClick(event); this.onClick(event);

View File

@ -12,6 +12,9 @@
} }
& > span { & > span {
font-size: $input-font-size; font-size: $input-font-size;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
} }
& > .btn { & > .btn {
position: relative; position: relative;

View File

@ -13,7 +13,7 @@ export default class Tooltip extends Component {
constructor($element, $scope, $timeout) { constructor($element, $scope, $timeout) {
super($element, $scope); super($element, $scope);
this.$timeout = $timeout; this.$timeout = $timeout;
$element.addClass('vn-tooltip mdl-shadow--4dp'); $element.addClass('vn-tooltip vn-shadow');
this.position = 'down'; this.position = 'down';
this.margin = 10; this.margin = 10;
} }

View File

@ -1,110 +1,41 @@
import ngModule from '../module'; import ngModule from '../module';
import FormInput from '../components/form-input';
function vnAcl(aclService, $timeout) { function vnAcl(aclService) {
let acls = []; let acls = [];
function getMaterialType(className) {
let type = '';
if (className) {
type = className.replace('mdl-', '').replace('__input', '');
type = type.charAt(0).toUpperCase() + type.slice(1);
}
return type;
}
function updateMaterial(input) {
if (input && input.className) {
let find = input.className.match(/mdl-[\w]+input/g);
if (find && find.length && find[0]) {
let type = getMaterialType(find[0]);
if (type && input.parentNode[`Material${type}`] && input.parentNode[`Material${type}`].updateClasses_)
input.parentNode[`Material${type}`].updateClasses_();
}
}
}
function getDynamicConditions($attrs) {
let atributes = $attrs.$attr;
let conditions = {};
Object.keys(atributes).forEach(atribute => {
if (atribute.startsWith('aclConditionalTo')) {
let role = atributes[atribute].split('-').slice(-1)[0];
conditions[atribute] = {
role: role
};
}
});
return conditions;
}
function permissionElement($element, action) {
if (!aclService.hasAny(acls)) {
if (action === 'disabled') {
let element = $element[0];
let selector = 'input, textarea, button, submit, md-checkbox';
if (element.$ctrl) {
element.setAttribute('disabled', 'true');
element.$ctrl.disabled = true;
}
if (!element.matches(selector))
element = element.querySelector(selector);
if (element) {
$timeout(() => {
element.setAttribute('disabled', 'true');
updateMaterial(element);
});
$element[0].querySelectorAll('vn-drop-down').forEach(element => {
element.parentNode.removeChild(element);
});
}
} else
$element.remove();
}
}
function updateAcls(role, toAdd) {
let position = acls.indexOf(role);
if (!toAdd && position > -1)
acls.splice(position, 1);
// XXX: add acl and enabled element if previusly was disabled
}
return { return {
restrict: 'A', restrict: 'A',
priority: -1, priority: -1,
link: function($scope, $element, $attrs) { link: function(_, $element, $attrs) {
acls = $attrs.vnAcl.split(',').map(i => i.trim()); acls = $attrs.vnAcl.split(',').map(i => i.trim());
if (acls[0] == '') return; if (acls[0] == '') return;
let action = $attrs.vnAclAction || 'disabled'; let action = $attrs.vnAclAction || 'disable';
let conditions = getDynamicConditions($attrs);
permissionElement($element, action); if (aclService.hasAny(acls)) return;
if (Object.keys(conditions).length) { if (action === 'disable') {
let watchConditions = $scope.$watch(() => { let element = $element[0];
Object.keys(conditions).forEach(attrName => { let elementToDisable = element.$ctrl;
let hasPermission = $scope.$eval($attrs[attrName]);
if (!hasPermission) {
updateAcls(conditions[attrName].role, hasPermission);
permissionElement($element, action);
delete conditions[attrName];
}
});
if (Object.keys(conditions).length === 0) { if (!(elementToDisable instanceof FormInput)) {
// unWacth let selector = 'input, textarea, button, submit';
watchConditions();
} if (!element.matches(selector))
}); element = element.querySelector(selector);
}
elementToDisable = element;
}
if (elementToDisable)
elementToDisable.disabled = true;
} else
$element.remove();
} }
}; };
} }
vnAcl.$inject = ['aclService', '$timeout']; vnAcl.$inject = ['aclService'];
ngModule.directive('vnAcl', vnAcl); ngModule.directive('vnAcl', vnAcl);

View File

@ -1,54 +1,97 @@
describe('Directive acl', () => { describe('Directive acl', () => {
let scope; let $scope;
let $element;
let element; let element;
let compile; let compile;
let $timeout;
beforeEach(angular.mock.module('vnCore', $translateProvider => { beforeEach(angular.mock.module('vnCore', $translateProvider => {
$translateProvider.translations('en', {}); $translateProvider.translations('en', {});
})); }));
compile = (hasPermissions, _element) => { beforeEach(inject(($httpBackend, aclService) => {
inject(($compile, $rootScope, aclService, _$timeout_) => { $httpBackend.whenGET('/api/Accounts/acl')
spyOn(aclService, 'hasAny').and.returnValue(hasPermissions); .respond({
scope = $rootScope.$new(); user: {id: 1, name: 'myUser'},
$timeout = _$timeout_; roles: [
element = angular.element(_element); {role: {name: 'myRole'}},
$compile(element)(scope); {role: {name: 'myOtherRole'}}
scope.$digest(); ]
});
aclService.load();
$httpBackend.flush();
}));
afterEach(() => {
$element.remove();
$scope.$destroy();
});
compile = html => {
inject(($compile, $rootScope) => {
$scope = $rootScope.$new();
$element = $compile(html)($scope);
$scope.$digest();
element = $element[0];
}); });
}; };
it('should not disable the input element as the user has permision', () => { it('should not disable the input element as the user owns the role', () => {
let html = `<div vn-acl="administrative,client" vn-acl-action="disabled"><input/></div>`; let html = `
compile(true, html); <div
let input = element.find('input'); vn-acl="randomRole, myRole"
vn-acl-action="disable">
<input/>
</div>
`;
compile(html);
let input = element.querySelector('input');
expect(input).toBeDefined(); expect(input.disabled).toBeFalsy();
expect(input.attr('disabled')).toBeFalsy();
}); });
it('should delete the element as the user does not have permission and there is no action', () => { it('should disable the element as the action is to disable and the user does not own the role', () => {
let html = `<container><div vn-acl="administrative,client" vn-acl-action="anything but disabled"><input/></div></container>`; let html = `
compile(false, html); <div
vn-acl="unownedRole, randomRole"
vn-acl-action="disable">
<input/>
</div>
`;
compile(html);
let input = element.querySelector('input');
expect(element.children().length).toEqual(0); expect(input.disabled).toBeTruthy();
}); });
it('should disable the element as the action is to disable it but the user has no permission but present', () => { it('should keep the element as the action is to remove and the user owns the role', () => {
let html = `<div vn-acl="administrative,client" vn-acl-action="disabled"><input/></div>`; let html = `
compile(false, html); <section>
let input = element.find('input'); <div
$timeout.flush(); vn-acl="myOtherRole, randomRole"
vn-acl-action="remove">
<input/>
</div>
</section>
`;
compile(html);
let div = element.querySelector('div');
expect(input).toBeDefined(); expect(div).not.toBeNull();
expect(input.attr('disabled')).toBeTruthy();
}); });
it('should delete any element with the tag vn-drop-down', () => { it('should delete the element as the action is to remove and the user does not own the role', () => {
let html = `<div vn-acl="administrative,client" vn-acl-action="disabled"><vn-drop-down></vn-drop-down><input/></div>`; let html = `
compile(false, html); <section>
<div
vn-acl="unownedRole, randomRole"
vn-acl-action="remove">
<input/>
</div>
</section>
`;
compile(html);
let div = element.querySelector('div');
expect(element.find('vn-drop-down').length).toBe(0); expect(div).toBeNull();
}); });
}); });

View File

@ -1,42 +0,0 @@
import Component from './component';
/**
* Component that host an input.
*/
export default class Input extends Component {
constructor($element, $scope) {
super($element, $scope);
this.input = this.element.querySelector('input');
}
set disabled(value) {
this.input.disabled = value == true;
this.mdlUpdate();
}
get disabled() {
return this.input.disabled;
}
select() {
this.input.select();
}
focus() {
this.input.focus();
}
mdlUpdate() {
if (this.mdlElement)
this.mdlElement.updateClasses_();
}
}
Input.$inject = ['$element', '$scope'];
export const $options = {
bindings: {
label: '@?',
disabled: '<?',
readonly: '<?'
}
};

View File

@ -1,7 +1,6 @@
import {ng, ngDeps} from './vendor'; import {ng, ngDeps} from './vendor';
const ngModule = ng.module('vnCore', ngDeps); const ngModule = ng.module('vnCore', ngDeps);
ngModule.constant('moment', require('moment-timezone'));
export default ngModule; export default ngModule;
/** /**
@ -43,6 +42,9 @@ ngModule.vnComponent = function(name, options) {
config.$inject = ['$translateProvider', '$translatePartialLoaderProvider']; config.$inject = ['$translateProvider', '$translatePartialLoaderProvider'];
export function config($translateProvider, $translatePartialLoaderProvider) { export function config($translateProvider, $translatePartialLoaderProvider) {
// For CSS browser targeting
document.documentElement.setAttribute('data-browser', navigator.userAgent);
$translatePartialLoaderProvider.addPart('core'); $translatePartialLoaderProvider.addPart('core');
let conf = {urlTemplate: '/locale/{part}/{lang}.json'}; let conf = {urlTemplate: '/locale/{part}/{lang}.json'};

View File

@ -9,3 +9,9 @@
.item-disabled { .item-disabled {
opacity: $color-disabled; opacity: $color-disabled;
} }
.vn-shadow {
box-shadow: $shadow;
}
.invisible {
visibility: hidden;
}

View File

@ -16,3 +16,26 @@
font-weight: 400; font-weight: 400;
src: url('./icons/Material-Design-Icons.woff2') format('woff2'); src: url('./icons/Material-Design-Icons.woff2') format('woff2');
} }
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Support for IE. */
font-feature-settings: 'liga';
}

View File

@ -0,0 +1,40 @@
@import "variables";
html, body {
background-color: $color-bg;
overflow: auto;
height: 100%;
font-family: vn-font;
color: $color-font;
font-size: 12pt;
margin: 0;
padding: 0;
}
a:focus {
outline: 1px solid $color-spacer-light;
}
input,
button {
&:focus {
outline: none;
}
}
button,
input {
&::-moz-focus-inner {
border: none;
}
}
input[type=submit],
input[type=button],
button {
cursor: pointer;
&:disabled {
opacity: .7;
}
}
a {
color: $color-font-link;
text-decoration: none;
}

View File

@ -1,10 +1,9 @@
import './effects.scss';
import './background.scss'; import './background.scss';
import './border.scss'; import './border.scss';
import './font-family.scss'; import './font-family.scss';
import './global.scss';
import './icons/salixfont.css'; import './icons/salixfont.css';
import './layout.scss'; import './layout.scss';
import './mdl-override.scss';
import './responsive.scss'; import './responsive.scss';
import './spacing.scss'; import './spacing.scss';
import './text.scss'; import './text.scss';

View File

@ -1,61 +0,0 @@
@import "variables";
/**
* Rewrited CSS rules from Material Design Lite.
* FIXME: don't use !important
*/
body {
line-height: initial;
font-size: 12pt;
}
// Textfield
.mdl-textfield--floating-label {
&.is-focused,
&.is-dirty,
&.has-placeholder {
.mdl-textfield__label {
color: $color-main !important;
}
}
}
.mdl-textfield__label::after {
background-color: $color-main !important;
}
fieldset[disabled] .mdl-textfield,
.mdl-textfield.is-disabled {
.mdl-textfield__input {
border: none !important;
color: inherit !important;
}
.mdl-textfield__label {
color: $color-main !important;
}
}
// Button
.mdl-button {
font-weight: bolder;
color: $color-main;
}
.mdl-button--fab {
color: $color-font-dark !important;
background-color: $color-main !important;
}
.mdl-button--colored {
color: $color-font-dark !important;
}
.mdl-button--raised:hover {
background-color: $color-main !important;
}
.mdl-button--colored {
&,
&:focus,
&:active,
&:hover {
background-color: $color-main !important;
}
}

View File

@ -1,5 +1,4 @@
@import "./variables"; @import "./variables";
@import "./font-family";
/* Headings */ /* Headings */
@ -44,7 +43,6 @@ h1, h2, h3, h4, h5, h6 {
padding: 0; padding: 0;
margin-top: 0; margin-top: 0;
margin-bottom: .2em; margin-bottom: .2em;
font-family: vn-font-bold;
} }
/* Colors */ /* Colors */

View File

@ -0,0 +1,6 @@
@mixin browser($browser) {
html[data-browser*="#{$browser}"] & {
@content;
}
}

View File

@ -1,3 +1,4 @@
@import "./util";
$menu-width: 16em; $menu-width: 16em;
$topbar-height: 4em; $topbar-height: 4em;
@ -107,3 +108,4 @@ $color-alert-light: darken($color-alert, 35%);
$border-thin: .05em solid $color-spacer; $border-thin: .05em solid $color-spacer;
$border-thin-light: .05em solid $color-spacer-light; $border-thin-light: .05em solid $color-spacer-light;
$shadow: 0 .15em .15em 0 rgba(0, 0, 0, .3);

View File

@ -7,18 +7,13 @@ import 'angular-translate-loader-partial';
import '@uirouter/angularjs'; import '@uirouter/angularjs';
import 'mg-crud'; import 'mg-crud';
import 'oclazyload'; import 'oclazyload';
import 'angular-moment';
export const ngDeps = [ export const ngDeps = [
'pascalprecht.translate', 'pascalprecht.translate',
'ui.router', 'ui.router',
'mgCrud', 'mgCrud',
'oc.lazyLoad', 'oc.lazyLoad'
'angularMoment'
]; ];
import 'material-design-lite';
import 'material-design-lite/dist/material.orange-deep_orange.min.css';
import * as validator from 'validator'; import * as validator from 'validator';
export {validator}; export {validator};

View File

@ -31,24 +31,6 @@
"resolved": "https://registry.npmjs.org/angular/-/angular-1.7.5.tgz", "resolved": "https://registry.npmjs.org/angular/-/angular-1.7.5.tgz",
"integrity": "sha512-760183yxtGzni740IBTieNuWLtPNAoMqvmC0Z62UoU0I3nqk+VJuO3JbQAXOyvo3Oy/ZsdNQwrSTh/B0OQZjNw==" "integrity": "sha512-760183yxtGzni740IBTieNuWLtPNAoMqvmC0Z62UoU0I3nqk+VJuO3JbQAXOyvo3Oy/ZsdNQwrSTh/B0OQZjNw=="
}, },
"angular-animate": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.7.7.tgz",
"integrity": "sha512-KLbU9gtgCyNSaMZKnNe9Yi6UTlDMN2EWyokQ06TG5fbDWOePm+kv2xqeUg1S2h+ZLjK0NnoVDIvwDhVQ+AWAag=="
},
"angular-aria": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/angular-aria/-/angular-aria-1.7.7.tgz",
"integrity": "sha512-Jju0VudfKVp+6FUtfzpDBuOJE8+8cGPSM10nRicXvJRX/Nx/YOu38f2aL3HQwThrRK+3E5jfo7yRwVNYoSmSxg=="
},
"angular-moment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
"requires": {
"moment": ">=2.8.0 <3.0.0"
}
},
"angular-translate": { "angular-translate": {
"version": "2.18.1", "version": "2.18.1",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.1.tgz", "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.1.tgz",
@ -83,11 +65,6 @@
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
}, },
"flatpickr": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.5.2.tgz",
"integrity": "sha512-jDy4QYGpmiy7+Qk8QvKJ4spjDdxcx9cxMydmq1x427HkKWBw0qizLYeYM2F6tMcvvqGjU5VpJS55j4LnsaBblA=="
},
"js-yaml": { "js-yaml": {
"version": "3.13.1", "version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
@ -97,11 +74,6 @@
"esprima": "^4.0.0" "esprima": "^4.0.0"
} }
}, },
"material-design-lite": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/material-design-lite/-/material-design-lite-1.3.0.tgz",
"integrity": "sha1-0ATOP+6Zoe63Sni4oyUTSl8RcdM="
},
"mg-crud": { "mg-crud": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz", "resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
@ -110,19 +82,6 @@
"angular": "^1.6.1" "angular": "^1.6.1"
} }
}, },
"moment": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"moment-timezone": {
"version": "0.5.25",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz",
"integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==",
"requires": {
"moment": ">= 2.9.0"
}
},
"npm": { "npm": {
"version": "6.11.3", "version": "6.11.3",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.11.3.tgz", "resolved": "https://registry.npmjs.org/npm/-/npm-6.11.3.tgz",

View File

@ -12,16 +12,10 @@
"@babel/polyfill": "^7.2.5", "@babel/polyfill": "^7.2.5",
"@uirouter/angularjs": "^1.0.20", "@uirouter/angularjs": "^1.0.20",
"angular": "^1.7.5", "angular": "^1.7.5",
"angular-animate": "^1.7.7",
"angular-aria": "^1.7.7",
"angular-moment": "^1.3.0",
"angular-translate": "^2.18.1", "angular-translate": "^2.18.1",
"angular-translate-loader-partial": "^2.18.1", "angular-translate-loader-partial": "^2.18.1",
"flatpickr": "^4.5.2",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"material-design-lite": "^1.3.0",
"mg-crud": "^1.1.2", "mg-crud": "^1.1.2",
"moment-timezone": "^0.5.25",
"npm": "^6.11.3", "npm": "^6.11.3",
"oclazyload": "^0.6.3", "oclazyload": "^0.6.3",
"require-yaml": "0.0.1", "require-yaml": "0.0.1",

View File

@ -1,12 +1,5 @@
@import "variables"; @import "variables";
body {
background-color: $color-bg;
overflow: auto;
height: 100%;
font-family: vn-font;
color: $color-font;
}
vn-app { vn-app {
height: inherit; height: inherit;
display: block; display: block;
@ -104,37 +97,3 @@ vn-app {
} }
} }
} }
form vn-horizontal {
align-items: center;
& > * {
box-sizing: border-box;
min-height: 2.8em;
padding: 0 $spacing-sm;
&:first-child {
padding-left: 0;
padding-right: $spacing-xs;
}
&:last-child {
padding-left: $spacing-xs;
padding-right: 0;
}
&:first-child:last-child {
padding: 0;
}
}
@media screen and (max-width: $mobile-width) {
flex-direction: column;
align-items: initial;
& > * {
&,
&:first-child,
&:last-child {
padding: 0;
}
}
}
}

View File

@ -0,0 +1,24 @@
<a ng-if="$ctrl.links.btnOne"
vn-tooltip="{{::$ctrl.links.btnOne.tooltip}}"
class="vn-button colored"
ui-sref="{{::$ctrl.links.btnOne.state}}" target="_blank">
<vn-icon
icon="{{::$ctrl.links.btnOne.icon}}">
</vn-icon>
</a>
<a ng-if="$ctrl.links.btnTwo"
vn-tooltip="{{::$ctrl.links.btnTwo.tooltip}}"
class="vn-button colored"
ui-sref="{{::$ctrl.links.btnTwo.state}}" target="_blank">
<vn-icon
icon="{{::$ctrl.links.btnTwo.icon}}">
</vn-icon>
</a>
<a ng-if="$ctrl.links.btnThree"
vn-tooltip="{{::$ctrl.links.btnThree.tooltip}}"
class="vn-button colored"
ui-sref="{{::$ctrl.links.btnThree.state}}" target="_blank">
<vn-icon
icon="{{::$ctrl.links.btnThree.icon}}">
</vn-icon>
</a>

View File

@ -1 +1,12 @@
import ngModule from '../../module';
import './style.scss'; import './style.scss';
export default class QuickLinks {}
ngModule.component('vnQuickLinks', {
template: require('./index.html'),
controller: QuickLinks,
bindings: {
links: '<?'
}
});

View File

@ -13,15 +13,19 @@
color: $color-font-dark; color: $color-font-dark;
& > * { & > * {
min-width: 1.8em;
@extend %clickable; @extend %clickable;
min-width: 45px;
height: 45px;
box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: .5em;
color: inherit; color: inherit;
& > vn-icon { & > vn-icon {
padding: 10px;
}
vn-icon {
font-size: 1.8em; font-size: 1.8em;
} }
} }
@ -55,28 +59,25 @@
} }
} }
} }
& > .quicklinks { .quicklinks,
vn-quick-links {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 0;
& > a { & > a {
padding: $spacing-sm; padding: 0 $spacing-md;
margin: 0 $spacing-sm;
& > vn-icon { & > vn-icon {
font-size: 1.8em; font-size: 1.8em;
padding: 0; padding: 0;
& > i {
line-height: 36px
}
} }
} }
} }
} }
} }
vn-popover { .vn-popover {
.vn-descriptor > .header > a:first-child { .vn-descriptor > .header > a:first-child {
visibility: hidden; visibility: hidden;
} }

View File

@ -4,7 +4,7 @@
ng-repeat="mod in ::$ctrl.modules" ng-repeat="mod in ::$ctrl.modules"
ui-sref="{{::mod.route.state}}" ui-sref="{{::mod.route.state}}"
translate-attr="::{title: mod.name}" translate-attr="::{title: mod.name}"
class="mdl-shadow--4dp"> class="vn-shadow">
<div> <div>
<vn-icon icon="{{::mod.icon || 'photo'}}"></vn-icon> <vn-icon icon="{{::mod.icon || 'photo'}}"></vn-icon>
</div> </div>

View File

@ -1,11 +1,11 @@
import './app/app'; import './app/app';
import './login/login';
import './home/home';
import './main-menu/main-menu';
import './background/background'; import './background/background';
import './side-menu/side-menu';
import './left-menu/left-menu';
import './topbar/topbar';
import './user-popover';
import './descriptor'; import './descriptor';
import './home/home';
import './left-menu/left-menu';
import './login/login';
import './main-menu/main-menu';
import './topbar/topbar';
import './side-menu/side-menu';
import './summary'; import './summary';
import './user-popover';

View File

@ -4,14 +4,12 @@
<vn-textfield <vn-textfield
label="User" label="User"
ng-model="$ctrl.user" ng-model="$ctrl.user"
name="user"
vn-id="userField" vn-id="userField"
vn-focus> vn-focus>
</vn-textfield> </vn-textfield>
<vn-textfield <vn-textfield
label="Password" label="Password"
ng-model="$ctrl.password" ng-model="$ctrl.password"
name="password"
type="password"> type="password">
</vn-textfield> </vn-textfield>
<vn-check <vn-check

View File

@ -11,8 +11,8 @@ vn-main-menu {
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
& > *:hover { & > * {
color: $color-main; transition: color 250ms ease-out;
} }
& > #user { & > #user {
vertical-align: middle; vertical-align: middle;
@ -20,12 +20,16 @@ vn-main-menu {
margin-right: .2em; margin-right: .2em;
cursor: pointer; cursor: pointer;
} }
& > vn-icon-button { & > .vn-button {
font-size: 2.1em; font-size: 1.2em;
color: inherit; color: inherit;
padding: 0; padding: 0;
margin-left: .3em; margin-left: .3em;
} }
& > :hover {
color: $color-main;
opacity: 1;
}
} }
} }

View File

@ -20,6 +20,7 @@
& > vn-horizontal { & > vn-horizontal {
flex-wrap: wrap; flex-wrap: wrap;
padding: $spacing-md; padding: $spacing-md;
overflow: hidden;
h4 { h4 {
margin-bottom: $spacing-md; margin-bottom: $spacing-md;
@ -28,7 +29,7 @@
line-height: 1; line-height: 1;
padding: 7px; padding: 7px;
padding-bottom: 4px; /* Bottom line-height fix */ padding-bottom: 4px; /* Bottom line-height fix */
font-family: unset; font-weight: lighter;
background-color: $color-main-light; background-color: $color-main-light;
border-bottom: .1em solid $color-main; border-bottom: .1em solid $color-main;
white-space: nowrap; white-space: nowrap;
@ -38,7 +39,6 @@
& > * { & > * {
margin: $spacing-sm; margin: $spacing-sm;
min-width: 14em; min-width: 14em;
overflow: hidden;
padding: 0; padding: 0;
} }
& > vn-auto { & > vn-auto {

View File

@ -1,31 +1,43 @@
@import "./variables"; @import "./variables";
@import "./effects"; @import "./effects";
html, body { form vn-horizontal {
margin: 0; align-items: stretch;
padding: 0;
& > * {
box-sizing: border-box;
min-height: 2.8em;
padding: 0 $spacing-sm;
&:first-child {
padding-left: 0;
padding-right: $spacing-xs;
}
&:last-child {
padding-left: $spacing-xs;
padding-right: 0;
}
&:first-child:last-child {
padding: 0;
}
}
@media screen and (max-width: $mobile-width) {
flex-direction: column;
align-items: initial;
& > * {
&,
&:first-child,
&:last-child {
padding: 0;
}
}
}
} }
a:focus,
input:focus, .link {
button:focus {
outline: none;
}
button::-moz-focus-inner,
input[type=submit]::-moz-focus-inner,
input[type=button]::-moz-focus-inner,
input[type=reset]::-moz-focus-inner {
border: none;
}
.unselectable {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
a, .link {
color: $color-font-link; color: $color-font-link;
text-decoration: none;
outline: 0
} }
.link { .link {
cursor: pointer; cursor: pointer;
@ -34,6 +46,12 @@ a, .link {
text-decoration: underline; text-decoration: underline;
} }
} }
.unselectable {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
vn-bg-title { vn-bg-title {
display: block; display: block;
text-align: center; text-align: center;
@ -77,9 +95,6 @@ html [pointer], .pointer{
html [noDrop], .noDrop{ html [noDrop], .noDrop{
cursor: no-drop; cursor: no-drop;
} }
button {
@extend %clickable;
}
vn-button-bar { vn-button-bar {
display: block; display: block;
margin-top: $spacing-sm; margin-top: $spacing-sm;
@ -91,9 +106,6 @@ vn-tool-bar {
margin-right: .6em; margin-right: .6em;
} }
} }
input[type="submit"]:disabled, button:disabled {
opacity: 0.7;
}
html [scrollable] { html [scrollable] {
min-height: 1px; min-height: 1px;
flex: 1; flex: 1;

View File

@ -80,7 +80,8 @@
vn-tooltip="New zone" vn-tooltip="New zone"
vn-bind="+" vn-bind="+"
fixed-bottom-right> fixed-bottom-right>
<vn-float-button icon="add" <vn-float-button
icon="add"
vn-acl="deliveryBoss" vn-acl="deliveryBoss"
vn-acl-action="remove"> vn-acl-action="remove">
</vn-float-button> </vn-float-button>

View File

@ -28,16 +28,18 @@
ng-click="$ctrl.showLastTickets($event)" ng-click="$ctrl.showLastTickets($event)"
vn-tooltip="Imports ticket lines"> vn-tooltip="Imports ticket lines">
</vn-button> </vn-button>
<vn-input-range <vn-range
vn-one vn-one
label="Responsability" label="Responsability"
value="$ctrl.claim.responsibility" min-label="Company"
max-label="Sales/Client"
ng-model="$ctrl.claim.responsibility"
max="$ctrl.maxResponsibility" max="$ctrl.maxResponsibility"
min="1" min="1"
step="1" step="1"
vn-acl="salesAssistant" vn-acl="salesAssistant"
on-change="$ctrl.saveResponsibility(value)"> on-change="$ctrl.saveResponsibility(value)">
</vn-input-range> </vn-range>
</vn-tool-bar> </vn-tool-bar>
<vn-one <vn-one
style = "text-align:right"> style = "text-align:right">

Some files were not shown because too many files have changed in this diff Show More