mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 04:55:44 +00:00
Adds API mixin for "bulk delete" (#3146)
* Introduces a BulkDelete API mixin class - Allows deletion of multiple items against a single API request * Bump API version * Adds BulkDelete mixin to StockItemTestResult API class * refactor "multi BOM Item delete" to use new approach * Refactor various attachment API endpoints * Refactor multi delete for StockItem * Convert remaining enndpoints over * Fix for API test code
This commit is contained in:
@ -7,7 +7,6 @@
|
||||
/* exported
|
||||
inventreeGet,
|
||||
inventreeDelete,
|
||||
inventreeMultiDelete,
|
||||
inventreeFormDataUpload,
|
||||
showApiError,
|
||||
*/
|
||||
@ -160,59 +159,20 @@ function inventreePut(url, data={}, options={}) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Performs a DELETE API call to the server
|
||||
*/
|
||||
function inventreeDelete(url, options={}) {
|
||||
/*
|
||||
* Delete a record
|
||||
*/
|
||||
|
||||
options = options || {};
|
||||
|
||||
options.method = 'DELETE';
|
||||
|
||||
return inventreePut(url, {}, options);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform a 'multi delete' operation:
|
||||
*
|
||||
* - Items are deleted sequentially from the database, rather than simultaneous requests
|
||||
* - This prevents potential overload / transaction issues in the DB backend
|
||||
*
|
||||
* Notes:
|
||||
* - Assumes that each item in the 'items' list has a parameter 'pk'
|
||||
*/
|
||||
function inventreeMultiDelete(url, items, options={}) {
|
||||
|
||||
if (!url.endsWith('/')) {
|
||||
url += '/';
|
||||
}
|
||||
|
||||
function doNextDelete() {
|
||||
if (items.length > 0) {
|
||||
var item = items.shift();
|
||||
|
||||
inventreeDelete(`${url}${item.pk}/`, {
|
||||
complete: doNextDelete
|
||||
});
|
||||
} else {
|
||||
if (options.modal) {
|
||||
$(options.modal).modal('hide');
|
||||
}
|
||||
|
||||
if (options.success) {
|
||||
options.success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.modal) {
|
||||
showModalSpinner(options.modal);
|
||||
}
|
||||
|
||||
// Initiate the process
|
||||
doNextDelete();
|
||||
|
||||
return inventreePut(
|
||||
url,
|
||||
options.data || {},
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,9 +86,11 @@ function deleteAttachments(attachments, url, options={}) {
|
||||
}
|
||||
|
||||
var rows = '';
|
||||
var ids = [];
|
||||
|
||||
attachments.forEach(function(att) {
|
||||
rows += renderAttachment(att);
|
||||
ids.push(att.pk);
|
||||
});
|
||||
|
||||
var html = `
|
||||
@ -105,22 +107,16 @@ function deleteAttachments(attachments, url, options={}) {
|
||||
</table>
|
||||
`;
|
||||
|
||||
constructFormBody({}, {
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Attachments" %}',
|
||||
preFormContent: html,
|
||||
onSubmit: function(fields, opts) {
|
||||
inventreeMultiDelete(
|
||||
url,
|
||||
attachments,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: function() {
|
||||
// Refresh the table once all attachments are deleted
|
||||
$('#attachment-table').bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
);
|
||||
form_data: {
|
||||
items: ids,
|
||||
},
|
||||
onSuccess: function() {
|
||||
// Refresh the table once all attachments are deleted
|
||||
$('#attachment-table').bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -672,9 +672,11 @@ function deleteBomItems(items, options={}) {
|
||||
}
|
||||
|
||||
var rows = '';
|
||||
var ids = [];
|
||||
|
||||
items.forEach(function(item) {
|
||||
rows += renderItem(item);
|
||||
ids.push(item.pk);
|
||||
});
|
||||
|
||||
var html = `
|
||||
@ -692,22 +694,14 @@ function deleteBomItems(items, options={}) {
|
||||
</table>
|
||||
`;
|
||||
|
||||
constructFormBody({}, {
|
||||
constructForm('{% url "api-bom-list" %}', {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete selected BOM items?" %}',
|
||||
fields: {},
|
||||
preFormContent: html,
|
||||
onSubmit: function(fields, opts) {
|
||||
|
||||
inventreeMultiDelete(
|
||||
'{% url "api-bom-list" %}',
|
||||
items,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: options.success,
|
||||
}
|
||||
);
|
||||
form_data: {
|
||||
items: ids,
|
||||
},
|
||||
preFormContent: html,
|
||||
onSuccess: options.success,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
/* globals
|
||||
constructForm,
|
||||
imageHoverIcon,
|
||||
inventreeMultiDelete,
|
||||
loadTableFilters,
|
||||
makeIconButton,
|
||||
renderLink,
|
||||
@ -238,9 +237,11 @@ function deleteSupplierParts(parts, options={}) {
|
||||
}
|
||||
|
||||
var rows = '';
|
||||
var ids = [];
|
||||
|
||||
parts.forEach(function(sup_part) {
|
||||
rows += renderPart(sup_part);
|
||||
ids.push(sup_part.pk);
|
||||
});
|
||||
|
||||
var html = `
|
||||
@ -258,21 +259,14 @@ function deleteSupplierParts(parts, options={}) {
|
||||
</table>
|
||||
`;
|
||||
|
||||
constructFormBody({}, {
|
||||
constructForm('{% url "api-supplier-part-list" %}', {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Supplier Parts" %}',
|
||||
preFormContent: html,
|
||||
onSubmit: function(fields, opts) {
|
||||
|
||||
inventreeMultiDelete(
|
||||
'{% url "api-supplier-part-list" %}',
|
||||
parts,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: options.success
|
||||
}
|
||||
);
|
||||
}
|
||||
form_data: {
|
||||
items: ids,
|
||||
},
|
||||
onSuccess: options.success,
|
||||
});
|
||||
}
|
||||
|
||||
@ -472,9 +466,11 @@ function deleteManufacturerParts(selections, options={}) {
|
||||
}
|
||||
|
||||
var rows = '';
|
||||
var ids = [];
|
||||
|
||||
selections.forEach(function(man_part) {
|
||||
rows += renderPart(man_part);
|
||||
ids.push(man_part.pk);
|
||||
});
|
||||
|
||||
var html = `
|
||||
@ -491,21 +487,14 @@ function deleteManufacturerParts(selections, options={}) {
|
||||
</table>
|
||||
`;
|
||||
|
||||
constructFormBody({}, {
|
||||
constructForm('{% url "api-manufacturer-part-list" %}', {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Manufacturer Parts" %}',
|
||||
preFormContent: html,
|
||||
onSubmit: function(fields, opts) {
|
||||
|
||||
inventreeMultiDelete(
|
||||
'{% url "api-manufacturer-part-list" %}',
|
||||
selections,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: options.success,
|
||||
}
|
||||
);
|
||||
}
|
||||
form_data: {
|
||||
items: ids,
|
||||
},
|
||||
onSuccess: options.success,
|
||||
});
|
||||
}
|
||||
|
||||
@ -525,9 +514,11 @@ function deleteManufacturerPartParameters(selections, options={}) {
|
||||
}
|
||||
|
||||
var rows = '';
|
||||
var ids = [];
|
||||
|
||||
selections.forEach(function(param) {
|
||||
rows += renderParam(param);
|
||||
ids.push(param.pk);
|
||||
});
|
||||
|
||||
var html = `
|
||||
@ -543,20 +534,14 @@ function deleteManufacturerPartParameters(selections, options={}) {
|
||||
</table>
|
||||
`;
|
||||
|
||||
constructFormBody({}, {
|
||||
constructForm('{% url "api-manufacturer-part-parameter-list" %}', {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Parameters" %}',
|
||||
preFormContent: html,
|
||||
onSubmit: function(fields, opts) {
|
||||
inventreeMultiDelete(
|
||||
'{% url "api-manufacturer-part-parameter-list" %}',
|
||||
selections,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: options.success,
|
||||
}
|
||||
);
|
||||
}
|
||||
form_data: {
|
||||
items: ids,
|
||||
},
|
||||
onSuccess: options.success,
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -725,7 +725,8 @@ function submitFormData(fields, options) {
|
||||
// Only used if file / image upload is required
|
||||
var form_data = new FormData();
|
||||
|
||||
var data = {};
|
||||
// We can (optionally) provide a "starting point" for the submitted data
|
||||
var data = options.form_data || {};
|
||||
|
||||
var has_files = false;
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
handleFormErrors,
|
||||
imageHoverIcon,
|
||||
inventreeGet,
|
||||
inventreeMultiDelete,
|
||||
inventreePut,
|
||||
launchModalForm,
|
||||
linkButtonsToSelection,
|
||||
@ -1107,12 +1106,23 @@ function adjustStock(action, items, options={}) {
|
||||
// Delete action is handled differently
|
||||
if (action == 'delete') {
|
||||
|
||||
inventreeMultiDelete(
|
||||
var ids = [];
|
||||
|
||||
items.forEach(function(item) {
|
||||
ids.push(item.pk);
|
||||
});
|
||||
|
||||
showModalSpinner(opts.modal, true);
|
||||
inventreeDelete(
|
||||
'{% url "api-stock-list" %}',
|
||||
items,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: options.success,
|
||||
data: {
|
||||
items: ids,
|
||||
},
|
||||
success: function(response) {
|
||||
$(opts.modal).modal('hide');
|
||||
options.success(response);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user