mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-26 09:52:16 +00:00
Fixed search and implemented an asset search api
Added asset picker for parent attribute Co-authored-by: Panagiotis Petridis <lPanagiotisPetridisl@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<form method="post" id="asset_update_form" action="{% url 'asset_create'%}">
|
<form method="post" id="asset_update_form" action="{% url 'asset_create'%}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% include 'form_errors.html' %}
|
||||||
<div class="row" style="padding-bottom: 1em">
|
<div class="row" style="padding-bottom: 1em">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
@@ -142,35 +143,8 @@
|
|||||||
Collection Details
|
Collection Details
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="form-group">
|
{% include 'partials/asset_picker.html' %}
|
||||||
<label for="parent_id">Parent</label>
|
</div
|
||||||
<input type="hidden" name="{{ form.parent.html_name }}" id="hidden_parent_id" value="{{ object.parent.id }}">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" id="parent_id" value="{{ object.parent|default:'' }}" disabled="" class="form-control">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button type="button" class="btn btn-default" onclick="clearParent()">Clear</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="parent_search">Search for asset</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" id="parent_search" class="form-control">
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<button type="button" class="btn btn-default" onclick="formAssetSearch()">
|
|
||||||
<i class="glyphicon glyphicon-search"></i> Search
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s2">
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
<div class="col s12" id="formAssetSearchResult">
|
|
||||||
<!--Placeholder for search results-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -11,20 +11,20 @@
|
|||||||
<form id="asset-search-form">
|
<form id="asset-search-form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="query" name="query" placeholder="Search by Asset ID/Description" class="form-control" value="{{searchName}}">
|
<input type="query" name="query" placeholder="Search by Asset ID/Description" class="form-control" value="{{search_name}}">
|
||||||
<label for="asset_id" class="sr-only">Asset ID/Description:</label>
|
<label for="asset_id" class="sr-only">Asset ID/Description:</label>
|
||||||
<span class="input-group-btn"><button type="submit" class="btn btn-default">Search</button></span>
|
<span class="input-group-btn"><button type="submit" class="btn btn-default">Search</button></span>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
|
||||||
<form class="form-inline" id="asset-filter-form">
|
|
||||||
{% csrf_token %}
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cat">Category:</label>
|
<label for="cat">Category:</label>
|
||||||
<select name="cat" class="form-control">
|
<select name="cat" class="form-control">
|
||||||
<option>None</option>
|
<option value="">None</option>
|
||||||
{% for name in categories %}
|
{% for name in categories %}
|
||||||
|
{% if name == category_select %}
|
||||||
|
<option selected>
|
||||||
|
{% else %}
|
||||||
<option>
|
<option>
|
||||||
|
{% endif %}
|
||||||
{{ name }}
|
{{ name }}
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -33,15 +33,19 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="status">Status:</label>
|
<label for="status">Status:</label>
|
||||||
<select name="status" class="form-control">
|
<select name="status" class="form-control">
|
||||||
<option>None</option>
|
<option value="">None</option>
|
||||||
{% for name in statuses %}
|
{% for name in statuses %}
|
||||||
|
{% if name == status_select %}
|
||||||
|
<option selected>
|
||||||
|
{% else %}
|
||||||
<option>
|
<option>
|
||||||
|
{% endif %}
|
||||||
{{ name }}
|
{{ name }}
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<!---TODO: Auto filter whenever an option is selected, instead of using a button --->
|
<!---TODO: Auto filter whenever an option is selected, instead of using a button -->
|
||||||
<button type="submit" class="btn btn-default">Filter</button>
|
<button type="submit" class="btn btn-default">Filter</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<form method="post" id="asset_update_form" action="{% url 'asset_update' pk=object.pk%}">
|
<form method="post" id="asset_update_form" action="{% url 'asset_update' pk=object.pk%}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% include 'form_errors.html' %}
|
||||||
<div class="row" style="padding-bottom: 1em">
|
<div class="row" style="padding-bottom: 1em">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
@@ -190,35 +191,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% if edit or duplicate %}
|
{% if edit or duplicate %}
|
||||||
<div class="form-group">
|
{% include 'partials/asset_picker.html' %}
|
||||||
<label for="parent_id">Parent</label>
|
{% else%}
|
||||||
<input type="hidden" name="{{ form.parent.html_name }}" id="hidden_parent_id"
|
|
||||||
value="{{ object.parent.id }}">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" id="parent_id" value="{{ object.parent|default:'' }}"
|
|
||||||
disabled="" class="form-control">
|
|
||||||
<span class="input-group-btn"><button type="button" class="btn btn-default" onclick="clearParent()">Clear
|
|
||||||
</button></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="parent_search">Search for asset</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" id="parent_search" class="form-control">
|
|
||||||
<span class="input-group-btn"><button type="button" class="btn btn-default" onclick="formAssetSearch()">
|
|
||||||
<i class="glyphicon glyphicon-search"></i> Search
|
|
||||||
</button></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col s2">
|
|
||||||
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
<div class="col s12" id="formAssetSearchResult">
|
|
||||||
<!--Placeholder for search results-->
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Parent</dt>
|
<dt>Parent</dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{% for item in object_list %}
|
{% for item in object_list %}
|
||||||
{# <li><a href="{% url 'asset_detail' item.pk %}">{{ item.asset_id }} - {{ item.description }}</a></li>#}
|
{# <li><a href="{% url 'asset_detail' item.pk %}">{{ item.asset_id }} - {{ item.description }}</a></li>#}
|
||||||
<!---TODO: When the ability to filter the list is added, remove the colours from the filter - specifically, stop greying out sold/binned stuff if it is being searched for--->
|
<!---TODO: When the ability to filter the list is added, remove the colours from the filter - specifically, stop greying out sold/binned stuff if it is being searched for--> <tr class="
|
||||||
<tr class="
|
|
||||||
{% if item.status.name == 'Broken' %}
|
{% if item.status.name == 'Broken' %}
|
||||||
danger
|
danger
|
||||||
{% elif item.status.name == 'Lost'%}
|
{% elif item.status.name == 'Lost'%}
|
||||||
|
|||||||
63
assets/templates/partials/asset_picker.html
Normal file
63
assets/templates/partials/asset_picker.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<select name="parent" id="parent_id" class="selectpicker">
|
||||||
|
{% if object.parent%}
|
||||||
|
<option value="{{object.parent.pk}}" selected>{{object.parent.description}}</option>
|
||||||
|
{% endif %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
{% block css %}
|
||||||
|
<link rel="stylesheet" href="{% static "css/bootstrap-select.min.css" %}"/>
|
||||||
|
<link rel="stylesheet" href="{% static "css/ajax-bootstrap-select.css" %}"/>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block preload_js %}
|
||||||
|
<script src="{% static "js/bootstrap-select.js" %}"></script>
|
||||||
|
<script src="{% static "js/ajax-bootstrap-select.js" %}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script>
|
||||||
|
$('#parent_id')
|
||||||
|
.selectpicker({
|
||||||
|
liveSearch: true
|
||||||
|
})
|
||||||
|
.ajaxSelectPicker({
|
||||||
|
ajax: {
|
||||||
|
url: '{% url 'asset_search_json'%}',
|
||||||
|
type: "get",
|
||||||
|
data: function () {
|
||||||
|
var params = {
|
||||||
|
{% verbatim %}query: '{{{q}}}'{% endverbatim %}
|
||||||
|
};
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
locale: {
|
||||||
|
emptyTitle: 'Search for item...'
|
||||||
|
},
|
||||||
|
preprocessData: function(data){
|
||||||
|
var assets = [];
|
||||||
|
if(data.length){
|
||||||
|
var len = data.length;
|
||||||
|
for(var i = 0; i < len; i++){
|
||||||
|
var curr = data[i];
|
||||||
|
assets.push(
|
||||||
|
{
|
||||||
|
'value': curr.id,
|
||||||
|
'text': curr.label,
|
||||||
|
'disabled': false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assets.push(
|
||||||
|
{
|
||||||
|
'value': null,
|
||||||
|
'text': "No parent"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return assets;
|
||||||
|
},
|
||||||
|
preserveSelected: false
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock js %}
|
||||||
@@ -15,6 +15,8 @@ urlpatterns = [
|
|||||||
path('asset/<int:pk>/duplicate/', views.AssetDuplicate.as_view(), name='asset_duplicate'),
|
path('asset/<int:pk>/duplicate/', views.AssetDuplicate.as_view(), name='asset_duplicate'),
|
||||||
path('asset/delete/', views.asset_delete, name='ajax_asset_delete'),
|
path('asset/delete/', views.asset_delete, name='ajax_asset_delete'),
|
||||||
|
|
||||||
|
path('asset/search/', views.AssetSearch.as_view(), name='asset_search_json'),
|
||||||
|
|
||||||
path('supplier/list', views.SupplierList.as_view(), name='supplier_list'),
|
path('supplier/list', views.SupplierList.as_view(), name='supplier_list'),
|
||||||
path('supplier/<int:pk>', views.SupplierDetail.as_view(), name='supplier_detail'),
|
path('supplier/<int:pk>', views.SupplierDetail.as_view(), name='supplier_detail'),
|
||||||
path('supplier/create', views.SupplierCreate.as_view(), name='supplier_create'),
|
path('supplier/create', views.SupplierCreate.as_view(), name='supplier_create'),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.http import HttpResponse, QueryDict
|
from django.http import HttpResponse, QueryDict, JsonResponse
|
||||||
from django.core import serializers
|
from django.core import serializers
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
@@ -22,27 +22,39 @@ class AssetList(LoginRequiredMixin, generic.ListView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
#TODO Feedback to user when search fails
|
#TODO Feedback to user when search fails
|
||||||
query = self.request.GET.get('query', "")
|
query = self.request.GET.get('query', "")
|
||||||
|
queryset = self.model.objects.all()
|
||||||
if len(query) >= 3:
|
if len(query) >= 3:
|
||||||
return self.model.objects.filter(Q(asset_id__exact=query) | Q(description__icontains=query))
|
queryset = self.model.objects.filter(Q(asset_id__exact=query) | Q(description__icontains=query))
|
||||||
elif query != "":
|
|
||||||
return self.model.objects.filter(Q(asset_id__exact=query))
|
cat = self.request.GET.get('cat', "")
|
||||||
else:
|
status = self.request.GET.get('status', "")
|
||||||
cat = self.request.GET.get('cat', "")
|
if cat != "":
|
||||||
status = self.request.GET.get('status', "")
|
queryset = queryset.filter(category__name__exact=cat)
|
||||||
if cat != "None":
|
elif status != "":
|
||||||
return self.model.objects.filter(category__name__exact=cat)
|
queryset = queryset.filter(status__name__exact=status)
|
||||||
elif status != "None":
|
|
||||||
return self.model.objects.filter(status__name__exact=status)
|
return queryset
|
||||||
else:
|
|
||||||
return self.model.objects.all()
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(AssetList, self).get_context_data(**kwargs)
|
context = super(AssetList, self).get_context_data(**kwargs)
|
||||||
context["search_name"] = self.request.GET.get('query', "")
|
context["search_name"] = self.request.GET.get('query', "")
|
||||||
|
|
||||||
context["categories"] = models.AssetCategory.objects.all()
|
context["categories"] = models.AssetCategory.objects.all()
|
||||||
|
context["category_select"] = self.request.GET.get('cat', "")
|
||||||
|
|
||||||
context["statuses"] = models.AssetStatus.objects.all()
|
context["statuses"] = models.AssetStatus.objects.all()
|
||||||
|
context["status_select"] = self.request.GET.get('stats', "")
|
||||||
return context;
|
return context;
|
||||||
|
|
||||||
|
class AssetSearch(AssetList):
|
||||||
|
def render_to_response(self, context, **response_kwargs):
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for asset in context["object_list"]:
|
||||||
|
result.append({"id":asset.pk, "label":(asset.asset_id + " | " + asset.description)})
|
||||||
|
|
||||||
|
return JsonResponse(result, safe=False)
|
||||||
|
|
||||||
class AssetDetail(LoginRequiredMixin, generic.DetailView):
|
class AssetDetail(LoginRequiredMixin, generic.DetailView):
|
||||||
model = models.Asset
|
model = models.Asset
|
||||||
template_name = 'asset_update.html'
|
template_name = 'asset_update.html'
|
||||||
|
|||||||
Reference in New Issue
Block a user