mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-18 13:05:42 +00:00
Feature/location types (#5588)
* Added model changes for StockLocationTypes * Implement icon for CUI * Added location type to location table with filters * Fix ruleset * Added tests * Bump api version to v136 * trigger: ci * Bump api version variable too
This commit is contained in:
@ -408,6 +408,82 @@ onPanelLoad('parts', function() {
|
||||
});
|
||||
});
|
||||
|
||||
// Javascript for the Stock settings panel
|
||||
onPanelLoad("stock", function() {
|
||||
|
||||
// Construct the stock location type table
|
||||
$('#location-type-table').bootstrapTable({
|
||||
url: '{% url "api-location-type-list" %}',
|
||||
search: true,
|
||||
sortable: true,
|
||||
formatNoMatches: function() {
|
||||
return '{% trans "No stock location types found" %}';
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'name',
|
||||
sortable: true,
|
||||
title: '{% trans "Name" %}',
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
sortable: false,
|
||||
title: '{% trans "Description" %}',
|
||||
},
|
||||
{
|
||||
field: 'icon',
|
||||
sortable: true,
|
||||
title: '{% trans "Icon" %}',
|
||||
},
|
||||
{
|
||||
field: 'location_count',
|
||||
sortable: true,
|
||||
title: '{% trans "Location count" %}',
|
||||
formatter: function(value, row) {
|
||||
let html = value;
|
||||
let buttons = '';
|
||||
|
||||
buttons += makeEditButton('button-location-type-edit', row.pk, '{% trans "Edit Location Type" %}');
|
||||
buttons += makeDeleteButton('button-location-type-delete', row.pk, '{% trans "Delete Location type" %}');
|
||||
|
||||
html += wrapButtons(buttons);
|
||||
return html;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
$('#location-type-table').on('click', '.button-location-type-edit', function() {
|
||||
let pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`{% url "api-location-type-list" %}${pk}/`, {
|
||||
title: '{% trans "Edit Location Type" %}',
|
||||
fields: stockLocationTypeFields(),
|
||||
refreshTable: '#location-type-table',
|
||||
});
|
||||
});
|
||||
|
||||
$('#location-type-table').on('click', '.button-location-type-delete', function() {
|
||||
let pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`{% url "api-location-type-list" %}${pk}/`, {
|
||||
title: '{% trans "Delete Location Type" %}',
|
||||
method: 'DELETE',
|
||||
refreshTable: '#location-type-table',
|
||||
});
|
||||
});
|
||||
|
||||
$('#new-location-type').click(function() {
|
||||
// Construct a new location type
|
||||
constructForm('{% url "api-location-type-list" %}', {
|
||||
fields: stockLocationTypeFields(),
|
||||
title: '{% trans "New Location Type" %}',
|
||||
method: 'POST',
|
||||
refreshTable: '#location-type-table',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Javascript for the Stocktake settings panel
|
||||
onPanelLoad('stocktake', function() {
|
||||
|
||||
|
@ -25,4 +25,19 @@
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class='panel-heading'>
|
||||
<div class='d-flex flex-span'>
|
||||
<h4>{% trans "Stock Location Types" %}</h4>
|
||||
{% include "spacer.html" %}
|
||||
<div class='btn-group' role='group'>
|
||||
<button class='btn btn-success' id='new-location-type'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Location Type" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='location-type-table'></table>
|
||||
|
||||
{% endblock content %}
|
||||
|
@ -24,6 +24,7 @@
|
||||
renderReturnOrder,
|
||||
renderStockItem,
|
||||
renderStockLocation,
|
||||
renderStockLocationType,
|
||||
renderSupplierPart,
|
||||
renderUser,
|
||||
*/
|
||||
@ -59,6 +60,8 @@ function getModelRenderer(model) {
|
||||
return renderStockItem;
|
||||
case 'stocklocation':
|
||||
return renderStockLocation;
|
||||
case 'stocklocationtype':
|
||||
return renderStockLocationType;
|
||||
case 'part':
|
||||
return renderPart;
|
||||
case 'partcategory':
|
||||
@ -259,6 +262,16 @@ function renderStockLocation(data, parameters={}) {
|
||||
);
|
||||
}
|
||||
|
||||
// Renderer for "StockLocationType" model
|
||||
function renderStockLocationType(data, parameters={}) {
|
||||
return renderModel(
|
||||
{
|
||||
text: `<span class="${data.icon} me-1"></span>${data.name}`,
|
||||
},
|
||||
parameters
|
||||
);
|
||||
}
|
||||
|
||||
function renderBuild(data, parameters={}) {
|
||||
|
||||
var image = blankImage();
|
||||
|
@ -81,6 +81,7 @@
|
||||
serializeStockItem,
|
||||
stockItemFields,
|
||||
stockLocationFields,
|
||||
stockLocationTypeFields,
|
||||
uninstallStockItem,
|
||||
*/
|
||||
|
||||
@ -130,6 +131,20 @@ function serializeStockItem(pk, options={}) {
|
||||
constructForm(url, options);
|
||||
}
|
||||
|
||||
function stockLocationTypeFields() {
|
||||
const fields = {
|
||||
name: {},
|
||||
description: {},
|
||||
icon: {
|
||||
help_text: `{% trans "Default icon for all locations that have no icon set (optional) - Explore all available icons on" %} <a href="https://fontawesome.com/v5/search?s=solid" target="_blank" rel="noopener noreferrer">Font Awesome</a>.`,
|
||||
placeholder: 'fas fa-box',
|
||||
icon: "fa-icons",
|
||||
},
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
function stockLocationFields(options={}) {
|
||||
var fields = {
|
||||
@ -146,9 +161,20 @@ function stockLocationFields(options={}) {
|
||||
owner: {},
|
||||
structural: {},
|
||||
external: {},
|
||||
icon: {
|
||||
location_type: {
|
||||
secondary: {
|
||||
title: '{% trans "Add Location type" %}',
|
||||
fields: function() {
|
||||
const fields = stockLocationTypeFields();
|
||||
|
||||
return fields;
|
||||
}
|
||||
},
|
||||
},
|
||||
custom_icon: {
|
||||
help_text: `{% trans "Icon (optional) - Explore all available icons on" %} <a href="https://fontawesome.com/v5/search?s=solid" target="_blank" rel="noopener noreferrer">Font Awesome</a>.`,
|
||||
placeholder: 'fas fa-box',
|
||||
icon: "fa-icons",
|
||||
},
|
||||
};
|
||||
|
||||
@ -2729,7 +2755,18 @@ function loadStockLocationTable(table, options) {
|
||||
formatter: function(value) {
|
||||
return yesNoLabel(value);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'location_type',
|
||||
title: '{% trans "Location type" %}',
|
||||
switchable: true,
|
||||
sortable: false,
|
||||
formatter: function(value, row) {
|
||||
if (row.location_type_detail) {
|
||||
return row.location_type_detail.name;
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
}
|
||||
|
@ -242,6 +242,30 @@ function getStockLocationFilters() {
|
||||
type: 'bool',
|
||||
title: '{% trans "External" %}',
|
||||
},
|
||||
location_type: {
|
||||
title: '{% trans "Location type" %}',
|
||||
options: function() {
|
||||
const locationTypes = {};
|
||||
|
||||
inventreeGet('{% url "api-location-type-list" %}', {}, {
|
||||
async: false,
|
||||
success: function(response) {
|
||||
for(const locationType of response) {
|
||||
locationTypes[locationType.pk] = {
|
||||
key: locationType.pk,
|
||||
value: locationType.name,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return locationTypes;
|
||||
},
|
||||
},
|
||||
has_location_type: {
|
||||
type: 'bool',
|
||||
title: '{% trans "Has location type" %}'
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user