fix: added a 'Continue' type slide

This commit is contained in:
Rucha Mahabal 2019-12-04 15:59:38 +05:30
parent 5b16efd1e7
commit d9bbd10382
5 changed files with 95 additions and 44 deletions

View file

@ -15,7 +15,6 @@
"slide_desc",
"action_section_break",
"slide_type",
"submit_method",
"column_break_6",
"max_count",
"add_more_button",
@ -25,7 +24,8 @@
"section_break_10",
"domains",
"column_break_12",
"help_links"
"help_links",
"is_completed"
],
"fields": [
{
@ -36,13 +36,6 @@
"reqd": 1,
"unique": 1
},
{
"depends_on": "eval:doc.slide_type!='Information'",
"description": "By default the code inside `create_onboarding_docs` method of the `Reference Document Type` is executed. If your method is not on the doctype level, place this method in {app_name}.utilities.onboarding_utils.{method_name} and specify the method name here",
"fieldname": "submit_method",
"fieldtype": "Data",
"label": "Submit Method"
},
{
"fieldname": "slide_desc",
"fieldtype": "HTML Editor",
@ -58,13 +51,13 @@
},
{
"default": "0",
"depends_on": "eval:doc.slide_type!='Information'",
"depends_on": "eval:doc.slide_type=='Create' || doc.slide_type=='Settings'",
"fieldname": "add_more_button",
"fieldtype": "Check",
"label": "Add More Button"
},
{
"depends_on": "eval:doc.slide_type!='Information'",
"depends_on": "eval:doc.slide_type=='Create' || doc.slide_type=='Settings'",
"fieldname": "slide_fields",
"fieldtype": "Table",
"label": "Slide Fields",
@ -98,11 +91,11 @@
"label": "Action Settings"
},
{
"description": "If slide type is Action there should be a submit method bound to be executed after the slide is completed.",
"description": "If Slide Type is Create or Settings there should be a 'create_onboarding_docs' method in the {ref_doctype}.py file bound to be executed after the slide is completed.",
"fieldname": "slide_type",
"fieldtype": "Select",
"label": "Slide Type",
"options": "Information\nCreate\nSettings",
"options": "Information\nCreate\nSettings\nContinue",
"reqd": 1
},
{
@ -131,7 +124,7 @@
"label": "Description"
},
{
"depends_on": "eval:doc.slide_type!='Information'",
"depends_on": "eval:doc.slide_type=='Create' || doc.slide_type=='Settings'",
"fieldname": "ref_doctype",
"fieldtype": "Link",
"label": "Reference Document Type",
@ -145,19 +138,28 @@
"label": "Slide Order"
},
{
"depends_on": "eval:doc.slide_type=='Information'",
"depends_on": "eval:doc.slide_type=='Information' || doc.slide_type=='Continue'",
"fieldname": "slide_module",
"fieldtype": "Link",
"label": "Module",
"options": "Module Def"
},
{
"collapsible_depends_on": "eval:doc.slide_type=='Create' || doc.slide_type=='Settings'",
"fieldname": "section_break_18",
"fieldtype": "Section Break",
"label": "Fields"
},
{
"default": "0",
"fieldname": "is_completed",
"fieldtype": "Check",
"hidden": 1,
"label": "Is Completed",
"print_hide": 1
}
],
"modified": "2019-12-02 16:17:17.368741",
"modified": "2019-12-04 10:50:43.528901",
"modified_by": "Administrator",
"module": "Desk",
"name": "Onboarding Slide",

View file

@ -5,10 +5,15 @@
from __future__ import unicode_literals
import frappe
import json
from frappe import _
from frappe.model.document import Document
from frappe.modules.export_file import export_to_files
class OnboardingSlide(Document):
def validate(self):
if frappe.db.exists('Onboarding Slide', {'slide_type': 'Continue', 'name': ('!=', self.name)}):
frappe.throw(_("An Onboarding Slide of Slide Type Continue already exists."))
def on_update(self):
if self.ref_doctype:
module = frappe.db.get_value('DocType', self.ref_doctype, 'module')
@ -18,14 +23,19 @@ class OnboardingSlide(Document):
def get_onboarding_slides_as_list():
slides = []
slide_docs = frappe.get_all('Onboarding Slide',
filters={'slide_order': ('!=', 0)},
slide_docs = frappe.db.get_all('Onboarding Slide',
filters={'is_completed': 0},
or_filters={'slide_order': ('!=', 0), 'slide_type': 'Continue'},
order_by='slide_order')
# to check if continue slide is required
first_slide = get_first_slide()
for entry in slide_docs:
# using get_doc because child table fields are not fetched in get_all
slide_doc = frappe.get_doc('Onboarding Slide', entry.name)
if frappe.scrub(slide_doc.app) in frappe.get_installed_apps():
slides.append(frappe._dict(
slide = frappe._dict(
slide_type=slide_doc.slide_type,
title=slide_doc.slide_title,
help=slide_doc.slide_desc,
@ -33,11 +43,16 @@ def get_onboarding_slides_as_list():
help_links=get_help_links(slide_doc),
add_more=slide_doc.add_more_button,
max_count=slide_doc.max_count,
submit_method=slide_doc.submit_method,
image_src=get_slide_image(slide_doc),
ref_doctype=slide_doc.ref_doctype,
app=slide_doc.app
))
)
if slide.slide_type == 'Continue':
if is_continue_slide_required(first_slide):
slides.insert(0, slide)
else:
slides.append(slide)
return slides
@frappe.whitelist()
@ -65,21 +80,26 @@ def get_slide_image(slide_doc):
return slide_doc.image_src
return None
def is_continue_slide_required(first_slide):
# check if first slide itself is not completed
if not first_slide.is_completed:
return False
# check if there is any active slide which is not completed
return frappe.db.exists('Onboarding Slide', {
'is_completed': 0,
'slide_order': ('!=', 0),
'slide_type': ('!=', 'Continue')
})
@frappe.whitelist()
def create_onboarding_docs(values, doctype=None, submit_method=None, app=None, slide_type=None):
def create_onboarding_docs(values, doctype=None, app=None, slide_type=None):
data = json.loads(values)
if submit_method:
try:
method = frappe.scrub(app) + '.utilities.onboarding_utils.' + submit_method
frappe.call(method, data)
except AttributeError:
create_generic_onboarding_doc(data, doctype, slide_type)
doc = frappe.new_doc(doctype)
if hasattr(doc, 'create_onboarding_docs'):
doc.create_onboarding_docs(data)
else:
doc = frappe.new_doc(doctype)
if hasattr(doc, 'create_onboarding_docs'):
doc.create_onboarding_docs(data)
else:
create_generic_onboarding_doc(data, doctype, slide_type)
create_generic_onboarding_doc(data, doctype, slide_type)
def create_generic_onboarding_doc(data, doctype, slide_type):
if slide_type == 'Settings':
@ -94,4 +114,16 @@ def create_generic_onboarding_doc(data, doctype, slide_type):
doc.set(entry, data.get(entry))
doc.flags.ignore_mandatory = True
doc.flags.ignore_links = True
doc.insert()
doc.insert()
@frappe.whitelist()
def mark_slide_as_completed(slide_title):
frappe.db.set_value('Onboarding Slide', slide_title, 'is_completed', 1)
def get_first_slide():
slides = frappe.db.get_all('Onboarding Slide',
filters={'slide_order': ('!=', 0), 'slide_type': ('!=', 'Continue')},
order_by='slide_order',
fields=['name', 'is_completed']
)
return slides[0]

View file

@ -14,7 +14,7 @@
"idx": 0,
"image_src": "/assets/erpnext/images/illustrations/letterhead-onboard.png",
"max_count": 0,
"modified": "2019-12-02 12:57:41.353913",
"modified": "2019-12-03 22:54:57.618989",
"modified_by": "Administrator",
"name": "Company Letter Head",
"owner": "Administrator",
@ -32,6 +32,5 @@
],
"slide_order": 20,
"slide_title": "Company Letter Head",
"slide_type": "Create",
"submit_method": ""
"slide_type": "Create"
}

View file

@ -496,11 +496,6 @@ frappe.Application = Class.extend({
slides: slides
});
me.progress_dialog.show();
frappe.call({
method: "frappe.desk.page.setup_wizard.setup_wizard.reset_is_first_startup",
args: {},
callback: () => {}
});
});
}
}

View file

@ -44,12 +44,12 @@ frappe.setup.OnboardingSlide = class OnboardingSlide extends frappe.ui.Slide {
args: {
values: me.values,
doctype: me.ref_doctype,
submit_method: me.submit_method,
app: me.app,
slide_type: me.slide_type
},
callback: function() {
if (me.id === me.parent[0].children.length-1) {
me.reset_is_first_startup();
$('.onboarding-dialog').modal('toggle');
frappe.msgprint({
message: __('You are all set up!'),
@ -86,11 +86,34 @@ frappe.setup.OnboardingSlide = class OnboardingSlide extends frappe.ui.Slide {
}
setup_action_button() {
if (this.slide_type !== 'Information') {
if (this.slide_type === 'Create' || this.slide_type == 'Settings' || this.id === this.parent[0].children.length-1) {
this.$action_button.addClass('primary');
} else {
this.$action_button.removeClass('primary');
}
this.$action_button.on('click', () => {
if (this.slide_type != 'Continue') {
this.mark_as_completed();
}
});
}
mark_as_completed() {
frappe.call({
method: 'frappe.desk.doctype.onboarding_slide.onboarding_slide.mark_slide_as_completed',
args: {slide_title: this.title},
callback: () => {},
freeze: true
});
}
reset_is_first_startup() {
frappe.call({
method: "frappe.desk.page.setup_wizard.setup_wizard.reset_is_first_startup",
args: {},
callback: () => {}
});
}
};