Merge pull request #7928 from netchampfaris/feat-desktop-cards-reorder

feat: Re-arrange cards on Desktop
This commit is contained in:
mergify[bot] 2019-07-19 09:19:48 +00:00 committed by GitHub
commit dff5cab5ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 229 additions and 103 deletions

View file

@ -287,44 +287,141 @@ def get_onboard_items(app, module):
return onboard_items or fallback_items
@frappe.whitelist()
def get_links_for_module(app, module):
return [l.get('label') for l in get_links(app, module)]
def get_links(app, module):
try:
sections = get_config(app, frappe.scrub(module))
except ImportError:
return []
link_names = []
links = []
for section in sections:
for item in section["items"]:
link_names.append(item.get("label"))
return link_names
for item in section['items']:
links.append(item)
return links
@frappe.whitelist()
def hide_modules_from_desktop(modules):
def get_desktop_settings():
from frappe.config import get_modules_from_all_apps_for_user
all_modules = get_modules_from_all_apps_for_user()
home_settings = get_home_settings()
modules_by_name = {}
for m in all_modules:
modules_by_name[m['module_name']] = m
module_categories = ['Modules', 'Domains', 'Places', 'Administration']
user_modules_by_category = {}
user_saved_modules_by_category = home_settings.modules_by_category or {}
user_saved_links_by_module = home_settings.links_by_module or {}
def apply_user_saved_links(module):
module = frappe._dict(module)
all_links = get_links(module.app, module.module_name)
module_links_by_label = {}
for link in all_links:
module_links_by_label[link['label']] = link
if module.module_name in user_saved_links_by_module:
user_links = frappe.parse_json(user_saved_links_by_module[module.module_name])
module.links = [module_links_by_label[l] for l in user_links if l in module_links_by_label]
return module
for category in module_categories:
if category in user_saved_modules_by_category:
user_modules = user_saved_modules_by_category[category]
user_modules_by_category[category] = [apply_user_saved_links(modules_by_name[m]) \
for m in user_modules]
else:
user_modules_by_category[category] = [apply_user_saved_links(m) \
for m in all_modules if m['category'] == category]
# filter out hidden modules
if home_settings.hidden_modules:
for category in user_modules_by_category:
hidden_modules = home_settings.hidden_modules or []
modules = user_modules_by_category[category]
user_modules_by_category[category] = [module for module in modules if module.module_name not in hidden_modules]
return user_modules_by_category
@frappe.whitelist()
def update_hidden_modules(category_map):
category_map = frappe.parse_json(category_map)
home_settings = get_home_settings()
saved_hidden_modules = home_settings.hidden_modules or []
for category in category_map:
config = frappe._dict(category_map[category])
saved_hidden_modules += config.removed or []
saved_hidden_modules = [d for d in saved_hidden_modules if d not in (config.added or [])]
home_settings.hidden_modules = saved_hidden_modules
set_home_settings(home_settings)
return get_desktop_settings()
@frappe.whitelist()
def update_modules_order(module_category, modules):
modules = frappe.parse_json(modules)
home_settings = frappe.db.get_value("User", frappe.session.user, 'home_settings')
home_settings = frappe.parse_json(home_settings or '{}')
home_settings['hidden_modules'] = modules
frappe.db.set_value('User', frappe.session.user, 'home_settings', json.dumps(home_settings))
return home_settings
home_settings = get_home_settings()
home_settings.modules_by_category = home_settings.modules_by_category or {}
home_settings.modules_by_category[module_category] = modules
set_home_settings(home_settings)
@frappe.whitelist()
def update_links_for_module(module_name, links):
home_settings = frappe.db.get_value("User", frappe.session.user, 'home_settings')
home_settings = frappe.parse_json(home_settings or '{}')
links = frappe.parse_json(links)
home_settings = get_home_settings()
home_settings.setdefault('links', {})
home_settings['links'].setdefault(module_name, None)
home_settings['links'][module_name] = links
home_settings.setdefault('links_by_module', {})
home_settings['links_by_module'].setdefault(module_name, None)
home_settings['links_by_module'][module_name] = links
set_home_settings(home_settings)
return get_desktop_settings()
@frappe.whitelist()
def get_options_for_show_hide_cards():
from frappe.config import get_modules_from_all_apps_for_user
all_modules = get_modules_from_all_apps_for_user()
home_settings = get_home_settings()
hidden_modules = home_settings.hidden_modules or []
options = []
for module in all_modules:
module = frappe._dict(module)
options.append({
'category': module.category,
'label': module.label,
'value': module.module_name,
'checked': module.module_name not in hidden_modules
})
return options
def set_home_settings(home_settings):
frappe.cache().hset('home_settings', frappe.session.user, home_settings)
frappe.db.set_value('User', frappe.session.user, 'home_settings', json.dumps(home_settings))
@frappe.whitelist()
def get_home_settings():
def get_from_db():
settings = frappe.db.get_value("User", frappe.session.user, 'home_settings')
return frappe.parse_json(settings or '{}')
home_settings = frappe.cache().hget('home_settings', frappe.session.user, get_from_db)
return home_settings

View file

@ -237,7 +237,7 @@ frappe.patches.v12_0.set_primary_key_in_series
execute:frappe.delete_doc("Page", "modules", ignore_missing=True)
frappe.patches.v11_0.set_default_letter_head_source
frappe.patches.v12_0.setup_comments_from_communications
frappe.patches.v12_0.init_desk_settings #11-03-2019
frappe.patches.v12_0.init_desk_settings #16-05-2019
frappe.patches.v12_0.replace_null_values_in_tables
frappe.patches.v12_0.reset_home_settings
frappe.patches.v12_0.update_print_format_type

View file

@ -8,4 +8,4 @@ from frappe.desk.moduleview import get_onboard_items
def execute():
"""Reset the initial customizations for desk, with modules, indices and links."""
frappe.reload_doc("core", "doctype", "user")
frappe.db.sql("""update `tabUser` set home_settings = %s""", (''), debug=True)
frappe.db.sql("""update tabUser set home_settings = ''""")

View file

@ -3,6 +3,7 @@
v-if="!hidden"
class="border module-box"
:class="{ 'hovered-box': hovered }"
:data-module-name="module_name"
>
<div class="flush-top">
<div class="module-box-content">
@ -10,7 +11,7 @@
<a class="module-box-link" :href="type === 'module' ? '#modules/' + module_name : link">
<h4 class="h4">
<div>
<i :class="iconClass" style="color:#8d99a6;font-size:18px;margin-right:6px;"></i>
<i :class="icon_class" style="color:#8d99a6;font-size:18px;margin-right:6px;"></i>
{{ label }}
</div>
</h4>
@ -54,7 +55,7 @@ export default {
};
},
computed: {
iconClass() {
icon_class() {
if (this.icon) {
return this.icon;
} else {
@ -82,7 +83,12 @@ export default {
background-color: #ffffff;
}
.module-box:hover {
.module-box.sortable-chosen {
background-color: @disabled-background;
border-color: @disabled-background;
}
.modules-container:not(.dragging) .module-box:hover {
border-color: @text-muted;
}

View file

@ -4,10 +4,10 @@
<div class="module-category h6 uppercase">{{ category }}</div>
</div>
<div class="modules-container">
<div class="modules-container" :class="{'dragging': dragging}" ref="modules-container">
<desk-module-box
v-for="(module, index) in modules"
:key="module.name"
:key="module.module_name"
:index="index"
v-bind="module"
@customize="show_module_card_customize_dialog(module)"
@ -24,7 +24,32 @@ export default {
components: {
DeskModuleBox
},
data() {
return {
dragging: false
}
},
mounted() {
this.setup_sortable();
},
methods: {
setup_sortable() {
let modules_container =this.$refs['modules-container'];
this.sortable = new Sortable(modules_container, {
animation: 150,
onStart: () => this.dragging = true,
onEnd: () => {
this.dragging = false;
let modules = Array.from(modules_container.querySelectorAll('.module-box'))
.map(node => node.dataset.moduleName);
this.$emit('module-order-change', {
module_category: this.category,
modules
});
}
})
},
show_module_card_customize_dialog(module) {
const d = new frappe.ui.Dialog({
title: __('Customize Shortcuts'),
@ -34,7 +59,7 @@ export default {
fieldname: 'links',
fieldtype: 'MultiSelectPills',
get_data() {
return frappe.call('frappe.desk.moduleview.get_links', {
return frappe.call('frappe.desk.moduleview.get_links_for_module', {
app: module.app,
module: module.module_name,
}).then(r => r.message);
@ -48,7 +73,7 @@ export default {
module_name: module.module_name,
links
}).then(r => {
this.$emit('update_home_settings', r.message);
this.$emit('update-desktop-settings', r.message);
});
d.hide();
}

View file

@ -14,7 +14,8 @@
v-if="get_modules_for_category(category).length"
:category="category"
:modules="get_modules_for_category(category)"
@update_home_settings="hs => update_modules_with_home_settings(hs)"
@update-desktop-settings="update_desktop_settings"
@module-order-change="update_module_order"
>
</desk-section>
</div>
@ -30,99 +31,96 @@ export default {
DeskSection
},
data() {
let modules_list = frappe.boot.allowed_modules
.filter(d => (d.type==='module' || d.category==='Places') && !d.blocked)
.map(d => {
d.links = (d.links || []).map(link => {
link.route = generate_route(link);
return link;
});
return d;
});
return {
module_categories: ['Modules', 'Domains', 'Places', 'Administration'],
modules: modules_list,
modules: [],
home_settings_fetched: false
};
},
created() {
this.fetch_home_settings();
this.fetch_desktop_settings();
},
methods: {
fetch_home_settings() {
return frappe.db.get_value('User', user, 'home_settings')
fetch_desktop_settings() {
frappe.call('frappe.desk.moduleview.get_desktop_settings')
.then(r => {
let home_settings = JSON.parse(r.message.home_settings || '{}');
this.update_modules_with_home_settings(home_settings);
this.home_settings_fetched = true;
if (r.message) {
this.update_desktop_settings(r.message);
this.home_settings_fetched = true;
}
});
},
update_modules_with_home_settings(home_settings) {
this.modules = this.modules.map(m => {
let hidden_modules = home_settings.hidden_modules || [];
m.hidden = hidden_modules.includes(m.module_name);
let links = home_settings.links && home_settings.links[m.module_name];
if (links) {
links = JSON.parse(links);
let default_links = m.links.map(link => link.name);
m.links = m.links.map(link => {
link.hidden = !links.includes(link.name);
update_desktop_settings(desktop_settings) {
this.modules = this.add_routes_for_module_links(desktop_settings);
},
add_routes_for_module_links(user_settings) {
for (let category in user_settings) {
user_settings[category] = user_settings[category].map(m => {
m.links = (m.links || []).map(link => {
link.route = generate_route(link);
return link;
});
let new_links = links
.filter(link => !default_links.includes(link))
.filter(Boolean)
.map(link => {
let new_link = { name: link, label: link, type: 'doctype' };
new_link.route = generate_route(new_link);
return new_link;
});
m.links = m.links.concat(new_links);
}
return m;
});
return m;
});
}
return user_settings;
},
update_module_order({ module_category, modules }) {
frappe.call('frappe.desk.moduleview.update_modules_order', { module_category, modules });
},
get_modules_for_category(category) {
return this.modules.filter(m => m.category === category && !m.hidden);
return this.modules[category] || [];
},
show_hide_cards_dialog() {
let fields = this.module_categories.map(category => {
let modules = this.modules.filter(m => m.category === category);
let options = modules.map(
m => ({ label: m.label, value: m.module_name, checked: !m.hidden })
);
return {
label: category,
fieldname: category,
fieldtype: 'MultiCheck',
options,
columns: 2
}
});
const d = new frappe.ui.Dialog({
title: __('Show / Hide Cards'),
fields: fields.filter(f => f.options.length > 0),
primary_action_label: __('Save'),
primary_action: (values) => {
let all_modules = this.modules.map(m => m.module_name);
let modules_to_show = Object.keys(values).map(k => values[k]).flatMap(m => m);
let modules_to_hide = all_modules.filter(m => !modules_to_show.includes(m));
d.hide();
frappe.call('frappe.desk.moduleview.get_options_for_show_hide_cards')
.then(r => {
let module_options = r.message;
let fields = this.module_categories.map(category => {
let options = module_options.filter(m => m.category === category);
return {
label: category,
fieldname: category,
fieldtype: 'MultiCheck',
options,
columns: 2
}
}).filter(f => f.options.length > 0);
frappe.call('frappe.desk.moduleview.hide_modules_from_desktop', {
modules: modules_to_hide
})
.then(r => r.message)
.then(hs => this.update_modules_with_home_settings(hs));
}
});
let old_values = null;
d.show();
const d = new frappe.ui.Dialog({
title: __('Show / Hide Cards'),
fields: fields,
primary_action_label: __('Save'),
primary_action: (values) => {
let category_map = {};
for (let category of this.module_categories) {
let old_modules = old_values[category] || [];
let new_modules = values[category] || [];
let removed = old_modules.filter(module => !new_modules.includes(module));
let added = new_modules.filter(module => !old_modules.includes(module));
category_map[category] = { added, removed };
}
frappe.call({
method: 'frappe.desk.moduleview.update_hidden_modules',
args: { category_map },
btn: d.get_primary_btn()
}).then(r => {
this.update_desktop_settings(r.message)
d.hide();
});
}
});
d.show();
// deepcopy
old_values = JSON.parse(JSON.stringify(d.get_values()));
});
}
}
}