diff --git a/routes.py b/routes.py index b39e427..b8e6934 100644 --- a/routes.py +++ b/routes.py @@ -1,5 +1,5 @@ from flask import Blueprint, render_template, url_for, request, redirect -from .models import Brand, Item, Inventory, RoomFunction, User, WorkLog, Room +from .models import Brand, Item, Inventory, RoomFunction, User, WorkLog, Room, Area from sqlalchemy import or_ from sqlalchemy.orm import aliased from typing import Callable, Any, List @@ -433,4 +433,7 @@ def search(): @main.route('/settings') def settings(): brands = db.session.query(Brand).order_by(Brand.name).all() - return render_template('settings.html', title="Settings", brands=brands) + types = db.session.query(Item.id, Item.description.label("name")).order_by(Item.description).all() + sections = db.session.query(Area).order_by(Area.name).all() + functions = db.session.query(RoomFunction.id, RoomFunction.description.label("name")).order_by(RoomFunction.description).all() + return render_template('settings.html', title="Settings", brands=brands, types=types, sections=sections, functions=functions) diff --git a/static/js/widget.js b/static/js/widget.js new file mode 100644 index 0000000..fd571a4 --- /dev/null +++ b/static/js/widget.js @@ -0,0 +1,81 @@ +const ComboBoxWidget = (() => { + let tempIdCounter = -1; + + function initComboBox(ns) { + const input = document.querySelector(`#${ns}-input`); + const list = document.querySelector(`#${ns}-list`); + const addBtn = document.querySelector(`#${ns}-add`); + const removeBtn = document.querySelector(`#${ns}-remove`); + let currentlyEditing = null; + + if (!input || !list || !addBtn || !removeBtn) { + console.warn(`ComboBoxWidget: Missing elements for namespace '${ns}'`); + return; + } + + function updateAddButtonIcon() { + addBtn.innerHTML = currentlyEditing ? icons.edit : icons.add; + } + + input.addEventListener('input', () => { + addBtn.disabled = input.value.trim() === ''; + }); + + list.addEventListener('change', () => { + const selected = list.selectedOptions; + removeBtn.disabled = selected.length === 0; + + if (selected.length === 1) { + // Load the text into input for editing + input.value = selected[0].textContent; + addBtn.disabled = input.value.trim() === ''; + currentlyEditing = selected[0]; + } else { + input.value = ''; + currentlyEditing = null; + addBtn.disabled = true; + } + + updateAddButtonIcon(); + }); + + addBtn.addEventListener('click', () => { + const newItem = input.value.trim(); + if (!newItem) return; + + if (currentlyEditing) { + currentlyEditing.textContent = newItem; + currentlyEditing = null; + } else { + const option = document.createElement('option'); + option.textContent = newItem; + option.value = tempIdCounter--; + list.appendChild(option); + } + + input.value = ''; + addBtn.disabled = true; + removeBtn.disabled = true; + sortOptions(list); + }); + + removeBtn.addEventListener('click', () => { + Array.from(list.selectedOptions).forEach(opt => opt.remove()); + currentlyEditing = null; + removeBtn.disabled = true; + input.value = ''; + addBtn.disabled = true; + }); + } + + function sortOptions(selectElement) { + const sorted = Array.from(selectElement.options) + .sort((a, b) => a.text.localeCompare(b.text)); + selectElement.innerHTML = ''; + sorted.forEach(option => selectElement.appendChild(option)); + } + + return { + initComboBox + }; +})(); diff --git a/templates/fragments/_combobox_fragment.html b/templates/fragments/_combobox_fragment.html new file mode 100644 index 0000000..e5919ae --- /dev/null +++ b/templates/fragments/_combobox_fragment.html @@ -0,0 +1,29 @@ +{% import "fragments/_icon_fragment.html" as icons %} + +{% macro render_combobox(id, options, label=none, placeholder=none) %} + {% if label %} + + {% endif %} +
+ + +{% endmacro %} \ No newline at end of file diff --git a/templates/fragments/_icon_fragment.html b/templates/fragments/_icon_fragment.html index 1258994..ba8bc24 100644 --- a/templates/fragments/_icon_fragment.html +++ b/templates/fragments/_icon_fragment.html @@ -77,6 +77,14 @@ {% endmacro %} +{% macro pencil(size=24) %} + +{% endmacro %} + {% macro plus(size=24) %}