2018-03-28 10:26:24 +00:00
|
|
|
const frappe = require('frappejs');
|
|
|
|
const utils = require('frappejs/client/ui/utils');
|
|
|
|
const slideConfigs = require('./config');
|
|
|
|
const Tree = require('frappejs/client/ui/tree');
|
|
|
|
const FormLayout = require('frappejs/client/view/formLayout');
|
2018-03-30 17:02:28 +00:00
|
|
|
const Observable = require('frappejs/utils/observable');
|
2018-03-28 10:26:24 +00:00
|
|
|
|
|
|
|
module.exports = class SetupWizard {
|
2018-03-30 17:02:28 +00:00
|
|
|
constructor() {
|
|
|
|
this.slideCount = slideConfigs.layout.length;
|
2018-03-28 10:26:24 +00:00
|
|
|
this.indicatorList = [];
|
2018-03-28 11:15:43 +00:00
|
|
|
|
|
|
|
this.currentIndex = 0;
|
2018-03-30 17:02:28 +00:00
|
|
|
this.doc = new Observable();
|
|
|
|
|
|
|
|
this.promise = new Promise(resolve => {
|
|
|
|
this.onComplete = resolve;
|
|
|
|
});
|
|
|
|
|
|
|
|
this.footerButtons = [
|
|
|
|
{
|
|
|
|
label: 'Prev', name: 'prev',
|
|
|
|
action: this.prevSlide.bind(this),
|
|
|
|
condition: index => index !== 0
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Next', name: 'next',
|
|
|
|
action: this.nextSlide.bind(this),
|
|
|
|
condition: index => index !== this.slideCount - 1
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: 'Complete', name: 'complete',
|
|
|
|
action: this.onComplete.bind(this, this.doc),
|
|
|
|
condition: index => index === this.slideCount - 1
|
|
|
|
}
|
|
|
|
];
|
2018-03-28 10:26:24 +00:00
|
|
|
|
2018-03-28 11:15:43 +00:00
|
|
|
this.make();
|
2018-03-30 17:02:28 +00:00
|
|
|
}
|
2018-03-28 10:26:24 +00:00
|
|
|
|
2018-03-30 17:02:28 +00:00
|
|
|
async start() {
|
|
|
|
this.showSlide(0);
|
|
|
|
return this.promise;
|
2018-03-28 11:15:43 +00:00
|
|
|
}
|
2018-03-28 10:26:24 +00:00
|
|
|
|
2018-03-28 11:15:43 +00:00
|
|
|
make() {
|
|
|
|
let body = document.querySelector('body');
|
|
|
|
this.container = frappe.ui.add('form', 'setup-container container', body);
|
2018-03-28 10:26:24 +00:00
|
|
|
this.$indicators = frappe.ui.add('div', 'indicators vertical-margin align-center', this.container);
|
|
|
|
|
2018-03-28 11:15:43 +00:00
|
|
|
this.makeSlides();
|
2018-03-30 17:02:28 +00:00
|
|
|
this.makeButtons();
|
2018-03-28 11:15:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
makeSlides() {
|
2018-03-30 17:02:28 +00:00
|
|
|
this.formLayout = new FormLayout(Object.assign(slideConfigs, {
|
|
|
|
doc: this.doc
|
|
|
|
}));
|
|
|
|
this.container.appendChild(this.formLayout.form);
|
2018-03-28 10:26:24 +00:00
|
|
|
|
2018-03-30 17:02:28 +00:00
|
|
|
slideConfigs.layout.forEach(() => {
|
|
|
|
// indicator for each section
|
2018-03-28 11:15:43 +00:00
|
|
|
let indicator = frappe.ui.create('span', {
|
|
|
|
inside: this.$indicators,
|
|
|
|
className: 'indicator gray'
|
2018-03-30 17:02:28 +00:00
|
|
|
});
|
2018-03-28 10:26:24 +00:00
|
|
|
this.indicatorList.push(indicator);
|
|
|
|
});
|
2018-03-30 17:02:28 +00:00
|
|
|
|
2018-03-28 11:15:43 +00:00
|
|
|
}
|
2018-03-28 10:26:24 +00:00
|
|
|
|
2018-03-30 17:02:28 +00:00
|
|
|
makeButtons() {
|
2018-03-28 10:26:24 +00:00
|
|
|
this.linkArea = frappe.ui.add('div', 'setup-link-area align-right', this.container);
|
|
|
|
|
2018-03-30 17:02:28 +00:00
|
|
|
this.footerButtons.map(link => {
|
|
|
|
link.element = utils.addButton(link.label, this.linkArea, link.action);
|
2018-03-28 11:15:43 +00:00
|
|
|
});
|
2018-03-28 10:26:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
showSlide(index) {
|
2018-03-30 17:02:28 +00:00
|
|
|
this.currentIndex = index;
|
|
|
|
utils.activate(this.container, `.form-section:nth-child(${index + 1})`, '.form-section', 'active');
|
2018-03-28 10:26:24 +00:00
|
|
|
this.activateIndicator(index);
|
2018-03-28 11:15:43 +00:00
|
|
|
this.showFooterLinks(index);
|
2018-03-28 10:26:24 +00:00
|
|
|
}
|
|
|
|
|
2018-03-28 11:15:43 +00:00
|
|
|
prevSlide() {
|
|
|
|
this.showSlide(this.currentIndex - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
nextSlide() {
|
2018-04-02 17:06:16 +00:00
|
|
|
const isValid = this.validateCurrentSlide();
|
|
|
|
frappe.ui.toggleClass(this.formLayout.sections[this.currentIndex], 'was-validated', !isValid);
|
|
|
|
|
|
|
|
if (isValid) {
|
|
|
|
this.showSlide(this.currentIndex + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
validateCurrentSlide() {
|
|
|
|
const fields = this.getFieldsInSlide(this.currentIndex);
|
|
|
|
const inputValidityMap = fields.map(field => this.formLayout.controls[field].input.checkValidity());
|
|
|
|
const isValid = !inputValidityMap.includes(false);
|
|
|
|
return isValid;
|
|
|
|
}
|
|
|
|
|
|
|
|
getFieldsInSlide(index) {
|
|
|
|
const visibleSection = slideConfigs.layout[index];
|
|
|
|
const fieldsInSlide = visibleSection.fields ||
|
|
|
|
visibleSection.columns.reduce(
|
|
|
|
(col, fields) => fields.concat(col.fields), []
|
|
|
|
);
|
|
|
|
|
|
|
|
return fieldsInSlide;
|
2018-03-28 11:15:43 +00:00
|
|
|
}
|
|
|
|
|
2018-03-28 10:26:24 +00:00
|
|
|
activateIndicator(index) {
|
2018-03-30 17:02:28 +00:00
|
|
|
this.indicatorList.forEach(indicator => indicator.classList.add('gray'));
|
2018-03-28 10:26:24 +00:00
|
|
|
let indicator = this.indicatorList[index];
|
2018-03-30 17:02:28 +00:00
|
|
|
utils.activate(this.$indicators, indicator, '.gray', 'blue', index);
|
2018-03-28 10:26:24 +00:00
|
|
|
|
|
|
|
frappe.ui.removeClass(indicator, 'gray');
|
|
|
|
indicator.classList.remove('gray');
|
|
|
|
}
|
|
|
|
|
2018-03-28 11:15:43 +00:00
|
|
|
showFooterLinks(index) {
|
2018-03-30 17:02:28 +00:00
|
|
|
this.footerButtons.map(link => {
|
|
|
|
const show = link.condition(this.currentIndex);
|
|
|
|
if (show) {
|
|
|
|
link.element.classList.remove('hide');
|
|
|
|
} else {
|
|
|
|
link.element.classList.add('hide');
|
2018-03-28 11:15:43 +00:00
|
|
|
}
|
2018-03-30 17:02:28 +00:00
|
|
|
})
|
2018-03-28 10:26:24 +00:00
|
|
|
}
|
|
|
|
}
|