From 1903ac12cd17a2d7dc3a73d22d1914ef30ebec88 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 16 May 2022 22:43:29 +1000 Subject: [PATCH 1/2] Allow customization of button class in modal forms --- InvenTree/templates/js/translated/forms.js | 1 + InvenTree/templates/js/translated/modals.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/InvenTree/templates/js/translated/forms.js b/InvenTree/templates/js/translated/forms.js index 642523a60b..d45a2de78c 100644 --- a/InvenTree/templates/js/translated/forms.js +++ b/InvenTree/templates/js/translated/forms.js @@ -288,6 +288,7 @@ function constructDeleteForm(fields, options) { * - method: The HTTP method e.g. 'PUT', 'POST', 'DELETE' (default='PATCH') * - title: The form title * - submitText: Text for the "submit" button + * - submitClass: CSS class for the "submit" button (default = ') * - closeText: Text for the "close" button * - fields: list of fields to display, with the following options * - filters: API query filters diff --git a/InvenTree/templates/js/translated/modals.js b/InvenTree/templates/js/translated/modals.js index 85f503682e..464006ae12 100644 --- a/InvenTree/templates/js/translated/modals.js +++ b/InvenTree/templates/js/translated/modals.js @@ -42,6 +42,8 @@ function createNewModal(options={}) { } }); + var submitClass = options.submitClass || 'primary'; + var html = ` From 6658b899460f544c5c9f76858586c5c6e9489cba Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 16 May 2022 22:51:34 +1000 Subject: [PATCH 2/2] Refactor BOM item deletion - Send delete requests sequentially, rather than simultaneously - Prevents server overload - Present a much cleaner dialog to the user --- InvenTree/part/templates/part/detail.html | 31 ++------ InvenTree/templates/js/translated/bom.js | 96 ++++++++++++++++++++--- 2 files changed, 93 insertions(+), 34 deletions(-) diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index bcedc95da8..1c80a88c28 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -589,32 +589,15 @@ // Get a list of the selected BOM items var rows = $("#bom-table").bootstrapTable('getSelections'); - // TODO - In the future, display (in the dialog) which items are going to be deleted + if (rows.length == 0) { + rows = $('#bom-table').bootstrapTable('getData'); + } - showQuestionDialog( - '{% trans "Delete selected BOM items?" %}', - '{% trans "All selected BOM items will be deleted" %}', - { - accept: function() { - - // Keep track of each DELETE request - var requests = []; - - rows.forEach(function(row) { - requests.push( - inventreeDelete( - `/api/bom/${row.pk}/`, - ) - ); - }); - - // Wait for *all* the requests to complete - $.when.apply($, requests).done(function() { - location.reload(); - }); - } + deleteBomItems(rows, { + success: function() { + $('#bom-table').bootstrapTable('refresh'); } - ); + }); }); $('#bom-upload').click(function() { diff --git a/InvenTree/templates/js/translated/bom.js b/InvenTree/templates/js/translated/bom.js index 9bd66877da..0119b36664 100644 --- a/InvenTree/templates/js/translated/bom.js +++ b/InvenTree/templates/js/translated/bom.js @@ -16,6 +16,7 @@ /* exported constructBomUploadTable, + deleteBomItems, downloadBomTemplate, exportBom, newPartFromBomWizard, @@ -647,7 +648,88 @@ function bomSubstitutesDialog(bom_item_id, substitutes, options={}) { reloadParentTable(); } }); +} + +function deleteBomItems(items, options={}) { + /* Delete the selected BOM items from the database + */ + + function renderItem(item, opts={}) { + + var sub_part = item.sub_part_detail; + var thumb = thumbnailImage(sub_part.thumbnail || sub_part.image); + + var html = ` + + ${thumb} ${sub_part.full_name} + ${item.reference} + ${item.quantity} + + `; + + return html; + } + + var rows = ''; + + items.forEach(function(item) { + rows += renderItem(item); + }); + + var html = ` +
+ {% trans "All selected BOM items will be deleted" %} +
+ + + + + + + + ${rows} +
{% trans "Part" %}{% trans "Reference" %}{% trans "Quantity" %}
+ `; + + constructFormBody({}, { + title: '{% trans "Delete selected BOM items?" %}', + fields: {}, + preFormContent: html, + submitText: '{% trans "Delete" %}', + submitClass: 'danger', + confirm: true, + onSubmit: function(fields, opts) { + // Individually send DELETE requests for each BOM item + // We do *not* send these all at once, to prevent overloading the server + + // Show the progress spinner + $(opts.modal).find('#modal-progress-spinner').show(); + + function deleteNextBomItem() { + + if (items.length > 0) { + + var item = items.shift(); + + inventreeDelete(`/api/bom/${item.pk}/`, + { + complete: deleteNextBomItem, + } + ); + } else { + // Destroy this modal once all items are deleted + $(opts.modal).modal('hide'); + + if (options.success) { + options.success(); + } + } + } + + deleteNextBomItem(); + }, + }); } @@ -1146,19 +1228,13 @@ function loadBomTable(table, options={}) { var pk = $(this).attr('pk'); - var html = ` -
- {% trans "Are you sure you want to delete this BOM item?" %} -
`; + var item = table.bootstrapTable('getRowByUniqueId', pk); - constructForm(`/api/bom/${pk}/`, { - method: 'DELETE', - title: '{% trans "Delete BOM Item" %}', - preFormContent: html, - onSuccess: function() { + deleteBomItems([item], { + success: function() { reloadBomTable(table); } - }); + }); }); // Callback for "edit" button