2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-18 04:55:44 +00:00

Fix: Treegrid is loading an eternity for huge amounts of data (#3451)

* Added default max depth and lazy loading to StorageLocation

* Added default max depth and lazy loading to PartCategory

* Update API version

* lint: fix

* Added INVENTREE_TREE_DEPTH setting

* Refactored int conversion into own helper function

* Added tests
This commit is contained in:
luwol03
2022-08-05 00:07:12 +02:00
committed by GitHub
parent a2c2d1d0a4
commit a9e22d0ae9
10 changed files with 225 additions and 36 deletions

View File

@ -22,6 +22,7 @@
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DOWNLOAD_FROM_URL" icon="fa-cloud-download-alt" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE" icon="fa-server" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_REQUIRE_CONFIRM" icon="fa-check" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_TREE_DEPTH" icon="fa-sitemap" %}
</tbody>
</table>

View File

@ -1750,6 +1750,7 @@ function loadPartCategoryTable(table, options) {
if (tree_view) {
params.cascade = true;
params.depth = global_settings.INVENTREE_TREE_DEPTH;
}
var original = {};
@ -1761,6 +1762,35 @@ function loadPartCategoryTable(table, options) {
setupFilterList(filterKey, table, filterListElement);
// Function to request sub-category items
function requestSubItems(parent_pk) {
inventreeGet(
options.url || '{% url "api-part-category-list" %}',
{
parent: parent_pk,
},
{
success: function(response) {
// Add the returned sub-items to the table
for (var idx = 0; idx < response.length; idx++) {
response[idx].parent = parent_pk;
}
const row = $(table).bootstrapTable('getRowByUniqueId', parent_pk);
row.subReceived = true;
$(table).bootstrapTable('updateByUniqueId', parent_pk, row, true);
table.bootstrapTable('append', response);
},
error: function(xhr) {
console.error('Error requesting sub-category for category=' + parent_pk);
showApiError(xhr);
}
}
);
}
table.inventreeTable({
treeEnable: tree_view,
rootParentId: tree_view ? options.params.parent : null,
@ -1839,6 +1869,20 @@ function loadPartCategoryTable(table, options) {
}
});
// Callback for 'load sub category' button
$(table).find('.load-sub-category').click(function(event) {
event.preventDefault();
const pk = $(this).attr('pk');
const row = $(table).bootstrapTable('getRowByUniqueId', pk);
// Request sub-category for this category
requestSubItems(row.pk);
row.subRequested = true;
$(table).bootstrapTable('updateByUniqueId', pk, row, true);
});
} else {
$('#view-category-tree').removeClass('btn-secondary').addClass('btn-outline-secondary');
$('#view-category-list').removeClass('btn-outline-secondary').addClass('btn-secondary');
@ -1859,8 +1903,20 @@ function loadPartCategoryTable(table, options) {
switchable: true,
sortable: true,
formatter: function(value, row) {
let html = '';
var html = renderLink(
if (row._level >= global_settings.INVENTREE_TREE_DEPTH && !row.subReceived) {
if (row.subRequested) {
html += `<a href='#'><span class='fas fa-sync fa-spin'></span></a>`;
} else {
html += `
<a href='#' pk='${row.pk}' class='load-sub-category'>
<span class='fas fa-sync-alt' title='{% trans "Load Subcategories" %}'></span>
</a> `;
}
}
html += renderLink(
value,
`/part/category/${row.pk}/`
);

View File

@ -2226,6 +2226,7 @@ function loadStockLocationTable(table, options) {
if (tree_view) {
params.cascade = true;
params.depth = global_settings.INVENTREE_TREE_DEPTH;
}
var filters = {};
@ -2248,6 +2249,35 @@ function loadStockLocationTable(table, options) {
filters[key] = params[key];
}
// Function to request sub-location items
function requestSubItems(parent_pk) {
inventreeGet(
options.url || '{% url "api-location-list" %}',
{
parent: parent_pk,
},
{
success: function(response) {
// Add the returned sub-items to the table
for (var idx = 0; idx < response.length; idx++) {
response[idx].parent = parent_pk;
}
const row = $(table).bootstrapTable('getRowByUniqueId', parent_pk);
row.subReceived = true;
$(table).bootstrapTable('updateByUniqueId', parent_pk, row, true);
table.bootstrapTable('append', response);
},
error: function(xhr) {
console.error('Error requesting sub-locations for location=' + parent_pk);
showApiError(xhr);
}
}
);
}
table.inventreeTable({
treeEnable: tree_view,
rootParentId: tree_view ? options.params.parent : null,
@ -2286,6 +2316,20 @@ function loadStockLocationTable(table, options) {
}
});
// Callback for 'load sub location' button
$(table).find('.load-sub-location').click(function(event) {
event.preventDefault();
const pk = $(this).attr('pk');
const row = $(table).bootstrapTable('getRowByUniqueId', pk);
// Request sub-location for this location
requestSubItems(row.pk);
row.subRequested = true;
$(table).bootstrapTable('updateByUniqueId', pk, row, true);
});
} else {
$('#view-location-tree').removeClass('btn-secondary').addClass('btn-outline-secondary');
$('#view-location-list').removeClass('btn-outline-secondary').addClass('btn-secondary');
@ -2345,10 +2389,25 @@ function loadStockLocationTable(table, options) {
switchable: true,
sortable: true,
formatter: function(value, row) {
return renderLink(
let html = '';
if (row._level >= global_settings.INVENTREE_TREE_DEPTH && !row.subReceived) {
if (row.subRequested) {
html += `<a href='#'><span class='fas fa-sync fa-spin'></span></a>`;
} else {
html += `
<a href='#' pk='${row.pk}' class='load-sub-location'>
<span class='fas fa-sync-alt' title='{% trans "Load Subloactions" %}'></span>
</a> `;
}
}
html += renderLink(
value,
`/stock/location/${row.pk}/`
);
return html;
},
},
{