diff --git a/.github/workflows/patch-mariadb-tests.yml b/.github/workflows/patch-mariadb-tests.yml index d9a6ca6f59..52fa987994 100644 --- a/.github/workflows/patch-mariadb-tests.yml +++ b/.github/workflows/patch-mariadb-tests.yml @@ -10,6 +10,7 @@ concurrency: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 60 name: Patch Test diff --git a/.github/workflows/server-mariadb-tests.yml b/.github/workflows/server-mariadb-tests.yml index 588f357f26..4edf74ba71 100644 --- a/.github/workflows/server-mariadb-tests.yml +++ b/.github/workflows/server-mariadb-tests.yml @@ -14,6 +14,7 @@ concurrency: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 60 strategy: fail-fast: false @@ -128,4 +129,4 @@ jobs: fail_ci_if_error: true files: /home/runner/frappe-bench/sites/coverage.xml verbose: true - flags: server \ No newline at end of file + flags: server diff --git a/.github/workflows/server-postgres-tests.yml b/.github/workflows/server-postgres-tests.yml index 78f379837b..895af5184e 100644 --- a/.github/workflows/server-postgres-tests.yml +++ b/.github/workflows/server-postgres-tests.yml @@ -13,6 +13,7 @@ concurrency: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 60 strategy: fail-fast: false diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index fcc53ba59c..cb502f68a7 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -13,6 +13,7 @@ concurrency: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 60 strategy: fail-fast: false diff --git a/cypress/integration/report_view.js b/cypress/integration/report_view.js index 0253e8fd43..629ae72eb8 100644 --- a/cypress/integration/report_view.js +++ b/cypress/integration/report_view.js @@ -7,6 +7,8 @@ context('Report View', () => { cy.visit('/app/website'); cy.insert_doc('DocType', custom_submittable_doctype, true); cy.clear_cache(); + }); + it('Field with enabled allow_on_submit should be editable.', () => { cy.insert_doc(doctype_name, { 'title': 'Doc 1', 'description': 'Random Text', @@ -14,8 +16,6 @@ context('Report View', () => { // submit document 'docstatus': 1 }, true).as('doc'); - }); - it('Field with enabled allow_on_submit should be editable.', () => { cy.intercept('POST', 'api/method/frappe.client.set_value').as('value-update'); cy.visit(`/app/List/${doctype_name}/Report`); // check status column added from docstatus diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index 4d22075b78..54ddbce2c4 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -146,25 +146,43 @@ def add_attachments(name, attachments): }) _file.save(ignore_permissions=True) -@frappe.whitelist(allow_guest=True) -def mark_email_as_seen(name=None): +@frappe.whitelist(allow_guest=True, methods=("GET",)) +def mark_email_as_seen(name: str = None): try: - if name and frappe.db.exists("Communication", name) and not frappe.db.get_value("Communication", name, "read_by_recipient"): - frappe.db.set_value("Communication", name, "read_by_recipient", 1) - frappe.db.set_value("Communication", name, "delivery_status", "Read") - frappe.db.set_value("Communication", name, "read_by_recipient_on", get_datetime()) - frappe.db.commit() + update_communication_as_read(name) + frappe.db.commit() # nosemgrep: this will be called in a GET request + except Exception: frappe.log_error(frappe.get_traceback()) - finally: - # Return image as response under all circumstances - from PIL import Image - import io - im = Image.new('RGBA', (1, 1)) - im.putdata([(255,255,255,0)]) - buffered_obj = io.BytesIO() - im.save(buffered_obj, format="PNG") - frappe.response["type"] = 'binary' - frappe.response["filename"] = "imaginary_pixel.png" - frappe.response["filecontent"] = buffered_obj.getvalue() + finally: + frappe.response.update({ + "type": "binary", + "filename": "imaginary_pixel.png", + "filecontent": ( + b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00" + b"\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\r" + b"IDATx\x9cc\xf8\xff\xff?\x03\x00\x08\xfc\x02\xfe\xa7\x9a\xa0" + b"\xa0\x00\x00\x00\x00IEND\xaeB`\x82" + ) + }) + +def update_communication_as_read(name): + if not name or not isinstance(name, str): + return + + communication = frappe.db.get_value( + "Communication", + name, + "read_by_recipient", + as_dict=True + ) + + if not communication or communication.read_by_recipient: + return + + frappe.db.set_value("Communication", name, { + "read_by_recipient": 1, + "delivery_status": "Read", + "read_by_recipient_on": get_datetime() + }) diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json index ea31e76a57..cf05ce0c15 100644 --- a/frappe/core/doctype/user/user.json +++ b/frappe/core/doctype/user/user.json @@ -599,7 +599,7 @@ "fieldname": "desk_theme", "fieldtype": "Select", "label": "Desk Theme", - "options": "Light\nDark" + "options": "Light\nDark\nAutomatic" }, { "fieldname": "module_profile", @@ -669,7 +669,7 @@ } ], "max_attachments": 5, - "modified": "2021-10-27 17:17:16.098457", + "modified": "2021-11-17 17:17:16.098457", "modified_by": "Administrator", "module": "Core", "name": "User", diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 86fd1cb4a6..b127cf5f0c 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -1046,7 +1046,7 @@ def generate_keys(user): @frappe.whitelist() def switch_theme(theme): - if theme in ["Dark", "Light"]: + if theme in ["Dark", "Light", "Automatic"]: frappe.db.set_value("User", frappe.session.user, "desk_theme", theme) def get_enabled_users(): diff --git a/frappe/desk/doctype/notification_settings/notification_settings.json b/frappe/desk/doctype/notification_settings/notification_settings.json index fc12022e89..fc535fa405 100644 --- a/frappe/desk/doctype/notification_settings/notification_settings.json +++ b/frappe/desk/doctype/notification_settings/notification_settings.json @@ -15,7 +15,9 @@ "enable_email_energy_point", "enable_email_share", "user", - "seen" + "seen", + "system_notifications_section", + "energy_points_system_notifications" ], "fields": [ { @@ -84,15 +86,27 @@ "fieldtype": "Check", "hidden": 1, "label": "Seen" + }, + { + "fieldname": "system_notifications_section", + "fieldtype": "Section Break", + "label": "System Notifications" + }, + { + "default": "1", + "fieldname": "energy_points_system_notifications", + "fieldtype": "Check", + "label": "Energy Points" } ], "in_create": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2020-11-04 12:54:57.989317", + "modified": "2021-11-16 12:18:46.955501", "modified_by": "Administrator", "module": "Desk", "name": "Notification Settings", + "naming_rule": "Set by user", "owner": "Administrator", "permissions": [ { @@ -111,4 +125,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} \ No newline at end of file +} diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index a53368d67a..2855c6ae7c 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -64,6 +64,19 @@ frappe.Application = class Application { } }); + frappe.ui.add_system_theme_switch_listener(); + const root = document.documentElement; + + const observer = new MutationObserver(() => { + frappe.ui.set_theme(); + }); + observer.observe(root, { + attributes: true, + attributeFilter: ['data-theme-mode'] + }); + + frappe.ui.set_theme(); + // page container this.make_page_container(); this.set_route(); diff --git a/frappe/public/js/frappe/form/dashboard.js b/frappe/public/js/frappe/form/dashboard.js index 9d5e7cbe09..df4dbf09e7 100644 --- a/frappe/public/js/frappe/form/dashboard.js +++ b/frappe/public/js/frappe/form/dashboard.js @@ -14,6 +14,7 @@ frappe.ui.form.Dashboard = class FormDashboard { this.progress_area = this.make_section({ css_class: 'progress-area', hidden: 1, + collapsible: 1, is_dashboard_section: 1, }); @@ -21,6 +22,7 @@ frappe.ui.form.Dashboard = class FormDashboard { label: __("Overview"), css_class: 'form-heatmap', hidden: 1, + collapsible: 1, is_dashboard_section: 1, body_html: `
@@ -32,6 +34,7 @@ frappe.ui.form.Dashboard = class FormDashboard { label: __("Graph"), css_class: 'form-graph', hidden: 1, + collapsible: 1, is_dashboard_section: 1 }); @@ -40,6 +43,7 @@ frappe.ui.form.Dashboard = class FormDashboard { label: __("Stats"), css_class: 'form-stats', hidden: 1, + collapsible: 1, is_dashboard_section: 1, body_html: this.stats_area_row }); @@ -50,6 +54,7 @@ frappe.ui.form.Dashboard = class FormDashboard { label: __("Connections"), css_class: 'form-links', hidden: 1, + collapsible: 1, is_dashboard_section: 1, body_html: this.transactions_area }); @@ -84,9 +89,10 @@ frappe.ui.form.Dashboard = class FormDashboard { hidden, body_html, make_card: true, + collapsible: 1, is_dashboard_section: 1 }; - return new Section(this.frm.layout.wrapper, options).body; + return new Section(this.parent, options).body; } add_progress(title, percent, message) { @@ -203,7 +209,7 @@ frappe.ui.form.Dashboard = class FormDashboard { after_refresh() { // show / hide new buttons (if allowed) this.links_area.body.find('.btn-new').each((i, el) => { - if (this.frm.can_create($(this).attr('data-doctype'))) { + if (this.frm.can_create($(el).attr('data-doctype'))) { $(el).removeClass('hidden'); } }); diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index 75d68b12db..27281d8927 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -156,8 +156,11 @@ frappe.ui.form.Form = class FrappeForm { let dashboard_parent = $('
'); - let main_page = this.layout.tabs.length ? this.layout.tabs[0].wrapper : this.layout.wrapper; - main_page.prepend(dashboard_parent); + if (this.layout.tabs.length) { + this.layout.tabs[0].wrapper.prepend(dashboard_parent); + } else { + dashboard_parent.insertAfter(this.layout.wrapper.find('.form-message')); + } this.dashboard = new frappe.ui.form.Dashboard(dashboard_parent, this); this.tour = new frappe.ui.form.FormTour({ diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index 7710c82ee7..0de6b1db0d 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -245,7 +245,7 @@ frappe.ui.form.Layout = class Layout { } make_section(df) { - this.section = new Section(this.current_tab ? this.current_tab.wrapper : this.page, df, this.card_layout); + this.section = new Section(this.current_tab ? this.current_tab.wrapper : this.page, df, this.card_layout, this); // append to layout fields if (df) { diff --git a/frappe/public/js/frappe/form/section.js b/frappe/public/js/frappe/form/section.js index e0120f6afc..b0ec491ce6 100644 --- a/frappe/public/js/frappe/form/section.js +++ b/frappe/public/js/frappe/form/section.js @@ -1,5 +1,6 @@ export default class Section { - constructor(parent, df, card_layout) { + constructor(parent, df, card_layout, layout) { + this.layout = layout; this.card_layout = card_layout; this.parent = parent; this.df = df || {}; @@ -25,6 +26,7 @@ export default class Section { ${this.df.is_dashboard_section ? "form-dashboard-section" : "form-section"} ${ make_card ? "card-section" : "" }"> `).appendTo(this.parent); + this.layout && this.layout.sections.push(this); if (this.df) { if (this.df.label) { diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 07c8acef27..64530e15ef 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -307,6 +307,8 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { } update_checkbox(target) { + if (!this.$checkbox_actions) return; + let $check_all_checkbox = this.$checkbox_actions.find(".list-check-all"); if ($check_all_checkbox.prop("checked") && target && !target.prop("checked")) { diff --git a/frappe/public/js/frappe/ui/theme_switcher.js b/frappe/public/js/frappe/ui/theme_switcher.js index 4524472415..2c1d93a2ec 100644 --- a/frappe/public/js/frappe/ui/theme_switcher.js +++ b/frappe/public/js/frappe/ui/theme_switcher.js @@ -42,7 +42,7 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { } refresh() { - this.current_theme = document.documentElement.getAttribute("data-theme") || "light"; + this.current_theme = document.documentElement.getAttribute("data-theme-mode") || "light"; this.fetch_themes().then(() => { this.render(); }); @@ -54,10 +54,17 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { { name: "light", label: __("Frappe Light"), + info: __("Light Theme") }, { name: "dark", label: __("Timeless Night"), + info: __("Dark Theme") + }, + { + name: "automatic", + label: __("Automatic"), + info: __("Uses system's theme to switch between light and dark mode") } ]; @@ -74,11 +81,15 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { } get_preview_html(theme) { + const is_auto_theme = theme.name === "automatic"; const preview = $(`
-
+
-
${frappe.utils.icon('tick', 'xs')}
+
+ ${frappe.utils.icon('tick', 'xs')} +
@@ -112,13 +123,14 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { toggle_theme(theme) { this.current_theme = theme.toLowerCase(); - document.documentElement.setAttribute("data-theme", this.current_theme); + document.documentElement.setAttribute("data-theme-mode", this.current_theme); frappe.show_alert("Theme Changed", 3); frappe.xcall("frappe.core.doctype.user.user.switch_theme", { theme: toTitle(theme) }); } + show() { this.dialog.show(); } @@ -127,3 +139,22 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { this.dialog.hide(); } }; + +frappe.ui.add_system_theme_switch_listener = () => { + frappe.ui.dark_theme_media_query.addEventListener('change', () => { + frappe.ui.set_theme(); + }); +}; + +frappe.ui.dark_theme_media_query = window.matchMedia("(prefers-color-scheme: dark)"); + +frappe.ui.set_theme = (theme) => { + const root = document.documentElement; + let theme_mode = root.getAttribute("data-theme-mode"); + if (!theme) { + if (theme_mode === "automatic") { + theme = frappe.ui.dark_theme_media_query.matches ? 'dark' : 'light'; + } + } + root.setAttribute("data-theme", theme || theme_mode); +}; \ No newline at end of file diff --git a/frappe/public/scss/desk/theme_switcher.scss b/frappe/public/scss/desk/theme_switcher.scss index 00e3f35be8..924c2edd9d 100644 --- a/frappe/public/scss/desk/theme_switcher.scss +++ b/frappe/public/scss/desk/theme_switcher.scss @@ -1,6 +1,6 @@ .modal-body .theme-grid { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(3, minmax(0, 1fr)); grid-gap: 18px; .background { @@ -9,7 +9,7 @@ border-radius: var(--border-radius-lg); overflow: hidden; cursor: pointer; - height: 160px; + height: 120px; position: relative; &:hover { @@ -28,6 +28,7 @@ margin-right: var(--margin-sm); border-radius: var(--border-radius-full); + z-index: 1; } } @@ -72,6 +73,7 @@ border-radius: var(--border-radius-sm); height: 10px; width: 20px; + z-index: 1; } .text { @@ -80,4 +82,17 @@ height: 10px; width: 40px; } +} + +// TODO: Replace with better alternative +[data-is-auto-theme="true"] { + .background::after { + content: ""; + top: 0; + right: 0; + height: 100%; + width: 50%; + background: var(--gray-900); + position: absolute; + } } \ No newline at end of file diff --git a/frappe/sessions.py b/frappe/sessions.py index 9a0f19df80..91c8bbdecb 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -158,6 +158,8 @@ def get(): bootinfo["setup_complete"] = cint(frappe.db.get_single_value('System Settings', 'setup_complete')) bootinfo["is_first_startup"] = cint(frappe.db.get_single_value('System Settings', 'is_first_startup')) + bootinfo['desk_theme'] = frappe.db.get_value("User", frappe.session.user, "desk_theme") or 'Light' + return bootinfo @frappe.whitelist() diff --git a/frappe/social/doctype/energy_point_log/energy_point_log.py b/frappe/social/doctype/energy_point_log/energy_point_log.py index 3ffabcd241..86843302e9 100644 --- a/frappe/social/doctype/energy_point_log/energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/energy_point_log.py @@ -32,7 +32,9 @@ class EnergyPointLog(Document): frappe.cache().hdel('energy_points', self.user) frappe.publish_realtime('update_points', after_commit=True) - if self.type != 'Review': + if self.type != 'Review' and \ + frappe.get_cached_value('Notification Settings', self.user, 'energy_points_system_notifications'): + reference_user = self.user if self.type == 'Auto' else self.owner notification_doc = { 'type': 'Energy Point', diff --git a/frappe/social/doctype/energy_point_log/test_energy_point_log.py b/frappe/social/doctype/energy_point_log/test_energy_point_log.py index c2bcbde825..a1f4503c34 100644 --- a/frappe/social/doctype/energy_point_log/test_energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/test_energy_point_log.py @@ -8,6 +8,18 @@ from frappe.utils.testutils import add_custom_field, clear_custom_fields from frappe.desk.form.assign_to import add as assign_to class TestEnergyPointLog(unittest.TestCase): + @classmethod + def setUpClass(cls): + settings = frappe.get_single('Energy Point Settings') + settings.enabled = 1 + settings.save() + + @classmethod + def tearDownClass(cls): + settings = frappe.get_single('Energy Point Settings') + settings.enabled = 0 + settings.save() + def setUp(self): frappe.cache().delete_value('energy_point_rule_map') @@ -336,4 +348,4 @@ def assign_users_to_todo(todo_name, users): 'assign_to': [user], 'doctype': 'ToDo', 'name': todo_name - }) \ No newline at end of file + }) diff --git a/frappe/social/doctype/energy_point_settings/energy_point_settings.json b/frappe/social/doctype/energy_point_settings/energy_point_settings.json index 0001b26529..d1f9aea3d0 100644 --- a/frappe/social/doctype/energy_point_settings/energy_point_settings.json +++ b/frappe/social/doctype/energy_point_settings/energy_point_settings.json @@ -1,229 +1,70 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, + "actions": [], "creation": "2019-03-19 13:17:51.710241", - "custom": 0, - "docstatus": 0, "doctype": "DocType", - "document_type": "", "editable_grid": 1, "engine": "InnoDB", + "field_order": [ + "enabled", + "section_break_2", + "review_levels", + "point_allocation_periodicity", + "last_point_allocation_date" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fetch_if_empty": 0, + "default": "0", "fieldname": "enabled", "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Enabled", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "Enabled" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "depends_on": "enabled", - "fetch_if_empty": 0, "fieldname": "section_break_2", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldtype": "Section Break" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "review_levels", "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Review Levels", - "length": 0, - "no_copy": 0, - "options": "Review Level", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "options": "Review Level" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "Weekly", - "fetch_if_empty": 0, "fieldname": "point_allocation_periodicity", "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Point Allocation Periodicity", - "length": 0, - "no_copy": 0, - "options": "Daily\nWeekly\nMonthly", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "options": "Daily\nWeekly\nMonthly" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "last_point_allocation_date", "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Last Point Allocation Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1 } ], - "has_web_view": 0, "hide_toolbar": 1, - "idx": 0, - "in_create": 0, - "is_submittable": 0, "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2019-03-26 19:10:14.087840", + "links": [], + "modified": "2021-11-16 23:24:01.366928", "modified_by": "Administrator", "module": "Social", "name": "Energy Point Settings", - "name_case": "", "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, - "report": 0, "role": "System Manager", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 } ], "quick_entry": 1, - "read_only": 0, - "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "ASC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + "track_changes": 1 } \ No newline at end of file diff --git a/frappe/social/doctype/energy_point_settings/test_energy_point_settings.py b/frappe/social/doctype/energy_point_settings/test_energy_point_settings.py new file mode 100644 index 0000000000..3b0a756878 --- /dev/null +++ b/frappe/social/doctype/energy_point_settings/test_energy_point_settings.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies and Contributors +# See license.txt + +# import frappe +import unittest + +class TestEnergyPointSettings(unittest.TestCase): + pass diff --git a/frappe/www/app.html b/frappe/www/app.html index 68a6dc8e86..37579066e0 100644 --- a/frappe/www/app.html +++ b/frappe/www/app.html @@ -1,5 +1,5 @@ - + diff --git a/frappe/www/app.py b/frappe/www/app.py index 92107816c7..4c8048662a 100644 --- a/frappe/www/app.py +++ b/frappe/www/app.py @@ -45,7 +45,7 @@ def get_context(context): "lang": frappe.local.lang, "sounds": hooks["sounds"], "boot": boot if context.get("for_mobile") else boot_json, - "desk_theme": desk_theme or "Light", + "desk_theme": desk_theme, "csrf_token": csrf_token, "google_analytics_id": frappe.conf.get("google_analytics_id"), "google_analytics_anonymize_ip": frappe.conf.get("google_analytics_anonymize_ip"),