# 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:

1. **Title at the Top** (1 row, fixed height)
   - Centered bold text: `[::b]Title Text`
   - Use `tview.NewTextView()` with `SetTextAlign(tview.AlignCenter)`
   - Enable dynamic colors: `SetDynamicColors(true)`

2. **Content in the Middle** (flexible height)
   - Tables, lists, forms, or info displays
   - Uses flex weight of 1 for dynamic sizing

3. **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:

1. **Save Button** (always first)
   - Label: "Save"
   - Primary action that commits changes

2. **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

3. **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:

1. **Tab Key** - Moves focus to the next focusable element
2. **Shift+Tab (BackTab)** - Moves focus to the previous focusable element
3. **At the End** - Tab cycles back to the first element
4. **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

1. **Layout Structure** - All screens: Title (top) → Content (middle) → Buttons (bottom)
2. **Title Format** - Bold (`[::b]`), centered, dynamic colors enabled
3. **Tables** - Fixed headers (row 0), borders enabled, selectable rows
4. **Buttons** - Include keyboard shortcuts in labels (e.g., "Back [b]")
5. **Forms** - Button order: Save, Delete (if edit), Back
6. **Destructive Actions** - Always show confirmation dialogs
7. **ESC Key** - All screens support ESC to go back
8. **Action Buttons** - Positioned before Back button, in logical order
9. **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:** `btnFlex` for button containers, `flex` for 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

1. **Delete Confirmations** - Required for all destructive actions
   - Show item name in confirmation text
   - Buttons: "Cancel", "Delete"
   - ESC key dismisses dialog

2. **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

3. **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:

1. **After Save** - Remove and recreate the previous screen to display updated data
2. **After Delete** - Remove and recreate the previous screen to display remaining data
3. **After Cancel/Back** - Remove and recreate the previous screen (data may have changed)
4. **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 `SchemaEditor` struct, 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

1. **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

2. **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):**
```go
form.AddButton("Save", func() {
    schema := &models.Schema{Name: name, Description: desc, ...}
    se.db.Schemas = append(se.db.Schemas, schema)
})
```

**Good (Using Dataops Methods):**
```go
form.AddButton("Save", func() {
    se.CreateSchema(name, description)
})
```

#### Editing Existing Items

**Bad (Modifying Data in onChange Callbacks):**
```go
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):**
```go
// 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:**
1. **Deferred Changes** - Changes only apply when Save is clicked
2. **Cancellable** - Back button discards changes without saving
3. **Handles Renames** - Original name preserved to update map keys correctly
4. **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)
