From 6b48977e7b5d183ebeb852a06918cf7a683b88a4 Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 29 Sep 2020 15:16:12 -0500 Subject: [PATCH 01/49] Added 'Parametric Table' tab to category detail view, added part_count to 'Parts' tab --- InvenTree/part/templates/part/category.html | 15 +++++++ .../templates/part/category_parametric.html | 12 +++++ .../templates/part/category_partlist.html | 12 +++++ .../part/templates/part/category_tabs.html | 11 +++++ InvenTree/part/urls.py | 3 +- InvenTree/part/views.py | 13 +++++- InvenTree/templates/js/part.html | 45 +++++++++++++++++++ 7 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 InvenTree/part/templates/part/category_parametric.html create mode 100644 InvenTree/part/templates/part/category_partlist.html create mode 100644 InvenTree/part/templates/part/category_tabs.html diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index 1c7980ba9b..1f5ee7c48b 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -115,8 +115,11 @@ + +{% block part_list %}
+{% endblock part_list %} {% endblock %} {% block js_load %} @@ -242,4 +245,16 @@ }, ); + loadParametricPartTable( + "#parametric-part-table", + "{% url 'api-part-list' %}", + { + params: { + {% if category %}category: {{ category.id }}, + {% else %}category: "null", + {% endif %} + }, + }, + ); + {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/category_parametric.html b/InvenTree/part/templates/part/category_parametric.html new file mode 100644 index 0000000000..7139a539b0 --- /dev/null +++ b/InvenTree/part/templates/part/category_parametric.html @@ -0,0 +1,12 @@ +{% extends "part/category.html" %} +{% load static %} +{% load i18n %} + +{% block part_list %} + +{% include 'part/category_tabs.html' with tab='parametric-table' %} + + +
+ +{% endblock %} diff --git a/InvenTree/part/templates/part/category_partlist.html b/InvenTree/part/templates/part/category_partlist.html new file mode 100644 index 0000000000..bf4aef52a8 --- /dev/null +++ b/InvenTree/part/templates/part/category_partlist.html @@ -0,0 +1,12 @@ +{% extends "part/category.html" %} +{% load static %} +{% load i18n %} + +{% block part_list %} + +{% include 'part/category_tabs.html' with tab='part-list' %} + + +
+ +{% endblock %} diff --git a/InvenTree/part/templates/part/category_tabs.html b/InvenTree/part/templates/part/category_tabs.html new file mode 100644 index 0000000000..b5d8d3c214 --- /dev/null +++ b/InvenTree/part/templates/part/category_tabs.html @@ -0,0 +1,11 @@ +{% load i18n %} +{% load inventree_extras %} + + diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index e61947e243..88d15c1b5b 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -77,7 +77,8 @@ part_category_urls = [ url(r'^edit/?', views.CategoryEdit.as_view(), name='category-edit'), url(r'^delete/?', views.CategoryDelete.as_view(), name='category-delete'), - url('^.*$', views.CategoryDetail.as_view(), name='category-detail'), + url(r'^parametric/?', views.CategoryDetail.as_view(template_name='part/category_parametric.html'), name='category-parametric'), + url(r'^.*$', views.CategoryDetail.as_view(template_name='part/category_partlist.html'), name='category-detail'), ] part_bom_urls = [ diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index ccf607afc0..3c94afc5a5 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1875,7 +1875,18 @@ class CategoryDetail(DetailView): model = PartCategory context_object_name = 'category' queryset = PartCategory.objects.all().prefetch_related('children') - template_name = 'part/category.html' + template_name = 'part/category_partlist.html' + + def get_context_data(self, **kwargs): + + context = super(CategoryDetail, self).get_context_data(**kwargs).copy() + + try: + context['part_count'] = kwargs['object'].partcount() + except KeyError: + context['part_count'] = 0 + + return context class CategoryEdit(AjaxUpdateView): diff --git a/InvenTree/templates/js/part.html b/InvenTree/templates/js/part.html index 5576d91367..0b32ef61b9 100644 --- a/InvenTree/templates/js/part.html +++ b/InvenTree/templates/js/part.html @@ -163,6 +163,51 @@ function loadSimplePartTable(table, url, options={}) { } +function loadParametricPartTable(table, url, options={}) { + /* Load parametric part data into specified table. + * + * Args: + * - table: HTML reference to the table + * - url: Base URL for API query + */ + + // Ensure category detail is included + options.params['category_detail'] = true; + + var params = options.params || {}; + console.log(params) + + var filters = {}; + for (var key in params) { + filters[key] = params[key]; + } + console.log(filters) + + var columns = [ + { + field: 'pk', + title: 'ID', + visible: true, + switchable: true, + searchable: false, + } + ]; + + $(table).inventreeTable({ + url: url, + sortName: 'pk', + method: 'get', + queryParams: filters, + groupBy: false, + name: options.name || 'part', + original: params, + formatNoMatches: function() { return "{% trans "No parts found" %}"; }, + columns: columns, + showColumns: true, + }); +} + + function loadPartTable(table, url, options={}) { /* Load part listing data into specified table. * From d05a5978a044662af8df7ec3a3ea6f0c0163387b Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 29 Sep 2020 16:13:08 -0500 Subject: [PATCH 02/49] Unique parameters names from category makes it to bootstrap table --- InvenTree/part/models.py | 14 ++++ InvenTree/part/templates/part/category.html | 16 +--- .../templates/part/category_parametric.html | 21 ++++- .../templates/part/category_partlist.html | 2 +- InvenTree/part/urls.py | 4 +- InvenTree/part/views.py | 15 ++++ InvenTree/templates/js/part.html | 80 +++++++++++++++++-- 7 files changed, 127 insertions(+), 25 deletions(-) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index afb2dfa64e..707b0b948c 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -111,6 +111,20 @@ class PartCategory(InvenTreeTree): """ True if there are any parts in this category """ return self.partcount() > 0 + def get_unique_parameters(self, cascade=True): + """ Get all parameters for all parts from this category """ + parameters = [] + + parts = self.get_parts(cascade=cascade).prefetch_related('parameters', 'parameters__template') + + for part in parts: + for parameter in part.parameters.all(): + template_name = parameter.template.name + if template_name not in parameters: + parameters.append(template_name) + + return parameters + @receiver(pre_delete, sender=PartCategory, dispatch_uid='partcategory_delete_log') def before_delete_part_category(sender, instance, using, **kwargs): diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index 1f5ee7c48b..0f5ba6de43 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -116,10 +116,10 @@ -{% block part_list %} +{% block category_tables %}
-{% endblock part_list %} +{% endblock category_tables %} {% endblock %} {% block js_load %} @@ -245,16 +245,4 @@ }, ); - loadParametricPartTable( - "#parametric-part-table", - "{% url 'api-part-list' %}", - { - params: { - {% if category %}category: {{ category.id }}, - {% else %}category: "null", - {% endif %} - }, - }, - ); - {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/category_parametric.html b/InvenTree/part/templates/part/category_parametric.html index 7139a539b0..5c99fe391b 100644 --- a/InvenTree/part/templates/part/category_parametric.html +++ b/InvenTree/part/templates/part/category_parametric.html @@ -2,7 +2,7 @@ {% load static %} {% load i18n %} -{% block part_list %} +{% block category_tables %} {% include 'part/category_tabs.html' with tab='parametric-table' %} @@ -10,3 +10,22 @@ {% endblock %} + +{% block js_ready %} +{{ block.super }} + + loadParametricPartTable( + "#parametric-part-table", + "{% url 'api-part-list' %}", + { + params: { + {% if category %}category: {{ category.id }}, + {% else %}category: "null", + {% endif %} + }, + headers: {{ parameters|safe }}, + name: 'parametric', + }, + ); + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/part/templates/part/category_partlist.html b/InvenTree/part/templates/part/category_partlist.html index bf4aef52a8..302fdd3a02 100644 --- a/InvenTree/part/templates/part/category_partlist.html +++ b/InvenTree/part/templates/part/category_partlist.html @@ -2,7 +2,7 @@ {% load static %} {% load i18n %} -{% block part_list %} +{% block category_tables %} {% include 'part/category_tabs.html' with tab='part-list' %} diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 88d15c1b5b..32cd1b0615 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -77,8 +77,8 @@ part_category_urls = [ url(r'^edit/?', views.CategoryEdit.as_view(), name='category-edit'), url(r'^delete/?', views.CategoryDelete.as_view(), name='category-delete'), - url(r'^parametric/?', views.CategoryDetail.as_view(template_name='part/category_parametric.html'), name='category-parametric'), - url(r'^.*$', views.CategoryDetail.as_view(template_name='part/category_partlist.html'), name='category-detail'), + url(r'^parametric/?', views.CategoryParametric.as_view(), name='category-parametric'), + url(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'), ] part_bom_urls = [ diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 3c94afc5a5..80e5beadf8 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1889,6 +1889,21 @@ class CategoryDetail(DetailView): return context +class CategoryParametric(CategoryDetail): + """ Parametric view for PartCategory """ + template_name = 'part/category_parametric.html' + + def get_context_data(self, **kwargs): + + context = super(CategoryParametric, self).get_context_data(**kwargs).copy() + + category = kwargs['object'] + context['parameters'] = category.get_unique_parameters() + print(context) + + return context + + class CategoryEdit(AjaxUpdateView): """ Update view to edit a PartCategory """ model = PartCategory diff --git a/InvenTree/templates/js/part.html b/InvenTree/templates/js/part.html index 0b32ef61b9..4d8d09dc9c 100644 --- a/InvenTree/templates/js/part.html +++ b/InvenTree/templates/js/part.html @@ -171,13 +171,10 @@ function loadParametricPartTable(table, url, options={}) { * - url: Base URL for API query */ - // Ensure category detail is included - options.params['category_detail'] = true; - var params = options.params || {}; console.log(params) - var filters = {}; + var filters = loadTableFilters("parts"); for (var key in params) { filters[key] = params[key]; } @@ -187,19 +184,88 @@ function loadParametricPartTable(table, url, options={}) { { field: 'pk', title: 'ID', - visible: true, - switchable: true, + visible: false, + switchable: false, searchable: false, } ]; + columns.push({ + field: 'IPN', + title: 'IPN', + sortable: true, + }), + + columns.push({ + field: 'name', + title: '{% trans '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 += `{% trans "Inactive" %}`; + } + return display; + } + }); + + for (header of options.headers) { + columns.push({ + field: header, + title: header, + sortable: true, + }) + } + $(table).inventreeTable({ url: url, sortName: 'pk', method: 'get', queryParams: filters, groupBy: false, - name: options.name || 'part', + name: options.name || 'parametric', original: params, formatNoMatches: function() { return "{% trans "No parts found" %}"; }, columns: columns, From 40d8a07acc8a63a505908110c961531069049e45 Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 29 Sep 2020 16:49:53 -0500 Subject: [PATCH 03/49] Now loading data! Still need to be bonified --- InvenTree/part/models.py | 32 ++++-- .../templates/part/category_parametric.html | 14 +-- InvenTree/part/views.py | 6 +- InvenTree/templates/js/part.html | 98 +++---------------- 4 files changed, 47 insertions(+), 103 deletions(-) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 707b0b948c..41fcf0bfce 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -112,18 +112,38 @@ class PartCategory(InvenTreeTree): return self.partcount() > 0 def get_unique_parameters(self, cascade=True): - """ Get all parameters for all parts from this category """ - parameters = [] + """ Get all unique parameter names for all parts from this category """ + unique_parameters_names = [] parts = self.get_parts(cascade=cascade).prefetch_related('parameters', 'parameters__template') for part in parts: for parameter in part.parameters.all(): - template_name = parameter.template.name - if template_name not in parameters: - parameters.append(template_name) + parameter_name = parameter.template.name + if parameter_name not in unique_parameters_names: + unique_parameters_names.append(parameter_name) - return parameters + return unique_parameters_names + + def get_parts_parameters(self, cascade=True): + """ Get all parameter names and values for all parts from this category """ + category_parameters = [] + + parts = self.get_parts(cascade=cascade).prefetch_related('parameters', 'parameters__template') + + for part in parts: + part_parameters = { + 'IPN': part.IPN, + 'Name': part.name, + } + for parameter in part.parameters.all(): + parameter_name = parameter.template.name + parameter_value = parameter.data + part_parameters[parameter_name] = parameter_value + + category_parameters.append(part_parameters) + + return category_parameters @receiver(pre_delete, sender=PartCategory, dispatch_uid='partcategory_delete_log') diff --git a/InvenTree/part/templates/part/category_parametric.html b/InvenTree/part/templates/part/category_parametric.html index 5c99fe391b..4643dfee8a 100644 --- a/InvenTree/part/templates/part/category_parametric.html +++ b/InvenTree/part/templates/part/category_parametric.html @@ -16,16 +16,10 @@ loadParametricPartTable( "#parametric-part-table", - "{% url 'api-part-list' %}", - { - params: { - {% if category %}category: {{ category.id }}, - {% else %}category: "null", - {% endif %} - }, - headers: {{ parameters|safe }}, - name: 'parametric', - }, + { + headers: {{ headers|safe }}, + data: {{ parameters|safe }}, + } ); {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 80e5beadf8..0f0f21b9fc 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1898,8 +1898,10 @@ class CategoryParametric(CategoryDetail): context = super(CategoryParametric, self).get_context_data(**kwargs).copy() category = kwargs['object'] - context['parameters'] = category.get_unique_parameters() - print(context) + context['headers'] = category.get_unique_parameters() + context['headers'].append('IPN') + context['headers'].append('Name') + context['parameters'] = category.get_parts_parameters() return context diff --git a/InvenTree/templates/js/part.html b/InvenTree/templates/js/part.html index 4d8d09dc9c..5ba46b4f31 100644 --- a/InvenTree/templates/js/part.html +++ b/InvenTree/templates/js/part.html @@ -163,95 +163,22 @@ function loadSimplePartTable(table, url, options={}) { } -function loadParametricPartTable(table, url, options={}) { +function loadParametricPartTable(table, options={}) { /* Load parametric part data into specified table. * * Args: * - table: HTML reference to the table - * - url: Base URL for API query + * - data: Parameters data */ - var params = options.params || {}; - console.log(params) + var table_headers = options.headers + var table_data = options.data +/* console.log(table_headers) + console.log(table_data)*/ - var filters = loadTableFilters("parts"); - for (var key in params) { - filters[key] = params[key]; - } - console.log(filters) + var columns = []; - var columns = [ - { - field: 'pk', - title: 'ID', - visible: false, - switchable: false, - searchable: false, - } - ]; - - columns.push({ - field: 'IPN', - title: 'IPN', - sortable: true, - }), - - columns.push({ - field: 'name', - title: '{% trans '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 += `{% trans "Inactive" %}`; - } - return display; - } - }); - - for (header of options.headers) { + for (header of table_headers) { columns.push({ field: header, title: header, @@ -260,16 +187,17 @@ function loadParametricPartTable(table, url, options={}) { } $(table).inventreeTable({ - url: url, - sortName: 'pk', +/* url: url,*/ + sortName: 'name', method: 'get', - queryParams: filters, + queryParams: table_headers, groupBy: false, name: options.name || 'parametric', - original: params, +/* original: params,*/ formatNoMatches: function() { return "{% trans "No parts found" %}"; }, columns: columns, showColumns: true, + data: table_data, }); } From 756f3ddb0fed6aacbe5283c27a4d9844a9bf347e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 1 Oct 2020 00:25:24 +1000 Subject: [PATCH 04/49] Hide main elements of navigation bar based on user permissions --- InvenTree/templates/navbar.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/InvenTree/templates/navbar.html b/InvenTree/templates/navbar.html index cfadad977c..57a902b755 100644 --- a/InvenTree/templates/navbar.html +++ b/InvenTree/templates/navbar.html @@ -15,9 +15,16 @@