From e86df2ecf6ee84b78a0745e61f88e73dfef774f1 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 29 May 2023 17:19:11 +0530 Subject: [PATCH 1/3] feat: Scroll to field via URL --- frappe/public/js/frappe/form/form.js | 10 +++++++--- frappe/public/js/frappe/utils/utils.js | 25 ++++++++++++++----------- frappe/public/scss/desk/global.scss | 16 +++++++++++++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index 47917422b5..e33c4ab7d3 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -1414,8 +1414,12 @@ frappe.ui.form.Form = class FrappeForm { if (selector.length) { frappe.utils.scroll_to(selector); } - } else if (window.location.hash && $(window.location.hash).length) { - frappe.utils.scroll_to(window.location.hash, true, 200, null, null, true); + } else if (window.location.hash) { + if ($(window.location.hash).length) { + frappe.utils.scroll_to(window.location.hash, true, 200, null, null, true); + } else { + this.scroll_to_field(window.location.hash.replace("#", "")); + } } } @@ -1926,7 +1930,7 @@ frappe.ui.form.Form = class FrappeForm { } // highlight control inside field - let control_element = $el.find(".form-control"); + let control_element = $el.closest(".frappe-control"); control_element.addClass("highlight"); setTimeout(() => { control_element.removeClass("highlight"); diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js index ac9a18785b..7020513f47 100644 --- a/frappe/public/js/frappe/utils/utils.js +++ b/frappe/public/js/frappe/utils/utils.js @@ -340,9 +340,21 @@ Object.assign(frappe.utils, { scroll_top = 0; } + const highlight = () => { + if (highlight_element) { + $(element).addClass("highlight"); + document.addEventListener( + "click", + function () { + $(element).removeClass("highlight"); + }, + { once: true } + ); + } + }; // already there if (scroll_top == element_to_be_scrolled.scrollTop()) { - return; + return highlight(); } if (animate) { @@ -352,16 +364,7 @@ Object.assign(frappe.utils, { }) .promise() .then(() => { - if (highlight_element) { - $(element).addClass("highlight"); - document.addEventListener( - "click", - function () { - $(element).removeClass("highlight"); - }, - { once: true } - ); - } + highlight(); callback && callback(); }); } else { diff --git a/frappe/public/scss/desk/global.scss b/frappe/public/scss/desk/global.scss index 765e51cab9..08715c28b0 100644 --- a/frappe/public/scss/desk/global.scss +++ b/frappe/public/scss/desk/global.scss @@ -571,11 +571,25 @@ details > summary:focus { display: none; } -.highlight { +.highlight:not(.frappe-control) { transition: 0.5s ease background-color; box-shadow: var(--highlight-shadow) !important; } +.frappe-control.highlight { + --wrap-padding: calc(-1 * var(--padding-sm)); + &::after { + content: " "; + border-radius: 5px; + box-shadow: var(--highlight-shadow) !important; + top: var(--wrap-padding); + position: absolute; + bottom: var(--wrap-padding); + left: var(--wrap-padding); + right: var(--wrap-padding); + } +} + .dropdown-menu.small { font-size: var(--text-sm); min-width: 140px; From b9d4974360fe6b35823c54ff97cec6cb58c5d2a4 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 29 May 2023 17:34:38 +0530 Subject: [PATCH 2/3] fix: Clear hash once the scrolling is done --- frappe/public/js/frappe/form/form.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index e33c4ab7d3..322776ada9 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -1418,7 +1418,8 @@ frappe.ui.form.Form = class FrappeForm { if ($(window.location.hash).length) { frappe.utils.scroll_to(window.location.hash, true, 200, null, null, true); } else { - this.scroll_to_field(window.location.hash.replace("#", "")); + this.scroll_to_field(window.location.hash.replace("#", "")) && + history.replaceState(null, null, " "); } } } @@ -1935,6 +1936,7 @@ frappe.ui.form.Form = class FrappeForm { setTimeout(() => { control_element.removeClass("highlight"); }, 2000); + return true; } setup_docinfo_change_listener() { From 895dab85352ae9de686aa833d98829df130196b1 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Sat, 10 Jun 2023 17:33:42 +0530 Subject: [PATCH 3/3] fix: Pass URL hash separately --- frappe/public/js/frappe/router.js | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index c03bfc9b95..9ad917a57a 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -31,20 +31,21 @@ window.addEventListener("popstate", (e) => { return false; }); -// routing v2, capture all clicks so that the target is managed with push-state +// Capture all clicks so that the target is managed with push-state $("body").on("click", "a", function (e) { - let override = (route) => { + const target_element = e.currentTarget; + const href = target_element.getAttribute("href"); + const is_on_same_host = target_element.hostname === window.location.hostname; + + const override = (route) => { e.preventDefault(); frappe.set_route(route); return false; }; - const target_element = e.currentTarget; - const href = target_element.getAttribute("href"); - const is_on_same_host = target_element.hostname === window.location.hostname; - // click handled, but not by href if ( + !is_on_same_host || // external link target_element.getAttribute("onclick") || // has a handler e.ctrlKey || e.metaKey || // open in a new tab @@ -53,18 +54,13 @@ $("body").on("click", "a", function (e) { return; } - if (href === "") { - return override("/app"); - } - if (href && href.startsWith("#")) { // target startswith "#", this is a v1 style route, so remake it. return override(target_element.hash); } - if (is_on_same_host && frappe.router.is_app_route(target_element.pathname)) { + if (frappe.router.is_app_route(target_element.pathname)) { // target has "/app, this is a v2 style route. - if (target_element.search) { frappe.route_options = {}; let params = new URLSearchParams(target_element.search); @@ -72,7 +68,10 @@ $("body").on("click", "a", function (e) { frappe.route_options[key] = value; } } - return override(target_element.pathname + target_element.hash); + if (target_element.hash) { + frappe.route_hash = target_element.hash; + } + return override(target_element.pathname); } }); @@ -139,6 +138,12 @@ frappe.router = { if (!frappe.app) return; let sub_path = this.get_sub_path(); + if (frappe.boot.setup_complete) { + !frappe.re_route["setup-wizard"] && (frappe.re_route["setup-wizard"] = "app"); + } else if (!sub_path.startsWith("setup-wizard")) { + frappe.re_route["setup-wizard"] && delete frappe.re_route["setup-wizard"]; + frappe.set_route(["setup-wizard"]); + } if (this.re_route(sub_path)) return; this.current_sub_path = sub_path; @@ -346,8 +351,8 @@ frappe.router = { route = this.get_route_from_arguments(route); route = this.convert_from_standard_route(route); let sub_path = this.make_url(route); - // replace each # occurrences in the URL with encoded character except for last - // sub_path = sub_path.replace(/[#](?=.*[#])/g, "%23"); + sub_path += frappe.route_hash || ""; + frappe.route_hash = null; if (frappe.open_in_new_tab) { localStorage["route_options"] = JSON.stringify(frappe.route_options); window.open(sub_path, "_blank");