Feature/add image map editor

This commit is contained in:
dmytro
2026-07-10 08:47:27 +00:00
committed by Igor Martyniuk
parent 1dde907313
commit 2232ef0029
22 changed files with 2099 additions and 35 deletions
+8 -3
View File
@@ -1,6 +1,8 @@
# File Manager Module
The File Manager module provides authenticated file browsing and file operations for the admin app. It has a backend API for storage operations and a frontend UI for browsing, previewing, uploading, renaming, deleting, duplicating, and editing supported files.
The File Manager module provides authenticated file browsing and file operations for the admin app.
It has a backend API for storage operations and a frontend UI for browsing, previewing, uploading,
renaming, deleting, duplicating, and editing supported files.
## Source Map
@@ -31,6 +33,7 @@ The File Manager module provides authenticated file browsing and file operations
- Rename, delete, and duplicate entries.
- Search entries.
- Open an image editor for image files.
- Create and edit image map zones for supported image files.
- Pick files through reusable frontend picker components.
- Insert files into RichText editor through reusable frontend picker components.
- Use local filesystem storage or S3-compatible storage through Adonis Drive.
@@ -72,7 +75,8 @@ type FolderEntry = {
};
```
The frontend maps DTOs into frontend entities and adds UI-oriented metadata such as `parent` and `extension`.
The frontend maps DTOs into frontend entities and adds UI-oriented metadata such as `parent` and
`extension`.
## Ownership Rules
@@ -80,7 +84,8 @@ The frontend maps DTOs into frontend entities and adds UI-oriented metadata such
- Frontend owns navigation, selection, view settings, operation progress, and user interactions.
- React Query owns server state in the frontend.
- MobX stores own local UI and operation state in the frontend.
- Storage adapters must implement `storage_service_interface.ts`; callers should depend on that interface, not a concrete disk implementation.
- Storage adapters must implement `storage_service_interface.ts`; callers should depend on that
interface, not a concrete disk implementation.
- The active storage adapter is selected by `DRIVE_DISK`.
## Common Change Guide
+62 -17
View File
@@ -1,8 +1,12 @@
# File Manager Frontend
The frontend module implements the admin file manager UI. It provides file browsing, previews, uploads, deletion, duplication, renaming, image editing, settings, and reusable file picker widgets.
The frontend module implements the admin file manager UI. It provides file browsing, previews,
uploads, deletion, duplication, renaming, image editing tools, image map tools, settings, and
reusable file picker widgets.
This module follows the general [React frontend architecture](../../apps-architecture/react-frontend/Readme.md) inside its own module boundary.
This module follows the general
[React frontend architecture](../../apps-architecture/react-frontend/Readme.md) inside its own
module boundary.
Source root:
@@ -66,12 +70,13 @@ Mounted module path:
Current child routes:
| Route | Page | Purpose |
| -------------------------------- | ------------------- | ----------------------------------- |
| `/file-manager/drive/explorer/*` | `DriveExplorerPage` | Browse folders and files. |
| `/file-manager/drive/viewer/-/*` | `DriveViewerPage` | View file details and preview. |
| `/file-manager/drive/settings` | `DriveSettingsPage` | Configure file-manager UI settings. |
| `/file-manager/editor/image/-/*` | `ImageEditorPage` | Edit image files. |
| Route | Page | Purpose |
| -------------------------------------- | ------------------- | ------------------------------------------- |
| `/file-manager/drive/explorer/*` | `DriveExplorerPage` | Browse folders and files. |
| `/file-manager/drive/viewer/-/*` | `DriveViewerPage` | View file details and preview. |
| `/file-manager/drive/settings` | `DriveSettingsPage` | Configure file-manager UI settings. |
| `/file-manager/tools/image-editor/-/*` | `ImageEditorPage` | Edit image files. |
| `/file-manager/tools/image-map/-/*` | `ImageMapPage` | Create and edit image map areas for images. |
Path helpers live in:
@@ -83,6 +88,19 @@ shared/path/leadingSlash.ts
Use these helpers instead of manually building file-manager URLs.
## Menu Structure
File Manager navigation is grouped into three top-level menu entries:
- `Drive` for file browsing, preview, and viewer-related flows.
- `Tools` for standalone file tools such as image editing and image map editing.
- `Settings` for persisted file-manager UI settings.
The `Tools` group currently contains:
- `ImageEditorPage`
- `ImageMapPage`
## API Boundary
Raw backend calls are centralized in:
@@ -135,11 +153,13 @@ does three things:
2. Fetches entries with React Query.
3. Syncs loaded entries into `EntriesStore`.
`EntriesStore` is not the fetch owner. It is an index of loaded entries used by the sidebar tree, selection lookups, active entry lookup, and operation state.
`EntriesStore` is not the fetch owner. It is an index of loaded entries used by the sidebar tree,
selection lookups, active entry lookup, and operation state.
### Deep Links
When opening a nested folder directly, `useEntries()` preloads ancestor folders through React Query. This keeps the sidebar tree and entry index usable for paths like:
When opening a nested folder directly, `useEntries()` preloads ancestor folders through React Query.
This keeps the sidebar tree and entry index usable for paths like:
```txt
/folder/subfolder/current
@@ -155,7 +175,8 @@ Mutations use React Query hooks:
- `useDuplicateFiles`
- `useUploadFile`
After a successful mutation, the UI updates local cache and stores directly. It does not invalidate entries queries after every operation.
After a successful mutation, the UI updates local cache and stores directly. It does not invalidate
entries queries after every operation.
This avoids unnecessary refetches when many items are created, deleted, or uploaded in sequence.
@@ -175,7 +196,8 @@ removeEntriesFromCache(paths);
renameEntryInCache(prevPath, renamedEntry);
```
These helpers update existing React Query cache data in memory. They do not trigger a network request.
These helpers update existing React Query cache data in memory. They do not trigger a network
request.
Important behavior:
@@ -184,7 +206,8 @@ Important behavior:
- Deleted entries are removed from all cached entry pages.
- Renamed entries are updated across cached entry pages.
Tradeoff: because the module avoids refetching, exact backend sort order may not be perfect after local cache insertion until the folder is naturally refetched or reloaded.
Tradeoff: because the module avoids refetching, exact backend sort order may not be perfect after
local cache insertion until the folder is naturally refetched or reloaded.
## Stores
@@ -303,7 +326,8 @@ Use:
const { entriesStore, explorerStore } = useDrive();
```
`SettingsProvider` owns persisted settings such as view mode, compact mode, sidebar visibility, and grid size.
`SettingsProvider` owns persisted settings such as view mode, compact mode, sidebar visibility, and
grid size.
## Pages And Widgets
@@ -349,6 +373,24 @@ view/widgets/ImageEditor/helpers.ts
This prevents `view` code from importing from `pages`.
### `ImageMapPage`
Image map page. Uses:
```ts
useGetFile();
useGetRawFile();
```
Image map config and helpers live in the widget layer:
```txt
view/widgets/ImageEditor/config.ts
view/widgets/ImageEditor/helpers.ts
```
This prevents `view` code from importing from `pages`.
### `FilePickerDialog`
Reusable picker widgets live in:
@@ -357,7 +399,8 @@ Reusable picker widgets live in:
view/widgets/FilePickerDialog/
```
Keep picker behavior feature-scoped, but pass reusable UI state through props and context instead of coupling low-level UI components to page-level stores.
Keep picker behavior feature-scoped, but pass reusable UI state through props and context instead of
coupling low-level UI components to page-level stores.
## View Layer Rules
@@ -371,7 +414,8 @@ Lower-level reusable UI components should stay prop-driven. Examples:
- `FileManagerFileIcon`
- `FilePreview`
Do not import backend DTOs into view components. View components should consume frontend entities and props.
Do not import backend DTOs into view components. View components should consume frontend entities
and props.
## File Types And Icons
@@ -425,7 +469,8 @@ Do not import MobX stores or providers inside `data/queries`.
4. Update `EntriesStore` if lookup state must change.
5. Update `data/queries/cache.ts` helpers if visible query cache must change.
Do not invalidate entries queries after each operation unless a full refetch is intentionally required.
Do not invalidate entries queries after each operation unless a full refetch is intentionally
required.
## Frontend Change Checklist