Easy Email Pro Asset Manager
The easy-email-pro-asset-manager package provides a comprehensive file management component for uploading, organizing, and selecting assets (images, files) within the email editor. It supports folder structures, file previews, image editing, and drag-and-drop uploads.
Overview​
The Asset Manager is a modal-based component that allows users to:
- Browse and navigate through folders and files
- Upload files via drag-and-drop or file selection
- Create and manage folders
- Preview images and files
- Edit images (crop, resize, rotate)
- Delete files and folders
- Select files for use in email templates
Installation​
pnpm install easy-email-pro-asset-manager
Component API​
AssetManager​
The main component for file management.
import { AssetManager } from "easy-email-pro-asset-manager";
<AssetManager {...assetManagerProps} />
AssetManagerProps​
interface AssetManagerProps {
// File type restrictions (e.g., "image/*", "image/png,image/jpeg")
accept?: string;
// Fetch files and folders from server
request: (folderId?: string) => Promise<Array<FileItem | FolderItem>>;
// Modal title
title?: string;
// Upload file to server, returns file URL
upload: (blob: Blob) => Promise<string>;
// Create a new file record
onCreateFile: (params: {
name: string;
url: string;
parentFolderId: string | null;
}) => Promise<FileItem>;
// Delete a file
onDeleteFile: (params: { id: string }) => Promise<boolean>;
// Delete a folder
onDeleteFolder: (params: { id: string }) => Promise<boolean>;
// Update file metadata
onUpdateFile: (item: FileItem) => Promise<FileItem>;
// Update folder metadata
onUpdateFolder: (item: FolderItem) => Promise<FolderItem>;
// Create a new folder
onCreateFolder: (params: {
name: string;
parentFolderId: string | null;
}) => Promise<FolderItem>;
// Callback when a file is selected
onSelect: (url: string) => void;
// Control modal visibility
visible?: boolean;
setVisible: React.Dispatch<React.SetStateAction<boolean>>;
// Show files that don't match accept filter
showUnacceptedFile?: boolean;
// Enable/disable folder creation
addFolderEnabled?: boolean;
}
FileItem​
interface FileItem {
id: string;
url: string;
type: "FILE";
name: string;
parentFolderId: string | null;
thumbnail?: string; // Optional thumbnail URL for images
}
FolderItem​
interface FolderItem {
id: string;
name: string;
type: "FOLDER";
parentFolderId: string | null;
thumbnail?: string; // Optional folder icon
count?: number; // Number of items in folder
}
Usage​
Basic Integration​
import React, { useState } from "react";
import { AssetManager, FileItem, FolderItem } from "easy-email-pro-asset-manager";
function MyEditor() {
const [assetManagerVisible, setAssetManagerVisible] = useState(false);
// Fetch files and folders from your backend
const fetchAssets = async (folderId?: string): Promise<Array<FileItem | FolderItem>> => {
const response = await fetch(`/api/assets${folderId ? `?folderId=${folderId}` : ""}`);
return response.json();
};
// Upload file to your backend
const uploadFile = async (blob: Blob): Promise<string> => {
const formData = new FormData();
formData.append("file", blob);
const response = await fetch("/api/upload", {
method: "POST",
body: formData,
});
const data = await response.json();
return data.url; // Return the file URL
};
// Create file record in your database
const createFile = async (params: {
name: string;
url: string;
parentFolderId: string | null;
}): Promise<FileItem> => {
const response = await fetch("/api/files", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params),
});
return response.json();
};
// Delete file
const deleteFile = async (params: { id: string }): Promise<boolean> => {
const response = await fetch(`/api/files/${params.id}`, {
method: "DELETE",
});
return response.ok;
};
// Delete folder
const deleteFolder = async (params: { id: string }): Promise<boolean> => {
const response = await fetch(`/api/folders/${params.id}`, {
method: "DELETE",
});
return response.ok;
};
// Update file
const updateFile = async (item: FileItem): Promise<FileItem> => {
const response = await fetch(`/api/files/${item.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(item),
});
return response.json();
};
// Update folder
const updateFolder = async (item: FolderItem): Promise<FolderItem> => {
const response = await fetch(`/api/folders/${item.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(item),
});
return response.json();
};
// Create folder
const createFolder = async (params: {
name: string;
parentFolderId: string | null;
}): Promise<FolderItem> => {
const response = await fetch("/api/folders", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params),
});
return response.json();
};
// Handle file selection
const handleSelect = (url: string) => {
console.log("Selected file:", url);
// Use the selected file URL in your email template
setAssetManagerVisible(false);
};
return (
<>
<button onClick={() => setAssetManagerVisible(true)}>
Open Asset Manager
</button>
<AssetManager
accept="image/*"
request={fetchAssets}
upload={uploadFile}
onCreateFile={createFile}
onDeleteFile={deleteFile}
onDeleteFolder={deleteFolder}
onUpdateFile={updateFile}
onUpdateFolder={updateFolder}
onCreateFolder={createFolder}
onSelect={handleSelect}
visible={assetManagerVisible}
setVisible={setAssetManagerVisible}
addFolderEnabled={true}
/>
</>
);
}
Integration with Email Editor​
The Asset Manager is typically integrated with the email editor's image upload functionality:
import { EmailEditorProvider } from "easy-email-pro-editor";
import { Retro } from "easy-email-pro-theme";
import { AssetManager } from "easy-email-pro-asset-manager";
import { useState } from "react";
function EmailEditor() {
const [assetManagerVisible, setAssetManagerVisible] = useState(false);
const [selectedImageUrl, setSelectedImageUrl] = useState<string | null>(null);
const config = Retro.useCreateConfig({
onUpload: async (file: Blob) => {
// Open asset manager instead of direct upload
setAssetManagerVisible(true);
// Return a placeholder or handle differently
return "";
},
// ... other config
});
return (
<>
<EmailEditorProvider {...config}>
<Retro.Layout />
</EmailEditorProvider>
<AssetManager
accept="image/*"
request={fetchAssets}
upload={uploadFile}
onCreateFile={createFile}
onDeleteFile={deleteFile}
onDeleteFolder={deleteFolder}
onUpdateFile={updateFile}
onUpdateFolder={updateFolder}
onCreateFolder={createFolder}
onSelect={(url) => {
setSelectedImageUrl(url);
setAssetManagerVisible(false);
// Update the editor with the selected image
}}
visible={assetManagerVisible}
setVisible={setAssetManagerVisible}
/>
</>
);
}
Features​
File Type Restrictions​
Use the accept prop to restrict file types:
// Only images
<AssetManager accept="image/*" {...props} />
// Specific image types
<AssetManager accept="image/png,image/jpeg,image/gif" {...props} />
// PDF files
<AssetManager accept="application/pdf" {...props} />
Folder Navigation​
The Asset Manager supports hierarchical folder structures. Users can:
- Navigate into folders by clicking on them
- Use breadcrumbs to navigate back
- Create new folders
- Delete empty folders
Image Editing​
When an image is selected, users can:
- Rename: Change the file name
- Resize: Adjust image dimensions
- Crop: Crop the image to a specific area
- Rotate: Rotate the image
- Delete: Remove the image
Drag and Drop Upload​
Users can drag and drop files directly into the Asset Manager window for quick uploads.
Permission Control​
The Asset Manager respects the editor's feature flags. It will not render if the FILE_MANAGER feature is disabled:
import { EditorAuth } from "easy-email-pro-core";
// Check if file manager is enabled
const isEnabled = EditorAuth.getFeatureEnabled("FILE_MANAGER");
Backend Requirements​
The Asset Manager requires a backend API that handles:
- File Upload: Accept file uploads and return file URLs
- File Listing: Return lists of files and folders for a given folder ID
- CRUD Operations: Create, read, update, and delete files and folders
Example Backend API Structure​
GET /api/assets?folderId=<id> - List files and folders
POST /api/upload - Upload file
POST /api/files - Create file record
PUT /api/files/:id - Update file
DELETE /api/files/:id - Delete file
POST /api/folders - Create folder
PUT /api/folders/:id - Update folder
DELETE /api/folders/:id - Delete folder
Best Practices​
- File Organization: Encourage users to organize files into folders for better management
- Thumbnail Generation: Generate thumbnails for images to improve loading performance
- File Size Limits: Implement file size limits on the backend
- Error Handling: Provide clear error messages for failed operations
- Loading States: Show loading indicators during file operations
Notes​
- The Asset Manager is a modal component that overlays the editor
- File operations are asynchronous and require backend integration
- The component automatically handles file type validation based on the
acceptprop - Image editing features require the
cropperjslibrary (already included as a dependency)