Merge branch 'rebrand-ui' of https://github.com/frappe/frappe into rebrand-ui
This commit is contained in:
commit
36d41bfc35
19 changed files with 1852 additions and 1069 deletions
|
|
@ -293,6 +293,7 @@
|
|||
"public/js/frappe/list/list_view.js",
|
||||
"public/js/frappe/list/list_factory.js",
|
||||
|
||||
"public/js/frappe/list/views.js",
|
||||
"public/js/frappe/list/list_sidebar.js",
|
||||
"public/js/frappe/list/list_sidebar.html",
|
||||
"public/js/frappe/list/list_sidebar_stat.html",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ frappe.views.BaseList = class BaseList {
|
|||
this.setup_side_bar,
|
||||
this.setup_main_section,
|
||||
this.setup_view,
|
||||
this.setup_view_menu,
|
||||
].map((fn) => fn.bind(this));
|
||||
|
||||
this.init_promise = frappe.run_serially(tasks);
|
||||
|
|
@ -164,9 +165,20 @@ frappe.views.BaseList = class BaseList {
|
|||
this.page.set_title(this.page_title);
|
||||
}
|
||||
|
||||
setup_view_menu() {
|
||||
this.views_menu = this.page.add_custom_button_group(__(`View as {0}`, [this.view_name]), 'list');
|
||||
this.views_list = new frappe.views.Views({
|
||||
doctype: this.doctype,
|
||||
parent: this.views_menu,
|
||||
page: this.page,
|
||||
list_view: this,
|
||||
sidebar: this.list_sidebar,
|
||||
});
|
||||
}
|
||||
|
||||
set_menu_items() {
|
||||
if (this.secondary_action) {
|
||||
const $secondary_action = this.page.set_secondary_action(
|
||||
const $secondary_action = this.page.set_secondary_action(
|
||||
this.secondary_action.label,
|
||||
this.secondary_action.action,
|
||||
this.secondary_action.icon
|
||||
|
|
@ -739,13 +751,13 @@ class FilterArea {
|
|||
// utility function to validate view modes
|
||||
frappe.views.view_modes = [
|
||||
"List",
|
||||
"Report",
|
||||
"Dashboard",
|
||||
"Gantt",
|
||||
"Kanban",
|
||||
"Calendar",
|
||||
"Image",
|
||||
"Inbox",
|
||||
"Report",
|
||||
"Dashboard",
|
||||
];
|
||||
frappe.views.is_valid = (view_mode) =>
|
||||
frappe.views.view_modes.includes(view_mode);
|
||||
|
|
|
|||
|
|
@ -1,96 +1,74 @@
|
|||
<ul class="list-unstyled sidebar-menu visible-sm visible-xs">
|
||||
<li>
|
||||
<a class="navbar-home" href="#">
|
||||
<img class="app-logo" src="{{ frappe.app.logo_url }}">
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu user-actions hide">
|
||||
<li class="divider"></li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu standard-actions">
|
||||
{% if frappe.model.can_get_report(doctype) %}
|
||||
<li class="list-sidebar-label">Views</li>
|
||||
<li class="divider visible-sm visible-xs"></li>
|
||||
<li class="list-link">
|
||||
<div class="btn-group">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#" onclick="return false;">
|
||||
{{ __("Reports") }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu reports-dropdown" role="menu">
|
||||
<li><a href="#List/{{ doctype }}/Report">{{ __("Report Builder") }}</a></li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu">
|
||||
<div class="sidebar-section views-section hide">
|
||||
<li class="list-sidebar-label">
|
||||
</li>
|
||||
<div class="current-view">
|
||||
<li class="list-link">
|
||||
<a class="btn btn-default btn-sm list-sidebar-button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
href="#"
|
||||
>
|
||||
<span class="text-muted selected-view">
|
||||
</span>
|
||||
<span>
|
||||
<svg class="icon icon-xs">
|
||||
<use xlink:href="#icon-select"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu views-dropdown" role="menu">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar-action">
|
||||
<a class="view-action"></a>
|
||||
</li>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="divider"></li>
|
||||
<li class="list-link" data-view="List">
|
||||
<a href="#List/{%= doctype %}/List">{%= __("List") %}</a></li>
|
||||
<li class="list-link" data-view="Dashboard">
|
||||
<a href="#List/{%= doctype %}/Dashboard">{%= __("Dashboard") %}</a></li>
|
||||
<li class="hide list-link" data-view="Image">
|
||||
<a href="#List/{%= doctype %}/Image">{%= __("Images") %}</a></li>
|
||||
<li class="hide list-link" data-view="Gantt">
|
||||
<a href="#List/{%= doctype %}/Gantt">{%= __("Gantt") %}</a></li>
|
||||
<li class="hide tree-link">
|
||||
<a href="#Tree/{%= doctype %}">{%= __("Tree") %}</a></li>
|
||||
<li class="hide list-link" data-view="Calendar">
|
||||
<a href="#List/{%= doctype %}/Calendar">{%= __("Calendar") %}</a></li>
|
||||
<li class="hide list-link" data-view="Kanban">
|
||||
<div class="btn-group">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#" onclick="return false;">
|
||||
{{ __("Kanban") }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu kanban-dropdown" style="max-height: 300px; overflow-y: auto;" role="menu">
|
||||
<li class="new-kanban-board"><a href="#" onclick="return false;">{{ __("New Kanban Board") }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section filter-section">
|
||||
<li class="list-sidebar-label">
|
||||
{{ __("Filter By") }}
|
||||
</li>
|
||||
|
||||
<div class="list-group-by">
|
||||
</div>
|
||||
</li>
|
||||
<li class="hide list-link" data-view="Inbox">
|
||||
<div class="btn-group">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#" onclick="return false;">
|
||||
{{ __("Email Inbox") }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu email-account-dropdown" style="max-height: 300px; overflow-y: auto;" role="menu">
|
||||
</ul>
|
||||
|
||||
<div class="list-tags">
|
||||
<li class="list-stats list-link">
|
||||
<a
|
||||
class="btn btn-default btn-sm list-sidebar-button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
href="#"
|
||||
>
|
||||
<span class="text-muted">{{ __("Tags") }}</span>
|
||||
<span>
|
||||
<svg class="icon icon-xs">
|
||||
<use xlink:href="#icon-select"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu list-stats-dropdown" role="menu">
|
||||
<div class="dropdown-search">
|
||||
<input type="text" placeholder="Search" data-element="search" class="form-control input-xs">
|
||||
</div>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar-action show-tags">
|
||||
<a class="list-tag-preview">{{ __("Show Tags") }}</a>
|
||||
</li>
|
||||
</div>
|
||||
</li>
|
||||
{% if(frappe.help.has_help(doctype)) { %}
|
||||
<li><a class="help-link list-link" data-doctype="{{ doctype }}">{{ __("Help") }}</a></li>
|
||||
{% } %}
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu list-group-by">
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<ul class="list-unstyled sidebar-menu sidebar-stat">
|
||||
<li class="list-sidebar-label stat-label">{{ __("Tags") }}</li>
|
||||
<li class="list-stats list-link">
|
||||
<div class="btn-group">
|
||||
<a class = "dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#" onclick="return false;">
|
||||
{{ __("Tags") }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu list-stats-dropdown" role="menu">
|
||||
<div class="dropdown-search">
|
||||
<input type="text" placeholder="Search" data-element="search" class="form-control input-xs">
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-link" style="margin-top: 10px;">
|
||||
<a class="list-tag-preview hidden-xs text-muted">{{ __("Show Tags") }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu charts-menu hide">
|
||||
<li class="h6">{%= __("Charts") %}</li>
|
||||
<li class="list-link">
|
||||
<a class="toggle-charts">{%= __("Toggle Charts") %}</a>
|
||||
</li>
|
||||
<li class="list-link">
|
||||
<a class="configure-charts hidden">{%= __("Configure Charts") %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu list-filters"></ul>
|
||||
<ul class="list-unstyled close-sidebar-button visible-xs visible-sm">
|
||||
<li class="divider"></li>
|
||||
<li class="close-sidebar">{{ __("Close") }}</li>
|
||||
</ul>
|
||||
<!-- {% if(frappe.help.has_help(doctype)) { %} -->
|
||||
<!-- <div class="sidebar-section help-section">
|
||||
<li><a class="help-link list-link" data-doctype="{{ doctype }}">{{ __("Help") }}</a></li>
|
||||
</div> -->
|
||||
<!-- {% } %} -->
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
import ListFilter from './list_filter';
|
||||
frappe.provide('frappe.views');
|
||||
|
||||
// opts:
|
||||
|
|
@ -23,13 +22,6 @@ frappe.views.ListSidebar = class ListSidebar {
|
|||
.html(sidebar_content)
|
||||
.appendTo(this.page.sidebar.empty());
|
||||
|
||||
this.setup_reports();
|
||||
this.setup_list_filter();
|
||||
this.setup_views();
|
||||
this.setup_kanban_boards();
|
||||
this.setup_calendar_view();
|
||||
this.setup_email_inbox();
|
||||
this.setup_keyboard_shortcuts();
|
||||
this.setup_list_group_by();
|
||||
|
||||
// do not remove
|
||||
|
|
@ -46,193 +38,6 @@ frappe.views.ListSidebar = class ListSidebar {
|
|||
|
||||
}
|
||||
|
||||
setup_views() {
|
||||
var show_list_link = false;
|
||||
|
||||
if (frappe.views.calendar[this.doctype]) {
|
||||
this.sidebar.find('.list-link[data-view="Calendar"]').removeClass("hide");
|
||||
this.sidebar.find('.list-link[data-view="Gantt"]').removeClass('hide');
|
||||
show_list_link = true;
|
||||
}
|
||||
//show link for kanban view
|
||||
this.sidebar.find('.list-link[data-view="Kanban"]').removeClass('hide');
|
||||
if (this.doctype === "Communication" && frappe.boot.email_accounts.length) {
|
||||
this.sidebar.find('.list-link[data-view="Inbox"]').removeClass('hide');
|
||||
show_list_link = true;
|
||||
}
|
||||
|
||||
if (frappe.treeview_settings[this.doctype] || frappe.get_meta(this.doctype).is_tree) {
|
||||
this.sidebar.find(".tree-link").removeClass("hide");
|
||||
}
|
||||
|
||||
this.current_view = 'List';
|
||||
var route = frappe.get_route();
|
||||
if (route.length > 2 && frappe.views.view_modes.includes(route[2])) {
|
||||
this.current_view = route[2];
|
||||
|
||||
if (this.current_view === 'Kanban') {
|
||||
this.kanban_board = route[3];
|
||||
} else if (this.current_view === 'Inbox') {
|
||||
this.email_account = route[3];
|
||||
}
|
||||
}
|
||||
|
||||
// disable link for current view
|
||||
this.sidebar.find('.list-link[data-view="' + this.current_view + '"] a')
|
||||
.attr('disabled', 'disabled').addClass('disabled');
|
||||
|
||||
//enable link for Kanban view
|
||||
this.sidebar.find('.list-link[data-view="Kanban"] a, .list-link[data-view="Inbox"] a')
|
||||
.attr('disabled', null).removeClass('disabled');
|
||||
|
||||
// show image link if image_view
|
||||
if (this.list_view.meta.image_field) {
|
||||
this.sidebar.find('.list-link[data-view="Image"]').removeClass('hide');
|
||||
show_list_link = true;
|
||||
}
|
||||
|
||||
if (show_list_link) {
|
||||
this.sidebar.find('.list-link[data-view="List"]').removeClass('hide');
|
||||
}
|
||||
}
|
||||
|
||||
setup_reports() {
|
||||
// add reports linked to this doctype to the dropdown
|
||||
var me = this;
|
||||
var added = [];
|
||||
var dropdown = this.page.sidebar.find('.reports-dropdown');
|
||||
var divider = false;
|
||||
|
||||
var add_reports = function(reports) {
|
||||
$.each(reports, function(name, r) {
|
||||
if (!r.ref_doctype || r.ref_doctype == me.doctype) {
|
||||
var report_type = r.report_type === 'Report Builder' ?
|
||||
`List/${r.ref_doctype}/Report` : 'query-report';
|
||||
|
||||
var route = r.route || report_type + '/' + (r.title || r.name);
|
||||
|
||||
if (added.indexOf(route) === -1) {
|
||||
// don't repeat
|
||||
added.push(route);
|
||||
|
||||
if (!divider) {
|
||||
me.get_divider().appendTo(dropdown);
|
||||
divider = true;
|
||||
}
|
||||
|
||||
$('<li><a href="#' + route + '">' +
|
||||
__(r.title || r.name) + '</a></li>').appendTo(dropdown);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// from reference doctype
|
||||
if (this.list_view.settings.reports) {
|
||||
add_reports(this.list_view.settings.reports);
|
||||
}
|
||||
|
||||
// Sort reports alphabetically
|
||||
var reports = Object.values(frappe.boot.user.all_reports).sort((a,b) => a.title.localeCompare(b.title)) || [];
|
||||
|
||||
// from specially tagged reports
|
||||
add_reports(reports);
|
||||
}
|
||||
|
||||
setup_list_filter() {
|
||||
this.list_filter = new ListFilter({
|
||||
wrapper: this.page.sidebar.find('.list-filters'),
|
||||
doctype: this.doctype,
|
||||
list_view: this.list_view
|
||||
});
|
||||
}
|
||||
|
||||
setup_kanban_boards() {
|
||||
const $dropdown = this.page.sidebar.find('.kanban-dropdown');
|
||||
frappe.views.KanbanView.setup_dropdown_in_sidebar(this.doctype, $dropdown);
|
||||
}
|
||||
|
||||
setup_calendar_view() {
|
||||
const doctype = this.doctype;
|
||||
|
||||
frappe.db.get_list('Calendar View', {
|
||||
filters: {
|
||||
reference_doctype: doctype
|
||||
}
|
||||
}).then(result => {
|
||||
if (!(result && Array.isArray(result) && result.length)) return;
|
||||
const calendar_views = result;
|
||||
const $link_calendar = this.sidebar.find('.list-link[data-view="Calendar"]');
|
||||
|
||||
let default_link = '';
|
||||
if (frappe.views.calendar[this.doctype]) {
|
||||
// has standard calendar view
|
||||
default_link = `<li><a href="#List/${doctype}/Calendar/Default">
|
||||
${ __("Default") }</a></li>`;
|
||||
}
|
||||
const other_links = calendar_views.map(
|
||||
calendar_view => `<li><a href="#List/${doctype}/Calendar/${calendar_view.name}">
|
||||
${ __(calendar_view.name) }</a>
|
||||
</li>`
|
||||
).join('');
|
||||
|
||||
const dropdown_html = `
|
||||
<div class="btn-group">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
${ __("Calendar") } <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu calendar-dropdown" style="max-height: 300px; overflow-y: auto;">
|
||||
${default_link}
|
||||
${other_links}
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
$link_calendar.removeClass('hide');
|
||||
$link_calendar.html(dropdown_html);
|
||||
});
|
||||
}
|
||||
|
||||
setup_email_inbox() {
|
||||
// get active email account for the user and add in dropdown
|
||||
if (this.doctype != "Communication")
|
||||
return;
|
||||
|
||||
let $dropdown = this.page.sidebar.find('.email-account-dropdown');
|
||||
let divider = false;
|
||||
|
||||
if (has_common(frappe.user_roles, ["System Manager", "Administrator"])) {
|
||||
$(`<li class="new-email-account"><a>${__("New Email Account")}</a></li>`)
|
||||
.appendTo($dropdown);
|
||||
}
|
||||
|
||||
let accounts = frappe.boot.email_accounts;
|
||||
accounts.forEach((account) => {
|
||||
let email_account = (account.email_id == "All Accounts") ? "All Accounts" : account.email_account;
|
||||
let route = ["List", "Communication", "Inbox", email_account].join('/');
|
||||
let display_name = ["All Accounts", "Sent Mail", "Spam", "Trash"].includes(account.email_id) ? __(account.email_id) : account.email_id;
|
||||
|
||||
if (!divider) {
|
||||
this.get_divider().appendTo($dropdown);
|
||||
divider = true;
|
||||
}
|
||||
$(`<li><a href="#${route}">${display_name}</a></li>`).appendTo($dropdown);
|
||||
if (account.email_id === "Sent Mail")
|
||||
divider = false;
|
||||
});
|
||||
|
||||
$dropdown.find('.new-email-account').click(function() {
|
||||
frappe.new_doc("Email Account");
|
||||
});
|
||||
}
|
||||
|
||||
setup_keyboard_shortcuts() {
|
||||
this.sidebar.find('.list-link > a, .list-link > .btn-group > a').each((i, el) => {
|
||||
frappe.ui.keys
|
||||
.get_shortcut_group(this.page)
|
||||
.add($(el));
|
||||
});
|
||||
}
|
||||
|
||||
setup_list_group_by() {
|
||||
this.list_group_by = new frappe.views.ListGroupBy({
|
||||
doctype: this.doctype,
|
||||
|
|
@ -255,7 +60,7 @@ frappe.views.ListSidebar = class ListSidebar {
|
|||
stats: me.stats,
|
||||
doctype: me.doctype,
|
||||
// wait for list filter area to be generated before getting filters, or fallback to default filters
|
||||
filters: (me.list_view.filter_area ? me.list_filter.get_current_filters() : me.default_filters) || []
|
||||
filters: (me.list_view.filter_area ? me.list_view.get_filters_for_args() : me.default_filters) || []
|
||||
},
|
||||
callback: function(r) {
|
||||
me.render_stat("_user_tags", (r.message.stats || {})["_user_tags"]);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
frappe.provide('frappe.views');
|
||||
|
||||
frappe.views.ListGroupBy = class ListGroupBy {
|
||||
|
|
@ -8,8 +7,10 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
|
||||
this.user_settings = frappe.get_user_settings(this.doctype);
|
||||
this.group_by_fields = ['assigned_to', 'owner'];
|
||||
if(this.user_settings.group_by_fields) {
|
||||
this.group_by_fields = this.group_by_fields.concat(this.user_settings.group_by_fields);
|
||||
if (this.user_settings.group_by_fields) {
|
||||
this.group_by_fields = this.group_by_fields.concat(
|
||||
this.user_settings.group_by_fields
|
||||
);
|
||||
}
|
||||
this.render_group_by_items();
|
||||
this.make_group_by_fields_modal();
|
||||
|
|
@ -18,23 +19,31 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
}
|
||||
|
||||
make_group_by_fields_modal() {
|
||||
let d = new frappe.ui.Dialog ({
|
||||
title: __("Select Filters"),
|
||||
fields: this.get_group_by_dropdown_fields()
|
||||
let d = new frappe.ui.Dialog({
|
||||
title: __('Select Filters'),
|
||||
fields: this.get_group_by_dropdown_fields(),
|
||||
});
|
||||
|
||||
d.set_primary_action("Save", ({ group_by_fields }) => {
|
||||
frappe.model.user_settings.save(this.doctype, 'group_by_fields', group_by_fields || null);
|
||||
this.group_by_fields = group_by_fields ? ['assigned_to', 'owner', ...group_by_fields] : ['assigned_to', 'owner'];
|
||||
d.set_primary_action('Save', ({ group_by_fields }) => {
|
||||
frappe.model.user_settings.save(
|
||||
this.doctype,
|
||||
'group_by_fields',
|
||||
group_by_fields || null
|
||||
);
|
||||
this.group_by_fields = group_by_fields
|
||||
? ['assigned_to', 'owner', ...group_by_fields]
|
||||
: ['assigned_to', 'owner'];
|
||||
this.render_group_by_items();
|
||||
d.hide();
|
||||
});
|
||||
|
||||
d.$body.prepend(`<div class="filters-search">
|
||||
<input type="text" placeholder="${__('Search')}" data-element="search" class="form-control input-xs">
|
||||
<input type="text" placeholder="${__(
|
||||
'Search'
|
||||
)}" data-element="search" class="form-control input-xs">
|
||||
</div>`);
|
||||
|
||||
this.page.sidebar.find(".add-list-group-by a").on("click", () => {
|
||||
this.page.sidebar.find('.add-list-group-by a').on('click', () => {
|
||||
frappe.utils.setup_search(d.$body, '.unit-checkbox', '.label-area');
|
||||
d.show();
|
||||
});
|
||||
|
|
@ -43,14 +52,11 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
make_wrapper() {
|
||||
this.$wrapper = this.sidebar.sidebar.find('.list-group-by');
|
||||
let html = `
|
||||
<li class="list-sidebar-label">
|
||||
${__('Filter By')}
|
||||
</li>
|
||||
<div class="list-group-by-fields">
|
||||
</div>
|
||||
<li class="add-list-group-by list-link">
|
||||
<a class="add-group-by hidden-xs text-muted">
|
||||
${__("Add Fields")} <i class="octicon octicon-plus" style="margin-left: 2px;"></i>
|
||||
<li class="add-list-group-by sidebar-action">
|
||||
<a class="add-group-by hidden-xs">
|
||||
+ ${__('Add Fields')}
|
||||
</a>
|
||||
</li>
|
||||
`;
|
||||
|
|
@ -74,19 +80,19 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
}
|
||||
|
||||
return `<li class="group-by-field list-link">
|
||||
<div class="btn-group">
|
||||
<a class = "dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||
<a class="btn btn-default btn-sm list-sidebar-button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||
data-label="${label}" data-fieldname="${fieldname}" data-fieldtype="${fieldtype}"
|
||||
href="#" onclick="return false;">
|
||||
${__(label)} <span class="caret"></span>
|
||||
<span class="text-muted ellipsis">${__(label)}</span>
|
||||
<span>${frappe.utils.icon('select', 'xs')}</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu group-by-dropdown" role="menu">
|
||||
<li><div class="list-loading text-center group-by-loading text-muted">
|
||||
${__("Loading...")}
|
||||
<li>
|
||||
<div class="empty-state group-by-loading">
|
||||
${__('Loading...')}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>`;
|
||||
};
|
||||
let html = this.group_by_fields.map(get_item_html).join('');
|
||||
|
|
@ -94,18 +100,27 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
}
|
||||
|
||||
setup_dropdown() {
|
||||
this.$wrapper.on('click', '.group-by-field', (e)=> {
|
||||
this.$wrapper.on('click', '.group-by-field', (e) => {
|
||||
let dropdown = $(e.currentTarget).find('.group-by-dropdown');
|
||||
let fieldname = $(e.currentTarget).find('a').attr('data-fieldname');
|
||||
let fieldtype = $(e.currentTarget).find('a').attr('data-fieldtype');
|
||||
this.get_group_by_count(fieldname).then(field_count_list => {
|
||||
let fieldname = $(e.currentTarget)
|
||||
.find('a')
|
||||
.attr('data-fieldname');
|
||||
let fieldtype = $(e.currentTarget)
|
||||
.find('a')
|
||||
.attr('data-fieldtype');
|
||||
this.get_group_by_count(fieldname).then((field_count_list) => {
|
||||
if (field_count_list.length) {
|
||||
this.render_dropdown_items(field_count_list, fieldtype, dropdown);
|
||||
frappe.utils.setup_search(dropdown, '.group-by-item', '.group-by-value', 'data-name');
|
||||
frappe.utils.setup_search(
|
||||
dropdown,
|
||||
'.group-by-item',
|
||||
'.group-by-value',
|
||||
'data-name'
|
||||
);
|
||||
} else {
|
||||
dropdown.html(
|
||||
`<div class="list-loading text-center group-by-empty text-muted">
|
||||
${__("No filters found")}
|
||||
`<div class="empty-state group-by-empty">
|
||||
${__('No filters found')}
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
|
|
@ -115,18 +130,19 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
|
||||
get_group_by_dropdown_fields() {
|
||||
let group_by_fields = [];
|
||||
let fields = this.list_view.meta.fields.filter((f)=> ["Select", "Link", "Data", "Int", "Check"].includes(f.fieldtype));
|
||||
let fields = this.list_view.meta.fields.filter((f) =>
|
||||
['Select', 'Link', 'Data', 'Int', 'Check'].includes(f.fieldtype)
|
||||
);
|
||||
group_by_fields.push({
|
||||
label: __(this.doctype),
|
||||
fieldname: 'group_by_fields',
|
||||
fieldtype: 'MultiCheck',
|
||||
columns: 2,
|
||||
options: fields
|
||||
.map(df => ({
|
||||
label: __(df.label),
|
||||
value: df.fieldname,
|
||||
checked: this.group_by_fields.includes(df.fieldname)
|
||||
}))
|
||||
options: fields.map((df) => ({
|
||||
label: __(df.label),
|
||||
value: df.fieldname,
|
||||
checked: this.group_by_fields.includes(df.fieldname),
|
||||
})),
|
||||
});
|
||||
return group_by_fields;
|
||||
}
|
||||
|
|
@ -135,25 +151,32 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
let current_filters = this.list_view.get_filters_for_args();
|
||||
|
||||
// remove filter of the current field
|
||||
current_filters =
|
||||
current_filters.filter((f_arr) => !f_arr.includes(field === 'assigned_to' ? '_assign': field));
|
||||
current_filters = current_filters.filter(
|
||||
(f_arr) => !f_arr.includes(field === 'assigned_to' ? '_assign' : field)
|
||||
);
|
||||
|
||||
let args = {
|
||||
let args = {
|
||||
doctype: this.doctype,
|
||||
current_filters: current_filters,
|
||||
field: field,
|
||||
};
|
||||
|
||||
|
||||
return frappe.call('frappe.desk.listview.get_group_by_count', args).then((r) => {
|
||||
let field_counts = r.message || [];
|
||||
field_counts = field_counts.filter(f => f.count !== 0);
|
||||
let current_user = field_counts.find(f => f.name === frappe.session.user);
|
||||
field_counts = field_counts.filter(f => !['Guest', 'Administrator', frappe.session.user].includes(f.name));
|
||||
// Set frappe.session.user on top of the list
|
||||
if (current_user) field_counts.unshift(current_user);
|
||||
return field_counts;
|
||||
});
|
||||
return frappe
|
||||
.call('frappe.desk.listview.get_group_by_count', args)
|
||||
.then((r) => {
|
||||
let field_counts = r.message || [];
|
||||
field_counts = field_counts.filter((f) => f.count !== 0);
|
||||
let current_user = field_counts.find(
|
||||
(f) => f.name === frappe.session.user
|
||||
);
|
||||
field_counts = field_counts.filter(
|
||||
(f) =>
|
||||
!['Guest', 'Administrator', frappe.session.user].includes(f.name)
|
||||
);
|
||||
// Set frappe.session.user on top of the list
|
||||
if (current_user) field_counts.unshift(current_user);
|
||||
return field_counts;
|
||||
});
|
||||
}
|
||||
|
||||
render_dropdown_items(fields, fieldtype, dropdown) {
|
||||
|
|
@ -162,20 +185,22 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
if (label === frappe.session.user) {
|
||||
label = __('Me');
|
||||
} else if (fieldtype && fieldtype == 'Check') {
|
||||
label = label == '0'? __('No'): __('Yes');
|
||||
label = label == '0' ? __('No') : __('Yes');
|
||||
}
|
||||
let value = field.name == null ? '' : encodeURIComponent(field.name);
|
||||
|
||||
return `<li class="group-by-item" data-value="${value}">
|
||||
<a class="badge-hover" href="#" onclick="return false;">
|
||||
<span class="group-by-value" data-name="${field.name}">${label}</span>
|
||||
<span class="badge pull-right group-by-count">${field.count}</span>
|
||||
<a class="dropdown-item" href="#" onclick="return false;">
|
||||
<span class="group-by-value ellipsis" data-name="${field.name}">${label}</span>
|
||||
<span class="group-by-count">${field.count}</span>
|
||||
</a>
|
||||
</li>`;
|
||||
};
|
||||
let standard_html = `
|
||||
<div class="dropdown-search">
|
||||
<input type="text" placeholder="${__('Search')}" data-element="search" class="dropdown-search-input form-control input-xs">
|
||||
<input type="text" placeholder="${__(
|
||||
'Search'
|
||||
)}" data-element="search" class="dropdown-search-input form-control input-xs">
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
|
@ -186,27 +211,34 @@ frappe.views.ListGroupBy = class ListGroupBy {
|
|||
setup_filter_by() {
|
||||
this.$wrapper.on('click', '.group-by-item', (e) => {
|
||||
let $target = $(e.currentTarget);
|
||||
let fieldname = $target.parents('.group-by-field').find('a').data('fieldname');
|
||||
let value = typeof $target.data('value') === 'string'
|
||||
? decodeURIComponent($target.data('value').trim())
|
||||
: $target.data('value');
|
||||
fieldname = fieldname === 'assigned_to' ? '_assign': fieldname;
|
||||
let fieldname = $target
|
||||
.parents('.group-by-field')
|
||||
.find('a')
|
||||
.data('fieldname');
|
||||
let value =
|
||||
typeof $target.data('value') === 'string'
|
||||
? decodeURIComponent($target.data('value').trim())
|
||||
: $target.data('value');
|
||||
fieldname = fieldname === 'assigned_to' ? '_assign' : fieldname;
|
||||
|
||||
return this.list_view.filter_area.remove(fieldname)
|
||||
.then(() => {
|
||||
let operator = '=';
|
||||
if (value === '') {
|
||||
operator = 'is';
|
||||
value = 'not set';
|
||||
}
|
||||
if (fieldname === '_assign') {
|
||||
operator = 'like';
|
||||
value = `%${value}%`;
|
||||
}
|
||||
return this.list_view.filter_area.remove(fieldname).then(() => {
|
||||
let operator = '=';
|
||||
if (value === '') {
|
||||
operator = 'is';
|
||||
value = 'not set';
|
||||
}
|
||||
if (fieldname === '_assign') {
|
||||
operator = 'like';
|
||||
value = `%${value}%`;
|
||||
}
|
||||
|
||||
return this.list_view.filter_area.add(this.doctype, fieldname, operator, value);
|
||||
});
|
||||
return this.list_view.filter_area.add(
|
||||
this.doctype,
|
||||
fieldname,
|
||||
operator,
|
||||
value
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
var stat_count = stat[i][1];
|
||||
%}
|
||||
<li>
|
||||
<a class="stat-link badge-hover" data-label="{{ stat_label %}" data-field="{{ field %}" href="#" onclick="return false;">
|
||||
<span class="badge pull-right" style="position: relative">{{ stat_count }}</span>
|
||||
<a class="stat-link dropdown-item" data-label="{{ stat_label %}" data-field="{{ field %}" href="#" onclick="return false;">
|
||||
<span class="stat-label">{{ __(stat_label) }}</span>
|
||||
<span>{{ stat_count }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% }
|
||||
|
|
|
|||
|
|
@ -751,7 +751,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
doc[this.meta.title_field || ""] !== doc.name
|
||||
) {
|
||||
html += `
|
||||
<div class="level-item hidden-xs hidden-sm ellipsis">
|
||||
<div class="level-item ellipsis">
|
||||
<a class="text-muted ellipsis" href="${this.get_form_link(doc)}">
|
||||
${doc.name}
|
||||
</a>
|
||||
|
|
@ -784,12 +784,14 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
const comment_count = `<span class="${
|
||||
!doc._comment_count ? "text-extra-muted" : ""
|
||||
} comment-count">
|
||||
<i class="octicon octicon-comment-discussion"></i>
|
||||
<svg class="icon icon-sm">
|
||||
<use xlink:href="#icon-small-message"></use>
|
||||
</svg>
|
||||
${doc._comment_count > 99 ? "99+" : doc._comment_count}
|
||||
</span>`;
|
||||
|
||||
html += `
|
||||
<div class="level-item hidden-xs list-row-activity">
|
||||
<div class="level-item list-row-activity">
|
||||
${modified}
|
||||
${assigned_to}
|
||||
${comment_count}
|
||||
|
|
|
|||
264
frappe/public/js/frappe/list/views.js
Normal file
264
frappe/public/js/frappe/list/views.js
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
frappe.provide('frappe.views');
|
||||
|
||||
frappe.views.Views = class Views {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.set_current_view();
|
||||
this.setup_views();
|
||||
}
|
||||
|
||||
add_view_to_menu(view, action) {
|
||||
let $el = this.page.add_custom_menu_item(
|
||||
this.parent,
|
||||
view,
|
||||
action,
|
||||
true,
|
||||
);
|
||||
$el.parent().attr('data-view', view)
|
||||
}
|
||||
|
||||
set_current_view() {
|
||||
this.current_view = 'List';
|
||||
var route = frappe.get_route();
|
||||
if (route.length > 2 && frappe.views.view_modes.includes(route[2])) {
|
||||
this.current_view = route[2];
|
||||
|
||||
if (this.current_view === 'Kanban') {
|
||||
this.kanban_board = route[3];
|
||||
} else if (this.current_view === 'Inbox') {
|
||||
this.email_account = route[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup_views() {
|
||||
const views = {
|
||||
'List': {
|
||||
condition: true,
|
||||
action: () => frappe.set_route(`List/${this.doctype}/List`)
|
||||
},
|
||||
'Report': {
|
||||
condition: true,
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Report`),
|
||||
current_view_handler: () => {
|
||||
const reports = this.get_reports();
|
||||
this.setup_dropdown_in_sidebar(
|
||||
'Report',
|
||||
reports,
|
||||
{
|
||||
label: __('Report Builder'),
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Report`)
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
'Dashboard': {
|
||||
condition: true,
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Dashboard`)
|
||||
},
|
||||
'Calendar': {
|
||||
condition: frappe.views.calendar[this.doctype],
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Calendar/Default`),
|
||||
current_view_handler: () => {
|
||||
this.get_calendars().then(calendars => {
|
||||
this.setup_dropdown_in_sidebar(
|
||||
'Calendar',
|
||||
calendars,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
'Gantt': {
|
||||
condition: frappe.views.calendar[this.doctype],
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Gantt`)
|
||||
},
|
||||
'Inbox': {
|
||||
condition: this.doctype === "Communication" && frappe.boot.email_accounts.length,
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Inbox`),
|
||||
current_view_handler: () => {
|
||||
const accounts = this.get_email_accounts();
|
||||
let default_action;
|
||||
if (has_common(frappe.user_roles, ["System Manager", "Administrator"])) {
|
||||
default_action = {
|
||||
label: __('New Email Account'),
|
||||
action: () => frappe.new_doc("Email Account")
|
||||
}
|
||||
}
|
||||
this.setup_dropdown_in_sidebar(
|
||||
'Inbox',
|
||||
accounts,
|
||||
default_action,
|
||||
);
|
||||
}
|
||||
},
|
||||
'Image': {
|
||||
condition: this.list_view.meta.image_field,
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Image`)
|
||||
},
|
||||
'Tree': {
|
||||
condition: frappe.treeview_settings[this.doctype] || frappe.get_meta(this.doctype).is_tree,
|
||||
action: () => frappe.set_route(`List/${this.doctype}/Tree`)
|
||||
},
|
||||
'Kanban': {
|
||||
condition: true,
|
||||
action: () => this.setup_kanban_boards(),
|
||||
current_view_handler: () => {
|
||||
frappe.views.KanbanView.get_kanbans(this.doctype).then((kanbans) => {
|
||||
this.setup_dropdown_in_sidebar(
|
||||
'Kanban',
|
||||
kanbans,
|
||||
{
|
||||
label: __('New Kanban Board'),
|
||||
action: () => frappe.views.KanbanView.show_kanban_dialog(this.doctype)
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
frappe.views.view_modes.forEach(view => {
|
||||
if (this.current_view !== view && views[view].condition) {
|
||||
this.add_view_to_menu(view, views[view].action);
|
||||
}
|
||||
|
||||
if (this.current_view == view) {
|
||||
views[view].current_view_handler && views[view].current_view_handler();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
setup_dropdown_in_sidebar(view, items, default_action) {
|
||||
const views_wrapper = this.sidebar.sidebar.find('.views-section');
|
||||
views_wrapper.find('.list-sidebar-label').html(`${__(view)}`);
|
||||
const $dropdown = views_wrapper.find('.views-dropdown');
|
||||
|
||||
let placeholder = `Select ${view}`;
|
||||
let html = ``;
|
||||
|
||||
if (!items || !items.length) {
|
||||
html = `<div class="empty-state">
|
||||
${__('No {} Found', [view])}
|
||||
</div>`;
|
||||
} else {
|
||||
items.map(item => {
|
||||
if (item.name == frappe.get_route().slice(-1)[0]) {
|
||||
placeholder = item.name;
|
||||
}
|
||||
html += `<li><a class="dropdown-item" href="#${item.route}">${item.name}</a></li>`;
|
||||
});
|
||||
}
|
||||
|
||||
views_wrapper.find('.selected-view').html(placeholder);
|
||||
|
||||
if (default_action) {
|
||||
views_wrapper.find('.sidebar-action a').html(default_action.label);
|
||||
views_wrapper.find('.sidebar-action a').click(() => default_action.action());
|
||||
}
|
||||
|
||||
$dropdown.html(html);
|
||||
|
||||
views_wrapper.removeClass('hide');
|
||||
}
|
||||
|
||||
get_reports() {
|
||||
// add reports linked to this doctype to the dropdown
|
||||
let added = [];
|
||||
let reports_to_add = [];
|
||||
|
||||
let add_reports = (reports) => {
|
||||
reports.map((r) => {
|
||||
if (!r.ref_doctype || r.ref_doctype == this.doctype) {
|
||||
const report_type = r.report_type === 'Report Builder' ?
|
||||
`List/${r.ref_doctype}/Report` : 'query-report';
|
||||
|
||||
const route = r.route || report_type + '/' + (r.title || r.name);
|
||||
|
||||
if (added.indexOf(route) === -1) {
|
||||
// don't repeat
|
||||
added.push(route);
|
||||
reports_to_add.push({name: r.title || r.name, route: route});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// from reference doctype
|
||||
if (this.list_view.settings.reports) {
|
||||
add_reports(this.list_view.settings.reports);
|
||||
}
|
||||
|
||||
// Sort reports alphabetically
|
||||
var reports = Object.values(frappe.boot.user.all_reports).sort((a,b) => a.title.localeCompare(b.title)) || [];
|
||||
|
||||
// from specially tagged reports
|
||||
add_reports(reports);
|
||||
|
||||
return reports_to_add;
|
||||
}
|
||||
|
||||
setup_kanban_boards() {
|
||||
const last_opened_kanban = frappe.model.user_settings[this.doctype]['Kanban']
|
||||
&& frappe.model.user_settings[this.doctype]['Kanban'].last_kanban_board;
|
||||
|
||||
if (last_opened_kanban) {
|
||||
frappe.set_route(`List/${this.doctype}/Kanban/${last_opened_kanban}`);
|
||||
} else {
|
||||
frappe.views.KanbanView.show_kanban_dialog(this.doctype, true);
|
||||
}
|
||||
}
|
||||
|
||||
get_calendars() {
|
||||
const doctype = this.doctype;
|
||||
let calendars = [];
|
||||
|
||||
return frappe.db.get_list('Calendar View', {
|
||||
filters: {
|
||||
reference_doctype: doctype
|
||||
}
|
||||
}).then(result => {
|
||||
if (!(result && Array.isArray(result) && result.length)) return;
|
||||
|
||||
if (frappe.views.calendar[this.doctype]) {
|
||||
// has standard calendar view
|
||||
calendars.push({
|
||||
name: 'Default',
|
||||
route: `List/${this.doctype}/Calendar/Default`
|
||||
});
|
||||
}
|
||||
result.map(calendar => {
|
||||
calendars.push({name: calendar.name, route: `List/${doctype}/Calendar/${calendar.name}`});
|
||||
});
|
||||
|
||||
return calendars;
|
||||
});
|
||||
}
|
||||
|
||||
get_email_accounts() {
|
||||
let accounts_to_add = [];
|
||||
let accounts = frappe.boot.email_accounts;
|
||||
accounts.forEach(account => {
|
||||
let email_account = (account.email_id == "All Accounts") ? "All Accounts" : account.email_account;
|
||||
let route = ["List", "Communication", "Inbox", email_account].join('/');
|
||||
let display_name = ["All Accounts", "Sent Mail", "Spam", "Trash"].includes(account.email_id)
|
||||
? __(account.email_id)
|
||||
: account.email_account;
|
||||
|
||||
accounts_to_add.push({
|
||||
name: display_name,
|
||||
route: route
|
||||
});
|
||||
});
|
||||
|
||||
return accounts_to_add;
|
||||
}
|
||||
|
||||
setup_keyboard_shortcuts() {
|
||||
this.sidebar.find('.list-link > a, .list-link > .btn-group > a').each((i, el) => {
|
||||
frappe.ui.keys
|
||||
.get_shortcut_group(this.page)
|
||||
.add($(el));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<!-- <span class="checked-items-status text-ellipsis text-muted small hide hidden-xs hidden-sm" style="margin-right: 20px;">## items selected</span> -->
|
||||
<!-- <h6 class="ellipsis sub-heading hide text-muted"></h6> -->
|
||||
<span class="page-icon-group hide hidden-xs hidden-sm"></span>
|
||||
<div class="custom-actions hide hidden-xs hidden-sm"></div>
|
||||
<div class="custom-actions hide"></div>
|
||||
<!-- buttons -->
|
||||
<div class="menu-btn-group hide">
|
||||
<button type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-expanded="false">
|
||||
|
|
|
|||
|
|
@ -243,6 +243,16 @@ frappe.ui.Page = Class.extend({
|
|||
});
|
||||
},
|
||||
|
||||
add_custom_menu_item: function(parent, label, click, standard, shortcut) {
|
||||
return this.add_dropdown_item({
|
||||
label,
|
||||
click,
|
||||
standard,
|
||||
parent: parent,
|
||||
shortcut,
|
||||
});
|
||||
},
|
||||
|
||||
clear_menu: function() {
|
||||
this.clear_btn_group(this.menu);
|
||||
},
|
||||
|
|
@ -574,7 +584,28 @@ frappe.ui.Page = Class.extend({
|
|||
button.appendTo(this.custom_actions)
|
||||
button.onclick = click;
|
||||
|
||||
return button
|
||||
return button;
|
||||
},
|
||||
|
||||
add_custom_button_group: function(label, icon) {
|
||||
let custom_btn_group = $(`
|
||||
<div class="custom-btn-group hide">
|
||||
<button type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-expanded="false">
|
||||
<span class="hidden-xs">
|
||||
${frappe.utils.icon(icon)}
|
||||
<span class="custom-btn-group-label">${__(label)}</span>
|
||||
<span class="caret"></span>
|
||||
</span>
|
||||
<span class="visible-xs">
|
||||
${frappe.utils.icon(icon)}
|
||||
</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu"></ul>
|
||||
</div>
|
||||
`);
|
||||
this.custom_actions.removeClass('hide').append(custom_btn_group);
|
||||
|
||||
return custom_btn_group.find('.dropdown-menu');
|
||||
},
|
||||
|
||||
add_dropdown_button: function(parent, label, click, icon) {
|
||||
|
|
|
|||
|
|
@ -179,29 +179,33 @@ frappe.views.KanbanView = class KanbanView extends frappe.views.ListView {
|
|||
};
|
||||
|
||||
|
||||
frappe.views.KanbanView.setup_dropdown_in_sidebar = function(doctype, $dropdown) {
|
||||
// get kanban boards and append to dropdown
|
||||
get_kanban_boards()
|
||||
frappe.views.KanbanView.get_kanbans = function(doctype) {
|
||||
let kanbans = [];
|
||||
|
||||
return get_kanban_boards()
|
||||
.then((kanban_boards) => {
|
||||
if (!kanban_boards) return;
|
||||
if (kanban_boards) {
|
||||
kanban_boards.forEach(board => {
|
||||
let route = ['List', board.reference_doctype, 'Kanban', board.name].join('/');
|
||||
kanbans.push({name: board.name, route: route});
|
||||
});
|
||||
}
|
||||
|
||||
$('<li role="separator" class="divider"></li>').appendTo($dropdown);
|
||||
|
||||
kanban_boards.forEach(board => {
|
||||
const route = ['List', board.reference_doctype, 'Kanban', board.name].join('/');
|
||||
|
||||
$(`<li>
|
||||
<a href="#${route}">
|
||||
<span>${__(board.name)}</span>
|
||||
${board.private ? '<i class="fa fa-lock fa-fw text-warning"></i>' : ''}
|
||||
</a>
|
||||
</li>
|
||||
`).appendTo($dropdown);
|
||||
});
|
||||
return kanbans;
|
||||
});
|
||||
|
||||
$dropdown.on('click', '.new-kanban-board', () => {
|
||||
const dialog = new_kanban_dialog();
|
||||
function get_kanban_boards() {
|
||||
return frappe.call('frappe.desk.doctype.kanban_board.kanban_board.get_kanban_boards', { doctype })
|
||||
.then(r => r.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
frappe.views.KanbanView.show_kanban_dialog = function(doctype, show_existing) {
|
||||
let dialog = null;
|
||||
|
||||
frappe.views.KanbanView.get_kanbans(doctype).then(kanbans => {
|
||||
dialog = new_kanban_dialog(kanbans, show_existing);
|
||||
dialog.show();
|
||||
});
|
||||
|
||||
|
|
@ -225,19 +229,22 @@ frappe.views.KanbanView.setup_dropdown_in_sidebar = function(doctype, $dropdown)
|
|||
});
|
||||
}
|
||||
|
||||
let dialog = null;
|
||||
|
||||
function new_kanban_dialog() {
|
||||
function new_kanban_dialog(kanbans, show_existing) {
|
||||
if (dialog) return dialog;
|
||||
|
||||
const fields = get_fields_for_dialog();
|
||||
const fields = get_fields_for_dialog(kanbans.map(kanban=> kanban.name), show_existing);
|
||||
|
||||
let primary_action_label = fields.length > 1 ? __('Save') : '';
|
||||
let primary_action = fields.length > 1 ?
|
||||
({ board_name, field_name, project }) => {
|
||||
make_kanban_board(board_name, field_name, project)
|
||||
let primary_action_label = __('Save');
|
||||
|
||||
let primary_action = () => {
|
||||
const values = dialog.get_values();
|
||||
if (!values.selected_kanban || values.selected_kanban == 'Create New Board') {
|
||||
make_kanban_board(values.board_name, values.field_name, values.project)
|
||||
.then(() => dialog.hide(), (err) => frappe.msgprint(err));
|
||||
} : null;
|
||||
} else {
|
||||
frappe.set_route(kanbans.find(kanban => kanban.name == values.selected_kanban).route);
|
||||
}
|
||||
}
|
||||
|
||||
dialog = new frappe.ui.Dialog({
|
||||
title: __('New Kanban Board'),
|
||||
|
|
@ -248,16 +255,33 @@ frappe.views.KanbanView.setup_dropdown_in_sidebar = function(doctype, $dropdown)
|
|||
return dialog;
|
||||
}
|
||||
|
||||
function get_fields_for_dialog() {
|
||||
function get_fields_for_dialog(kanban_options, show_existing=false) {
|
||||
kanban_options.push('Create New Board');
|
||||
|
||||
let fields = [{
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'board_name',
|
||||
label: __('Kanban Board Name'),
|
||||
reqd: 1,
|
||||
description: ['Note', 'ToDo'].includes(doctype) ?
|
||||
__('This Kanban Board will be private') : ''
|
||||
}];
|
||||
let fields = [
|
||||
{
|
||||
fieldtype: 'Select',
|
||||
fieldname: 'selected_kanban',
|
||||
label: __('Choose Kanban Board'),
|
||||
reqd: 1,
|
||||
depends_on: `eval: ${show_existing}`,
|
||||
mandatory_depends_on: `eval: ${show_existing}`,
|
||||
options: kanban_options,
|
||||
},
|
||||
{
|
||||
fieldname: 'new_kanban_board_sb',
|
||||
fieldtype: 'Section Break',
|
||||
depends_on: `eval: !${show_existing} || doc.selected_kanban == "Create New Board"`,
|
||||
},
|
||||
{
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'board_name',
|
||||
label: __('Kanban Board Name'),
|
||||
mandatory_depends_on: 'eval: doc.selected_kanban == "Create New Board"',
|
||||
description: ['Note', 'ToDo'].includes(doctype) ?
|
||||
__('This Kanban Board will be private') : ''
|
||||
}
|
||||
];
|
||||
|
||||
if (doctype === 'Task') {
|
||||
fields.push({
|
||||
|
|
@ -282,7 +306,7 @@ frappe.views.KanbanView.setup_dropdown_in_sidebar = function(doctype, $dropdown)
|
|||
label: __('Columns based on'),
|
||||
options: select_fields.map(df => ({label: df.label, value: df.fieldname})),
|
||||
default: select_fields[0],
|
||||
reqd: 1,
|
||||
mandatory_depends_on: 'eval: doc.selected_kanban == "Create New Board"',
|
||||
});
|
||||
} else {
|
||||
fields = [{
|
||||
|
|
@ -302,9 +326,4 @@ frappe.views.KanbanView.setup_dropdown_in_sidebar = function(doctype, $dropdown)
|
|||
|
||||
return fields;
|
||||
}
|
||||
|
||||
function get_kanban_boards() {
|
||||
return frappe.call('frappe.desk.doctype.kanban_board.kanban_board.get_kanban_boards', { doctype })
|
||||
.then(r => r.message);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -57,6 +57,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.control-label,
|
||||
.grid-heading-row {
|
||||
color: var(--grey-700);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
// .form-print-wrapper {
|
||||
// border: 1px solid $border-color;
|
||||
// border-top: none;
|
||||
|
|
|
|||
|
|
@ -134,3 +134,8 @@ h2 {
|
|||
padding: 4px 12px;
|
||||
font-size: var(--text-md);
|
||||
}
|
||||
|
||||
.input-xs {
|
||||
height: 26px;
|
||||
font-size: var(--text-md);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@
|
|||
stroke: var(--grey-700);
|
||||
}
|
||||
|
||||
.icon-xs {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.icon-sm {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,588 @@
|
|||
.frappe-list {
|
||||
.result, .no-result, .freeze {
|
||||
min-height: #{"calc(100vh - 284px)"};
|
||||
}
|
||||
|
||||
.msg-box {
|
||||
margin-bottom: 8em;
|
||||
// To compensate for percieved centering
|
||||
|
||||
.null-state {
|
||||
height: 15rem !important;
|
||||
max-height: 150px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.meta-description {
|
||||
width: 45%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.freeze-row {
|
||||
.level-left, .level-right, .list-row-col {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list-row-col {
|
||||
background-color: $border-color;
|
||||
border-radius: 2px;
|
||||
animation: 2s breathe infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes breathe {
|
||||
0% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
// body.no-list-sidebar {
|
||||
// [data-page-route^="List/"] {
|
||||
// @media (min-width: $screen-md) {
|
||||
// .layout-side-section {
|
||||
// display: none;
|
||||
// }
|
||||
|
||||
// .layout-main-section-wrapper {
|
||||
// width: 100% !important;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.filter-list {
|
||||
position: relative;
|
||||
.tag-filters-area {
|
||||
padding: 10px 150px 0 10px;
|
||||
}
|
||||
.sort-selector {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
.dropdown:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.dropdown-menu {
|
||||
max-height: 300px;
|
||||
overflow-y: scroll;
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-row-container {
|
||||
border-bottom: 1px solid $border-color;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
outline: none;
|
||||
|
||||
// &:focus {
|
||||
// background-color: $light-yellow;
|
||||
// }
|
||||
}
|
||||
|
||||
.list-row {
|
||||
padding: 12px 15px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
-webkit-transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
background-color: $gray-50;
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
.level-left {
|
||||
flex: 3;
|
||||
width: 75%;
|
||||
}
|
||||
.level-right {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
font-size: var(--text-md);
|
||||
}
|
||||
|
||||
.list-row-activity {
|
||||
justify-content: flex-end;
|
||||
min-width: 120px;
|
||||
|
||||
.avatar:not(.avatar-empty) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&> span {
|
||||
display: inline-block;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-count {
|
||||
min-width: 35px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-row-head {
|
||||
|
||||
.list-subject {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.checkbox-actions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list-row-col {
|
||||
flex: 1;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.list-subject {
|
||||
flex: 2;
|
||||
justify-content: start;
|
||||
|
||||
.level-item {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&.seen {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.list-paging-area, .footnote-area {
|
||||
padding: 10px 15px;
|
||||
border-top: 1px solid $border-color;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
||||
.progress {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.likes-count {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.list-liked-by-me {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
input.list-check-all, input.list-row-checkbox {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.filterable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.listview-main-section {
|
||||
.octicon-heart {
|
||||
cursor: pointer;
|
||||
}
|
||||
.page-form {
|
||||
padding-left: 17px;
|
||||
|
||||
// @media (max-width: $screen-sm) {
|
||||
// padding-left: 25px;
|
||||
// }
|
||||
|
||||
.octicon-search {
|
||||
float: left;
|
||||
padding-top: 7px;
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
// @media (max-width: $screen-sm) {
|
||||
// margin-left: -12px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
.list-item--head {
|
||||
position: sticky !important;
|
||||
z-index: 500;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.list-items {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list-item-container {
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item-table {
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
height: 40px;
|
||||
padding-left: 15px;
|
||||
|
||||
font-size: var(--text-md);
|
||||
|
||||
&:hover {
|
||||
background-color: $gray-50;
|
||||
}
|
||||
|
||||
// @media (max-width: $screen-xs) {
|
||||
// height: 50px;
|
||||
// padding-left: 10px;
|
||||
|
||||
// font-size: $text-regular;
|
||||
// font-weight: normal;
|
||||
// }
|
||||
|
||||
&--head {
|
||||
background-color: $gray-50;
|
||||
border-bottom: 1px solid $border-color;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
margin: 0;
|
||||
margin-right: 5px;
|
||||
flex: 0 0 12px;
|
||||
}
|
||||
|
||||
.liked-by, .liked-by-filter-button {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item__content {
|
||||
flex: 1;
|
||||
margin-right: 15px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&--flex-2 {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
&--activity {
|
||||
justify-content: flex-end;
|
||||
margin-right: 5px;
|
||||
min-width: 110px;
|
||||
|
||||
.list-row-modified, .avatar-small {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&--indicator span::before {
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
&--id {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.frappe-timestamp {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// .like-action.octicon-heart {
|
||||
// color: $heart-color;
|
||||
// }
|
||||
|
||||
.list-comment-count {
|
||||
display: inline-block;
|
||||
width: 37px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
// tags
|
||||
|
||||
.result.tags-shown {
|
||||
.tag-row {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-row {
|
||||
display: none;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.taggle_placeholder {
|
||||
top: 0;
|
||||
left: 5px;
|
||||
font-size: 11px;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.page-form {
|
||||
.awesomplete > ul {
|
||||
min-width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.frappe-rtl {
|
||||
.restricted-button {
|
||||
margin: auto auto auto 5px;
|
||||
direction: ltr;
|
||||
}
|
||||
}
|
||||
|
||||
// Image view
|
||||
|
||||
// .image-view-container {
|
||||
|
||||
// display: flex;
|
||||
// flex-wrap: wrap;
|
||||
|
||||
// .image-view-row {
|
||||
// display: flex;
|
||||
// border-bottom: 1px solid #ebeff2;
|
||||
// }
|
||||
|
||||
// .image-view-item {
|
||||
// flex: 0 0 100%/4;
|
||||
// padding: 15px;
|
||||
// // border-bottom: 1px solid $light-border-color;
|
||||
// // border-right: 1px solid $light-border-color;
|
||||
// max-width: 100%/4;
|
||||
// }
|
||||
|
||||
// .image-view-item:nth-child(4n) {
|
||||
// border-right: none;
|
||||
// }
|
||||
|
||||
// .image-view-header {
|
||||
// margin-bottom: 10px;
|
||||
// }
|
||||
|
||||
// .image-view-info {
|
||||
// margin-top: 10px;
|
||||
// }
|
||||
|
||||
// .image-view-body {
|
||||
// &:hover .zoom-view {
|
||||
// opacity: 0.7;
|
||||
// }
|
||||
|
||||
// a {
|
||||
// text-decoration: none;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .image-field {
|
||||
// display: flex;
|
||||
// align-content: center;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// position: relative;
|
||||
// height: 200px;
|
||||
|
||||
// img {
|
||||
// max-height: 100%;
|
||||
// }
|
||||
|
||||
// // &.no-image {
|
||||
// // background-color: $light-bg;
|
||||
// // }
|
||||
// }
|
||||
|
||||
// .placeholder-text {
|
||||
// font-size: 72px;
|
||||
// // color: $text-extra-muted;
|
||||
// }
|
||||
|
||||
// .zoom-view {
|
||||
// bottom: 10px !important;
|
||||
// right: 10px !important;
|
||||
// width: 36px;
|
||||
// height: 36px;
|
||||
// opacity: 0;
|
||||
// font-size: 16px;
|
||||
// color: $text-color;
|
||||
// position: absolute;
|
||||
|
||||
// // // show zoom button on mobile devices
|
||||
// // @media (max-width: $screen-xs) {
|
||||
// // opacity: 0.5
|
||||
// // }
|
||||
// }
|
||||
|
||||
// // 3 columns for small screen
|
||||
// // @media(max-width: $screen-sm) {
|
||||
// // .image-view-container.three-column;
|
||||
// // }
|
||||
// }
|
||||
|
||||
// .item-selector {
|
||||
// border: 1px solid $border-color;
|
||||
|
||||
// .image-view-row {
|
||||
// width: 100%;
|
||||
// }
|
||||
// .image-field {
|
||||
// height: 120px;
|
||||
// }
|
||||
|
||||
// .placeholder-text {
|
||||
// font-size: 48px;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .image-view-container.three-column {
|
||||
// .image-view-item {
|
||||
// flex: 0 0 100%/3;
|
||||
// max-width: 100%/3;
|
||||
// }
|
||||
|
||||
// .image-view-item:nth-child(3n) {
|
||||
// border-right: none;
|
||||
// }
|
||||
// .image-view-item:nth-last-child(-n + 3):nth-child(3n + 1),
|
||||
// .image-view-item:nth-last-child(-n + 3):nth-child(3n + 1) ~ .image-view-item {
|
||||
// border-bottom: none;
|
||||
// }
|
||||
|
||||
// .image-view-item:nth-child(4n) {
|
||||
// // border-right: 1px solid $light-border-color;
|
||||
// }
|
||||
// .image-view-item:nth-last-child(-n + 4):nth-child(4n + 1),
|
||||
// .image-view-item:nth-last-child(-n + 4):nth-child(4n + 1) ~ .image-view-item {
|
||||
// border-bottom: 1px solid $light-border-color;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .pswp--svg .pswp__button,
|
||||
// .pswp--svg .pswp__button--arrow--left:before,
|
||||
// .pswp--svg .pswp__button--arrow--right:before {
|
||||
// background-image: url('/assets/frappe/images/default-skin.svg') !important;
|
||||
// }
|
||||
// .pswp--svg .pswp__button--arrow--left,
|
||||
// .pswp--svg .pswp__button--arrow--right {
|
||||
// background: none !important;
|
||||
// }
|
||||
|
||||
// .pswp__bg {
|
||||
// background-color: #fff !important;
|
||||
// }
|
||||
|
||||
// .pswp__more-items {
|
||||
// position: absolute;
|
||||
// bottom: 12px;
|
||||
// left: 50%;
|
||||
// transform: translateX(-50%);
|
||||
// }
|
||||
|
||||
// .pswp__more-item {
|
||||
// display: inline-block;
|
||||
// margin: 5px;
|
||||
// height: 100px;
|
||||
// cursor: pointer;
|
||||
// border: 1px solid $border-color;
|
||||
|
||||
// img {
|
||||
// max-height: 100%;
|
||||
// }
|
||||
// }
|
||||
|
||||
// gantt
|
||||
// .list-paging-area .gantt-view-mode {
|
||||
// margin-left: 15px;
|
||||
// margin-right: 15px;
|
||||
// }
|
||||
|
||||
// .gantt {
|
||||
// .details-container {
|
||||
// .heading {
|
||||
// margin-bottom: 10px;
|
||||
// font-size: 12px;
|
||||
// }
|
||||
|
||||
// .avatar-small {
|
||||
// width: 16px;
|
||||
// height: 16px;
|
||||
// }
|
||||
|
||||
// .standard-image {
|
||||
// display: block;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// .inbox-attachment, .inbox-link {
|
||||
// margin-right: 7px;
|
||||
// }
|
||||
|
||||
// .select-inbox {
|
||||
// padding: 30px 30px;
|
||||
// }
|
||||
|
||||
// .inbox-value {
|
||||
// padding-top: 2px;
|
||||
// }
|
||||
|
||||
// list view
|
||||
|
||||
|
||||
|
||||
// .file-grid {
|
||||
// display: flex;
|
||||
// flex-wrap: wrap;
|
||||
// align-content: flex-start;
|
||||
|
||||
// a {
|
||||
// height: 100%;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .file-wrapper {
|
||||
// width: 120px;
|
||||
// flex-direction: column;
|
||||
// align-items: center;
|
||||
// }
|
||||
|
||||
// .file-title {
|
||||
// margin-top: 5px;
|
||||
// }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
@import "desktop";
|
||||
@import "awesomebar";
|
||||
@import "sidebar";
|
||||
@import "list";
|
||||
|
||||
@import "frappe/public/css/font-awesome";
|
||||
@import "multilevel-dropdown";
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
padding: 4px 20px;
|
||||
font-size: var(--text-md);
|
||||
}
|
||||
.custom-btn-group .btn {
|
||||
padding: 4px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.page-form {
|
||||
|
|
@ -120,13 +123,13 @@
|
|||
// margin-top: 70px;
|
||||
// }
|
||||
|
||||
// /* show menu aligned to the right border of the dropdown */
|
||||
// .page-actions .dropdown-menu,
|
||||
// .form-inner-toolbar .dropdown-menu {
|
||||
// right: 0px;
|
||||
// left: auto;
|
||||
// z-index: 100;
|
||||
// }
|
||||
/* show menu aligned to the right border of the dropdown */
|
||||
.page-actions .dropdown-menu,
|
||||
.form-inner-toolbar .dropdown-menu {
|
||||
right: 0px;
|
||||
left: auto;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
// .layout-footer {
|
||||
// border: 1px solid @border-color;
|
||||
|
|
@ -419,12 +422,12 @@
|
|||
// align-items: center;
|
||||
// }
|
||||
|
||||
// .menu-btn-group {
|
||||
// .dropdown-menu {
|
||||
// width: max-content;
|
||||
// }
|
||||
.menu-btn-group, .custom-btn-group {
|
||||
.dropdown-menu {
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
// .menu-item-label {
|
||||
// margin-right: 15px;
|
||||
// }
|
||||
// }
|
||||
.menu-item-label {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
|
@ -65,13 +65,13 @@ body[data-route^="Module"] .main-menu {
|
|||
}
|
||||
|
||||
.sidebar-menu {
|
||||
.badge {
|
||||
position: absolute;
|
||||
font-weight: normal;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
// .badge {
|
||||
// position: absolute;
|
||||
// font-weight: normal;
|
||||
// right: 0px;
|
||||
// top: 0px;
|
||||
// padding-bottom: 4px;
|
||||
// }
|
||||
|
||||
.octicon {
|
||||
font-size: 12px;
|
||||
|
|
@ -85,10 +85,6 @@ body[data-route^="Module"] .main-menu {
|
|||
> li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.list-link {
|
||||
margin: 7px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
// form sidebar
|
||||
|
|
@ -367,22 +363,54 @@ body[data-route^="Module"] .main-menu {
|
|||
|
||||
|
||||
.list-sidebar {
|
||||
|
||||
.sidebar-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.list-link {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.list-sidebar-label {
|
||||
color: $text-muted;
|
||||
color: var(--grey-600);
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 0;
|
||||
font-size: var(--text-sm);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.list-sidebar-button {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.group-by-count {
|
||||
position:relative
|
||||
}
|
||||
|
||||
.group-by-dropdown, .list-stats-dropdown {
|
||||
.group-by-value {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
min-width: 180px;
|
||||
max-width: 250px;
|
||||
z-index: 100;
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 10px 15px;
|
||||
text-align: center;
|
||||
color: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-search {
|
||||
|
|
@ -392,6 +420,12 @@ body[data-route^="Module"] .main-menu {
|
|||
.stat-no-records {
|
||||
margin: 5px 10px;
|
||||
}
|
||||
|
||||
.sidebar-action {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--primary);
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.filters-search {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue