diff --git a/frappe/public/build.json b/frappe/public/build.json index dd1ff3c24b..8e04fbf48a 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -368,6 +368,7 @@ "js/web_form.min.js": [ "public/js/frappe/misc/datetime.js", "public/js/frappe/web_form/web_form_class.js", + "public/js/frappe/web_form/web_form_list_class.js", "public/js/frappe/web_form/web_form.js", "public/js/lib/datepicker/datepicker.min.js", "public/js/lib/datepicker/datepicker.en.js" diff --git a/frappe/public/js/frappe/web_form/web_form_class.js b/frappe/public/js/frappe/web_form/web_form_class.js index 79f303ccc4..3e527c7138 100644 --- a/frappe/public/js/frappe/web_form/web_form_class.js +++ b/frappe/public/js/frappe/web_form/web_form_class.js @@ -1,8 +1,7 @@ frappe.provide("frappe.ui"); -frappe.provide("frappe.views"); window.web_form = null; -window.web_form_list = null; + frappe.ui.WebForm = class WebForm extends frappe.ui.FieldGroup { constructor(opts) { @@ -44,7 +43,7 @@ frappe.ui.WebForm = class WebForm extends frappe.ui.FieldGroup { const delete_button = document.createElement("button"); delete_button.classList.add( "btn", - "btn-danger", + "btn-secondary", "button-delete", "btn-sm", "ml-2" @@ -120,261 +119,5 @@ frappe.ui.WebForm = class WebForm extends frappe.ui.FieldGroup { success_dialog.set_message(success_message); success_dialog.show(); } + }; - -frappe.views.WebFormList = class WebFormList { - constructor(opts) { - Object.assign(this, opts); - window.web_form_list = this; - this.wrapper = document.getElementById("datatable"); - this.refresh(); - this.make_actions(); - } - - refresh() { - this.table && this.table.remove() && delete this.table; - this.rows = []; - this.page_length = 20; - this.web_list_start = 0; - - frappe.run_serially([ - () => this.get_list_view_fields(), - () => this.get_data(), - () => this.make_table(), - ]); - } - - get_list_view_fields() { - return frappe - .call({ - method: - "frappe.website.doctype.web_form.web_form.get_in_list_view_fields", - args: { doctype: this.doctype } - }) - .then(response => (this.fields_list = response.message)); - } - - fetch_data() { - return frappe.call({ - method: "frappe.www.list.get_list_data", - args: { - doctype: this.doctype, - fields: this.fields_list.map(df => df.fieldname), - limit_start: this.web_list_start, - web_form_name: this.web_form_name - } - }); - } - - async get_data() { - let response = await this.fetch_data(); - this.data = await response.message; - } - - more() { - this.web_list_start += this.page_length - this.fetch_data().then((res) => { - if (res.message.length === 0) { - frappe.msgprint("No more items to display") - } - this.append_rows(res.message) - }) - - } - - make_table() { - this.table = document.createElement("table"); - this.table.classList.add("table"); - - this.make_table_head(); - this.append_rows(this.data); - - this.wrapper.appendChild(this.table); - } - - make_table_head() { - // Create Heading - let thead = this.table.createTHead(); - thead.style.backgroundColor = "#f7fafc"; - thead.style.color = "#8d99a6"; - let row = thead.insertRow(); - this.columns = this.fields_list.map(df => { - return { - label: df.label, - fieldname: df.fieldname - }; - }); - - let th = document.createElement("th"); - - let checkbox = document.createElement("input"); - checkbox.type = "checkbox"; - checkbox.onclick = event => - this.toggle_select_all(event.target.checked); - - th.appendChild(checkbox); - row.appendChild(th); - - add_heading(row, "Sr."); - this.columns.forEach(col => { - let th = document.createElement("th"); - let text = document.createTextNode(col.label); - th.appendChild(text); - row.appendChild(th); - }); - - function add_heading(row, label) { - let th = document.createElement("th"); - th.innerText = label; - row.appendChild(th); - } - } - - append_rows(row_data) { - const tbody = this.table.childNodes[1] || this.table.createTBody(); - row_data.forEach((data_item) => { - let row_element = tbody.insertRow(); - row_element.setAttribute("id", data_item.name); - - let row = new frappe.ui.WebFromListRow({ - row: row_element, - doc: data_item, - columns: this.columns, - serial_number: web_form_list.rows.length + 1, - events: { - onEdit: () => this.open_form(data_item.name), - onSelect: () => this.toggle_delete() - } - }); - - this.rows.push(row); - }); - } - - make_actions() { - const actions = document.querySelector(".list-view-actions"); - const footer = document.querySelector(".list-view-footer"); - - addButton(actions, "delete-rows", "danger", true, "Delete", () => - this.delete_rows() - ); - - addButton( - actions, - "new", - "primary", - false, - "New", - () => (window.location.href = window.location.pathname + "?new=1") - ); - - if (this.rows.length >= this.page_length) addButton(footer, "more", "secondary", false, "More", () => - this.more() - ); - - function addButton(wrapper, id, type, hidden, name, action) { - const button = document.createElement("button"); - button.classList.add("btn", "btn-primary", "btn-sm", "ml-2"); - if (type == "secondary") - button.classList.add( - "btn", - "btn-secondary", - "btn-sm", - "ml-2", - "text-white" - ); - if (type == "danger") - button.classList.add( - "btn", - "btn-danger", - "button-delete", - "btn-sm", - "ml-2" - ); - - button.id = id; - button.innerText = name; - button.hidden = hidden; - - button.onclick = action; - wrapper.appendChild(button); - } - } - - toggle_select_all(checked) { - this.rows.forEach(row => row.toggle_select(checked)); - } - - open_form(name) { - window.location.href = window.location.pathname + "?name=" + name; - } - - get_selected() { - return this.rows.filter(row => row.is_selected()); - } - - toggle_delete() { - let btn = document.getElementById("delete-rows"); - btn.hidden = !this.get_selected().length; - } - - delete_rows() { - frappe - .call({ - type: "POST", - method: - "frappe.website.doctype.web_form.web_form.delete_multiple", - args: { - web_form_name: this.web_form_name, - docnames: this.get_selected().map(row => row.doc.name) - } - }) - .then(() => { - this.refresh() - this.toggle_delete() - }); - } -}; - -frappe.ui.WebFromListRow = class WebFromListRow { - constructor({ row, doc, columns, serial_number, events, options }) { - Object.assign(this, { row, doc, columns, serial_number, events }); - this.make_row(); - } - - make_row() { - // Add Checkboxes - let cell = this.row.insertCell(); - - this.checkbox = document.createElement("input"); - this.checkbox.type = "checkbox"; - this.checkbox.onclick = event => { - this.toggle_select(event.target.checked); - event.stopImmediatePropagation(); - } - - cell.appendChild(this.checkbox); - - // Add Serial Number - let serialNo = this.row.insertCell(); - serialNo.innerText = this.serial_number; - - this.columns.forEach(field => { - let cell = this.row.insertCell(); - let text = document.createTextNode(this.doc[field.fieldname] || ""); - cell.appendChild(text); - }); - - this.row.onclick = () => this.events.onEdit(); - this.row.style.cursor = "pointer"; - } - - toggle_select(checked) { - this.checkbox.checked = checked; - this.events.onSelect(checked); - } - - is_selected() { - return this.checkbox.checked; - } -}; \ No newline at end of file diff --git a/frappe/public/js/frappe/web_form/web_form_list_class.js b/frappe/public/js/frappe/web_form/web_form_list_class.js new file mode 100644 index 0000000000..0b0437d242 --- /dev/null +++ b/frappe/public/js/frappe/web_form/web_form_list_class.js @@ -0,0 +1,269 @@ +frappe.provide("frappe.ui"); +frappe.provide("frappe.views"); + +window.web_form_list = null; + +frappe.views.WebFormList = class WebFormList { + constructor(opts) { + Object.assign(this, opts); + window.web_form_list = this; + this.wrapper = document.getElementById("datatable"); + this.refresh(); + this.make_actions(); + this.make_filters(); + } + + refresh() { + this.table && Array.from(this.table.tBodies).forEach(o_o => o_o.remove()); + this.rows = []; + this.page_length = 20; + this.web_list_start = 0; + + frappe.run_serially([ + () => this.get_list_view_fields(), + () => this.get_data(), + () => this.make_table(), + ]); + } + + make_filters() { + console.log("making_filters"); + } + + get_list_view_fields() { + return frappe + .call({ + method: + "frappe.website.doctype.web_form.web_form.get_in_list_view_fields", + args: { doctype: this.doctype } + }) + .then(response => (this.fields_list = response.message)); + } + + fetch_data() { + return frappe.call({ + method: "frappe.www.list.get_list_data", + args: { + doctype: this.doctype, + fields: this.fields_list.map(df => df.fieldname), + limit_start: this.web_list_start, + web_form_name: this.web_form_name + } + }); + } + + async get_data() { + let response = await this.fetch_data(); + this.data = await response.message; + } + + more() { + this.web_list_start += this.page_length + this.fetch_data().then((res) => { + if (res.message.length === 0) { + frappe.msgprint("No more items to display") + } + this.append_rows(res.message) + }) + + } + + make_table() { + this.columns = this.fields_list.map(df => { + return { + label: df.label, + fieldname: df.fieldname + }; + }); + + if (! this.table) { + this.table = document.createElement("table"); + this.table.classList.add("table"); + this.make_table_head(); + } + + this.append_rows(this.data); + + this.wrapper.appendChild(this.table); + } + + make_table_head() { + // Create Heading + let thead = this.table.createTHead(); + thead.style.backgroundColor = "#f7fafc"; + thead.style.color = "#8d99a6"; + let row = thead.insertRow(); + + let th = document.createElement("th"); + + let checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.onclick = event => + this.toggle_select_all(event.target.checked); + + th.appendChild(checkbox); + row.appendChild(th); + + add_heading(row, "Sr."); + this.columns.forEach(col => { + let th = document.createElement("th"); + let text = document.createTextNode(col.label); + th.appendChild(text); + row.appendChild(th); + }); + + function add_heading(row, label) { + let th = document.createElement("th"); + th.innerText = label; + row.appendChild(th); + } + } + + append_rows(row_data) { + const tbody = this.table.childNodes[1] || this.table.createTBody(); + row_data.forEach((data_item) => { + let row_element = tbody.insertRow(); + row_element.setAttribute("id", data_item.name); + + let row = new frappe.ui.WebFromListRow({ + row: row_element, + doc: data_item, + columns: this.columns, + serial_number: web_form_list.rows.length + 1, + events: { + onEdit: () => this.open_form(data_item.name), + onSelect: () => this.toggle_delete() + } + }); + + this.rows.push(row); + }); + } + + make_actions() { + const actions = document.querySelector(".list-view-actions"); + const footer = document.querySelector(".list-view-footer"); + + addButton(actions, "delete-rows", "danger", true, "Delete", () => + this.delete_rows() + ); + + addButton( + actions, + "new", + "primary", + false, + "New", + () => (window.location.href = window.location.pathname + "?new=1") + ); + + if (this.rows.length >= this.page_length) addButton(footer, "more", "secondary", false, "More", () => + this.more() + ); + + function addButton(wrapper, id, type, hidden, name, action) { + const button = document.createElement("button"); + button.classList.add("btn", "btn-primary", "btn-sm", "ml-2"); + if (type == "secondary") + button.classList.add( + "btn", + "btn-secondary", + "btn-sm", + "ml-2", + "text-white" + ); + if (type == "danger") + button.classList.add( + "btn", + "btn-danger", + "button-delete", + "btn-sm", + "ml-2" + ); + + button.id = id; + button.innerText = name; + button.hidden = hidden; + + button.onclick = action; + wrapper.appendChild(button); + } + } + + toggle_select_all(checked) { + this.rows.forEach(row => row.toggle_select(checked)); + } + + open_form(name) { + window.location.href = window.location.pathname + "?name=" + name; + } + + get_selected() { + return this.rows.filter(row => row.is_selected()); + } + + toggle_delete() { + let btn = document.getElementById("delete-rows"); + btn.hidden = !this.get_selected().length; + } + + delete_rows() { + frappe + .call({ + type: "POST", + method: + "frappe.website.doctype.web_form.web_form.delete_multiple", + args: { + web_form_name: this.web_form_name, + docnames: this.get_selected().map(row => row.doc.name) + } + }) + .then(() => { + this.refresh() + this.toggle_delete() + }); + } +}; + +frappe.ui.WebFromListRow = class WebFromListRow { + constructor({ row, doc, columns, serial_number, events, options }) { + Object.assign(this, { row, doc, columns, serial_number, events }); + this.make_row(); + } + + make_row() { + // Add Checkboxes + let cell = this.row.insertCell(); + + this.checkbox = document.createElement("input"); + this.checkbox.type = "checkbox"; + this.checkbox.onclick = event => { + this.toggle_select(event.target.checked); + event.stopImmediatePropagation(); + } + + cell.appendChild(this.checkbox); + + // Add Serial Number + let serialNo = this.row.insertCell(); + serialNo.innerText = this.serial_number; + + this.columns.forEach(field => { + let cell = this.row.insertCell(); + let text = document.createTextNode(this.doc[field.fieldname] || ""); + cell.appendChild(text); + }); + + this.row.onclick = () => this.events.onEdit(); + this.row.style.cursor = "pointer"; + } + + toggle_select(checked) { + this.checkbox.checked = checked; + this.events.onSelect(checked); + } + + is_selected() { + return this.checkbox.checked; + } +}; \ No newline at end of file diff --git a/frappe/website/doctype/web_form/templates/web_form.html b/frappe/website/doctype/web_form/templates/web_form.html index f8d5b6f179..bce669f412 100644 --- a/frappe/website/doctype/web_form/templates/web_form.html +++ b/frappe/website/doctype/web_form/templates/web_form.html @@ -21,8 +21,13 @@ {% block page_content %}
+
+
+{% if is_list %} +
+{% endif %} {% endblock %} {% block script %} diff --git a/package.json b/package.json index 59f402dae1..27dc664dbd 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "cypress": "^3.1.1", "cypress-file-upload": "^3.1.0", "less": "^3.0.4", - "node-sass": "^4.11.0", + "node-sass": "^4.12.0", "rollup": "^1.2.2", "rollup-plugin-buble": "^0.19.2", "rollup-plugin-commonjs": "^8.3.0", diff --git a/yarn.lock b/yarn.lock index 7ee8775740..d1e9c484d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2703,21 +2703,11 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= -lodash.clonedeep@^4.3.2: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -2728,11 +2718,6 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.mergewith@^4.6.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" - integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== - lodash.once@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" @@ -2743,7 +2728,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.11, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.5, lodash@~4.17.10: +lodash@4.17.11, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.11, lodash@^4.17.5, lodash@~4.17.10: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -2998,10 +2983,10 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -nan@^2.10.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== +nan@^2.13.2: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanomatch@^1.2.9: version "1.2.13" @@ -3055,10 +3040,10 @@ node-releases@^1.1.8: dependencies: semver "^5.3.0" -node-sass@^4.11.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.11.0.tgz#183faec398e9cbe93ba43362e2768ca988a6369a" - integrity sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA== +node-sass@^4.12.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" + integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -3067,12 +3052,10 @@ node-sass@^4.11.0: get-stdin "^4.0.1" glob "^7.0.3" in-publish "^2.0.0" - lodash.assign "^4.2.0" - lodash.clonedeep "^4.3.2" - lodash.mergewith "^4.6.0" + lodash "^4.17.11" meow "^3.7.0" mkdirp "^0.5.1" - nan "^2.10.0" + nan "^2.13.2" node-gyp "^3.8.0" npmlog "^4.0.0" request "^2.88.0"