6.6 KiB
Custom File Dialogs Implementation
This document describes the custom file dialog implementations for the desktop-angular project. Both dialogs are native Electron BrowserWindows that provide file browsing and saving capabilities with customizable styling and filtering.
Overview
The custom file dialog replaces the system file dialog with a custom implementation that:
- Opens in a specific directory (configs folder)
- Supports file filtering by extension
- Has customizable colors and styling
- Provides a file browser interface
- Returns the same data structure as the system dialog
Files Added
src/main/open-dialog.html
Purpose: HTML/CSS/JS interface for the file open dialog Features:
- File browser with directory navigation
- File filtering by extension
- Customizable colors via CSS variables
- Double-click to open files
- Path input with browse functionality
- File icons based on extension
- File size display
- File preview - Shows first 500 characters of selected files
src/main/save-dialog.html
Purpose: HTML/CSS/JS interface for the file save dialog Features:
- File name input with validation
- Directory path selection
- Files list - Shows all files in current directory (no filtering)
- File type filtering
- Customizable colors via CSS variables
- Filename validation (invalid characters, reserved names)
- Browse button - Opens system directory picker
src/main/main.js
(Updated)
New Function: openCustomFileDialog(config)
- Creates a modal BrowserWindow (800x600)
- Loads the open-dialog.html interface
- Handles IPC communication with the dialog
- Returns file selection results
New IPC Handler: dialog:customFile
- Accepts configuration for the dialog
- Returns file selection result
API Usage
From Angular Component
const result = await this.ipc.showCustomFileDialog({
title: "Open Configuration File",
defaultPath: "/path/to/configs",
filters: [
{
name: "YAML Files",
extensions: ["yaml", "yml", "txt"]
},
{
name: "All Files",
extensions: ["*"]
}
],
colors: {
background: "#aa1c3a",
text: "#ffffff",
buttonBg: "#ffffff",
buttonText: "#aa1c3a",
border: "rgba(255,255,255,0.2)"
}
});
if (!result.canceled) {
console.log("Selected file:", result.filePath);
console.log("File content:", result.content);
}
Configuration Schema
interface FileDialogConfig {
title?: string; // Dialog title
defaultPath?: string; // Initial directory path
filters?: Array<{ // File type filters
name: string; // Filter name (e.g., "YAML Files")
extensions: string[]; // File extensions (e.g., ["yaml", "yml"])
}>;
colors?: { // Custom colors
background?: string; // Dialog background
text?: string; // Text color
buttonBg?: string; // Button background
buttonText?: string; // Button text color
border?: string; // Border color
};
}
Result Schema
interface FileDialogResult {
canceled: boolean; // True if dialog was canceled
filePath?: string; // Selected file path (if not canceled)
content?: string; // File content (if not canceled)
}
Features
File Browser
- Directory Navigation: Click folders to navigate
- File Selection: Click files to select, double-click to open
- Path Input: Type path manually and press Enter
- Browse Button: Alternative way to navigate directories
File Filtering
- Extension-based: Filters files by extension
- Multiple Filters: Support for multiple filter groups
- Wildcard Support: Use "*" for all files
Styling
- CSS Variables: Customizable via CSS custom properties
- Theme Matching: Default colors match app footer theme
- Responsive: Adapts to window resizing
File Icons
- Extension-based: Different icons for different file types
- Fallback: Default document icon for unknown types
Integration
Current Usage
The custom file dialog is automatically used by the file:open
IPC handler:
- Opens in the configs directory
- Filters for YAML/encrypted/text files
- Uses app theme colors
Manual Usage
You can also use it directly:
// From any Angular component
const result = await this.ipc.showCustomFileDialog({
title: "Select Image",
defaultPath: os.homedir(),
filters: [
{ name: "Images", extensions: ["png", "jpg", "gif"] }
]
});
Advantages Over System Dialog
- Guaranteed Path: Always opens in the correct directory
- Custom Styling: Matches application theme
- File Content: Returns file content automatically
- Cross-platform: Consistent behavior across platforms
- Customizable: Easy to modify appearance and behavior
File Structure
src/main/
├── open-dialog.html # Custom file dialog interface
├── main.js # Updated with dialog functions
└── preload.js # Updated with API exposure
src/frontend/src/app/
└── ipc.service.ts # Updated with dialog wrapper
Technical Details
Window Configuration
- Size: 800x600 pixels (resizable)
- Modal: Always on top of parent window
- Frameless: Custom window chrome
- Node Integration: Enabled for file system access
File System Access
- Read Directory: Lists files and folders
- Read Files: Loads file content as UTF-8
- Path Validation: Checks if paths exist and are accessible
- Error Handling: Graceful handling of permission errors
IPC Communication
- Config Channel:
file-dialog:config
- sends dialog configuration - Result Channel:
file-dialog:result
- returns selection result - Directory Picker:
dialog:showDirectoryPicker
- system directory selection - Async/Await: Promise-based API for easy integration
Recent Updates
File Open Dialog
- File Preview: Added preview section showing first 500 characters of selected files
- Smart Preview: Only shows preview for text files under 1MB
- Preview Styling: Monospace font with scrollable content area
File Save Dialog
- Files List: Replaced content preview with list of files in current directory
- All Files Shown: Shows all files without filtering by extension
- Browse Button: Now opens system directory picker dialog
- Directory Navigation: Click directories in file list to navigate
- File Information: Shows file size and type icons
This implementation provides a reliable, customizable file dialog that integrates seamlessly with the application's design and functionality.