mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add endpoint for dynamic javascript files
This commit is contained in:
parent
e998098e4f
commit
5160165669
@ -2,22 +2,6 @@
|
|||||||
* Requires api.js to be loaded first
|
* Requires api.js to be loaded first
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getPartCategoryList(filters={}, options={}) {
|
|
||||||
return inventreeGet('/api/part/category/', filters, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSupplierPartList(filters={}, options={}) {
|
|
||||||
return inventreeGet('/api/part/supplier/', filters, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPartList(filters={}, options={}) {
|
|
||||||
return inventreeGet('/api/part/', filters, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBomList(filters={}, options={}) {
|
|
||||||
return inventreeGet('/api/bom/', filters, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleStar(options) {
|
function toggleStar(options) {
|
||||||
/* Toggle the 'starred' status of a part.
|
/* Toggle the 'starred' status of a part.
|
||||||
* Performs AJAX queries and updates the display on the button.
|
* Performs AJAX queries and updates the display on the button.
|
||||||
@ -73,229 +57,3 @@ function toggleStar(options) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadPartTable(table, url, options={}) {
|
|
||||||
/* Load part listing data into specified table.
|
|
||||||
*
|
|
||||||
* Args:
|
|
||||||
* - table: HTML reference to the table
|
|
||||||
* - url: Base URL for API query
|
|
||||||
* - options: object containing following (optional) fields
|
|
||||||
* checkbox: Show the checkbox column
|
|
||||||
* query: extra query params for API request
|
|
||||||
* buttons: If provided, link buttons to selection status of this table
|
|
||||||
* disableFilters: If true, disable custom filters
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Ensure category detail is included
|
|
||||||
options.params['category_detail'] = true;
|
|
||||||
|
|
||||||
var params = options.params || {};
|
|
||||||
|
|
||||||
var filters = {};
|
|
||||||
|
|
||||||
if (!options.disableFilters) {
|
|
||||||
filters = loadTableFilters("parts");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var key in params) {
|
|
||||||
filters[key] = params[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
setupFilterList("parts", $(table));
|
|
||||||
|
|
||||||
var columns = [
|
|
||||||
{
|
|
||||||
field: 'pk',
|
|
||||||
title: 'ID',
|
|
||||||
visible: false,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
if (options.checkbox) {
|
|
||||||
columns.push({
|
|
||||||
checkbox: true,
|
|
||||||
title: 'Select',
|
|
||||||
searchable: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
columns.push({
|
|
||||||
field: 'name',
|
|
||||||
title: 'Part',
|
|
||||||
sortable: true,
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
|
|
||||||
var name = '';
|
|
||||||
|
|
||||||
if (row.IPN) {
|
|
||||||
name += row.IPN;
|
|
||||||
name += ' | ';
|
|
||||||
}
|
|
||||||
|
|
||||||
name += value;
|
|
||||||
|
|
||||||
if (row.revision) {
|
|
||||||
name += ' | ';
|
|
||||||
name += row.revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.is_template) {
|
|
||||||
name = '<i>' + name + '</i>';
|
|
||||||
}
|
|
||||||
|
|
||||||
var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/');
|
|
||||||
|
|
||||||
if (row.is_template) {
|
|
||||||
display += `<span class='fas fa-clone label-right' title='Template part'></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.assembly) {
|
|
||||||
display += `<span class='fas fa-tools label-right' title='Assembled part'></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.starred) {
|
|
||||||
display += `<span class='fas fa-star label-right' title='Starred part'></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (row.salable) {
|
|
||||||
display += `<span class='fas fa-dollar-sign label-right' title='Salable part'></span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (row.component) {
|
|
||||||
display = display + `<span class='fas fa-cogs label-right' title='Component part'></span>`;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!row.active) {
|
|
||||||
display += `<span class='label label-warning label-right'>INACTIVE</span>`;
|
|
||||||
}
|
|
||||||
return display;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
columns.push({
|
|
||||||
sortable: true,
|
|
||||||
field: 'description',
|
|
||||||
title: 'Description',
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
|
|
||||||
if (row.is_template) {
|
|
||||||
value = '<i>' + value + '</i>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
columns.push({
|
|
||||||
sortable: true,
|
|
||||||
field: 'category_detail',
|
|
||||||
title: 'Category',
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
if (row.category) {
|
|
||||||
return renderLink(value.pathstring, "/part/category/" + row.category + "/");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 'No category';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
columns.push({
|
|
||||||
field: 'in_stock',
|
|
||||||
title: 'Stock',
|
|
||||||
searchable: false,
|
|
||||||
sortable: true,
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
var link = "stock";
|
|
||||||
|
|
||||||
if (value) {
|
|
||||||
// There IS stock available for this part
|
|
||||||
|
|
||||||
// Is stock "low" (below the 'minimum_stock' quantity)?
|
|
||||||
if (row.minimum_stock && row.minimum_stock > value) {
|
|
||||||
value += "<span class='label label-right label-warning'>Low stock</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (row.on_order) {
|
|
||||||
// There is no stock available, but stock is on order
|
|
||||||
value = "0<span class='label label-right label-primary'>On Order : " + row.on_order + "</span>";
|
|
||||||
link = "orders";
|
|
||||||
} else if (row.building) {
|
|
||||||
// There is no stock available, but stock is being built
|
|
||||||
value = "0<span class='label label-right label-info'>Building : " + row.building + "</span>";
|
|
||||||
link = "builds";
|
|
||||||
} else {
|
|
||||||
// There is no stock available
|
|
||||||
value = "0<span class='label label-right label-danger'>No Stock</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return renderLink(value, '/part/' + row.pk + "/" + link + "/");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(table).inventreeTable({
|
|
||||||
url: url,
|
|
||||||
sortName: 'name',
|
|
||||||
method: 'get',
|
|
||||||
queryParams: filters,
|
|
||||||
groupBy: false,
|
|
||||||
original: params,
|
|
||||||
formatNoMatches: function() { return "No parts found"; },
|
|
||||||
columns: columns,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (options.buttons) {
|
|
||||||
linkButtonsToSelection($(table), options.buttons);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Button callbacks for part table buttons */
|
|
||||||
|
|
||||||
$("#multi-part-order").click(function() {
|
|
||||||
var selections = $(table).bootstrapTable("getSelections");
|
|
||||||
|
|
||||||
var parts = [];
|
|
||||||
|
|
||||||
selections.forEach(function(item) {
|
|
||||||
parts.push(item.pk);
|
|
||||||
});
|
|
||||||
|
|
||||||
launchModalForm("/order/purchase-order/order-parts/", {
|
|
||||||
data: {
|
|
||||||
parts: parts,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#multi-part-category").click(function() {
|
|
||||||
var selections = $(table).bootstrapTable("getSelections");
|
|
||||||
|
|
||||||
var parts = [];
|
|
||||||
|
|
||||||
selections.forEach(function(item) {
|
|
||||||
parts.push(item.pk);
|
|
||||||
});
|
|
||||||
|
|
||||||
launchModalForm("/part/set-category/", {
|
|
||||||
data: {
|
|
||||||
parts: parts,
|
|
||||||
},
|
|
||||||
reload: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#multi-part-export').click(function() {
|
|
||||||
var selections = $(table).bootstrapTable("getSelections");
|
|
||||||
|
|
||||||
var parts = '';
|
|
||||||
|
|
||||||
selections.forEach(function(item) {
|
|
||||||
parts += item.pk;
|
|
||||||
parts += ',';
|
|
||||||
});
|
|
||||||
|
|
||||||
location.href = '/part/export/?parts=' + parts;
|
|
||||||
});
|
|
||||||
}
|
|
@ -35,6 +35,7 @@ from rest_framework.documentation import include_docs_urls
|
|||||||
|
|
||||||
from .views import IndexView, SearchView, DatabaseStatsView
|
from .views import IndexView, SearchView, DatabaseStatsView
|
||||||
from .views import SettingsView, EditUserView, SetPasswordView
|
from .views import SettingsView, EditUserView, SetPasswordView
|
||||||
|
from .views import DynamicJsView
|
||||||
|
|
||||||
from .api import InfoView, BarcodePluginView, ActionPluginView
|
from .api import InfoView, BarcodePluginView, ActionPluginView
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ settings_urls = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
dynamic_javascript_urls = [
|
dynamic_javascript_urls = [
|
||||||
|
url(r'^part.js', DynamicJsView.as_view(template_name='js/part.js'), name='part.js'),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -514,6 +514,18 @@ class SearchView(TemplateView):
|
|||||||
return super(TemplateView, self).render_to_response(context)
|
return super(TemplateView, self).render_to_response(context)
|
||||||
|
|
||||||
|
|
||||||
|
class DynamicJsView(TemplateView):
|
||||||
|
"""
|
||||||
|
View for returning javacsript files,
|
||||||
|
which instead of being served dynamically,
|
||||||
|
are passed through the django translation engine!
|
||||||
|
"""
|
||||||
|
|
||||||
|
template_name = ""
|
||||||
|
content_type = 'text/javascript'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsView(TemplateView):
|
class SettingsView(TemplateView):
|
||||||
""" View for configuring User settings
|
""" View for configuring User settings
|
||||||
"""
|
"""
|
||||||
|
@ -114,6 +114,8 @@ InvenTree
|
|||||||
<script type='text/javascript' src="{% static 'script/inventree/notification.js' %}"></script>
|
<script type='text/javascript' src="{% static 'script/inventree/notification.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% static 'script/inventree/sidenav.js' %}"></script>
|
<script type='text/javascript' src="{% static 'script/inventree/sidenav.js' %}"></script>
|
||||||
|
|
||||||
|
<script type='text/javascript' src="{% url 'part.js' %}"></script>
|
||||||
|
|
||||||
<script type='text/javascript' src="{% static 'fontawesome/js/solid.js' %}"></script>
|
<script type='text/javascript' src="{% static 'fontawesome/js/solid.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% static 'fontawesome/js/brands.js' %}"></script>
|
<script type='text/javascript' src="{% static 'fontawesome/js/brands.js' %}"></script>
|
||||||
<script type='text/javascript' src="{% static 'fontawesome/js/fontawesome.js' %}"></script>
|
<script type='text/javascript' src="{% static 'fontawesome/js/fontawesome.js' %}"></script>
|
||||||
|
227
InvenTree/templates/js/part.js
Normal file
227
InvenTree/templates/js/part.js
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
function loadPartTable(table, url, options={}) {
|
||||||
|
/* Load part listing data into specified table.
|
||||||
|
*
|
||||||
|
* Args:
|
||||||
|
* - table: HTML reference to the table
|
||||||
|
* - url: Base URL for API query
|
||||||
|
* - options: object containing following (optional) fields
|
||||||
|
* checkbox: Show the checkbox column
|
||||||
|
* query: extra query params for API request
|
||||||
|
* buttons: If provided, link buttons to selection status of this table
|
||||||
|
* disableFilters: If true, disable custom filters
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Ensure category detail is included
|
||||||
|
options.params['category_detail'] = true;
|
||||||
|
|
||||||
|
var params = options.params || {};
|
||||||
|
|
||||||
|
var filters = {};
|
||||||
|
|
||||||
|
if (!options.disableFilters) {
|
||||||
|
filters = loadTableFilters("parts");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var key in params) {
|
||||||
|
filters[key] = params[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
setupFilterList("parts", $(table));
|
||||||
|
|
||||||
|
var columns = [
|
||||||
|
{
|
||||||
|
field: 'pk',
|
||||||
|
title: 'ID',
|
||||||
|
visible: false,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
if (options.checkbox) {
|
||||||
|
columns.push({
|
||||||
|
checkbox: true,
|
||||||
|
title: 'Select',
|
||||||
|
searchable: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
columns.push({
|
||||||
|
field: 'name',
|
||||||
|
title: 'Part',
|
||||||
|
sortable: true,
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
|
||||||
|
var name = '';
|
||||||
|
|
||||||
|
if (row.IPN) {
|
||||||
|
name += row.IPN;
|
||||||
|
name += ' | ';
|
||||||
|
}
|
||||||
|
|
||||||
|
name += value;
|
||||||
|
|
||||||
|
if (row.revision) {
|
||||||
|
name += ' | ';
|
||||||
|
name += row.revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.is_template) {
|
||||||
|
name = '<i>' + name + '</i>';
|
||||||
|
}
|
||||||
|
|
||||||
|
var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/');
|
||||||
|
|
||||||
|
if (row.is_template) {
|
||||||
|
display += `<span class='fas fa-clone label-right' title='Template part'></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.assembly) {
|
||||||
|
display += `<span class='fas fa-tools label-right' title='Assembled part'></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.starred) {
|
||||||
|
display += `<span class='fas fa-star label-right' title='Starred part'></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row.salable) {
|
||||||
|
display += `<span class='fas fa-dollar-sign label-right' title='Salable part'></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (row.component) {
|
||||||
|
display = display + `<span class='fas fa-cogs label-right' title='Component part'></span>`;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!row.active) {
|
||||||
|
display += `<span class='label label-warning label-right'>INACTIVE</span>`;
|
||||||
|
}
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
columns.push({
|
||||||
|
sortable: true,
|
||||||
|
field: 'description',
|
||||||
|
title: 'Description',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
|
||||||
|
if (row.is_template) {
|
||||||
|
value = '<i>' + value + '</i>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
columns.push({
|
||||||
|
sortable: true,
|
||||||
|
field: 'category_detail',
|
||||||
|
title: 'Category',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
if (row.category) {
|
||||||
|
return renderLink(value.pathstring, "/part/category/" + row.category + "/");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'No category';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
columns.push({
|
||||||
|
field: 'in_stock',
|
||||||
|
title: 'Stock',
|
||||||
|
searchable: false,
|
||||||
|
sortable: true,
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
var link = "stock";
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
// There IS stock available for this part
|
||||||
|
|
||||||
|
// Is stock "low" (below the 'minimum_stock' quantity)?
|
||||||
|
if (row.minimum_stock && row.minimum_stock > value) {
|
||||||
|
value += "<span class='label label-right label-warning'>Low stock</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (row.on_order) {
|
||||||
|
// There is no stock available, but stock is on order
|
||||||
|
value = "0<span class='label label-right label-primary'>On Order : " + row.on_order + "</span>";
|
||||||
|
link = "orders";
|
||||||
|
} else if (row.building) {
|
||||||
|
// There is no stock available, but stock is being built
|
||||||
|
value = "0<span class='label label-right label-info'>Building : " + row.building + "</span>";
|
||||||
|
link = "builds";
|
||||||
|
} else {
|
||||||
|
// There is no stock available
|
||||||
|
value = "0<span class='label label-right label-danger'>No Stock</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderLink(value, '/part/' + row.pk + "/" + link + "/");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(table).inventreeTable({
|
||||||
|
url: url,
|
||||||
|
sortName: 'name',
|
||||||
|
method: 'get',
|
||||||
|
queryParams: filters,
|
||||||
|
groupBy: false,
|
||||||
|
original: params,
|
||||||
|
formatNoMatches: function() { return "No parts found"; },
|
||||||
|
columns: columns,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options.buttons) {
|
||||||
|
linkButtonsToSelection($(table), options.buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button callbacks for part table buttons */
|
||||||
|
|
||||||
|
$("#multi-part-order").click(function() {
|
||||||
|
var selections = $(table).bootstrapTable("getSelections");
|
||||||
|
|
||||||
|
var parts = [];
|
||||||
|
|
||||||
|
selections.forEach(function(item) {
|
||||||
|
parts.push(item.pk);
|
||||||
|
});
|
||||||
|
|
||||||
|
launchModalForm("/order/purchase-order/order-parts/", {
|
||||||
|
data: {
|
||||||
|
parts: parts,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#multi-part-category").click(function() {
|
||||||
|
var selections = $(table).bootstrapTable("getSelections");
|
||||||
|
|
||||||
|
var parts = [];
|
||||||
|
|
||||||
|
selections.forEach(function(item) {
|
||||||
|
parts.push(item.pk);
|
||||||
|
});
|
||||||
|
|
||||||
|
launchModalForm("/part/set-category/", {
|
||||||
|
data: {
|
||||||
|
parts: parts,
|
||||||
|
},
|
||||||
|
reload: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#multi-part-export').click(function() {
|
||||||
|
var selections = $(table).bootstrapTable("getSelections");
|
||||||
|
|
||||||
|
var parts = '';
|
||||||
|
|
||||||
|
selections.forEach(function(item) {
|
||||||
|
parts += item.pk;
|
||||||
|
parts += ',';
|
||||||
|
});
|
||||||
|
|
||||||
|
location.href = '/part/export/?parts=' + parts;
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user