diff --git a/src/routes/api/v1/index.ts b/src/routes/api/v1/index.ts
index 8fe8a9a..f0640f9 100644
--- a/src/routes/api/v1/index.ts
+++ b/src/routes/api/v1/index.ts
@@ -7,6 +7,9 @@ import categoryRoute from './categories.js';
import storageUnitRoute from './storageUnits.js';
import storageLocationRoute from './storageLocations.js';
+import search_routes from './search/index.js';
+
+
// Router base is '/api/v1'
const Router = express.Router({ strict: false });
@@ -16,6 +19,8 @@ Router.route('/categories').get(categoryRoute.get).post(categoryRoute.post).patc
Router.route('/storageUnits').get(storageUnitRoute.get).post(storageUnitRoute.post).patch(storageUnitRoute.patch).delete(storageUnitRoute.del);
Router.route('/storageLocations').get(storageLocationRoute.get).post(storageLocationRoute.post).patch(storageLocationRoute.patch).delete(storageLocationRoute.del);
+Router.use('/search', search_routes);
+
Router.route('/test').get(testRoute.get);
export default Router;
diff --git a/src/routes/api/v1/search/index.ts b/src/routes/api/v1/search/index.ts
new file mode 100644
index 0000000..72685ad
--- /dev/null
+++ b/src/routes/api/v1/search/index.ts
@@ -0,0 +1,9 @@
+import express from 'express';
+import sku from './sku.js';
+
+// Router base is '/api/v1'
+const Router = express.Router({ strict: false });
+
+Router.route('/sku').get(sku.get);
+
+export default Router;
diff --git a/static/js/searchBox.js b/static/js/searchBox.js
index f1705c9..a396961 100644
--- a/static/js/searchBox.js
+++ b/static/js/searchBox.js
@@ -1,29 +1,113 @@
-document.getElementById("SearchBox").addEventListener("keyup", handleSearchChange);
-const autocompleteBox = document.getElementById("autocomplete-items");
-autocompleteBox.style.display = "none";
+document.getElementById('SearchBoxInput').addEventListener('keyup', handleSearchChange);
+document.getElementById('searchForm').addEventListener('submit', handleSearchSubmit);
+document.addEventListener('keyup', handleHotKey)
+const autocompleteBox = document.getElementById('autocompletBody');
+autocompleteBox.style.display = 'none';
+
+currentBestGuessCommand = '';
+
function handleSearchChange(e) {
console.log(e.target.value);
// document.getElementById("SearchBox").setAttribute("data-bs-content", "Search results will show up here soon")
-
- return; // No you won't. I'm not done yet.
+ // return; // No you won't. I'm not done yet.
// Check if known prefix is used (either > or #)
- if(e.target.value != "" ) {
- autocompleteBox.style.display = "block";
- autocompleteBox.innerHTML = "Search results will show up here soon
Trust me
Results";
+ if (e.target.value != '') {
+ autocompleteBox.style.display = 'block';
+ autocompleteBox.innerHTML = 'Search results will show up here soon
Trust me
Results';
} else {
- autocompleteBox.style.display = "none";
+ autocompleteBox.style.display = 'none';
}
- if (e.target.value[0] == ">") {
- autocompleteBox.innerHTML = "Start typing to search for commands
>goto items";
- if(e.target.value == ">goto items") {
- autocompleteBox.innerHTML = "
Goto Items";
+ if (e.target.value[0] == '>') {
+ // List of valid routes
+ urlList = {
+ items: { url: '/items?page=1', alias: ['item'] },
+ 'storage locations': { url: '/manage/storages', alias: ['locations', 'storage'] },
+ 'storage units': { url: '/manage/storages#storage-unit-tab', alias: ['units'] },
+ categories: { url: '/manage/categories', alias: ['category'] }
+ };
+ autocompleteBox.innerHTML = 'Start typing to search for commands
>goto items';
+ const args = e.target.value.split(' ');
+ console.log(args);
+ if (args.length > 1) {
+ if (args[0] == '>goto' || args[0] == '>g') {
+ console.log('Handling >goto');
+ autocompleteBox.innerHTML = 'Start typing to search for commands
' + Object.keys(urlList).join('
') + '
';
+ if (args.length >= 2) {
+ console.log("Autocomplete for 'goto' command with " + args[1] + " as the second argument")
+ // Check if the second argument matches the urlList or any of its aliases
+ for (const [key, value] of Object.entries(urlList)) {
+ console.log(key, value)
+ if (args[1] == key || value.alias.includes(args[1])) {
+ // Match found
+ console.log('Match found');
+ autocompleteBox.innerHTML = `Go to
${key}`;
+ currentBestGuessCommand = "open;" + value.url;
+ break;
+ } else {
+ currentBestGuessCommand = '';
+ }
+ }
+
+ }
+ }
}
- } else if (e.target.value[0] == "#") {
+ } else if (e.target.value[0] == '#') {
// Search for SKU
- autocompleteBox.innerHTML = "Start typing to search for items by SKU";
+ const searchedSKU = e.target.value.substring(1);
+ if(searchedSKU == '') {
+ autocompleteBox.innerHTML = 'Start typing to search for commands
#SKU';
+ return;
+ }
+ const baseURI = window.location.origin;
+ const url = baseURI + '/api/v1/search/sku?sku=' + searchedSKU;
+
+
+ $.ajax({
+ type: 'get',
+ url: url,
+ success: function (data) {
+ let result = JSON.parse(data);
+ let htmlResult = ""
+ result.forEach(element => {
+ console.log(element);
+ htmlResult += `
${element.name}`
+ });
+
+ autocompleteBox.innerHTML = htmlResult;
+ },
+ error: function (data) {
+ createNewToast('
Something went wrong while searching...', "text-bg-danger", autoHideTime = 3000, autoReload = false)
+ }
+ });
} else {
// Search for name
}
-}
\ No newline at end of file
+}
+
+function handleSearchSubmit(e) {
+ console.log('Search submitted');
+ if(currentBestGuessCommand != '') {
+ console.log('Submitting command ' + currentBestGuessCommand);
+ cmdArgs = currentBestGuessCommand.split(';');
+ if(cmdArgs[0] == 'open') {
+ // Open the url in the current tab
+ setTimeout(() => {
+
+ window.location.replace(cmdArgs[1]);
+ }, 200);
+ return false;
+ }
+ }
+ return false;
+}
+
+function handleHotKey(e) {
+ // If c is pressed, focus on the search box
+ if(e.key == 'c') {
+ // Show search_modal modal
+ bootstrap.Modal.getOrCreateInstance($('#search_modal')).show()
+ document.getElementById('SearchBoxInput').focus();
+ }
+}