Merge branch 'develop' into fix-note-2
This commit is contained in:
commit
d5b0c5ab90
20 changed files with 296 additions and 68 deletions
|
|
@ -32,7 +32,7 @@ context("Form Builder", () => {
|
|||
|
||||
cy.click_modal_primary_button("Change");
|
||||
|
||||
cy.get(".page-title .title-text").should("have.text", "Form Builder: Web Form Field");
|
||||
cy.get(".page-title .title-text").should("have.text", "Web Form Field");
|
||||
});
|
||||
|
||||
it("Save without change, check form dirty and reset changes", () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# License: MIT. See LICENSE
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from jinja2 import TemplateSyntaxError
|
||||
|
||||
import frappe
|
||||
|
|
@ -100,32 +102,26 @@ def get_preferred_address(doctype, name, preferred_key="is_primary_address"):
|
|||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_default_address(doctype, name, sort_key="is_primary_address"):
|
||||
def get_default_address(
|
||||
doctype: str, name: str, sort_key: str = "is_primary_address"
|
||||
) -> str | None:
|
||||
"""Returns default Address name for the given doctype, name"""
|
||||
if sort_key not in ["is_shipping_address", "is_primary_address"]:
|
||||
return None
|
||||
|
||||
out = frappe.db.sql(
|
||||
""" SELECT
|
||||
addr.name, addr.%s
|
||||
FROM
|
||||
`tabAddress` addr, `tabDynamic Link` dl
|
||||
WHERE
|
||||
dl.parent = addr.name and dl.link_doctype = %s and
|
||||
dl.link_name = %s and ifnull(addr.disabled, 0) = 0
|
||||
"""
|
||||
% (sort_key, "%s", "%s"),
|
||||
(doctype, name),
|
||||
as_dict=True,
|
||||
addresses = frappe.get_all(
|
||||
"Address",
|
||||
filters=[
|
||||
["Dynamic Link", "link_doctype", "=", doctype],
|
||||
["Dynamic Link", "link_name", "=", name],
|
||||
["disabled", "=", 0],
|
||||
],
|
||||
pluck="name",
|
||||
order_by=f"{sort_key} DESC",
|
||||
limit=1,
|
||||
)
|
||||
|
||||
if out:
|
||||
for contact in out:
|
||||
if contact.get(sort_key):
|
||||
return contact.name
|
||||
return out[0].name
|
||||
else:
|
||||
return None
|
||||
return addresses[0] if addresses else None
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ frappe.ui.form.on("DocType", {
|
|||
frm.toggle_enable("beta", 0);
|
||||
}
|
||||
|
||||
!frm.is_new() &&
|
||||
frm.add_custom_button(__("Try new form builder", [__(frm.doc.name)]), () => {
|
||||
frappe.set_route("form-builder", frm.doc.name);
|
||||
});
|
||||
render_form_builder_message(frm);
|
||||
|
||||
if (!frm.is_new() && !frm.doc.istable) {
|
||||
if (frm.doc.issingle) {
|
||||
|
|
@ -118,4 +115,31 @@ frappe.ui.form.on("DocField", {
|
|||
},
|
||||
});
|
||||
|
||||
function render_form_builder_message(frm) {
|
||||
$(frm.fields_dict["try_form_builder_html"].wrapper).empty();
|
||||
if (!frm.is_new() && frm.fields_dict["try_form_builder_html"]) {
|
||||
let title = __("Use Form Builder to visually edit your form layout");
|
||||
let msg = __(
|
||||
"You can drag and drop fields to create your form layout, add tabs, sections and columns to organize your form and update field properties all from one screen."
|
||||
);
|
||||
|
||||
let message = `
|
||||
<div class="flex form-message blue p-3">
|
||||
<div class="mr-3"><img style="border-radius: var(--border-radius-md)" width="360" src="/assets/frappe/images/form-builder.gif"></div>
|
||||
<div>
|
||||
<p style="font-size: var(--text-lg)">${title}</p>
|
||||
<p>${msg}</p>
|
||||
<div>
|
||||
<a class="btn btn-primary btn-sm" href="/app/form-builder/${frm.doc.name}">
|
||||
${__("Form Builder")} ${frappe.utils.icon("right", "xs")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$(frm.fields_dict["try_form_builder_html"].wrapper).html(message);
|
||||
}
|
||||
}
|
||||
|
||||
extend_cscript(cur_frm.cscript, new frappe.model.DocTypeController({ frm: cur_frm }));
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
"is_virtual",
|
||||
"queue_in_background",
|
||||
"fields_section_break",
|
||||
"try_form_builder_html",
|
||||
"fields",
|
||||
"sb1",
|
||||
"naming_rule",
|
||||
|
|
@ -630,6 +631,11 @@
|
|||
"fieldname": "is_calendar_and_gantt",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Calendar and Gantt"
|
||||
},
|
||||
{
|
||||
"fieldname": "try_form_builder_html",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Try Form Builder HTML"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-bolt",
|
||||
|
|
@ -712,7 +718,7 @@
|
|||
"link_fieldname": "reference_doctype"
|
||||
}
|
||||
],
|
||||
"modified": "2023-03-23 16:15:51.067267",
|
||||
"modified": "2023-05-15 14:07:51.526257",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "DocType",
|
||||
|
|
|
|||
|
|
@ -638,7 +638,9 @@ class File(Document):
|
|||
|
||||
def create_attachment_record(self):
|
||||
icon = ' <i class="fa fa-lock text-warning"></i>' if self.is_private else ""
|
||||
file_url = quote(frappe.safe_encode(self.file_url)) if self.file_url else self.file_name
|
||||
file_url = (
|
||||
quote(frappe.safe_encode(self.file_url), safe="/:") if self.file_url else self.file_name
|
||||
)
|
||||
file_name = self.file_name or self.file_url
|
||||
|
||||
self.add_comment_in_reference_doc(
|
||||
|
|
|
|||
|
|
@ -124,14 +124,14 @@
|
|||
"depends_on": "enable_rate_limit",
|
||||
"fieldname": "rate_limit_count",
|
||||
"fieldtype": "Int",
|
||||
"label": "Limit"
|
||||
"label": "Request Limit"
|
||||
},
|
||||
{
|
||||
"default": "86400",
|
||||
"depends_on": "enable_rate_limit",
|
||||
"fieldname": "rate_limit_seconds",
|
||||
"fieldtype": "Int",
|
||||
"label": "Seconds"
|
||||
"label": "Time Window (Seconds)"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
|
|
@ -141,7 +141,7 @@
|
|||
"link_fieldname": "server_script"
|
||||
}
|
||||
],
|
||||
"modified": "2023-05-12 20:54:54.365266",
|
||||
"modified": "2023-05-16 11:03:58.282680",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Server Script",
|
||||
|
|
|
|||
|
|
@ -436,8 +436,8 @@ class TestUser(FrappeTestCase):
|
|||
getdoc("User", "Administrator")
|
||||
doc = frappe.response.docs[0]
|
||||
self.assertListEqual(
|
||||
doc.get("__onload").get("all_modules", []),
|
||||
[m.get("module_name") for m in get_modules_from_all_apps()],
|
||||
sorted(doc.get("__onload").get("all_modules", [])),
|
||||
sorted(m.get("module_name") for m in get_modules_from_all_apps()),
|
||||
)
|
||||
|
||||
def test_reset_password_link_expiry(self):
|
||||
|
|
|
|||
|
|
@ -115,14 +115,7 @@ frappe.ui.form.on("Customize Form", {
|
|||
frm.page.set_title(__("Customize Form - {0}", [frm.doc.doc_type]));
|
||||
frappe.customize_form.set_primary_action(frm);
|
||||
|
||||
if (!frm.is_new()) {
|
||||
frm.add_custom_button(
|
||||
__("Try new form builder", [__(frm.doc.doc_type)]),
|
||||
() => {
|
||||
frappe.set_route("form-builder", frm.doc.doc_type, "customize");
|
||||
}
|
||||
);
|
||||
}
|
||||
render_form_builder_message(frm);
|
||||
|
||||
frm.add_custom_button(
|
||||
__("Go to {0} List", [__(frm.doc.doc_type)]),
|
||||
|
|
@ -426,4 +419,31 @@ frappe.customize_form.clear_locals_and_refresh = function (frm) {
|
|||
frm.refresh();
|
||||
};
|
||||
|
||||
function render_form_builder_message(frm) {
|
||||
$(frm.fields_dict["try_form_builder_html"].wrapper).empty();
|
||||
if (!frm.is_new() && frm.fields_dict["try_form_builder_html"]) {
|
||||
let title = __("Use Form Builder to visually customize your form layout");
|
||||
let msg = __(
|
||||
"You can drag and drop fields to create your form layout, add tabs, sections and columns to organize your form and update field properties all from one screen."
|
||||
);
|
||||
|
||||
let message = `
|
||||
<div class="flex form-message blue p-3">
|
||||
<div class="mr-3"><img style="border-radius: var(--border-radius-md)" width="275" src="/assets/frappe/images/form-builder.gif"></div>
|
||||
<div>
|
||||
<p style="font-size: var(--text-lg)">${title}</p>
|
||||
<p>${msg}</p>
|
||||
<div>
|
||||
<a class="btn btn-primary btn-sm" href="/app/form-builder/${frm.doc.doc_type}/customize">
|
||||
${__("Form Builder")} ${frappe.utils.icon("right", "xs")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$(frm.fields_dict["try_form_builder_html"].wrapper).html(message);
|
||||
}
|
||||
}
|
||||
|
||||
extend_cscript(cur_frm.cscript, new frappe.model.DocTypeController({ frm: cur_frm }));
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
"allow_import",
|
||||
"queue_in_background",
|
||||
"fields_section_break",
|
||||
"try_form_builder_html",
|
||||
"fields",
|
||||
"naming_section",
|
||||
"naming_rule",
|
||||
|
|
@ -366,6 +367,11 @@
|
|||
"fieldname": "is_calendar_and_gantt",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Calendar and Gantt"
|
||||
},
|
||||
{
|
||||
"fieldname": "try_form_builder_html",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Try Form Builder HTML"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
|
|
@ -374,7 +380,7 @@
|
|||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2022-10-30 23:39:49.628093",
|
||||
"modified": "2023-05-15 16:03:19.872532",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Custom",
|
||||
"name": "Customize Form",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ frappe.pages["form-builder"].on_page_show = function (wrapper) {
|
|||
|
||||
function load_form_builder(wrapper) {
|
||||
let route = frappe.get_route();
|
||||
route = route.filter((a) => a);
|
||||
if (route.length > 1) {
|
||||
let doctype = route[1];
|
||||
let is_customize_form = route[2] === "customize";
|
||||
|
|
@ -42,5 +43,140 @@ function load_form_builder(wrapper) {
|
|||
customize: is_customize_form,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
let d = new frappe.ui.Dialog({
|
||||
title: __("Select DocType"),
|
||||
fields: [
|
||||
{
|
||||
label: __("Select DocType"),
|
||||
fieldname: "doctype",
|
||||
fieldtype: "Link",
|
||||
options: "DocType",
|
||||
only_select: 1,
|
||||
},
|
||||
{
|
||||
label: __("Customize"),
|
||||
fieldname: "customize",
|
||||
fieldtype: "Check",
|
||||
},
|
||||
],
|
||||
primary_action_label: __("Edit"),
|
||||
primary_action({ doctype, customize }) {
|
||||
if (customize) {
|
||||
frappe.model.with_doctype(doctype).then(() => {
|
||||
let meta = frappe.get_meta(doctype);
|
||||
if (in_list(frappe.model.core_doctypes_list, this.doctype))
|
||||
frappe.throw(__("Core DocTypes cannot be customized."));
|
||||
|
||||
if (meta.issingle)
|
||||
frappe.throw(__("Single DocTypes cannot be customized."));
|
||||
|
||||
if (meta.custom)
|
||||
frappe.throw(
|
||||
__(
|
||||
"Only standard DocTypes are allowed to be customized from Customize Form."
|
||||
)
|
||||
);
|
||||
frappe.set_route("form-builder", doctype, "customize");
|
||||
});
|
||||
} else {
|
||||
frappe.set_route("form-builder", doctype);
|
||||
}
|
||||
},
|
||||
secondary_action_label: __("Create New DocType"),
|
||||
secondary_action() {
|
||||
d.hide();
|
||||
let new_d = new frappe.ui.Dialog({
|
||||
title: __("Create New DocType"),
|
||||
fields: [
|
||||
{
|
||||
label: __("DocType Name"),
|
||||
fieldname: "doctype_name",
|
||||
fieldtype: "Data",
|
||||
reqd: 1,
|
||||
},
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
label: __("Module"),
|
||||
fieldname: "module",
|
||||
fieldtype: "Link",
|
||||
options: "Module Def",
|
||||
reqd: 1,
|
||||
},
|
||||
{ fieldtype: "Section Break" },
|
||||
{
|
||||
label: __("Is Submittable"),
|
||||
fieldname: "is_submittable",
|
||||
fieldtype: "Check",
|
||||
description: __(
|
||||
"Once submitted, submittable documents cannot be changed. They can only be Cancelled and Amended."
|
||||
),
|
||||
depends_on: "eval:!doc.istable && !doc.issingle",
|
||||
},
|
||||
{
|
||||
label: __("Is Child Table"),
|
||||
fieldname: "istable",
|
||||
fieldtype: "Check",
|
||||
description: __("Child Tables are shown as a Grid in other DocTypes"),
|
||||
depends_on: "eval:!doc.is_submittable && !doc.issingle",
|
||||
},
|
||||
{
|
||||
label: __("Editable Grid"),
|
||||
fieldname: "editable_grid",
|
||||
fieldtype: "Check",
|
||||
depends_on: "istable",
|
||||
default: 1,
|
||||
},
|
||||
{
|
||||
label: __("Is Single"),
|
||||
fieldname: "issingle",
|
||||
fieldtype: "Check",
|
||||
description: __(
|
||||
"Single Types have only one record no tables associated. Values are stored in tabSingles"
|
||||
),
|
||||
depends_on: "eval:!doc.istable && !doc.is_submittable",
|
||||
},
|
||||
{
|
||||
label: __("Custom?"),
|
||||
fieldname: "custom",
|
||||
fieldtype: "Check",
|
||||
},
|
||||
],
|
||||
primary_action_label: __("Create & Continue"),
|
||||
primary_action(values) {
|
||||
if (!values.istable) values.editable_grid = 0;
|
||||
frappe.db
|
||||
.insert({
|
||||
doctype: "DocType",
|
||||
name: values.doctype_name,
|
||||
module: values.module,
|
||||
istable: values.istable,
|
||||
editable_grid: values.editable_grid,
|
||||
issingle: values.issingle,
|
||||
custom: values.custom,
|
||||
is_submittable: values.is_submittable,
|
||||
fields: [
|
||||
{
|
||||
label: "Title",
|
||||
fieldname: "title",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
],
|
||||
})
|
||||
.then((doc) => {
|
||||
frappe.set_route("form-builder", doc.name);
|
||||
});
|
||||
},
|
||||
secondary_action_label: __("Back"),
|
||||
secondary_action() {
|
||||
new_d.hide();
|
||||
d.show();
|
||||
},
|
||||
});
|
||||
new_d.show();
|
||||
},
|
||||
});
|
||||
|
||||
d.show();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -298,7 +298,9 @@ def export_query():
|
|||
if isinstance(visible_idx, str):
|
||||
visible_idx = json.loads(visible_idx)
|
||||
|
||||
data = run(report_name, form_params.filters, custom_columns=custom_columns)
|
||||
data = run(
|
||||
report_name, form_params.filters, custom_columns=custom_columns, are_default_filters=False
|
||||
)
|
||||
data = frappe._dict(data)
|
||||
if not data.columns:
|
||||
frappe.respond_as_web_page(
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ frappe.ui.form.on("Auto Email Report", {
|
|||
wrapper
|
||||
);
|
||||
|
||||
var filters = JSON.parse(frm.doc.filters || "{}");
|
||||
var filters = {};
|
||||
|
||||
let report_filters;
|
||||
|
||||
|
|
@ -102,8 +102,19 @@ frappe.ui.form.on("Auto Email Report", {
|
|||
frappe.query_reports[frm.doc.reference_report] &&
|
||||
frappe.query_reports[frm.doc.reference_report].filters
|
||||
) {
|
||||
if (frm.doc.filters) {
|
||||
filters = JSON.parse(frm.doc.filters);
|
||||
} else {
|
||||
frappe.db.get_value("Report", frm.doc.report, "json", (r) => {
|
||||
if (r && r.json) {
|
||||
filters = JSON.parse(r.json).filters || {};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
report_filters = frappe.query_reports[frm.doc.reference_report].filters;
|
||||
} else {
|
||||
filters = JSON.parse(frm.doc.filters || "{}");
|
||||
report_filters = frappe.query_reports[frm.doc.report].filters;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -328,6 +328,13 @@ def check_if_doc_is_dynamically_linked(doc, method="Delete"):
|
|||
):
|
||||
reference_doctype = refdoc.parenttype if meta.istable else df.parent
|
||||
reference_docname = refdoc.parent if meta.istable else refdoc.name
|
||||
|
||||
if reference_doctype in frappe.get_hooks("ignore_links_on_delete") or (
|
||||
reference_doctype in ignore_linked_doctypes and method == "Cancel"
|
||||
):
|
||||
# don't check for communication and todo!
|
||||
continue
|
||||
|
||||
at_position = f"at Row: {refdoc.idx}" if meta.istable else ""
|
||||
|
||||
raise_link_exists_exception(doc, reference_doctype, reference_docname, at_position)
|
||||
|
|
|
|||
BIN
frappe/public/images/form-builder.gif
Normal file
BIN
frappe/public/images/form-builder.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 478 KiB |
|
|
@ -1,8 +1,8 @@
|
|||
<script setup>
|
||||
import Sidebar from "./Sidebar.vue";
|
||||
import Tabs from "./Tabs.vue";
|
||||
import Sidebar from "./components/Sidebar.vue"
|
||||
import Tabs from "./components/Tabs.vue";
|
||||
import { computed, onMounted, watch, ref } from "vue";
|
||||
import { useStore } from "../store";
|
||||
import { useStore } from "./store";
|
||||
import { onClickOutside, useMagicKeys, whenever } from "@vueuse/core";
|
||||
|
||||
let store = useStore();
|
||||
|
|
@ -35,8 +35,8 @@ function setup_change_doctype_dialog() {
|
|||
default: store.doctype || null
|
||||
},
|
||||
{
|
||||
label: __("For Customize Form"),
|
||||
fieldname: "for_customize_form",
|
||||
label: __("Customize"),
|
||||
fieldname: "customize",
|
||||
fieldtype: "Check",
|
||||
default: store.is_customize_form
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ function setup_change_doctype_dialog() {
|
|||
primary_action_label: __("Change"),
|
||||
primary_action({ doctype }) {
|
||||
dialog.hide();
|
||||
let customize = dialog.get_value("for_customize_form") ? "customize" : "";
|
||||
let customize = dialog.get_value("customize") ? "customize" : "";
|
||||
frappe.set_route("form-builder", doctype, customize);
|
||||
}
|
||||
});
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { createApp, watchEffect } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import { useStore } from "./store";
|
||||
import FormBuilderComponent from "./components/FormBuilder.vue";
|
||||
import FormBuilderComponent from "./FormBuilder.vue";
|
||||
import { registerGlobalComponents } from "./globals.js";
|
||||
|
||||
class FormBuilder {
|
||||
|
|
@ -17,7 +17,7 @@ class FormBuilder {
|
|||
|
||||
init(refresh) {
|
||||
// set page title
|
||||
this.page.set_title(__("Form Builder: {0}", [this.doctype]));
|
||||
this.page.set_title(__(this.doctype));
|
||||
|
||||
this.setup_page_actions();
|
||||
!refresh && this.setup_app();
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ export const useStore = defineStore("form-builder-store", () => {
|
|||
});
|
||||
|
||||
setup_undo_redo();
|
||||
setup_breadcrumbs();
|
||||
}
|
||||
|
||||
let undo_redo_keyboard_event = onKeyDown(true, (e) => {
|
||||
|
|
@ -120,6 +121,23 @@ export const useStore = defineStore("form-builder-store", () => {
|
|||
undo_redo_keyboard_event;
|
||||
}
|
||||
|
||||
function setup_breadcrumbs() {
|
||||
let breadcrumbs = `
|
||||
<li><a href="/app/doctype">${__("DocType")}</a></li>
|
||||
<li><a href="/app/doctype/${doctype.value}">${__(doctype.value)}</a></li>
|
||||
`;
|
||||
if (is_customize_form.value) {
|
||||
breadcrumbs = `
|
||||
<li><a href="/app/customize-form?doc_type=${doctype.value}">
|
||||
${__("Customize Form")}
|
||||
</a></li>
|
||||
`;
|
||||
}
|
||||
breadcrumbs += `<li class="disabled"><a href="#">${__("Form Builder")}</a></li>`;
|
||||
frappe.breadcrumbs.clear();
|
||||
frappe.breadcrumbs.$breadcrumbs.append(breadcrumbs);
|
||||
}
|
||||
|
||||
function reset_changes() {
|
||||
fetch();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ frappe.ui.form.ControlDateRange = class ControlDateRange extends frappe.ui.form.
|
|||
}
|
||||
format_for_input(value1, value2) {
|
||||
if (value1 && value2) {
|
||||
value1 = frappe.datetime.str_to_user(value1);
|
||||
value2 = frappe.datetime.str_to_user(value2);
|
||||
value1 = frappe.datetime.str_to_user(value1, false, true);
|
||||
value2 = frappe.datetime.str_to_user(value2, false, true);
|
||||
return __("{0} to {1}", [value1, value2]);
|
||||
}
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -36,11 +36,13 @@ frappe.workflow = {
|
|||
frappe.workflow.setup(doc.doctype);
|
||||
return frappe.xcall("frappe.model.workflow.get_transitions", { doc: doc });
|
||||
},
|
||||
get_document_state: function (doctype, state) {
|
||||
get_document_state_roles: function (doctype, state) {
|
||||
frappe.workflow.setup(doctype);
|
||||
return frappe.get_children(frappe.workflow.workflows[doctype], "states", {
|
||||
state: state,
|
||||
})[0];
|
||||
let workflow_states =
|
||||
frappe.get_children(frappe.workflow.workflows[doctype], "states", { state: state }) ||
|
||||
[];
|
||||
let allow_edit_list = workflow_states.map((d) => d.allow_edit);
|
||||
return allow_edit_list;
|
||||
},
|
||||
is_self_approval_enabled: function (doctype) {
|
||||
return frappe.workflow.workflows[doctype].allow_self_approval;
|
||||
|
|
@ -55,14 +57,13 @@ frappe.workflow = {
|
|||
var state =
|
||||
doc[state_fieldname] || frappe.workflow.get_default_state(doctype, doc.docstatus);
|
||||
|
||||
var allow_edit = state
|
||||
? frappe.workflow.get_document_state(doctype, state) &&
|
||||
frappe.workflow.get_document_state(doctype, state).allow_edit
|
||||
let allow_edit_roles = state
|
||||
? frappe.workflow.get_document_state_roles(doctype, state)
|
||||
: null;
|
||||
|
||||
if (!frappe.user_roles.includes(allow_edit)) {
|
||||
return true;
|
||||
}
|
||||
let has_common_role = frappe.user_roles.some((role) =>
|
||||
allow_edit_roles.includes(role)
|
||||
);
|
||||
return !has_common_role;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -411,10 +411,9 @@ export default class OnboardingWidget extends Widget {
|
|||
});
|
||||
};
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
message: __("Let us continue with the onboarding"),
|
||||
title: __("Document Saved"),
|
||||
});
|
||||
frappe.show_alert(
|
||||
__("Document Saved") + "<br>" + __("Let us continue with the onboarding")
|
||||
);
|
||||
this.mark_complete(step);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue