diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 220ccc9..3df7c86 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,6 +1,119 @@ { "version": "2.0.0", "tasks": [ + { + "label": "Rebuild Stockroom Docker app", + "type": "shell", + "command": "docker", + "args": [ + "compose", + "up", + "--build", + "-d" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "Rebuild Stockroom Docker app", + "type": "shell", + "command": "docker", + "args": [ + "compose", + "up", + "--build", + "-d" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "Inspect container inventory database", + "type": "shell", + "command": "docker", + "args": [ + "compose", + "exec", + "-T", + "inventory", + "python", + "-c", + "import sqlite3; c=sqlite3.connect('/data/inventory.db'); print(c.execute('select count(*) from inventory_items').fetchone()[0]); print(c.execute('select count(*) from inventory_images').fetchone()[0])" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "Inspect Docker inventory mount", + "type": "shell", + "command": "docker", + "args": [ + "inspect", + "storageinventory-inventory-1", + "--format={{json .Mounts}}" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "Check container database count", + "type": "shell", + "command": "docker", + "args": [ + "compose", + "exec", + "-T", + "inventory", + "python", + "-c", + "import sqlite3; print(sqlite3.connect(\"/data/inventory.db\").execute(\"select count(*) from inventory_items\").fetchone()[0])" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "List container data files", + "type": "shell", + "command": "docker", + "args": [ + "compose", + "exec", + "-T", + "inventory", + "ls", + "-l", + "/data" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "Check container database path", + "type": "shell", + "command": "docker", + "args": [ + "compose", + "exec", + "-T", + "inventory", + "printenv", + "DATABASE_PATH" + ], + "isBackground": false, + "problemMatcher": [] + }, + { + "label": "Check running inventory containers", + "type": "shell", + "command": "docker", + "args": [ + "ps", + "--format", + "{{.Names}} {{.Ports}}" + ], + "isBackground": false, + "problemMatcher": [] + }, { "label": "Rebuild Stockroom Docker app", "type": "shell", diff --git a/app.py b/app.py index c487d2f..0c3360e 100644 --- a/app.py +++ b/app.py @@ -221,7 +221,7 @@ def clean(value): def item_payload(data): - return { + payload = { "name": clean(data.get("name")), "item_type": clean(data.get("item_type")), "brand": clean(data.get("brand")), @@ -240,6 +240,15 @@ def item_payload(data): "storage": clean(data.get("storage")), "media_format": clean(data.get("media_format")), } + if payload["item_type"] != "Computer": + payload["cpu"] = "" + payload["ram"] = "" + if payload["item_type"] not in {"Computer", "Graphics"}: + payload["gpu"] = "" + payload["storage"] = "" + if payload["item_type"] not in {"CD", "Long play disk", "Audio"}: + payload["media_format"] = "" + return payload def serialize(row, connection): diff --git a/static/app.js b/static/app.js index 149c04d..ebd30fa 100644 --- a/static/app.js +++ b/static/app.js @@ -33,8 +33,27 @@ function renderItems(items) { function escapeHtml(value) { return String(value).replace(/[&<>'"]/g, (char) => ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }[char])); } function ensureImageControls() { if (!$('#destination')) $('[name="location"]').insertAdjacentHTML('afterend', ''); if (!$('#checkoutDate')) $('#destination').parentElement.insertAdjacentHTML('afterend', ''); if ($('#imageInput')) return; const section = document.querySelector('.form-section'); section.insertAdjacentHTML('beforebegin', ''); } +function updateTypeFields() { + const type = $('[name="item_type"]').value; + const technicalFields = new Set(['cpu', 'ram', 'gpu', 'storage']); + const computerFields = new Set(['cpu', 'ram', 'gpu', 'storage']); + const graphicsFields = new Set(['gpu']); + const mediaFields = new Set(['media_format']); + document.querySelectorAll('#itemForm [name]').forEach((field) => { + if (!technicalFields.has(field.name) && field.name !== 'media_format') return; + const visible = type === 'Computer' ? computerFields.has(field.name) : type === 'Graphics' ? graphicsFields.has(field.name) : mediaFields.has(field.name) && ['CD', 'Long play disk', 'Audio'].includes(type); + field.parentElement.hidden = !visible; + if (!visible) field.value = ''; + }); + const section = document.querySelector('#itemForm .form-section'); + if (section) { + section.hidden = !['Computer', 'Graphics', 'CD', 'Long play disk', 'Audio'].includes(type); + const heading = section.querySelector('span'); + if (heading) heading.firstChild.textContent = ['CD', 'Long play disk', 'Audio'].includes(type) ? 'Format details ' : 'Technical details '; + } +} function renderImageGallery(images = []) { $('#imageGallery').innerHTML = images.map((image) => `