adde desktop-angular
This commit is contained in:
230
desktop-angular/CUSTOM_FILE_DIALOG.md
Normal file
230
desktop-angular/CUSTOM_FILE_DIALOG.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# 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.
|
Reference in New Issue
Block a user