231 lines
6.6 KiB
Markdown
231 lines
6.6 KiB
Markdown
# 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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
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:
|
|
```typescript
|
|
// 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
|
|
|
|
1. **Guaranteed Path**: Always opens in the correct directory
|
|
2. **Custom Styling**: Matches application theme
|
|
3. **File Content**: Returns file content automatically
|
|
4. **Cross-platform**: Consistent behavior across platforms
|
|
5. **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.
|