Implemented suggestions on recipe new sku modal

This commit is contained in:
Jadowyne Ulve 2025-08-12 17:08:54 -05:00
parent 78d79f9a57
commit 113c2f0632
7 changed files with 105 additions and 4 deletions

View File

@ -125,6 +125,33 @@ def getPicturePath(site:str, payload:tuple):
cur.execute(f"SELECT picture_path FROM {site}_recipes WHERE id=%s;", payload)
rows = cur.fetchone()[0]
return rows
def getFuzzyMatch(site: str, payload, convert=True, conn=None):
matches = []
self_conn = False
sql = f"SELECT id, item_name FROM {site}_items WHERE LOWER(item_name) ILIKE '%%' || LOWER(TRIM(%s)) || '%%';"
try:
if not conn:
database_config = config.config()
conn = psycopg2.connect(**database_config)
conn.autocommit = True
self_conn = True
print(payload)
with conn.cursor() as cur:
cur.execute(sql, (payload,))
rows = cur.fetchall()
print(rows)
if rows and convert:
matches = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows]
elif rows and not convert:
matches = rows
if self_conn:
conn.close()
return matches
except Exception as error:
return error
def selectSiteTuple(payload, convert=True):
""" payload (tuple): (site_name,) """

View File

@ -228,7 +228,6 @@ def saveRecipeItem():
return jsonify({'recipe': recipe, 'error': False, 'message': f'Recipe Item {updated_line['item_name']} was updated successful!'})
return jsonify({'recipe': recipe, 'error': True, 'message': f'method {request.method} not allowed!'})
@recipes_api.route('/api/receiptRecipe', methods=["POST"])
@access_api.login_required
def receiptRecipe():
@ -239,4 +238,14 @@ def receiptRecipe():
if not status:
return jsonify(status=400, message=message)
return jsonify(status=201, message="Recipe Transacted Successfully!")
return jsonify(status=405, message=f"{request.method} is not an allowed method on this endpoint!")
return jsonify(status=405, message=f"{request.method} is not an allowed method on this endpoint!")
@recipes_api.route('/api/fuzzy-match')
@access_api.login_required
def fuzzyMatchItems():
query = request.args.get('q', '').strip().lower()
site_name = session['selected_site']
print(query)
matches = database_recipes.getFuzzyMatch(site_name, query, convert=False)
return jsonify(status=201, message="matches fetched Successfully!", matches=matches)

View File

@ -379,6 +379,62 @@ async function openNewSKUModal() {
UIkit.modal(itemsModal).show();
}
// Suggestions for new sku Model
var fullsuggestions = '';
var shortsuggestions = '';
async function showMoreSuggestions(){
document.getElementById('similar-items-list').innerHTML = fullsuggestions;
}
async function showLessSuggestions(){
document.getElementById('similar-items-list').innerHTML = shortsuggestions;
}
document.getElementById('newSKUName').addEventListener('input', async function(e) {
let query = e.target.value.trim();
if(query.length === 0) {
document.getElementById('suggestions').innerHTML = '';
return;
}
let resp = await fetch(`/recipes/api/fuzzy-match?q=${encodeURIComponent(query)}`);
let data = await resp.json();
let matches = data.matches
let total_matches = 3
let html = `<span uk-icon="icon: warning"></span> Similar item(s) found: `
let fullhtml = '<span uk-icon="icon: warning"></span> Similar item(s) found: '
if(matches.length){
document.getElementById('item-warning').hidden = false
if (matches.length < total_matches){
total_matches = matches.length
}
for (let i = 0; i < total_matches; i++){
html = html + `<a class="uk-link-muted" href="/items/${matches[i][0]}" target="_blank"><strong>${matches[i][1]}</strong></a>, `
fullhtml = fullhtml + `<a class="uk-link-muted" href="/items/${matches[i][0]}" target="_blank"><strong>${matches[i][1]}</strong></a>, `
shortsuggestions = html
fullsuggestions = fullhtml
}
for (let i = total_matches + 1; i < matches.length; i++){
fullhtml = fullhtml + `<a class="uk-link-muted" href="/items/${matches[i][0]}" target="_blank"><strong>${matches[i][1]}</strong></a>, `
fullsuggestions = fullhtml + `<a class="uk-link-muted" onclick="showLessSuggestions()"><strong>Show less</strong></a>`
}
if(matches.length > 3 ){
html = html + `<a class="uk-link-muted" onclick="showMoreSuggestions()"><strong>${matches.length - (total_matches+1)}</strong></a> more matches...`
}
shortsuggestions = html
document.getElementById('similar-items-list').innerHTML = html;
} else {
document.getElementById('item-warning').hidden = true
document.getElementById('similar-items-list').innerHTML = '';
}
});
let pagination_current = 1;
let pagination_end = 10;
let search_string = "";

View File

@ -341,8 +341,13 @@
<div class="uk-margin-small">
<label class="uk-form-label" for="newSKUName">Item Name</label>
<div class="uk-form-controls">
<input class="uk-input" id="newSKUName" type="text" placeholder="">
<input class="uk-input" id="newSKUName" autocomplete="off" type="text" placeholder="">
</div>
<div id="item-warning" class="uk-alert uk-alert-warning uk-padding-small uk-margin-small-top">
<p class="uk-text-small uk-margin-small-top uk-margin-remove-bottom" id="similar-items-list"><span uk-icon="icon: warning"></span><strong>Similar item(s) found:</strong></p>
<div class="uk-text-small uk-margin-remove-top">Are you sure you want to add a new item?</div>
</div>
<ul id="suggestions"></ul>
</div>
<div class="uk-margin-small">
<label class="uk-form-label" for="newSKUSubtype">Item Type</label>

View File

@ -254,7 +254,11 @@ select, option {
color: var(--error-text);
}
.uk-alert {
background-color: rgba(255, 115, 0, 0.404);
color: var(--primary-text);
border-radius: var(--radius);
}
/* Darkmode settings for planner plage */