From 62455199f3f150566489408368f48fa59a2620a2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 21 Feb 2023 07:24:49 +1100 Subject: [PATCH] Js forms updates (#4378) * Refactor forms for creating and editing SalesOrder - Common function for defining fields * More visual improvements for forms * Refactor fields for SupplierPartPriceBreak * More refactoring * Refactor for stockitemtestresult table * Comment fields * JS linting fix --- .../templates/company/supplier_part.html | 25 +-- .../templates/order/sales_order_base.html | 23 +-- InvenTree/part/templates/part/detail.html | 14 +- InvenTree/stock/templates/stock/item.html | 14 +- .../stock/templates/stock/item_base.html | 4 +- .../templates/js/translated/attachment.js | 20 +- InvenTree/templates/js/translated/bom.js | 5 +- InvenTree/templates/js/translated/build.js | 4 +- InvenTree/templates/js/translated/company.js | 47 ++++- InvenTree/templates/js/translated/order.js | 173 +++++++++++------- InvenTree/templates/js/translated/part.js | 60 ++++-- InvenTree/templates/js/translated/stock.js | 50 +++-- 12 files changed, 267 insertions(+), 172 deletions(-) diff --git a/InvenTree/company/templates/company/supplier_part.html b/InvenTree/company/templates/company/supplier_part.html index 82d0311f96..58ac0fa0eb 100644 --- a/InvenTree/company/templates/company/supplier_part.html +++ b/InvenTree/company/templates/company/supplier_part.html @@ -299,27 +299,12 @@ loadSupplierPriceBreakTable({ }); $('#new-price-break').click(function() { - - constructForm( - '{% url "api-part-supplier-price-list" %}', - { - method: 'POST', - fields: { - quantity: {}, - part: { - value: {{ part.pk }}, - hidden: true, - }, - price: {}, - price_currency: { - }, - }, - title: '{% trans "Add Price Break" %}', - onSuccess: function() { - $("#price-break-table").bootstrapTable("refresh"); - } + createSupplierPartPriceBreak({{ part.pk }}, { + onSuccess: function() { + $("#price-break-table").bootstrapTable("refresh"); } - ); + }); + }); loadPurchaseOrderTable($("#purchase-order-table"), { diff --git a/InvenTree/order/templates/order/sales_order_base.html b/InvenTree/order/templates/order/sales_order_base.html index b0ab15be67..2521f92bb9 100644 --- a/InvenTree/order/templates/order/sales_order_base.html +++ b/InvenTree/order/templates/order/sales_order_base.html @@ -206,28 +206,7 @@ src="{% static 'img/blank_image.png' %}" $("#edit-order").click(function() { - constructForm('{% url "api-so-detail" order.pk %}', { - fields: { - reference: { - icon: 'fa-hashtag', - }, - {% if order.lines.count == 0 and order.status == SalesOrderStatus.PENDING %} - customer: { - }, - {% endif %} - customer_reference: {}, - description: {}, - target_date: { - icon: 'fa-calendar-alt', - }, - link: { - icon: 'fa-link', - }, - responsible: { - icon: 'fa-user', - }, - }, - title: '{% trans "Edit Sales Order" %}', + editSalesOrder({{ order.pk }}, { reload: true, }); }); diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index f064f6a8cb..372eecd076 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -793,17 +793,9 @@ constructForm('{% url "api-part-test-template-list" %}', { method: 'POST', - fields: { - test_name: {}, - description: {}, - required: {}, - requires_value: {}, - requires_attachment: {}, - part: { - value: {{ part.pk }}, - hidden: true, - } - }, + fields: partTestTemplateFields({ + part: {{ part.pk }} + }), title: '{% trans "Add Test Result Template" %}', onSuccess: function() { $("#test-template-table").bootstrapTable("refresh"); diff --git a/InvenTree/stock/templates/stock/item.html b/InvenTree/stock/templates/stock/item.html index 22e43be7b6..15e905f96e 100644 --- a/InvenTree/stock/templates/stock/item.html +++ b/InvenTree/stock/templates/stock/item.html @@ -313,17 +313,9 @@ constructForm('{% url "api-stock-test-result-list" %}', { method: 'POST', - fields: { - test: {}, - result: {}, - value: {}, - attachment: {}, - notes: {}, - stock_item: { - value: {{ item.pk }}, - hidden: true, - } - }, + fields: stockItemTestResultFields({ + stock_item: {{ item.pk }}, + }), title: '{% trans "Add Test Result" %}', onSuccess: reloadTable, }); diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index ffe49237f1..2ec331e233 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -640,7 +640,9 @@ $("#stock-return-from-customer").click(function() { value: {{ item.part.default_location.pk }}, {% endif %} }, - notes: {}, + notes: { + icon: 'fa-sticky-note', + }, }, method: 'POST', title: '{% trans "Return to Stock" %}', diff --git a/InvenTree/templates/js/translated/attachment.js b/InvenTree/templates/js/translated/attachment.js index e56f5928ef..2ef3018123 100644 --- a/InvenTree/templates/js/translated/attachment.js +++ b/InvenTree/templates/js/translated/attachment.js @@ -25,7 +25,9 @@ function addAttachmentButtonCallbacks(url, fields={}) { var file_fields = { attachment: {}, - comment: {}, + comment: { + icon: 'fa-comment', + }, }; Object.assign(file_fields, fields); @@ -42,8 +44,12 @@ function addAttachmentButtonCallbacks(url, fields={}) { $('#new-attachment-link').click(function() { var link_fields = { - link: {}, - comment: {}, + link: { + icon: 'fa-link', + }, + comment: { + icon: 'fa-comment', + }, }; Object.assign(link_fields, fields); @@ -252,8 +258,12 @@ function loadAttachmentTable(url, options) { constructForm(`${url}${pk}/`, { fields: { - link: {}, - comment: {}, + link: { + icon: 'fa-link', + }, + comment: { + icon: 'fa-comment', + }, }, processResults: function(data, fields, opts) { // Remove the "link" field if the attachment is a file! diff --git a/InvenTree/templates/js/translated/bom.js b/InvenTree/templates/js/translated/bom.js index 4e94c014b0..4d277e9620 100644 --- a/InvenTree/templates/js/translated/bom.js +++ b/InvenTree/templates/js/translated/bom.js @@ -408,6 +408,7 @@ function bomItemFields() { hidden: true, }, sub_part: { + icon: 'fa-shapes', secondary: { title: '{% trans "New Part" %}', fields: function() { @@ -424,7 +425,9 @@ function bomItemFields() { quantity: {}, reference: {}, overage: {}, - note: {}, + note: { + icon: 'fa-sticky-note', + }, allow_variants: {}, inherited: {}, consumable: {}, diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index ef8ad46109..7d410a2a54 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -536,7 +536,9 @@ function completeBuildOutputs(build_id, outputs, options={}) { structural: false, }, }, - notes: {}, + notes: { + icon: 'fa-sticky-note', + }, accept_incomplete_allocation: {}, }, confirm: true, diff --git a/InvenTree/templates/js/translated/company.js b/InvenTree/templates/js/translated/company.js index 16b3ae9458..10eee69f48 100644 --- a/InvenTree/templates/js/translated/company.js +++ b/InvenTree/templates/js/translated/company.js @@ -13,11 +13,13 @@ createCompany, createManufacturerPart, createSupplierPart, + createSupplierPartPriceBreak, deleteManufacturerParts, deleteManufacturerPartParameters, deleteSupplierParts, duplicateSupplierPart, editCompany, + editSupplierPartPriceBreak, loadCompanyTable, loadManufacturerPartTable, loadManufacturerPartParameterTable, @@ -128,7 +130,7 @@ function supplierPartFields(options={}) { icon: 'fa-link', }, note: { - icon: 'fa-pencil-alt', + icon: 'fa-sticky-note', }, packaging: { icon: 'fa-box', @@ -321,6 +323,43 @@ function deleteSupplierParts(parts, options={}) { } +/* Construct set of fields for SupplierPartPriceBreak form */ +function supplierPartPriceBreakFields(options={}) { + let fields = { + part: { + hidden: true, + }, + quantity: {}, + price: { + icon: 'fa-dollar-sign', + }, + price_currency: { + icon: 'fa-coins', + }, + }; + + return fields; +} + +/* Create a new SupplierPartPriceBreak instance */ +function createSupplierPartPriceBreak(part_id, options={}) { + + let fields = supplierPartPriceBreakFields(options); + + fields.part.value = part_id; + + constructForm('{% url "api-part-supplier-price-list" %}', { + fields: fields, + method: 'POST', + fields: fields, + title: '{% trans "Add Price Break" %}', + onSuccess: function(response) { + handleFormSuccess(response, options); + } + }); +} + + // Returns a default form-set for creating / editing a Company object function companyFormFields() { @@ -1125,11 +1164,7 @@ function loadSupplierPriceBreakTable(options={}) { var pk = $(this).attr('pk'); constructForm(`/api/company/price-break/${pk}/`, { - fields: { - quantity: {}, - price: {}, - price_currency: {}, - }, + fields: supplierPartPriceBreakFields(), title: '{% trans "Edit Price Break" %}', onSuccess: function() { table.bootstrapTable('refresh'); diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js index f1044c020d..9bdef47dd0 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -35,6 +35,7 @@ duplicatePurchaseOrder, editPurchaseOrder, editPurchaseOrderLineItem, + editSalesOrder, exportOrder, issuePurchaseOrder, loadPurchaseOrderLineItemTable, @@ -55,6 +56,9 @@ */ +/* + * Form field definitions for a SalesOrderShipment + */ function salesOrderShipmentFields(options={}) { var fields = { order: {}, @@ -520,42 +524,55 @@ function createSalesOrderShipment(options={}) { } +function salesOrderFields(options={}) { + let fields = { + reference: { + icon: 'fa-hashtag', + }, + description: {}, + customer: { + icon: 'fa-user-tie', + secondary: { + title: '{% trans "Add Customer" %}', + fields: function() { + var fields = companyFormFields(); + + fields.is_customer.value = true; + + return fields; + } + } + }, + customer_reference: {}, + target_date: { + icon: 'fa-calendar-alt', + }, + link: { + icon: 'fa-link', + }, + responsible: { + icon: 'fa-user', + } + }; + + return fields; +} + + /* * Create a new SalesOrder */ function createSalesOrder(options={}) { + let fields = salesOrderFields(options); + + if (options.customer) { + fields.customer.value = options.customer; + } + constructForm('{% url "api-so-list" %}', { method: 'POST', - fields: { - reference: { - icon: 'fa-hashtag', - }, - customer: { - value: options.customer, - secondary: { - title: '{% trans "Add Customer" %}', - fields: function() { - var fields = companyFormFields(); - - fields.is_customer.value = true; - - return fields; - } - } - }, - customer_reference: {}, - description: {}, - target_date: { - icon: 'fa-calendar-alt', - }, - link: { - icon: 'fa-link', - }, - responsible: { - icon: 'fa-user', - } - }, + fields: fields, onSuccess: function(data) { location.href = `/order/sales-order/${data.pk}/`; }, @@ -564,12 +581,27 @@ function createSalesOrder(options={}) { } +/* + * Edit an existing SalesOrder + */ +function editSalesOrder(order_id, options={}) { + + constructForm(`/api/order/so/${order_id}/`, { + fields: salesOrderFields(options), + title: '{% trans "Edit Sales Order" %}', + onSuccess: function(response) { + handleFormSuccess(response, options); + } + }); +} + + /* * Launch a modal form to create a new SalesOrderLineItem */ function createSalesOrderLineItem(options={}) { - var fields = soLineItemFields(options); + let fields = soLineItemFields(options); constructForm('{% url "api-so-line-list" %}', { fields: fields, @@ -591,6 +623,7 @@ function purchaseOrderFields(options={}) { reference: { icon: 'fa-hashtag', }, + description: {}, supplier: { icon: 'fa-building', secondary: { @@ -604,7 +637,6 @@ function purchaseOrderFields(options={}) { } } }, - description: {}, supplier_reference: {}, target_date: { icon: 'fa-calendar-alt', @@ -758,17 +790,27 @@ function createPurchaseOrderLineItem(order, options={}) { /* Construct a set of fields for the SalesOrderLineItem form */ function soLineItemFields(options={}) { - var fields = { + let fields = { order: { hidden: true, }, - part: {}, + part: { + icon: 'fa-shapes', + }, quantity: {}, reference: {}, - sale_price: {}, - sale_price_currency: {}, - target_date: {}, - notes: {}, + sale_price: { + icon: 'fa-dollar-sign', + }, + sale_price_currency: { + icon: 'fa-coins', + }, + target_date: { + icon: 'fa-calendar-alt', + }, + notes: { + icon: 'fa-sticky-note', + }, }; if (options.order) { @@ -792,9 +834,15 @@ function extraLineFields(options={}) { }, quantity: {}, reference: {}, - price: {}, - price_currency: {}, - notes: {}, + price: { + icon: 'fa-dollar-sign', + }, + price_currency: { + icon: 'fa-coins', + }, + notes: { + icon: 'fa-sticky-note', + }, }; if (options.order) { @@ -815,6 +863,7 @@ function poLineItemFields(options={}) { } }, part: { + icon: 'fa-shapes', filters: { part_detail: true, supplier_detail: true, @@ -911,15 +960,24 @@ function poLineItemFields(options={}) { }, quantity: {}, reference: {}, - purchase_price: {}, - purchase_price_currency: {}, - target_date: {}, + purchase_price: { + icon: 'fa-dollar-sign', + }, + purchase_price_currency: { + icon: 'fa-coins', + }, + target_date: { + icon: 'fa-calendar-alt', + }, destination: { + icon: 'fa-sitemap', filters: { structural: false, } }, - notes: {}, + notes: { + icon: 'fa-sticky-note', + }, }; if (options.order) { @@ -2655,13 +2713,7 @@ function loadPurchaseOrderExtraLineTable(table, options={}) { var pk = $(this).attr('pk'); constructForm(`/api/order/po-extra-line/${pk}/`, { - fields: { - quantity: {}, - reference: {}, - price: {}, - price_currency: {}, - notes: {}, - }, + fields: extraLineFields(), title: '{% trans "Edit Line" %}', onSuccess: reloadTable, }); @@ -4102,7 +4154,7 @@ function loadSalesOrderLineItemTable(table, options={}) { inventreeGet(`/api/order/so-line/${pk}/`, {}, { success: function(data) { - var fields = soLineItemFields(); + let fields = soLineItemFields(); constructForm('{% url "api-so-line-list" %}', { method: 'POST', @@ -4122,14 +4174,7 @@ function loadSalesOrderLineItemTable(table, options={}) { var pk = $(this).attr('pk'); constructForm(`/api/order/so-line/${pk}/`, { - fields: { - quantity: {}, - reference: {}, - sale_price: {}, - sale_price_currency: {}, - target_date: {}, - notes: {}, - }, + fields: soLineItemFields(), title: '{% trans "Edit Line Item" %}', onSuccess: reloadTable, }); @@ -4465,13 +4510,7 @@ function loadSalesOrderExtraLineTable(table, options={}) { var pk = $(this).attr('pk'); constructForm(`/api/order/so-extra-line/${pk}/`, { - fields: { - quantity: {}, - reference: {}, - price: {}, - price_currency: {}, - notes: {}, - }, + fields: extraLineFields(), title: '{% trans "Edit Line" %}', onSuccess: reloadTable, }); diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index 5f944fdc7c..94ffbc5333 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -41,6 +41,7 @@ loadSimplePartTable, partDetail, partStockLabel, + partTestTemplateFields, toggleStar, validateBom, */ @@ -108,11 +109,13 @@ function partFields(options={}) { icon: 'fa-link', }, default_location: { + icon: 'fa-sitemap', filters: { structural: false, } }, default_supplier: { + icon: 'fa-building', filters: { part_detail: true, supplier_detail: true, @@ -253,6 +256,7 @@ function categoryFields() { name: {}, description: {}, default_location: { + icon: 'fa-sitemap', filters: { structural: false, } @@ -978,11 +982,21 @@ function loadPartStocktakeTable(partId, options={}) { fields: { item_count: {}, quantity: {}, - cost_min: {}, - cost_min_currency: {}, - cost_max: {}, - cost_max_currency: {}, - note: {}, + cost_min: { + icon: 'fa-dollar-sign', + }, + cost_min_currency: { + icon: 'fa-coins', + }, + cost_max: { + icon: 'fa-dollar-sign', + }, + cost_max_currency: { + icon: 'fa-coins', + }, + note: { + icon: 'fa-sticky-note', + }, }, title: '{% trans "Edit Stocktake Entry" %}', onSuccess: function() { @@ -2403,10 +2417,32 @@ function loadPartCategoryTable(table, options) { }); } + +/* Construct a set of fields for the PartTestTemplate model form */ +function partTestTemplateFields(options={}) { + let fields = { + test_name: {}, + description: {}, + required: {}, + requires_value: {}, + requires_attachment: {}, + part: { + hidden: true, + } + }; + + if (options.part) { + fields.part.value = options.part; + } + + return fields; +} + + +/* + * Load PartTestTemplate table. + */ function loadPartTestTemplateTable(table, options) { - /* - * Load PartTestTemplate table. - */ var params = options.params || {}; @@ -2505,13 +2541,7 @@ function loadPartTestTemplateTable(table, options) { var url = `/api/part/test-template/${pk}/`; constructForm(url, { - fields: { - test_name: {}, - description: {}, - required: {}, - requires_value: {}, - requires_attachment: {}, - }, + fields: partTestTemplateFields(), title: '{% trans "Edit Test Result Template" %}', onSuccess: function() { table.bootstrapTable('refresh'); diff --git a/InvenTree/templates/js/translated/stock.js b/InvenTree/templates/js/translated/stock.js index 356b000463..bf6784ae81 100644 --- a/InvenTree/templates/js/translated/stock.js +++ b/InvenTree/templates/js/translated/stock.js @@ -315,7 +315,9 @@ function stockItemFields(options={}) { purchase_price: { icon: 'fa-dollar-sign', }, - purchase_price_currency: {}, + purchase_price_currency: { + icon: 'fa-coins', + }, packaging: { icon: 'fa-box', }, @@ -686,7 +688,9 @@ function assignStockToCustomer(items, options={}) { is_customer: true, }, }, - notes: {}, + notes: { + icon: 'fa-sticky-note', + }, }, confirm: true, confirmMessage: '{% trans "Confirm stock assignment" %}', @@ -855,7 +859,9 @@ function mergeStockItems(items, options={}) { structural: false, } }, - notes: {}, + notes: { + icon: 'fa-sticky-note', + }, allow_mismatched_suppliers: {}, allow_mismatched_status: {}, }, @@ -1299,6 +1305,28 @@ function formatDate(row) { return html; } +/* Construct set of default fields for a StockItemTestResult */ +function stockItemTestResultFields(options={}) { + let fields = { + test: {}, + result: {}, + value: {}, + attachment: {}, + notes: { + icon: 'fa-sticky-note', + }, + stock_item: { + hidden: true, + }, + }; + + if (options.stock_item) { + fields.stock_item.value = options.stock_item; + } + + return fields; +} + /* * Load StockItemTestResult table */ @@ -1564,7 +1592,9 @@ function loadStockTestResultsTable(table, options) { result: {}, value: {}, attachment: {}, - notes: {}, + notes: { + icon: 'fa-sticky-note', + }, stock_item: { value: options.stock_item, hidden: true, @@ -1584,13 +1614,7 @@ function loadStockTestResultsTable(table, options) { var url = `/api/stock/test/${pk}/`; constructForm(url, { - fields: { - test: {}, - result: {}, - value: {}, - attachment: {}, - notes: {}, - }, + fields: stockItemTestResultFields(), title: '{% trans "Edit Test Result" %}', onSuccess: reloadTestTable, }); @@ -2860,7 +2884,9 @@ function uninstallStockItem(installed_item_id, options={}) { structural: false, } }, - note: {}, + note: { + icon: 'fa-sticky-note', + }, }, preFormContent: function(opts) { var html = '';