vnDatePicker refactor
This commit is contained in:
parent
7dfd1fe6f2
commit
3bf44d08de
|
@ -6,6 +6,93 @@ import config from './config.js';
|
||||||
|
|
||||||
let currentUser;
|
let currentUser;
|
||||||
|
|
||||||
|
let asyncActions = {
|
||||||
|
// Generic extensions
|
||||||
|
|
||||||
|
clickIfExists: async function(selector) {
|
||||||
|
let exists = await this.exists(selector);
|
||||||
|
if (exists) await this.click(selector);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Salix specific extensions
|
||||||
|
|
||||||
|
changeLanguageToEnglish: async function() {
|
||||||
|
let langSelector = '.user-popover vn-autocomplete[ng-model="$ctrl.lang"]';
|
||||||
|
|
||||||
|
let lang = await this.waitToClick('#user')
|
||||||
|
.wait(langSelector)
|
||||||
|
.waitToGetProperty(`${langSelector} input`, 'value');
|
||||||
|
|
||||||
|
if (lang !== 'English')
|
||||||
|
await this.autocompleteSearch(langSelector, 'English');
|
||||||
|
},
|
||||||
|
|
||||||
|
login: async function(userName) {
|
||||||
|
if (currentUser !== userName) {
|
||||||
|
this.clickIfExists('#logout')
|
||||||
|
.clickIfExists('.vn-dialog.shown button[response=ACCEPT]');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.waitForURL('#!/login');
|
||||||
|
} catch (e) {
|
||||||
|
this.goto(`${config.url}/#!/login`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.wait(`vn-login input[name=user]`)
|
||||||
|
.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('#!/')
|
||||||
|
.changeLanguageToEnglish();
|
||||||
|
|
||||||
|
currentUser = userName;
|
||||||
|
} else
|
||||||
|
await this.waitToClick('vn-topbar a[ui-sref="home"]');
|
||||||
|
},
|
||||||
|
|
||||||
|
waitForLogin: async function(userName) {
|
||||||
|
await this.login(userName);
|
||||||
|
},
|
||||||
|
|
||||||
|
selectModule: async function(moduleName) {
|
||||||
|
let snakeName = moduleName.replace(/[\w]([A-Z])/g, m => {
|
||||||
|
return m[0] + '-' + m[1];
|
||||||
|
}).toLowerCase();
|
||||||
|
|
||||||
|
await this.waitToClick(`vn-home a[ui-sref="${moduleName}.index"]`)
|
||||||
|
.waitForURL(snakeName);
|
||||||
|
},
|
||||||
|
|
||||||
|
loginAndModule: async function(userName, moduleName) {
|
||||||
|
await this.login(userName)
|
||||||
|
.selectModule(moduleName);
|
||||||
|
},
|
||||||
|
|
||||||
|
datePicker: async function(selector, changeMonth, day) {
|
||||||
|
let date = new Date();
|
||||||
|
if (changeMonth) date.setMonth(date.getMonth() + changeMonth);
|
||||||
|
date.setDate(day ? day : 16);
|
||||||
|
date = date.toISOString().substr(0, 10);
|
||||||
|
|
||||||
|
await this.wait(selector)
|
||||||
|
.evaluate((selector, date) => {
|
||||||
|
let input = document.querySelector(selector).$ctrl.input;
|
||||||
|
input.value = date;
|
||||||
|
input.dispatchEvent(new Event('change'));
|
||||||
|
}, selector, date);
|
||||||
|
},
|
||||||
|
|
||||||
|
pickTime: async function(selector, time) {
|
||||||
|
await this.wait(selector)
|
||||||
|
.evaluate((selector, time) => {
|
||||||
|
let input = document.querySelector(selector);
|
||||||
|
input.value = time;
|
||||||
|
input.dispatchEvent(new Event('change'));
|
||||||
|
}, selector, time);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let actions = {
|
let actions = {
|
||||||
clearTextarea: function(selector, done) {
|
clearTextarea: function(selector, done) {
|
||||||
this.wait(selector)
|
this.wait(selector)
|
||||||
|
@ -28,48 +115,6 @@ let actions = {
|
||||||
.catch(done);
|
.catch(done);
|
||||||
},
|
},
|
||||||
|
|
||||||
login: function(userName, done) {
|
|
||||||
if (currentUser)
|
|
||||||
this.waitToClick('#logout');
|
|
||||||
|
|
||||||
let doLogin = () => {
|
|
||||||
this.wait(`vn-login input[name=user]`)
|
|
||||||
.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]`)
|
|
||||||
.then(() => {
|
|
||||||
currentUser = userName;
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
.catch(done);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.waitForURL('#!/login')
|
|
||||||
.then(doLogin)
|
|
||||||
.catch(() => {
|
|
||||||
this.goto(`${config.url}/#!/login`)
|
|
||||||
.then(doLogin)
|
|
||||||
.catch(done);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
waitForLogin: function(userName, done) {
|
|
||||||
if (currentUser === userName) {
|
|
||||||
return this.waitToClick('vn-topbar a[ui-sref="home"]')
|
|
||||||
.waitForURL('#!/')
|
|
||||||
.changeLanguageToEnglish()
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
}
|
|
||||||
return this.login(userName)
|
|
||||||
.waitForURL('#!/')
|
|
||||||
.url()
|
|
||||||
.changeLanguageToEnglish()
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
},
|
|
||||||
|
|
||||||
resetLogin: function(done) {
|
resetLogin: function(done) {
|
||||||
this.then(() => {
|
this.then(() => {
|
||||||
currentUser = undefined;
|
currentUser = undefined;
|
||||||
|
@ -78,41 +123,6 @@ let actions = {
|
||||||
.catch(done);
|
.catch(done);
|
||||||
},
|
},
|
||||||
|
|
||||||
changeLanguageToEnglish: function(done) {
|
|
||||||
let langSelector = '.user-popover vn-autocomplete[ng-model="$ctrl.lang"]';
|
|
||||||
|
|
||||||
this.waitToClick('#user')
|
|
||||||
.wait(langSelector)
|
|
||||||
.waitToGetProperty(`${langSelector} input`, 'value')
|
|
||||||
.then(lang => {
|
|
||||||
if (lang === 'English') {
|
|
||||||
this.then(done)
|
|
||||||
.catch(done);
|
|
||||||
} else {
|
|
||||||
this.autocompleteSearch(langSelector, 'English')
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
selectModule: function(moduleName, done) {
|
|
||||||
let snakeName = moduleName.replace(/[\w]([A-Z])/g, m => {
|
|
||||||
return m[0] + '-' + m[1];
|
|
||||||
}).toLowerCase();
|
|
||||||
this.waitToClick(`vn-home a[ui-sref="${moduleName}.index"]`)
|
|
||||||
.waitForURL(snakeName)
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
},
|
|
||||||
|
|
||||||
loginAndModule: function(userName, moduleName, done) {
|
|
||||||
this.waitForLogin(userName)
|
|
||||||
.selectModule(moduleName)
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
},
|
|
||||||
|
|
||||||
parsedUrl: function(done) {
|
parsedUrl: function(done) {
|
||||||
this.url()
|
this.url()
|
||||||
.then(url => {
|
.then(url => {
|
||||||
|
@ -419,51 +429,6 @@ let actions = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
pickTime: function(selector, time, done) {
|
|
||||||
this.wait(selector)
|
|
||||||
.evaluate((selector, time) => {
|
|
||||||
let input = document.querySelector(selector);
|
|
||||||
input.value = time;
|
|
||||||
input.dispatchEvent(new Event('change'));
|
|
||||||
}, selector, time)
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
},
|
|
||||||
|
|
||||||
datePicker: function(selector, changeMonth, day, done) {
|
|
||||||
this.wait(selector)
|
|
||||||
.mousedown(`${selector} input`)
|
|
||||||
.wait('.flatpickr-calendar.open');
|
|
||||||
|
|
||||||
if (changeMonth > 0)
|
|
||||||
this.mousedown(`.flatpickr-calendar.open .flatpickr-next-month`);
|
|
||||||
if (changeMonth < 0)
|
|
||||||
this.mousedown(`.flatpickr-calendar.open .flatpickr-prev-month`);
|
|
||||||
|
|
||||||
let daySelector;
|
|
||||||
|
|
||||||
if (!day)
|
|
||||||
daySelector = `.flatpickr-calendar.open .flatpickr-day:nth-child(16)`;
|
|
||||||
if (day)
|
|
||||||
daySelector = `.flatpickr-calendar.open .flatpickr-day[aria-label~="${day},"]:not(.prevMonthDay):not(.nextMonthDay)`;
|
|
||||||
|
|
||||||
this.wait(selector => {
|
|
||||||
return document.querySelector(selector);
|
|
||||||
}, daySelector)
|
|
||||||
.evaluate(selector => {
|
|
||||||
let event = new MouseEvent('mousedown', {
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
view: window
|
|
||||||
});
|
|
||||||
document.querySelector(selector).dispatchEvent(event);
|
|
||||||
}, daySelector)
|
|
||||||
.then(done)
|
|
||||||
.catch(() => {
|
|
||||||
done(new Error(`.datePicker(), for ${daySelector} timed out`));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
reloadSection: function(sectionRoute, done) {
|
reloadSection: function(sectionRoute, done) {
|
||||||
this.waitToClick('vn-icon[icon="desktop_windows"]')
|
this.waitToClick('vn-icon[icon="desktop_windows"]')
|
||||||
.wait('vn-card.summary')
|
.wait('vn-card.summary')
|
||||||
|
@ -520,3 +485,13 @@ Object.keys(actions).forEach(function(name) {
|
||||||
let fn = actions[name];
|
let fn = actions[name];
|
||||||
Nightmare.action(name, fn);
|
Nightmare.action(name, fn);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (let name in asyncActions) {
|
||||||
|
let fn = asyncActions[name];
|
||||||
|
|
||||||
|
Nightmare.action(name, function(...args) {
|
||||||
|
let done = args[args.length - 1];
|
||||||
|
fn.apply(this, args)
|
||||||
|
.then(res => done(null, res), done);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
const Nightmare = require('nightmare');
|
const Nightmare = require('nightmare');
|
||||||
|
const config = require('./config.js');
|
||||||
|
|
||||||
let nightmare;
|
let nightmare;
|
||||||
|
|
||||||
module.exports = function createNightmare(width = 1280, height = 720) {
|
module.exports = function createNightmare(width = 1280, height = 720) {
|
||||||
|
@ -22,5 +24,5 @@ module.exports = function createNightmare(width = 1280, height = 720) {
|
||||||
});
|
});
|
||||||
|
|
||||||
nightmare.header('Accept-Language', 'en');
|
nightmare.header('Accept-Language', 'en');
|
||||||
return nightmare;
|
return nightmare.goto(config.url);
|
||||||
};
|
};
|
||||||
|
|
|
@ -420,7 +420,6 @@ export default {
|
||||||
firstSaleQuantity: 'vn-input-number[ng-model="sale.quantity"]:nth-child(1) input',
|
firstSaleQuantity: 'vn-input-number[ng-model="sale.quantity"]:nth-child(1) input',
|
||||||
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)',
|
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)',
|
||||||
firstSaleQuantityClearInput: 'vn-textfield[ng-model="sale.quantity"] div.suffix > i',
|
firstSaleQuantityClearInput: 'vn-textfield[ng-model="sale.quantity"] div.suffix > i',
|
||||||
firstSaleIdInput: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete input',
|
|
||||||
firstSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete',
|
firstSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete',
|
||||||
idAutocompleteFirstResult: '.vn-popover.shown .vn-drop-down li',
|
idAutocompleteFirstResult: '.vn-popover.shown .vn-drop-down li',
|
||||||
firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
|
firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import createNightmare from '../../helpers/nightmare';
|
import createNightmare from '../../helpers/nightmare';
|
||||||
import config from '../../helpers/config.js';
|
|
||||||
|
|
||||||
|
|
||||||
describe('Login path', () => {
|
describe('Login path', () => {
|
||||||
|
@ -10,7 +9,6 @@ describe('Login path', () => {
|
||||||
const password = 'nightmare';
|
const password = 'nightmare';
|
||||||
|
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.goto(`${config.url}/#!/login`)
|
|
||||||
.wait(`vn-login input[name=user]`)
|
.wait(`vn-login input[name=user]`)
|
||||||
.write(`vn-login input[name=user]`, username)
|
.write(`vn-login input[name=user]`, username)
|
||||||
.write(`vn-login input[name=password]`, password)
|
.write(`vn-login input[name=password]`, password)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div
|
<div
|
||||||
class="container"
|
class="container"
|
||||||
ng-click="$ctrl.onContainerMouseDown($event)"
|
ng-click="$ctrl.onContainerClick($event)"
|
||||||
ng-keydown="$ctrl.onContainerKeyDown($event)">
|
ng-keydown="$ctrl.onContainerKeyDown($event)">
|
||||||
<div
|
<div
|
||||||
ng-transclude="prepend"
|
ng-transclude="prepend"
|
||||||
|
@ -48,5 +48,5 @@
|
||||||
vn-id="drop-down"
|
vn-id="drop-down"
|
||||||
on-select="$ctrl.onDropDownSelect(item)"
|
on-select="$ctrl.onDropDownSelect(item)"
|
||||||
on-data-ready="$ctrl.onDataReady()"
|
on-data-ready="$ctrl.onDataReady()"
|
||||||
on-close="$ctrl.focus()">
|
on-close-start="$ctrl.focus()">
|
||||||
</vn-drop-down>
|
</vn-drop-down>
|
|
@ -228,7 +228,7 @@ export default class Autocomplete extends Field {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
onContainerMouseDown(event) {
|
onContainerClick(event) {
|
||||||
if (event.defaultPrevented) return;
|
if (event.defaultPrevented) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.showDropDown();
|
this.showDropDown();
|
||||||
|
@ -260,6 +260,7 @@ export default class Autocomplete extends Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
showDropDown(search) {
|
showDropDown(search) {
|
||||||
|
if (this.readonly) return;
|
||||||
this.assignDropdownProps();
|
this.assignDropdownProps();
|
||||||
this.$.dropDown.show(this.container, search);
|
this.$.dropDown.show(this.container, search);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,4 +20,7 @@ vn-autocomplete.vn-field {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.readonly > .container > .icons.post {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,40 @@
|
||||||
import ngModule from '../../module';
|
import ngModule from '../../module';
|
||||||
import Field from '../field';
|
import Field from '../field';
|
||||||
import {Flatpickr} from '../../vendor';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
class DatePicker extends Field {
|
class DatePicker extends Field {
|
||||||
constructor($element, $scope, $compile, $translate) {
|
constructor($element, $scope, $compile, $translate, $filter) {
|
||||||
super($element, $scope, $compile);
|
super($element, $scope, $compile);
|
||||||
this.$translate = $translate;
|
this.$translate = $translate;
|
||||||
|
this.$filter = $filter;
|
||||||
|
|
||||||
this.input = $compile(`<input type="text"></input>`)($scope)[0];
|
this.input = $compile(`<input type="date"></input>`)($scope)[0];
|
||||||
this.initPicker();
|
this.input.addEventListener('change', () => this.onValueUpdate());
|
||||||
|
}
|
||||||
|
|
||||||
|
onValueUpdate() {
|
||||||
|
let date = null;
|
||||||
|
let value = this.input.value;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
date = new Date(value);
|
||||||
|
|
||||||
|
if (this.field) {
|
||||||
|
let orgDate = this.field instanceof Date
|
||||||
|
? this.field
|
||||||
|
: new Date(this.field);
|
||||||
|
|
||||||
|
date.setHours(
|
||||||
|
orgDate.getHours(),
|
||||||
|
orgDate.getMinutes(),
|
||||||
|
orgDate.getSeconds(),
|
||||||
|
orgDate.getMilliseconds()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.field = date;
|
||||||
|
this.$.$applyAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
get field() {
|
get field() {
|
||||||
|
@ -18,69 +43,10 @@ class DatePicker extends Field {
|
||||||
|
|
||||||
set field(value) {
|
set field(value) {
|
||||||
super.field = value;
|
super.field = value;
|
||||||
|
this.input.value = this.$filter('dateTime')(value, 'yyyy-MM-dd');
|
||||||
let date = value;
|
|
||||||
if (date && !(date instanceof Date))
|
|
||||||
date = new Date(date);
|
|
||||||
|
|
||||||
this.picker.setDate(fixDate(date));
|
|
||||||
}
|
|
||||||
|
|
||||||
set options(value) {
|
|
||||||
let selectedDates = this.picker.selectedDates || [];
|
|
||||||
this._options = value;
|
|
||||||
this.initPicker();
|
|
||||||
this.picker.setDate(selectedDates[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
get options() {
|
|
||||||
return this._options;
|
|
||||||
}
|
|
||||||
|
|
||||||
initPicker() {
|
|
||||||
let locale = this.$translate.use();
|
|
||||||
let format = locale == 'es' ? 'd-m-Y' : 'Y-m-d';
|
|
||||||
|
|
||||||
let options = this.options || {};
|
|
||||||
let defaultOptions = {
|
|
||||||
locale: locale,
|
|
||||||
dateFormat: format,
|
|
||||||
enableTime: false,
|
|
||||||
disableMobile: true,
|
|
||||||
onValueUpdate: () => this.onValueUpdate()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (options.enableTime) {
|
|
||||||
Object.assign(defaultOptions, {
|
|
||||||
dateFormat: `${format} h:i`,
|
|
||||||
time_24hr: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mergedOptions = Object.assign({},
|
|
||||||
defaultOptions,
|
|
||||||
options
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.picker) this.picker.destroy();
|
|
||||||
this.picker = new Flatpickr(this.input, mergedOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
onValueUpdate() {
|
|
||||||
let date = null;
|
|
||||||
|
|
||||||
if (this.picker.selectedDates.length)
|
|
||||||
date = this.picker.selectedDates[0];
|
|
||||||
|
|
||||||
super.field = fixDate(date, -1);
|
|
||||||
this.$.$applyAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
$onDestroy() {
|
|
||||||
this.picker.destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DatePicker.$inject = ['$element', '$scope', '$compile', '$translate'];
|
DatePicker.$inject = ['$element', '$scope', '$compile', '$translate', '$filter'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnDatePicker', {
|
ngModule.vnComponent('vnDatePicker', {
|
||||||
controller: DatePicker,
|
controller: DatePicker,
|
||||||
|
@ -88,12 +54,3 @@ ngModule.vnComponent('vnDatePicker', {
|
||||||
options: '<?'
|
options: '<?'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function fixDate(date, mult = 1) {
|
|
||||||
if (date) {
|
|
||||||
let offset = date.getTimezoneOffset() * 60000;
|
|
||||||
date.setTime(date.getTime() + (offset * mult));
|
|
||||||
}
|
|
||||||
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ describe('Component vnDatePicker', () => {
|
||||||
let $filter;
|
let $filter;
|
||||||
let $element;
|
let $element;
|
||||||
let $ctrl;
|
let $ctrl;
|
||||||
let today;
|
|
||||||
|
|
||||||
beforeEach(angular.mock.module('vnCore', $translateProvider => {
|
beforeEach(angular.mock.module('vnCore', $translateProvider => {
|
||||||
$translateProvider.translations('en', {});
|
$translateProvider.translations('en', {});
|
||||||
|
@ -13,9 +12,6 @@ describe('Component vnDatePicker', () => {
|
||||||
|
|
||||||
$element = $compile(`<vn-date-picker></vn-date-picker>`)($rootScope);
|
$element = $compile(`<vn-date-picker></vn-date-picker>`)($rootScope);
|
||||||
$ctrl = $element.controller('vnDatePicker');
|
$ctrl = $element.controller('vnDatePicker');
|
||||||
|
|
||||||
today = new Date();
|
|
||||||
today.setUTCHours(0, 0, 0, 0);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -24,22 +20,14 @@ describe('Component vnDatePicker', () => {
|
||||||
|
|
||||||
describe('field() setter', () => {
|
describe('field() setter', () => {
|
||||||
it(`should display the formated the date`, () => {
|
it(`should display the formated the date`, () => {
|
||||||
$ctrl.field = today;
|
let today;
|
||||||
|
today = new Date();
|
||||||
|
today.setUTCHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
$ctrl.field = today;
|
||||||
let displayed = $filter('dateTime')(today, 'yyyy-MM-dd');
|
let displayed = $filter('dateTime')(today, 'yyyy-MM-dd');
|
||||||
|
|
||||||
expect($ctrl.value).toEqual(displayed);
|
expect($ctrl.value).toEqual(displayed);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('options() setter', () => {
|
|
||||||
it(`should display the date with the new format`, () => {
|
|
||||||
$ctrl.options = {dateFormat: 'Y-m'};
|
|
||||||
$ctrl.field = today;
|
|
||||||
|
|
||||||
let displayed = $filter('dateTime')(today, 'yyyy-MM');
|
|
||||||
|
|
||||||
expect($ctrl.value).toEqual(displayed);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<vn-popover
|
<vn-popover
|
||||||
vn-id="popover"
|
vn-id="popover"
|
||||||
on-open="$ctrl.onOpen()"
|
on-open="$ctrl.onOpen()"
|
||||||
on-close="$ctrl.onClose()">
|
on-close="$ctrl.onClose()"
|
||||||
|
on-close-start="$ctrl.emit('closeStart')">
|
||||||
<div class="vn-drop-down">
|
<div class="vn-drop-down">
|
||||||
<div ng-show="$ctrl.showFilter" class="filter">
|
<div ng-show="$ctrl.showFilter" class="filter">
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
|
|
|
@ -193,7 +193,7 @@ export default class DropDown extends Component {
|
||||||
onOpen() {
|
onOpen() {
|
||||||
this.document.addEventListener('keydown', this.docKeyDownHandler);
|
this.document.addEventListener('keydown', this.docKeyDownHandler);
|
||||||
this.$.list.scrollTop = 0;
|
this.$.list.scrollTop = 0;
|
||||||
this.$.input.focus();
|
setTimeout(() => this.$.input.focus());
|
||||||
this.emit('open');
|
this.emit('open');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,10 +69,12 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +183,8 @@ export default class Field extends FormInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick() {
|
onClick() {
|
||||||
if (event.defaultPrevented) return;
|
// if (event.defaultPrevented) return;
|
||||||
event.preventDefault();
|
// event.preventDefault();
|
||||||
|
|
||||||
if (this.input !== document.activeElement)
|
if (this.input !== document.activeElement)
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
|
@ -64,12 +64,33 @@
|
||||||
color: inherit;
|
color: inherit;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-height: 56px;
|
min-height: 56px;
|
||||||
|
}
|
||||||
|
& > input {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&[type=time],
|
||||||
|
&[type=date],
|
||||||
|
&[type=password] {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 200ms ease-in-out;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
&[type=time],
|
&[type=time],
|
||||||
&[type=date] {
|
&[type=date] {
|
||||||
clip-path: inset(0 20px 0 0);
|
clip-path: inset(0 20px 0 0);
|
||||||
|
|
||||||
|
&::-webkit-inner-spin-button,
|
||||||
|
&::-webkit-clear-button {
|
||||||
|
display: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
&::-webkit-calendar-picker-indicator {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 200ms ease-in-out;
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&[type=number] {
|
&[type=number] {
|
||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
|
@ -83,6 +104,15 @@
|
||||||
&:invalid {
|
&:invalid {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
&:-internal-autofill-selected {
|
||||||
|
&,
|
||||||
|
&:hover,
|
||||||
|
&:focus,
|
||||||
|
&:active,
|
||||||
|
&:valid {
|
||||||
|
box-shadow: 0 0 0 40px $color-bg-panel inset;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +202,8 @@
|
||||||
}
|
}
|
||||||
& > .control > * {
|
& > .control > * {
|
||||||
&[type=time],
|
&[type=time],
|
||||||
&[type=date] {
|
&[type=date],
|
||||||
|
&[type=password] {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,10 @@ export default class InputTime extends Field {
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
let split = value.split(':').map(i => parseInt(i) || null);
|
let split = value.split(':').map(i => parseInt(i) || null);
|
||||||
date = new Date(this.field || null);
|
|
||||||
|
date = this.field instanceof Date
|
||||||
|
? this.field
|
||||||
|
: new Date(this.field || null);
|
||||||
date.setHours(split[0], split[1], 0, 0);
|
date.setHours(split[0], split[1], 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ export default class Popover extends Component {
|
||||||
this.showTimeout = null;
|
this.showTimeout = null;
|
||||||
this.element.style.display = 'none';
|
this.element.style.display = 'none';
|
||||||
this.document.body.removeChild(this.element);
|
this.document.body.removeChild(this.element);
|
||||||
|
this.emit('close');
|
||||||
}, 250);
|
}, 250);
|
||||||
|
|
||||||
this.document.removeEventListener('keydown', this.docKeyDownHandler);
|
this.document.removeEventListener('keydown', this.docKeyDownHandler);
|
||||||
|
@ -118,7 +119,7 @@ export default class Popover extends Component {
|
||||||
this.bgMouseDownHandler = null;
|
this.bgMouseDownHandler = null;
|
||||||
|
|
||||||
if (this.deregisterCallback) this.deregisterCallback();
|
if (this.deregisterCallback) this.deregisterCallback();
|
||||||
this.emit('close');
|
this.emit('closeStart');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default class Controller extends Component {
|
||||||
|
|
||||||
this.$panelScope = this.$.$new();
|
this.$panelScope = this.$.$new();
|
||||||
this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);
|
this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);
|
||||||
let panel = this.$panel.isolateScope().$ctrl;
|
let panel = this.$panel[0].$ctrl;
|
||||||
if (this.shownFilter)
|
if (this.shownFilter)
|
||||||
panel.filter = JSON.parse(JSON.stringify(this.shownFilter));
|
panel.filter = JSON.parse(JSON.stringify(this.shownFilter));
|
||||||
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
const regex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i;
|
||||||
|
export const isMobile = regex.test(navigator.userAgent);
|
||||||
|
|
||||||
export function focus(input) {
|
export function focus(input) {
|
||||||
|
if (isMobile) return;
|
||||||
|
|
||||||
const element = input;
|
const element = input;
|
||||||
let selector = 'input, textarea, button, submit';
|
let selector = 'input, textarea, button, submit';
|
||||||
|
|
||||||
|
@ -14,7 +19,6 @@ export function focus(input) {
|
||||||
view: window
|
view: window
|
||||||
});
|
});
|
||||||
element.dispatchEvent(focusEvent);
|
element.dispatchEvent(focusEvent);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,3 @@ 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};
|
||||||
|
|
||||||
import Flatpickr from 'flatpickr';
|
|
||||||
import 'flatpickr/dist/flatpickr.css';
|
|
||||||
import 'flatpickr/dist/themes/material_orange.css';
|
|
||||||
import l10ns from 'flatpickr/dist/l10n';
|
|
||||||
Flatpickr.l10ns = l10ns;
|
|
||||||
export {Flatpickr};
|
|
||||||
|
|
|
@ -88,21 +88,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.5.2.tgz",
|
||||||
"integrity": "sha512-jDy4QYGpmiy7+Qk8QvKJ4spjDdxcx9cxMydmq1x427HkKWBw0qizLYeYM2F6tMcvvqGjU5VpJS55j4LnsaBblA=="
|
"integrity": "sha512-jDy4QYGpmiy7+Qk8QvKJ4spjDdxcx9cxMydmq1x427HkKWBw0qizLYeYM2F6tMcvvqGjU5VpJS55j4LnsaBblA=="
|
||||||
},
|
},
|
||||||
"fs-extra": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
|
|
||||||
"requires": {
|
|
||||||
"graceful-fs": "^4.1.2",
|
|
||||||
"jsonfile": "^4.0.0",
|
|
||||||
"universalify": "^0.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"graceful-fs": {
|
|
||||||
"version": "4.1.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.10.tgz",
|
|
||||||
"integrity": "sha1-8tcgwiCS90Mih3XHXjYSYyUB8TE="
|
|
||||||
},
|
|
||||||
"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",
|
||||||
|
@ -112,14 +97,6 @@
|
||||||
"esprima": "^4.0.0"
|
"esprima": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jsonfile": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
|
||||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
|
||||||
"requires": {
|
|
||||||
"graceful-fs": "^4.1.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"material-design-lite": {
|
"material-design-lite": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/material-design-lite/-/material-design-lite-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/material-design-lite/-/material-design-lite-1.3.0.tgz",
|
||||||
|
@ -3229,11 +3206,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||||
},
|
},
|
||||||
"universalify": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
|
||||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
|
||||||
},
|
|
||||||
"validator": {
|
"validator": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
"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",
|
"flatpickr": "^4.5.2",
|
||||||
"fs-extra": "^5.0.0",
|
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
"material-design-lite": "^1.3.0",
|
"material-design-lite": "^1.3.0",
|
||||||
"mg-crud": "^1.1.2",
|
"mg-crud": "^1.1.2",
|
||||||
|
|
|
@ -8,23 +8,18 @@
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
|
||||||
<vn-card class="vn-pa-lg">
|
<vn-card class="vn-pa-lg">
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
disabled="true"
|
|
||||||
ng-model="$ctrl.claim.clientFk"
|
|
||||||
url="/client/api/Clients"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
label="Client"
|
label="Client"
|
||||||
order="id">
|
ng-model="$ctrl.claim.client.name"
|
||||||
</vn-autocomplete>
|
readonly="true">
|
||||||
<vn-date-picker
|
</vn-textfield>
|
||||||
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
disabled="true"
|
|
||||||
label="Created"
|
label="Created"
|
||||||
ng-model="$ctrl.claim.created"
|
field="::$ctrl.claim.created | dateTime:'yyyy-MM-dd hh:mm'"
|
||||||
options="{enableTime: true}">
|
readonly="true">
|
||||||
</vn-date-picker>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
|
|
|
@ -32,21 +32,26 @@
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-id="country"
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
|
vn-id="country"
|
||||||
ng-model="$ctrl.client.countryFk"
|
ng-model="$ctrl.client.countryFk"
|
||||||
url="/api/Countries"
|
url="/api/Countries"
|
||||||
show-field="country"
|
show-field="country"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Country">
|
label="Country"
|
||||||
|
rule>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete vn-id="province" vn-one
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
vn-id="province"
|
||||||
ng-model="$ctrl.client.provinceFk"
|
ng-model="$ctrl.client.provinceFk"
|
||||||
url="/api/Provinces"
|
url="/api/Provinces"
|
||||||
where="{countryFk: country.selection.id}"
|
where="{countryFk: country.selection.id}"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Province">
|
label="Province"
|
||||||
|
rule>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
|
|
@ -151,7 +151,7 @@ class Controller {
|
||||||
|
|
||||||
this.$panelScope = this.$scope.$new();
|
this.$panelScope = this.$scope.$new();
|
||||||
this.$panel = this.$compile(`<vn-order-catalog-search-panel/>`)(this.$panelScope);
|
this.$panel = this.$compile(`<vn-order-catalog-search-panel/>`)(this.$panelScope);
|
||||||
const panel = this.$panel.isolateScope().$ctrl;
|
const panel = this.$panel[0].$ctrl;
|
||||||
panel.filter = this.filter;
|
panel.filter = this.filter;
|
||||||
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,12 @@
|
||||||
value-field="id"
|
value-field="id"
|
||||||
ng-model="$ctrl.addressId"
|
ng-model="$ctrl.addressId"
|
||||||
order="isActive DESC">
|
order="isActive DESC">
|
||||||
<tpl-item ng-class="::{notActive: isActive === false}">
|
<tpl-item class="address" ng-class="::{inactive: !isActive}">
|
||||||
<span class="inactive" translate>{{::isActive ? '' : 'INACTIVE'}}</span> {{::nickname}}
|
<span class="inactive" translate>{{::!isActive ? '(Inactive)' : ''}}</span>
|
||||||
<span ng-show="city || province || street">- {{::street}} - {{::city}} - {{::province.name}} - {{::agencyMode.name}}</span>
|
{{::nickname}}
|
||||||
|
<span ng-show="city || province || street">
|
||||||
|
, {{::street}}, {{::city}}, {{::province.name}} - {{::agencyMode.name}}
|
||||||
|
</span>
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
|
@ -43,15 +46,22 @@
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
vn-one
|
vn-one
|
||||||
label="Shipped"
|
label="Shipped"
|
||||||
ng-model="$ctrl.shipped"
|
ng-model="$ctrl.shipped">
|
||||||
options="{enableTime: true}">
|
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
|
<vn-input-time
|
||||||
|
vn-one
|
||||||
|
label="Shipped hour"
|
||||||
|
ng-model="$ctrl.shipped">
|
||||||
|
</vn-input-time>
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
vn-one
|
vn-one
|
||||||
label="Landed"
|
label="Landed"
|
||||||
ng-model="$ctrl.landed">
|
ng-model="$ctrl.landed">
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
<vn-autocomplete vn-one
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
url="/api/Companies"
|
url="/api/Companies"
|
||||||
label="Company"
|
label="Company"
|
||||||
show-field="code"
|
show-field="code"
|
||||||
|
@ -59,16 +69,16 @@
|
||||||
ng-model="$ctrl.ticket.companyFk"
|
ng-model="$ctrl.ticket.companyFk"
|
||||||
initial-data="$ctrl.ticket.companyFk">
|
initial-data="$ctrl.ticket.companyFk">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
<vn-autocomplete
|
||||||
<vn-horizontal>
|
vn-one
|
||||||
<vn-autocomplete vn-one
|
|
||||||
url="/api/AgencyModes/isActive"
|
url="/api/AgencyModes/isActive"
|
||||||
label="Agency"
|
label="Agency"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
ng-model="$ctrl.agencyModeId">
|
ng-model="$ctrl.agencyModeId">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
data="zones"
|
data="zones"
|
||||||
label="Zone"
|
label="Zone"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
tpl-item{
|
.vn-popover {
|
||||||
&.notActive {
|
.address.inactive {
|
||||||
background-color: $color-bg;
|
|
||||||
color: $color-font-secondary;
|
color: $color-font-secondary;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .inactive {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,8 +107,8 @@ let baseConfig = {
|
||||||
],
|
],
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
stats: {
|
stats: {
|
||||||
modules: false,
|
|
||||||
assets: false,
|
assets: false,
|
||||||
|
modules: false,
|
||||||
children: false,
|
children: false,
|
||||||
entrypoints: false,
|
entrypoints: false,
|
||||||
colors: true
|
colors: true
|
||||||
|
|
Loading…
Reference in New Issue