From acbf784e2a9a2d254948c8d4e53cf218bf65e786 Mon Sep 17 00:00:00 2001 From: Maharshi Patel Date: Thu, 18 May 2023 02:15:09 +0530 Subject: [PATCH] feat: add fields for onboarding ui tours. Fields required for UI Tours. --- .../doctype/form_tour_settings/__init__.py | 0 .../form_tour_settings/form_tour_settings.js | 8 ++ .../form_tour_settings.json | 51 ++++++++ .../form_tour_settings/form_tour_settings.py | 15 +++ .../test_form_tour_settings.py | 9 ++ .../form_tour_settings_item/__init__.py | 0 .../form_tour_settings_item.json | 61 ++++++++++ .../form_tour_settings_item.py | 9 ++ frappe/desk/doctype/form_tour/form_tour.json | 113 +++++++++++++++++- .../form_tour_step/form_tour_step.json | 112 ++++++++++++++++- 10 files changed, 368 insertions(+), 10 deletions(-) create mode 100644 frappe/core/doctype/form_tour_settings/__init__.py create mode 100644 frappe/core/doctype/form_tour_settings/form_tour_settings.js create mode 100644 frappe/core/doctype/form_tour_settings/form_tour_settings.json create mode 100644 frappe/core/doctype/form_tour_settings/form_tour_settings.py create mode 100644 frappe/core/doctype/form_tour_settings/test_form_tour_settings.py create mode 100644 frappe/core/doctype/form_tour_settings_item/__init__.py create mode 100644 frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.json create mode 100644 frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.py diff --git a/frappe/core/doctype/form_tour_settings/__init__.py b/frappe/core/doctype/form_tour_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/core/doctype/form_tour_settings/form_tour_settings.js b/frappe/core/doctype/form_tour_settings/form_tour_settings.js new file mode 100644 index 0000000000..123e51dbf9 --- /dev/null +++ b/frappe/core/doctype/form_tour_settings/form_tour_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2023, Frappe Technologies and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Form Tour Settings", { +// refresh(frm) { + +// }, +// }); diff --git a/frappe/core/doctype/form_tour_settings/form_tour_settings.json b/frappe/core/doctype/form_tour_settings/form_tour_settings.json new file mode 100644 index 0000000000..15795edde5 --- /dev/null +++ b/frappe/core/doctype/form_tour_settings/form_tour_settings.json @@ -0,0 +1,51 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2023-05-11 18:07:26.879273", + "default_view": "List", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "onboarding_tours", + "form_tours" + ], + "fields": [ + { + "fieldname": "form_tours", + "fieldtype": "Table", + "label": "Form Tours", + "options": "Form Tour Settings Item" + }, + { + "default": "\"[]\"", + "fieldname": "onboarding_tours", + "fieldtype": "JSON", + "hidden": 1, + "label": "Onboarding Tours" + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2023-05-17 16:45:21.362524", + "modified_by": "Administrator", + "module": "Core", + "name": "Form Tour Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/frappe/core/doctype/form_tour_settings/form_tour_settings.py b/frappe/core/doctype/form_tour_settings/form_tour_settings.py new file mode 100644 index 0000000000..52b68286d7 --- /dev/null +++ b/frappe/core/doctype/form_tour_settings/form_tour_settings.py @@ -0,0 +1,15 @@ +# Copyright (c) 2023, Frappe Technologies and contributors +# For license information, please see license.txt + +import json + +import frappe +from frappe.model.document import Document + + +class FormTourSettings(Document): + def on_update(self): + onboarding_tours = [[tour.form_tour, json.loads(tour.page_route)] for tour in self.form_tours] + frappe.db.set_single_value( + "Form Tour Settings", "onboarding_tours", json.dumps(onboarding_tours) + ) diff --git a/frappe/core/doctype/form_tour_settings/test_form_tour_settings.py b/frappe/core/doctype/form_tour_settings/test_form_tour_settings.py new file mode 100644 index 0000000000..95838ecb97 --- /dev/null +++ b/frappe/core/doctype/form_tour_settings/test_form_tour_settings.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestFormTourSettings(FrappeTestCase): + pass diff --git a/frappe/core/doctype/form_tour_settings_item/__init__.py b/frappe/core/doctype/form_tour_settings_item/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.json b/frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.json new file mode 100644 index 0000000000..54ab61da21 --- /dev/null +++ b/frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.json @@ -0,0 +1,61 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2023-05-11 18:10:15.194034", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "form_tour", + "view", + "list_view", + "page_route" + ], + "fields": [ + { + "fieldname": "form_tour", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Form Tour", + "options": "Form Tour", + "read_only": 1 + }, + { + "fetch_from": "form_tour.view_name", + "fieldname": "view", + "fieldtype": "Data", + "in_list_view": 1, + "label": "View", + "read_only": 1 + }, + { + "fetch_from": "form_tour.list_name", + "fieldname": "list_view", + "fieldtype": "Data", + "in_list_view": 1, + "label": "List View", + "read_only": 1 + }, + { + "fetch_from": "form_tour.page_route", + "fieldname": "page_route", + "fieldtype": "Data", + "hidden": 1, + "in_list_view": 1, + "label": "Page Route", + "read_only": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2023-05-17 22:22:58.507769", + "modified_by": "Administrator", + "module": "Core", + "name": "Form Tour Settings Item", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.py b/frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.py new file mode 100644 index 0000000000..0958b000ad --- /dev/null +++ b/frappe/core/doctype/form_tour_settings_item/form_tour_settings_item.py @@ -0,0 +1,9 @@ +# Copyright (c) 2023, Frappe Technologies and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class FormTourSettingsItem(Document): + pass diff --git a/frappe/desk/doctype/form_tour/form_tour.json b/frappe/desk/doctype/form_tour/form_tour.json index 6f3bd56a4e..3890da468a 100644 --- a/frappe/desk/doctype/form_tour/form_tour.json +++ b/frappe/desk/doctype/form_tour/form_tour.json @@ -7,27 +7,39 @@ "engine": "InnoDB", "field_order": [ "title", + "view_name", + "workspace_name", + "list_name", + "report_name", + "dashboard_name", + "new_document_form", + "page_name", "reference_doctype", "module", "column_break_6", + "ui_tour", + "track_steps", + "reset_tours", "is_standard", "save_on_complete", "first_document", "include_name_field", + "page_route", "section_break_3", "steps" ], "fields": [ { + "depends_on": "eval:(!doc.ui_tour || doc.is_ui_tour && [\"Workspaces\", \"Page\", \"Tree\"].indexOf(doc.view_name) == -1);", "fieldname": "reference_doctype", "fieldtype": "Link", "in_list_view": 1, "label": "Reference Document", - "options": "DocType", - "reqd": 1 + "mandatory_depends_on": "eval:(!doc.ui_tour)", + "options": "DocType" }, { - "depends_on": "reference_doctype", + "depends_on": "eval:(doc.ui_tour || doc.reference_doctype)", "fieldname": "steps", "fieldtype": "Table", "label": "Steps", @@ -47,6 +59,7 @@ }, { "default": "0", + "depends_on": "eval:(!doc.ui_tour)", "fieldname": "save_on_complete", "fieldtype": "Check", "label": "Save on Completion" @@ -72,21 +85,110 @@ }, { "default": "0", + "depends_on": "eval:(!doc.ui_tour)", "fieldname": "first_document", "fieldtype": "Check", "label": "Show First Document Tour" }, { "default": "0", - "depends_on": "eval:!doc.first_document", + "depends_on": "eval:(!doc.ui_tour && !doc.first_document)", "fieldname": "include_name_field", "fieldtype": "Check", "label": "Include Name Field" + }, + { + "default": "0", + "fieldname": "ui_tour", + "fieldtype": "Check", + "label": "UI Tour", + "set_only_once": 1 + }, + { + "depends_on": "is_ui_tour", + "fieldname": "page_route", + "fieldtype": "JSON", + "hidden": 1, + "label": "Page Route" + }, + { + "default": "0", + "depends_on": "ui_tour", + "description": "Please check this if you want to reset this tour and show it to all users.", + "fieldname": "reset_tours", + "fieldtype": "Check", + "label": "Reset Tours" + }, + { + "depends_on": "eval:(doc.ui_tour && doc.view_name == \"List\" && doc.list_name == \"Dashboard\")", + "fetch_from": ".", + "fieldname": "dashboard_name", + "fieldtype": "Link", + "label": "Select Dashboard", + "options": "Dashboard" + }, + { + "depends_on": "ui_tour", + "fieldname": "view_name", + "fieldtype": "Select", + "label": "View", + "mandatory_depends_on": "ui_tour", + "options": "Workspaces\nList\nForm\nTree\nPage" + }, + { + "depends_on": "eval:(doc.ui_tour && doc.view_name == \"Workspaces\")", + "fetch_from": ".", + "fieldname": "workspace_name", + "fieldtype": "Link", + "label": "Select Workspace", + "options": "Workspace" + }, + { + "depends_on": "eval:(doc.ui_tour && doc.view_name == \"Page\")", + "fetch_from": ".", + "fieldname": "page_name", + "fieldtype": "Link", + "label": "Select Page", + "mandatory_depends_on": "eval:(doc.ui_tour && doc.view_name == \"Page\")", + "options": "Page" + }, + { + "default": "List", + "depends_on": "eval:(doc.ui_tour && doc.view_name == \"List\")", + "fetch_from": ".", + "fieldname": "list_name", + "fieldtype": "Select", + "label": "Select List View", + "mandatory_depends_on": "eval:(doc.ui_tour && doc.view_name == \"List\")", + "options": "List\nReport\nDashboard\nKanban\nGantt\nCalendar\nFile\nImage\nInbox\nMap" + }, + { + "depends_on": "eval:(doc.ui_tour && doc.view_name == \"List\" && doc.list_name == \"Report\")", + "fetch_from": ".", + "fieldname": "report_name", + "fieldtype": "Link", + "label": "Select Report", + "options": "Report" + }, + { + "default": "0", + "depends_on": "ui_tour", + "description": "The next tour will start from where the user left off.", + "fieldname": "track_steps", + "fieldtype": "Check", + "label": "Track Steps" + }, + { + "default": "0", + "depends_on": "eval: (doc.ui_tour && doc.view_name == \"Form\")", + "fieldname": "new_document_form", + "fieldtype": "Check", + "label": "New Document Form" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-11-24 12:03:45.449311", + "modified": "2023-05-18 01:28:24.593730", "modified_by": "Administrator", "module": "Desk", "name": "Form Tour", @@ -108,5 +210,6 @@ ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/frappe/desk/doctype/form_tour_step/form_tour_step.json b/frappe/desk/doctype/form_tour_step/form_tour_step.json index 7eb6eab223..f0cb8751b7 100644 --- a/frappe/desk/doctype/form_tour_step/form_tour_step.json +++ b/frappe/desk/doctype/form_tour_step/form_tour_step.json @@ -4,18 +4,29 @@ "doctype": "DocType", "engine": "InnoDB", "field_order": [ + "ui_tour", "is_table_field", "section_break_2", + "title", "parent_fieldname", "fieldname", - "title", + "element_selector", + "parent_element_selector", "description", + "ondemand_description", "column_break_2", "position", + "hide_buttons", + "popover_element", + "modal_trigger", + "offset_x", + "offset_y", + "next_on_click", "label", "fieldtype", "has_next_condition", "next_step_condition", + "next_form_tour", "section_break_13", "child_doctype" ], @@ -31,18 +42,20 @@ "columns": 4, "fieldname": "description", "fieldtype": "HTML Editor", + "ignore_xss_filter": 1, "in_list_view": 1, "label": "Description", "reqd": 1 }, { - "depends_on": "eval: (!doc.is_table_field || (doc.is_table_field && doc.parent_fieldname))", + "depends_on": "eval: (!doc.ui_tour && (!doc.is_table_field || (doc.is_table_field && doc.parent_fieldname)))", "fieldname": "fieldname", "fieldtype": "Select", "label": "Fieldname", - "reqd": 1 + "mandatory_depends_on": "eval: (!doc.ui_tour)" }, { + "depends_on": "eval:(!doc.ui_tour)", "fieldname": "label", "fieldtype": "Data", "in_list_view": 1, @@ -70,12 +83,14 @@ }, { "default": "0", + "depends_on": "eval:(!doc.ui_tour)", "fieldname": "has_next_condition", "fieldtype": "Check", "label": "Has Next Condition" }, { "default": "0", + "depends_on": "eval:(!doc.ui_tour)", "fieldname": "fieldtype", "fieldtype": "Data", "label": "Fieldtype", @@ -83,6 +98,7 @@ }, { "default": "0", + "depends_on": "eval:(!doc.ui_tour)", "fieldname": "is_table_field", "fieldtype": "Check", "label": "Is Table Field" @@ -105,17 +121,103 @@ "read_only": 1 }, { - "depends_on": "is_table_field", + "depends_on": "eval: (!doc.ui_tour || doc.is_table_field)", "fieldname": "parent_fieldname", "fieldtype": "Select", "label": "Parent Field", "mandatory_depends_on": "is_table_field" + }, + { + "default": "0", + "fetch_from": "next_form_tour.ui_tour", + "fieldname": "ui_tour", + "fieldtype": "Check", + "in_list_view": 1, + "label": "UI Tour" + }, + { + "depends_on": "eval:(doc.ui_tour)", + "description": "CSS selector for the element you want to highlight.", + "fieldname": "element_selector", + "fieldtype": "Data", + "label": "Element Selector", + "mandatory_depends_on": "eval:(doc.ui_tour)", + "reqd": 1 + }, + { + "depends_on": "eval:(doc.ui_tour)", + "description": "Mozilla doesn't support :has() so you can pass parent selector here as workaround", + "fieldname": "parent_element_selector", + "fieldtype": "Data", + "label": "Parent Element Selector" + }, + { + "depends_on": "eval:(doc.ui_tour)", + "fieldname": "next_form_tour", + "fieldtype": "Link", + "label": "Next Form Tour", + "options": "Form Tour" + }, + { + "default": "0", + "depends_on": "eval:(doc.ui_tour)", + "description": "Hide Previous, Next and Close button on highlight dialog.", + "fieldname": "hide_buttons", + "fieldtype": "Check", + "label": "Hide Buttons" + }, + { + "default": "0", + "depends_on": "eval:(doc.ui_tour)", + "description": "Move to next step when clicked inside highlighted area.", + "fieldname": "next_on_click", + "fieldtype": "Check", + "label": "Next on Click" + }, + { + "default": "0", + "depends_on": "eval:(doc.ui_tour)", + "description": "when clicked on element it will focus popover if present.", + "fieldname": "popover_element", + "fieldtype": "Check", + "label": "Popover Element" + }, + { + "default": "0", + "depends_on": "eval:(doc.ui_tour)", + "fieldname": "offset_x", + "fieldtype": "Int", + "label": "Offset X" + }, + { + "default": "0", + "depends_on": "eval:(doc.ui_tour)", + "fieldname": "offset_y", + "fieldtype": "Int", + "label": "Offset Y" + }, + { + "default": "0", + "depends_on": "eval:(doc.ui_tour)", + "description": "Enable if on click\nopens modal.", + "fieldname": "modal_trigger", + "fieldtype": "Check", + "label": "Modal Trigger" + }, + { + "columns": 4, + "depends_on": "eval: (doc.popover_element || doc.modal_trigger)", + "fieldname": "ondemand_description", + "fieldtype": "HTML Editor", + "ignore_xss_filter": 1, + "in_list_view": 1, + "label": "Popover or Modal Description" } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2022-01-27 15:18:36.481801", + "modified": "2023-05-18 01:55:44.245357", "modified_by": "Administrator", "module": "Desk", "name": "Form Tour Step",