Merge branch 'rebrand-ui' of https://github.com/frappe/frappe into rebrand-ui

This commit is contained in:
prssanna 2020-10-29 14:20:11 +05:30
commit a5cf86f806
7 changed files with 290 additions and 151 deletions

View file

@ -9,36 +9,34 @@ frappe.setup = {
utils: {},
domains: [],
on: function(event, fn) {
if(!frappe.setup.events[event]) {
on: function (event, fn) {
if (!frappe.setup.events[event]) {
frappe.setup.events[event] = [];
}
frappe.setup.events[event].push(fn);
},
add_slide: function(slide) {
add_slide: function (slide) {
frappe.setup.slides.push(slide);
},
remove_slide: function(slide_name){
remove_slide: function (slide_name) {
frappe.setup.slides = frappe.setup.slides.filter((slide) => slide.name !== slide_name);
},
run_event: function(event) {
$.each(frappe.setup.events[event] || [], function(i, fn) {
run_event: function (event) {
$.each(frappe.setup.events[event] || [], function (i, fn) {
fn();
});
}
}
frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
frappe.pages['setup-wizard'].on_page_load = function (wrapper) {
let requires = (frappe.boot.setup_wizard_requires || []);
frappe.require(requires, function() {
frappe.require(requires, function () {
frappe.call({
method: "frappe.desk.page.setup_wizard.setup_wizard.load_languages",
freeze: true,
callback: function(r) {
callback: function (r) {
frappe.setup.data.lang = r.message;
frappe.setup.run_event("before_load");
@ -47,12 +45,13 @@ frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
slides: frappe.setup.slides,
slide_class: frappe.setup.SetupWizardSlide,
unidirectional: 1,
done_state: 1,
before_load: ($footer) => {
$footer.find('.next-btn').removeClass('btn-default')
.addClass('btn-primary');
$footer.find('.text-right').prepend(
$(`<a class="complete-btn btn btn-sm primary">
${__("Complete Setup")}</a>`));
$(`<button class="complete-btn btn btn-sm primary">
${__("Complete Setup")}</button>`));
}
}
@ -60,7 +59,7 @@ frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
frappe.setup.run_event("after_load");
// frappe.wizard.values = test_values_edu;
let route = frappe.get_route();
if(route) {
if (route) {
frappe.wizard.show_slide(route[1]);
}
}
@ -68,16 +67,16 @@ frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
});
};
frappe.pages['setup-wizard'].on_page_show = function(wrapper) {
if(frappe.get_route()[1]) {
frappe.pages['setup-wizard'].on_page_show = function (wrapper) {
if (frappe.get_route()[1]) {
frappe.wizard && frappe.wizard.show_slide(frappe.get_route()[1]);
}
};
frappe.setup.on("before_load", function() {
frappe.setup.on("before_load", function () {
// load slides
frappe.setup.slides_settings.forEach((s) => {
if(!(s.name==='user' && frappe.boot.developer_mode)) {
if (!(s.name === 'user' && frappe.boot.developer_mode)) {
// if not user slide with developer mode
frappe.setup.add_slide(s);
}
@ -113,7 +112,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
handle_enter_press(e) {
if (e.which === frappe.ui.keyCode.ENTER) {
var $target = $(e.target);
if($target.hasClass('prev-btn')) {
if ($target.hasClass('prev-btn')) {
$target.trigger('click');
} else {
this.container.find('.next-btn').trigger('click');
@ -123,7 +122,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
}
before_show_slide() {
if(!this.welcomed) {
if (!this.welcomed) {
frappe.set_route(this.page_name);
return false;
}
@ -142,7 +141,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
show_hide_prev_next(id) {
super.show_hide_prev_next(id);
if (id + 1 === this.slides.length){
if (id + 1 === this.slides.length) {
this.$next_btn.removeClass("btn-primary").hide();
this.$complete_btn.addClass("btn-primary").show()
.on('click', this.action_on_complete.bind(this));
@ -155,7 +154,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
refresh_slides() {
// For Translations, etc.
if(this.in_refresh_slides || !this.current_slide.set_values()) {
if (this.in_refresh_slides || !this.current_slide.set_values()) {
return;
}
this.in_refresh_slides = true;
@ -171,7 +170,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
// re-render all slide, only remake made slides
$.each(this.slide_dict, (id, slide) => {
if(slide.made) {
if (slide.made) {
this.made_slide_ids.push(id);
}
});
@ -194,11 +193,11 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
return frappe.call({
method: "frappe.desk.page.setup_wizard.setup_wizard.setup_complete",
args: {args: this.values},
args: { args: this.values },
callback: (r) => {
if(r.message.status === 'ok') {
if (r.message.status === 'ok') {
this.post_setup_success();
} else if(r.message.fail !== undefined) {
} else if (r.message.fail !== undefined) {
this.abort_setup(r.message.fail);
}
},
@ -208,16 +207,16 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
post_setup_success() {
this.set_setup_complete_message(__("Setup Complete"), __("Refreshing..."));
if(frappe.setup.welcome_page) {
if (frappe.setup.welcome_page) {
localStorage.setItem("session_last_route", frappe.setup.welcome_page);
}
setTimeout(function() {
setTimeout(function () {
// Reload
window.location.href = '/desk';
}, 2000);
}
abort_setup(fail_msg, error=false) {
abort_setup(fail_msg, error = false) {
this.$working_state.find('.state-icon-container').html('');
fail_msg = fail_msg ? fail_msg : __("Failed to complete setup");
@ -231,12 +230,12 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
listen_for_setup_stages() {
frappe.realtime.on("setup_task", (data) => {
// console.log('data', data);
if(data.stage_status) {
if (data.stage_status) {
// .html('Process '+ data.progress[0] + ' of ' + data.progress[1] + ': ' + data.stage_status);
this.update_setup_message(data.stage_status);
this.set_setup_load_percent((data.progress[0]+1)/data.progress[1] * 100);
this.set_setup_load_percent((data.progress[0] + 1) / data.progress[1] * 100);
}
if(data.fail_msg) {
if (data.fail_msg) {
this.abort_setup(data.fail_msg);
}
})
@ -248,8 +247,8 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
get_setup_slides_filtered_by_domain() {
var filtered_slides = [];
frappe.setup.slides.forEach(function(slide) {
if(frappe.setup.domains) {
frappe.setup.slides.forEach(function (slide) {
if (frappe.setup.domains) {
let active_domains = frappe.setup.domains;
if (!slide.domains ||
slide.domains.filter(d => active_domains.includes(d)).length > 0) {
@ -277,8 +276,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
}
attach_abort_button() {
this.$abort_btn = $(`<button class='btn btn-default btn-xs text-muted'
style="margin-bottom: 30px;">${__('Retry')}</button>`);
this.$abort_btn = $(`<button class='btn btn-secondary btn-xs btn-abort text-muted'>${__('Retry')}</button>`);
this.$working_state.find('.content').append(this.$abort_btn);
this.$abort_btn.on('click', () => {
@ -290,18 +288,18 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
this.$abort_btn.hide();
}
get_message(title, message="") {
const loading_html = `<div class="progress-chart" style ="width: 150px;">
<div class="progress" style="margin-top: 70px; margin-bottom: 0px">
<div class="progress-bar" style="width: 2%; background-color: #5e64ff;"></div>
get_message(title, message = "") {
const loading_html = `<div class="progress-chart">
<div class="progress">
<div class="progress-bar"></div>
</div>
</div>`;
return $(`<div class="slides-wrapper setup-wizard-slide setup-in-progress">
return $(`<div class="slides-wrapper container setup-wizard-slide setup-in-progress">
<div class="content text-center">
<p class="title lead">${title}</p>
<h1 class="slide-title title">${title}</h1>
<div class="state-icon-container">${loading_html}</div>
<p class="setup-message text-muted" style="margin: 30px 0px;">${message}</p>
<p class="setup-message text-muted">${message}</p>
</div>
</div>`);
}
@ -312,7 +310,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
}
set_setup_load_percent(percent) {
this.$working_state.find('.progress-bar').css({"width": percent + "%"});
this.$working_state.find('.progress-bar').css({ "width": percent + "%" });
}
};
@ -327,13 +325,13 @@ frappe.setup.SetupWizardSlide = class SetupWizardSlide extends frappe.ui.Slide {
this.reset_action_button_state();
}
set_init_values () {
set_init_values() {
var me = this;
// set values from frappe.setup.values
if(frappe.wizard.values && this.fields) {
this.fields.forEach(function(f) {
if (frappe.wizard.values && this.fields) {
this.fields.forEach(function (f) {
var value = frappe.wizard.values[f.fieldname];
if(value) {
if (value) {
me.get_field(f.fieldname).set_input(value);
}
});
@ -354,11 +352,13 @@ frappe.setup.slides_settings = [
// help: __("Let's prepare the system for first use."),
fields: [
{ fieldname: "language", label: __("Your Language"),
fieldtype: "Select", reqd: 1}
{
fieldname: "language", label: __("Your Language"),
fieldtype: "Select", reqd: 1
}
],
onload: function(slide) {
onload: function (slide) {
this.setup_fields(slide);
var language_field = slide.get_field("language");
@ -372,7 +372,7 @@ frappe.setup.slides_settings = [
moment.locale("en");
},
setup_fields: function(slide) {
setup_fields: function (slide) {
frappe.setup.utils.setup_language_field(slide);
frappe.setup.utils.bind_language_events(slide);
},
@ -385,25 +385,31 @@ frappe.setup.slides_settings = [
icon: "fa fa-flag",
// help: __("Select your Country, Time Zone and Currency"),
fields: [
{ fieldname: "country", label: __("Your Country"), reqd:1,
fieldtype: "Select" },
{
fieldname: "country", label: __("Your Country"), reqd: 1,
fieldtype: "Select"
},
{ fieldtype: "Section Break" },
{ fieldname: "timezone", label: __("Time Zone"), reqd:1,
fieldtype: "Select" },
{
fieldname: "timezone", label: __("Time Zone"), reqd: 1,
fieldtype: "Select"
},
{ fieldtype: "Column Break" },
{ fieldname: "currency", label: __("Currency"), reqd:1,
fieldtype: "Select" }
{
fieldname: "currency", label: __("Currency"), reqd: 1,
fieldtype: "Select"
}
],
onload: function(slide) {
if(frappe.setup.data.regional_data) {
onload: function (slide) {
if (frappe.setup.data.regional_data) {
this.setup_fields(slide);
} else {
frappe.setup.utils.load_regional_data(slide, this.setup_fields);
}
},
setup_fields: function(slide) {
setup_fields: function (slide) {
frappe.setup.utils.setup_region_fields(slide);
frappe.setup.utils.bind_region_events(slide);
}
@ -415,24 +421,30 @@ frappe.setup.slides_settings = [
title: __("The First User: You"),
icon: "fa fa-user",
fields: [
{ "fieldtype":"Attach Image", "fieldname":"attach_user_image",
label: __("Attach Your Picture"), is_private: 0, align: 'center'},
{ "fieldname": "full_name", "label": __("Full Name"), "fieldtype": "Data",
reqd:1},
{ "fieldname": "email", "label": __("Email Address") + ' (' + __("Will be your login ID") + ')',
"fieldtype": "Data", "options":"Email"},
{
"fieldtype": "Attach Image", "fieldname": "attach_user_image",
label: __("Attach Your Picture"), is_private: 0, align: 'center'
},
{
"fieldname": "full_name", "label": __("Full Name"), "fieldtype": "Data",
reqd: 1
},
{
"fieldname": "email", "label": __("Email Address") + ' (' + __("Will be your login ID") + ')',
"fieldtype": "Data", "options": "Email"
},
{ "fieldname": "password", "label": __("Password"), "fieldtype": "Password" }
],
// help: __('The first user will become the System Manager (you can change this later).'),
onload: function(slide) {
if(frappe.session.user!=="Administrator") {
onload: function (slide) {
if (frappe.session.user !== "Administrator") {
slide.form.fields_dict.email.$wrapper.toggle(false);
slide.form.fields_dict.password.$wrapper.toggle(false);
// remove password field
delete slide.form.fields_dict.password;
if(frappe.boot.user.first_name || frappe.boot.user.last_name) {
if (frappe.boot.user.first_name || frappe.boot.user.last_name) {
slide.form.fields_dict.full_name.set_input(
[frappe.boot.user.first_name, frappe.boot.user.last_name].join(' ').trim());
}
@ -440,7 +452,7 @@ frappe.setup.slides_settings = [
var user_image = frappe.get_cookie("user_image");
var $attach_user_image = slide.form.fields_dict.attach_user_image.$wrapper;
if(user_image) {
if (user_image) {
$attach_user_image.find(".missing-image").toggle(false);
$attach_user_image.find("img").attr("src", decodeURIComponent(user_image));
$attach_user_image.find(".img-container").toggle(true);
@ -457,11 +469,11 @@ frappe.setup.slides_settings = [
}
},
setup_fields: function(slide) {
if(frappe.setup.data.full_name) {
setup_fields: function (slide) {
if (frappe.setup.data.full_name) {
slide.form.fields_dict.full_name.set_input(frappe.setup.data.full_name);
}
if(frappe.setup.data.email) {
if (frappe.setup.data.email) {
let email = frappe.setup.data.email;
slide.form.fields_dict.email.set_input(email);
if (frappe.get_gravatar(email, 200)) {
@ -476,21 +488,21 @@ frappe.setup.slides_settings = [
];
frappe.setup.utils = {
load_regional_data: function(slide, callback) {
load_regional_data: function (slide, callback) {
frappe.call({
method:"frappe.geo.country_info.get_country_timezone_info",
callback: function(data) {
method: "frappe.geo.country_info.get_country_timezone_info",
callback: function (data) {
frappe.setup.data.regional_data = data.message;
callback(slide);
}
});
},
load_user_details: function(slide, callback) {
load_user_details: function (slide, callback) {
frappe.call({
method: "frappe.desk.page.setup_wizard.setup_wizard.load_user_details",
freeze: true,
callback: function(r) {
callback: function (r) {
frappe.setup.data.full_name = r.message.full_name;
frappe.setup.data.email = r.message.email;
callback(slide);
@ -498,13 +510,13 @@ frappe.setup.utils = {
})
},
setup_language_field: function(slide) {
setup_language_field: function (slide) {
var language_field = slide.get_field("language");
language_field.df.options = frappe.setup.data.lang.languages;
language_field.refresh();
},
setup_region_fields: function(slide) {
setup_region_fields: function (slide) {
/*
Set a slide's country, timezone and currency fields
*/
@ -517,32 +529,32 @@ frappe.setup.utils = {
slide.get_input("currency").empty()
.add_options(frappe.utils.unique([""].concat($.map(data.country_info,
function(opts, country) { return opts.currency; }))).sort());
function (opts, country) { return opts.currency; }))).sort());
slide.get_input("timezone").empty()
.add_options([""].concat(data.all_timezones));
// set values if present
if(frappe.wizard.values.country) {
if (frappe.wizard.values.country) {
country_field.set_input(frappe.wizard.values.country);
} else if (data.default_country) {
country_field.set_input(data.default_country);
}
if(frappe.wizard.values.currency) {
if (frappe.wizard.values.currency) {
slide.get_field("currency").set_input(frappe.wizard.values.currency);
}
if(frappe.wizard.values.timezone) {
if (frappe.wizard.values.timezone) {
slide.get_field("timezone").set_input(frappe.wizard.values.timezone);
}
},
bind_language_events: function(slide) {
slide.get_input("language").unbind("change").on("change", function() {
clearTimeout (slide.language_call_timeout);
slide.language_call_timeout = setTimeout (() => {
bind_language_events: function (slide) {
slide.get_input("language").unbind("change").on("change", function () {
clearTimeout(slide.language_call_timeout);
slide.language_call_timeout = setTimeout(() => {
var lang = $(this).val() || "English";
frappe._messages = {};
frappe.call({
@ -551,7 +563,7 @@ frappe.setup.utils = {
args: {
language: lang
},
callback: function(r) {
callback: function (r) {
frappe.setup._from_load_messages = true;
frappe.wizard.refresh_slides();
}
@ -560,11 +572,11 @@ frappe.setup.utils = {
});
},
bind_region_events: function(slide) {
bind_region_events: function (slide) {
/*
Bind a slide's country, timezone and currency fields
*/
slide.get_input("country").on("change", function() {
slide.get_input("country").on("change", function () {
var country = slide.get_input("country").val();
var $timezone = slide.get_input("timezone");
var data = frappe.setup.data.regional_data;
@ -572,7 +584,7 @@ frappe.setup.utils = {
$timezone.empty();
// add country specific timezones first
if(country) {
if (country) {
var timezone_list = data.country_info[country].timezones || [];
$timezone.add_options(timezone_list.sort());
slide.get_field("currency").set_input(data.country_info[country].currency);
@ -589,16 +601,16 @@ frappe.setup.utils = {
|| "dd-mm-yyyy");
});
slide.get_input("currency").on("change", function() {
slide.get_input("currency").on("change", function () {
var currency = slide.get_input("currency").val();
if (!currency) return;
frappe.model.with_doc("Currency", currency, function() {
frappe.model.with_doc("Currency", currency, function () {
frappe.provide("locals.:Currency." + currency);
var currency_doc = frappe.model.get_doc("Currency", currency);
var number_format = currency_doc.number_format;
if (number_format==="#.###") {
if (number_format === "#.###") {
number_format = "#.###,##";
} else if (number_format==="#,###") {
} else if (number_format === "#,###") {
number_format = "#,###.##"
}

View file

@ -25,8 +25,8 @@
</ul>
{% if frm.meta.beta %}
<div class="sidebar-menu">
<p><label class="label label-warning" title="{{ __("This feature is brand new and still experimental") }}">{{ __("Under Development") }}</label></p>
<p><a class="small" href="https://github.com/frappe/{{ frappe.boot.module_app[frappe.scrub(frm.meta.module)] }}/issues/new"
<p><label class="indicator-pill yellow" title="{{ __("This feature is brand new and still experimental") }}">{{ __("Under Development") }}</label></p>
<p><a class="small text-muted" href="https://github.com/frappe/{{ frappe.boot.module_app[frappe.scrub(frm.meta.module)] }}/issues/new"
target="_blank">
{{ __("Click here to post bugs and suggestions") }}</a></p>

View file

@ -11,24 +11,24 @@ frappe.ui.Slide = class Slide {
setup() {
this.$wrapper = $('<div class="slide-wrapper hidden"></div>')
.attr({"data-slide-id": this.id, "data-slide-name": this.name})
.attr({ "data-slide-id": this.id, "data-slide-name": this.name })
.appendTo(this.parent);
}
// Make has to be called manually, to account for on-demand use cases
make() {
if(this.before_load) { this.before_load(this); }
if (this.before_load) { this.before_load(this); }
this.$body = $(`<div class="slide-body">
<div class="content text-center">
<p class="title lead">${this.title}</p>
<h1 class="title slide-title">${this.title}</h1>
</div>
<div class="form-wrapper">
<div class="form"></div>
<div class="add-more text-center" style="margin-top: 5px;">
<a class="form-more-btn hide btn btn-default btn-xs">
<button class="form-more-btn hide btn btn-default btn-xs">
<span>Add More</span>
</a>
</button>
</div>
</div>
</div>`).appendTo(this.$wrapper);
@ -38,9 +38,9 @@ frappe.ui.Slide = class Slide {
this.$primary_btn = this.slides_footer.find('.primary');
this.$form_wrapper = this.$body.find(".form-wrapper");
if(this.image_src) this.$content.append(
if (this.image_src) this.$content.append(
$(`<img src="${this.image_src}" style="margin: 20px;">`));
if(this.help) this.$content.append($(`<p class="slide-help">${this.help}</p>`));
if (this.help) this.$content.append($(`<p class="slide-help">${this.help}</p>`));
this.reqd_fields = [];
@ -50,7 +50,7 @@ frappe.ui.Slide = class Slide {
refresh() {
this.render_parent_dots();
if(!this.done) {
if (!this.done) {
this.setup_form();
} else {
this.setup_done_state();
@ -64,15 +64,15 @@ frappe.ui.Slide = class Slide {
no_submit_on_enter: true
});
this.form.make();
if(this.add_more) this.bind_more_button();
if (this.add_more) this.bind_more_button();
this.set_reqd_fields();
if(this.onload) { this.onload(this); }
if (this.onload) { this.onload(this); }
this.set_reqd_fields();
}
setup_done_state() {}
setup_done_state() { }
// Form methods
get_atomic_fields() {
@ -99,7 +99,7 @@ frappe.ui.Slide = class Slide {
var dict = this.form.fields_dict;
this.reqd_fields = [];
Object.keys(dict).map(key => {
if(dict[key].df.reqd) {
if (dict[key].df.reqd) {
this.reqd_fields.push(dict[key]);
}
});
@ -107,7 +107,7 @@ frappe.ui.Slide = class Slide {
set_values() {
this.values = this.form.get_values();
if (this.values===null) {
if (this.values === null) {
return false;
}
if (this.validate && !this.validate()) {
@ -132,7 +132,7 @@ frappe.ui.Slide = class Slide {
return field;
}));
if(this.count === this.max_count) {
if (this.count === this.max_count) {
this.$more.addClass('hide');
}
});
@ -182,7 +182,7 @@ frappe.ui.Slide = class Slide {
}
is_last_slide() {
if (this.id === this.parent[0].children.length-1) {
if (this.id === this.parent[0].children.length - 1) {
return true;
}
return false;
@ -194,7 +194,7 @@ frappe.ui.Slide = class Slide {
this.$wrapper.removeClass("hidden");
this.before_show();
this.resetup_primary_button();
if(!this.done) {
if (!this.done) {
this.$body.find('.form-control').first().focus();
this.$primary_btn.show();
} else {
@ -252,10 +252,10 @@ frappe.ui.Slides = class Slides {
}
make() {
this.container = $('<div>').addClass("slides-wrapper").attr({"tabindex": -1})
.appendTo(this.parent);
this.$slide_progress = $(`<div>`).addClass(`slides-progress text-center text-extra-muted`)
.appendTo(this.container);
.appendTo(this.parent);
this.container = $('<div>').addClass("slides-wrapper").attr({ "tabindex": -1 })
.appendTo(this.parent);
this.$body = $(`<div>`).addClass(`slide-container`)
.appendTo(this.container);
this.$footer = $(`<div>`).addClass(`slide-footer`)
@ -263,7 +263,7 @@ frappe.ui.Slides = class Slides {
this.render_progress_dots();
this.make_prev_next_buttons();
if(this.before_load) { this.before_load(this.$footer); }
if (this.before_load) { this.before_load(this.$footer); }
// can be on demand
this.setup();
@ -274,7 +274,7 @@ frappe.ui.Slides = class Slides {
setup() {
this.slides.map((slide, id) => {
if(!this.slide_dict[id]) {
if (!this.slide_dict[id]) {
this.slide_dict[id] = new (this.slide_class)(
$.extend(this.slides[id], {
parent: this.$body,
@ -283,11 +283,11 @@ frappe.ui.Slides = class Slides {
id: id,
})
);
if(!this.unidirectional) {
if (!this.unidirectional) {
this.slide_dict[id].make();
}
} else {
if(this.made_slide_ids.includes(id+"")) {
if (this.made_slide_ids.includes(id + "")) {
this.slide_dict[id].destroy();
this.slide_dict[id].make();
}
@ -307,15 +307,17 @@ frappe.ui.Slides = class Slides {
this.$slide_progress.empty();
this.slides.map((slide, id) => {
let $dot = $(`<i class="fa fa-fw fa-circle"> </i> `)
.attr({'data-step-id': id});
let $dot = $(`<div class="slide-step">
<div class="slide-step-indicator"></div>
<div class="slide-step-complete">${frappe.utils.icon('tick', 'xs')}</div>
</div>`)
.attr({ 'data-step-id': id });
if(this.done_state && (this.slide_dict[id] &&
if (this.done_state && (this.slide_dict[id] &&
this.slide_dict[id].done || slide.done)) {
$dot.addClass('text-success');
$dot.addClass('step-success');
}
if((this.unidirectional && id <= this.current_id) ||
id === this.current_id) {
if (this.unidirectional && id === this.current_id) {
$dot.addClass('active');
}
// Add pointer event for non-unidirectional
@ -324,24 +326,24 @@ frappe.ui.Slides = class Slides {
this.completed = 0;
this.slides.map((slide, i) => {
if(this.slide_dict[i]) {
if(this.slide_dict[i].done) this.completed++;
if (this.slide_dict[i]) {
if (this.slide_dict[i].done) this.completed++;
} else {
if(slide.done) this.completed++;
if (slide.done) this.completed++;
}
});
if(this.on_update) {this.on_update(this.completed, this.slides.length);}
if (this.on_update) { this.on_update(this.completed, this.slides.length); }
if(!this.unidirectional) this.bind_progress_dots();
if (!this.unidirectional) this.bind_progress_dots();
}
make_prev_next_buttons() {
$(`<div class="row">
<div class="col-sm-4 text-left prev-div">
<a class="prev-btn btn btn-default btn-sm" tabindex="0">${__("Previous")}</a>
<button class="prev-btn btn btn-secondary btn-sm" tabindex="0">${__("Previous")}</button>
</div>
<div class="col-sm-8 text-right next-div">
<a class="next-btn btn btn-default btn-sm" tabindex="0">${__("Next")}</a>
<button class="next-btn btn btn-default btn-sm" tabindex="0">${__("Next")}</button>
</div>
</div>`).appendTo(this.$footer);
@ -350,6 +352,10 @@ frappe.ui.Slides = class Slides {
this.$next_btn = this.$footer.find('.next-btn').attr('tabIndex', 0)
.on('click', () => {
if (this.done_state) {
if (this.slide) this.slide.done = true;
if (this.current_slide) this.current_slide.done = true;
}
if (!this.unidirectional || (this.unidirectional && this.current_slide.set_values())) {
this.show_slide(this.current_id + 1);
}
@ -358,7 +364,7 @@ frappe.ui.Slides = class Slides {
bind_progress_dots() {
var me = this;
this.$slide_progress.find('.fa-circle').addClass('link').on('click', function() {
this.$slide_progress.find('.fa-circle').addClass('link').on('click', function () {
let id = $(this).attr('data-step-id');
me.show_slide(id);
});
@ -370,15 +376,15 @@ frappe.ui.Slides = class Slides {
show_slide(id) {
id = cint(id);
if(!this.before_show_slide() ||
(this.current_slide && this.current_id===id)) {
if (!this.before_show_slide() ||
(this.current_slide && this.current_id === id)) {
return;
}
this.update_values();
if(this.current_slide) this.current_slide.hide_slide();
if(this.unidirectional && !this.slide_dict[id].made) {
if (this.current_slide) this.current_slide.hide_slide();
if (this.unidirectional && !this.slide_dict[id].made) {
this.slide_dict[id].make();
}
this.current_id = id;
@ -388,11 +394,11 @@ frappe.ui.Slides = class Slides {
}
destroy_slide(id) {
if(this.slide_dict[id]) this.slide_dict[id].destroy();
if (this.slide_dict[id]) this.slide_dict[id].destroy();
this.slide_dict[id] = null;
}
on_update(completed, total) {}
on_update(completed, total) { }
show_hide_prev_next(id) {
(id === 0) ?
@ -403,8 +409,8 @@ frappe.ui.Slides = class Slides {
get_values() {
var values = {};
$.each(this.slide_dict, function(id, slide) {
if(slide.values) {
$.each(this.slide_dict, function (id, slide) {
if (slide.values) {
$.extend(values, slide.values);
}
});

View file

@ -8,6 +8,7 @@
@import "list";
@import "navbar";
@import "modal";
@import "slides";
@import "toast";
@import "breadcrumb";
@import "indicator";

View file

@ -0,0 +1,113 @@
.slides-progress {
margin-top: 80px;
display: flex;
margin-bottom: var(--margin-lg);
justify-content: center;
.slide-step {
@include flex(flex, center, center, null);
height: 18px;
width: 18px;
border-radius: var(--border-radius-full);
border: 1px solid var(--gray-300);
margin: 0 var(--margin-xs);
background-color: var(--card-bg);
.slide-step-indicator {
height: 6px;
width: 6px;
background-color: var(--gray-300);
border-radius: var(--border-radius-full);
// display: none;
}
.slide-step-complete {
display: none;
.icon-xs {
height: 10px;
width: 10px;
}
}
&.active {
// background-color: var(--primary);
border: 1px solid var(--primary);
.slide-step-indicator {
display: block;
background-color: var(--primary);
}
}
// &.step-success.active {
// background-color: var(--primary);
// border: 1px solid var(--primary);
// .slide-step-indicator {
// display: block;
// background-color: var(--white);
// }
// }
&.step-success:not(.active) {
background-color: var(--primary);
border: 1px solid var(--primary);
.slide-step-indicator {
display: none;
}
.slide-step-complete {
display: flex;
.icon use {
stroke-width: 2;
stroke: var(--white);
}
}
}
}
}
.slides-wrapper {
width: 520px;
max-width: 520px;
background: var(--card-bg);
padding: var(--padding-xl);
box-shadow: var(--card-shadow);
border-radius: var(--border-radius-md);
.slide-footer {
margin: var(--margin-md) 0;
padding: 0 var(--padding-sm);
.btn {
box-shadow: none;
}
}
h1.slide-title {
font-size: var(--text-3xl);
font-weight: 700;
}
.form-wrapper {
margin-top: var(--margin-xl);
}
&.setup-in-progress {
.state-icon-container {
margin-top: var(--margin-xl);
}
.setup-message {
margin-top: var(--margin-lg);
}
.btn-abort {
margin: var(--margin-lg) auto;
}
}
}

View file

@ -7,7 +7,7 @@
.page-card {
max-width: 460px;
padding: var(--padding-2xl);
padding: 50px;
margin: 70px auto;
border-radius: var(--border-radius-md);
background-color: #fff;
@ -16,6 +16,10 @@
form {
max-width: 330px;
margin: 0 auto;
.form-group {
margin-bottom: var(--margin-sm);
}
}
.page-card-actions {
@ -76,7 +80,8 @@
.page-card-body {
::placeholder, /* Chrome, Firefox, Opera, Safari 10.1+ */
::-ms-input-placeholder { /* Microsoft Edge */
::-ms-input-placeholder {
/* Microsoft Edge */
color: var(--text-light);
opacity: 1; /* Firefox */
}
@ -105,6 +110,8 @@
.forgot-password-message {
text-align: right;
line-height: 1;
> * {
color: var(--text-light);
font-size: var(--text-sm);

View file

@ -24,7 +24,7 @@
<div class="page-card-body">
<div class="form-group">
<label class="form-label" for="login_email">{{ login_label or _("Email")}}</label>
<label class="form-label sr-only" for="login_email">{{ login_label or _("Email")}}</label>
<div class="email-field">
<input type="text" id="login_email" class="form-control"
placeholder="{% if login_name_placeholder %}{{ login_name_placeholder }}{% else %}{{ _('jane@example.com') }}{% endif %}"
@ -43,7 +43,7 @@
</div>
<div class="form-group">
<label class="form-label" for="login_password">{{ _("Password") }}</label>
<label class="form-label sr-only" for="login_password">{{ _("Password") }}</label>
<div class="password-field">
<input type="password" id="login_password" class="form-control" placeholder="•••••"
autocomplete="current-password" required>
@ -62,7 +62,7 @@
<a href="#forgot">{{ _("Forgot Password?") }}</a></p>
</div>
<div class="page-card-actions mt-8">
<div class="page-card-actions">
<button class="btn btn-sm btn-primary btn-block btn-login" type="submit">
{{ _("Login") }}</button>
@ -107,12 +107,12 @@
</div>
<div class="page-card-body">
<div class="form-group">
<label class="form-label" for="signup_fullname">Full Name</label>
<label class="form-label sr-only" for="signup_fullname">Full Name</label>
<input type="text" id="signup_fullname" class="form-control" placeholder="{{ _('Jane Doe') }}"
required autofocus>
</div>
<div class="form-group">
<label class="form-label" for="signup_email">Email</label>
<label class="form-label sr-only" for="signup_email">Email</label>
<input type="email" id="signup_email" class="form-control"
placeholder="{{ _('jane@example.com') }}" required>
</div>