diff --git a/InvenTree/InvenTree/static/css/inventree.css b/InvenTree/InvenTree/static/css/inventree.css
index 3f6fffe19b..78f3f4addc 100644
--- a/InvenTree/InvenTree/static/css/inventree.css
+++ b/InvenTree/InvenTree/static/css/inventree.css
@@ -1018,4 +1018,30 @@ input[type='number']{
a {
text-decoration: none;
background-color: transparent;
+}
+
+/* Quicksearch Panel */
+
+.search-result-panel {
+ max-width: 800px;
+ width: 50%
+}
+
+.search-result-group {
+ padding: 5px;
+ border: 1px solid var(--border-color);
+ margin-bottom: 10px;
+}
+
+.search-result-group-buttons > button{
+ padding: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+ font-size: 80%;
+}
+
+.search-result-entry {
+ border-top: 1px solid var(--border-color);
+ padding: 3px;
+ margin-top: 3px;
}
\ No newline at end of file
diff --git a/InvenTree/templates/js/translated/model_renderers.js b/InvenTree/templates/js/translated/model_renderers.js
index e3abe1186f..5f81cb9abf 100644
--- a/InvenTree/templates/js/translated/model_renderers.js
+++ b/InvenTree/templates/js/translated/model_renderers.js
@@ -31,7 +31,7 @@
// Renderer for "Company" model
// eslint-disable-next-line no-unused-vars
-function renderCompany(name, data, parameters, options) {
+function renderCompany(name, data, parameters={}, options={}) {
var html = select2Thumbnail(data.image);
@@ -45,7 +45,7 @@ function renderCompany(name, data, parameters, options) {
// Renderer for "StockItem" model
// eslint-disable-next-line no-unused-vars
-function renderStockItem(name, data, parameters, options) {
+function renderStockItem(name, data, parameters={}, options={}) {
var image = blankImage();
@@ -111,7 +111,7 @@ function renderStockItem(name, data, parameters, options) {
// Renderer for "StockLocation" model
// eslint-disable-next-line no-unused-vars
-function renderStockLocation(name, data, parameters, options) {
+function renderStockLocation(name, data, parameters={}, options={}) {
var level = '- '.repeat(data.level);
@@ -133,7 +133,7 @@ function renderStockLocation(name, data, parameters, options) {
}
// eslint-disable-next-line no-unused-vars
-function renderBuild(name, data, parameters, options) {
+function renderBuild(name, data, parameters={}, options={}) {
var image = null;
@@ -154,7 +154,7 @@ function renderBuild(name, data, parameters, options) {
// Renderer for "Part" model
// eslint-disable-next-line no-unused-vars
-function renderPart(name, data, parameters, options) {
+function renderPart(name, data, parameters={}, options={}) {
var html = select2Thumbnail(data.image);
@@ -164,13 +164,14 @@ function renderPart(name, data, parameters, options) {
html += ` - ${data.description}`;
}
- var extra = '';
+ var stock_data = '';
- // Display available part quantity
if (user_settings.PART_SHOW_QUANTITY_IN_FORMS) {
- extra += partStockLabel(data);
+ stock_data = partStockLabel(data);
}
+ var extra = '';
+
if (!data.active) {
extra += `{% trans "Inactive" %}`;
}
@@ -178,6 +179,7 @@ function renderPart(name, data, parameters, options) {
html += `
+ ${stock_data}
${extra}
{% trans "Part ID" %}: ${data.pk}
@@ -188,7 +190,7 @@ function renderPart(name, data, parameters, options) {
// Renderer for "User" model
// eslint-disable-next-line no-unused-vars
-function renderUser(name, data, parameters, options) {
+function renderUser(name, data, parameters={}, options={}) {
var html = `${data.username}`;
@@ -202,7 +204,7 @@ function renderUser(name, data, parameters, options) {
// Renderer for "Owner" model
// eslint-disable-next-line no-unused-vars
-function renderOwner(name, data, parameters, options) {
+function renderOwner(name, data, parameters={}, options={}) {
var html = `${data.name}`;
@@ -223,7 +225,7 @@ function renderOwner(name, data, parameters, options) {
// Renderer for "PurchaseOrder" model
// eslint-disable-next-line no-unused-vars
-function renderPurchaseOrder(name, data, parameters, options) {
+function renderPurchaseOrder(name, data, parameters={}, options={}) {
var html = '';
var prefix = global_settings.PURCHASEORDER_REFERENCE_PREFIX;
@@ -257,7 +259,7 @@ function renderPurchaseOrder(name, data, parameters, options) {
// Renderer for "SalesOrder" model
// eslint-disable-next-line no-unused-vars
-function renderSalesOrder(name, data, parameters, options) {
+function renderSalesOrder(name, data, parameters={}, options={}) {
var html = `${data.reference}`;
if (data.description) {
@@ -277,7 +279,7 @@ function renderSalesOrder(name, data, parameters, options) {
// Renderer for "SalesOrderShipment" model
// eslint-disable-next-line no-unused-vars
-function renderSalesOrderShipment(name, data, parameters, options) {
+function renderSalesOrderShipment(name, data, parameters={}, options={}) {
var so_prefix = global_settings.SALESORDER_REFERENCE_PREFIX;
@@ -294,7 +296,7 @@ function renderSalesOrderShipment(name, data, parameters, options) {
// Renderer for "PartCategory" model
// eslint-disable-next-line no-unused-vars
-function renderPartCategory(name, data, parameters, options) {
+function renderPartCategory(name, data, parameters={}, options={}) {
var level = '- '.repeat(data.level);
@@ -310,7 +312,7 @@ function renderPartCategory(name, data, parameters, options) {
}
// eslint-disable-next-line no-unused-vars
-function renderPartParameterTemplate(name, data, parameters, options) {
+function renderPartParameterTemplate(name, data, parameters={}, options={}) {
var units = '';
@@ -326,7 +328,7 @@ function renderPartParameterTemplate(name, data, parameters, options) {
// Renderer for "ManufacturerPart" model
// eslint-disable-next-line no-unused-vars
-function renderManufacturerPart(name, data, parameters, options) {
+function renderManufacturerPart(name, data, parameters={}, options={}) {
var manufacturer_image = null;
var part_image = null;
@@ -355,7 +357,7 @@ function renderManufacturerPart(name, data, parameters, options) {
// Renderer for "SupplierPart" model
// eslint-disable-next-line no-unused-vars
-function renderSupplierPart(name, data, parameters, options) {
+function renderSupplierPart(name, data, parameters={}, options={}) {
var supplier_image = null;
var part_image = null;
diff --git a/InvenTree/templates/js/translated/search.js b/InvenTree/templates/js/translated/search.js
index 26ba8ed5dd..a3e4ea59de 100644
--- a/InvenTree/templates/js/translated/search.js
+++ b/InvenTree/templates/js/translated/search.js
@@ -32,6 +32,11 @@ function openSearchPanel() {
panel.find('#search-input').on('keyup change', searchTextChanged);
+ // Callback for "clear search" button
+ panel.find('#search-clear').click(function() {
+ panel.find('#search-input').val('');
+ clearSearchResults();
+ });
}
var searchRequests = [];
@@ -80,7 +85,15 @@ function updateSearch() {
},
{
success: function(response) {
- addSearchResults('part', response.results, '{% trans "Parts" %}');
+ addSearchResults(
+ 'part',
+ response.results,
+ '{% trans "Parts" %}',
+ renderPart,
+ {
+ show_stock_data: false,
+ }
+ );
}
}
));
@@ -92,10 +105,19 @@ function updateSearch() {
search: searchText,
limit: 10,
offset: 0,
+ part_detail: true,
+ location_detail: true,
},
{
success: function(response) {
- addSearchResults('stock', response.results, '{% trans "Stock Items" %}');
+ addSearchResults(
+ 'stock',
+ response.results,
+ '{% trans "Stock Items" %}',
+ renderStockItem,
+ {
+ }
+ );
}
}
));
@@ -115,7 +137,7 @@ function clearSearchResults() {
// Add a group of results to the list
-function addSearchResults(key, results, title, formatter) {
+function addSearchResults(key, results, title, renderFunc, renderParams={}) {
if (results.length == 0) {
// Do not display this group, as there are no results
@@ -126,21 +148,48 @@ function addSearchResults(key, results, title, formatter) {
// Ensure the 'no results found' element is hidden
panel.find('#search-no-results').hide();
-
- var results_element = panel.find('#search-results');
-
- var header = `search-results-${key}`;
panel.find('#search-results').append(`
-