Co-authored-by: hrwx <himanshuwarekar@yahoo.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit b0c1e400ea
)
Co-authored-by: Shariq Ansari <30859809+shariquerik@users.noreply.github.com>
version-14
@@ -24,6 +24,7 @@ context("Folder Navigation", () => { | |||
it("Navigating the nested folders, checking if the URL formed is correct, checking if the added content in the child folder is correct", () => { | |||
//Navigating inside the Attachments folder | |||
cy.wait(500); | |||
cy.get('[title="Attachments"] > span').click(); | |||
//To check if the URL formed after visiting the attachments folder is correct | |||
@@ -36,6 +37,7 @@ context("Folder Navigation", () => { | |||
cy.click_modal_primary_button("Create"); | |||
//Navigating inside the added folder in the Attachments folder | |||
cy.wait(500); | |||
cy.get('[title="Test Folder"] > span').click(); | |||
//To check if the URL is correct after visiting the Test Folder | |||
@@ -51,7 +53,12 @@ context("Folder Navigation", () => { | |||
cy.click_modal_primary_button("Upload"); | |||
//To check if the added file is present in the Test Folder | |||
cy.get("span.level-item > span").should("contain", "Test Folder"); | |||
cy.visit("/app/file/view/home/Attachments"); | |||
cy.wait(500); | |||
cy.get("span.level-item > a > span").should("contain", "Test Folder"); | |||
cy.visit("/app/file/view/home/Attachments/Test%20Folder"); | |||
cy.wait(500); | |||
cy.get(".list-row-container").eq(0).should("contain.text", "72402.jpg"); | |||
cy.get(".list-row-checkbox").eq(0).click(); | |||
@@ -0,0 +1,231 @@ | |||
context("View", () => { | |||
before(() => { | |||
cy.login(); | |||
cy.visit("/app/website"); | |||
}); | |||
it("Route to ToDo List View", () => { | |||
cy.visit("/app/todo/view/list"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("List"); | |||
}); | |||
}); | |||
it("Route to ToDo Report View", () => { | |||
cy.visit("/app/todo/view/report"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
it("Route to ToDo Dashboard View", () => { | |||
cy.visit("/app/todo/view/dashboard"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Dashboard"); | |||
}); | |||
}); | |||
it("Route to ToDo Gantt View", () => { | |||
cy.visit("/app/todo/view/gantt"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Gantt"); | |||
}); | |||
}); | |||
it("Route to ToDo Kanban View", () => { | |||
cy.call("frappe.tests.ui_test_helpers.create_kanban").then(() => { | |||
cy.visit("/app/note/view/kanban/_Note _Kanban"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Kanban"); | |||
}); | |||
}); | |||
}); | |||
it("Route to ToDo Calendar View", () => { | |||
cy.visit("/app/todo/view/calendar"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Calendar"); | |||
}); | |||
}); | |||
it("Route to Custom Tree View", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_tree_doctype").then(() => { | |||
cy.visit("/app/custom-tree/view/tree"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_tree") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Tree"); | |||
}); | |||
}); | |||
}); | |||
it("Route to Custom Image View", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_image_doctype").then(() => { | |||
cy.visit("app/custom-image/view/image"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Image"); | |||
}); | |||
}); | |||
}); | |||
it("Route to Communication Inbox View", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_inbox").then(() => { | |||
cy.visit("app/communication/view/inbox"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Inbox"); | |||
}); | |||
}); | |||
}); | |||
it("Route to File View", () => { | |||
cy.visit("app/file"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("File"); | |||
expect(list.current_folder).to.equal("Home"); | |||
}); | |||
cy.visit("app/file/view/home/Attachments"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("File"); | |||
expect(list.current_folder).to.equal("Home/Attachments"); | |||
}); | |||
}); | |||
it("Re-route to default view", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { view: "Report" }).then(() => { | |||
cy.visit("app/event"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
}); | |||
it("Route to default view from app/{doctype}", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { view: "Report" }).then(() => { | |||
cy.visit("/app/event"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
}); | |||
it("Route to default view from app/{doctype}/view", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { view: "Report" }).then(() => { | |||
cy.visit("/app/event/view"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
}); | |||
it("Force Route to default view from app/{doctype}", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { | |||
view: "Report", | |||
force_reroute: true, | |||
}).then(() => { | |||
cy.visit("/app/event"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
}); | |||
it("Force Route to default view from app/{doctype}/view", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { | |||
view: "Report", | |||
force_reroute: true, | |||
}).then(() => { | |||
cy.visit("/app/event/view"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
}); | |||
it("Force Route to default view from app/{doctype}/view", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { | |||
view: "Report", | |||
force_reroute: true, | |||
}).then(() => { | |||
cy.visit("/app/event/view/list"); | |||
cy.wait(500); | |||
cy.window() | |||
.its("cur_list") | |||
.then((list) => { | |||
expect(list.view_name).to.equal("Report"); | |||
}); | |||
}); | |||
}); | |||
it("Validate Route History for Default View", () => { | |||
cy.call("frappe.tests.ui_test_helpers.setup_default_view", { view: "Report" }).then(() => { | |||
cy.visit("/app/event"); | |||
cy.visit("/app/event/view/list"); | |||
cy.location("pathname").should("eq", "/app/event/view/list"); | |||
cy.go("back"); | |||
cy.location("pathname").should("eq", "/app/event"); | |||
}); | |||
}); | |||
it("Route to Form", () => { | |||
cy.call("frappe.tests.ui_test_helpers.create_note").then(() => { | |||
cy.visit("/app/note/Routing Test"); | |||
cy.window() | |||
.its("cur_frm") | |||
.then((frm) => { | |||
expect(frm.doc.title).to.equal("Routing Test"); | |||
}); | |||
}); | |||
}); | |||
it("Route to Settings Workspace", () => { | |||
cy.visit("/app/settings"); | |||
cy.get(".title-text").should("contain", "Settings"); | |||
}); | |||
}); |
@@ -2,6 +2,7 @@ | |||
"actions": [], | |||
"allow_import": 1, | |||
"creation": "2013-01-29 10:47:14", | |||
"default_view": "Inbox", | |||
"description": "Keeps track of all communications", | |||
"doctype": "DocType", | |||
"document_type": "Setup", | |||
@@ -198,7 +199,6 @@ | |||
"label": "More Information" | |||
}, | |||
{ | |||
"bold": 0, | |||
"default": "Now", | |||
"fieldname": "communication_date", | |||
"fieldtype": "Datetime", | |||
@@ -395,7 +395,7 @@ | |||
"icon": "fa fa-comment", | |||
"idx": 1, | |||
"links": [], | |||
"modified": "2022-03-30 11:24:25.728637", | |||
"modified": "2022-05-09 00:13:45.310564", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "Communication", | |||
@@ -454,8 +454,9 @@ | |||
"sender_field": "sender", | |||
"sort_field": "modified", | |||
"sort_order": "DESC", | |||
"states": [], | |||
"subject_field": "subject", | |||
"title_field": "subject", | |||
"track_changes": 1, | |||
"track_seen": 1 | |||
} | |||
} |
@@ -55,6 +55,7 @@ frappe.ui.form.on("DocType", { | |||
if (frm.is_new()) { | |||
frm.events.set_default_permission(frm); | |||
frm.set_value("default_view", "List"); | |||
} else { | |||
frm.toggle_enable("engine", 0); | |||
} | |||
@@ -66,12 +67,14 @@ frappe.ui.form.on("DocType", { | |||
frm.cscript.autoname(frm); | |||
frm.cscript.set_naming_rule_description(frm); | |||
frm.trigger("setup_default_views"); | |||
}, | |||
istable: (frm) => { | |||
if (frm.doc.istable && frm.is_new()) { | |||
frm.set_value("autoname", "autoincrement"); | |||
frm.set_value("allow_rename", 0); | |||
frm.set_value("default_view", null); | |||
} else if (!frm.doc.istable && !frm.is_new()) { | |||
frm.events.set_default_permission(frm); | |||
} | |||
@@ -82,6 +85,18 @@ frappe.ui.form.on("DocType", { | |||
frm.add_child("permissions", { role: "System Manager" }); | |||
} | |||
}, | |||
is_tree: (frm) => { | |||
frm.trigger("setup_default_views"); | |||
}, | |||
is_calendar_and_gantt: (frm) => { | |||
frm.trigger("setup_default_views"); | |||
}, | |||
setup_default_views: (frm) => { | |||
frappe.model.set_default_views_for_doctype(frm.doc.name, frm); | |||
}, | |||
}); | |||
frappe.ui.form.on("DocField", { | |||
@@ -171,6 +186,10 @@ frappe.ui.form.on("DocField", { | |||
fieldtype: function (frm) { | |||
frm.trigger("max_attachments"); | |||
}, | |||
fields_add: (frm) => { | |||
frm.trigger("setup_default_views"); | |||
}, | |||
}); | |||
extend_cscript(cur_frm.cscript, new frappe.model.DocTypeController({ frm: cur_frm })); |
@@ -14,6 +14,7 @@ | |||
"istable", | |||
"issingle", | |||
"is_tree", | |||
"is_calendar_and_gantt", | |||
"editable_grid", | |||
"quick_entry", | |||
"cb01", | |||
@@ -53,6 +54,8 @@ | |||
"default_print_format", | |||
"sort_field", | |||
"sort_order", | |||
"default_view", | |||
"force_re_route_to_default_view", | |||
"column_break_29", | |||
"document_type", | |||
"icon", | |||
@@ -606,6 +609,24 @@ | |||
"fieldname": "make_attachments_public", | |||
"fieldtype": "Check", | |||
"label": "Make Attachments Public by Default" | |||
}, | |||
{ | |||
"fieldname": "default_view", | |||
"fieldtype": "Select", | |||
"label": "Default View" | |||
}, | |||
{ | |||
"default": "0", | |||
"fieldname": "force_re_route_to_default_view", | |||
"fieldtype": "Check", | |||
"label": "Force Re-route to Default View" | |||
}, | |||
{ | |||
"default": "0", | |||
"description": "Enables Calendar and Gantt views.", | |||
"fieldname": "is_calendar_and_gantt", | |||
"fieldtype": "Check", | |||
"label": "Is Calendar and Gantt" | |||
} | |||
], | |||
"icon": "fa fa-bolt", | |||
@@ -688,7 +709,7 @@ | |||
"link_fieldname": "reference_doctype" | |||
} | |||
], | |||
"modified": "2022-09-02 12:05:59.589751", | |||
"modified": "2022-10-12 14:13:27.315351", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "DocType", | |||
@@ -2,6 +2,7 @@ | |||
"actions": [], | |||
"allow_import": 1, | |||
"creation": "2012-12-12 11:19:22", | |||
"default_view": "File", | |||
"doctype": "DocType", | |||
"engine": "InnoDB", | |||
"field_order": [ | |||
@@ -169,10 +170,11 @@ | |||
"read_only": 1 | |||
} | |||
], | |||
"force_re_route_to_default_view": 1, | |||
"icon": "fa fa-file", | |||
"idx": 1, | |||
"links": [], | |||
"modified": "2022-09-13 15:50:15.508250", | |||
"modified": "2022-09-13 15:50:15.508251", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "File", | |||
@@ -72,6 +72,7 @@ frappe.ui.form.on("Customize Form", { | |||
} else { | |||
frm.refresh(); | |||
frm.trigger("setup_sortable"); | |||
frm.trigger("setup_default_views"); | |||
} | |||
} | |||
localStorage["customize_doctype"] = frm.doc.doc_type; | |||
@@ -82,8 +83,12 @@ frappe.ui.form.on("Customize Form", { | |||
} | |||
}, | |||
is_calendar_and_gantt: function (frm) { | |||
frm.trigger("setup_default_views"); | |||
}, | |||
setup_sortable: function (frm) { | |||
frm.doc.fields.forEach(function (f, i) { | |||
frm.doc.fields.forEach(function (f) { | |||
if (!f.is_custom_field) { | |||
f._sortable = false; | |||
} | |||
@@ -222,6 +227,10 @@ frappe.ui.form.on("Customize Form", { | |||
frm.set_df_property("sort_field", "options", fields); | |||
} | |||
}, | |||
setup_default_views(frm) { | |||
frappe.model.set_default_views_for_doctype(frm.doc.doc_type, frm); | |||
}, | |||
}); | |||
// can't delete standard fields | |||
@@ -237,6 +246,7 @@ frappe.ui.form.on("Customize Form Field", { | |||
var f = frappe.model.get_doc(cdt, cdn); | |||
f.is_system_generated = false; | |||
f.is_custom_field = true; | |||
frm.trigger("setup_default_views"); | |||
}, | |||
}); | |||
@@ -13,6 +13,7 @@ | |||
"search_fields", | |||
"column_break_5", | |||
"istable", | |||
"is_calendar_and_gantt", | |||
"editable_grid", | |||
"quick_entry", | |||
"track_changes", | |||
@@ -35,6 +36,8 @@ | |||
"show_title_field_in_link", | |||
"translated_doctype", | |||
"default_print_format", | |||
"default_view", | |||
"force_re_route_to_default_view", | |||
"column_break_29", | |||
"show_preview_popup", | |||
"email_settings_section", | |||
@@ -337,6 +340,25 @@ | |||
"fieldname": "make_attachments_public", | |||
"fieldtype": "Check", | |||
"label": "Make Attachments Public by Default" | |||
}, | |||
{ | |||
"fieldname": "default_view", | |||
"fieldtype": "Select", | |||
"label": "Default View" | |||
}, | |||
{ | |||
"default": "0", | |||
"depends_on": "default_view", | |||
"fieldname": "force_re_route_to_default_view", | |||
"fieldtype": "Check", | |||
"label": "Force Re-route to Default View" | |||
}, | |||
{ | |||
"default": "0", | |||
"description": "Enables Calendar and Gantt views.", | |||
"fieldname": "is_calendar_and_gantt", | |||
"fieldtype": "Check", | |||
"label": "Is Calendar and Gantt" | |||
} | |||
], | |||
"hide_toolbar": 1, | |||
@@ -345,7 +367,7 @@ | |||
"index_web_pages_for_search": 1, | |||
"issingle": 1, | |||
"links": [], | |||
"modified": "2022-08-24 06:57:47.966331", | |||
"modified": "2022-08-30 11:45:16.772277", | |||
"modified_by": "Administrator", | |||
"module": "Custom", | |||
"name": "Customize Form", | |||
@@ -586,6 +586,10 @@ doctype_properties = { | |||
"naming_rule": "Data", | |||
"autoname": "Data", | |||
"show_title_field_in_link": "Check", | |||
"translate_link_fields": "Check", | |||
"is_calendar_and_gantt": "Check", | |||
"default_view": "Select", | |||
"force_re_route_to_default_view": "Check", | |||
"translated_doctype": "Check", | |||
} | |||
@@ -196,7 +196,7 @@ frappe.views.BaseList = class BaseList { | |||
Map: "map", | |||
}; | |||
if (frappe.boot.desk_settings.view_switcher) { | |||
if (frappe.boot.desk_settings.view_switcher && !this.meta.force_re_route_to_default_view) { | |||
/* @preserve | |||
for translation, don't remove | |||
__("List View") __("Report View") __("Dashboard View") __("Gantt View"), | |||
@@ -349,7 +349,7 @@ $.extend(frappe.model, { | |||
is_tree: function (doctype) { | |||
if (!doctype) return false; | |||
return frappe.boot.treeviews.indexOf(doctype) != -1; | |||
return locals.DocType[doctype] && locals.DocType[doctype].is_tree; | |||
}, | |||
is_fresh(doc) { | |||
@@ -754,6 +754,42 @@ $.extend(frappe.model, { | |||
} | |||
return frappe.model.numeric_fieldtypes.includes(fieldtype); | |||
}, | |||
set_default_views_for_doctype(doctype, frm) { | |||
frappe.model.with_doctype(doctype, () => { | |||
let meta = frappe.get_meta(doctype); | |||
let default_views = ["List", "Report", "Dashboard", "Kanban"]; | |||
if (meta.is_calendar_and_gantt && frappe.views.calendar[doctype]) { | |||
let views = ["Calendar", "Gantt"]; | |||
default_views.push(...views); | |||
} | |||
if (meta.is_tree) { | |||
default_views.push("Tree"); | |||
} | |||
if (frm.doc.image_field) { | |||
default_views.push("Image"); | |||
} | |||
if (doctype === "Communication" && frappe.boot.email_accounts.length) { | |||
default_views.push("Inbox"); | |||
} | |||
if ( | |||
(frm.doc.fields.find((i) => i.fieldname === "latitude") && | |||
frm.doc.fields.find((i) => i.fieldname === "longitude")) || | |||
frm.doc.fields.find( | |||
(i) => i.fieldname === "location" && i.fieldtype == "Geolocation" | |||
) | |||
) { | |||
default_views.push("Map"); | |||
} | |||
frm.set_df_property("default_view", "options", default_views); | |||
}); | |||
}, | |||
}); | |||
// legacy | |||
@@ -89,6 +89,18 @@ frappe.router = { | |||
"image", | |||
"inbox", | |||
], | |||
list_views_route: { | |||
list: "List", | |||
kanban: "Kanban", | |||
report: "Report", | |||
calendar: "Calendar", | |||
tree: "Tree", | |||
gantt: "Gantt", | |||
dashboard: "Dashboard", | |||
image: "Image", | |||
inbox: "Inbox", | |||
file: "Home", | |||
}, | |||
layout_mapped: {}, | |||
is_app_route(path) { | |||
@@ -115,7 +127,7 @@ frappe.router = { | |||
} | |||
}, | |||
route() { | |||
async route() { | |||
// resolve the route from the URL or hash | |||
// translate it so the objects are well defined | |||
// and render the page as required | |||
@@ -126,22 +138,22 @@ frappe.router = { | |||
if (this.re_route(sub_path)) return; | |||
this.current_sub_path = sub_path; | |||
this.current_route = this.parse(); | |||
this.current_route = await this.parse(); | |||
this.set_history(sub_path); | |||
this.render(); | |||
this.set_title(sub_path); | |||
this.trigger("change"); | |||
}, | |||
parse(route) { | |||
async parse(route) { | |||
route = this.get_sub_path_string(route).split("/"); | |||
if (!route) return []; | |||
route = $.map(route, this.decode_component); | |||
this.set_route_options_from_url(); | |||
return this.convert_to_standard_route(route); | |||
return await this.convert_to_standard_route(route); | |||
}, | |||
convert_to_standard_route(route) { | |||
async convert_to_standard_route(route) { | |||
// /app/settings = ["Workspaces", "Settings"] | |||
// /app/private/settings = ["Workspaces", "private", "Settings"] | |||
// /app/user = ["List", "User"] | |||
@@ -161,7 +173,7 @@ frappe.router = { | |||
route = ["Workspaces", "private", frappe.workspaces[private_workspace].title]; | |||
} else if (this.routes[route[0]]) { | |||
// route | |||
route = this.set_doctype_route(route); | |||
route = await this.set_doctype_route(route); | |||
} | |||
return route; | |||
@@ -174,36 +186,85 @@ frappe.router = { | |||
set_doctype_route(route) { | |||
let doctype_route = this.routes[route[0]]; | |||
// doctype route | |||
if (route[1]) { | |||
if (route[2] && route[1] === "view") { | |||
route = this.get_standard_route_for_list(route, doctype_route); | |||
} else { | |||
return frappe.model.with_doctype(doctype_route.doctype).then(() => { | |||
// doctype route | |||
let meta = frappe.get_meta(doctype_route.doctype); | |||
if (route[1] && route[1] === "view" && route[2]) { | |||
route = this.get_standard_route_for_list( | |||
route, | |||
doctype_route, | |||
meta.force_re_route_to_default_view && meta.default_view | |||
? meta.default_view | |||
: null | |||
); | |||
} else if (route[1] && route[1] !== "view" && !route[2]) { | |||
let docname = route[1]; | |||
if (route.length > 2) { | |||
docname = route.slice(1).join("/"); | |||
} | |||
route = ["Form", doctype_route.doctype, docname]; | |||
} else if (frappe.model.is_single(doctype_route.doctype)) { | |||
route = ["Form", doctype_route.doctype, doctype_route.doctype]; | |||
} else if (meta.default_view) { | |||
route = [ | |||
"List", | |||
doctype_route.doctype, | |||
this.list_views_route[meta.default_view.toLowerCase()], | |||
]; | |||
} else { | |||
route = ["List", doctype_route.doctype, "List"]; | |||
} | |||
} else if (frappe.model.is_single(doctype_route.doctype)) { | |||
route = ["Form", doctype_route.doctype, doctype_route.doctype]; | |||
} else { | |||
route = ["List", doctype_route.doctype, "List"]; | |||
} | |||
// reset the layout to avoid using incorrect views | |||
this.doctype_layout = doctype_route.doctype_layout; | |||
return route; | |||
// reset the layout to avoid using incorrect views | |||
this.doctype_layout = doctype_route.doctype_layout; | |||
return route; | |||
}); | |||
}, | |||
get_standard_route_for_list(route, doctype_route) { | |||
get_standard_route_for_list(route, doctype_route, default_view) { | |||
let standard_route; | |||
if (route[2].toLowerCase() === "tree") { | |||
let _route = default_view || route[2] || ""; | |||
if (_route.toLowerCase() === "tree") { | |||
standard_route = ["Tree", doctype_route.doctype]; | |||
} else { | |||
standard_route = ["List", doctype_route.doctype, frappe.utils.to_title_case(route[2])]; | |||
let new_route = this.list_views_route[_route.toLowerCase()]; | |||
let re_route = route[2].toLowerCase() !== new_route.toLowerCase(); | |||
if (re_route) { | |||
/** | |||
* In case of force_re_route, the url of the route should change, | |||
* if the _route and route[2] are different, it means there is a default_view | |||
* with force_re_route enabled. | |||
* | |||
* To change the url, to the correct view, the route[2] is changed with default_view | |||
* | |||
* Eg: If default_view is set to Report with force_re_route enabled and user routes | |||
* to List, | |||
* route: [todo, view, list] | |||
* default_view: report | |||
* | |||
* replaces the list to report and re-routes to the new route but should be replaced in | |||
* the history since the list route should not exist in history as we are rerouting it to | |||
* report | |||
*/ | |||
frappe.route_flags.replace_route = true; | |||
route[2] = _route.toLowerCase(); | |||
this.set_route(route); | |||
} | |||
standard_route = [ | |||
"List", | |||
doctype_route.doctype, | |||
this.list_views_route[_route.toLowerCase()], | |||
]; | |||
// calendar / kanban / dashboard / folder | |||
if (route[3]) standard_route.push(...route.slice(3, route.length)); | |||
} | |||
return standard_route; | |||
}, | |||
@@ -345,6 +406,7 @@ frappe.router = { | |||
} else if (view === "tree") { | |||
new_route = [this.slug(route[1]), "view", "tree"]; | |||
} | |||
return new_route; | |||
}, | |||
@@ -208,13 +208,10 @@ frappe.search.utils = { | |||
}, | |||
}); | |||
} | |||
if (in_list(frappe.boot.treeviews, item)) { | |||
out.push(option("Tree", ["Tree", item], 0.05)); | |||
} else { | |||
out.push(option("List", ["List", item], 0.05)); | |||
if (frappe.model.can_get_report(item)) { | |||
out.push(option("Report", ["List", item, "Report"], 0.04)); | |||
} | |||
out.push(option("List", ["List", item], 0.05)); | |||
if (frappe.model.can_get_report(item)) { | |||
out.push(option("Report", ["List", item, "Report"], 0.04)); | |||
} | |||
} | |||
} | |||
@@ -1260,20 +1260,12 @@ Object.assign(frappe.utils, { | |||
if (frappe.model.is_single(item.doctype)) { | |||
route = doctype_slug; | |||
} else { | |||
if (!item.doc_view) { | |||
if (frappe.model.is_tree(item.doctype)) { | |||
item.doc_view = "Tree"; | |||
} else { | |||
item.doc_view = "List"; | |||
} | |||
} | |||
switch (item.doc_view) { | |||
case "List": | |||
if (item.filters) { | |||
frappe.route_options = item.filters; | |||
} | |||
route = doctype_slug; | |||
route = `${doctype_slug}/view/list`; | |||
break; | |||
case "Tree": | |||
route = `${doctype_slug}/view/tree`; | |||
@@ -1290,12 +1282,11 @@ Object.assign(frappe.utils, { | |||
case "Calendar": | |||
route = `${doctype_slug}/view/calendar/default`; | |||
break; | |||
case "Kanban": | |||
route = `${doctype_slug}/view/kanban`; | |||
break; | |||
default: | |||
frappe.throw({ | |||
message: __("Not a valid view:") + item.doc_view, | |||
title: __("Unknown View"), | |||
}); | |||
route = ""; | |||
route = doctype_slug; | |||
} | |||
} | |||
} else if (type === "report") { | |||
@@ -144,7 +144,7 @@ frappe.breadcrumbs = { | |||
} else { | |||
let route; | |||
const doctype_route = frappe.router.slug(frappe.router.doctype_layout || doctype); | |||
if (frappe.boot.treeviews.indexOf(doctype) !== -1) { | |||
if (doctype_meta.is_tree) { | |||
let view = frappe.model.user_settings[doctype].last_view || "Tree"; | |||
route = `${doctype_route}/view/${view}`; | |||
} else { | |||
@@ -74,7 +74,7 @@ frappe.views.FileView = class FileView extends frappe.views.ListView { | |||
this.page_title = __("File Manager"); | |||
const route = frappe.get_route(); | |||
this.current_folder = route.slice(2).join("/"); | |||
this.current_folder = route.slice(2).join("/") || "Home"; | |||
this.filters = [["File", "folder", "=", this.current_folder, true]]; | |||
this.order_by = this.view_user_settings.order_by || "file_name asc"; | |||
@@ -286,7 +286,7 @@ frappe.views.FileView = class FileView extends frappe.views.ListView { | |||
} | |||
get_breadcrumbs_html() { | |||
const route = frappe.router.parse(); | |||
const route = frappe.get_route(); | |||
const folders = route.slice(2); | |||
return folders | |||
@@ -9,14 +9,9 @@ frappe.views.KanbanView = class KanbanView extends frappe.views.ListView { | |||
const doctype = route[1]; | |||
const user_settings = frappe.get_user_settings(doctype)["Kanban"] || {}; | |||
if (!user_settings.last_kanban_board) { | |||
frappe.msgprint({ | |||
title: __("Error"), | |||
indicator: "red", | |||
message: __("Missing parameter Kanban Board Name"), | |||
}); | |||
frappe.set_route("List", doctype, "List"); | |||
return true; | |||
return new frappe.views.KanbanView({ doctype: doctype }); | |||
} | |||
route.push(user_settings.last_kanban_board); | |||
frappe.set_route(route); | |||
return true; | |||
@@ -28,9 +23,35 @@ frappe.views.KanbanView = class KanbanView extends frappe.views.ListView { | |||
return "Kanban"; | |||
} | |||
show() { | |||
frappe.views.KanbanView.get_kanbans(this.doctype).then((kanbans) => { | |||
if (!kanbans.length) { | |||
return frappe.views.KanbanView.show_kanban_dialog(this.doctype, true); | |||
} else if (kanbans.length && frappe.get_route().length !== 4) { | |||
return frappe.views.KanbanView.show_kanban_dialog(this.doctype, true); | |||
} else { | |||
this.kanbans = kanbans; | |||
return frappe.run_serially([ | |||
() => this.show_skeleton(), | |||
() => this.fetch_meta(), | |||
() => this.hide_skeleton(), | |||
() => this.check_permissions(), | |||
() => this.init(), | |||
() => this.before_refresh(), | |||
() => this.refresh(), | |||
]); | |||
} | |||
}); | |||
} | |||
setup_defaults() { | |||
return super.setup_defaults().then(() => { | |||
this.board_name = frappe.get_route()[3]; | |||
let get_board_name = () => { | |||
return this.kanbans.length && this.kanbans[0].name; | |||
}; | |||
this.board_name = frappe.get_route()[3] || get_board_name() || null; | |||
this.page_title = __(this.board_name); | |||
this.card_meta = this.get_card_meta(); | |||
this.page_length = 0; | |||
@@ -143,21 +164,22 @@ frappe.views.KanbanView = class KanbanView extends frappe.views.ListView { | |||
render() { | |||
const board_name = this.board_name; | |||
if (!this.kanban) { | |||
this.kanban = new frappe.views.KanbanBoard({ | |||
doctype: this.doctype, | |||
board: this.board, | |||
board_name: board_name, | |||
cards: this.data, | |||
card_meta: this.card_meta, | |||
wrapper: this.$result, | |||
cur_list: this, | |||
user_settings: this.view_user_settings, | |||
}); | |||
} | |||
if (this.kanban && board_name === this.kanban.board_name) { | |||
this.kanban.update(this.data); | |||
return; | |||
} | |||
this.kanban = new frappe.views.KanbanBoard({ | |||
doctype: this.doctype, | |||
board: this.board, | |||
board_name: board_name, | |||
cards: this.data, | |||
card_meta: this.card_meta, | |||
wrapper: this.$result, | |||
cur_list: this, | |||
user_settings: this.view_user_settings, | |||
}); | |||
} | |||
get_card_meta() { | |||
@@ -37,6 +37,10 @@ frappe.views.TreeFactory = class TreeFactory extends frappe.views.Factory { | |||
let treeview = frappe.views.trees[route[1]]; | |||
treeview && treeview.make_tree(); | |||
} | |||
get view_name() { | |||
return "Tree"; | |||
} | |||
}; | |||
frappe.views.TreeView = class TreeView { | |||
@@ -196,6 +200,7 @@ frappe.views.TreeView = class TreeView { | |||
}); | |||
cur_tree = this.tree; | |||
cur_tree.view_name = "Tree"; | |||
this.post_render(); | |||
} | |||
@@ -384,18 +384,22 @@ class ShortcutDialog extends WidgetDialog { | |||
onchange: () => { | |||
if (this.dialog.get_value("type") == "DocType") { | |||
let doctype = this.dialog.get_value("link_to"); | |||
if (doctype && frappe.boot.single_types.includes(doctype)) { | |||
this.hide_filters(); | |||
} else if (doctype) { | |||
this.setup_filter(doctype); | |||
this.show_filters(); | |||
} | |||
const views = ["List", "Report Builder", "Dashboard", "New"]; | |||
if (frappe.boot.treeviews.includes(doctype)) views.push("Tree"); | |||
if (frappe.boot.calendars.includes(doctype)) views.push("Calendar"); | |||
this.dialog.set_df_property("doc_view", "options", views.join("\n")); | |||
frappe.model.with_doctype(doctype, () => { | |||
let meta = frappe.get_meta(doctype); | |||
if (doctype && frappe.boot.single_types.includes(doctype)) { | |||
this.hide_filters(); | |||
} else if (doctype) { | |||
this.setup_filter(doctype); | |||
this.show_filters(); | |||
} | |||
const views = ["List", "Report Builder", "Dashboard", "New"]; | |||
if (meta.is_tree === "Tree") views.push("Tree"); | |||
if (frappe.boot.calendars.includes(doctype)) views.push("Calendar"); | |||
this.dialog.set_df_property("doc_view", "options", views.join("\n")); | |||
}); | |||
} else { | |||
this.hide_filters(); | |||
} | |||
@@ -405,7 +409,7 @@ class ShortcutDialog extends WidgetDialog { | |||
fieldtype: "Select", | |||
fieldname: "doc_view", | |||
label: "DocType View", | |||
options: "List\nReport Builder\nDashboard\nTree\nNew\nCalendar", | |||
options: "List\nReport Builder\nDashboard\nTree\nNew\nCalendar\nKanban", | |||
description: __( | |||
"Which view of the associated DocType should this shortcut take you to?" | |||
), | |||
@@ -43,16 +43,32 @@ def create_todo_records(): | |||
frappe.db.truncate("ToDo") | |||
frappe.get_doc( | |||
{"doctype": "ToDo", "date": add_to_date(now(), days=7), "description": "this is first todo"} | |||
{ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), days=7), | |||
"description": "this is first todo", | |||
} | |||
).insert() | |||
frappe.get_doc( | |||
{"doctype": "ToDo", "date": add_to_date(now(), days=-7), "description": "this is second todo"} | |||
{ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), days=-7), | |||
"description": "this is second todo", | |||
} | |||
).insert() | |||
frappe.get_doc( | |||
{"doctype": "ToDo", "date": add_to_date(now(), months=2), "description": "this is third todo"} | |||
{ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), months=2), | |||
"description": "this is third todo", | |||
} | |||
).insert() | |||
frappe.get_doc( | |||
{"doctype": "ToDo", "date": add_to_date(now(), months=-2), "description": "this is fourth todo"} | |||
{ | |||
"doctype": "ToDo", | |||
"date": add_to_date(now(), months=-2), | |||
"description": "this is fourth todo", | |||
} | |||
).insert() | |||
@@ -431,3 +447,134 @@ def create_test_user(): | |||
user.append("roles", {"role": role}) | |||
user.save() | |||
@frappe.whitelist() | |||
def setup_tree_doctype(): | |||
frappe.delete_doc_if_exists("DocType", "Custom Tree") | |||
frappe.get_doc( | |||
{ | |||
"doctype": "DocType", | |||
"module": "Core", | |||
"custom": 1, | |||
"fields": [ | |||
{"fieldname": "tree", "fieldtype": "Data", "label": "Tree"}, | |||
], | |||
"permissions": [{"role": "System Manager", "read": 1}], | |||
"name": "Custom Tree", | |||
"is_tree": True, | |||
"naming_rule": "By fieldname", | |||
"autoname": "field:tree", | |||
} | |||
).insert() | |||
if not frappe.db.exists("Custom Tree", "All Trees"): | |||
frappe.get_doc({"doctype": "Custom Tree", "tree": "All Trees"}).insert() | |||
@frappe.whitelist() | |||
def setup_image_doctype(): | |||
frappe.delete_doc_if_exists("DocType", "Custom Image") | |||
frappe.get_doc( | |||
{ | |||
"doctype": "DocType", | |||
"module": "Core", | |||
"custom": 1, | |||
"fields": [ | |||
{"fieldname": "image", "fieldtype": "Attach Image", "label": "Image"}, | |||
], | |||
"permissions": [{"role": "System Manager", "read": 1}], | |||
"name": "Custom Image", | |||
"image_field": "image", | |||
} | |||
).insert() | |||
@frappe.whitelist() | |||
def setup_inbox(): | |||
frappe.db.sql("DELETE FROM `tabUser Email`") | |||
user = frappe.get_doc("User", frappe.session.user) | |||
user.append("user_emails", {"email_account": "Email Linking"}) | |||
user.save() | |||
@frappe.whitelist() | |||
def setup_default_view(view, force_reroute=None): | |||
frappe.delete_doc_if_exists("Property Setter", "Event-main-default_view") | |||
frappe.delete_doc_if_exists("Property Setter", "Event-main-force_re_route_to_default_view") | |||
frappe.get_doc( | |||
{ | |||
"is_system_generated": 0, | |||
"doctype_or_field": "DocType", | |||
"doc_type": "Event", | |||
"property": "default_view", | |||
"property_type": "Select", | |||
"value": view, | |||
"doctype": "Property Setter", | |||
} | |||
).insert() | |||
if force_reroute: | |||
frappe.get_doc( | |||
{ | |||
"is_system_generated": 0, | |||
"doctype_or_field": "DocType", | |||
"doc_type": "Event", | |||
"property": "force_re_route_to_default_view", | |||
"property_type": "Check", | |||
"value": "1", | |||
"doctype": "Property Setter", | |||
} | |||
).insert() | |||
@frappe.whitelist() | |||
def create_note(): | |||
if not frappe.db.exists("Note", "Routing Test"): | |||
frappe.get_doc({"doctype": "Note", "title": "Routing Test"}).insert() | |||
@frappe.whitelist() | |||
def create_kanban(): | |||
if not frappe.db.exists("Custom Field", "Note-kanban"): | |||
frappe.get_doc( | |||
{ | |||
"is_system_generated": 0, | |||
"dt": "Note", | |||
"label": "Kanban", | |||
"fieldname": "kanban", | |||
"insert_after": "seen_by", | |||
"fieldtype": "Select", | |||
"options": "Open\nClosed", | |||
"doctype": "Custom Field", | |||
} | |||
).insert() | |||
if not frappe.db.exists("Kanban Board", "_Note _Kanban"): | |||
frappe.get_doc( | |||
{ | |||
"doctype": "Kanban Board", | |||
"name": "_Note _Kanban", | |||
"kanban_board_name": "_Note _Kanban", | |||
"reference_doctype": "Note", | |||
"field_name": "kanban", | |||
"private": 1, | |||
"show_labels": 0, | |||
"columns": [ | |||
{ | |||
"column_name": "Open", | |||
"status": "Active", | |||
"indicator": "Gray", | |||
}, | |||
{ | |||
"column_name": "Closed", | |||
"status": "Active", | |||
"indicator": "Gray", | |||
}, | |||
], | |||
} | |||
).insert() |