mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
7be1edd896
2
.gitignore
vendored
2
.gitignore
vendored
@ -34,6 +34,8 @@ docs/_build
|
||||
# Local static and media file storage (only when running in development mode)
|
||||
InvenTree/media
|
||||
InvenTree/static
|
||||
media
|
||||
static
|
||||
|
||||
# Local config file
|
||||
config.yaml
|
||||
|
@ -88,6 +88,12 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.basecurrency {
|
||||
color: #050;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bomselect {
|
||||
max-width: 250px;
|
||||
}
|
||||
@ -198,6 +204,28 @@
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.settings-container {
|
||||
width: 90%;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.settings-nav {
|
||||
height: 100%;
|
||||
width: 160px;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
//top: 0;
|
||||
//left: 0;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.settings-content {
|
||||
margin-left: 175px;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
.breadcrump {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
@ -14,11 +14,13 @@ from company.urls import company_urls
|
||||
from company.urls import supplier_part_urls
|
||||
from company.urls import price_break_urls
|
||||
|
||||
from common.urls import common_urls
|
||||
from part.urls import part_urls
|
||||
from stock.urls import stock_urls
|
||||
from build.urls import build_urls
|
||||
from order.urls import order_urls
|
||||
|
||||
from common.api import common_api_urls
|
||||
from part.api import part_api_urls, bom_api_urls
|
||||
from company.api import company_api_urls
|
||||
from stock.api import stock_api_urls
|
||||
@ -39,6 +41,7 @@ from users.urls import user_urls
|
||||
admin.site.site_header = "InvenTree Admin"
|
||||
|
||||
apipatterns = [
|
||||
url(r'^common/', include(common_api_urls)),
|
||||
url(r'^part/', include(part_api_urls)),
|
||||
url(r'^bom/', include(bom_api_urls)),
|
||||
url(r'^company/', include(company_api_urls)),
|
||||
@ -53,11 +56,23 @@ apipatterns = [
|
||||
url(r'^$', InfoView.as_view(), name='inventree-info'),
|
||||
]
|
||||
|
||||
settings_urls = [
|
||||
|
||||
url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'),
|
||||
url(r'^currency/?', SettingsView.as_view(template_name='InvenTree/settings/currency.html'), name='settings-currency'),
|
||||
url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'),
|
||||
|
||||
# Catch any other urls
|
||||
url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings'),
|
||||
]
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^part/', include(part_urls)),
|
||||
url(r'^supplier-part/', include(supplier_part_urls)),
|
||||
url(r'^price-break/', include(price_break_urls)),
|
||||
|
||||
url(r'^common/', include(common_urls)),
|
||||
|
||||
url(r'^stock/', include(stock_urls)),
|
||||
|
||||
url(r'^company/', include(company_urls)),
|
||||
@ -70,7 +85,7 @@ urlpatterns = [
|
||||
url(r'^login/', auth_views.LoginView.as_view(), name='login'),
|
||||
url(r'^logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='logout'),
|
||||
|
||||
url(r'^settings/', SettingsView.as_view(), name='settings'),
|
||||
url(r'^settings/', include(settings_urls)),
|
||||
|
||||
url(r'^edit-user/', EditUserView.as_view(), name='edit-user'),
|
||||
url(r'^set-password/', SetPasswordView.as_view(), name='set-password'),
|
||||
|
39
InvenTree/common/api.py
Normal file
39
InvenTree/common/api.py
Normal file
@ -0,0 +1,39 @@
|
||||
"""
|
||||
Provides a JSON API for common components.
|
||||
"""
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from rest_framework import permissions, generics, filters
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from .models import Currency
|
||||
from .serializers import CurrencySerializer
|
||||
|
||||
|
||||
class CurrencyList(generics.ListCreateAPIView):
|
||||
""" API endpoint for accessing a list of Currency objects.
|
||||
|
||||
- GET: Return a list of Currencies
|
||||
- POST: Create a new currency
|
||||
"""
|
||||
|
||||
queryset = Currency.objects.all()
|
||||
serializer_class = CurrencySerializer
|
||||
|
||||
permission_classes = [
|
||||
permissions.IsAuthenticated,
|
||||
]
|
||||
|
||||
filter_backends = [
|
||||
filters.OrderingFilter,
|
||||
]
|
||||
|
||||
ordering_fields = ['suffix', 'value']
|
||||
|
||||
|
||||
common_api_urls = [
|
||||
url(r'^currency/?$', CurrencyList.as_view(), name='api-currency-list'),
|
||||
]
|
24
InvenTree/common/forms.py
Normal file
24
InvenTree/common/forms.py
Normal file
@ -0,0 +1,24 @@
|
||||
"""
|
||||
Django forms for interacting with common objects
|
||||
"""
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from InvenTree.forms import HelperForm
|
||||
|
||||
from .models import Currency
|
||||
|
||||
|
||||
class CurrencyEditForm(HelperForm):
|
||||
""" Form for creating / editing a currency object """
|
||||
|
||||
class Meta:
|
||||
model = Currency
|
||||
fields = [
|
||||
'symbol',
|
||||
'suffix',
|
||||
'description',
|
||||
'value',
|
||||
'base'
|
||||
]
|
22
InvenTree/common/serializers.py
Normal file
22
InvenTree/common/serializers.py
Normal file
@ -0,0 +1,22 @@
|
||||
"""
|
||||
JSON serializers for common components
|
||||
"""
|
||||
|
||||
from .models import Currency
|
||||
|
||||
from InvenTree.serializers import InvenTreeModelSerializer
|
||||
|
||||
|
||||
class CurrencySerializer(InvenTreeModelSerializer):
|
||||
""" Serializer for Currency object """
|
||||
|
||||
class Meta:
|
||||
model = Currency
|
||||
fields = [
|
||||
'pk',
|
||||
'symbol',
|
||||
'suffix',
|
||||
'description',
|
||||
'value',
|
||||
'base'
|
||||
]
|
7
InvenTree/common/templates/common/delete_currency.html
Normal file
7
InvenTree/common/templates/common/delete_currency.html
Normal file
@ -0,0 +1,7 @@
|
||||
{% extends "modal_delete_form.html" %}
|
||||
|
||||
{% block pre_form_content %}
|
||||
|
||||
Are you sure you wish to delete this currency?
|
||||
|
||||
{% endblock %}
|
18
InvenTree/common/urls.py
Normal file
18
InvenTree/common/urls.py
Normal file
@ -0,0 +1,18 @@
|
||||
"""
|
||||
URL lookup for common views
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
|
||||
from . import views
|
||||
|
||||
currency_urls = [
|
||||
url(r'^new/', views.CurrencyCreate.as_view(), name='currency-create'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/edit/', views.CurrencyEdit.as_view(), name='currency-edit'),
|
||||
url(r'^(?P<pk>\d+)/delete/', views.CurrencyDelete.as_view(), name='currency-delete'),
|
||||
]
|
||||
|
||||
common_urls = [
|
||||
url(r'currency/', include(currency_urls)),
|
||||
]
|
@ -1 +1,35 @@
|
||||
# Create your views here.
|
||||
"""
|
||||
Django views for interacting with common models
|
||||
"""
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView
|
||||
|
||||
from . import models
|
||||
from . import forms
|
||||
|
||||
|
||||
class CurrencyCreate(AjaxCreateView):
|
||||
""" View for creating a new Currency object """
|
||||
|
||||
model = models.Currency
|
||||
form_class = forms.CurrencyEditForm
|
||||
ajax_form_title = 'Create new Currency'
|
||||
|
||||
|
||||
class CurrencyEdit(AjaxUpdateView):
|
||||
""" View for editing an existing Currency object """
|
||||
|
||||
model = models.Currency
|
||||
form_class = forms.CurrencyEditForm
|
||||
ajax_form_title = 'Edit Currency'
|
||||
|
||||
|
||||
class CurrencyDelete(AjaxDeleteView):
|
||||
""" View for deleting an existing Currency object """
|
||||
|
||||
model = models.Currency
|
||||
ajax_form_title = 'Delete Currency'
|
||||
ajax_template_name = "common/delete_currency.html"
|
||||
|
@ -21,10 +21,12 @@ from django.urls import reverse
|
||||
import os
|
||||
|
||||
from .models import Part, PartCategory, BomItem, PartStar
|
||||
from .models import PartParameter, PartParameterTemplate
|
||||
|
||||
from .serializers import PartSerializer, BomItemSerializer
|
||||
from .serializers import CategorySerializer
|
||||
from .serializers import PartStarSerializer
|
||||
from .serializers import PartParameterSerializer, PartParameterTemplateSerializer
|
||||
|
||||
from InvenTree.views import TreeSerializer
|
||||
from InvenTree.helpers import str2bool
|
||||
@ -261,6 +263,53 @@ class PartStarList(generics.ListCreateAPIView):
|
||||
]
|
||||
|
||||
|
||||
class PartParameterTemplateList(generics.ListCreateAPIView):
|
||||
""" API endpoint for accessing a list of PartParameterTemplate objects.
|
||||
|
||||
- GET: Return list of PartParameterTemplate objects
|
||||
- POST: Create a new PartParameterTemplate object
|
||||
"""
|
||||
|
||||
queryset = PartParameterTemplate.objects.all()
|
||||
serializer_class = PartParameterTemplateSerializer
|
||||
|
||||
permission_classes = [
|
||||
permissions.IsAuthenticated,
|
||||
]
|
||||
|
||||
filter_backends = [
|
||||
filters.OrderingFilter,
|
||||
]
|
||||
|
||||
filter_fields = [
|
||||
'name',
|
||||
]
|
||||
|
||||
|
||||
class PartParameterList(generics.ListCreateAPIView):
|
||||
""" API endpoint for accessing a list of PartParameter objects
|
||||
|
||||
- GET: Return list of PartParameter objects
|
||||
- POST: Create a new PartParameter object
|
||||
"""
|
||||
|
||||
queryset = PartParameter.objects.all()
|
||||
serializer_class = PartParameterSerializer
|
||||
|
||||
permission_classes = [
|
||||
permissions.IsAuthenticated,
|
||||
]
|
||||
|
||||
filter_backends = [
|
||||
DjangoFilterBackend
|
||||
]
|
||||
|
||||
filter_fields = [
|
||||
'part',
|
||||
'template',
|
||||
]
|
||||
|
||||
|
||||
class BomList(generics.ListCreateAPIView):
|
||||
""" API endpoint for accessing a list of BomItem objects.
|
||||
|
||||
@ -362,12 +411,18 @@ part_star_api_urls = [
|
||||
url(r'^.*$', PartStarList.as_view(), name='api-part-star-list'),
|
||||
]
|
||||
|
||||
part_param_api_urls = [
|
||||
url(r'^template/$', PartParameterTemplateList.as_view(), name='api-part-param-template-list'),
|
||||
|
||||
url(r'^.*$', PartParameterList.as_view(), name='api-part-param-list'),
|
||||
]
|
||||
|
||||
part_api_urls = [
|
||||
url(r'^tree/?', PartCategoryTree.as_view(), name='api-part-tree'),
|
||||
|
||||
url(r'^category/', include(cat_api_urls)),
|
||||
url(r'^star/', include(part_star_api_urls)),
|
||||
url(r'^parameter/', include(part_param_api_urls)),
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', PartDetail.as_view(), name='api-part-detail'),
|
||||
|
||||
|
18
InvenTree/part/migrations/0018_auto_20190907_0941.py
Normal file
18
InvenTree/part/migrations/0018_auto_20190907_0941.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 2.2.4 on 2019-09-07 09:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('part', '0017_bomitem_checksum'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='partparametertemplate',
|
||||
name='name',
|
||||
field=models.CharField(help_text='Parameter Name', max_length=100, unique=True),
|
||||
),
|
||||
]
|
@ -1068,7 +1068,7 @@ class PartParameterTemplate(models.Model):
|
||||
""" Return the number of instances of this Parameter Template """
|
||||
return self.instances.count()
|
||||
|
||||
name = models.CharField(max_length=100, help_text='Parameter Name')
|
||||
name = models.CharField(max_length=100, help_text='Parameter Name', unique=True)
|
||||
|
||||
units = models.CharField(max_length=25, help_text='Parameter Units', blank=True)
|
||||
|
||||
|
@ -8,6 +8,7 @@ from .models import Part, PartStar
|
||||
|
||||
from .models import PartCategory
|
||||
from .models import BomItem
|
||||
from .models import PartParameter, PartParameterTemplate
|
||||
|
||||
from InvenTree.serializers import InvenTreeModelSerializer
|
||||
|
||||
@ -174,3 +175,28 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
||||
'note',
|
||||
'validated',
|
||||
]
|
||||
|
||||
|
||||
class PartParameterSerializer(InvenTreeModelSerializer):
|
||||
""" JSON serializers for the PartParameter model """
|
||||
|
||||
class Meta:
|
||||
model = PartParameter
|
||||
fields = [
|
||||
'pk',
|
||||
'part',
|
||||
'template',
|
||||
'data'
|
||||
]
|
||||
|
||||
|
||||
class PartParameterTemplateSerializer(InvenTreeModelSerializer):
|
||||
""" JSON serializer for the PartParameterTemplate model """
|
||||
|
||||
class Meta:
|
||||
model = PartParameterTemplate
|
||||
fields = [
|
||||
'pk',
|
||||
'name',
|
||||
'units',
|
||||
]
|
||||
|
@ -21,6 +21,8 @@ part_attachment_urls = [
|
||||
part_parameter_urls = [
|
||||
|
||||
url('^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'),
|
||||
url('^template/(?P<pk>\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'),
|
||||
url('^template/(?P<pk>\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'),
|
||||
|
||||
url('^new/', views.PartParameterCreate.as_view(), name='part-param-create'),
|
||||
url('^(?P<pk>\d+)/edit/', views.PartParameterEdit.as_view(), name='part-param-edit'),
|
||||
|
@ -1446,6 +1446,21 @@ class PartParameterTemplateCreate(AjaxCreateView):
|
||||
ajax_form_title = 'Create Part Parameter Template'
|
||||
|
||||
|
||||
class PartParameterTemplateEdit(AjaxUpdateView):
|
||||
""" View for editing a PartParameterTemplate """
|
||||
|
||||
model = PartParameterTemplate
|
||||
form_class = part_forms.EditPartParameterTemplateForm
|
||||
ajax_form_title = 'Edit Part Parameter Template'
|
||||
|
||||
|
||||
class PartParameterTemplateDelete(AjaxDeleteView):
|
||||
""" View for deleting an existing PartParameterTemplate """
|
||||
|
||||
model = PartParameterTemplate
|
||||
ajax_form_title = "Delete Part Parameter Template"
|
||||
|
||||
|
||||
class PartParameterCreate(AjaxCreateView):
|
||||
""" View for creating a new PartParameter """
|
||||
|
||||
|
108
InvenTree/templates/InvenTree/settings/currency.html
Normal file
108
InvenTree/templates/InvenTree/settings/currency.html
Normal file
@ -0,0 +1,108 @@
|
||||
{% extends "InvenTree/settings/settings.html" %}
|
||||
|
||||
{% block tabs %}
|
||||
{% include "InvenTree/settings/tabs.html" with tab='currency' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block settings %}
|
||||
|
||||
<h4>Currencies</h4>
|
||||
|
||||
<div id='currency-buttons'>
|
||||
<button class='btn btn-success' id='new-currency'>New Currency</button>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='currency-table' data-toolbar='#currency-buttons'>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$("#currency-table").bootstrapTable({
|
||||
url: "{% url 'api-currency-list' %}",
|
||||
queryParams: {
|
||||
ordering: 'suffix'
|
||||
},
|
||||
sortable: true,
|
||||
search: true,
|
||||
pagination: true,
|
||||
pageSize: 25,
|
||||
formatNoMatches: function() { return "No currencies found"; },
|
||||
rowStyle: function(row, index) {
|
||||
if (row.base) {
|
||||
return {classes: 'basecurrency'};
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'pk',
|
||||
title: 'ID',
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
field: 'symbol',
|
||||
title: 'Symbol',
|
||||
},
|
||||
{
|
||||
field: 'suffix',
|
||||
title: 'Currency',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
title: 'Description',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'value',
|
||||
title: 'Value',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
formatter: function(value, row, index, field) {
|
||||
|
||||
var bEdit = "<button title='Edit Currency' class='cur-edit btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-edit'></span></button>";
|
||||
var bDel = "<button title='Delete Currency' class='cur-delete btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-trash'></span></button>";
|
||||
|
||||
var html = "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
$("#currency-table").on('click', '.cur-edit', function() {
|
||||
var button = $(this);
|
||||
var url = "/common/currency/" + button.attr('pk') + "/edit/";
|
||||
|
||||
launchModalForm(url, {
|
||||
success: function() {
|
||||
$("#currency-table").bootstrapTable('refresh');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#currency-table").on('click', '.cur-delete', function() {
|
||||
var button = $(this);
|
||||
var url = "/common/currency/" + button.attr('pk') + "/delete/";
|
||||
|
||||
launchModalForm(url, {
|
||||
success: function() {
|
||||
$("#currency-table").bootstrapTable('refresh');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#new-currency").click(function() {
|
||||
launchModalForm("{% url 'currency-create' %}", {
|
||||
success: function() {
|
||||
$("#currency-table").bootstrapTable('refresh');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
93
InvenTree/templates/InvenTree/settings/part.html
Normal file
93
InvenTree/templates/InvenTree/settings/part.html
Normal file
@ -0,0 +1,93 @@
|
||||
{% extends "InvenTree/settings/settings.html" %}
|
||||
|
||||
{% block tabs %}
|
||||
{% include "InvenTree/settings/tabs.html" with tab='part' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block settings %}
|
||||
<h4>Part Parameter Templates</h4>
|
||||
|
||||
<div id='param-buttons'>
|
||||
<button class='btn btn-success' id='new-param'>New Parameter</button>
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed' id='param-table' data-toolbar='#param-buttons'>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$("#param-table").bootstrapTable({
|
||||
url: "{% url 'api-part-param-template-list' %}",
|
||||
queryParams: {
|
||||
ordering: 'name',
|
||||
},
|
||||
sortable: true,
|
||||
search: true,
|
||||
pagination: true,
|
||||
pageSize: 25,
|
||||
formatNoMatches: function() { return "No part parameter templates found"; },
|
||||
columns: [
|
||||
{
|
||||
field: 'pk',
|
||||
title: 'ID',
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
title: 'Name',
|
||||
sortable: 'true',
|
||||
},
|
||||
{
|
||||
field: 'units',
|
||||
title: 'Units',
|
||||
sortable: 'true',
|
||||
},
|
||||
{
|
||||
formatter: function(value, row, index, field) {
|
||||
var bEdit = "<button title='Edit Template' class='template-edit btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-edit'></span></button>";
|
||||
var bDel = "<button title='Delete Template' class='template-delete btn btn-default btn-glyph' type='button' pk='" + row.pk + "'><span class='glyphicon glyphicon-trash'></span></button>";
|
||||
|
||||
var html = "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
$("#new-param").click(function() {
|
||||
launchModalForm("{% url 'part-param-template-create' %}", {
|
||||
success: function() {
|
||||
$("#param-table").bootstrapTable('refresh');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#param-table").on('click', '.template-edit', function() {
|
||||
var button = $(this);
|
||||
|
||||
var url = "/part/parameter/template/" + button.attr('pk') + "/edit/";
|
||||
|
||||
launchModalForm(url, {
|
||||
success: function() {
|
||||
$("#param-table").bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#param-table").on('click', '.template-delete', function() {
|
||||
var button = $(this);
|
||||
|
||||
var url = "/part/parameter/template/" + button.attr('pk') + "/delete/";
|
||||
|
||||
launchModalForm(url, {
|
||||
success: function() {
|
||||
$("#param-table").bootstrapTable('refresh');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
{% endblock %}
|
32
InvenTree/templates/InvenTree/settings/settings.html
Normal file
32
InvenTree/templates/InvenTree/settings/settings.html
Normal file
@ -0,0 +1,32 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | Settings
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class='settings-container'>
|
||||
|
||||
<h3>InvenTree Settings</h3>
|
||||
<hr>
|
||||
|
||||
<div class='settings-nav'>
|
||||
{% block tabs %}
|
||||
{% include "InvenTree/settings/tabs.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<div class='settings-content'>
|
||||
{% block settings %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_load %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
11
InvenTree/templates/InvenTree/settings/tabs.html
Normal file
11
InvenTree/templates/InvenTree/settings/tabs.html
Normal file
@ -0,0 +1,11 @@
|
||||
<ul class='nav nav-pills nav-stacked'>
|
||||
<li{% ifequal tab 'user' %} class='active'{% endifequal %}>
|
||||
<a href="{% url 'settings-user' %}"><span class='glyphicon glyphicon-user'></span> User</a>
|
||||
</li>
|
||||
<li{% ifequal tab 'currency' %} class='active'{% endifequal %}>
|
||||
<a href="{% url 'settings-currency' %}"><span class='glyphicon glyphicon-usd'></span> Currency</a>
|
||||
</li>
|
||||
<li{% ifequal tab 'part' %} class='active'{% endifequal %}>
|
||||
<a href="{% url 'settings-part' %}"><span class='glyphicon glyphicon-briefcase'></span> Part</a>
|
||||
</li>
|
||||
</ul>
|
@ -1,12 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "InvenTree/settings/settings.html" %}
|
||||
|
||||
{% block page_title %}
|
||||
InvenTree | Settings
|
||||
{% block tabs %}
|
||||
{% include "InvenTree/settings/tabs.html" with tab='user' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h3>InvenTree Settings</h3>
|
||||
<hr>
|
||||
{% block settings %}
|
||||
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
@ -18,8 +16,7 @@ InvenTree | Settings
|
||||
<div class='btn btn-primary' type='button' id='edit-password' title='Change Password'>Set Password</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<table class='table table-striped table-condensed'>
|
||||
<tr>
|
||||
@ -38,10 +35,6 @@ InvenTree | Settings
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_load %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
@ -1,10 +1,12 @@
|
||||
from rest_framework import generics, permissions
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from .serializers import UserSerializer
|
||||
|
||||
from rest_framework.authtoken.views import ObtainAuthToken
|
||||
from rest_framework.authtoken.models import Token
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
class UserDetail(generics.RetrieveAPIView):
|
||||
@ -27,15 +29,30 @@ class GetAuthToken(ObtainAuthToken):
|
||||
""" Return authentication token for an authenticated user. """
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return self.login(request)
|
||||
|
||||
def delete(self, request):
|
||||
return self.logout(request)
|
||||
|
||||
def login(self, request):
|
||||
serializer = self.serializer_class(data=request.data,
|
||||
context={'request': request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
user = serializer.validated_data['user']
|
||||
token, created = Token.objects.get_or_create(user=user)
|
||||
|
||||
|
||||
return Response({
|
||||
'token': token.key,
|
||||
'pk': user.pk,
|
||||
'username': user.username,
|
||||
'email': user.email
|
||||
})
|
||||
|
||||
def logout(self, request):
|
||||
try:
|
||||
request.user.auth_token.delete()
|
||||
return Response({"success": "Successfully logged out."},
|
||||
status=status.HTTP_202_ACCEPTED)
|
||||
except (AttributeError, ObjectDoesNotExist):
|
||||
return Response({"error": "Bad request"},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
Loading…
Reference in New Issue
Block a user