diff --git a/app.py b/app.py index 18d8ff9..41cd39d 100644 --- a/app.py +++ b/app.py @@ -1955,26 +1955,27 @@ def all_products(): limit = request.args.get("limit", type=int) or 100 offset = request.args.get("offset", type=int) or 0 - normalized_name = func.lower(func.trim(func.replace(Item.name, ' ', ' '))) - item_usage = db.session.query( - normalized_name.label("name"), - func.sum(Item.quantity).label("count") - ).group_by(normalized_name).all() - - usage_map = {row.name: row.count for row in item_usage} + rows = db.session.query(Item.name, Item.list_id).distinct().all() - all_names = sorted(usage_map.keys()) + usage_map = defaultdict(set) + original_names = {} - if sort == "popularity": - sorted_names = sorted(all_names, key=lambda name: (-usage_map[name], name)) - else: - sorted_names = sorted(all_names) + for raw_name, list_id in rows: + norm = normalize_name(raw_name) + usage_map[norm].add(list_id) + if norm not in original_names or len(raw_name) < len(original_names[norm]): + original_names[norm] = raw_name.strip() - paged_names = sorted_names[offset:offset+limit] - products = [{"name": name, "count": usage_map[name]} for name in paged_names] - product_count = len(all_names) + counts = {k: len(v) for k, v in usage_map.items()} + sorted_keys = sorted( + counts.keys(), + key=lambda k: (-counts[k], k) if sort == "popularity" else k + ) - return jsonify({"products": products, "total_count": product_count}) + paged_keys = sorted_keys[offset:offset + limit] + products = [{"name": original_names[k], "count": counts[k]} for k in paged_keys] + + return jsonify({"products": products, "total_count": len(counts)}) @app.route("/upload_receipt/", methods=["POST"]) diff --git a/static/js/mass_add.js b/static/js/mass_add.js index 8f19744..89b2f01 100644 --- a/static/js/mass_add.js +++ b/static/js/mass_add.js @@ -6,11 +6,17 @@ document.addEventListener('DOMContentLoaded', function () { const modalBody = modal?.querySelector('.modal-body'); function normalize(str) { - return str ? str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase() : ''; + return str + ? str.normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/\s+/g, ' ') + .trim() + .toLowerCase() + : ''; } let sortMode = 'popularity'; - let limit = 150; + let limit = 100; let offset = 0; let loading = false; let reachedEnd = false;