Update app.py
Browse files
app.py
CHANGED
|
@@ -1363,15 +1363,15 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1363 |
gr.Markdown("*Smart inventory management powered by AI*", elem_id="main-menu-subtitle")
|
| 1364 |
|
| 1365 |
with gr.Row():
|
| 1366 |
-
checkout_btn = gr.Button("
|
| 1367 |
-
add_items_btn = gr.Button("
|
| 1368 |
-
analysis_btn = gr.Button("
|
| 1369 |
|
| 1370 |
# CHECK OUT MODULE
|
| 1371 |
with gr.Group(visible=False, elem_classes=["module-page"]) as checkout_module:
|
| 1372 |
-
gr.Markdown("#
|
| 1373 |
|
| 1374 |
-
with gr.Accordion("
|
| 1375 |
gr.Markdown("""
|
| 1376 |
**Step 1:** Upload a photo of items or type item names manually (comma-separated)
|
| 1377 |
|
|
@@ -1383,7 +1383,7 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1383 |
""")
|
| 1384 |
|
| 1385 |
with gr.Group(visible=True) as checkout_screen1:
|
| 1386 |
-
gr.Markdown("###
|
| 1387 |
|
| 1388 |
with gr.Row():
|
| 1389 |
with gr.Column(scale=2):
|
|
@@ -1394,7 +1394,7 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1394 |
height=400
|
| 1395 |
)
|
| 1396 |
|
| 1397 |
-
load_example_checkout_btn = gr.Button("
|
| 1398 |
|
| 1399 |
with gr.Column(scale=1):
|
| 1400 |
gr.Markdown("""
|
|
@@ -1414,7 +1414,7 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1414 |
)
|
| 1415 |
|
| 1416 |
checkout_status = gr.Markdown("")
|
| 1417 |
-
checkout_scan_btn = gr.Button("
|
| 1418 |
|
| 1419 |
with gr.Group(visible=False) as checkout_screen2:
|
| 1420 |
gr.Markdown("### Review Selected Items", elem_classes=["subsection-header"])
|
|
@@ -1428,7 +1428,7 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1428 |
with gr.Column(scale=1):
|
| 1429 |
item_qty = gr.Number(value=1, minimum=1, label="Qty")
|
| 1430 |
with gr.Column(scale=1):
|
| 1431 |
-
item_remove = gr.Button("
|
| 1432 |
|
| 1433 |
checkout_item_controls.append({
|
| 1434 |
'row': item_row,
|
|
@@ -1438,11 +1438,11 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1438 |
})
|
| 1439 |
|
| 1440 |
with gr.Row():
|
| 1441 |
-
checkout_rescan_btn = gr.Button("
|
| 1442 |
-
checkout_confirm_btn = gr.Button("
|
| 1443 |
|
| 1444 |
with gr.Group(visible=False) as checkout_screen3:
|
| 1445 |
-
gr.Markdown("###
|
| 1446 |
|
| 1447 |
checkout_preview = gr.Markdown("")
|
| 1448 |
|
|
@@ -1455,20 +1455,20 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1455 |
checkout_processing = gr.Markdown("")
|
| 1456 |
|
| 1457 |
with gr.Row():
|
| 1458 |
-
checkout_cancel_btn = gr.Button("
|
| 1459 |
-
checkout_final_btn = gr.Button("
|
| 1460 |
|
| 1461 |
checkout_result = gr.Markdown("")
|
| 1462 |
|
| 1463 |
with gr.Row():
|
| 1464 |
-
checkout_return_btn = gr.Button("
|
| 1465 |
-
checkout_another_btn = gr.Button("
|
| 1466 |
|
| 1467 |
# ADD ITEMS MODULE
|
| 1468 |
with gr.Group(visible=False, elem_classes=["module-page"]) as add_items_module:
|
| 1469 |
-
gr.Markdown("#
|
| 1470 |
|
| 1471 |
-
with gr.Accordion("
|
| 1472 |
gr.Markdown("""
|
| 1473 |
**Receipt Upload:**
|
| 1474 |
1. Upload receipt image or PDF β AI extracts items
|
|
@@ -1484,17 +1484,17 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1484 |
- Track all changes with timestamps
|
| 1485 |
""")
|
| 1486 |
|
| 1487 |
-
with gr.Tab("
|
| 1488 |
gr.Markdown("### Upload Receipt", elem_classes=["subsection-header"])
|
| 1489 |
|
| 1490 |
receipt_file = gr.File(label="Upload Receipt (PDF or Image)", file_types=[".pdf", ".png", ".jpg", ".jpeg"])
|
| 1491 |
|
| 1492 |
-
load_example_receipt_btn = gr.Button("
|
| 1493 |
|
| 1494 |
receipt_status = gr.Markdown("")
|
| 1495 |
|
| 1496 |
gr.Markdown("### Review Detected Items", elem_classes=["subsection-header"])
|
| 1497 |
-
gr.Markdown("*Check items to include, edit quantities, then apply*")
|
| 1498 |
|
| 1499 |
add_items_table = gr.Dataframe(
|
| 1500 |
headers=["Include", "Item Name", "Quantity", "Match Confidence"],
|
|
@@ -1507,11 +1507,11 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1507 |
add_items_status = gr.Markdown("")
|
| 1508 |
|
| 1509 |
with gr.Row():
|
| 1510 |
-
add_items_reject_btn = gr.Button("
|
| 1511 |
-
add_items_confirm_btn = gr.Button("
|
| 1512 |
|
| 1513 |
-
with gr.Tab("
|
| 1514 |
-
gr.Markdown("###
|
| 1515 |
|
| 1516 |
with gr.Row():
|
| 1517 |
manual_item = gr.Textbox(
|
|
@@ -1525,11 +1525,11 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1525 |
minimum=1
|
| 1526 |
)
|
| 1527 |
|
| 1528 |
-
manual_apply_btn = gr.Button("
|
| 1529 |
manual_status = gr.Markdown("")
|
| 1530 |
manual_inventory_display = gr.Dataframe(label="Updated Inventory", visible=False)
|
| 1531 |
|
| 1532 |
-
with gr.Tab("
|
| 1533 |
gr.Markdown("### Current Inventory", elem_classes=["subsection-header"])
|
| 1534 |
|
| 1535 |
with gr.Row():
|
|
@@ -1538,26 +1538,26 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1538 |
value="All",
|
| 1539 |
label="Filter by Category"
|
| 1540 |
)
|
| 1541 |
-
view_inventory_btn = gr.Button("
|
| 1542 |
|
| 1543 |
inventory_display = gr.Dataframe(label="Current Inventory", visible=False)
|
| 1544 |
|
| 1545 |
gr.Markdown("### Update History", elem_classes=["subsection-header"])
|
| 1546 |
|
| 1547 |
-
view_history_btn = gr.Button("
|
| 1548 |
history_display = gr.Textbox(label="Update History", lines=10, visible=False)
|
| 1549 |
|
| 1550 |
-
add_items_return_btn = gr.Button("
|
| 1551 |
|
| 1552 |
# INVENTORY ANALYSIS MODULE
|
| 1553 |
with gr.Group(visible=False, elem_classes=["module-page"]) as analysis_module:
|
| 1554 |
-
gr.Markdown("#
|
| 1555 |
|
| 1556 |
-
with gr.Accordion("
|
| 1557 |
gr.Markdown("""
|
| 1558 |
This module analyzes checkout patterns to optimize item placement and minimize walking distance.
|
| 1559 |
|
| 1560 |
-
###
|
| 1561 |
|
| 1562 |
**Support** - Frequency of co-occurrence (e.g., 0.10 = 10% of checkouts)
|
| 1563 |
|
|
@@ -1567,13 +1567,13 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1567 |
|
| 1568 |
**Distance Saved** - Walking distance reduction in grid units
|
| 1569 |
|
| 1570 |
-
###
|
| 1571 |
Items frequently checked together should be placed closer to reduce travel time!
|
| 1572 |
""")
|
| 1573 |
|
| 1574 |
with gr.Row():
|
| 1575 |
with gr.Column(scale=1):
|
| 1576 |
-
gr.Markdown("###
|
| 1577 |
|
| 1578 |
min_support = gr.Slider(
|
| 1579 |
minimum=0.01,
|
|
@@ -1611,25 +1611,25 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1611 |
info="Threshold for suggestions"
|
| 1612 |
)
|
| 1613 |
|
| 1614 |
-
run_analysis_btn = gr.Button("
|
| 1615 |
|
| 1616 |
with gr.Column(scale=2):
|
| 1617 |
-
gr.Markdown("###
|
| 1618 |
analysis_summary = gr.Textbox(label="", lines=14, show_label=False)
|
| 1619 |
|
| 1620 |
-
gr.Markdown("###
|
| 1621 |
analysis_viz = gr.Image(label="", type="numpy", show_label=False)
|
| 1622 |
|
| 1623 |
with gr.Row():
|
| 1624 |
with gr.Column():
|
| 1625 |
-
gr.Markdown("###
|
| 1626 |
pairs_table = gr.Dataframe(label="", show_label=False)
|
| 1627 |
|
| 1628 |
with gr.Column():
|
| 1629 |
-
gr.Markdown("###
|
| 1630 |
recs_table = gr.Dataframe(label="", show_label=False)
|
| 1631 |
|
| 1632 |
-
analysis_return_btn = gr.Button("
|
| 1633 |
|
| 1634 |
# EVENT HANDLERS - Navigation
|
| 1635 |
def show_checkout():
|
|
@@ -1715,14 +1715,14 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1715 |
return gr.update(visible=False), gr.update(visible=True)
|
| 1716 |
|
| 1717 |
checkout_scan_btn.click(
|
| 1718 |
-
fn=lambda: (gr.update(value="
|
| 1719 |
outputs=[checkout_scan_btn, checkout_status]
|
| 1720 |
).then(
|
| 1721 |
fn=scan_items_checkout,
|
| 1722 |
inputs=[checkout_image, checkout_manual],
|
| 1723 |
outputs=[matched_items_state, checkout_status]
|
| 1724 |
).then(
|
| 1725 |
-
fn=lambda: gr.update(value="
|
| 1726 |
outputs=[checkout_scan_btn]
|
| 1727 |
).then(
|
| 1728 |
fn=lambda items: (
|
|
@@ -1777,14 +1777,14 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1777 |
)
|
| 1778 |
|
| 1779 |
checkout_final_btn.click(
|
| 1780 |
-
fn=lambda: (gr.update(value="
|
| 1781 |
outputs=[checkout_final_btn, checkout_processing]
|
| 1782 |
).then(
|
| 1783 |
fn=process_checkout,
|
| 1784 |
inputs=[matched_items_state, checkout_user_id],
|
| 1785 |
outputs=[checkout_result]
|
| 1786 |
).then(
|
| 1787 |
-
fn=lambda: (gr.update(value="
|
| 1788 |
outputs=[checkout_final_btn, checkout_processing]
|
| 1789 |
).then(
|
| 1790 |
fn=lambda: (gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)),
|
|
@@ -1805,32 +1805,32 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1805 |
|
| 1806 |
# EVENT HANDLERS - Add Items
|
| 1807 |
receipt_file.change(
|
| 1808 |
-
fn=lambda: "
|
| 1809 |
outputs=[receipt_status]
|
| 1810 |
).then(
|
| 1811 |
fn=extract_text_from_receipt,
|
| 1812 |
inputs=[receipt_file],
|
| 1813 |
outputs=[add_items_table, proposals_state]
|
| 1814 |
).then(
|
| 1815 |
-
fn=lambda proposals: (gr.update(interactive=len(proposals) > 0), "
|
| 1816 |
inputs=[proposals_state],
|
| 1817 |
outputs=[add_items_confirm_btn, receipt_status]
|
| 1818 |
)
|
| 1819 |
|
| 1820 |
add_items_confirm_btn.click(
|
| 1821 |
-
fn=lambda: (gr.update(value="
|
| 1822 |
outputs=[add_items_confirm_btn, add_items_status]
|
| 1823 |
).then(
|
| 1824 |
fn=apply_updates_from_table,
|
| 1825 |
inputs=[add_items_table],
|
| 1826 |
outputs=[add_items_status, inventory_display]
|
| 1827 |
).then(
|
| 1828 |
-
fn=lambda: (gr.update(value="
|
| 1829 |
outputs=[add_items_confirm_btn, inventory_display]
|
| 1830 |
)
|
| 1831 |
|
| 1832 |
add_items_reject_btn.click(
|
| 1833 |
-
fn=lambda: ([["No items", "", "", ""]], "
|
| 1834 |
outputs=[add_items_table, add_items_status, proposals_state]
|
| 1835 |
).then(
|
| 1836 |
fn=lambda: gr.update(interactive=False),
|
|
@@ -1838,14 +1838,14 @@ with gr.Blocks(title="Makerspace Inventory System", css=CUSTOM_CSS) as demo:
|
|
| 1838 |
)
|
| 1839 |
|
| 1840 |
manual_apply_btn.click(
|
| 1841 |
-
fn=lambda: gr.update(value="
|
| 1842 |
outputs=[manual_apply_btn]
|
| 1843 |
).then(
|
| 1844 |
fn=manual_update,
|
| 1845 |
inputs=[manual_item, manual_qty],
|
| 1846 |
outputs=[manual_status, manual_inventory_display]
|
| 1847 |
).then(
|
| 1848 |
-
fn=lambda: (gr.update(value="
|
| 1849 |
outputs=[manual_apply_btn, manual_inventory_display]
|
| 1850 |
)
|
| 1851 |
|
|
|
|
| 1363 |
gr.Markdown("*Smart inventory management powered by AI*", elem_id="main-menu-subtitle")
|
| 1364 |
|
| 1365 |
with gr.Row():
|
| 1366 |
+
checkout_btn = gr.Button("Check Out Items", size="lg", elem_classes=["module-button"], scale=1)
|
| 1367 |
+
add_items_btn = gr.Button("Add Items", size="lg", elem_classes=["module-button"], scale=1)
|
| 1368 |
+
analysis_btn = gr.Button("Inventory Analysis", size="lg", elem_classes=["module-button"], scale=1)
|
| 1369 |
|
| 1370 |
# CHECK OUT MODULE
|
| 1371 |
with gr.Group(visible=False, elem_classes=["module-page"]) as checkout_module:
|
| 1372 |
+
gr.Markdown("# Check Out Items", elem_classes=["section-header"])
|
| 1373 |
|
| 1374 |
+
with gr.Accordion("How to Use This Module", open=False):
|
| 1375 |
gr.Markdown("""
|
| 1376 |
**Step 1:** Upload a photo of items or type item names manually (comma-separated)
|
| 1377 |
|
|
|
|
| 1383 |
""")
|
| 1384 |
|
| 1385 |
with gr.Group(visible=True) as checkout_screen1:
|
| 1386 |
+
gr.Markdown("### Scan Items", elem_classes=["subsection-header"])
|
| 1387 |
|
| 1388 |
with gr.Row():
|
| 1389 |
with gr.Column(scale=2):
|
|
|
|
| 1394 |
height=400
|
| 1395 |
)
|
| 1396 |
|
| 1397 |
+
load_example_checkout_btn = gr.Button("Load Example", size="sm", variant="secondary", scale=0, visible=EXAMPLE_CHECKOUT_IMAGE is not None)
|
| 1398 |
|
| 1399 |
with gr.Column(scale=1):
|
| 1400 |
gr.Markdown("""
|
|
|
|
| 1414 |
)
|
| 1415 |
|
| 1416 |
checkout_status = gr.Markdown("")
|
| 1417 |
+
checkout_scan_btn = gr.Button("Scan & Match Items", variant="primary", size="lg")
|
| 1418 |
|
| 1419 |
with gr.Group(visible=False) as checkout_screen2:
|
| 1420 |
gr.Markdown("### Review Selected Items", elem_classes=["subsection-header"])
|
|
|
|
| 1428 |
with gr.Column(scale=1):
|
| 1429 |
item_qty = gr.Number(value=1, minimum=1, label="Qty")
|
| 1430 |
with gr.Column(scale=1):
|
| 1431 |
+
item_remove = gr.Button("Remove", size="sm", variant="stop")
|
| 1432 |
|
| 1433 |
checkout_item_controls.append({
|
| 1434 |
'row': item_row,
|
|
|
|
| 1438 |
})
|
| 1439 |
|
| 1440 |
with gr.Row():
|
| 1441 |
+
checkout_rescan_btn = gr.Button("Rescan", variant="secondary")
|
| 1442 |
+
checkout_confirm_btn = gr.Button("Proceed to Checkout", variant="primary", size="lg")
|
| 1443 |
|
| 1444 |
with gr.Group(visible=False) as checkout_screen3:
|
| 1445 |
+
gr.Markdown("### Confirm Checkout", elem_classes=["subsection-header"])
|
| 1446 |
|
| 1447 |
checkout_preview = gr.Markdown("")
|
| 1448 |
|
|
|
|
| 1455 |
checkout_processing = gr.Markdown("")
|
| 1456 |
|
| 1457 |
with gr.Row():
|
| 1458 |
+
checkout_cancel_btn = gr.Button("Cancel", variant="secondary")
|
| 1459 |
+
checkout_final_btn = gr.Button("Complete Checkout", variant="primary", size="lg")
|
| 1460 |
|
| 1461 |
checkout_result = gr.Markdown("")
|
| 1462 |
|
| 1463 |
with gr.Row():
|
| 1464 |
+
checkout_return_btn = gr.Button("Return to Main Menu", variant="secondary")
|
| 1465 |
+
checkout_another_btn = gr.Button("Check Out More Items", variant="primary", visible=False)
|
| 1466 |
|
| 1467 |
# ADD ITEMS MODULE
|
| 1468 |
with gr.Group(visible=False, elem_classes=["module-page"]) as add_items_module:
|
| 1469 |
+
gr.Markdown("# Add Items to Inventory", elem_classes=["section-header"])
|
| 1470 |
|
| 1471 |
+
with gr.Accordion("How to Use This Module", open=False):
|
| 1472 |
gr.Markdown("""
|
| 1473 |
**Receipt Upload:**
|
| 1474 |
1. Upload receipt image or PDF β AI extracts items
|
|
|
|
| 1484 |
- Track all changes with timestamps
|
| 1485 |
""")
|
| 1486 |
|
| 1487 |
+
with gr.Tab("Receipt Upload"):
|
| 1488 |
gr.Markdown("### Upload Receipt", elem_classes=["subsection-header"])
|
| 1489 |
|
| 1490 |
receipt_file = gr.File(label="Upload Receipt (PDF or Image)", file_types=[".pdf", ".png", ".jpg", ".jpeg"])
|
| 1491 |
|
| 1492 |
+
load_example_receipt_btn = gr.Button("Load Example", size="sm", variant="secondary", scale=0, visible=EXAMPLE_RECEIPT_PDF is not None)
|
| 1493 |
|
| 1494 |
receipt_status = gr.Markdown("")
|
| 1495 |
|
| 1496 |
gr.Markdown("### Review Detected Items", elem_classes=["subsection-header"])
|
| 1497 |
+
gr.Markdown("*Check items to include, edit quantities as needed, then apply changes*")
|
| 1498 |
|
| 1499 |
add_items_table = gr.Dataframe(
|
| 1500 |
headers=["Include", "Item Name", "Quantity", "Match Confidence"],
|
|
|
|
| 1507 |
add_items_status = gr.Markdown("")
|
| 1508 |
|
| 1509 |
with gr.Row():
|
| 1510 |
+
add_items_reject_btn = gr.Button("Clear All", variant="secondary")
|
| 1511 |
+
add_items_confirm_btn = gr.Button("Apply Updates", variant="primary", interactive=False)
|
| 1512 |
|
| 1513 |
+
with gr.Tab("Manual Entry"):
|
| 1514 |
+
gr.Markdown("### Add Items Manually", elem_classes=["subsection-header"])
|
| 1515 |
|
| 1516 |
with gr.Row():
|
| 1517 |
manual_item = gr.Textbox(
|
|
|
|
| 1525 |
minimum=1
|
| 1526 |
)
|
| 1527 |
|
| 1528 |
+
manual_apply_btn = gr.Button("Add to Inventory", variant="primary")
|
| 1529 |
manual_status = gr.Markdown("")
|
| 1530 |
manual_inventory_display = gr.Dataframe(label="Updated Inventory", visible=False)
|
| 1531 |
|
| 1532 |
+
with gr.Tab("View & History"):
|
| 1533 |
gr.Markdown("### Current Inventory", elem_classes=["subsection-header"])
|
| 1534 |
|
| 1535 |
with gr.Row():
|
|
|
|
| 1538 |
value="All",
|
| 1539 |
label="Filter by Category"
|
| 1540 |
)
|
| 1541 |
+
view_inventory_btn = gr.Button("Refresh Inventory")
|
| 1542 |
|
| 1543 |
inventory_display = gr.Dataframe(label="Current Inventory", visible=False)
|
| 1544 |
|
| 1545 |
gr.Markdown("### Update History", elem_classes=["subsection-header"])
|
| 1546 |
|
| 1547 |
+
view_history_btn = gr.Button("View Update Log")
|
| 1548 |
history_display = gr.Textbox(label="Update History", lines=10, visible=False)
|
| 1549 |
|
| 1550 |
+
add_items_return_btn = gr.Button("Return to Main Menu", variant="secondary")
|
| 1551 |
|
| 1552 |
# INVENTORY ANALYSIS MODULE
|
| 1553 |
with gr.Group(visible=False, elem_classes=["module-page"]) as analysis_module:
|
| 1554 |
+
gr.Markdown("# Inventory Layout Analysis", elem_classes=["section-header"])
|
| 1555 |
|
| 1556 |
+
with gr.Accordion("Understanding the Analysis", open=True):
|
| 1557 |
gr.Markdown("""
|
| 1558 |
This module analyzes checkout patterns to optimize item placement and minimize walking distance.
|
| 1559 |
|
| 1560 |
+
### Key Metrics:
|
| 1561 |
|
| 1562 |
**Support** - Frequency of co-occurrence (e.g., 0.10 = 10% of checkouts)
|
| 1563 |
|
|
|
|
| 1567 |
|
| 1568 |
**Distance Saved** - Walking distance reduction in grid units
|
| 1569 |
|
| 1570 |
+
### Goal:
|
| 1571 |
Items frequently checked together should be placed closer to reduce travel time!
|
| 1572 |
""")
|
| 1573 |
|
| 1574 |
with gr.Row():
|
| 1575 |
with gr.Column(scale=1):
|
| 1576 |
+
gr.Markdown("### Analysis Parameters", elem_classes=["subsection-header"])
|
| 1577 |
|
| 1578 |
min_support = gr.Slider(
|
| 1579 |
minimum=0.01,
|
|
|
|
| 1611 |
info="Threshold for suggestions"
|
| 1612 |
)
|
| 1613 |
|
| 1614 |
+
run_analysis_btn = gr.Button("Run Analysis", variant="primary", size="lg")
|
| 1615 |
|
| 1616 |
with gr.Column(scale=2):
|
| 1617 |
+
gr.Markdown("### Analysis Summary", elem_classes=["subsection-header"])
|
| 1618 |
analysis_summary = gr.Textbox(label="", lines=14, show_label=False)
|
| 1619 |
|
| 1620 |
+
gr.Markdown("### Visual Layout Comparison", elem_classes=["subsection-header"])
|
| 1621 |
analysis_viz = gr.Image(label="", type="numpy", show_label=False)
|
| 1622 |
|
| 1623 |
with gr.Row():
|
| 1624 |
with gr.Column():
|
| 1625 |
+
gr.Markdown("### Frequent Pairs", elem_classes=["subsection-header"])
|
| 1626 |
pairs_table = gr.Dataframe(label="", show_label=False)
|
| 1627 |
|
| 1628 |
with gr.Column():
|
| 1629 |
+
gr.Markdown("### Relocation Recommendations", elem_classes=["subsection-header"])
|
| 1630 |
recs_table = gr.Dataframe(label="", show_label=False)
|
| 1631 |
|
| 1632 |
+
analysis_return_btn = gr.Button("Return to Main Menu", variant="secondary")
|
| 1633 |
|
| 1634 |
# EVENT HANDLERS - Navigation
|
| 1635 |
def show_checkout():
|
|
|
|
| 1715 |
return gr.update(visible=False), gr.update(visible=True)
|
| 1716 |
|
| 1717 |
checkout_scan_btn.click(
|
| 1718 |
+
fn=lambda: (gr.update(value="Scanning...", interactive=False), "Processing image with AI..."),
|
| 1719 |
outputs=[checkout_scan_btn, checkout_status]
|
| 1720 |
).then(
|
| 1721 |
fn=scan_items_checkout,
|
| 1722 |
inputs=[checkout_image, checkout_manual],
|
| 1723 |
outputs=[matched_items_state, checkout_status]
|
| 1724 |
).then(
|
| 1725 |
+
fn=lambda: gr.update(value="Scan & Match Items", interactive=True),
|
| 1726 |
outputs=[checkout_scan_btn]
|
| 1727 |
).then(
|
| 1728 |
fn=lambda items: (
|
|
|
|
| 1777 |
)
|
| 1778 |
|
| 1779 |
checkout_final_btn.click(
|
| 1780 |
+
fn=lambda: (gr.update(value="Processing...", interactive=False), "Updating inventory..."),
|
| 1781 |
outputs=[checkout_final_btn, checkout_processing]
|
| 1782 |
).then(
|
| 1783 |
fn=process_checkout,
|
| 1784 |
inputs=[matched_items_state, checkout_user_id],
|
| 1785 |
outputs=[checkout_result]
|
| 1786 |
).then(
|
| 1787 |
+
fn=lambda: (gr.update(value="Complete Checkout", interactive=True), ""),
|
| 1788 |
outputs=[checkout_final_btn, checkout_processing]
|
| 1789 |
).then(
|
| 1790 |
fn=lambda: (gr.update(visible=False), gr.update(visible=False), gr.update(visible=False)),
|
|
|
|
| 1805 |
|
| 1806 |
# EVENT HANDLERS - Add Items
|
| 1807 |
receipt_file.change(
|
| 1808 |
+
fn=lambda: "Processing receipt with OCR...",
|
| 1809 |
outputs=[receipt_status]
|
| 1810 |
).then(
|
| 1811 |
fn=extract_text_from_receipt,
|
| 1812 |
inputs=[receipt_file],
|
| 1813 |
outputs=[add_items_table, proposals_state]
|
| 1814 |
).then(
|
| 1815 |
+
fn=lambda proposals: (gr.update(interactive=len(proposals) > 0), "Items detected! Review the table below."),
|
| 1816 |
inputs=[proposals_state],
|
| 1817 |
outputs=[add_items_confirm_btn, receipt_status]
|
| 1818 |
)
|
| 1819 |
|
| 1820 |
add_items_confirm_btn.click(
|
| 1821 |
+
fn=lambda: (gr.update(value="Applying...", interactive=False), "Updating inventory..."),
|
| 1822 |
outputs=[add_items_confirm_btn, add_items_status]
|
| 1823 |
).then(
|
| 1824 |
fn=apply_updates_from_table,
|
| 1825 |
inputs=[add_items_table],
|
| 1826 |
outputs=[add_items_status, inventory_display]
|
| 1827 |
).then(
|
| 1828 |
+
fn=lambda: (gr.update(value="Apply Updates", interactive=False), gr.update(visible=True)),
|
| 1829 |
outputs=[add_items_confirm_btn, inventory_display]
|
| 1830 |
)
|
| 1831 |
|
| 1832 |
add_items_reject_btn.click(
|
| 1833 |
+
fn=lambda: ([["No items", "", "", ""]], "Cleared all items.", []),
|
| 1834 |
outputs=[add_items_table, add_items_status, proposals_state]
|
| 1835 |
).then(
|
| 1836 |
fn=lambda: gr.update(interactive=False),
|
|
|
|
| 1838 |
)
|
| 1839 |
|
| 1840 |
manual_apply_btn.click(
|
| 1841 |
+
fn=lambda: gr.update(value="Adding...", interactive=False),
|
| 1842 |
outputs=[manual_apply_btn]
|
| 1843 |
).then(
|
| 1844 |
fn=manual_update,
|
| 1845 |
inputs=[manual_item, manual_qty],
|
| 1846 |
outputs=[manual_status, manual_inventory_display]
|
| 1847 |
).then(
|
| 1848 |
+
fn=lambda: (gr.update(value="Add to Inventory", interactive=True), gr.update(visible=True)),
|
| 1849 |
outputs=[manual_apply_btn, manual_inventory_display]
|
| 1850 |
)
|
| 1851 |
|