claude's gae

This commit is contained in:
2026-01-20 16:05:31 +01:00
parent e00c47a56f
commit afa053f006
6 changed files with 258 additions and 149 deletions
+22 -133
View File
@@ -6,6 +6,7 @@ UI component for secret generation form.
import customtkinter as ctk
from typing import List, Dict, Callable, Optional
from ui.components.unified_dropdown import UnifiedDropdown
class SecretGenerationFrame(ctk.CTkFrame):
@@ -51,31 +52,18 @@ class SecretGenerationFrame(ctk.CTkFrame):
)
self.description_entry.grid(row=2, column=0, columnspan=2, padx=20, pady=(0, 15), sticky="ew")
# Key Vault Label
self.vault_label = ctk.CTkLabel(
# Key Vault Dropdown (using UnifiedDropdown)
self.vault_dropdown = UnifiedDropdown(
self,
text="Select Key Vault:",
font=ctk.CTkFont(size=14)
title="Select Key Vault:",
on_selection_changed=self._on_vault_selected,
show_count=False,
display_format=lambda v: f"{v['name']} (RG: {v['resource_group']})",
max_dropdown_height=300,
button_width=600,
button_height=40
)
self.vault_label.grid(row=3, column=0, columnspan=2, padx=20, pady=(0, 5), sticky="w")
# Key Vault Dropdown Button (simplified inline version)
self.vault_dropdown_button = ctk.CTkButton(
self,
text="Please select a subscription first",
command=self._open_vault_dropdown,
width=600,
height=40,
font=ctk.CTkFont(size=14),
anchor="w",
state="disabled"
)
self.vault_dropdown_button.grid(row=4, column=0, columnspan=2, padx=20, pady=(0, 15), sticky="ew")
# Store vaults and selection
self.vaults = []
self.selected_vault = None
self.vault_popup = None
self.vault_dropdown.grid(row=3, column=0, columnspan=2, padx=0, pady=(0, 15), sticky="ew")
# Remove old secrets checkbox
self.remove_old_checkbox = ctk.CTkCheckBox(
@@ -83,7 +71,7 @@ class SecretGenerationFrame(ctk.CTkFrame):
text="Remove old secrets after creating new one",
font=ctk.CTkFont(size=14)
)
self.remove_old_checkbox.grid(row=5, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="w")
self.remove_old_checkbox.grid(row=4, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="w")
# Generate button
self.generate_button = ctk.CTkButton(
@@ -94,7 +82,7 @@ class SecretGenerationFrame(ctk.CTkFrame):
font=ctk.CTkFont(size=16, weight="bold"),
state="disabled"
)
self.generate_button.grid(row=6, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="ew")
self.generate_button.grid(row=5, column=0, columnspan=2, padx=20, pady=(0, 20), sticky="ew")
# Configure grid
self.grid_columnconfigure(0, weight=1)
@@ -106,104 +94,12 @@ class SecretGenerationFrame(ctk.CTkFrame):
Args:
vaults: List of vault dictionaries with 'name' and 'resource_group'
"""
self.vaults = vaults
self.vault_dropdown.set_items(vaults)
if vaults:
self.vault_dropdown_button.configure(state="normal")
# Auto-select first vault
self._select_vault(vaults[0])
else:
self.vault_dropdown_button.configure(state="disabled", text="No Key Vaults found")
self.selected_vault = None
def _open_vault_dropdown(self):
"""Open the vault selection popup."""
if not self.vaults or self.vault_popup:
return
import tkinter as tk
# Create popup
self.vault_popup = tk.Toplevel(self)
self.vault_popup.wm_overrideredirect(True)
self.vault_popup.wm_attributes("-topmost", True)
# Calculate height
item_height = 44
calculated_height = len(self.vaults) * item_height + 10
popup_height = min(calculated_height, 300)
# Create scrollable frame
scroll_frame = ctk.CTkScrollableFrame(
self.vault_popup,
width=580,
height=popup_height
)
scroll_frame.pack(fill="both", expand=True)
# Configure scroll speed to match main window (40px per scroll unit = 2x faster)
scroll_frame._parent_canvas.configure(yscrollincrement=40)
# Create buttons
for idx, vault in enumerate(self.vaults):
display_text = f"{vault['name']} (RG: {vault['resource_group']})"
max_chars = 60
truncated = display_text if len(display_text) <= max_chars else display_text[:max_chars] + "..."
btn = ctk.CTkButton(
scroll_frame,
text=truncated,
command=lambda v=vault: self._select_vault_and_close(v),
font=ctk.CTkFont(size=14),
height=40,
fg_color="transparent",
border_width=1,
border_color="gray50",
hover_color=("gray70", "gray30"),
anchor="w"
)
btn.grid(row=idx, column=0, padx=5, pady=2, sticky="ew")
scroll_frame.grid_columnconfigure(0, weight=1)
# Bind mouse wheel
def popup_scroll(event):
if event.delta > 0:
scroll_frame._parent_canvas.yview_scroll(-1, "units")
else:
scroll_frame._parent_canvas.yview_scroll(1, "units")
return "break"
btn.bind("<MouseWheel>", popup_scroll, add="+")
# Position popup
self.vault_popup.update_idletasks()
x = self.vault_dropdown_button.winfo_rootx()
y = self.vault_dropdown_button.winfo_rooty() + self.vault_dropdown_button.winfo_height()
self.vault_popup.wm_geometry(f"+{x}+{y}")
# Bind events
self.vault_popup.bind("<Escape>", lambda e: self._close_vault_popup())
self.vault_popup.bind("<FocusOut>", lambda e: self._close_vault_popup())
self.vault_popup.focus_set()
def _select_vault(self, vault: Dict):
"""Select a vault and update button text."""
self.selected_vault = vault
display_text = f"{vault['name']} (RG: {vault['resource_group']})"
max_chars = 60
truncated = display_text if len(display_text) <= max_chars else display_text[:max_chars] + "..."
self.vault_dropdown_button.configure(text=truncated)
def _select_vault_and_close(self, vault: Dict):
"""Select vault and close popup."""
self._select_vault(vault)
self._close_vault_popup()
def _close_vault_popup(self):
"""Close the vault popup."""
if self.vault_popup:
self.vault_popup.destroy()
self.vault_popup = None
def _on_vault_selected(self, vault: Dict):
"""Handle vault selection."""
# Selection is stored in dropdown - no additional action needed
pass
def _on_generate_clicked(self):
"""Handle generate button click."""
@@ -222,7 +118,7 @@ class SecretGenerationFrame(ctk.CTkFrame):
Returns:
Dict: Selected vault or None
"""
return self.selected_vault
return self.vault_dropdown.get_selected()
def get_description(self) -> str:
"""
@@ -251,13 +147,12 @@ class SecretGenerationFrame(ctk.CTkFrame):
"""
if enabled:
self.description_entry.configure(state="normal")
if self.vaults:
self.vault_dropdown_button.configure(state="normal")
self.vault_dropdown.set_enabled(True)
self.remove_old_checkbox.configure(state="normal")
self.generate_button.configure(state="normal")
else:
self.description_entry.configure(state="disabled")
self.vault_dropdown_button.configure(state="disabled")
self.vault_dropdown.set_enabled(False)
self.remove_old_checkbox.configure(state="disabled")
self.generate_button.configure(state="disabled")
@@ -280,13 +175,7 @@ class SecretGenerationFrame(ctk.CTkFrame):
Args:
loading: Whether currently loading
"""
if loading:
self.vault_dropdown_button.configure(state="disabled", text="Loading Key Vaults...")
else:
if self.vaults:
self.vault_dropdown_button.configure(state="normal")
else:
self.vault_dropdown_button.configure(state="disabled", text="No Key Vaults found")
self.vault_dropdown.set_loading(loading)
def reset(self):
"""Reset the form to initial state."""