mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
More features
- Custom renderers depending on specified model name - Paginate API results
This commit is contained in:
parent
b29db6f258
commit
565631ef87
@ -973,3 +973,10 @@ input[type="date"].form-control, input[type="time"].form-control, input[type="da
|
|||||||
.select2-container {
|
.select2-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.select2-thumbnail {
|
||||||
|
max-width: 24px;
|
||||||
|
max-height: 24px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
@ -105,6 +105,7 @@ settings_urls = [
|
|||||||
dynamic_javascript_urls = [
|
dynamic_javascript_urls = [
|
||||||
url(r'^api.js', DynamicJsView.as_view(template_name='js/api.js'), name='api.js'),
|
url(r'^api.js', DynamicJsView.as_view(template_name='js/api.js'), name='api.js'),
|
||||||
url(r'^forms.js', DynamicJsView.as_view(template_name='js/forms.js'), name='forms.js'),
|
url(r'^forms.js', DynamicJsView.as_view(template_name='js/forms.js'), name='forms.js'),
|
||||||
|
url(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/model_renderers.js'), name='model_renderers.js'),
|
||||||
url(r'^modals.js', DynamicJsView.as_view(template_name='js/modals.js'), name='modals.js'),
|
url(r'^modals.js', DynamicJsView.as_view(template_name='js/modals.js'), name='modals.js'),
|
||||||
url(r'^barcode.js', DynamicJsView.as_view(template_name='js/barcode.js'), name='barcode.js'),
|
url(r'^barcode.js', DynamicJsView.as_view(template_name='js/barcode.js'), name='barcode.js'),
|
||||||
url(r'^bom.js', DynamicJsView.as_view(template_name='js/bom.js'), name='bom.js'),
|
url(r'^bom.js', DynamicJsView.as_view(template_name='js/bom.js'), name='bom.js'),
|
||||||
|
@ -150,6 +150,7 @@
|
|||||||
<!-- translated -->
|
<!-- translated -->
|
||||||
<script type='text/javascript' src="{% i18n_static 'api.js' %}"></script>
|
<script type='text/javascript' src="{% i18n_static 'api.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% i18n_static 'forms.js' %}"></script>
|
<script type='text/javascript' src="{% i18n_static 'forms.js' %}"></script>
|
||||||
|
<script type='text/javascript' src="{% i18n_static 'model_renderers.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% i18n_static 'barcode.js' %}"></script>
|
<script type='text/javascript' src="{% i18n_static 'barcode.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% i18n_static 'bom.js' %}"></script>
|
<script type='text/javascript' src="{% i18n_static 'bom.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% i18n_static 'company.js' %}"></script>
|
<script type='text/javascript' src="{% i18n_static 'company.js' %}"></script>
|
||||||
|
@ -364,7 +364,8 @@ function initializeRelatedField(modal, name, field, options) {
|
|||||||
|
|
||||||
// TODO: Add 'placeholder' support for entry select2 fields
|
// TODO: Add 'placeholder' support for entry select2 fields
|
||||||
|
|
||||||
// TODO: Add 'pagination' support for the query
|
// limit size for AJAX requests
|
||||||
|
var pageSize = options.pageSize || 25;
|
||||||
|
|
||||||
select.select2({
|
select.select2({
|
||||||
ajax: {
|
ajax: {
|
||||||
@ -377,31 +378,52 @@ function initializeRelatedField(modal, name, field, options) {
|
|||||||
cache: true,
|
cache: true,
|
||||||
// matcher: partialMatcher,
|
// matcher: partialMatcher,
|
||||||
data: function(params) {
|
data: function(params) {
|
||||||
|
|
||||||
|
if (!params.page) {
|
||||||
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
offset = (params.page - 1) * pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
// Re-format search term into InvenTree API style
|
// Re-format search term into InvenTree API style
|
||||||
return {
|
return {
|
||||||
search: params.term,
|
search: params.term,
|
||||||
|
offset: offset,
|
||||||
|
limit: pageSize,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
processResults: function(data) {
|
processResults: function(response) {
|
||||||
// Convert the returned InvenTree data into select2-friendly format
|
// Convert the returned InvenTree data into select2-friendly format
|
||||||
var rows = [];
|
|
||||||
|
|
||||||
// Only ever show the first x items
|
var data = [];
|
||||||
for (var idx = 0; idx < data.length && idx < 50; idx++) {
|
|
||||||
var row = data[idx];
|
|
||||||
|
|
||||||
// Reformat to match select2 requirements
|
var more = false;
|
||||||
row.id = row.id || row.pk;
|
|
||||||
|
|
||||||
// TODO: Fix me?
|
if ('count' in response && 'results' in response) {
|
||||||
row.text = `This is ${field.api_url}${row.id}/`;
|
// Response is paginated
|
||||||
|
data = response.results;
|
||||||
|
|
||||||
rows.push(row);
|
// Any more data available?
|
||||||
|
if (response.next) {
|
||||||
|
more = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Non-paginated response
|
||||||
|
data = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each 'row' must have the 'id' attribute
|
||||||
|
for (var idx = 0; idx < data.length; idx++) {
|
||||||
|
data[idx].id = data[idx].pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref: https://select2.org/data-sources/formats
|
// Ref: https://select2.org/data-sources/formats
|
||||||
var results = {
|
var results = {
|
||||||
results: rows,
|
results: data,
|
||||||
|
pagination: {
|
||||||
|
more: more,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
@ -442,7 +464,7 @@ function initializeRelatedField(modal, name, field, options) {
|
|||||||
* - parameters: The field definition (OPTIONS) request
|
* - parameters: The field definition (OPTIONS) request
|
||||||
* - options: Other options provided at time of modal creation by the client
|
* - options: Other options provided at time of modal creation by the client
|
||||||
*/
|
*/
|
||||||
function renderModelData(name, model, data, paramaters, options) {
|
function renderModelData(name, model, data, parameters, options) {
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return '{% trans "Searching" %}...';
|
return '{% trans "Searching" %}...';
|
||||||
@ -452,20 +474,41 @@ function renderModelData(name, model, data, paramaters, options) {
|
|||||||
|
|
||||||
var html = null;
|
var html = null;
|
||||||
|
|
||||||
|
var renderer = null;
|
||||||
|
|
||||||
|
// Find a custom renderer
|
||||||
switch (model) {
|
switch (model) {
|
||||||
case 'company':
|
case 'company':
|
||||||
html = `<span>${data.name}</span> - <i>${data.description}</i>`;
|
renderer = renderCompany;
|
||||||
|
break;
|
||||||
|
case 'stockitem':
|
||||||
|
renderer = renderStockItem;
|
||||||
|
break;
|
||||||
|
case 'stocklocation':
|
||||||
|
renderer = renderStockLocation;
|
||||||
|
break;
|
||||||
|
case 'part':
|
||||||
|
renderer = renderPart;
|
||||||
|
break;
|
||||||
|
case 'partcategory':
|
||||||
|
renderer = renderPartCategory;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (renderer != null) {
|
||||||
|
html = renderer(name, data, parameters, options);
|
||||||
|
}
|
||||||
|
|
||||||
if (html != null) {
|
if (html != null) {
|
||||||
// Render HTML to an object
|
// Render HTML to an object
|
||||||
var $state = $(html);
|
var $state = $(html);
|
||||||
return $state;
|
return $state;
|
||||||
} else {
|
} else {
|
||||||
|
console.log(`ERROR: Rendering not implemented for model '${model}'`);
|
||||||
// Simple text rendering
|
// Simple text rendering
|
||||||
return data.text;
|
return data.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
83
InvenTree/templates/js/model_renderers.js
Normal file
83
InvenTree/templates/js/model_renderers.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* This file contains functions for rendering various InvenTree database models,
|
||||||
|
* in particular for displaying them in modal forms in a 'select2' context.
|
||||||
|
*
|
||||||
|
* Each renderer is provided with three arguments:
|
||||||
|
*
|
||||||
|
* - name: The 'name' of the model instance in the referring model
|
||||||
|
* - data: JSON data which represents the model instance. Returned via a GET request.
|
||||||
|
* - parameters: The field parameters provided via an OPTIONS request to the endpoint.
|
||||||
|
* - options: User options provided by the client
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Renderer for "Company" model
|
||||||
|
function renderCompany(name, data, parameters, options) {
|
||||||
|
|
||||||
|
var html = `<span>${data.name}</span> - <i>${data.description}</i>`;
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Renderer for "StockItem" model
|
||||||
|
function renderStockItem(name, data, parameters, options) {
|
||||||
|
|
||||||
|
// TODO - Include part detail, location, quantity
|
||||||
|
// TODO - Include part image
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Renderer for "StockLocation" model
|
||||||
|
function renderStockLocation(name, data, parameters, options) {
|
||||||
|
|
||||||
|
var html = `<span>${data.name}</span>`;
|
||||||
|
|
||||||
|
if (data.description) {
|
||||||
|
html += ` - <i>${data.description}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.pathstring) {
|
||||||
|
html += `<p><small>${data.pathstring}</small></p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Renderer for "Part" model
|
||||||
|
function renderPart(name, data, parameters, options) {
|
||||||
|
|
||||||
|
var image = data.image;
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
image = `/static/img/blank_image.png`;
|
||||||
|
}
|
||||||
|
|
||||||
|
var html = `<img src='${image}' class='select2-thumbnail'>`;
|
||||||
|
|
||||||
|
html += ` <span>${data.full_name ?? data.name}</span>`;
|
||||||
|
|
||||||
|
if (data.description) {
|
||||||
|
html += ` - <i>${data.description}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Renderer for "PartCategory" model
|
||||||
|
function renderPartCategory(name, data, parameters, options) {
|
||||||
|
|
||||||
|
var html = `<span>${data.name}</span>`;
|
||||||
|
|
||||||
|
if (data.description) {
|
||||||
|
html += ` - <i>${data.description}</i>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.pathstring) {
|
||||||
|
html += `<p><small>${data.pathstring}</small></p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user