Spaces:
Sleeping
Sleeping
UX: Replace remaining st.spinner usage with stable placeholders to avoid layout jitter during item save flow. Use themed status messages and short delay before rerun for smoother updates.
Browse files- streamlit_app.py +52 -45
streamlit_app.py
CHANGED
|
@@ -692,53 +692,60 @@ def main():
|
|
| 692 |
if not name_clean:
|
| 693 |
st.warning("⚠️ Item name is required.")
|
| 694 |
else:
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 698 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 699 |
try:
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
)
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
log_event("item_logged_fallback", user_email, {
|
| 720 |
-
"visit_id": v["id"],
|
| 721 |
-
"item_name": name_clean,
|
| 722 |
-
"quantity": quantity
|
| 723 |
-
})
|
| 724 |
-
except Exception as e:
|
| 725 |
-
try:
|
| 726 |
-
fallback_direct_insert(user_email, int(v["id"]), name_clean, int(quantity),
|
| 727 |
-
clean_text(category,80), clean_text(unit,40),
|
| 728 |
-
clean_text(barcode,64), ts_iso, ingest_id)
|
| 729 |
-
st.success("✅ Item logged successfully (fallback method)!")
|
| 730 |
-
log_event("item_logged_fallback", user_email, {
|
| 731 |
-
"visit_id": v["id"],
|
| 732 |
-
"item_name": name_clean,
|
| 733 |
-
"quantity": quantity
|
| 734 |
-
})
|
| 735 |
-
except Exception as e2:
|
| 736 |
-
st.error(f"❌ Failed to log item: {e2}")
|
| 737 |
-
log_event("item_log_failed", user_email, {"error": str(e2)}, "error")
|
| 738 |
-
|
| 739 |
-
st.session_state["last_activity_at"] = local_now()
|
| 740 |
-
st.session_state["scanned_item_name"] = name_clean
|
| 741 |
-
st.rerun()
|
| 742 |
|
| 743 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 744 |
|
|
|
|
| 692 |
if not name_clean:
|
| 693 |
st.warning("⚠️ Item name is required.")
|
| 694 |
else:
|
| 695 |
+
save_status = st.empty()
|
| 696 |
+
with save_status.container():
|
| 697 |
+
st.markdown(ModernUIComponents.create_status_message("Saving item...", "loading"), unsafe_allow_html=True)
|
| 698 |
+
ts_iso = datetime.utcnow().isoformat()
|
| 699 |
+
ingest_id = deterministic_ingest_id(int(v["id"]), user_email, name_clean, int(quantity), ts_iso)
|
| 700 |
+
|
| 701 |
+
try:
|
| 702 |
+
ok, msg = try_rpc_ingest(
|
| 703 |
+
email=user_email, v_id=int(v["id"]), name=name_clean, qty=int(quantity),
|
| 704 |
+
category=clean_text(category, 80), unit=clean_text(unit, 40),
|
| 705 |
+
barcode=clean_text(barcode, 64), ts_iso=ts_iso, ingest_id=ingest_id
|
| 706 |
+
)
|
| 707 |
|
| 708 |
+
if ok:
|
| 709 |
+
save_status.empty()
|
| 710 |
+
st.markdown(ModernUIComponents.create_status_message("Item logged successfully!", "success"), unsafe_allow_html=True)
|
| 711 |
+
log_event("item_logged", user_email, {
|
| 712 |
+
"visit_id": v["id"],
|
| 713 |
+
"item_name": name_clean,
|
| 714 |
+
"quantity": quantity
|
| 715 |
+
})
|
| 716 |
+
else:
|
| 717 |
+
st.markdown(ModernUIComponents.create_status_message(f"{msg}. Trying fallback method...", "warning"), unsafe_allow_html=True)
|
| 718 |
+
fallback_direct_insert(user_email, int(v["id"]), name_clean, int(quantity),
|
| 719 |
+
clean_text(category,80), clean_text(unit,40),
|
| 720 |
+
clean_text(barcode,64), ts_iso, ingest_id)
|
| 721 |
+
save_status.empty()
|
| 722 |
+
st.markdown(ModernUIComponents.create_status_message("Item logged successfully (fallback method)!", "success"), unsafe_allow_html=True)
|
| 723 |
+
log_event("item_logged_fallback", user_email, {
|
| 724 |
+
"visit_id": v["id"],
|
| 725 |
+
"item_name": name_clean,
|
| 726 |
+
"quantity": quantity
|
| 727 |
+
})
|
| 728 |
+
except Exception as e:
|
| 729 |
try:
|
| 730 |
+
fallback_direct_insert(user_email, int(v["id"]), name_clean, int(quantity),
|
| 731 |
+
clean_text(category,80), clean_text(unit,40),
|
| 732 |
+
clean_text(barcode,64), ts_iso, ingest_id)
|
| 733 |
+
save_status.empty()
|
| 734 |
+
st.markdown(ModernUIComponents.create_status_message("Item logged successfully (fallback method)!", "success"), unsafe_allow_html=True)
|
| 735 |
+
log_event("item_logged_fallback", user_email, {
|
| 736 |
+
"visit_id": v["id"],
|
| 737 |
+
"item_name": name_clean,
|
| 738 |
+
"quantity": quantity
|
| 739 |
+
})
|
| 740 |
+
except Exception as e2:
|
| 741 |
+
save_status.empty()
|
| 742 |
+
st.error(f"❌ Failed to log item: {e2}")
|
| 743 |
+
log_event("item_log_failed", user_email, {"error": str(e2)}, "error")
|
| 744 |
+
|
| 745 |
+
st.session_state["last_activity_at"] = local_now()
|
| 746 |
+
st.session_state["scanned_item_name"] = name_clean
|
| 747 |
+
time.sleep(0.2)
|
| 748 |
+
st.rerun()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 749 |
|
| 750 |
st.markdown('</div>', unsafe_allow_html=True)
|
| 751 |
|