Merge branch 'tree-improvements'

This commit is contained in:
Oliver 2018-05-04 23:32:20 +10:00
commit 2edb865528
23 changed files with 413 additions and 438 deletions

View File

@ -1,6 +1,7 @@
<div class='navigation'>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li><a href='#' id='toggle-part-tree'><b>+</b></a></li>
<li class="breadcrumb-item{% if category is None %} active" aria-current="page{% endif %}"><a href="/part/">Parts</a></li>
{% if category %}
{% for path_item in category.parentpath %}

View File

@ -0,0 +1,157 @@
{% extends "part/part_app_base.html" %}
{% load static %}
{% block content %}
<div class='row'>
<div class='col-sm-6'>
{% if category %}
<h3>{{ category.name }}</h3>
<p>{{ category.description }}</p>
{% else %}
<h3>Parts</h3>
{% endif %}
</div>
<div class='col-sm-6'>
<h3>
<div style='float: right;'>
<button class='btn btn-success' id='cat-create'>New Category</button>
{% if category %}
<div class="dropdown" style="float: right;">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
Options
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" id='cat-edit' title='Edit part category'>Edit</a></li>
<li><a href="#" id='cat-delete' title='Delete part category'>Delete</a></li>
</ul>
</div>
{% endif %}
</div>
</h3>
</div>
</div>
{% if category %}
{% include "part/subcategories.html" with children=category.children.all %}
{% else %}
{% include "part/subcategories.html" with children=children %}
{% endif %}
<hr>
<table class='table table-striped table-condensed' id='part-table'>
</table>
{% endblock %}
{% block js_ready %}
{{ block.super }}
$("#cat-create").click(function() {
launchModalForm("#modal-form",
"{% url 'category-create' %}",
{
follow: true,
{% if category %}
data: {
category: {{ category.id }}
}
{% endif %}
});
})
{% if category %}
$("#cat-edit").click(function () {
launchModalForm("#modal-form",
"{% url 'category-edit' category.id %}",
{
reload: true
},
);
return false;
});
{% if category.parent %}
var redirect = "{% url 'category-detail' category.parent.id %}";
{% else %}
var redirect = "{% url 'part-index' %}";
{% endif %}
$('#cat-delete').click(function() {
launchDeleteForm('#modal-delete',
"{% url 'category-delete' category.id %}",
{
redirect: redirect
});
});
{% endif %}
$("#part-table").bootstrapTable({
sortable: true,
search: true,
sortName: 'description',
idField: 'pk',
method: 'get',
pagination: true,
rememberOrder: true,
{% if category %}
queryParams: function(p) {
return {
{% if category %}
category: {{ category.id }},
{% endif %}
}
},
{% endif %}
columns: [
{
checkbox: true,
title: 'Select',
searchable: false,
},
{
field: 'pk',
title: 'ID',
visible: false,
},
{
field: 'name',
title: 'Part',
sortable: true,
formatter: function(value, row, index, field) {
return renderLink(value, row.url);
}
},
{
sortable: true,
field: 'description',
title: 'Description',
},
{% if category == None %}
{
sortable: true,
field: 'category',
title: 'Category',
formatter: function(value, row, index, field) {
if (row.category) {
return renderLink(row.category.name, row.category.url);
}
else {
return '';
}
}
},
{% endif %}
{
field: 'total_stock',
title: 'Stock',
searchable: false,
sortable: true,
}
],
url: "{% url 'api-part-list' %}",
});
{% endblock %}

View File

@ -1,93 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
{% include "part/cat_link.html" with category=category %}
<p>
<b>{{ category.name }}</b><br>
<i>{{ category.description }}</i>
</p>
{% if category.has_children %}
<h4>Subcategories</h4>
{% include "part/category_subcategories.html" with children=category.children.all %}
{% endif %}
{% if category.has_parts %}
<table class='table table-striped table-condensed' id='part-table'>
</table>
{% endif %}
<div class='container-fluid'>
<button type='button' class='btn btn-primary' id='create-cat'>
New Category
</button>
<button class="btn btn-info" id='edit-category'>Edit Category</button>
<button class="btn btn-success" id='create-part'>New Part</button>
<button class="btn btn-danger" id='delete-category'>Delete Category</button>
<button class='btn btn-primary' id='get-rows'>Do thing</button>
</div>
{% include 'modals.html' %}
{% endblock %}
{% block js_load %}
<script type='text/javascript' src="{% static 'script/modal_form.js' %}"></script>
{% endblock %}
{% block js_ready %}
$("#edit-category").click(function () {
launchModalForm("#modal-form",
"{% url 'category-edit' category.id %}",
{reload: true},
);
});
{% if category.parent %}
var categoryRedirect = "{% url 'category-detail' category.parent.id %}";
{% else %}
var categoryRedirect = "{% url 'part-index' %}";
{% endif %}
$("#delete-category").click(function() {
launchDeleteForm("#modal-delete",
"{% url 'category-delete' category.id %}",
{
redirect: categoryRedirect
});
});
$("#create-cat").click(function() {
launchModalForm("#modal-form",
"{% url 'category-create' %}",
{
follow: true,
data: {
category: {{ category.id }}
}
});
});
$("#create-part").click( function() {
launchModalForm("#modal-form",
"{% url 'part-create' %}",
{
data: {
category: {{ category.id }}
},
follow: true
});
});
{% include "part/category_parts.html" with category=category %}
$("#get-rows").click( function() {
alert($("#part-table").bootstrapTable('getSelections'));
});
{% endblock %}

View File

@ -1,63 +0,0 @@
$("#part-table").bootstrapTable({
sortable: true,
search: true,
sortName: 'description',
idField: 'pk',
method: 'get',
pagination: true,
rememberOrder: true,
{% if category %}
queryParams: function(p) {
return {
category: {{ category.id }},
}
},
{% endif %}
columns: [
{
checkbox: true,
title: 'Select',
searchable: false,
},
{
field: 'pk',
title: 'ID',
visible: false,
},
{
field: 'name',
title: 'Part',
sortable: true,
formatter: function(value, row, index, field) {
return renderLink(value, row.url);
}
},
{
sortable: true,
field: 'description',
title: 'Description',
},
{% if category == None %}
{
sortable: true,
field: 'category',
title: 'Category',
formatter: function(value, row, index, field) {
if (row.category) {
return renderLink(row.category.name, row.category.url);
}
else {
return '';
}
}
},
{% endif %}
{
field: 'total_stock',
title: 'Stock',
searchable: false,
sortable: true,
}
],
url: "{% url 'api-part-list' %}",
});

View File

@ -1,11 +0,0 @@
<ul class="list-group">
{% for child in children %}
<li class="list-group-item">
<b><a href="{% url 'category-detail' child.id %}">{{ child.name }}</a></b>
{% if child.description %}
<i> - {{ child.description }}</i>
{% endif %}
<span class='badge'>{{ child.partcount }}</span>
</li>
{% endfor %}
</ul>

View File

@ -1,77 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block css %}
<link rel='stylesheet' href="{% static 'css/bootstrap-treeview.css' %}">
{% endblock %}
{% block content %}
{% include "part/cat_link.html" with category=category %}
{% include 'modals.html' %}
{% if children.all|length > 0 %}
<h4>Part Categories</h4>
{% include "part/category_subcategories.html" with children=children %}
{% endif %}
<table class='table table-striped table-condensed' id='part-table'>
<div class='container-fluid'>
<button type='button' class='btn btn-primary' id='create-cat'>
New Category
</button>
<button class="btn btn-success" id='create-part'>New Part</button>
</div>
{% endblock %}
{% block js_load %}
<script type='text/javascript' src="{% static 'script/modal_form.js' %}"></script>
{% endblock %}
{% block js_ready %}
$("#create-cat").click(function() {
launchModalForm("#modal-form",
"{% url 'category-create' %}",
{
follow: true
});
});
function loadTree() {
var requestData = {};
{% if category %}
requestData.category = {{ category.id }};
{% endif %}
$.ajax({
url: "{% url 'api-part-tree' %}",
type: 'get',
dataType: 'json',
data: requestData,
success: function (response) {
if (response.tree) {
$("#part-tree").treeview({
data: response.tree,
enableLinks: true
});
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Error retrieving part tree:\n' + thrownError);
}
});
}
$("#create-part").click(function() {
launchModalForm("#modal-form", "{% url 'part-create' %}");
});
{% include "part/category_parts.html" %}
loadTree();
{% endblock %}

View File

@ -0,0 +1,28 @@
{% extends "base.html" %}
{% block sidenav %}
<div id='part-tree'></div>
{% endblock %}
{% block pre_content %}
{% if part %}
{% include "part/cat_link.html" with category=part.category %}
{% else %}
{% include 'part/cat_link.html' with category=category %}
{% endif %}
{% endblock %}
{% block js_ready %}
{{ block.super }}
loadTree("{% url 'api-part-tree' %}",
"#part-tree");
$("#toggle-part-tree").click(function() {
toggleSideNav("#sidenav");
return false;
})
initSideNav();
{% endblock %}

View File

@ -1,11 +1,9 @@
{% extends "base.html" %}
{% extends "part/part_app_base.html" %}
{% load static %}
{% block content %}
{% include "part/cat_link.html" with category=part.category %}
<div class="row">
<div class="col-sm-6">
<div class="media">
@ -85,7 +83,7 @@
{% endblock %}
{% block js_ready %}
{{ block.super }}
$("#part-thumb").click(function() {
launchModalForm("#modal-form",
"{% url 'part-image' part.id %}",

View File

@ -0,0 +1,27 @@
{% if children|length > 0 %}
<hr>
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1">Child Categories</a><span class='badge'>{{ children|length }}</span>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
<ul class="list-group">
{% for child in children %}
<li class="list-group-item">
<b><a href="{% url 'category-detail' child.id %}">{{ child.name }}</a></b>
{% if child.description %}
<i> - {{ child.description }}</i>
{% endif %}
<span class='badge'>{{ child.partcount }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endif %}

View File

@ -23,7 +23,7 @@ from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView
class PartIndex(ListView):
model = Part
template_name = 'part/index.html'
template_name = 'part/category.html'
context_object_name = 'parts'
def get_queryset(self):
@ -128,7 +128,7 @@ class CategoryDetail(DetailView):
model = PartCategory
context_object_name = 'category'
queryset = PartCategory.objects.all()
template_name = 'part/category_detail.html'
template_name = 'part/category.html'
class CategoryEdit(AjaxUpdateView):

View File

@ -47,7 +47,7 @@
margin-right: 50px;
margin-left: 50px;
width: 100%;
transition: 0.5s;
//transition: 0.1s;
}
.body {
@ -88,7 +88,7 @@
position: fixed; /* Stay in place */
background-color: #fff; /* Black*/
overflow-x: hidden; /* Disable horizontal scroll */
transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */
//transition: 0.1s; /* 0.5 second transition effect to slide in the sidenav */
}
.wrapper {

View File

@ -1,9 +1,52 @@
function loadTree(url, tree, data) {
$.ajax({
url: url,
type: 'get',
dataType: 'json',
data: data,
success: function (response) {
if (response.tree) {
$(tree).treeview({
data: response.tree,
enableLinks: true
});
}
},
error: function (xhr, ajaxOptions, thrownError) {
//TODO
}
});
}
function openSideNav() {
document.getElementById("sidenav").style.width = "250px";
document.getElementById("inventree-content").style.marginLeft = "270px";
sessionStorage.setItem('inventree-sidenav-state', 'open');
}
function closeSideNav() {
document.getElementById("sidenav").style.width = "0";
document.getElementById("inventree-content").style.marginLeft = "50px";
sessionStorage.setItem('inventree-sidenav-state', 'closed');
}
function toggleSideNav(nav) {
if ($(nav).width() == 0) {
openSideNav();
}
else {
closeSideNav();
}
}
function initSideNav() {
if (sessionStorage.getItem("inventree-sidenav-state") && sessionStorage.getItem('inventree-sidenav-state') == 'open') {
openSideNav();
}
else {
closeSideNav();
}
}

View File

@ -1,20 +0,0 @@
function loadTree(url, tree, data) {
$.ajax({
url: url,
type: 'get',
dataType: 'json',
data: data,
success: function (response) {
if (response.tree) {
$(tree).treeview({
data: response.tree,
enableLinks: true
});
}
},
error: function (xhr, ajaxOptions, thrownError) {
//TODO
}
});
}

View File

@ -1,47 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
{% include "stock/loc_link.html" with location=None %}
<div class='row'>
<div class='col-sm-6'>
<h3>Storage Locations</h3>
</div>
<div class='col-sm-6'>
<h3>
<button style='float: right;' class='btn btn-success' id='location-create'>New Stock Location</button>
</h3>
</div>
</div>
<hr>
{% if locations|length > 0 %}
{% include "stock/location_list.html" with locations=locations %}
<hr>
{% endif %}
<h3>Stock Items</h3>
<table class="table table-striped" id='stock-table'>
</table>
{% include 'modals.html' %}
{% endblock %}
{% block js_load %}
<script type='text/javascript' src="{% static 'script/modal_form.js' %}"></script>
{% endblock %}
{% block js_ready %}
$('#location-create').click(function () {
launchModalForm("#modal-form",
"{% url 'stock-location-create' %}",
{
follow: true
});
});
{% include "stock/stock_table.html" %}
{% endblock %}

View File

@ -1,9 +1,7 @@
{% extends "base.html" %}
{% extends "stock/stock_app_base.html" %}
{% load static %}
{% block content %}
{% include "stock/loc_link.html" with location=item.location %}
<h3>Stock entry details</h3>
<table class="table table-striped">
@ -109,8 +107,6 @@
<button class='btn btn-danger' id='delete-item'>Delete Stock Item</button>
</div>
{% include 'modals.html' %}
{% endblock %}
{% block js_load %}

View File

@ -1,6 +1,7 @@
<div class="navigation">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li><a href='#' id='toggle-stock-tree'><b>+</b></a></li>
<li class="breadcrumb-item{% if location is None %} active" aria-current="page{% endif %}"><a href="/stock/">Stock</a></li>
{% if location %}
{% for path_item in location.parentpath %}

View File

@ -1,45 +1,50 @@
{% extends "base.html" %}
{% extends "stock/stock_app_base.html" %}
{% load static %}
{% block content %}
{% include "stock/loc_link.html" with location=location %}
<div class='row'>
<div class='col-sm-6'>
{% if location %}
<h3>{{ location.name }}</h3>
<p>{{ location.description }}</p>
{% else %}
<h3>Stock</h3>
{% endif %}
</div>
<div class='col-sm-6'>
<h3>
<div style='float: right;'>
<button class='btn btn-success' id='location-create'>New Stock Location</button>
{% if location %}
<div class="dropdown" style="float: right;">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Stock Location
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Options
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="#" id='location-edit' title='Edit stock location'>Edit</a></li>
<li><a href="#" id='location-delete' title='Delete stock location'>Delete</a></li>
</ul>
</div>
{% endif %}
</div>
</h3>
</div>
</div>
{% if location.has_children %}
<h3>Sub Locations</h3>
{% include "stock/location_list.html" with locations=location.children %}
{% if location %}
{% include 'stock/location_list.html' with children=location.children.all %}
{% else %}
{% include 'stock/location_list.html' with children=locations %}
{% endif %}
{% if location.has_items %}
<hr>
<table class='table table-striped table-condensed' id='stock-table'>
</table>
{% endif %}
<div class='container-fluid' style='float: right;'>
<button class="btn btn-success" id='item-create'>New Stock Item</span></button>
<div class="dropdown" style='float: right;'>
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Selected
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Options
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="#" id='multi-item-stocktake' title='Stocktake selected stock items'>Stocktake</a></li>
@ -57,19 +62,22 @@
<script type='text/javascript' src="{% static 'script/modal_form.js' %}"></script>
{% endblock %}
{% block js_ready %}
{{ block.super }}
$('#location-create').click(function () {
launchModalForm("#modal-form",
"{% url 'stock-location-create' %}",
{
data: {
{% if location %}
location: {{ location.id }}
{% endif %}
},
follow: true
});
return false;
});
{% if location %}
$('#location-edit').click(function() {
launchModalForm("#modal-form",
"{% url 'stock-location-edit' location.id %}",
@ -86,7 +94,9 @@
redirect: "{% url 'stock-index' %}"
});
return false;
})
});
{% endif %}
$('#item-create').click(function () {
launchModalForm("#modal-form",
@ -96,7 +106,9 @@
$("#stock-table").bootstrapTable('refresh');
},
data: {
{% if location %}
location: {{ location.id }}
{% endif %}
}
});
@ -133,6 +145,65 @@
return false;
});
{% include 'stock/stock_table.html' with location=location %}
$("#stock-table").bootstrapTable({
sortable: true,
search: true,
method: 'get',
pagination: true,
rememberOrder: true,
{% if location %}
queryParams: function(p) {
return {
location: {{ location.id }}
}
},
{% endif %}
columns: [
{
checkbox: true,
title: 'Select',
searchable: false,
},
{
field: 'pk',
title: 'ID',
visible: false,
},
{
field: 'part.name',
title: 'Part',
sortable: true,
formatter: function(value, row, index, field) {
return renderLink(value, row.part.url);
}
},
{% if location == None %}
{
field: 'location',
title: 'Location',
sortable: true,
formatter: function(value, row, index, field) {
if (row.location) {
return renderLink(row.location.name, row.location.url);
}
else {
return '';
}
}
},
{% endif %}
{
field: 'quantity',
title: 'Stock',
sortable: true,
},
{
field: 'status',
title: 'Status',
sortable: true,
}
],
url: "{% url 'api-stock-list' %}",
});
{% endblock %}

View File

@ -1,5 +1,23 @@
<ul class="list-group">
{% for child in locations.all %}
<li class="list-group-item"><a href="{% url 'stock-location-detail' child.id %}">{{ child.name }}</a> - <i>{{ child.description }}</i></li>
{% endfor %}
</ul>
{% if children|length > 0 %}
<hr>
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1">Sub-Locations</a><span class='badge'>{{ children|length }}</span>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
<ul class="list-group">
{% for child in children %}
<li class="list-group-item"><a href="{% url 'stock-location-detail' child.id %}">{{ child.name }}</a> - <i>{{ child.description }}</i></li>
<span class='badge'>{{ child.partcount }}</span>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endif %}

View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load static %}
{% block sidenav %}
<div id='stock-tree'></div>
{% endblock %}
{% block pre_content %}
{% if item %}
{% include 'stock/loc_link.html' with location=item.location %}
{% else %}
{% include 'stock/loc_link.html' with location=location %}
{% endif %}
{% endblock %}
{% block js_ready %}
initSideNav();
{{ block.super }}
loadTree("{% url 'api-stock-tree' %}",
"#stock-tree");
$("#toggle-stock-tree").click(function() {
toggleSideNav("#sidenav");
return false;
})
{% endblock %}

View File

@ -1,60 +0,0 @@
$("#stock-table").bootstrapTable({
sortable: true,
search: true,
method: 'get',
pagination: true,
rememberOrder: true,
{% if location %}
queryParams: function(p) {
return {
location: {{ location.id }}
}
},
{% endif %}
columns: [
{
checkbox: true,
title: 'Select',
searchable: false,
},
{
field: 'pk',
title: 'ID',
visible: false,
},
{
field: 'part.name',
title: 'Part',
sortable: true,
formatter: function(value, row, index, field) {
return renderLink(value, row.part.url);
}
},
{% if location == None %}
{
field: 'location',
title: 'Location',
sortable: true,
formatter: function(value, row, index, field) {
if (row.location) {
return renderLink(row.location.name, row.location.url);
}
else {
return '';
}
}
},
{% endif %}
{
field: 'quantity',
title: 'Stock',
sortable: true,
},
{
field: 'status',
title: 'Status',
sortable: true,
}
],
url: "{% url 'api-stock-list' %}",
});

View File

@ -20,7 +20,7 @@ from .forms import StocktakeForm
class StockIndex(ListView):
model = StockItem
template_name = 'stock/index.html'
template_name = 'stock/location.html'
context_obect_name = 'locations'
def get_context_data(self, **kwargs):

View File

@ -32,14 +32,22 @@ InvenTree
<div class='main body wrapper'>
{% include "sidebar.html" %}
<div class="container container-fluid inventree-content" id='inventree-content'>
{% block content %}
<!-- Each view fills in here.. -->
<div class='sidenav' id='sidenav'>
{% block sidenav %}
{% endblock %}
</div>
<div class="container container-fluid inventree-content" id='inventree-content'>
{% block pre_content %}
{% endblock %}
{% block content %}
<!-- Each view fills in here.. -->
{% endblock %}
{% block post_content %}
{% endblock %}
</div>
{% include 'modals.html' %}
{% include 'notification.html' %}
</div>
@ -54,38 +62,18 @@ InvenTree
<script type='text/javascript' src="{% static 'script/bootstrap-table-en-US.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/tables.js' %}"></script>
<script type='text/javascript' src="{% static 'script/trees.js' %}"></script>
<script type='text/javascript' src="{% static 'script/sidenav.js' %}"></script>
<script type='text/javascript' src="{% static 'script/notification.js' %}"></script>
<script type='text/javascript' src="{% static 'script/jquery.form.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/modal_form.js' %}"></script>
{% block js_load %}
{% endblock %}
<script type='text/javascript'>
$(document).ready(function () {
loadTree("{% url 'api-part-tree' %}",
"#part-tree");
loadTree("{% url 'api-stock-tree' %}",
"#stock-tree");
$('#logo').click(function() {
if ($("#sidenav").width() == 0) {
openSideNav();
}
else {
closeSideNav();
}
});
{% block js_ready %}
{% endblock %}
showCachedAlerts();
});
</script>

View File

@ -1,9 +0,0 @@
<div class='sidenav' id='sidenav'>
<div id='part-tree'></div>
<hr>
<div id='stock-tree'></div>
</div>