# Modal Dialog Implementation Documentation ## Overview This document describes the implementation of two configurable modal dialog systems for the desktop-angular project: 1) Angular in-app modal component (already integrated into the UI) 2) Electron-native modal window (opens a frameless BrowserWindow as a dialog) Both allow variable questions, 1-3 buttons with custom labels, and return metadata for the clicked button. The Electron-native dialog additionally supports color customization for background, text, button colors per dialog. ## Files Added/Modified ### 1. New Files Created #### `src/frontend/src/app/modal.service.ts` **Purpose**: Core service for managing modal dialogs **What it does**: - Defines interfaces for modal configuration (`ModalConfig`, `ModalButton`, `ModalResult`) - Provides `ModalService` with methods to show/hide modals - Returns promises that resolve with button click results - Includes convenience methods for common dialog types **Key Features**: - `show(config: ModalConfig): Promise` - Main method to show custom modals - `showConfirm(title, message): Promise` - Yes/No confirmation dialog - `showYesNoCancel(title, message): Promise<'yes'|'no'|'cancel'>` - Three-option dialog - `showInfo(title, message): Promise` - Information dialog with OK button #### `src/frontend/src/app/modal.component.ts` **Purpose**: Angular component that renders the modal dialog **What it does**: - Displays modal overlay and dialog box - Renders configurable buttons with different styles - Handles button clicks and communicates with service - Manages modal visibility through service subscription **Key Features**: - Standalone Angular component - Reactive to service state changes - Supports button styling (primary, secondary, danger) - Overlay click handling (currently disabled) #### `src/frontend/src/app/modal.component.scss` **Purpose**: Styling for the modal dialog **What it does**: - Creates modal overlay with semi-transparent background - Styles dialog box with footer-matching colors (#aa1c3a) - Implements button styles matching the app's footer buttons - Provides responsive design for mobile devices **Key Features**: - Modal overlay with backdrop - Dialog box with header, body, and footer sections - Button styles matching app footer (white background, red text) - Three button style variants: primary, secondary, danger - Mobile-responsive design ### 2. Modified Files #### `src/frontend/src/app/root.component.ts` **Changes Made**: - Added imports for `ModalService` and `ModalComponent` - Added `ModalComponent` to component imports - Injected `ModalService` in constructor - Added example methods demonstrating modal usage: - `showCustomModal()` - Shows 3-button custom dialog - `showConfirmDialog()` - Shows Yes/No confirmation - `showYesNoCancelDialog()` - Shows Yes/No/Cancel dialog - `showInfoDialog()` - Shows information dialog #### `src/frontend/src/app/root.component.html` **Changes Made**: - Added `` component to template - Added test buttons in form section to demonstrate modal functionality - Test buttons include: Custom Modal, Confirm Dialog, Yes/No/Cancel, Info Dialog ### 3. Electron-Native Modal (Alternative) To support invoking modals from the Electron main process with fully customizable styling, we added an alternative modal implementation which opens a dedicated `BrowserWindow` as a modal dialog. #### New Files - `src/main/modal.html` - HTML/CSS/JS for a self-contained modal page - Receives configuration over IPC (`custom-modal:config`) - Renders title, message and up to 3 buttons - Colors can be customized via CSS variables populated from config: - background, text, buttonBg, buttonText, secondaryBg, secondaryText - Each button can define its own inline style overrides via `buttonStyles` map #### Changes in `src/main/main.js` - Added `openCustomModalWindow(config)` helper to create a modal `BrowserWindow` - Loads `modal.html` and sends the configuration after load - Listens for `custom-modal:result` IPC to resolve the clicked button - Exposed IPC handler `dialog:custom` to open the modal from renderer/preload #### Changes in `src/preload/preload.js` - Exposed `showNativeModal(config)` in `window.api` via `ipcRenderer.invoke('dialog:custom')` #### Changes in `src/frontend/src/app/ipc.service.ts` - Added wrapper method `showNativeModal(config)` to call the Electron-native modal from Angular code #### Usage Example (from Angular renderer) ```ts const result = await this.ipc.showNativeModal({ title: 'System Dialog', message: 'Proceed with operation?', buttons: [ { id: 'yes', label: 'Yes', style: 'primary' }, { id: 'no', label: 'No', style: 'secondary' }, { id: 'cancel', label: 'Cancel', style: 'danger' } ], colors: { background: '#aa1c3a', text: '#ffffff', buttonBg: '#ffffff', buttonText: '#aa1c3a', secondaryBg: 'rgba(255,255,255,0.1)', secondaryText: '#ffffff' }, buttonStyles: { yes: { bg: '#ffffff', text: '#aa1c3a' }, no: { bg: 'rgba(255,255,255,0.1)', text: '#ffffff' }, cancel: { bg: '#e53935', text: '#fff' } } }); // result => { buttonId: 'yes' | 'no' | 'cancel', buttonIndex: number, buttonLabel?: string } ``` ## Usage Examples ### Basic Custom Modal ```typescript const result = await this.modal.show({ title: 'Custom Dialog', message: 'Choose an option:', buttons: [ { id: 'option1', label: 'Option 1', style: 'primary' }, { id: 'option2', label: 'Option 2', style: 'secondary' }, { id: 'cancel', label: 'Cancel', style: 'danger' } ] }); console.log(`Clicked: ${result.buttonLabel} (ID: ${result.buttonId})`); ``` ### Confirmation Dialog ```typescript const confirmed = await this.modal.showConfirm( 'Delete Item', 'Are you sure you want to delete this item?' ); if (confirmed) { // Proceed with deletion } ``` ### Yes/No/Cancel Dialog ```typescript const result = await this.modal.showYesNoCancel( 'Save Changes', 'Do you want to save your changes?' ); switch (result) { case 'yes': /* Save and continue */ break; case 'no': /* Continue without saving */ break; case 'cancel': /* Cancel operation */ break; } ``` ### Information Dialog ```typescript await this.modal.showInfo( 'Success', 'Your changes have been saved successfully.' ); ``` ## Button Styles The modal supports three button styles: 1. **Primary** (`style: 'primary'`): White background, red text - matches footer buttons 2. **Secondary** (`style: 'secondary'`): Transparent background, white text 3. **Danger** (`style: 'danger'`): Red background, white text ## Styling Details ### Color Scheme - **Background**: #aa1c3a (matches footer) - **Text**: White (#ffffff) - **Primary Buttons**: White background, red text - **Secondary Buttons**: Transparent with white text - **Danger Buttons**: Red background (#e53935) ### Layout - Modal overlay covers entire screen - Dialog is centered and responsive - Maximum width: 500px - Mobile-friendly with stacked buttons on small screens ## Integration Points ### Service Integration The `ModalService` is provided at root level, making it available throughout the application: ```typescript constructor(private modal: ModalService) {} ``` ### Component Integration The `ModalComponent` is imported in the main component and added to the template: ```html ``` ## Testing The implementation includes test buttons in the form section that demonstrate all modal types: - Custom Modal: Shows 3-button dialog with different styles - Confirm Dialog: Shows Yes/No confirmation - Yes/No/Cancel: Shows 3-option dialog - Info Dialog: Shows information with OK button ## Future Enhancements Potential improvements could include: 1. Modal animations (fade in/out) 2. Keyboard navigation support 3. Escape key to close 4. Custom modal sizes 5. Modal stacking support 6. Form inputs within modals 7. Optional keyboard shortcuts (Enter/Esc) 8. Focus management and initial focus button ## Dependencies The modal system requires: - Angular CommonModule - RxJS for reactive programming - No external dependencies ## File Structure ``` еуче src/frontend/src/app/ ├── modal.service.ts # Service for modal management ├── modal.component.ts # Modal component ├── modal.component.scss # Modal styles ├── root.component.ts # Updated with modal integration └── root.component.html # Updated with modal component ``` This implementation provides a complete, reusable modal dialog system that matches the application's design language and provides flexible configuration options for various dialog types.