Add endpoint for dynamic javascript files

This commit is contained in:
Oliver Walters 2020-05-02 21:19:34 +10:00
parent e998098e4f
commit 5160165669
5 changed files with 243 additions and 242 deletions

View File

@ -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;
});
}

View File

@ -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 = [

View File

@ -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
""" """

View File

@ -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>

View 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;
});
}