Added uploads, part renaming, bulk data import acceptance
This commit is contained in:
178
ui/app_tk.py
178
ui/app_tk.py
@@ -15,10 +15,175 @@ from apis.digikey_api import suggest_category_from_digikey
|
||||
# ------------ Pages ------------
|
||||
|
||||
class HomePage(ttk.Frame):
|
||||
"""Always listening; on scan -> ask Part-DB; route to View or Create."""
|
||||
"""Home page with tools and settings."""
|
||||
def __init__(self, master, app):
|
||||
super().__init__(master)
|
||||
self.app = app
|
||||
|
||||
ttk.Label(self, text="Part-DB Helper", font=("Segoe UI", 16, "bold")).pack(pady=(18,8))
|
||||
|
||||
# Settings section
|
||||
settings_frame = ttk.LabelFrame(self, text="Settings", padding=10)
|
||||
settings_frame.pack(fill="x", padx=20, pady=(0,10))
|
||||
|
||||
# Mode toggle (Live/Dry Run)
|
||||
mode_frame = ttk.Frame(settings_frame)
|
||||
mode_frame.pack(fill="x", pady=2)
|
||||
ttk.Label(mode_frame, text="Standardization Mode:", width=20).pack(side="left")
|
||||
self.mode_var = tk.StringVar(value="live")
|
||||
ttk.Radiobutton(mode_frame, text="Live (Make Changes)", variable=self.mode_var, value="live").pack(side="left", padx=5)
|
||||
ttk.Radiobutton(mode_frame, text="Dry Run (Preview Only)", variable=self.mode_var, value="dry").pack(side="left", padx=5)
|
||||
|
||||
# Provider update toggle
|
||||
provider_frame = ttk.Frame(settings_frame)
|
||||
provider_frame.pack(fill="x", pady=2)
|
||||
ttk.Label(provider_frame, text="Provider Updates:", width=20).pack(side="left")
|
||||
self.provider_var = tk.BooleanVar(value=True)
|
||||
ttk.Checkbutton(provider_frame, text="Update from information providers (Digi-Key, etc.)", variable=self.provider_var).pack(side="left", padx=5)
|
||||
|
||||
# Tools section
|
||||
ttk.Separator(self, orient="horizontal").pack(fill="x", pady=10, padx=20)
|
||||
ttk.Label(self, text="Tools", font=("Segoe UI", 14, "bold")).pack(pady=(0,10))
|
||||
|
||||
tools_frame = ttk.Frame(self)
|
||||
tools_frame.pack(pady=(0,10))
|
||||
ttk.Button(tools_frame, text="Scanner", command=self.goto_scanner, width=25).pack(pady=4)
|
||||
ttk.Button(tools_frame, text="Accept Import Jobs", command=self.run_accept_jobs, width=25).pack(pady=4)
|
||||
ttk.Button(tools_frame, text="Run Bulk Add", command=self.run_bulk_add, width=25).pack(pady=4)
|
||||
ttk.Button(tools_frame, text="Import from CSV Files", command=self.run_import_csv, width=25).pack(pady=4)
|
||||
ttk.Button(tools_frame, text="Update Components", command=self.run_standardize_components, width=25).pack(pady=4)
|
||||
|
||||
def goto_scanner(self):
|
||||
"""Navigate to scanner page."""
|
||||
self.app.goto_scanner()
|
||||
|
||||
def run_accept_jobs(self):
|
||||
"""Launch the accept import jobs automation in a new thread."""
|
||||
from workflows.accept_import_jobs import run_accept_import_jobs
|
||||
|
||||
def work():
|
||||
run_accept_import_jobs(auto_close=True)
|
||||
|
||||
t = threading.Thread(target=work, daemon=True)
|
||||
t.start()
|
||||
messagebox.showinfo("Started", "Import job acceptance automation started in browser.\nCheck the browser window for progress.")
|
||||
|
||||
def run_bulk_add(self):
|
||||
"""Launch the bulk add workflow."""
|
||||
from workflows.bulk_add import run_bulk_add
|
||||
|
||||
def work():
|
||||
run_bulk_add()
|
||||
|
||||
t = threading.Thread(target=work, daemon=True)
|
||||
t.start()
|
||||
messagebox.showinfo("Started", "Bulk add workflow started in browser.\nCheck the browser window for progress.")
|
||||
|
||||
def run_import_csv(self):
|
||||
"""Launch the CSV import workflow."""
|
||||
update_providers = self.provider_var.get()
|
||||
|
||||
from workflows.import_from_csv import run_import_from_csv
|
||||
from ui.progress_dialog import ProgressDialog
|
||||
|
||||
# Create progress dialog
|
||||
progress = ProgressDialog(self.app, "Importing from CSV")
|
||||
|
||||
def progress_callback(current, total, status):
|
||||
progress.update(current, total, status)
|
||||
return progress.is_cancelled()
|
||||
|
||||
def work():
|
||||
try:
|
||||
run_import_from_csv(update_providers=update_providers, progress_callback=progress_callback)
|
||||
finally:
|
||||
progress.close()
|
||||
# Show completion message
|
||||
self.app.after(0, lambda: messagebox.showinfo("Import Complete", "CSV import finished!\nCheck console for details."))
|
||||
|
||||
t = threading.Thread(target=work, daemon=True)
|
||||
t.start()
|
||||
|
||||
def run_standardize_components(self):
|
||||
"""Launch the component standardization workflow."""
|
||||
dry_run = (self.mode_var.get() == "dry")
|
||||
|
||||
from workflows.standardize_components import run_standardize_components
|
||||
from ui.progress_dialog import ProgressDialog
|
||||
|
||||
# Create progress dialog - self.app is the Tk root
|
||||
progress = ProgressDialog(self.app, "Standardizing Components")
|
||||
|
||||
def progress_callback(current, total, status):
|
||||
progress.update(current, total, status)
|
||||
return progress.is_cancelled()
|
||||
|
||||
def work():
|
||||
try:
|
||||
run_standardize_components(dry_run=dry_run, progress_callback=progress_callback)
|
||||
finally:
|
||||
progress.close()
|
||||
|
||||
t = threading.Thread(target=work, daemon=True)
|
||||
t.start()
|
||||
|
||||
def run_standardize_passives(self):
|
||||
"""Launch the passive components standardization workflow."""
|
||||
dry_run = (self.mode_var.get() == "dry")
|
||||
|
||||
from workflows.standardize_passives import run_standardize_passives
|
||||
from ui.progress_dialog import ProgressDialog
|
||||
|
||||
# Create progress dialog - self.app is the Tk root
|
||||
progress = ProgressDialog(self.app, "Standardizing Passives")
|
||||
|
||||
def progress_callback(current, total, status):
|
||||
progress.update(current, total, status)
|
||||
return progress.is_cancelled()
|
||||
|
||||
def work():
|
||||
try:
|
||||
run_standardize_passives(category_name="Passives", dry_run=dry_run, progress_callback=progress_callback)
|
||||
finally:
|
||||
progress.close()
|
||||
|
||||
t = threading.Thread(target=work, daemon=True)
|
||||
t.start()
|
||||
|
||||
def run_standardize_asdmb(self):
|
||||
"""Launch the ASDMB crystal standardization workflow."""
|
||||
dry_run = (self.mode_var.get() == "dry")
|
||||
provider_update = self.provider_var.get() and not dry_run
|
||||
|
||||
from workflows.standardize_asdmb import run_standardize_asdmb
|
||||
from ui.progress_dialog import ProgressDialog
|
||||
|
||||
# Create progress dialog - self.app is the Tk root
|
||||
progress = ProgressDialog(self.app, "Standardizing ASDMB Crystals")
|
||||
|
||||
def progress_callback(current, total, status):
|
||||
progress.update(current, total, status)
|
||||
return progress.is_cancelled()
|
||||
|
||||
def work():
|
||||
try:
|
||||
run_standardize_asdmb(category_name="Clock - ASDMB", dry_run=dry_run, update_providers=provider_update, progress_callback=progress_callback)
|
||||
finally:
|
||||
progress.close()
|
||||
|
||||
t = threading.Thread(target=work, daemon=True)
|
||||
t.start()
|
||||
|
||||
|
||||
class ScannerPage(ttk.Frame):
|
||||
"""Scanner page for scanning Digi-Key labels."""
|
||||
def __init__(self, master, app):
|
||||
super().__init__(master)
|
||||
self.app = app
|
||||
|
||||
# Back button
|
||||
ttk.Button(self, text="← Back to Home", command=self.app.goto_home).pack(anchor="w", padx=10, pady=10)
|
||||
|
||||
ttk.Label(self, text="Scan a Digi-Key code", font=("Segoe UI", 16, "bold")).pack(pady=(18,8))
|
||||
ttk.Label(self, text=f"Listening on {COM_PORT} @ {BAUD_RATE}").pack(pady=(0,12))
|
||||
|
||||
@@ -29,7 +194,7 @@ class HomePage(ttk.Frame):
|
||||
ttk.Entry(wrap, textvariable=self.last_var, state="readonly").pack(side="left", fill="x", expand=True, padx=(8,0))
|
||||
|
||||
ttk.Label(self, text="(This page listens continuously. Just scan another label.)", foreground="#666").pack()
|
||||
|
||||
|
||||
def on_scan(self, raw: str):
|
||||
self.last_var.set(raw)
|
||||
fields = parse_digikey(raw)
|
||||
@@ -50,6 +215,7 @@ class HomePage(ttk.Frame):
|
||||
# No part -> prepare creation
|
||||
self.app.goto_create(fields, raw)
|
||||
|
||||
|
||||
class ViewPage(ttk.Frame):
|
||||
"""Shows existing part summary + button to force Digi-Key provider update."""
|
||||
def __init__(self, master, app):
|
||||
@@ -275,10 +441,11 @@ class App(tk.Tk):
|
||||
self.pdb = PartDB(PARTDB_BASE, PARTDB_TOKEN)
|
||||
|
||||
self.home = HomePage(self, self)
|
||||
self.scanner = ScannerPage(self, self)
|
||||
self.view = ViewPage(self, self)
|
||||
self.create = CreatePage(self, self)
|
||||
|
||||
for f in (self.home, self.view, self.create):
|
||||
for f in (self.home, self.scanner, self.view, self.create):
|
||||
f.grid(row=0, column=0, sticky="nsew")
|
||||
|
||||
# start listening thread once
|
||||
@@ -290,10 +457,13 @@ class App(tk.Tk):
|
||||
def on_scan(self, flat: str):
|
||||
if self.busy:
|
||||
return # ignore scans during provider update
|
||||
self.home.on_scan(flat)
|
||||
self.scanner.on_scan(flat)
|
||||
|
||||
def goto_home(self):
|
||||
self.home.tkraise()
|
||||
|
||||
def goto_scanner(self):
|
||||
self.scanner.tkraise()
|
||||
|
||||
def goto_view(self, summary: dict):
|
||||
self.view.set_summary(summary)
|
||||
|
||||
Reference in New Issue
Block a user