diff --git a/InvenTree/InvenTree/static/script/inventree/part.js b/InvenTree/InvenTree/static/script/inventree/part.js index 92460a51a7..64849a30a6 100644 --- a/InvenTree/InvenTree/static/script/inventree/part.js +++ b/InvenTree/InvenTree/static/script/inventree/part.js @@ -2,22 +2,6 @@ * 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) { /* Toggle the 'starred' status of a part. * Performs AJAX queries and updates the display on the button. @@ -72,230 +56,4 @@ 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 = '' + name + ''; - } - - var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/'); - - if (row.is_template) { - display += ``; - } - - if (row.assembly) { - display += ``; - } - - if (row.starred) { - display += ``; - } - - if (row.salable) { - display += ``; - } - - /* - if (row.component) { - display = display + ``; - } - */ - - if (!row.active) { - display += `INACTIVE`; - } - return display; - } - }); - - columns.push({ - sortable: true, - field: 'description', - title: 'Description', - formatter: function(value, row, index, field) { - - if (row.is_template) { - value = '' + value + ''; - } - - 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 += "Low stock"; - } - - } else if (row.on_order) { - // There is no stock available, but stock is on order - value = "0On Order : " + row.on_order + ""; - link = "orders"; - } else if (row.building) { - // There is no stock available, but stock is being built - value = "0Building : " + row.building + ""; - link = "builds"; - } else { - // There is no stock available - value = "0No Stock"; - } - - 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; - }); } \ No newline at end of file diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index cf53667fb9..a3a8950401 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -35,6 +35,7 @@ from rest_framework.documentation import include_docs_urls from .views import IndexView, SearchView, DatabaseStatsView from .views import SettingsView, EditUserView, SetPasswordView +from .views import DynamicJsView from .api import InfoView, BarcodePluginView, ActionPluginView @@ -74,6 +75,7 @@ settings_urls = [ ] dynamic_javascript_urls = [ + url(r'^part.js', DynamicJsView.as_view(template_name='js/part.js'), name='part.js'), ] urlpatterns = [ diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 943a18d35c..400981eb17 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -514,6 +514,18 @@ class SearchView(TemplateView): 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): """ View for configuring User settings """ diff --git a/InvenTree/templates/base.html b/InvenTree/templates/base.html index bf5fa4a1c3..9d8f650c69 100644 --- a/InvenTree/templates/base.html +++ b/InvenTree/templates/base.html @@ -114,6 +114,8 @@ InvenTree + + diff --git a/InvenTree/templates/js/part.js b/InvenTree/templates/js/part.js new file mode 100644 index 0000000000..aea67065ca --- /dev/null +++ b/InvenTree/templates/js/part.js @@ -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 = '' + name + ''; + } + + var display = imageHoverIcon(row.thumbnail) + renderLink(name, '/part/' + row.pk + '/'); + + if (row.is_template) { + display += ``; + } + + if (row.assembly) { + display += ``; + } + + if (row.starred) { + display += ``; + } + + if (row.salable) { + display += ``; + } + + /* + if (row.component) { + display = display + ``; + } + */ + + if (!row.active) { + display += `INACTIVE`; + } + return display; + } + }); + + columns.push({ + sortable: true, + field: 'description', + title: 'Description', + formatter: function(value, row, index, field) { + + if (row.is_template) { + value = '' + value + ''; + } + + 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 += "Low stock"; + } + + } else if (row.on_order) { + // There is no stock available, but stock is on order + value = "0On Order : " + row.on_order + ""; + link = "orders"; + } else if (row.building) { + // There is no stock available, but stock is being built + value = "0Building : " + row.building + ""; + link = "builds"; + } else { + // There is no stock available + value = "0No Stock"; + } + + 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; + }); +} \ No newline at end of file