diff --git a/frappe/config/__init__.py b/frappe/config/__init__.py index cc9d0e6c67..30be82d0df 100644 --- a/frappe/config/__init__.py +++ b/frappe/config/__init__.py @@ -36,48 +36,10 @@ def get_modules_from_all_apps(): return modules_list def get_modules_from_app(app): - try: - modules = frappe.get_attr(app + '.config.desktop.get_data')() or {} - except ImportError: - return [] - - active_domains = frappe.get_active_domains() - - if isinstance(modules, dict): - active_modules_list = [] - for m, module in iteritems(modules): - module['module_name'] = m - module['app'] = app - active_modules_list.append(module) - else: - for m in modules: - if m.get("type") == "module" and "category" not in m: - m["category"] = "Modules" - - # Only newly formatted modules that have a category to be shown on desk - modules = [m for m in modules if m.get("category")] - active_modules_list = [] - - for m in modules: - to_add = True - module_name = m.get("module_name") - - # Check Domain - if is_domain(m) and module_name not in active_domains: - to_add = False - - # Check if config - if is_module(m) and not config_exists(app, frappe.scrub(module_name)): - to_add = False - - if "condition" in m and not m["condition"]: - to_add = False - - if to_add: - m["app"] = app - active_modules_list.append(m) - - return active_modules_list + return frappe.get_all('Module Def', + filters={'app_name': app}, + fields=['module_name', 'app_name as app'] + ) def get_all_empty_tables_by_module(): empty_tables = set(r[0] for r in frappe.db.multisql({ diff --git a/frappe/desk/doctype/notification_log/notification_log.py b/frappe/desk/doctype/notification_log/notification_log.py index a6126f1f9b..20551559fd 100644 --- a/frappe/desk/doctype/notification_log/notification_log.py +++ b/frappe/desk/doctype/notification_log/notification_log.py @@ -61,7 +61,7 @@ def make_notification_logs(doc, users): from frappe.social.doctype.energy_point_settings.energy_point_settings import is_energy_point_enabled for user in users: - if frappe.db.exists('User', {"name": user, "enabled": 1}): + if frappe.db.exists('User', {"email": user, "enabled": 1}): if is_notifications_enabled(user): if doc.type == 'Energy Point' and not is_energy_point_enabled(): return diff --git a/frappe/desk/form/load.py b/frappe/desk/form/load.py index 1f5c437330..c1429d361f 100644 --- a/frappe/desk/form/load.py +++ b/frappe/desk/form/load.py @@ -100,6 +100,7 @@ def get_docinfo(doc=None, doctype=None, name=None): "assignment_logs": get_comments(doc.doctype, doc.name, 'assignment'), "permissions": get_doc_permissions(doc), "shared": frappe.share.get_users(doc.doctype, doc.name), + "info_logs": get_comments(doc.doctype, doc.name, 'Info'), "share_logs": get_comments(doc.doctype, doc.name, 'share'), "like_logs": get_comments(doc.doctype, doc.name, 'Like'), "views": get_view_logs(doc.doctype, doc.name), diff --git a/frappe/public/icons/timeless/symbol-defs.svg b/frappe/public/icons/timeless/symbol-defs.svg index 2b0cc8b696..d2c162161f 100644 --- a/frappe/public/icons/timeless/symbol-defs.svg +++ b/frappe/public/icons/timeless/symbol-defs.svg @@ -693,4 +693,10 @@ + + + + + + diff --git a/frappe/public/js/frappe/form/controls/color.js b/frappe/public/js/frappe/form/controls/color.js index 7890ea755c..bf04581abd 100644 --- a/frappe/public/js/frappe/form/controls/color.js +++ b/frappe/public/js/frappe/form/controls/color.js @@ -76,7 +76,7 @@ frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({ refresh() { this._super(); let color = this.get_color(); - if (this.picker.color !== color) { + if (this.picker && this.picker.color !== color) { this.picker.color = color; this.picker.refresh(); } diff --git a/frappe/public/js/frappe/form/footer/form_timeline.js b/frappe/public/js/frappe/form/footer/form_timeline.js index 7b8d36d90b..1da59a2fdf 100644 --- a/frappe/public/js/frappe/form/footer/form_timeline.js +++ b/frappe/public/js/frappe/form/footer/form_timeline.js @@ -139,6 +139,7 @@ class FormTimeline extends BaseTimeline { this.timeline_items.push(...this.get_custom_timeline_contents()); this.timeline_items.push(...this.get_assignment_timeline_contents()); this.timeline_items.push(...this.get_attachment_timeline_contents()); + this.timeline_items.push(...this.get_info_timeline_contents()); this.timeline_items.push(...this.get_milestone_timeline_contents()); } } @@ -269,6 +270,17 @@ class FormTimeline extends BaseTimeline { return assignment_timeline_contents; } + get_info_timeline_contents() { + let info_timeline_contents = []; + (this.doc_info.info_logs || []).forEach(info_log => { + info_timeline_contents.push({ + creation: info_log.creation, + content: `${this.get_user_link(info_log.comment_email)} ${info_log.content}`, + }); + }); + return info_timeline_contents; + } + get_attachment_timeline_contents() { let attachment_timeline_contents = []; (this.doc_info.attachment_logs || []).forEach(attachment_log => { diff --git a/frappe/public/js/frappe/form/footer/version_timeline_content_builder.js b/frappe/public/js/frappe/form/footer/version_timeline_content_builder.js index 0f57998475..a563286413 100644 --- a/frappe/public/js/frappe/form/footer/version_timeline_content_builder.js +++ b/frappe/public/js/frappe/form/footer/version_timeline_content_builder.js @@ -144,6 +144,27 @@ function get_version_timeline_content(version_doc, frm) { function get_version_comment(version_doc, text) { + // TODO: Replace with a better solution + if (text.includes(" { + if ($(element).is('a')) { + version_comment += unlinked_content ? frappe.utils.get_form_link('Version', version_doc.name, true, unlinked_content) : ""; + unlinked_content = ""; + version_comment += element.outerHTML; + } else { + unlinked_content += element.outerHTML || element.textContent; + } + }); + if (unlinked_content) { + version_comment += frappe.utils.get_form_link('Version', version_doc.name, true, unlinked_content); + } + return version_comment; + } return frappe.utils.get_form_link('Version', version_doc.name, true, text); } @@ -164,4 +185,5 @@ function get_user_link(doc) { return frappe.utils.get_form_link('User', user, true, user_display_text); } -export { get_version_timeline_content }; \ No newline at end of file +export { get_version_timeline_content }; + diff --git a/frappe/public/js/frappe/form/formatters.js b/frappe/public/js/frappe/form/formatters.js index 4578cf2ded..f792d5b173 100644 --- a/frappe/public/js/frappe/form/formatters.js +++ b/frappe/public/js/frappe/form/formatters.js @@ -293,6 +293,12 @@ frappe.form.formatters = { return frappe.format(value, link_field, options, row); }); return formatted_values.join(', '); + }, + Color: (value) => { + return `
+
+ ${value} +
`; } } diff --git a/frappe/public/js/frappe/list/base_list.js b/frappe/public/js/frappe/list/base_list.js index 24e14ffc38..beacb136e6 100644 --- a/frappe/public/js/frappe/list/base_list.js +++ b/frappe/public/js/frappe/list/base_list.js @@ -179,7 +179,8 @@ frappe.views.BaseList = class BaseList { 'Calendar': 'calendar', 'Gantt': 'gantt', 'Kanban': 'kanban', - 'Dashboard': 'dashboard' + 'Dashboard': 'dashboard', + 'Map': 'map', }; if (frappe.boot.desk_settings.view_switcher) { @@ -285,6 +286,7 @@ frappe.views.BaseList = class BaseList { } setup_filter_area() { + if (this.hide_filters) return; this.filter_area = new FilterArea(this); if (this.filters && this.filters.length > 0) { @@ -293,6 +295,7 @@ frappe.views.BaseList = class BaseList { } setup_sort_selector() { + if (this.hide_sort_selector) return; this.sort_selector = new frappe.ui.SortSelector({ parent: this.$filter_section, doctype: this.doctype, @@ -410,7 +413,7 @@ frappe.views.BaseList = class BaseList { doctype: this.doctype, fields: this.get_fields(), filters: this.get_filters_for_args(), - order_by: this.sort_selector.get_sql_string(), + order_by: this.sort_selector && this.sort_selector.get_sql_string(), start: this.start, page_length: this.page_length, view: this.view, @@ -821,6 +824,7 @@ frappe.views.view_modes = [ "Image", "Inbox", "Tree", + "Map", ]; frappe.views.is_valid = (view_mode) => frappe.views.view_modes.includes(view_mode); diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 48ae8b1d08..c55ec4b3ab 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -417,11 +417,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { get_no_result_message() { let help_link = this.get_documentation_link(); - let filters = this.filter_area.get(); - let no_result_message = filters.length + let filters = this.filter_area && this.filter_area.get(); + let no_result_message = filters && filters.length ? __("No {0} found", [__(this.doctype)]) : __("You haven't created a {0} yet", [__(this.doctype)]); - let new_button_label = filters.length + let new_button_label = filters && filters.length ? __("Create a new {0}", [__(this.doctype)]) : __("Create your first {0}", [__(this.doctype)]); let empty_state_image = @@ -461,7 +461,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { } before_refresh() { - if (frappe.route_options) { + if (frappe.route_options && this.filter_area) { this.filters = this.parse_filters_from_route_options(); frappe.route_options = null; @@ -527,9 +527,9 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { this.view_name ); this.save_view_user_settings({ - filters: this.filter_area.get(), - sort_by: this.sort_selector.sort_by, - sort_order: this.sort_selector.sort_order, + filters: this.filter_area && this.filter_area.get(), + sort_by: this.sort_selector && this.sort_selector.sort_by, + sort_order: this.sort_selector && this.sort_selector.sort_order, }); this.toggle_paging && this.$paging_area.toggle(false); } diff --git a/frappe/public/js/frappe/list/list_view_select.js b/frappe/public/js/frappe/list/list_view_select.js index 826158ff3f..9607be6e90 100644 --- a/frappe/public/js/frappe/list/list_view_select.js +++ b/frappe/public/js/frappe/list/list_view_select.js @@ -123,7 +123,14 @@ frappe.views.ListViewSelect = class ListViewSelect { kanbans => this.setup_kanban_switcher(kanbans) ); } - } + }, + Map: { + condition: this.list_view.settings.get_coords_method || + (this.list_view.meta.fields.find(i => i.fieldname === "latitude") && + this.list_view.meta.fields.find(i => i.fieldname === "longitude")) || + (this.list_view.meta.fields.find(i => i.fieldname === 'location' && i.fieldtype == 'Geolocation')), + action: () => this.set_route("map") + }, }; frappe.views.view_modes.forEach(view => { diff --git a/frappe/public/js/frappe/ui/filters/field_select.js b/frappe/public/js/frappe/ui/filters/field_select.js index ed271a73aa..c362214ce2 100644 --- a/frappe/public/js/frappe/ui/filters/field_select.js +++ b/frappe/public/js/frappe/ui/filters/field_select.js @@ -36,6 +36,18 @@ frappe.ui.FieldSelect = Class.extend({ var item = me.awesomplete.get_item(value); me.$input.val(item.label); }); + this.$input.on("awesomplete-open", () => { + let modal = this.$input.parents('.modal-dialog')[0]; + if (modal) { + $(modal).removeClass("modal-dialog-scrollable"); + } + }); + this.$input.on("awesomplete-close", () => { + let modal = this.$input.parents('.modal-dialog')[0]; + if (modal) { + $(modal).addClass("modal-dialog-scrollable"); + } + }); if(this.filter_fields) { for(var i in this.filter_fields) diff --git a/frappe/public/js/frappe/ui/filters/filter.js b/frappe/public/js/frappe/ui/filters/filter.js index 945115af82..b2b2b623e2 100644 --- a/frappe/public/js/frappe/ui/filters/filter.js +++ b/frappe/public/js/frappe/ui/filters/filter.js @@ -495,6 +495,7 @@ frappe.ui.filter_utils = { 'Dynamic Link', 'Read Only', 'Assign', + 'Color', ].indexOf(df.fieldtype) != -1 ) { df.fieldtype = 'Data'; diff --git a/frappe/public/js/frappe/ui/filters/filter_list.js b/frappe/public/js/frappe/ui/filters/filter_list.js index 0b2218ceda..611ab024bf 100644 --- a/frappe/public/js/frappe/ui/filters/filter_list.js +++ b/frappe/public/js/frappe/ui/filters/filter_list.js @@ -283,6 +283,7 @@ frappe.ui.FilterGroup = class { } get_filter_area_template() { + /* eslint-disable indent */ return $(`
@@ -293,19 +294,23 @@ frappe.ui.FilterGroup = class {
- + ${this.filter_button ? + `` + : '' + }
` ); + /* eslint-disable indent */ } get_filters_as_object() { diff --git a/frappe/public/js/frappe/views/dashboard/dashboard_view.js b/frappe/public/js/frappe/views/dashboard/dashboard_view.js index 5137d840ec..252024463e 100644 --- a/frappe/public/js/frappe/views/dashboard/dashboard_view.js +++ b/frappe/public/js/frappe/views/dashboard/dashboard_view.js @@ -20,6 +20,8 @@ frappe.views.DashboardView = class DashboardView extends frappe.views.ListView { setup_page() { this.hide_sidebar = true; this.hide_page_form = true; + this.hide_filters = true; + this.hide_sort_selector = true; super.setup_page(); } @@ -74,6 +76,10 @@ frappe.views.DashboardView = class DashboardView extends frappe.views.ListView { this.toggle_customization_buttons(false); } + set_primary_action() { + // Don't render Add doc button for dashboard view + } + toggle_customization_buttons(show) { this.save_customizations_button.toggle(show); this.discard_customizations_button.toggle(show); diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 104c457991..01314b436f 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -573,14 +573,17 @@ export default class ChartWidget extends Widget { xIsSeries: this.chart_doc.timeseries, shortenYAxisNumbers: 1 }, - tooltipOptions: { + }; + + if (this.report_result && this.report_result.chart) { + chart_args.tooltipOptions = { formatTooltipY: value => frappe.format(value, { fieldtype: this.report_result.chart.fieldtype, options: this.report_result.chart.options }, { always_show_decimals: true, inline: true }) - } - }; + }; + } if (this.chart_doc.type == "Heatmap") { const heatmap_year = parseInt(this.selected_heatmap_year || this.chart_settings.heatmap_year || this.chart_doc.heatmap_year); diff --git a/frappe/public/scss/common/color_picker.scss b/frappe/public/scss/common/color_picker.scss index 627ab12a2e..7ab9b0c504 100644 --- a/frappe/public/scss/common/color_picker.scss +++ b/frappe/public/scss/common/color_picker.scss @@ -92,7 +92,7 @@ } } -.frappe-control[data-fieldtype='Color'] { +.frappe-control[data-fieldtype='Color'] { input { padding-left: 40px; } @@ -104,11 +104,20 @@ background-color: red; position: absolute; top: calc(50% + 1px); - left: 5px; + left: 8px; content: ' '; &.no-value { background: url('/assets/frappe/images/color-circle.png'); background-size: contain; } } -} \ No newline at end of file + .like-disabled-input { + .color-value { + padding-left: 25px; + } + .selected-color { + top: 20%; + cursor: default; + } + } +} diff --git a/frappe/public/scss/desk/list.scss b/frappe/public/scss/desk/list.scss index b7a195718e..ea3401b09e 100644 --- a/frappe/public/scss/desk/list.scss +++ b/frappe/public/scss/desk/list.scss @@ -332,10 +332,6 @@ input.list-check-all, input.list-row-checkbox { } .page-form { - // .awesomplete > ul { - // min-width: 300px; - // } - .standard-filter-section { flex-wrap: wrap; // width: 65%; diff --git a/frappe/public/scss/desk/page.scss b/frappe/public/scss/desk/page.scss index 85831dc2a0..65d535facc 100644 --- a/frappe/public/scss/desk/page.scss +++ b/frappe/public/scss/desk/page.scss @@ -117,6 +117,10 @@ display: none; } } + + .awesomplete > ul { + min-width: 300px; + } } .form-inner-toolbar { diff --git a/frappe/utils/connections.py b/frappe/utils/connections.py index 6bd24d57ec..bd30c7c060 100644 --- a/frappe/utils/connections.py +++ b/frappe/utils/connections.py @@ -23,7 +23,7 @@ def is_open(ip, port, timeout=10): def check_database(): db_type = config.get("db_type", "mariadb") db_host = config.get("db_host", "localhost") - db_port = config.get("db_port", 3306 if db_type == "mariadb" else 5342) + db_port = config.get("db_port", 3306 if db_type == "mariadb" else 5432) return {db_type: is_open(db_host, db_port)} diff --git a/yarn.lock b/yarn.lock index 3999616099..44f5555568 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8525,16 +8525,11 @@ xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -"y18n@^3.2.1 || ^4.0.0": +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"