* Add schema management screen with list and editor * Implement table management screen with list and editor * Create data operations for schema and table management * Define UI rules and guidelines for consistency * Ensure circular tab navigation and keyboard shortcuts * Add forms for creating and editing schemas and tables * Implement confirmation dialogs for destructive actions
10 KiB
UI Rules and Guidelines
Layout Requirements
All layouts / forms must be in seperate files regarding their domain or entity.
Screen Layout Structure
All screens must follow this consistent layout:
-
Title at the Top (1 row, fixed height)
- Centered bold text:
[::b]Title Text - Use
tview.NewTextView()withSetTextAlign(tview.AlignCenter) - Enable dynamic colors:
SetDynamicColors(true)
- Centered bold text:
-
Content in the Middle (flexible height)
- Tables, lists, forms, or info displays
- Uses flex weight of 1 for dynamic sizing
-
Action Buttons at the Bottom (1 row, fixed height)
- Must be in a horizontal flex container
- Action buttons before Back button
- Back button is always last
Form Layout Structure
All forms must follow this button order:
-
Save Button (always first)
- Label: "Save"
- Primary action that commits changes
-
Delete Button (optional, only for edit forms)
- Label: "Delete"
- Only shown when editing existing items (not for new items)
- Must show confirmation dialog before deletion
-
Back Button (always last)
- Label: "Back"
- Returns to previous screen without saving
Button Order Examples:
- New Item Forms: Save, Back
- Edit Item Forms: Save, Delete, Back
Tab Navigation
All screens must implement circular tab navigation:
- Tab Key - Moves focus to the next focusable element
- Shift+Tab (BackTab) - Moves focus to the previous focusable element
- At the End - Tab cycles back to the first element
- At the Start - Shift+Tab cycles back to the last element
Navigation Flow Pattern:
- Each widget must handle both Tab and BackTab
- First widget: BackTab → Last widget, Tab → Second widget
- Middle widgets: BackTab → Previous widget, Tab → Next widget
- Last widget: BackTab → Previous widget, Tab → First widget
Keyboard Shortcuts
Standard Keys
- ESC - Cancel current operation or go back to previous screen
- Tab - Move focus forward (circular)
- Shift+Tab - Move focus backward (circular)
- Enter - Activate/select current item in tables and lists
Letter Key Shortcuts
- 'n' - New (create new item)
- 'b' - Back (return to previous screen)
- 'e' - Edit (edit current item)
- 'd' - Delete (delete current item)
- 'c' - Edit Column (in table editor)
- 's' - Manage Schemas (in main menu)
- 't' - Manage Tables (in main menu)
- 'q' - Quit/Exit (in main menu)
Consistency Requirements
- Layout Structure - All screens: Title (top) → Content (middle) → Buttons (bottom)
- Title Format - Bold (
[::b]), centered, dynamic colors enabled - Tables - Fixed headers (row 0), borders enabled, selectable rows
- Buttons - Include keyboard shortcuts in labels (e.g., "Back [b]")
- Forms - Button order: Save, Delete (if edit), Back
- Destructive Actions - Always show confirmation dialogs
- ESC Key - All screens support ESC to go back
- Action Buttons - Positioned before Back button, in logical order
- Data Refresh - Always refresh the previous screen when returning from a form or dialog
Widget Naming Conventions
- Tables:
schemaTable,tableTable,colTable - Buttons: Prefix with
btn(e.g.,btnBack,btnDelete,btnNewSchema) - Flex containers:
btnFlexfor button containers,flexfor main layout - Forms:
form - Lists:
list,tableList - Text views:
title,info - Use camelCase for all variable names
Page Naming Conventions
Use descriptive kebab-case names:
- Main screens:
main,schemas,tables,schema-editor,table-editor,column-editor - Load/Save screens:
load-database,save-database - Creation dialogs:
new-schema,new-table,new-column,new-table-from-list - Edit dialogs:
edit-schema,edit-table - Confirmations:
confirm-delete-schema,confirm-delete-table,confirm-delete-column - Exit confirmations:
exit-confirm,exit-editor-confirm - Status dialogs:
error-dialog,success-dialog
Dialog and Confirmation Rules
Confirmation Dialogs
-
Delete Confirmations - Required for all destructive actions
- Show item name in confirmation text
- Buttons: "Cancel", "Delete"
- ESC key dismisses dialog
-
Exit Confirmations - Required when exiting forms with potential unsaved changes
- Text: "Exit without saving changes?"
- Buttons: "Cancel", "No, exit without saving"
- ESC key confirms exit
-
Save Confirmations - Optional, based on context
- Use for critical data changes
- Clear description of what will be saved
Dialog Behavior
- All dialogs must capture ESC key for dismissal
- Modal dialogs overlay current screen
- Confirmation dialogs use
tview.NewModal() - Remove dialog page after action completes
Data Refresh Rules
When returning from any form or dialog, the previous screen must be refreshed to show updated data. If Tables exists in the screen, their data must be updated:
- After Save - Remove and recreate the previous screen to display updated data
- After Delete - Remove and recreate the previous screen to display remaining data
- After Cancel/Back - Remove and recreate the previous screen (data may have changed)
- Implementation Pattern - Remove the current page, remove the previous page, then recreate the previous page with fresh data
Why This Matters:
- Ensures users see their changes immediately
- Prevents stale data from being displayed
- Maintains data consistency across the UI
- Avoids confusion from seeing outdated information
Example Flow:
User on Schema List → Opens Edit Schema Form → Saves Changes →
Returns to Schema List (refreshed with updated schema data)
Big Loading/Saving Operations
When loading big changes, files or data, always give a load completed or load error dialog. Do the same with saving. This informs the user what happens. When data is dirty, always ask the user to save when trying to exit.
Load/Save Screens
-
Load Screen (
load-database) - Shown when no source is specified via command line- Format dropdown (dbml, dctx, drawdb, graphql, json, yaml, gorm, bun, drizzle, prisma, typeorm, pgsql)
- File path input (for file-based formats)
- Connection string input (for database formats like pgsql)
- Load button [l] - Loads the database
- Create New button [n] - Creates a new empty database
- Exit button [q] - Exits the application
- ESC key exits the application
-
Save Screen (
save-database) - Accessible from main menu with 'w' key- Format dropdown (same as load screen)
- File path input
- Help text explaining format requirements
- Save button [s] - Saves the database
- Back button [b] - Returns to main menu
- ESC key returns to main menu
- Pre-populated with existing save configuration if available
Status Dialogs
- Error Dialog (
error-dialog) - Shows error messages with OK button and ESC to dismiss - Success Dialog (
success-dialog) - Shows success messages with OK button, ESC to dismiss, and optional callback on close
Screen Organization
Organize UI code into these files:
UI Files (Screens and Dialogs)
- editor.go - Core
SchemaEditorstruct, constructor,Run()method, helper functions - main_menu.go - Main menu screen
- load_save_screens.go - Database load and save screens
- database_screens.go - Database edit form
- schema_screens.go - Schema list, schema editor, new/edit schema dialogs
- table_screens.go - Tables list, table editor, new/edit table dialogs
- column_screens.go - Column editor, new column dialog
- domain_screens.go - Domain list, domain editor, new/edit domain dialogs
- dialogs.go - Confirmation dialogs (exit, delete)
Data Operations Files (Business Logic)
- schema_dataops.go - Schema CRUD operations (Create, Read, Update, Delete)
- table_dataops.go - Table CRUD operations
- column_dataops.go - Column CRUD operations
Code Separation Rules
UI vs Business Logic
-
UI Files - Handle only presentation and user interaction
- Display data in tables, lists, and forms
- Capture user input
- Navigate between screens
- Show/hide dialogs
- Call dataops methods for actual data changes
-
Dataops Files - Handle only business logic and data manipulation
- Create, read, update, delete operations
- Data validation
- Data structure manipulation
- Return created/updated objects or success/failure status
- No UI code or tview references
Implementation Pattern
Creating New Items
Bad (Direct Data Manipulation in UI):
form.AddButton("Save", func() {
schema := &models.Schema{Name: name, Description: desc, ...}
se.db.Schemas = append(se.db.Schemas, schema)
})
Good (Using Dataops Methods):
form.AddButton("Save", func() {
se.CreateSchema(name, description)
})
Editing Existing Items
Bad (Modifying Data in onChange Callbacks):
form.AddInputField("Name", column.Name, 40, nil, func(value string) {
column.Name = value // Changes immediately as user types!
})
form.AddButton("Save", func() {
// Data already changed, just refresh screen
})
Good (Local Variables + Dataops on Save):
// Store original values
originalName := column.Name
newName := column.Name
form.AddInputField("Name", column.Name, 40, nil, func(value string) {
newName = value // Store in local variable
})
form.AddButton("Save", func() {
// Apply changes only when Save is clicked
se.UpdateColumn(schemaIndex, tableIndex, originalName, newName, ...)
// Then refresh screen
})
form.AddButton("Back", func() {
// Discard changes - don't apply local variables
// Just refresh screen
})
Why This Matters
Edit Forms Must Use Local Variables:
- Deferred Changes - Changes only apply when Save is clicked
- Cancellable - Back button discards changes without saving
- Handles Renames - Original name preserved to update map keys correctly
- User Expectations - Save means "commit changes", Back means "cancel"
This separation ensures:
- Cleaner, more maintainable code
- Reusable business logic
- Easier testing
- Clear separation of concerns
- Proper change management (save vs cancel)