diff --git a/.eslintrc b/.eslintrc
index 46a4f4be8d..4b7dcf3457 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -120,6 +120,7 @@
"md5": true,
"$": true,
"jQuery": true,
+ "Vue": true,
"moment": true,
"hljs": true,
"Awesomplete": true,
diff --git a/cypress/integration/awesome_bar.js b/cypress/integration/awesome_bar.js
index 44dbde8fcf..4b2ae0da93 100644
--- a/cypress/integration/awesome_bar.js
+++ b/cypress/integration/awesome_bar.js
@@ -8,13 +8,6 @@ context('Awesome Bar', () => {
cy.get('.navbar-home').click();
});
- it('navigates to modules', () => {
- cy.get('#navbar-search')
- .type('modules{downarrow}{enter}', { delay: 100 });
-
- cy.location('hash').should('eq', '#modules');
- });
-
it('navigates to doctype list', () => {
cy.get('#navbar-search')
.type('todo{downarrow}{enter}', { delay: 100 });
diff --git a/frappe/boot.py b/frappe/boot.py
index 18fb080d4f..043c1b0361 100644
--- a/frappe/boot.py
+++ b/frappe/boot.py
@@ -96,8 +96,8 @@ def load_conf_settings(bootinfo):
if key in conf: bootinfo[key] = conf.get(key)
def load_desktop_icons(bootinfo):
- from frappe.desk.doctype.desktop_icon.desktop_icon import get_desktop_icons
- bootinfo.desktop_icons = get_desktop_icons()
+ from frappe.config import get_modules_from_all_apps_for_user
+ bootinfo.allowed_modules = get_modules_from_all_apps_for_user()
def get_allowed_pages():
return get_user_pages_or_reports('Page')
diff --git a/frappe/config/__init__.py b/frappe/config/__init__.py
index e69de29bb2..d26f788bba 100644
--- a/frappe/config/__init__.py
+++ b/frappe/config/__init__.py
@@ -0,0 +1,85 @@
+from __future__ import unicode_literals
+from frappe import _
+import frappe
+from frappe.desk.moduleview import get_data
+from six import iteritems
+
+def get_modules_from_all_apps_for_user(user=None):
+ if not user:
+ user = frappe.session.user
+
+ all_modules = get_modules_from_all_apps()
+ user_blocked_modules = frappe.get_doc('User', user).get_blocked_modules()
+
+ allowed_modules_list = [m for m in all_modules if m.get("module_name") not in user_blocked_modules]
+
+ return allowed_modules_list
+
+def get_modules_from_all_apps():
+ modules_list = []
+ for app in frappe.get_installed_apps():
+ modules_list += get_modules_from_app(app)
+ return modules_list
+
+def get_modules_from_app(app):
+ try:
+ modules = frappe.get_attr(app + '.config.desktop.get_data')() or {}
+ except ImportError:
+ return []
+
+ # Only newly formatted modules that have a category to be shown on desk
+ modules = [m for m in modules if m.get("category")]
+
+ active_domains = frappe.get_active_domains()
+
+ if isinstance(modules, dict):
+ active_modules_list = []
+ for m, module in iteritems(modules):
+ module['module_name'] = m
+ active_modules_list.append(module)
+ else:
+ active_modules_list = []
+ for m in modules:
+ to_add = True
+ module_name = m.get("module_name")
+
+ # Check Domain
+ if is_domain(m):
+ if module_name not in active_domains:
+ to_add = False
+
+ if "condition" in m and not m["condition"]:
+ to_add = False
+
+ if to_add:
+ onboard_present = is_onboard_present(m) if show_onboard(m) else False
+ m["onboard_present"] = onboard_present
+ active_modules_list.append(m)
+
+ return active_modules_list
+
+def show_onboard(module):
+ return module.get("type") == "module" and module.get("category") in ["Modules", "Domains"]
+
+def is_onboard_present(module):
+ print(module["module_name"])
+ exists_cache = {}
+ def exists(name, link_type):
+ exists = exists_cache.get(name)
+ if not exists:
+ if link_type == "doctype" and not frappe.db.get_value('DocType', name, 'issingle'):
+ exists = frappe.db.count(name)
+ else:
+ exists = True
+ exists_cache[name] = exists
+ return exists
+
+ sections = get_data(module["module_name"], False)
+ for section in sections:
+ for item in section["items"]:
+ if exists(item.get("name"), item.get("type")):
+ return True
+ return False
+
+def is_domain(module):
+ return module.get("category") == "Domains"
diff --git a/frappe/config/desk.py b/frappe/config/desk.py
index 8efe293411..40db97ef8c 100644
--- a/frappe/config/desk.py
+++ b/frappe/config/desk.py
@@ -12,11 +12,7 @@ def get_data():
"name": "ToDo",
"label": _("To Do"),
"description": _("Documents assigned to you and by you."),
- },
- {
- "type": "doctype",
- "name": "File",
- "label": _("Files"),
+ "onboard": 1,
},
{
"type": "doctype",
@@ -24,6 +20,18 @@ def get_data():
"label": _("Calendar"),
"link": "List/Event/Calendar",
"description": _("Event and other calendars."),
+ "onboard": 1,
+ },
+ {
+ "type": "doctype",
+ "name": "Note",
+ "description": _("Private and public Notes."),
+ "onboard": 1,
+ },
+ {
+ "type": "doctype",
+ "name": "File",
+ "label": _("Files"),
},
{
"type": "page",
@@ -32,11 +40,6 @@ def get_data():
"description": _("Chat messages and other notifications."),
"data_doctype": "Communication"
},
- {
- "type": "doctype",
- "name": "Note",
- "description": _("Private and public Notes."),
- },
{
"type": "page",
"label": _("Activity"),
@@ -52,6 +55,7 @@ def get_data():
"type": "doctype",
"name": "Newsletter",
"description": _("Newsletters to contacts, leads."),
+ "onboard": 1,
},
{
"type": "doctype",
diff --git a/frappe/config/desktop.py b/frappe/config/desktop.py
index b620508c06..d92f8469af 100644
--- a/frappe/config/desktop.py
+++ b/frappe/config/desktop.py
@@ -1,91 +1,87 @@
from __future__ import unicode_literals
+import frappe
from frappe import _
def get_data():
return [
+ # Administration
{
"module_name": "Desk",
+ "category": "Administration",
"label": _("Tools"),
"color": "#FFF5A7",
"reverse": 1,
"icon": "octicon octicon-calendar",
- "type": "module"
- },
- {
- "module_name": "File Manager",
- "color": "#AA784D",
- "doctype": "File",
- "icon": "octicon octicon-file-directory",
- "label": _("File Manager"),
- "link": "List/File",
- "type": "list",
- "hidden": 1
- },
- {
- "module_name": "Website",
- "color": "#16a085",
- "icon": "octicon octicon-globe",
"type": "module",
- "hidden": 1
+ "description": "Todos, Notes and other basic tools to help you track your work."
},
{
- "module_name": "Integrations",
- "color": "#16a085",
- "icon": "octicon octicon-globe",
- "type": "module",
- "hidden": 1
- },
- {
- "module_name": "Setup",
+ "module_name": "Settings",
+ "category": "Administration",
+ "label": _("Settings"),
"color": "#bdc3c7",
"reverse": 1,
"icon": "octicon octicon-settings",
"type": "module",
- "hidden": 1
+ "hidden": 1,
+ "description": "Configure your ERPNext account."
},
{
- "module_name": 'Email Inbox',
- "type": 'list',
- "label": 'Email Inbox',
- "_label": _('Email Inbox'),
- "_id": 'Email Inbox',
- "_doctype": 'Communication',
- "icon": 'fa fa-envelope-o',
- "color": '#589494',
- "link": 'List/Communication/Inbox'
+ "module_name": "Integrations",
+ "category": "Administration",
+ "label": _("Integrations"),
+ "color": "#16a085",
+ "icon": "octicon octicon-globe",
+ "type": "module",
+ "hidden": 1,
+ "description": "DropBox, Woocomerce, AWS, Shopify and GoCardless."
+ },
+ {
+ "module_name": 'Contacts',
+ "category": "Administration",
+ "label": _("Contacts"),
+ "type": 'module',
+ "icon": "octicon octicon-book",
+ "color": '#ffaedb',
+ "hidden": 1,
+ "description": "People Contacts and Address Book."
},
{
"module_name": "Core",
- "label": "Developer",
+ "category": "Administration",
"_label": _("Developer"),
+ "label": "Developer",
"color": "#589494",
"icon": "octicon octicon-circuit-board",
"type": "module",
"system_manager": 1,
- "hidden": 1
- },
- {
- "module_name": 'Contacts',
- "type": 'module',
- "icon": "octicon octicon-book",
- "color": '#FFAEDB',
+ "condition": getattr(frappe.local.conf, 'developer_mode', 0),
"hidden": 1,
+ "description": "The Frappe innards of ERPNext. (Only active when developer mode is enabled)"
+ },
+
+ # Places
+ {
+ "module_name": "Website",
+ "category": "Places",
+ "label": _("Website"),
+ "_label": _("Website"),
+ "color": "#16a085",
+ "icon": "octicon octicon-globe",
+ "type": "module",
+ "hidden": 1,
+ "description": "Webpages and the Portal Side of Things."
},
{
"module_name": 'Social',
+ "category": "Places",
"label": _('Social'),
"icon": "octicon octicon-heart",
"type": 'link',
- "link": 'social/home',
+ "link": '#social/home',
"color": '#FF4136',
'standard': 1,
- 'idx': 15
+ 'idx': 15,
+ "description": "Build your profile and share posts on the feed with other users."
},
- {
- "module_name": 'Settings',
- "color": "#bdc3c7",
- "reverse": 1,
- "icon": "octicon octicon-settings",
- "type": "module"
- }
]
diff --git a/frappe/config/settings.py b/frappe/config/settings.py
deleted file mode 100644
index d1c00c2e71..0000000000
--- a/frappe/config/settings.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from frappe import _
-
-def get_data():
- return [{
- "label": _("Settings"),
- "icon": "fa fa-wrench",
- "items": [
- {
- "type": "doctype",
- "name": "System Settings",
- "label": _("System Settings"),
- "description": _("Language, Date and Time settings"),
- "hide_count": True
- },
- {
- "type": "doctype",
- "name": "Domain Settings",
- "label": _("Domain Settings"),
- "description": _("Enable / Disable Domains"),
- "hide_count": True
- },
- {
- "type": "doctype",
- "name": "Print Settings",
- "label": _("Print Settings"),
- "description": _("Print Style, PDF Size"),
- "hide_count": True
- },
- {
- "type": "doctype",
- "name": "Website Settings",
- "label": _("Website Settings"),
- "description": _("Landing Page, Website Theme, Brand Setup and more"),
- "hide_count": True
- },
- {
- "type": "doctype",
- "name": "S3 Backup Settings",
- "label": _("S3 Backup Settings"),
- "description": _("Enable / Disable Backup, Backup Frequency"),
- "hide_count": True
- },
- {
- "type": "doctype",
- "name": "SMS Settings",
- "label": _("SMS Settings"),
- "description": _("SMS Gateway URL, Message & Receiver Parameter"),
- "hide_count": True
- }
- ]
- }]
diff --git a/frappe/config/website.py b/frappe/config/website.py
index de66ca0959..2de27a581b 100644
--- a/frappe/config/website.py
+++ b/frappe/config/website.py
@@ -11,11 +11,13 @@ def get_data():
"type": "doctype",
"name": "Web Page",
"description": _("Content web page."),
+ "onboard": 1,
},
{
"type": "doctype",
"name": "Web Form",
"description": _("User editable form on Website."),
+ "onboard": 1,
},
{
"type": "doctype",
@@ -35,6 +37,7 @@ def get_data():
"type": "doctype",
"name": "Blog Post",
"description": _("Single Post (article)."),
+ "onboard": 1,
},
{
"type": "doctype",
@@ -56,11 +59,13 @@ def get_data():
"type": "doctype",
"name": "Website Settings",
"description": _("Setup of top navigation bar, footer and logo."),
+ "onboard": 1,
},
{
"type": "doctype",
"name": "Website Theme",
"description": _("List of themes for Website."),
+ "onboard": 1,
},
{
"type": "doctype",
@@ -86,6 +91,7 @@ def get_data():
"type": "doctype",
"name": "Portal Settings",
"label": _("Portal Settings"),
+ "onboard": 1,
}
]
},
diff --git a/frappe/core/doctype/domain/domain.py b/frappe/core/doctype/domain/domain.py
index ea21e73b95..a4e9f503ab 100644
--- a/frappe/core/doctype/domain/domain.py
+++ b/frappe/core/doctype/domain/domain.py
@@ -18,8 +18,7 @@ class Domain(Document):
self.setup_roles()
self.setup_properties()
self.set_values()
- # always set the desktop icons while changing the domain settings
- self.setup_desktop_icons()
+
if not int(frappe.defaults.get_defaults().setup_complete or 0):
# if setup not complete, setup desktop etc.
self.setup_sidebar_items()
@@ -89,12 +88,6 @@ class Domain(Document):
frappe.db.set_value('Portal Settings', None, 'default_role',
self.data.get('default_portal_role'))
- def setup_desktop_icons(self):
- '''set desktop icons form `data.desktop_icons`'''
- from frappe.desk.doctype.desktop_icon.desktop_icon import set_desktop_icons
- if self.data.desktop_icons:
- set_desktop_icons(self.data.desktop_icons)
-
def setup_properties(self):
if self.data.properties:
for args in self.data.properties:
diff --git a/frappe/core/doctype/user/user.js b/frappe/core/doctype/user/user.js
index 71d7cfc0e8..d334731015 100644
--- a/frappe/core/doctype/user/user.js
+++ b/frappe/core/doctype/user/user.js
@@ -71,10 +71,6 @@ frappe.ui.form.on('User', {
frm.toggle_display(['sb1', 'sb3', 'modules_access'], false);
if(!frm.is_new()) {
- frm.add_custom_button(__("Set Desktop Icons"), function() {
- frappe.frappe_toolbar.modules_select.show(doc.name);
- }, null, "btn-default")
-
if(has_access_to_edit_user()) {
frm.add_custom_button(__("Set User Permissions"), function() {
diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json
index 4fcee60dc5..6d429f3248 100644
--- a/frappe/core/doctype/user/user.json
+++ b/frappe/core/doctype/user/user.json
@@ -1511,7 +1511,7 @@
"columns": 0,
"default": "",
"description": "",
- "fieldname": "desktop_icon_access",
+ "fieldname": "sb_allow_modules",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -1520,7 +1520,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Allow Desktop Icon",
+ "label": "Allow Modules",
"length": 0,
"no_copy": 0,
"permlevel": 1,
@@ -2303,7 +2303,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 5,
- "modified": "2018-11-21 12:34:57.652854",
+ "modified": "2019-01-30 13:56:10.732154",
"modified_by": "Administrator",
"module": "Core",
"name": "User",
diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py
index dbc2ccd873..087d7c9d21 100644
--- a/frappe/core/doctype/user/user.py
+++ b/frappe/core/doctype/user/user.py
@@ -36,9 +36,9 @@ class User(Document):
self.name = self.email
def onload(self):
+ from frappe.config import get_modules_from_all_apps
self.set_onload('all_modules',
- [m.module_name for m in frappe.db.get_all('Desktop Icon',
- fields=['module_name'], filters={'standard': 1}, order_by="module_name")])
+ [m.get("module_name") for m in get_modules_from_all_apps()])
def before_insert(self):
self.flags.in_insert = True
diff --git a/frappe/core/page/desktop/README.md b/frappe/core/page/desktop/README.md
deleted file mode 100644
index 4ac65f50b5..0000000000
--- a/frappe/core/page/desktop/README.md
+++ /dev/null
@@ -1 +0,0 @@
-First screen after login. Array of module icons based on permission.
\ No newline at end of file
diff --git a/frappe/core/page/desktop/__init__.py b/frappe/core/page/desktop/__init__.py
index 0e57cb68c3..e69de29bb2 100644
--- a/frappe/core/page/desktop/__init__.py
+++ b/frappe/core/page/desktop/__init__.py
@@ -1,3 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
-
diff --git a/frappe/core/page/desktop/all_applications_dialog.html b/frappe/core/page/desktop/all_applications_dialog.html
deleted file mode 100644
index d26152c84b..0000000000
--- a/frappe/core/page/desktop/all_applications_dialog.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-{% if (frappe.user.has_role("System Manager")) { %}
-Install new applications
-
-{% } %}
-
-{%= __("Checked items will be shown on desktop") %}
-
- {% for(var i=0, l=all_modules.length; i < l; i++) {
- var module_name = all_modules[i];
- var module = frappe.get_module(module_name);
- if (desktop_items.indexOf(module_name)===-1
- || frappe.user.is_module_blocked(module_name)) { continue; }
- %}
-
-
-
-
-
- {% } %}
-
diff --git a/frappe/core/page/desktop/desktop.js b/frappe/core/page/desktop/desktop.js
index 24dd0c3b4e..13b64c9246 100644
--- a/frappe/core/page/desktop/desktop.js
+++ b/frappe/core/page/desktop/desktop.js
@@ -1,344 +1 @@
-frappe.provide('frappe.desktop');
-
-frappe.pages['desktop'].on_page_load = function(wrapper) {
-
- // load desktop
- if(!frappe.list_desktop) {
- frappe.desktop.set_background();
- }
- frappe.desktop.refresh(wrapper);
-};
-
-frappe.pages['desktop'].on_page_show = function(wrapper) {
- if(frappe.list_desktop) {
- $("body").attr("data-route", "list-desktop");
- }
-};
-
-$.extend(frappe.desktop, {
- refresh: function(wrapper) {
- if (wrapper) {
- this.wrapper = $(wrapper);
- }
-
- this.render();
- this.make_sortable();
- },
-
- render: function() {
- var me = this;
- frappe.utils.set_title(__("Desktop"));
-
- var template = frappe.list_desktop ? "desktop_list_view" : "desktop_icon_grid";
-
- var all_icons = frappe.get_desktop_icons();
- var explore_icon = {
- module_name: 'Explore',
- label: 'Explore',
- _label: __('Explore'),
- _id: 'Explore',
- _doctype: '',
- icon: 'octicon octicon-telescope',
- color: '#7578f6',
- link: 'modules'
- };
- explore_icon.app_icon = frappe.ui.app_icon.get_html(explore_icon);
- all_icons.push(explore_icon);
-
- frappe.desktop.wrapper.html(frappe.render_template(template, {
- // all visible icons
- desktop_items: all_icons,
- }));
-
- frappe.desktop.setup_module_click();
-
- // notifications
- frappe.desktop.show_pending_notifications();
- $(document).on("notification-update", function() {
- me.show_pending_notifications();
- });
-
- $(document).trigger("desktop-render");
-
- },
-
- render_help_messages: function(help_messages) {
- var wrapper = frappe.desktop.wrapper.find('.help-message-wrapper');
- var $help_messages = wrapper.find('.help-messages');
-
- var set_current_message = function(idx) {
- idx = cint(idx);
- wrapper.current_message_idx = idx;
- wrapper.find('.left-arrow, .right-arrow').addClass('disabled');
- wrapper.find('.help-message-item').addClass('hidden');
- wrapper.find('[data-message-idx="'+idx+'"]').removeClass('hidden');
- if(idx > 0) {
- wrapper.find('.left-arrow').removeClass('disabled');
- }
- if(idx < help_messages.length - 1) {
- wrapper.find('.right-arrow').removeClass('disabled');
- }
- }
-
- if(help_messages) {
- wrapper.removeClass('hidden');
- help_messages.forEach(function(message, i) {
- var $message = $('')
- .attr('data-message-idx', i)
- .html(frappe.render_template('desktop_help_message', message))
- .appendTo($help_messages);
-
- });
-
- set_current_message(0);
-
- wrapper.find('.close').on('click', function() {
- wrapper.addClass('hidden');
- });
- }
-
- wrapper.find('.left-arrow').on('click', function() {
- if(wrapper.current_message_idx) {
- set_current_message(wrapper.current_message_idx - 1);
- }
- })
-
- wrapper.find('.right-arrow').on('click', function() {
- if(help_messages.length > wrapper.current_message_idx + 1) {
- set_current_message(wrapper.current_message_idx + 1);
- }
- });
-
- },
-
- setup_module_click: function() {
- frappe.desktop.wiggling = false;
-
- if(frappe.list_desktop) {
- frappe.desktop.wrapper.on("click", ".desktop-list-item", function() {
- frappe.desktop.open_module($(this));
- });
- } else {
- frappe.desktop.wrapper.on("click", ".app-icon, .app-icon-svg", function() {
- if ( !frappe.desktop.wiggling ) {
- frappe.desktop.open_module($(this).parent());
- }
- });
- }
- frappe.desktop.wrapper.on("click", ".circle", function() {
- var doctype = $(this).attr('data-doctype');
- if(doctype) {
- frappe.ui.notifications.show_open_count_list(doctype);
- }
- });
-
- frappe.desktop.setup_wiggle();
- },
-
- setup_wiggle: () => {
- // Wiggle, Wiggle, Wiggle.
- const DURATION_LONG_PRESS = 1000;
-
- var timer_id = 0;
- const $cases = frappe.desktop.wrapper.find('.case-wrapper');
- const $icons = frappe.desktop.wrapper.find('.app-icon');
- const $notis = $(frappe.desktop.wrapper.find('.circle').toArray().filter((object) => {
- // This hack is so bad, I should punch myself.
- // Seriously, punch yourself.
- const text = $(object).find('.circle-text').html();
-
- return text;
- }));
-
- const clearWiggle = () => {
- const $closes = $cases.find('.module-remove');
- $closes.hide();
- $notis.show();
-
- $icons.removeClass('wiggle');
-
- frappe.desktop.wiggling = false;
- };
-
- frappe.desktop.wrapper.on('mousedown', '.app-icon', () => {
- timer_id = setTimeout(() => {
- frappe.desktop.wiggling = true;
- // hide all notifications.
- $notis.hide();
-
- $cases.each((i) => {
- const $case = $($cases[i]);
- const template =
- `
-
- `;
-
- $case.append(template);
- const $close = $case.find('.module-remove');
- const name = $case.attr('title');
- $close.click(() => {
- // good enough to create dynamic dialogs?
- const dialog = new frappe.ui.Dialog({
- title: __(`Hide ${name}?`)
- });
- dialog.set_primary_action(__('Hide'), () => {
- frappe.call({
- method: 'frappe.desk.doctype.desktop_icon.desktop_icon.hide',
- args: { name: name },
- freeze: true,
- callback: (response) =>
- {
- if ( response.message ) {
- location.reload();
- }
- }
- })
-
- dialog.hide();
-
- clearWiggle();
- });
- // Hacks, Hacks and Hacks.
- var $cancel = dialog.get_close_btn();
- $cancel.click(() => {
- clearWiggle();
- });
- $cancel.html(__(`Cancel`));
-
- dialog.show();
- });
- });
-
- $icons.addClass('wiggle');
-
- }, DURATION_LONG_PRESS);
- });
- frappe.desktop.wrapper.on('mouseup mouseleave', '.app-icon', () => {
- clearTimeout(timer_id);
- });
-
- // also stop wiggling if clicked elsewhere.
- $('body').click((event) => {
- if ( frappe.desktop.wiggling ) {
- const $target = $(event.target);
- // our target shouldn't be .app-icons or .close
- const $parent = $target.parents('.case-wrapper');
- if ( $parent.length == 0 )
- clearWiggle();
- }
- });
- // end wiggle
- },
-
- open_module: function(parent) {
- var link = parent.attr("data-link");
- if(link) {
- if(link.indexOf('javascript:')===0) {
- eval(link.substr(11));
- } else if(link.substr(0, 1)==="/" || link.substr(0, 4)==="http") {
- window.open(link, "_blank");
- } else {
- frappe.set_route(link);
- }
- return false;
- } else {
- var module = frappe.get_module(parent.attr("data-name"));
- if (module && module.onclick) {
- module.onclick();
- return false;
- }
- }
- },
-
- make_sortable: function() {
- if (frappe.dom.is_touchscreen() || frappe.list_desktop) {
- return;
- }
-
- new Sortable($("#icon-grid").get(0), {
- animation: 150,
- onUpdate: function(event) {
- var new_order = [];
- $("#icon-grid .case-wrapper").each(function(i, e) {
- new_order.push($(this).attr("data-name"));
- });
-
- frappe.call({
- method: 'frappe.desk.doctype.desktop_icon.desktop_icon.set_order',
- args: {
- 'new_order': new_order,
- 'user': frappe.session.user
- },
- quiet: true
- });
- }
- });
- },
-
- set_background: function() {
- frappe.ui.set_user_background(frappe.boot.user.background_image, null,
- frappe.boot.user.background_style);
- },
-
- show_pending_notifications: function() {
- var modules_list = frappe.get_desktop_icons();
- for (var i=0, l=modules_list.length; i < l; i++) {
- var module = modules_list[i];
-
- var module_doctypes = frappe.boot.notification_info.module_doctypes[module.module_name];
-
- var sum = 0;
-
- if(module_doctypes && frappe.boot.notification_info.open_count_doctype) {
- // sum all doctypes for a module
- for (var j=0, k=module_doctypes.length; j < k; j++) {
- var doctype = module_doctypes[j];
- let count = (frappe.boot.notification_info.open_count_doctype[doctype] || 0);
- count = typeof count == "string" ? parseInt(count) : count;
- sum += count;
- }
- }
-
- if(frappe.boot.notification_info.open_count_doctype
- && frappe.boot.notification_info.open_count_doctype[module.module_name]!=null) {
- // notification count explicitly for doctype
- let count = frappe.boot.notification_info.open_count_doctype[module.module_name] || 0;
- count = typeof count == "string" ? parseInt(count) : count;
- sum += count;
- }
-
- if(frappe.boot.notification_info.open_count_module
- && frappe.boot.notification_info.open_count_module[module.module_name]!=null) {
- // notification count explicitly for module
- let count = frappe.boot.notification_info.open_count_module[module.module_name] || 0;
- count = typeof count == "string" ? parseInt(count) : count;
- sum += count;
- }
-
- // if module found
- if(module._id.indexOf('/')===-1 && !module._report) {
- var notifier = $(".module-count-" + frappe.scrub(module._id));
- if(notifier.length) {
- notifier.toggle(sum ? true : false);
- var circle = notifier.find(".circle-text");
- var text = sum || '';
- if(text > 99) {
- text = '99+';
- }
-
- if(circle.length) {
- circle.html(text);
- } else {
- notifier.html(text);
- }
- }
- }
- }
- }
-});
+frappe.pages['desktop'].on_page_load = function() {};
\ No newline at end of file
diff --git a/frappe/core/page/desktop/desktop.json b/frappe/core/page/desktop/desktop.json
index 6255e3e6fe..66bbfbfd40 100644
--- a/frappe/core/page/desktop/desktop.json
+++ b/frappe/core/page/desktop/desktop.json
@@ -1,10 +1,11 @@
{
- "creation": "2013-02-14 17:37:37.000000",
+ "content": null,
+ "creation": "2019-01-29 13:11:48.872579",
"docstatus": 0,
"doctype": "Page",
- "icon": "fa fa-th",
- "idx": 1,
- "modified": "2013-07-11 14:41:56.000000",
+ "icon": "icon-th",
+ "idx": 0,
+ "modified": "2019-01-29 13:11:48.872579",
"modified_by": "Administrator",
"module": "Core",
"name": "desktop",
@@ -15,6 +16,9 @@
"role": "All"
}
],
+ "script": null,
"standard": "Yes",
+ "style": null,
+ "system_page": 0,
"title": "Desktop"
}
\ No newline at end of file
diff --git a/frappe/core/page/desktop/desktop.py b/frappe/core/page/desktop/desktop.py
deleted file mode 100644
index f426a67979..0000000000
--- a/frappe/core/page/desktop/desktop.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from __future__ import unicode_literals
-
-import functools
-import frappe
-from past.builtins import cmp
-
-@frappe.whitelist()
-def get_help_messages():
- '''Return help messages for the desktop (called via `get_help_messages` hook)
-
- Format for message:
-
- {
- title: _('Add Employees to Manage Them'),
- description: _('Add your Employees so you can manage leaves, expenses and payroll'),
- action: 'Add Employee',
- route: 'List/Employee'
- }
-
- '''
- messages = []
- for fn in frappe.get_hooks('get_help_messages'):
- messages += frappe.get_attr(fn)()
-
- return sorted(messages, key = functools.cmp_to_key(lambda a, b: cmp(a.get('count'), b.get('count'))))
diff --git a/frappe/core/page/desktop/desktop_help_message.html b/frappe/core/page/desktop/desktop_help_message.html
deleted file mode 100644
index 7de47abf03..0000000000
--- a/frappe/core/page/desktop/desktop_help_message.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{{ title }}
-{{ description }}
-
\ No newline at end of file
diff --git a/frappe/core/page/desktop/desktop_icon_grid.html b/frappe/core/page/desktop/desktop_icon_grid.html
deleted file mode 100644
index 6b85c8a56e..0000000000
--- a/frappe/core/page/desktop/desktop_icon_grid.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
- {% for (var i=0, l=desktop_items.length; i < l; i++) { %}
- {{ frappe.render_template("desktop_module_icon", desktop_items[i]) }}
- {% } %}
-
-
-
-
diff --git a/frappe/core/page/desktop/desktop_list_view.html b/frappe/core/page/desktop/desktop_list_view.html
deleted file mode 100644
index d3dd514076..0000000000
--- a/frappe/core/page/desktop/desktop_list_view.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
- {% for (var i=0, l=desktop_items.length; i < l; i++) {
- var module = desktop_items[i];
- %}
-
-
-
- {{ module._label }}
-
-
-
- {% } %}
-
-
-
-
diff --git a/frappe/core/page/desktop/desktop_module_icon.html b/frappe/core/page/desktop/desktop_module_icon.html
deleted file mode 100644
index 3e9a451eec..0000000000
--- a/frappe/core/page/desktop/desktop_module_icon.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/frappe/desk/doctype/desktop_icon/desktop_icon.json b/frappe/desk/doctype/desktop_icon/desktop_icon.json
index ee9765e944..59c95953ad 100644
--- a/frappe/desk/doctype/desktop_icon/desktop_icon.json
+++ b/frappe/desk/doctype/desktop_icon/desktop_icon.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -14,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -40,10 +42,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -70,10 +74,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -100,10 +106,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -130,10 +138,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -159,10 +169,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -189,10 +201,76 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "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": "Description",
+ "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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "category",
+ "fieldtype": "Data",
+ "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": "Category",
+ "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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -219,10 +297,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -249,10 +329,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -279,10 +361,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -308,10 +392,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -339,10 +425,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -370,10 +458,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -401,10 +491,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -431,10 +523,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -460,10 +554,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -490,10 +586,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -520,10 +618,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -550,10 +650,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -580,6 +682,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -593,7 +696,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-05-08 15:41:31.121652",
+ "modified": "2019-01-24 04:58:58.720618",
"modified_by": "Administrator",
"module": "Desk",
"name": "Desktop Icon",
@@ -602,7 +705,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -629,5 +731,6 @@
"sort_order": "DESC",
"title_field": "module_name",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/frappe/desk/doctype/desktop_icon/desktop_icon.py b/frappe/desk/doctype/desktop_icon/desktop_icon.py
index 175d1ece7d..fcf10ef61d 100644
--- a/frappe/desk/doctype/desktop_icon/desktop_icon.py
+++ b/frappe/desk/doctype/desktop_icon/desktop_icon.py
@@ -31,7 +31,7 @@ def get_desktop_icons(user=None):
user_icons = frappe.cache().hget('desktop_icons', user)
if not user_icons:
- fields = ['module_name', 'hidden', 'label', 'link', 'type', 'icon', 'color',
+ fields = ['module_name', 'hidden', 'label', 'link', 'type', 'icon', 'color', 'description', 'category',
'_doctype', '_report', 'idx', 'force_show', 'reverse', 'custom', 'standard', 'blocked']
active_domains = frappe.get_active_domains()
diff --git a/frappe/desk/moduleview.py b/frappe/desk/moduleview.py
index f5a1e47bf4..b90d6584a5 100644
--- a/frappe/desk/moduleview.py
+++ b/frappe/desk/moduleview.py
@@ -24,7 +24,7 @@ def hide_module(module):
set_hidden(module, frappe.session.user, 1)
clear_desktop_icons_cache()
-def get_data(module):
+def get_data(module, build=True):
"""Get module data for the module view `desk/#Module/[name]`"""
doctype_info = get_doctype_info(module)
data = build_config_from_file(module)
@@ -42,6 +42,43 @@ def get_data(module):
#set_last_modified(data)
+
+ if build:
+ exists_cache = {}
+ def exists(name):
+ exists = exists_cache.get(name)
+ if not exists:
+ if not frappe.db.get_value('DocType', name, 'issingle'):
+ exists = frappe.db.count(name)
+ else:
+ exists = True
+ exists_cache[name] = exists
+ return exists
+
+ for section in data:
+ for item in section["items"]:
+ # Onboarding
+
+ # First disable based on exists of depends_on list
+ doctype = item.get("doctype")
+ dependencies = item.get("dependencies") or None
+ if not dependencies and doctype:
+ item["dependencies"] = [doctype]
+
+ dependencies = item.get("dependencies")
+ if dependencies:
+ incomplete_dependencies = [d for d in dependencies if not exists(d)]
+ if len(incomplete_dependencies):
+ item["incomplete_dependencies"] = incomplete_dependencies
+
+ if item.get("onboard"):
+ # Mark Spotlights for initial
+ if item.get("type") == "doctype":
+ name = item.get("name")
+ count = exists(name)
+
+ item["count"] = count
+
return data
def build_config_from_file(module):
diff --git a/frappe/desk/page/modules/__init__.py b/frappe/desk/page/modules/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/frappe/desk/page/modules/modules.js b/frappe/desk/page/modules/modules.js
deleted file mode 100644
index 80048fbf59..0000000000
--- a/frappe/desk/page/modules/modules.js
+++ /dev/null
@@ -1,185 +0,0 @@
-frappe.pages['modules'].on_page_load = function(wrapper) {
- var page = frappe.ui.make_app_page({
- parent: wrapper,
- title: 'Modules',
- single_column: false
- });
-
- frappe.modules_page = page;
- frappe.module_links = {};
- page.section_data = {};
-
- page.wrapper.find('.page-head h1').css({'padding-left': '15px'});
- // page.wrapper.find('.page-content').css({'margin-top': '0px'});
-
- // menu
- page.add_menu_item(__('Set Desktop Icons'), function() {
- frappe.frappe_toolbar.modules_select
- .show(frappe.session.user);
- });
-
- if(frappe.user.has_role('System Manager')) {
- page.add_menu_item(__('Install Apps'), function() {
- frappe.set_route("applications");
- });
- }
-
- page.get_page_modules = () => {
- return frappe.get_desktop_icons(true)
- .filter(d => d.type==='module' && !d.blocked)
- .sort((a, b) => { return (a._label > b._label) ? 1 : -1; });
- };
-
- let get_module_sidebar_item = (item) => ``;
-
- let get_sidebar_html = () => {
- let sidebar_items_html = page.get_page_modules()
- .map(get_module_sidebar_item.bind(this)).join("");
-
- return ``;
- };
-
- // render sidebar
- page.sidebar.html(get_sidebar_html());
-
- // help click
- page.main.on("click", '.module-section-link[data-type="help"]', function() {
- frappe.help.show_video($(this).attr("data-youtube-id"));
- return false;
- });
-
- // notifications click
- page.main.on("click", '.open-notification', function() {
- var doctype = $(this).attr('data-doctype');
- if(doctype) {
- frappe.ui.notifications.show_open_count_list(doctype);
- }
- });
-
- page.activate_link = function(link) {
- page.last_link = link;
- page.wrapper.find('.module-sidebar-item.active, .module-link.active').removeClass('active');
- $(link).addClass('active').parent().addClass("active");
- show_section($(link).attr('data-name'));
- };
-
- var show_section = function(module_name) {
- if (!module_name) return;
- if(module_name in page.section_data) {
- render_section(page.section_data[module_name]);
- } else {
- page.main.empty();
- return frappe.call({
- method: "frappe.desk.moduleview.get",
- args: {
- module: module_name
- },
- callback: function(r) {
- var m = frappe.get_module(module_name);
- m.data = r.message.data;
- process_data(module_name, m.data);
- page.section_data[module_name] = m;
- render_section(m);
- },
- freeze: true,
- });
- }
-
- };
-
- var render_section = function(m) {
- page.set_title(__(m.label));
- page.main.html(frappe.render_template('modules_section', m));
-
- // if(frappe.utils.is_xs() || frappe.utils.is_sm()) {
- // // call this after a timeout, becuase a refresh will set the page to the top
- // setTimeout(function() {
- // $(document).scrollTop($('.module-body').offset().top - 150);
- // }, 100);
- // }
-
- //setup_section_toggle();
- frappe.app.update_notification_count_in_modules();
- };
-
- var process_data = function(module_name, data) {
- frappe.module_links[module_name] = [];
- data.forEach(function(section) {
- section.items.forEach(function(item) {
- item.style = '';
- if(item.type==="doctype") {
- item.doctype = item.name;
-
- // map of doctypes that belong to a module
- frappe.module_links[module_name].push(item.name);
- }
- if(!item.route) {
- if(item.link) {
- item.route=strip(item.link, "#");
- }
- else if(item.type==="doctype") {
- if(frappe.model.is_single(item.doctype)) {
- item.route = 'Form/' + item.doctype;
- } else {
- if (item.filters) {
- frappe.route_options=item.filters;
- }
- item.route="List/" + item.doctype;
- //item.style = 'font-weight: 500;';
- }
- // item.style = 'font-weight: bold;';
- }
- else if(item.type==="report" && item.is_query_report) {
- item.route="query-report/" + item.name;
- }
- else if(item.type==="report") {
- item.route="List/" + item.doctype + "/Report/" + item.name;
- }
- else if(item.type==="page") {
- item.route=item.name;
- }
- }
-
- if(item.route_options) {
- item.route += "?" + $.map(item.route_options, function(value, key) {
- return encodeURIComponent(key) + "=" + encodeURIComponent(value); }).join('&');
- }
-
- if(item.type==="page" || item.type==="help" || item.type==="report" ||
- (item.doctype && frappe.model.can_read(item.doctype))) {
- item.shown = true;
- }
- });
- });
- };
-};
-
-frappe.pages['modules'].on_page_show = function(wrapper) {
- let route = frappe.get_route();
- let modules = frappe.modules_page.get_page_modules().map(d => d.module_name);
- $("body").attr("data-sidebar", 1);
- if(route.length > 1) {
- // activate section based on route
- let module_name = route[1];
- if(modules.includes(module_name)) {
- frappe.modules_page.activate_link(
- frappe.modules_page.sidebar.find('.module-link[data-name="'+ module_name +'"]'));
- } else {
- frappe.throw(__(`Module ${module_name} not found.`));
- }
- } else if(frappe.modules_page.last_link) {
- // open last link
- frappe.set_route('modules', frappe.modules_page.last_link.attr('data-name'));
- } else {
- // first time, open the first page
- frappe.modules_page.activate_link(frappe.modules_page.sidebar.find('.module-link:first'));
- }
-};
diff --git a/frappe/desk/page/modules/modules.json b/frappe/desk/page/modules/modules.json
deleted file mode 100644
index 1858a921b2..0000000000
--- a/frappe/desk/page/modules/modules.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "content": null,
- "creation": "2016-03-07 04:46:00.420330",
- "docstatus": 0,
- "doctype": "Page",
- "idx": 0,
- "modified": "2016-03-07 04:46:00.420330",
- "modified_by": "Administrator",
- "module": "Desk",
- "name": "modules",
- "owner": "Administrator",
- "page_name": "modules",
- "roles": [],
- "script": null,
- "standard": "Yes",
- "style": null,
- "title": "Modules"
-}
\ No newline at end of file
diff --git a/frappe/desk/page/modules/modules_section.html b/frappe/desk/page/modules/modules_section.html
deleted file mode 100644
index 5d23db795a..0000000000
--- a/frappe/desk/page/modules/modules_section.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-{% for (var i=0; i < data.length; i++) { var section = data[i]; %}
-{% if ((i % 2)===0) { %}
{% } %}
-
-
- {{ section.label }}
-
-
- {% for (var j=0; j < section.items.length; j++) {
- var item = section.items[j];
- if(item.shown) { %}
-
- {% } %}
- {% } %}
-
-
-{% if ((i % 2)===1 || i===data.length-1) { %}
{% } %}
-{% } %}
-
diff --git a/frappe/installer.py b/frappe/installer.py
index c4af23976f..792d8580e8 100755
--- a/frappe/installer.py
+++ b/frappe/installer.py
@@ -23,7 +23,7 @@ from frappe.database import setup_database
def install_db(root_login="root", root_password=None, db_name=None, source_sql=None,
admin_password=None, verbose=True, force=0, site_config=None, reinstall=False,
db_type=None):
-
+
if not db_type:
db_type = frappe.conf.db_type or 'mariadb'
@@ -158,9 +158,6 @@ def remove_app(app_name, dry_run=False, yes=False):
if not dry_run:
frappe.delete_doc("Module Def", module_name)
- # delete desktop icons
- frappe.db.sql('delete from `tabDesktop Icon` where app=%s', app_name)
-
remove_from_installed_apps(app_name)
if not dry_run:
diff --git a/frappe/patches.txt b/frappe/patches.txt
index c8623b78de..21f09f6f0f 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -145,11 +145,9 @@ frappe.patches.v6_16.feed_doc_owner
frappe.patches.v6_21.print_settings_repeat_header_footer
frappe.patches.v6_24.set_language_as_code
frappe.patches.v6_20x.update_insert_after
-finally:frappe.patches.v6_24.sync_desktop_icons
frappe.patches.v6_20x.set_allow_draft_for_print
frappe.patches.v6_20x.remove_roles_from_website_user
frappe.patches.v7_0.set_user_fullname
-frappe.patches.v7_0.desktop_icons_hidden_by_admin_as_blocked
frappe.patches.v7_0.add_communication_in_doc
frappe.patches.v7_0.update_send_after_in_bulk_email
execute:frappe.db.sql('''delete from `tabSingles` where doctype="Email Settings"''') # 2016-06-13
@@ -183,15 +181,11 @@ frappe.patches.v8_0.deprecate_integration_broker
frappe.patches.v8_0.update_gender_and_salutation
frappe.patches.v8_0.setup_email_inbox #2017-03-29
frappe.patches.v8_0.newsletter_childtable_migrate
-execute:frappe.db.sql("delete from `tabDesktop Icon` where module_name='Communication'")
-execute:frappe.db.sql("update `tabDesktop Icon` set type='list' where _doctype='Communication'")
-frappe.patches.v8_0.fix_non_english_desktop_icons # 2017-04-12
frappe.patches.v8_0.set_doctype_values_in_custom_role
frappe.patches.v8_0.install_new_build_system_requirements
frappe.patches.v8_0.set_currency_field_precision # 2017-05-09
frappe.patches.v8_0.rename_print_to_printing
frappe.patches.v7_1.disabled_print_settings_for_custom_print_format
-frappe.patches.v8_0.update_desktop_icons
execute:frappe.db.sql('update tabReport set module="Desk" where name="ToDo"')
frappe.patches.v8_1.enable_allow_error_traceback_in_system_settings
frappe.patches.v8_1.update_format_options_in_auto_email_report
@@ -236,3 +230,4 @@ frappe.patches.v11_0.fix_order_by_in_reports_json
execute:frappe.delete_doc('Page', 'applications', ignore_missing=True)
frappe.patches.v11_0.set_missing_creation_and_modified_value_for_user_permissions
frappe.patches.v12_0.set_primary_key_in_series
+execute:frappe.delete_doc("Page", "modules", ignore_missing=True)
diff --git a/frappe/patches/v6_24/sync_desktop_icons.py b/frappe/patches/v6_24/sync_desktop_icons.py
deleted file mode 100644
index 74f52e6056..0000000000
--- a/frappe/patches/v6_24/sync_desktop_icons.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from __future__ import unicode_literals
-import frappe, json
-
-from frappe.desk.doctype.desktop_icon.desktop_icon import sync_from_app, get_user_copy
-import frappe.defaults
-
-def execute():
- frappe.reload_doc('desk', 'doctype', 'desktop_icon')
-
- frappe.db.sql('delete from `tabDesktop Icon`')
-
- modules_list = []
- for app in frappe.get_installed_apps():
- modules_list += sync_from_app(app)
-
- # sync hidden modules
- hidden_modules = frappe.db.get_global('hidden_modules')
- if hidden_modules:
- for m in json.loads(hidden_modules):
- try:
- desktop_icon = frappe.get_doc('Desktop Icon', {'module_name': m, 'standard': 1, 'app': app})
- desktop_icon.db_set('hidden', 1)
- except frappe.DoesNotExistError:
- pass
-
- # sync user sort
- for user in frappe.get_all('User', filters={'user_type': 'System User'}):
- user_list = frappe.defaults.get_user_default('_user_desktop_items', user=user.name)
- if user_list:
- user_list = json.loads(user_list)
- for i, module_name in enumerate(user_list):
- try:
- desktop_icon = get_user_copy(module_name, user=user.name)
- desktop_icon.db_set('idx', i)
- except frappe.DoesNotExistError:
- pass
-
- # set remaining icons as hidden
- for module_name in list(set([m['module_name'] for m in modules_list]) - set(user_list)):
- try:
- desktop_icon = get_user_copy(module_name, user=user.name)
- desktop_icon.db_set('hidden', 1)
- except frappe.DoesNotExistError:
- pass
diff --git a/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py b/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py
deleted file mode 100644
index 496af17cd2..0000000000
--- a/frappe/patches/v7_0/desktop_icons_hidden_by_admin_as_blocked.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from __future__ import unicode_literals
-import frappe
-
-def execute():
- # all icons hidden in standard are "blocked"
- # this is for the use case where the admin wants to remove icon for everyone
-
- # in 7.0, icons may be hidden by default, but still can be shown to the user
- # e.g. Accounts, Stock etc, so we need a new property for blocked
-
- if frappe.db.table_exists('Desktop Icon'):
- frappe.db.sql('update `tabDesktop Icon` set blocked = 1 where standard=1 and hidden=1')
\ No newline at end of file
diff --git a/frappe/patches/v7_2/merge_knowledge_base.py b/frappe/patches/v7_2/merge_knowledge_base.py
index 81ff98230b..301d15e1dd 100644
--- a/frappe/patches/v7_2/merge_knowledge_base.py
+++ b/frappe/patches/v7_2/merge_knowledge_base.py
@@ -11,12 +11,6 @@ def execute():
update_routes(['Help Category', 'Help Article'])
remove_from_installed_apps('knowledge_base')
- # remove desktop icon
- desktop_icon_name = frappe.db.get_value('Desktop Icon',
- dict(module_name='Knowledge Base', type='module'))
- if desktop_icon_name:
- frappe.delete_doc('Desktop Icon', desktop_icon_name)
-
# remove module def
if frappe.db.exists('Module Def', 'Knowledge Base'):
frappe.delete_doc('Module Def', 'Knowledge Base')
diff --git a/frappe/patches/v8_0/fix_non_english_desktop_icons.py b/frappe/patches/v8_0/fix_non_english_desktop_icons.py
deleted file mode 100644
index b4389578ab..0000000000
--- a/frappe/patches/v8_0/fix_non_english_desktop_icons.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (c) 2017, Frappe and Contributors
-# License: GNU General Public License v3. See license.txt
-# -*- coding: utf-8 -*-
-
-from __future__ import unicode_literals
-import frappe
-from frappe.desk.doctype.desktop_icon.desktop_icon import clear_desktop_icons_cache
-
-def execute():
- frappe.db.sql("""
- update `tabDesktop Icon`
- set module_name=_doctype, label=_doctype
- where type = 'link' and _doctype != label and link like 'List/%'
- """)
\ No newline at end of file
diff --git a/frappe/patches/v8_0/setup_email_inbox.py b/frappe/patches/v8_0/setup_email_inbox.py
index 8cd8b28116..1bfe3b0b74 100644
--- a/frappe/patches/v8_0/setup_email_inbox.py
+++ b/frappe/patches/v8_0/setup_email_inbox.py
@@ -3,31 +3,18 @@ import frappe, json
from frappe.core.doctype.user.user import ask_pass_update, setup_user_email_inbox
def execute():
- """
+ """
depricate email inbox page if exists
remove desktop icon for email inbox page if exists
patch to remove Custom DocPerm for communication
+ add user inbox child table entry for existing email account in not exists
"""
if frappe.db.exists("Page", "email_inbox"):
frappe.delete_doc("Page", "email_inbox")
- desktop_icon = frappe.db.get_value("Desktop Icon", {
- "module_name": "Email",
- "type": "Page",
- "link": "email_inbox"
- })
-
- if desktop_icon:
- frappe.delete_doc("Desktop Icon", desktop_icon)
-
frappe.db.sql("""update `tabCustom DocPerm` set `write`=0, email=1 where parent='Communication'""")
- setup_inbox_from_email_account()
-
-def setup_inbox_from_email_account():
- """ add user inbox child table entry for existing email account in not exists """
-
frappe.reload_doc("core", "doctype", "user_email")
frappe.reload_doc("email", "doctype", "email_account")
@@ -36,4 +23,4 @@ def setup_inbox_from_email_account():
for email_account in email_accounts:
setup_user_email_inbox(email_account.get("name"), email_account.get("awaiting_password"),
- email_account.get("email_id"), email_account.get("enabled_outgoing"))
\ No newline at end of file
+ email_account.get("email_id"), email_account.get("enabled_outgoing"))
diff --git a/frappe/patches/v8_0/update_desktop_icons.py b/frappe/patches/v8_0/update_desktop_icons.py
deleted file mode 100644
index ea8527718b..0000000000
--- a/frappe/patches/v8_0/update_desktop_icons.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.utils import cstr
-
-def execute():
- """ update the desktop icons """
-
- frappe.reload_doc('desk', 'doctype', 'desktop_icon')
-
- icons = frappe.get_all("Desktop Icon", filters={ "type": "link" }, fields=["link", "name"])
-
- for icon in icons:
- # check if report exists
- icon_link = icon.get("link", "") or ""
- parts = icon_link.split("/")
- if not parts:
- continue
-
- report_name = parts[-1]
- if "report" in parts[0] and frappe.db.get_value("Report", report_name):
- frappe.db.sql(""" update `tabDesktop Icon` set _report='{report_name}'
- where name='{name}'""".format(report_name=report_name, name=icon.get("name")))
\ No newline at end of file
diff --git a/frappe/public/build.json b/frappe/public/build.json
index 6e8c8a97fc..adac42b164 100755
--- a/frappe/public/build.json
+++ b/frappe/public/build.json
@@ -133,6 +133,7 @@
"public/js/lib/Sortable.min.js",
"public/js/lib/jquery/jquery.hotkeys.js",
"public/js/lib/bootstrap.min.js",
+ "node_modules/vue/dist/vue.js",
"node_modules/moment/min/moment-with-locales.min.js",
"node_modules/moment-timezone/builds/moment-timezone-with-data.min.js",
"public/js/lib/socket.io.min.js",
@@ -229,7 +230,6 @@
"public/js/frappe/ui/toolbar/about.js",
"public/js/frappe/ui/toolbar/navbar.html",
"public/js/frappe/ui/toolbar/toolbar.js",
- "public/js/frappe/ui/toolbar/modules_select.js",
"public/js/frappe/ui/toolbar/notifications.js",
"public/js/frappe/views/communication.js",
"public/js/frappe/views/translation_manager.js",
@@ -381,5 +381,8 @@
],
"js/social.min.js": [
"public/js/frappe/social/social_home.js"
+ ],
+ "js/modules.min.js": [
+ "public/js/frappe/views/modules_home.js"
]
}
diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js
index 5313f64b41..a04e4eed4b 100644
--- a/frappe/public/js/frappe/desk.js
+++ b/frappe/public/js/frappe/desk.js
@@ -194,7 +194,7 @@ frappe.Application = Class.extend({
load_bootinfo: function() {
if(frappe.boot) {
frappe.modules = {};
- frappe.boot.desktop_icons.forEach(function(m) {
+ frappe.boot.allowed_modules.forEach(function(m) {
frappe.modules[m.module_name]=m;
});
frappe.model.sync(frappe.boot.docs);
@@ -264,9 +264,6 @@ frappe.Application = Class.extend({
$.extend(frappe.boot.notification_info, r.message);
$(document).trigger("notification-update");
- // update in module views
- me.update_notification_count_in_modules();
-
if(frappe.get_route()[0] != "messages") {
if(r.message.new_messages.length) {
frappe.utils.set_title_prefix("(" + r.message.new_messages.length + ")");
@@ -279,18 +276,6 @@ frappe.Application = Class.extend({
}
},
- update_notification_count_in_modules: function() {
- $.each(frappe.boot.notification_info.open_count_doctype, function(doctype, count) {
- if(count) {
- $('.open-notification.global[data-doctype="'+ doctype +'"]')
- .removeClass("hide").html(count > 99 ? "99+" : count);
- } else {
- $('.open-notification.global[data-doctype="'+ doctype +'"]')
- .addClass("hide");
- }
- });
- },
-
set_globals: function() {
frappe.session.user = frappe.boot.user.name;
frappe.session.user_email = frappe.boot.user.email;
@@ -591,86 +576,3 @@ frappe.get_module = function(m, default_module) {
return module;
};
-
-frappe.get_desktop_icons = function(show_hidden, show_global) {
- // filter valid icons
-
- // hidden == hidden from desktop
- // blocked == no view from modules either
-
- var out = [];
-
- var add_to_out = function(module) {
- module = frappe.get_module(module.module_name, module);
- module.app_icon = frappe.ui.app_icon.get_html(module);
- out.push(module);
- };
-
- var show_module = function(m) {
- var out = true;
- if(m.type==="page") {
- out = m.link in frappe.boot.page_info;
- } else if(m.force_show) {
- out = true;
- } else if(m._report) {
- out = m._report in frappe.boot.user.all_reports;
- } else if(m._doctype) {
- //out = frappe.model.can_read(m._doctype);
- out = frappe.boot.user.can_read.includes(m._doctype);
- } else {
- if(['Help', 'Settings'].includes(m.module_name)) {
- // no permissions necessary for learn
- out = true;
- } else if(m.module_name==='Setup' && frappe.user.has_role('System Manager')) {
- out = true;
- } else {
- out = frappe.boot.user.allow_modules.indexOf(m.module_name) !== -1;
- }
- }
- if(m.hidden && !show_hidden) {
- out = false;
- }
- if(m.blocked && !show_global) {
- out = false;
- }
- return out;
- };
-
- let m;
- for (var i=0, l=frappe.boot.desktop_icons.length; i < l; i++) {
- m = frappe.boot.desktop_icons[i];
- if ((['Setup', 'Core'].indexOf(m.module_name) === -1) && show_module(m)) {
- add_to_out(m);
- }
- }
-
- if(frappe.user_roles.includes('System Manager')) {
- m = frappe.get_module('Setup');
- if(show_module(m)) add_to_out(m);
- }
-
- if(frappe.user_roles.includes('Administrator')) {
- m = frappe.get_module('Core');
- if(show_module(m)) add_to_out(m);
- }
-
- return out;
-};
-
-frappe.add_to_desktop = function(label, doctype, report) {
- frappe.call({
- method: 'frappe.desk.doctype.desktop_icon.desktop_icon.add_user_icon',
- args: {
- 'link': frappe.get_route_str(),
- 'label': label,
- 'type': 'link',
- '_doctype': doctype,
- '_report': report
- },
- callback: function(r) {
- if(r.message) {
- frappe.show_alert(__("Added"));
- }
- }
- });
-};
diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js
index 99d913f1cd..44898c3b5e 100644
--- a/frappe/public/js/frappe/form/toolbar.js
+++ b/frappe/public/js/frappe/form/toolbar.js
@@ -153,13 +153,6 @@ frappe.ui.form.Toolbar = Class.extend({
this.page.add_menu_item(__("Reload"), function() {
me.frm.reload_doc();}, true);
- // add to desktop
- if(me.frm.meta.issingle) {
- this.page.add_menu_item(__('Add to Desktop'), function () {
- frappe.add_to_desktop(me.frm.doctype, me.frm.doctype);
- }, true);
- }
-
// delete
if((cint(me.frm.doc.docstatus) != 1) && !me.frm.doc.__islocal
&& frappe.model.can_delete(me.frm.doctype)) {
diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js
index 6052baa6c4..9d47f283c8 100644
--- a/frappe/public/js/frappe/list/list_view.js
+++ b/frappe/public/js/frappe/list/list_view.js
@@ -1008,13 +1008,6 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
standard: true
});
- // add to desktop
- items.push({
- label: __('Add to Desktop'),
- action: () => frappe.add_to_desktop(doctype, doctype),
- standard: true
- });
-
if (frappe.user.has_role('System Manager') && frappe.boot.developer_mode === 1) {
// edit doctype
items.push({
diff --git a/frappe/public/js/frappe/misc/user.js b/frappe/public/js/frappe/misc/user.js
index 4b6b52bea9..15e91a82c5 100644
--- a/frappe/public/js/frappe/misc/user.js
+++ b/frappe/public/js/frappe/misc/user.js
@@ -74,7 +74,7 @@ $.extend(frappe.user, {
},
get_desktop_items: function() {
// hide based on permission
- var modules_list = $.map(frappe.boot.desktop_icons, function(icon) {
+ var modules_list = $.map(frappe.boot.allowed_modules, function(icon) {
var m = icon.module_name;
var type = frappe.modules[m] && frappe.modules[m].type;
@@ -105,14 +105,6 @@ $.extend(frappe.user, {
return modules_list;
},
- is_module: function(m) {
- var icons = frappe.get_desktop_icons();
- for(var i=0; i' + frappe._('Usage Info') + '');
+ help_links.push('' + frappe._('Usage Info') + '');
help_links.push('');
$(help_links.join("\n")).insertBefore($("#toolbar-user").find("li:first"));
}
diff --git a/frappe/public/js/frappe/ui/toolbar/modules_select.js b/frappe/public/js/frappe/ui/toolbar/modules_select.js
deleted file mode 100644
index 1b41141c9b..0000000000
--- a/frappe/public/js/frappe/ui/toolbar/modules_select.js
+++ /dev/null
@@ -1,108 +0,0 @@
-frappe.provide('frappe.ui.toolbar');
-
-frappe.ui.toolbar.ModulesSelect = class {
- constructor() {
- this.user = frappe.boot.user.name;
- this.setup();
- }
-
- setup() {
- this.dialog = new frappe.ui.Dialog({
- title: __('Set Desktop Icons'),
- fields: [
- {
- label: __('Setup for'),
- fieldname: 'setup_for',
- fieldtype: 'Select',
- options: [
- {label: __('User'), value: 'user'},
- {label: __('Everyone'), value: 'everyone'}
- ],
- default: 'user',
- onchange: () => {
- let field = this.$setup_for;
- if(field.get_value() === 'everyone') {
- this.$user.$wrapper.hide();
- this.user = undefined;
- field.set_description(__('Limit icon choices for all users.'));
- } else {
- this.$user.$wrapper.show();
- this.user = this.$user.get_value();
- field.set_description('');
- }
- this.$icons_list.refresh();
- }
- },
- { fieldtype: 'Column Break' },
- {
- label: __('User'),
- fieldname: 'user',
- fieldtype: 'Link',
- options: 'User',
- default: frappe.boot.user.name,
- onchange: () => {
- this.user = this.get_value() || frappe.boot.user.name;
- this.$icons_list.refresh();
- }
- },
- { fieldtype: 'Section Break' },
- {
- // label: __('Icons'),
- fieldname: 'icons',
- fieldtype: 'MultiCheck',
- select_all: 1,
- columns: 2,
- get_data: () => {
- return new Promise((resolve) => {
- frappe.call({
- method: 'frappe.desk.doctype.desktop_icon.desktop_icon.get_module_icons',
- args: {user: this.user},
- freeze: true,
- callback: (r) => {
- const icons = r.message.icons;
- const user = r.message.user;
- resolve(icons
- .map(icon => {
- const uncheck = user ? icon.hidden : icon.blocked;
- return { label: icon.label, value: icon.module_name, checked:!uncheck };
- }).sort(function(a, b){
- if(a.label < b.label) return -1;
- if(a.label > b.label) return 1;
- return 0;
- })
- );
- }
- });
- });
- }
- }
- ]
- });
-
- this.dialog.set_primary_action(__('Save'), () => {
- frappe.call({
- method: 'frappe.desk.doctype.desktop_icon.desktop_icon.update_icons',
- args: {
- hidden_list: this.$icons_list.get_unchecked_options(),
- user: this.user
- },
- freeze: true,
- callback: () => {
- window.location.href = '';
- }
- });
- });
-
- this.$icons_list = this.dialog.fields_dict.icons;
- this.$setup_for = this.dialog.fields_dict.setup_for;
- this.$user = this.dialog.fields_dict.user;
- }
-
- show(user) {
- if(user) {
- this.user = user || frappe.boot.user.name;
- this.$icons_list.refresh();
- }
- this.dialog.show();
- }
-};
\ No newline at end of file
diff --git a/frappe/public/js/frappe/ui/toolbar/navbar.html b/frappe/public/js/frappe/ui/toolbar/navbar.html
index 729365f53a..ea6691a7a3 100644
--- a/frappe/public/js/frappe/ui/toolbar/navbar.html
+++ b/frappe/public/js/frappe/ui/toolbar/navbar.html
@@ -24,8 +24,6 @@
{%= frappe.user.full_name() %}