Browse Source

Merge branch 'develop' of github.com:frappe/frappe into multistep_webforms

version-14
hrwx 3 years ago
parent
commit
8935691b32
7 changed files with 57 additions and 29 deletions
  1. +1
    -1
      cypress/integration/web_form.js
  2. +20
    -19
      frappe/desk/page/setup_wizard/setup_wizard.js
  3. +1
    -1
      frappe/model/document.py
  4. +2
    -0
      frappe/public/js/frappe/form/controls/link.js
  5. +13
    -6
      frappe/public/js/frappe/ui/slides.js
  6. +2
    -2
      frappe/public/js/frappe/web_form/web_form.js
  7. +18
    -0
      frappe/tests/test_commands.py

+ 1
- 1
cypress/integration/web_form.js View File

@@ -11,7 +11,7 @@ context('Web Form', () => {
cy.get('.modal.show > .modal-dialog').should('be.visible'); cy.get('.modal.show > .modal-dialog').should('be.visible');
}); });


it('Timeline should have submit and cancel activity information', () => {
it('Navigate and Submit a MultiStep WebForm', () => {
cy.call('frappe.tests.ui_test_helpers.update_webform_to_multistep').then(() => { cy.call('frappe.tests.ui_test_helpers.update_webform_to_multistep').then(() => {
cy.visit('/update-profile'); cy.visit('/update-profile');
cy.get_field('last_name', 'Data').type('_Test User', {force: true}).wait(200); cy.get_field('last_name', 'Data').type('_Test User', {force: true}).wait(200);


+ 20
- 19
frappe/desk/page/setup_wizard/setup_wizard.js View File

@@ -46,14 +46,6 @@ frappe.pages['setup-wizard'].on_page_load = function (wrapper) {
slide_class: frappe.setup.SetupWizardSlide, slide_class: frappe.setup.SetupWizardSlide,
unidirectional: 1, unidirectional: 1,
done_state: 1, done_state: 1,
before_load: ($footer) => {
$footer.find('.next-btn').removeClass('btn-default')
.addClass('btn-primary');
$footer.find('.text-right').prepend(
$(`<button class="complete-btn btn btn-sm primary">
${__("Complete Setup")}</button>`));

}
} }
frappe.wizard = new frappe.setup.SetupWizard(wizard_settings); frappe.wizard = new frappe.setup.SetupWizard(wizard_settings);
frappe.setup.run_event("after_load"); frappe.setup.run_event("after_load");
@@ -97,7 +89,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
super.make(); super.make();
this.container.addClass("container setup-wizard-slide with-form"); this.container.addClass("container setup-wizard-slide with-form");
this.$next_btn.addClass('action'); this.$next_btn.addClass('action');
this.$complete_btn = this.$footer.find('.complete-btn').addClass('action');
this.$complete_btn.addClass('action');
this.setup_keyboard_nav(); this.setup_keyboard_nav();
} }


@@ -145,7 +137,6 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
this.$next_btn.removeClass("btn-primary").hide(); this.$next_btn.removeClass("btn-primary").hide();
this.$complete_btn.addClass("btn-primary").show() this.$complete_btn.addClass("btn-primary").show()
.on('click', () => this.action_on_complete()); .on('click', () => this.action_on_complete());

} else { } else {
this.$next_btn.addClass("btn-primary").show(); this.$next_btn.addClass("btn-primary").show();
this.$complete_btn.removeClass("btn-primary").hide(); this.$complete_btn.removeClass("btn-primary").hide();
@@ -178,6 +169,7 @@ frappe.setup.SetupWizard = class SetupWizard extends frappe.ui.Slides {
this.setup(); this.setup();


this.show_slide(this.current_id); this.show_slide(this.current_id);
this.refresh(this.current_id);
setTimeout(() => { setTimeout(() => {
this.container.find('.form-control').first().focus(); this.container.find('.form-control').first().focus();
}, 200); }, 200);
@@ -347,7 +339,6 @@ frappe.setup.SetupWizardSlide = class SetupWizardSlide extends frappe.ui.Slide {


// Frappe slides settings // Frappe slides settings
// ====================================================== // ======================================================

frappe.setup.slides_settings = [ frappe.setup.slides_settings = [
{ {
// Welcome (language) slide // Welcome (language) slide
@@ -365,10 +356,10 @@ frappe.setup.slides_settings = [


onload: function (slide) { onload: function (slide) {
this.setup_fields(slide); this.setup_fields(slide);
let browser_language = frappe.setup.utils.get_language_name_from_code(navigator.language);
let language_field = slide.get_field("language");


var language_field = slide.get_field("language");

language_field.set_input(frappe.setup.data.default_language || "English");
language_field.set_input(browser_language || "English");


if (!frappe.setup._from_load_messages) { if (!frappe.setup._from_load_messages) {
language_field.$input.trigger("change"); language_field.$input.trigger("change");
@@ -532,12 +523,18 @@ frappe.setup.utils = {
/* /*
Set a slide's country, timezone and currency fields Set a slide's country, timezone and currency fields
*/ */
var data = frappe.setup.data.regional_data;

var country_field = slide.get_field('country');

let data = frappe.setup.data.regional_data;
let country_field = slide.get_field('country');
let translated_countries = [];

Object.keys(data.country_info).sort().forEach(country => {
translated_countries.push({
label: __(country),
value: country
});
});


country_field.set_data(Object.keys(data.country_info).sort());
country_field.set_data(translated_countries);


slide.get_input("currency") slide.get_input("currency")
.empty() .empty()
@@ -584,6 +581,10 @@ frappe.setup.utils = {
}); });
}, },


get_language_name_from_code: function (language_code) {
return frappe.setup.data.lang.codes_to_names[language_code] || "English";
},

bind_region_events: function (slide) { bind_region_events: function (slide) {
/* /*
Bind a slide's country, timezone and currency fields Bind a slide's country, timezone and currency fields


+ 1
- 1
frappe/model/document.py View File

@@ -190,7 +190,7 @@ class Document(BaseDocument):
:param permtype: one of `read`, `write`, `submit`, `cancel`, `delete`""" :param permtype: one of `read`, `write`, `submit`, `cancel`, `delete`"""
if self.flags.ignore_permissions: if self.flags.ignore_permissions:
return True return True
return frappe.has_permission(self.doctype, permtype, self, verbose=verbose)
return frappe.permissions.has_permission(self.doctype, permtype, self, verbose=verbose)


def raise_no_permission_to(self, perm_type): def raise_no_permission_to(self, perm_type):
"""Raise `frappe.PermissionError`.""" """Raise `frappe.PermissionError`."""


+ 2
- 0
frappe/public/js/frappe/form/controls/link.js View File

@@ -456,6 +456,8 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
this.docname, value); this.docname, value);
} }
validate_link_and_fetch(df, options, docname, value) { validate_link_and_fetch(df, options, docname, value) {
if (!options) return;

let field_value = ""; let field_value = "";
const fetch_map = this.fetch_map; const fetch_map = this.fetch_map;
const columns_to_fetch = Object.values(fetch_map); const columns_to_fetch = Object.values(fetch_map);


+ 13
- 6
frappe/public/js/frappe/ui/slides.js View File

@@ -21,7 +21,7 @@ frappe.ui.Slide = class Slide {


this.$body = $(`<div class="slide-body"> this.$body = $(`<div class="slide-body">
<div class="content text-center"> <div class="content text-center">
<h1 class="title slide-title">${this.title}</h1>
<h1 class="title slide-title">${__(this.title)}</h1>
</div> </div>
<div class="form-wrapper"> <div class="form-wrapper">
<div class="form"></div> <div class="form"></div>
@@ -40,7 +40,7 @@ frappe.ui.Slide = class Slide {


if (this.image_src) this.$content.append( if (this.image_src) this.$content.append(
$(`<img src="${this.image_src}" style="margin: 20px;">`)); $(`<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 = []; this.reqd_fields = [];


@@ -263,7 +263,7 @@ frappe.ui.Slides = class Slides {
.appendTo(this.container); .appendTo(this.container);


this.render_progress_dots(); this.render_progress_dots();
this.make_prev_next_buttons();
this.make_prev_next_complete_buttons();
if (this.before_load) this.before_load(this.$footer); if (this.before_load) this.before_load(this.$footer);


// can be on demand // can be on demand
@@ -289,6 +289,7 @@ frappe.ui.Slides = class Slides {
} }
} else { } else {
if (this.made_slide_ids.includes(id + "")) { if (this.made_slide_ids.includes(id + "")) {
this.slide_dict[id].done = false;
this.slide_dict[id].destroy(); this.slide_dict[id].destroy();
this.slide_dict[id].make(); this.slide_dict[id].make();
} }
@@ -298,6 +299,7 @@ frappe.ui.Slides = class Slides {


refresh(id) { refresh(id) {
this.render_progress_dots(); this.render_progress_dots();
this.make_prev_next_complete_buttons();
this.show_hide_prev_next(id); this.show_hide_prev_next(id);
this.$body.find('.form-control').first().focus(); this.$body.find('.form-control').first().focus();
} }
@@ -338,13 +340,16 @@ frappe.ui.Slides = class Slides {
if (!this.unidirectional) this.bind_progress_dots(); if (!this.unidirectional) this.bind_progress_dots();
} }


make_prev_next_buttons() {
make_prev_next_complete_buttons() {
this.$footer.empty();

$(`<div class="row"> $(`<div class="row">
<div class="col-sm-4 text-left prev-div"> <div class="col-sm-4 text-left prev-div">
<button class="prev-btn btn btn-secondary btn-sm" tabindex="0">${__("Previous")}</button>
<button class="prev-btn btn btn-secondary btn-sm" tabindex="0">${__("Previous", null, "Go to previous slide")}</button>
</div> </div>
<div class="col-sm-8 text-right next-div"> <div class="col-sm-8 text-right next-div">
<button class="next-btn btn btn-default btn-sm" tabindex="0">${__("Next")}</button>
<button class="complete-btn btn btn-sm primary">${__("Complete Setup", null, "Finish the setup wizard")}</button>
<button class="next-btn btn btn-default btn-sm" tabindex="0">${__("Next", null, "Go to next slide")}</button>
</div> </div>
</div>`).appendTo(this.$footer); </div>`).appendTo(this.$footer);


@@ -361,6 +366,8 @@ frappe.ui.Slides = class Slides {
this.show_slide(this.current_id + 1); this.show_slide(this.current_id + 1);
} }
}); });

this.$complete_btn = this.$footer.find('.complete-btn').attr('tabIndex', 0);
} }


bind_progress_dots() { bind_progress_dots() {


+ 2
- 2
frappe/public/js/frappe/web_form/web_form.js View File

@@ -90,8 +90,8 @@ export default class WebForm extends frappe.ui.FieldGroup {


if (!is_validated) return; if (!is_validated) return;


/*
eslint cannot figure out if this is an infinite loop in backwards and
/**
The eslint utility cannot figure out if this is an infinite loop in backwards and
throws an error. Disabling for-direction just for this section. throws an error. Disabling for-direction just for this section.
for-direction doesnt throw an error if the values are hardcoded in the for-direction doesnt throw an error if the values are hardcoded in the
reverse for-loop, but in this case its a dynamic loop. reverse for-loop, but in this case its a dynamic loop.


+ 18
- 0
frappe/tests/test_commands.py View File

@@ -474,6 +474,24 @@ class TestCommands(BaseTestCommands):
# cleanup # cleanup
shutil.rmtree(test_app_path) shutil.rmtree(test_app_path)


def disable_test_bench_drop_site_should_archive_site(self):
site = 'test_site.localhost'

self.execute(
f"bench new-site {site} --force --verbose --admin-password {frappe.conf.admin_password} "
f"--mariadb-root-password {frappe.conf.root_password}"
)
self.assertEqual(self.returncode, 0)

self.execute(f"bench drop-site {site} --force --root-password {frappe.conf.root_password}")
self.assertEqual(self.returncode, 0)

bench_path = frappe.utils.get_bench_path()
site_directory = os.path.join(bench_path, f'sites/{site}')
self.assertFalse(os.path.exists(site_directory))
archive_directory = os.path.join(bench_path, f'archived/sites/{site}')
self.assertTrue(os.path.exists(archive_directory))



class RemoveAppUnitTests(unittest.TestCase): class RemoveAppUnitTests(unittest.TestCase):
def test_delete_modules(self): def test_delete_modules(self):


Loading…
Cancel
Save