From c1585018d6565dd9a653fee7f658ce44bf9e7197 Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 19 Feb 2026 12:03:04 +0530 Subject: [PATCH 1/5] refactor: billing components --- frappe/boot.py | 4 +- frappe/desk/page/desktop/desktop.css | 6 + frappe/desk/page/desktop/desktop.html | 2 +- frappe/hooks.py | 2 +- frappe/public/js/billing.bundle.js | 227 ++++++------------ frappe/public/js/frappe/form/info_card.js | 1 + frappe/public/js/frappe/ui/sidebar/sidebar.js | 9 +- .../js/frappe/ui/sidebar/sidebar_card.html | 10 +- .../js/frappe/ui/sidebar/sidebar_card.js | 25 ++ frappe/public/scss/desk/sidebar_card.scss | 10 +- 10 files changed, 136 insertions(+), 160 deletions(-) diff --git a/frappe/boot.py b/frappe/boot.py index 697c3eb16e..3eeb7a868a 100644 --- a/frappe/boot.py +++ b/frappe/boot.py @@ -19,7 +19,7 @@ from frappe.desk.doctype.form_tour.form_tour import get_onboarding_ui_tours from frappe.desk.doctype.route_history.route_history import frequently_visited_links from frappe.desk.form.load import get_meta_bundle from frappe.email.inbox import get_email_accounts -from frappe.integrations.frappe_providers.frappecloud_billing import is_fc_site +from frappe.integrations.frappe_providers.frappecloud_billing import current_site_info, is_fc_site from frappe.model.base_document import get_controller from frappe.permissions import has_permission from frappe.query_builder import DocType @@ -125,6 +125,8 @@ def get_bootinfo(): bootinfo.setup_wizard_completed_apps = get_setup_wizard_completed_apps() or [] bootinfo.desktop_icon_urls = get_desktop_icon_urls() bootinfo.desktop_icon_style = get_icon_style() or "Subtle" + if bootinfo.is_fc_site: + bootinfo.site_info = current_site_info() return bootinfo diff --git a/frappe/desk/page/desktop/desktop.css b/frappe/desk/page/desktop/desktop.css index 119b5fc747..27a128b60c 100644 --- a/frappe/desk/page/desktop/desktop.css +++ b/frappe/desk/page/desktop/desktop.css @@ -80,6 +80,12 @@ margin-top: 60px; padding: 20px; } +.icons-container:has(.sidebar-card){ + margin-top: 20px; + .sidebar-card{ + gap: 6px; + } +} .modal .modal-body .icons-container,.folder-icon .icons-container { padding:0px; diff --git a/frappe/desk/page/desktop/desktop.html b/frappe/desk/page/desktop/desktop.html index c8810e6159..bfefedb5a9 100644 --- a/frappe/desk/page/desktop/desktop.html +++ b/frappe/desk/page/desktop/desktop.html @@ -1,6 +1,6 @@
-
\ No newline at end of file diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar_card.js b/frappe/public/js/frappe/ui/sidebar/sidebar_card.js index 6ba32973f0..c6ce41de75 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar_card.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar_card.js @@ -5,6 +5,10 @@ frappe.provide("frappe.ui"); frappe.ui.SidebarCard = class SidebarCard { constructor(opts) { Object.assign(this, opts); + this.alignment_style_map = { + right: "flex-end", + left: "flex-start", + }; this.make(opts); this.setup(); this.display = false; @@ -31,10 +35,16 @@ frappe.ui.SidebarCard = class SidebarCard { ], }); } + if (this.outline) { + this.card.addClass("card-outline"); + this.card.removeClass("px-2 py-2"); + } this.card.prependTo(this.parent); + this.set_button_alignment(); } setup() { this.setup_primary_action(); + this.setup_close_button(); } toggle() { if (this.display) { @@ -59,6 +69,14 @@ frappe.ui.SidebarCard = class SidebarCard { me.primary_action(event); }); } + setup_close_button() { + const me = this; + if (this.close_button) { + this.card.find(".close-button").on("click", function () { + me.toggle(); + }); + } + } set_styles() { if (this.styles) { const $root = $(":root"); @@ -67,4 +85,11 @@ frappe.ui.SidebarCard = class SidebarCard { } } } + set_button_alignment() { + if (this.primary_button_alignment) { + this.card + .find(".sidebar-card-actions") + .css("justifyContent", this.alignment_style_map[this.primary_button_alignment]); + } + } }; diff --git a/frappe/public/scss/desk/sidebar_card.scss b/frappe/public/scss/desk/sidebar_card.scss index 56144f1754..d64bc5f828 100644 --- a/frappe/public/scss/desk/sidebar_card.scss +++ b/frappe/public/scss/desk/sidebar_card.scss @@ -1,6 +1,6 @@ :root { --sidebar-card-button-outline: var(--surface-blue-3); - --sidebar-card-button-bg-color: var(var(--surface-blue-2)); + --sidebar-card-button-bg-color: var(--surface-blue-2); --sidebar-card-button-color: var(--ink-blue-3); } .card-title-container { @@ -54,3 +54,11 @@ .cursor-pointer { cursor: pointer; } + +.card-outline { + border: 1px solid; + box-shadow: none; + border-color: var(--outline-gray-2, #e2e2e2); + border-radius: calc(var(--border-radius-lg) + 2px); + padding: calc(var(--padding-md) - 3px); +} From 06abc3e5acfd4a0b78d226004f74b0777f52a23b Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 19 Feb 2026 14:10:27 +0530 Subject: [PATCH 2/5] fix: render it correctly --- frappe/desk/page/desktop/desktop.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frappe/desk/page/desktop/desktop.js b/frappe/desk/page/desktop/desktop.js index 36e4633855..2249cc05c5 100644 --- a/frappe/desk/page/desktop/desktop.js +++ b/frappe/desk/page/desktop/desktop.js @@ -176,8 +176,7 @@ class DesktopPage { this.desktop_menu_items = []; } update() { - this.make(this.page); - this.setup(); + this.make(); } prepare() { this.apps_icons = []; @@ -277,8 +276,8 @@ class DesktopPage { if (this.edit_mode) { this.start_editing_layout(); } + this.setup(); } - setup() { $(document).trigger("desktop_screen", { desktop: this }); this.setup_avatar(); From 4717c64cf0c9c78eeae6a31157379f04f90ce2c4 Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 19 Feb 2026 16:16:27 +0530 Subject: [PATCH 3/5] fix: always show upgrade button FC user --- frappe/public/js/billing.bundle.js | 43 +++++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/frappe/public/js/billing.bundle.js b/frappe/public/js/billing.bundle.js index 3c90eee279..b2f384c715 100644 --- a/frappe/public/js/billing.bundle.js +++ b/frappe/public/js/billing.bundle.js @@ -5,7 +5,7 @@ $(document).ready(function () { const response = frappe.boot.site_info; const trial_end_date = new Date(response.trial_end_date); frappeCloudBaseEndpoint = response.base_url; - isFCUser = response.is_fc_user; + // isFCUser = response.is_fc_user; const today = new Date(); const diffTime = trial_end_date - today; @@ -24,15 +24,19 @@ $(document).ready(function () { popper: true, primary_button_alignment: "right", }; - isFCUser = true; if (isFCUser) { - card_args.primary_action_label = "Upgrade"; - card_args.primary_action_suffix_icon = "square-arrow-out-up-right"; - card_args.styles = { - "sidebar-card-button-bg-color": "var(--surface-gray-2)", - "sidebar-card-button-color": "var(--ink-gray-7)", - "sidebar-card-button-outline": "var(--ink-gray-7)", - }; + $.extend(card_args, { + primary_action_label: "Upgrade", + primary_action_suffix_icon: "square-arrow-out-up-right", + styles: { + "sidebar-card-button-bg-color": "var(--surface-gray-2)", + "sidebar-card-button-color": "var(--ink-gray-7)", + "sidebar-card-button-outline": "var(--ink-gray-7)", + }, + primary_action: () => { + openFrappeCloudDashboard(); + }, + }); } $(document).on("desktop_screen", function (event, data) { if ( @@ -54,16 +58,23 @@ $(document).ready(function () { }); $(document).on("sidebar_setup", function (event, data) { let sidebar = data.sidebar; - // card_args.close_button = null; - sidebar.add_card({ + let sidebar_card_args = { title: card_args.title, icon: "info", message: card_args.message, - // primary_action_icon: "zap", - // primary_action_label: "Upgrade", - // primary_button_width: "full", - // primary_action: () => {}, - }); + }; + isFCUser = true; + if (isFCUser) { + $.extend(sidebar_card_args, { + primary_action_label: "Upgrade", + primary_action_icon: "zap", + primary_button_width: "full", + primary_action: () => { + openFrappeCloudDashboard(); + }, + }); + } + sidebar.add_card(sidebar_card_args); }); }); From 3f053667ac97e6ade3cc1c706fd7ac758ba4ab7e Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 19 Feb 2026 17:06:08 +0530 Subject: [PATCH 4/5] feat: make the desktop banner dismissbable for a day --- frappe/public/js/billing.bundle.js | 6 ++-- .../js/frappe/ui/sidebar/sidebar_card.js | 29 +++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/frappe/public/js/billing.bundle.js b/frappe/public/js/billing.bundle.js index b2f384c715..fb83f48dba 100644 --- a/frappe/public/js/billing.bundle.js +++ b/frappe/public/js/billing.bundle.js @@ -1,11 +1,11 @@ let frappeCloudBaseEndpoint = "https://frappecloud.com"; -let isFCUser = true; +let isFCUser = false; $(document).ready(function () { const response = frappe.boot.site_info; const trial_end_date = new Date(response.trial_end_date); frappeCloudBaseEndpoint = response.base_url; - // isFCUser = response.is_fc_user; + isFCUser = response.is_fc_user; const today = new Date(); const diffTime = trial_end_date - today; @@ -23,6 +23,8 @@ $(document).ready(function () { close_button: true, popper: true, primary_button_alignment: "right", + dismiss_key: `${frappe.boot.site_info.name}_trial_card_time`, + dismiss_it_for: "day", }; if (isFCUser) { $.extend(card_args, { diff --git a/frappe/public/js/frappe/ui/sidebar/sidebar_card.js b/frappe/public/js/frappe/ui/sidebar/sidebar_card.js index c6ce41de75..45799a6fbc 100644 --- a/frappe/public/js/frappe/ui/sidebar/sidebar_card.js +++ b/frappe/public/js/frappe/ui/sidebar/sidebar_card.js @@ -1,6 +1,5 @@ import { createPopper } from "@popperjs/core"; frappe.provide("frappe.ui"); - // icon, title, message, condition, primary_action_label, primary_action frappe.ui.SidebarCard = class SidebarCard { constructor(opts) { @@ -9,15 +8,26 @@ frappe.ui.SidebarCard = class SidebarCard { right: "flex-end", left: "flex-start", }; + this.dismiss_intervals = { + minute: 60 * 1000, + hour: 60 * 60 * 1000, + day: 24 * 60 * 60 * 1000, + week: 7 * 24 * 60 * 60 * 1000, + }; this.make(opts); this.setup(); - this.display = false; this.set_styles(); } make() { if (!this.icon) { this.icon = "info"; } + if (this.dismiss_it_for) { + const next_time_for_show = localStorage.getItem(this.get_dismiss_key()); + if (next_time_for_show && Date.now() < Number(next_time_for_show)) { + this.hide(); + } + } this.card = $( frappe.render_template("sidebar_card", { card: this, @@ -41,6 +51,7 @@ frappe.ui.SidebarCard = class SidebarCard { } this.card.prependTo(this.parent); this.set_button_alignment(); + this.show(); } setup() { this.setup_primary_action(); @@ -56,11 +67,18 @@ frappe.ui.SidebarCard = class SidebarCard { hide() { this.display = false; this.parent.removeAttr("data-show"); + this.card.removeClass("d-inline-flex"); + this.card.addClass("hidden"); } show() { this.display = true; this.parent.attr("data-show", ""); - this.popper.update(); + this.popper && this.popper.update(); + this.card.addClass("d-inline-flex"); + this.card.removeClass("hidden"); + } + get_dismiss_key() { + return this.dismiss_key || "card_next_show_time"; } setup_primary_action() { const me = this; @@ -73,6 +91,11 @@ frappe.ui.SidebarCard = class SidebarCard { const me = this; if (this.close_button) { this.card.find(".close-button").on("click", function () { + if (me.dismiss_it_for) { + let next_show_time = Date.now() + me.dismiss_intervals[me.dismiss_it_for]; + + localStorage.setItem(me.get_dismiss_key(), next_show_time); + } me.toggle(); }); } From e1e871428ffa636008b1fa3276e0257f185b74b1 Mon Sep 17 00:00:00 2001 From: sokumon Date: Thu, 19 Feb 2026 17:49:45 +0530 Subject: [PATCH 5/5] fix: remove sidebar billing card --- frappe/public/js/billing.bundle.js | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/frappe/public/js/billing.bundle.js b/frappe/public/js/billing.bundle.js index fb83f48dba..c0fa0bcda0 100644 --- a/frappe/public/js/billing.bundle.js +++ b/frappe/public/js/billing.bundle.js @@ -58,26 +58,6 @@ $(document).ready(function () { }); } }); - $(document).on("sidebar_setup", function (event, data) { - let sidebar = data.sidebar; - let sidebar_card_args = { - title: card_args.title, - icon: "info", - message: card_args.message, - }; - isFCUser = true; - if (isFCUser) { - $.extend(sidebar_card_args, { - primary_action_label: "Upgrade", - primary_action_icon: "zap", - primary_button_width: "full", - primary_action: () => { - openFrappeCloudDashboard(); - }, - }); - } - sidebar.add_card(sidebar_card_args); - }); }); function setErrorMessage(message) {