2
0
mirror of https://github.com/frappe/books.git synced 2024-09-20 11:29:00 +00:00
books/setup/index.js

136 lines
3.4 KiB
JavaScript
Raw Normal View History

2018-03-28 10:26:24 +00:00
const frappe = require('frappejs');
const utils = require('frappejs/client/ui/utils');
const slideConfigs = require('./config');
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() {
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
}
}