Skip to content

Commit

Permalink
Merge pull request #952 from SchrodingersGat/variant-table
Browse files Browse the repository at this point in the history
Add ability to filter part list by 'ancestor'
  • Loading branch information
SchrodingersGat committed Sep 2, 2020
2 parents 104b9d2 + b89588f commit 81b5031
Show file tree
Hide file tree
Showing 11 changed files with 1,713 additions and 1,335 deletions.
Binary file modified InvenTree/locale/de/LC_MESSAGES/django.mo
Binary file not shown.
993 changes: 555 additions & 438 deletions InvenTree/locale/de/LC_MESSAGES/django.po

Large diffs are not rendered by default.

942 changes: 512 additions & 430 deletions InvenTree/locale/en/LC_MESSAGES/django.po

Large diffs are not rendered by default.

942 changes: 512 additions & 430 deletions InvenTree/locale/es/LC_MESSAGES/django.po

Large diffs are not rendered by default.

25 changes: 20 additions & 5 deletions InvenTree/part/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ class PartList(generics.ListCreateAPIView):
- purchaseable: Filter by purcahseable field
- salable: Filter by salable field
- active: Filter by active field
- ancestor: Filter parts by 'ancestor' (template / variant tree)
"""

serializer_class = part_serializers.PartSerializer
Expand Down Expand Up @@ -387,10 +388,24 @@ def filter_queryset(self, queryset):
We overide the DRF filter_fields here because
"""

params = self.request.query_params

queryset = super().filter_queryset(queryset)

# Filter by 'ancestor'?
ancestor = params.get('ancestor', None)

if ancestor is not None:
# If an 'ancestor' part is provided, filter to match only children
try:
ancestor = Part.objects.get(pk=ancestor)
descendants = ancestor.get_descendants(include_self=False)
queryset = queryset.filter(pk__in=[d.pk for d in descendants])
except (ValueError, Part.DoesNotExist):
pass

# Filter by 'starred' parts?
starred = self.request.query_params.get('starred', None)
starred = params.get('starred', None)

if starred is not None:
starred = str2bool(starred)
Expand All @@ -402,10 +417,10 @@ def filter_queryset(self, queryset):
queryset = queryset.exclude(pk__in=starred_parts)

# Cascade?
cascade = str2bool(self.request.query_params.get('cascade', None))
cascade = str2bool(params.get('cascade', None))

# Does the user wish to filter by category?
cat_id = self.request.query_params.get('category', None)
cat_id = params.get('category', None)

if cat_id is None:
# No category filtering if category is not specified
Expand Down Expand Up @@ -437,7 +452,7 @@ def filter_queryset(self, queryset):
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)

# Filter by whether the part has stock
has_stock = self.request.query_params.get("has_stock", None)
has_stock = params.get("has_stock", None)
if has_stock is not None:
has_stock = str2bool(has_stock)

Expand All @@ -447,7 +462,7 @@ def filter_queryset(self, queryset):
queryset = queryset.filter(Q(in_stock__lte=0))

# If we are filtering by 'low_stock' status
low_stock = self.request.query_params.get('low_stock', None)
low_stock = params.get('low_stock', None)

if low_stock is not None:
low_stock = str2bool(low_stock)
Expand Down
4 changes: 3 additions & 1 deletion InvenTree/part/templates/part/cat_link.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{% load i18n %}

<div class='navigation'>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li><a href='#' id='toggle-part-tree'><b><span class='fas fa-stream'></span></b></a></li>
<li class="breadcrumb-item{% if category is None %} active" aria-current="page{% endif %}"><a href="/part/">Parts</a></li>
<li class="breadcrumb-item{% if category is None %} active" aria-current="page{% endif %}"><a href="/part/">{% trans "Parts" %}</a></li>
{% if category %}
{% for path_item in category.parentpath %}
<li class="breadcrumb-item"><a href="{% url 'category-detail' path_item.id %}">{{ path_item.name }}</a></li>
Expand Down
2 changes: 1 addition & 1 deletion InvenTree/part/templates/part/part_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
{% endif %}
{% if part.variant_of %}
<div class='alert alert-info alert-block'>
{% trans "This part is a variant of" %} <b><a href="{% url 'part-detail' part.variant_of.id %}">{{ part.variant_of.full_name }}</a></b>
{% trans "This part is a variant of" %} <b><a href="{% url 'part-variants' part.variant_of.id %}">{{ part.variant_of.full_name }}</a></b>
</div>
{% endif %}

Expand Down
44 changes: 16 additions & 28 deletions InvenTree/part/templates/part/variants.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{% extends "part/part_base.html" %}
{% load static %}
{% load i18n %}
{% load inventree_extras %}

{% block details %}
{% include "part/tabs.html" with tab='variants' %}

<div class='row'>
<div class='col-sm-6'>
<h4>Part Variants</h4>
<h4>{% trans "Part Variants" %}</h4>
</div>
<div class='col-sm-6'>
</div>
Expand All @@ -17,45 +18,32 @@ <h4>Part Variants</h4>
<div id='button-toolbar'>
<div class='btn-group'>
{% if part.is_template and part.active %}
<button class='btn btn-success' id='new-variant' title='Create new variant'>New Variant</button>
<button class='btn btn-success' id='new-variant' title='{% trans "Create new variant" %}'>{% trans "New Variant" %}</button>
{% endif %}
</div>
</div>

<table class='table table-striped table-condensed' id='variant-table' data-toolbar='#button-toolbar'>
<thead>
<tr>
<th data-sortable='true'>Variant</th>
<th data-sortable='true'>Description</th>
<th data-sortable='true'>Stock</th>
</tr>
</thead>
<tbody>
{% for variant in part.variants.all %}
<tr>
<td>
{% include "hover_image.html" with image=variant.image hover=True %}
<a href="{% url 'part-detail' variant.id %}">{{ variant.full_name }}</a>
{% if not variant.active %}
<span class='label label-warning' style='float: right;'>INACTIVE</span>
{% endif %}
</td>
<td>{{ variant.description }}</td>
<td>{% decimal variant.total_stock %}</td>
</tr>
{% endfor %}
</tbody>
<table class='table table-striped table-condensed' id='variants-table' data-toolbar='#button-toolbar'>
</table>

{% endblock %}

{% block js_load %}
{{ block.super }}

<!-- jquery-treegrid -->
<script type='text/javascript' src='{% static "treegrid/js/jquery.treegrid.js" %}'></script>
<script type='text/javascript' src='{% static "treegrid/js/jquery.treegrid.bootstrap3.js" %}'></script>

<!-- boostrap-table-treegrid -->
<script type='text/javascript' src='{% static "bootstrap-table/extensions/treegrid/bootstrap-table-treegrid.js" %}'></script>

{% endblock %}

{% block js_ready %}
{{ block.super }}


$('#variant-table').inventreeTable({
});
loadPartVariantTable($('#variants-table'), {{ part.pk }});

$('#new-variant').click(function() {
launchModalForm(
Expand Down
2 changes: 1 addition & 1 deletion InvenTree/part/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def get_form(self):
form = super(AjaxCreateView, self).get_form()

# Hide some variant-related fields
form.fields['variant_of'].widget = HiddenInput()
# form.fields['variant_of'].widget = HiddenInput()

return form

Expand Down
92 changes: 92 additions & 0 deletions InvenTree/templates/js/part.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,98 @@
);
}


function loadPartVariantTable(table, partId, options) {
/* Load part variant table
*/

var params = {
ancestor: partId,
};

var cols = [
{
field: 'pk',
title: 'ID',
visible: false,
switchable: false,
},
{
field: 'name',
title: '{% trans "Name" %}',
switchable: false,
formatter: function(value, row, index, field) {
var html = '';

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>';
}

html += imageHoverIcon(row.thumbnail);
html += renderLink(name, `/part/${row.pk}/`);

return html;
},
},
{
field: 'IPN',
title: '{% trans 'IPN' %}',
},
{
field: 'revision',
title: '{% trans 'Revision' %}',
},
{
field: 'description',
title: '{% trans "Description" %}',
},
{
field: 'in_stock',
title: '{% trans "Stock" %}',
}
];

table.inventreeTable({
url: "{% url 'api-part-list' %}",
name: 'partvariants',
showColumns: true,
original: params,
queryParams: params,
formatNoMatches: function() { return "{% trans "No variants found" %}"; },
columns: cols,
treeEnable: true,
rootParentId: partId,
parentIdField: 'variant_of',
idField: 'pk',
uniqueId: 'pk',
treeShowField: 'name',
sortable: true,
search: true,
onPostBody: function() {
table.treegrid({
treeColumn: 0,
});

table.treegrid('collapseAll');
}
});
}


function loadPartTable(table, url, options={}) {
/* Load part listing data into specified table.
*
Expand Down
2 changes: 1 addition & 1 deletion tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def translate(c):
or after adding translations for existing strings.
"""

manage(c, "makemigrations")
manage(c, "makemessages")
manage(c, "compilemessages")

@task
Expand Down

0 comments on commit 81b5031

Please sign in to comment.