Ver código fonte

fix: Remove hardcoded tabs and make it configurable

version-14
Suraj Shetty 3 anos atrás
pai
commit
7f9a7af50c
6 arquivos alterados com 107 adições e 134 exclusões
  1. +16
    -8
      frappe/public/js/frappe/form/column.js
  2. +12
    -32
      frappe/public/js/frappe/form/dashboard.js
  3. +5
    -5
      frappe/public/js/frappe/form/form.js
  4. +34
    -34
      frappe/public/js/frappe/form/layout.js
  5. +17
    -29
      frappe/public/js/frappe/form/section.js
  6. +23
    -26
      frappe/public/js/frappe/form/tab.js

+ 16
- 8
frappe/public/js/frappe/form/column.js Ver arquivo

@@ -9,19 +9,25 @@ export default class Column {
} }


make() { make() {
this.wrapper = $(`<div class="form-column">
<form>
</form>
</div>`).appendTo(this.section.body)
this.wrapper = $(`
<div class="form-column">
<form>
</form>
</div>
`)
.appendTo(this.section.body)
.find("form") .find("form")
.on("submit", function () { .on("submit", function () {
return false; return false;
}); });


if (this.df.label) { if (this.df.label) {
$(`<label class="control-label">
${__(this.df.label)}
</label>`).appendTo(this.wrapper);
$(`
<label class="control-label">
${__(this.df.label)}
</label>
`)
.appendTo(this.wrapper);
} }
} }


@@ -29,7 +35,9 @@ export default class Column {
// distribute all columns equally // distribute all columns equally
let colspan = cint(12 / this.section.wrapper.find(".form-column").length); let colspan = cint(12 / this.section.wrapper.find(".form-column").length);


this.section.wrapper.find(".form-column").removeClass()
this.section.wrapper
.find(".form-column")
.removeClass()
.addClass("form-column") .addClass("form-column")
.addClass("col-sm-" + colspan); .addClass("col-sm-" + colspan);




+ 12
- 32
frappe/public/js/frappe/form/dashboard.js Ver arquivo

@@ -2,35 +2,22 @@
// MIT License. See license.txt // MIT License. See license.txt


import Section from "./section.js"; import Section from "./section.js";
import Tab from "./tab.js";


frappe.ui.form.Dashboard = class FormDashboard { frappe.ui.form.Dashboard = class FormDashboard {
constructor(opts) { constructor(opts) {
$.extend(this, opts); $.extend(this, opts);
this.setup_dashboard_tabs();
let parent = this.tab ? this.tab.wrapper : this.frm.layout.wrapper;
this.parent = $('<div class="form-dashboard">');
parent.prepend(this.parent);
this.setup_dashboard_sections(); this.setup_dashboard_sections();
} }


setup_dashboard_tabs() {
this.overview_tab = new Tab(this.frm.layout, {
label: __("Overview"),
hidden: 1,
fieldname: 'dashboard-overview'
});

this.connections_tab = new Tab(this.frm.layout, {
label: __("Connections"),
hidden: 1,
fieldname: 'dashboard-connection'
});
}

setup_dashboard_sections() { setup_dashboard_sections() {
this.progress_area = this.make_section({ this.progress_area = this.make_section({
css_class: 'progress-area', css_class: 'progress-area',
hidden: 1, hidden: 1,
is_dashboard_section: 1, is_dashboard_section: 1,
}, this.overview_tab);
});


this.heatmap_area = this.make_section({ this.heatmap_area = this.make_section({
label: __("Overview"), label: __("Overview"),
@@ -41,14 +28,14 @@ frappe.ui.form.Dashboard = class FormDashboard {
<div id="heatmap-${frappe.model.scrub(this.frm.doctype)}" class="heatmap"></div> <div id="heatmap-${frappe.model.scrub(this.frm.doctype)}" class="heatmap"></div>
<div class="text-muted small heatmap-message hidden"></div> <div class="text-muted small heatmap-message hidden"></div>
` `
}, this.overview_tab);
});


this.chart_area = this.make_section({ this.chart_area = this.make_section({
label: __("Graph"), label: __("Graph"),
css_class: 'form-graph', css_class: 'form-graph',
hidden: 1, hidden: 1,
is_dashboard_section: 1 is_dashboard_section: 1
}, this.overview_tab);
});


this.stats_area_row = $(`<div class="row"></div>`); this.stats_area_row = $(`<div class="row"></div>`);
this.stats_area = this.make_section({ this.stats_area = this.make_section({
@@ -57,7 +44,7 @@ frappe.ui.form.Dashboard = class FormDashboard {
hidden: 1, hidden: 1,
is_dashboard_section: 1, is_dashboard_section: 1,
body_html: this.stats_area_row body_html: this.stats_area_row
}, this.overview_tab);
});


this.transactions_area = $(`<div class="transactions"></div`); this.transactions_area = $(`<div class="transactions"></div`);


@@ -67,20 +54,14 @@ frappe.ui.form.Dashboard = class FormDashboard {
hidden: 1, hidden: 1,
is_dashboard_section: 1, is_dashboard_section: 1,
body_html: this.transactions_area body_html: this.transactions_area
}, this.connections_tab);
});
} }


make_section(df, tab) {
return new Section(
this.frm.layout,
df,
tab,
);
make_section(df) {
return new Section(this.parent, df);
} }


reset() { reset() {
// this.hide();

// clear progress // clear progress
this.progress_area.body.empty(); this.progress_area.body.empty();
this.progress_area.hide(); this.progress_area.hide();
@@ -98,8 +79,7 @@ frappe.ui.form.Dashboard = class FormDashboard {
// this.hide(); // this.hide();
} }


add_section(body_html, label=null, css_class="custom", hidden=false, tab=null) {
if (!tab) tab = this.overview_tab;
add_section(body_html, label=null, css_class="custom", hidden=false) {
let options = { let options = {
label, label,
css_class, css_class,
@@ -108,7 +88,7 @@ frappe.ui.form.Dashboard = class FormDashboard {
make_card: true, make_card: true,
is_dashboard_section: 1 is_dashboard_section: 1
}; };
return new Section(this.frm.layout, options, tab).body;
return new Section(this.frm.layout, options).body;
} }


add_progress(title, percent, message) { add_progress(title, percent, message) {


+ 5
- 5
frappe/public/js/frappe/form/form.js Ver arquivo

@@ -133,8 +133,8 @@ frappe.ui.form.Form = class FrappeForm {
} }


setup_std_layout() { setup_std_layout() {
this.form_wrapper = $('<div></div>').appendTo(this.layout_main);
this.body = $('<div></div>').appendTo(this.form_wrapper);
this.form_wrapper = $('<div></div>').appendTo(this.layout_main);
this.body = $('<div></div>').appendTo(this.form_wrapper);


// only tray // only tray
this.meta.section_style='Simple'; // always simple! this.meta.section_style='Simple'; // always simple!
@@ -146,9 +146,9 @@ frappe.ui.form.Form = class FrappeForm {
doctype_layout: this.doctype_layout, doctype_layout: this.doctype_layout,
frm: this, frm: this,
with_dashboard: true, with_dashboard: true,
card_layout: true,
tabbed_layout: true,
card_layout: true
}); });

this.layout.make(); this.layout.make();


this.fields_dict = this.layout.fields_dict; this.fields_dict = this.layout.fields_dict;
@@ -156,7 +156,7 @@ frappe.ui.form.Form = class FrappeForm {


this.dashboard = new frappe.ui.form.Dashboard({ this.dashboard = new frappe.ui.form.Dashboard({
frm: this, frm: this,
parent: this.layout.wrapper,
tab: this.layout.tabs.length ? this.layout.tabs[0] : null
}); });


this.tour = new frappe.ui.form.FormTour({ this.tour = new frappe.ui.form.FormTour({


+ 34
- 34
frappe/public/js/frappe/form/layout.js Ver arquivo

@@ -20,25 +20,28 @@ frappe.ui.form.Layout = class Layout {
} }
this.wrapper = $('<div class="form-layout">').appendTo(this.parent); this.wrapper = $('<div class="form-layout">').appendTo(this.parent);
this.message = $('<div class="form-message hidden"></div>').appendTo(this.wrapper); this.message = $('<div class="form-message hidden"></div>').appendTo(this.wrapper);

this.page = $('<div class="form-page"></div>').appendTo(this.wrapper); this.page = $('<div class="form-page"></div>').appendTo(this.wrapper);
this.tabbed_layout && this.setup_tabbed_layout();


if (!this.fields) { if (!this.fields) {
this.fields = this.get_doctype_fields(); this.fields = this.get_doctype_fields();
} }


this.setup_tabbing();
if (this.is_tabbed_layout()) {
this.setup_tabbed_layout();
}

this.setup_tab_events();
this.render(); this.render();
} }


setup_tabbed_layout() { setup_tabbed_layout() {
$(`<div class="form-tabs-list">
<ul class="nav form-tabs" id="form-tabs" role="tablist"></ul>
</div>`).appendTo(this.page);
$(`
<div class="form-tabs-list">
<ul class="nav form-tabs" id="form-tabs" role="tablist"></ul>
</div>
`).appendTo(this.page);
this.tabs_list = this.page.find('.form-tabs'); this.tabs_list = this.page.find('.form-tabs');
this.tabs_content = $(`<div class="form-tab-content tab-content"></div>`).appendTo(this.page); this.tabs_content = $(`<div class="form-tab-content tab-content"></div>`).appendTo(this.page);

this.setup_events(); this.setup_events();
} }


@@ -114,16 +117,16 @@ frappe.ui.form.Layout = class Layout {
this.section = null; this.section = null;
this.column = null; this.column = null;


// if (this.with_dashboard) {
// this.setup_dashboard_section();
// }

if (this.tabbed_layout && this.no_opening_tab()) {
this.make_tab({label: __('Details'), fieldname: 'details'});
if (this.no_opening_section() && !this.is_tabbed_layout()) {
this.fields.unshift({fieldtype: 'Section Break'});
} }


if (this.no_opening_section()) {
this.make_section();
if (this.is_tabbed_layout()) {
let default_tab = {label: __('Details'), fieldname: 'details'};
let first_tab = this.fields[1].fieldtype === "Tab Break" ? this.fields[1] : null;
if (!first_tab) {
this.fields.splice(1, 0, default_tab);
}
} }


fields.forEach(df => { fields.forEach(df => {
@@ -154,10 +157,8 @@ frappe.ui.form.Layout = class Layout {
return (this.fields[1] && this.fields[1].fieldtype != "Tab Break") || !this.fields.length; return (this.fields[1] && this.fields[1].fieldtype != "Tab Break") || !this.fields.length;
} }


setup_dashboard_section() {
if (this.no_opening_section()) {
this.fields.unshift({fieldtype: 'Section Break'});
}
is_tabbed_layout() {
return this.fields.find(f => f.fieldtype === "Tab Break");
} }


replace_field(fieldname, df, render) { replace_field(fieldname, df, render) {
@@ -190,7 +191,7 @@ frappe.ui.form.Layout = class Layout {
this.section.fields_list.push(fieldobj); this.section.fields_list.push(fieldobj);
this.section.fields_dict[df.fieldname] = fieldobj; this.section.fields_dict[df.fieldname] = fieldobj;
fieldobj.section = this.section; fieldobj.section = this.section;
fieldobj.tab = this.tab;
fieldobj.tab = this.current_tab;
} }


init_field(df, render=false) { init_field(df, render=false) {
@@ -239,7 +240,7 @@ frappe.ui.form.Layout = class Layout {
} }


make_section(df) { make_section(df) {
this.section = new Section(this, df, this.tab || null);
this.section = new Section(this, df, this.current_tab || null);


// append to layout fields // append to layout fields
if (df) { if (df) {
@@ -258,14 +259,12 @@ frappe.ui.form.Layout = class Layout {
} }


make_tab(df) { make_tab(df) {
this.tab = new Tab(this, df);

if (df) {
this.fields_dict[df.fieldname] = this.tab;
this.fields_list.push(this.tab);
}

return this.tab;
this.section = null;
let tab = new Tab(this, df, this.frm, this.tabs_list, this.tabs_content);
this.current_tab = tab;
this.make_section({fieldtype: 'Section Break'});
this.tabs.push(tab);
return tab;
} }


refresh(doc) { refresh(doc) {
@@ -421,14 +420,15 @@ frappe.ui.form.Layout = class Layout {
}); });
} }


setup_tabbing() {
setup_tab_events() {
this.wrapper.on("keydown", (ev) => { this.wrapper.on("keydown", (ev) => {
if (ev.which == 9) { if (ev.which == 9) {
let current = $(ev.target),
doctype = current.attr("data-doctype"),
fieldname = current.attr("data-fieldname");
if (doctype)
let current = $(ev.target);
let doctype = current.attr("data-doctype");
let fieldname = current.attr("data-fieldname");
if (doctype) {
return this.handle_tab(doctype, fieldname, ev.shiftKey); return this.handle_tab(doctype, fieldname, ev.shiftKey);
}
} }
}); });
} }


+ 17
- 29
frappe/public/js/frappe/form/section.js Ver arquivo

@@ -1,10 +1,7 @@
// import '../class';

export default class Section { export default class Section {
constructor(layout, df, tab) {
this.layout = layout;
this.tab = tab;
this.parent = this.tab && this.tab.wrapper || null;
constructor(parent, df) {
this.card_layout = true;
this.parent = parent;
this.df = df || {}; this.df = df || {};
this.fields_list = []; this.fields_list = [];
this.fields_dict = {}; this.fields_dict = {};
@@ -23,18 +20,11 @@ export default class Section {
} }


make() { make() {
if (!this.layout.page) {
this.layout.page = $('<div class="form-page"></div>').appendTo(this.layout.wrapper);
}

let make_card = this.layout.card_layout;

let make_card = this.card_layout;
this.wrapper = $(`<div class="row this.wrapper = $(`<div class="row
${this.df.is_dashboard_section ? "form-dashboard-section" : "form-section"} ${this.df.is_dashboard_section ? "form-dashboard-section" : "form-section"}
${ make_card ? "card-section" : "" }"> ${ make_card ? "card-section" : "" }">
`).appendTo(this.parent || this.layout.page);

this.layout.sections.push(this);
`).appendTo(this.parent);


if (this.df) { if (this.df) {
if (this.df.label) { if (this.df.label) {
@@ -86,17 +76,11 @@ export default class Section {
} }
} }


refresh() {
refresh(hide) {
if (!this.df) return; if (!this.df) return;

// hide if explicitly hidden // hide if explicitly hidden
let hide = this.df.hidden || this.df.hidden_due_to_dependency;
if (!hide && this.layout && this.layout.frm && !this.layout.frm.get_perm(this.df.permlevel || 0, "read")) {
hide = true;
}

hide = hide || this.df.hidden || this.df.hidden_due_to_dependency;
this.wrapper.toggleClass("hide-control", !!hide); this.wrapper.toggleClass("hide-control", !!hide);
// this.tab && this.tab.refresh();
} }


collapse(hide) { collapse(hide) {
@@ -136,9 +120,9 @@ export default class Section {
} }


has_missing_mandatory () { has_missing_mandatory () {
var missing_mandatory = false;
for (var j = 0, l = this.fields_list.length; j < l; j++) {
var section_df = this.fields_list[j].df;
let missing_mandatory = false;
for (let j = 0, l = this.fields_list.length; j < l; j++) {
const section_df = this.fields_list[j].df;
if (section_df.reqd && this.layout.doc[section_df.fieldname] == null) { if (section_df.reqd && this.layout.doc[section_df.fieldname] == null) {
missing_mandatory = true; missing_mandatory = true;
break; break;
@@ -148,11 +132,15 @@ export default class Section {
} }


hide() { hide() {
this.wrapper.toggleClass("hide-control", true);
this.on_section_toggle(false);
} }


show() { show() {
this.wrapper.toggleClass("hide-control", false);
this.tab && this.tab.toggle(true);
this.on_section_toggle(true);
}

on_section_toggle(show) {
this.wrapper.toggleClass("hide-control", !show);
this.on_section_toggle && this.on_section_toggle(show);
} }
} }

+ 23
- 26
frappe/public/js/frappe/form/tab.js Ver arquivo

@@ -1,8 +1,12 @@
export default class Tab { export default class Tab {
constructor(layout, df) {
this.layout = layout;
constructor(parent, df, frm, tabs_list, tabs_content) {
this.parent = parent;
this.df = df || {}; this.df = df || {};
this.label = this.df && this.df.label || 'Details';
this.frm = frm;
this.doctype = 'User';
this.label = this.df && this.df.label;
this.tabs_list = tabs_list;
this.tabs_content = tabs_content;
this.fields_list = []; this.fields_list = [];
this.fields_dict = {}; this.fields_dict = {};
this.make(); this.make();
@@ -10,28 +14,21 @@ export default class Tab {
} }


make() { make() {
if (!this.layout.page) {
this.layout.page = $('<div class="form-page"></div>').appendTo(this.layout.wrapper);
}
const id = `${frappe.scrub(this.layout.doctype, '-')}-${this.df.fieldname}`;
this.parent = $(`<li class="nav-item">
<a class="nav-link ${this.df.active ? "active": ""}" id="${id}-tab"
data-toggle="tab" href="#${id}" role="tab"
aria-controls="home" aria-selected="true">
${__(this.label)}
</a>
</li>`).appendTo(this.layout.tabs_list);
const id = `${frappe.scrub(this.doctype, '-')}-${this.df.fieldname}`;
this.parent = $(`
<li class="nav-item">
<a class="nav-link ${this.df.active ? "active": ""}" id="${id}-tab"
data-toggle="tab"
href="#${id}"
role="tab"
aria-controls="${this.label}">
${__(this.label)}
</a>
</li>
`).appendTo(this.tabs_list);


this.wrapper = $(`<div class="tab-pane fade show ${this.df.active ? "active": ""}" this.wrapper = $(`<div class="tab-pane fade show ${this.df.active ? "active": ""}"
id="${id}" role="tabpanel" aria-labelledby="${id}-tab">
`).appendTo(this.layout.tabs_content);

this.layout.tabs.push(this);
}

set_content() {

id="${id}" role="tabpanel" aria-labelledby="${id}-tab">`).appendTo(this.tabs_content);
} }


refresh() { refresh() {
@@ -39,15 +36,15 @@ export default class Tab {


// hide if explicitly hidden // hide if explicitly hidden
let hide = this.df.hidden || this.df.hidden_due_to_dependency; let hide = this.df.hidden || this.df.hidden_due_to_dependency;
if (!hide && this.layout && this.layout.frm && !this.layout.frm.get_perm(this.df.permlevel || 0, "read")) {
if (!hide && this.frm && !this.frm.get_perm(this.df.permlevel || 0, "read")) {
hide = true; hide = true;
} }
hide && this.toggle(false); hide && this.toggle(false);
} }


toggle(show) { toggle(show) {
this.parent.toggleClass('hide', !show);
this.parent.toggleClass('hide', !show);
this.wrapper.toggleClass('hide', !show); this.wrapper.toggleClass('hide', !show);
this.parent.toggleClass('show', show); this.parent.toggleClass('show', show);
this.wrapper.toggleClass('show', show); this.wrapper.toggleClass('show', show);


Carregando…
Cancelar
Salvar