feat(cli): improve member design and usability #2
This commit is contained in:
@@ -165,6 +165,9 @@ def cmd_schedules_accept(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
print("\n🛑 Cancelled")
|
print("\n🛑 Cancelled")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Clear screen after service selection
|
||||||
|
print("\033[2J\033[H")
|
||||||
|
|
||||||
# Find pending schedules for this service
|
# Find pending schedules for this service
|
||||||
all_schedules = cli.schedule_repo.list_all()
|
all_schedules = cli.schedule_repo.list_all()
|
||||||
pending_schedules = [
|
pending_schedules = [
|
||||||
@@ -332,15 +335,18 @@ def cmd_schedules_remove(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
service_type_map = {st.ServiceTypeId: st.TypeName for st in cli.service_type_repo.list_all()}
|
service_type_map = {st.ServiceTypeId: st.TypeName for st in cli.service_type_repo.list_all()}
|
||||||
|
|
||||||
# Show available services for the date
|
# Show available services for the date
|
||||||
print(f"\n{TableColors.HEADER}Services available on {args.date}:{TableColors.RESET}")
|
print(f"\n{TableColors.HEADER}Services available on {args.date}{TableColors.RESET}")
|
||||||
print(f"{TableColors.BORDER}{'─' * 40}{TableColors.RESET}")
|
print(f"{TableColors.BORDER}─" * 50 + f"{TableColors.RESET}")
|
||||||
|
print()
|
||||||
for i, service in enumerate(services_on_date, 1):
|
for i, service in enumerate(services_on_date, 1):
|
||||||
type_name = service_type_map.get(service.ServiceTypeId, "Unknown")
|
type_name = service_type_map.get(service.ServiceTypeId, "Unknown")
|
||||||
print(f"{TableColors.CYAN}{i}.{TableColors.RESET} {type_name} {TableColors.DIM}(Service ID: {service.ServiceId}){TableColors.RESET}")
|
print(f" {TableColors.CYAN}{i}.{TableColors.RESET} {type_name}")
|
||||||
|
print()
|
||||||
|
|
||||||
# Let user select service
|
# Let user select service
|
||||||
try:
|
try:
|
||||||
choice = input(f"\n{TableColors.INPUT_BOX}┌─ Select service (1-{len(services_on_date)}) ─┐{TableColors.RESET}\n{TableColors.INPUT_BOX}└─> {TableColors.RESET}").strip()
|
print(f"\n{TableColors.INPUT_BOX}┌─ Select service (1-{len(services_on_date)}) ─┐{TableColors.RESET}")
|
||||||
|
choice = input(f"{TableColors.INPUT_BOX}└─> {TableColors.RESET}").strip()
|
||||||
if not choice or not choice.isdigit():
|
if not choice or not choice.isdigit():
|
||||||
print(f"{TableColors.ERROR}❌ Invalid selection{TableColors.RESET}")
|
print(f"{TableColors.ERROR}❌ Invalid selection{TableColors.RESET}")
|
||||||
return
|
return
|
||||||
@@ -355,6 +361,9 @@ def cmd_schedules_remove(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
print(f"\n{TableColors.WARNING}🛑 Cancelled{TableColors.RESET}")
|
print(f"\n{TableColors.WARNING}🛑 Cancelled{TableColors.RESET}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Clear screen after service selection
|
||||||
|
print("\033[2J\033[H")
|
||||||
|
|
||||||
# Find all schedules for this service (not just pending)
|
# Find all schedules for this service (not just pending)
|
||||||
all_schedules = cli.schedule_repo.list_all()
|
all_schedules = cli.schedule_repo.list_all()
|
||||||
service_schedules = [
|
service_schedules = [
|
||||||
@@ -546,6 +555,9 @@ def cmd_schedules_decline(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
print("\n🛑 Cancelled")
|
print("\n🛑 Cancelled")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Clear screen after service selection
|
||||||
|
print("\033[2J\033[H")
|
||||||
|
|
||||||
# Find pending schedules for this service
|
# Find pending schedules for this service
|
||||||
all_schedules = cli.schedule_repo.list_all()
|
all_schedules = cli.schedule_repo.list_all()
|
||||||
pending_schedules = [
|
pending_schedules = [
|
||||||
@@ -562,18 +574,22 @@ def cmd_schedules_decline(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
member_map = {m.MemberId: m for m in cli.member_repo.list_all()}
|
member_map = {m.MemberId: m for m in cli.member_repo.list_all()}
|
||||||
|
|
||||||
# Show available members to decline
|
# Show available members to decline
|
||||||
print(f"\n👥 Members scheduled for {service_type_map.get(selected_service.ServiceTypeId, 'Unknown')} on {args.date}:")
|
service_name = service_type_map.get(selected_service.ServiceTypeId, 'Unknown')
|
||||||
print("-" * 60)
|
print(f"{TableColors.HEADER}Members scheduled for {service_name} on {args.date}{TableColors.RESET}")
|
||||||
|
print(f"{TableColors.BORDER}─" * 70 + f"{TableColors.RESET}")
|
||||||
|
print()
|
||||||
for i, schedule in enumerate(pending_schedules, 1):
|
for i, schedule in enumerate(pending_schedules, 1):
|
||||||
member = member_map.get(schedule.MemberId)
|
member = member_map.get(schedule.MemberId)
|
||||||
if member:
|
if member:
|
||||||
print(f"{i}. {member.FirstName} {member.LastName} (Schedule ID: {schedule.ScheduleId})")
|
print(f" {TableColors.CYAN}{i}.{TableColors.RESET} {member.FirstName} {member.LastName}")
|
||||||
else:
|
else:
|
||||||
print(f"{i}. Unknown Member (ID: {schedule.MemberId}) (Schedule ID: {schedule.ScheduleId})")
|
print(f" {TableColors.CYAN}{i}.{TableColors.RESET} {TableColors.DIM}Unknown Member (ID: {schedule.MemberId}){TableColors.RESET}")
|
||||||
|
print()
|
||||||
|
|
||||||
# Let user select member
|
# Let user select member
|
||||||
try:
|
try:
|
||||||
choice = input(f"\nSelect member to decline (1-{len(pending_schedules)}): ").strip()
|
print(f"\n{TableColors.INPUT_BOX}┌─ Select member to decline (1-{len(pending_schedules)}) ─┐{TableColors.RESET}")
|
||||||
|
choice = input(f"{TableColors.INPUT_BOX}└─> {TableColors.RESET}").strip()
|
||||||
if not choice or not choice.isdigit():
|
if not choice or not choice.isdigit():
|
||||||
print("❌ Invalid selection")
|
print("❌ Invalid selection")
|
||||||
return
|
return
|
||||||
@@ -697,6 +713,9 @@ def cmd_schedules_schedule(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
print("\n🛑 Operation cancelled")
|
print("\n🛑 Operation cancelled")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Clear screen after service selection
|
||||||
|
print("\033[2J\033[H")
|
||||||
|
|
||||||
elif hasattr(args, 'service_id') and args.service_id:
|
elif hasattr(args, 'service_id') and args.service_id:
|
||||||
# Service ID based selection
|
# Service ID based selection
|
||||||
print(f"Scheduling for service ID {args.service_id}...")
|
print(f"Scheduling for service ID {args.service_id}...")
|
||||||
@@ -713,7 +732,7 @@ def cmd_schedules_schedule(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
service_type = cli.service_type_repo.get_by_id(service.ServiceTypeId)
|
service_type = cli.service_type_repo.get_by_id(service.ServiceTypeId)
|
||||||
service_type_name = service_type.TypeName if service_type else "Unknown"
|
service_type_name = service_type.TypeName if service_type else "Unknown"
|
||||||
|
|
||||||
print(f"\n📅 Selected Service: {service_type_name} on {service.ServiceDate}")
|
print(f"{TableColors.HEADER}Selected Service: {service_type_name} on {service.ServiceDate}{TableColors.RESET}")
|
||||||
|
|
||||||
# Get classification constraints if not provided
|
# Get classification constraints if not provided
|
||||||
classification_ids = []
|
classification_ids = []
|
||||||
@@ -732,13 +751,17 @@ def cmd_schedules_schedule(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
else:
|
else:
|
||||||
# If no classifications specified, ask user to select
|
# If no classifications specified, ask user to select
|
||||||
all_classifications = cli.classification_repo.list_all()
|
all_classifications = cli.classification_repo.list_all()
|
||||||
print("\n🎵 Available classifications:")
|
print(f"\n{TableColors.HEADER}Available classifications{TableColors.RESET}")
|
||||||
|
print(f"{TableColors.BORDER}─" * 50 + f"{TableColors.RESET}")
|
||||||
|
print()
|
||||||
for i, classification in enumerate(all_classifications, 1):
|
for i, classification in enumerate(all_classifications, 1):
|
||||||
print(f" {i}. {classification.ClassificationName}")
|
print(f" {TableColors.CYAN}{i}.{TableColors.RESET} {classification.ClassificationName}")
|
||||||
|
print()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
choice = input(f"\n🎯 Select classification(s) (1-{len(all_classifications)}, comma-separated): ").strip()
|
print(f"\n{TableColors.INPUT_BOX}┌─ Select classification(s) (1-{len(all_classifications)}, comma-separated) ─┐{TableColors.RESET}")
|
||||||
|
choice = input(f"{TableColors.INPUT_BOX}└─> {TableColors.RESET}").strip()
|
||||||
if not choice:
|
if not choice:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -758,7 +781,8 @@ def cmd_schedules_schedule(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
selected_classifications = [c.ClassificationName for c in cli.classification_repo.list_all()
|
selected_classifications = [c.ClassificationName for c in cli.classification_repo.list_all()
|
||||||
if c.ClassificationId in classification_ids]
|
if c.ClassificationId in classification_ids]
|
||||||
|
|
||||||
print(f"\n🔍 Looking for eligible members in: {', '.join(selected_classifications)}")
|
print(f"\n{TableColors.SUCCESS}Looking for eligible members in: {', '.join(selected_classifications)}{TableColors.RESET}")
|
||||||
|
print()
|
||||||
|
|
||||||
excluded_members = set()
|
excluded_members = set()
|
||||||
|
|
||||||
@@ -781,12 +805,15 @@ def cmd_schedules_schedule(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
member_id, first_name, last_name = preview_result
|
member_id, first_name, last_name = preview_result
|
||||||
|
|
||||||
# Show preview
|
# Show preview
|
||||||
print(f"\n✨ Next available member:")
|
print(f"\n{TableColors.HEADER}Next available member{TableColors.RESET}")
|
||||||
print(f" 👤 {first_name} {last_name} (ID: {member_id})")
|
print(f"{TableColors.BORDER}─" * 50 + f"{TableColors.RESET}")
|
||||||
|
print(f" {TableColors.CYAN}{first_name} {last_name}{TableColors.RESET}")
|
||||||
|
print()
|
||||||
|
|
||||||
# Confirm scheduling
|
# Confirm scheduling
|
||||||
try:
|
try:
|
||||||
confirm = input(f"\n🤔 Schedule {first_name} {last_name} for this service? (y/N/q to quit): ").strip().lower()
|
print(f"\n{TableColors.INPUT_BOX}┌─ Schedule {first_name} {last_name} for this service? (y/N/q to quit) ─┐{TableColors.RESET}")
|
||||||
|
confirm = input(f"{TableColors.INPUT_BOX}└─> {TableColors.RESET}").strip().lower()
|
||||||
|
|
||||||
if confirm in ['y', 'yes']:
|
if confirm in ['y', 'yes']:
|
||||||
# Actually create the schedule
|
# Actually create the schedule
|
||||||
@@ -799,24 +826,25 @@ def cmd_schedules_schedule(cli: "NimbusFlowCLI", args) -> None:
|
|||||||
|
|
||||||
if result:
|
if result:
|
||||||
scheduled_member_id, scheduled_first, scheduled_last, schedule_id = result
|
scheduled_member_id, scheduled_first, scheduled_last, schedule_id = result
|
||||||
print(f"\n✅ Successfully scheduled {scheduled_first} {scheduled_last}!")
|
print(f"\n{TableColors.SUCCESS}Successfully scheduled {scheduled_first} {scheduled_last}!{TableColors.RESET}")
|
||||||
print(f" 📋 Schedule ID: {schedule_id}")
|
print(f"{TableColors.DIM}Schedule ID: {schedule_id}{TableColors.RESET}")
|
||||||
print(f" 📧 Status: Pending (awaiting member response)")
|
print(f"{TableColors.DIM}Status: Pending (awaiting member response){TableColors.RESET}")
|
||||||
else:
|
else:
|
||||||
print("❌ Failed to create schedule. The member may no longer be eligible.")
|
print("❌ Failed to create schedule. The member may no longer be eligible.")
|
||||||
return
|
return
|
||||||
|
|
||||||
elif confirm in ['q', 'quit']:
|
elif confirm in ['q', 'quit']:
|
||||||
print("🛑 Scheduling cancelled")
|
print(f"\n{TableColors.WARNING}Scheduling cancelled{TableColors.RESET}")
|
||||||
return
|
return
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# User declined this member - add to exclusion list and continue
|
# User declined this member - add to exclusion list and continue
|
||||||
excluded_members.add(member_id)
|
excluded_members.add(member_id)
|
||||||
print(f"⏭️ Skipping {first_name} {last_name}, looking for next member...")
|
print(f"\n{TableColors.DIM}Skipping {first_name} {last_name}, looking for next member...{TableColors.RESET}")
|
||||||
|
print()
|
||||||
|
|
||||||
except (KeyboardInterrupt, EOFError):
|
except (KeyboardInterrupt, EOFError):
|
||||||
print("\n🛑 Operation cancelled")
|
print(f"\n{TableColors.WARNING}Operation cancelled{TableColors.RESET}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user