@flusys/ng-storage 1.1.1-beta → 1.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +36 -623
  2. package/fesm2022/flusys-ng-storage-file-manager-form.component-DhqZmpuX.mjs +671 -0
  3. package/fesm2022/flusys-ng-storage-file-manager-form.component-DhqZmpuX.mjs.map +1 -0
  4. package/fesm2022/flusys-ng-storage-file-manager-list.component-nZDj1UfS.mjs +464 -0
  5. package/fesm2022/flusys-ng-storage-file-manager-list.component-nZDj1UfS.mjs.map +1 -0
  6. package/fesm2022/flusys-ng-storage-folder-form.component-Bru9NQyr.mjs +218 -0
  7. package/fesm2022/flusys-ng-storage-folder-form.component-Bru9NQyr.mjs.map +1 -0
  8. package/fesm2022/flusys-ng-storage-folder-list.component-fuJMWYWZ.mjs +263 -0
  9. package/fesm2022/flusys-ng-storage-folder-list.component-fuJMWYWZ.mjs.map +1 -0
  10. package/fesm2022/flusys-ng-storage-storage-config-form.component-Da-pWR7d.mjs +891 -0
  11. package/fesm2022/flusys-ng-storage-storage-config-form.component-Da-pWR7d.mjs.map +1 -0
  12. package/fesm2022/flusys-ng-storage-storage-config-list.component-D59X4sae.mjs +288 -0
  13. package/fesm2022/flusys-ng-storage-storage-config-list.component-D59X4sae.mjs.map +1 -0
  14. package/fesm2022/flusys-ng-storage.mjs +679 -321
  15. package/fesm2022/flusys-ng-storage.mjs.map +1 -1
  16. package/package.json +11 -10
  17. package/types/flusys-ng-storage.d.ts +179 -178
  18. package/fesm2022/flusys-ng-storage-file-manager-form.component-H3OZS0SW.mjs +0 -715
  19. package/fesm2022/flusys-ng-storage-file-manager-form.component-H3OZS0SW.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-storage-file-manager-list.component-4pb6TafD.mjs +0 -475
  21. package/fesm2022/flusys-ng-storage-file-manager-list.component-4pb6TafD.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-storage-folder-form.component-DQ0QY7P0.mjs +0 -253
  23. package/fesm2022/flusys-ng-storage-folder-form.component-DQ0QY7P0.mjs.map +0 -1
  24. package/fesm2022/flusys-ng-storage-folder-list.component-D-oMaEgl.mjs +0 -267
  25. package/fesm2022/flusys-ng-storage-folder-list.component-D-oMaEgl.mjs.map +0 -1
  26. package/fesm2022/flusys-ng-storage-storage-config-form.component-CjIAxfHC.mjs +0 -546
  27. package/fesm2022/flusys-ng-storage-storage-config-form.component-CjIAxfHC.mjs.map +0 -1
  28. package/fesm2022/flusys-ng-storage-storage-config-list.component-jHk8O9Mx.mjs +0 -328
  29. package/fesm2022/flusys-ng-storage-storage-config-list.component-jHk8O9Mx.mjs.map +0 -1
package/README.md CHANGED
@@ -1,657 +1,70 @@
1
- # Storage Package Guide
1
+ # @flusys/ng-storage
2
2
 
3
- > **Package:** `@flusys/ng-storage`
4
- > **Type:** File storage management with upload, folder organization, and multi-provider support
3
+ File storage UI for FLUSYS Angular apps — upload, file manager pages, presigned URL fetching, and provider adapter registration for Local, S3, Azure, and SFTP backends.
5
4
 
6
- ---
7
-
8
- ## Overview
5
+ [![npm version](https://img.shields.io/npm/v/@flusys/ng-storage.svg)](https://www.npmjs.com/package/@flusys/ng-storage)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
7
 
10
- `@flusys/ng-storage` provides complete file storage management:
11
-
12
- - **File Upload** - Single and multiple file uploads with image compression
13
- - **File Manager** - CRUD operations for file metadata with presigned URLs
14
- - **Folder Management** - Folder organization for files
15
- - **Storage Configs** - Multi-provider configurations (AWS S3, Azure Blob, SFTP, Local)
16
- - **Company Scoping** - Automatic company-scoped queries (when enabled)
17
- - **Lazy Loading** - All page components are lazy-loaded via routes
8
+ ---
18
9
 
19
- ### Package Hierarchy
10
+ ## Installation
20
11
 
12
+ ```bash
13
+ npm install @flusys/ng-storage @flusys/ng-core @flusys/ng-shared
21
14
  ```
22
- @flusys/ng-core <- Foundation (BaseApiService, APP_CONFIG)
23
- |
24
- @flusys/ng-shared <- Shared utilities (ApiResourceService, IBaseEntity)
25
- |
26
- @flusys/ng-layout <- Layout (LAYOUT_AUTH_STATE for company context)
27
- |
28
- @flusys/ng-storage <- File storage (THIS PACKAGE)
29
- ```
30
-
31
- ### Company Context
32
15
 
33
- Storage components use `LAYOUT_AUTH_STATE` from `@flusys/ng-layout` for company context. This follows the Provider Interface Pattern - ng-storage depends on ng-layout's abstraction, not ng-auth directly.
16
+ ## 1. Register Providers
34
17
 
35
18
  ```typescript
36
- import { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';
37
-
38
- private readonly companyContext = inject(LAYOUT_AUTH_STATE);
39
-
40
- readonly currentCompanyName = computed(
41
- () => this.companyContext.currentCompanyInfo()?.name ?? DEFAULT_APP_NAME,
42
- );
43
- ```
44
-
45
- ---
46
-
47
- ## Package Architecture
19
+ // app.config.ts
20
+ import { provideStorageProviders } from '@flusys/ng-storage';
48
21
 
22
+ export const appConfig: ApplicationConfig = {
23
+ providers: [
24
+ ...provideStorageProviders(), // registers FILE_PROVIDER for ng-shared's file picker and FileUrlService
25
+ ],
26
+ };
49
27
  ```
50
- ng-storage/
51
- ├── enums/
52
- │ ├── file-location.enum.ts # FileLocationEnum, ImageFormat
53
- │ └── public-api.ts
54
- ├── interfaces/
55
- │ ├── file-manager.interface.ts # IFileManager, ICreateFileManagerDto, IUpdateFileManagerDto
56
- │ ├── folder.interface.ts # IFolder, ICreateFolderDto, IUpdateFolderDto
57
- │ ├── storage-config.interface.ts # IStorageConfig, provider-specific configs
58
- │ ├── upload.interface.ts # IUploadOptionsDto, IUploadedFileInfo
59
- │ └── public-api.ts
60
- ├── services/
61
- │ ├── file-manager-api.service.ts # File metadata CRUD + presigned URLs
62
- │ ├── folder-api.service.ts # Folder CRUD
63
- │ ├── storage-config-api.service.ts # Storage config CRUD
64
- │ └── upload.service.ts # File upload/delete operations
65
- ├── pages/
66
- │ ├── storage-container/
67
- │ │ └── storage-container.component.ts # Tab container (Files, Folders, Configs)
68
- │ ├── file-manager/
69
- │ │ ├── file-manager-list.component.ts
70
- │ │ └── file-manager-form.component.ts
71
- │ ├── folder/
72
- │ │ ├── folder-list.component.ts
73
- │ │ └── folder-form.component.ts
74
- │ └── storage-config/
75
- │ ├── storage-config-list.component.ts
76
- │ └── storage-config-form.component.ts
77
- ├── routes/
78
- │ └── storage.routes.ts
79
- └── public-api.ts
80
- ```
81
-
82
- ---
83
28
 
84
- ## Route Integration
29
+ `FILE_PROVIDER` is consumed by `FileSelectorComponent` and `FileUrlService` in `ng-shared`. Without this, file pickers in other packages (e.g., ng-form-builder, ng-email) will not work.
85
30
 
86
- ### Adding Storage Routes
31
+ ## 2. Add Storage Routes (Optional)
87
32
 
88
33
  ```typescript
89
34
  // app.routes.ts
35
+ import { STORAGE_ROUTES } from '@flusys/ng-storage';
36
+
90
37
  export const routes: Routes = [
91
38
  {
92
39
  path: 'storage',
93
- loadChildren: () =>
94
- import('@flusys/ng-storage').then((m) => m.STORAGE_ROUTES),
40
+ loadChildren: () => STORAGE_ROUTES,
95
41
  },
96
42
  ];
97
43
  ```
98
44
 
99
- ### Route Structure
100
-
101
- All routes are wrapped by `StorageContainerComponent` which provides tab navigation (Files, Folders, Configs).
102
-
103
- | Path | Component | Description |
104
- |------|-----------|-------------|
105
- | `/storage` | StorageContainerComponent | Container with tab navigation |
106
- | `/storage/files` | FileManagerListComponent | List all files (default) |
107
- | `/storage/files/new` | FileManagerFormComponent | Upload new file |
108
- | `/storage/files/:id` | FileManagerFormComponent | Edit file metadata |
109
- | `/storage/folders` | FolderListComponent | List all folders |
110
- | `/storage/folders/new` | FolderFormComponent | Create folder |
111
- | `/storage/folders/:id` | FolderFormComponent | Edit folder |
112
- | `/storage/configs` | StorageConfigListComponent | List storage configurations |
113
- | `/storage/configs/new` | StorageConfigFormComponent | Create storage config |
114
- | `/storage/configs/:id` | StorageConfigFormComponent | Edit storage config |
115
-
116
- Default redirect: `/storage` -> `/storage/files`
117
-
118
- ---
119
-
120
- ## Enums
45
+ Routes included (all protected by `permissionGuard`):
121
46
 
122
- ### FileLocationEnum
47
+ ## 4. Fetch File URLs (Critical Rule)
123
48
 
124
- Storage provider types (matches backend).
49
+ Never construct file URLs manually. Always use `FileUrlService` from `ng-shared` — the backend generates presigned, access-controlled URLs for all storage providers.
125
50
 
126
51
  ```typescript
127
- enum FileLocationEnum {
128
- LOCAL = 'local',
129
- AWS = 'aws',
130
- AZURE = 'azure',
131
- SFTP = 'sftp',
132
- }
133
- ```
134
-
135
- ### ImageFormat
136
-
137
- Image compression output formats.
138
-
139
- ```typescript
140
- enum ImageFormat {
141
- ORIGINAL = 'original',
142
- JPEG = 'jpeg',
143
- PNG = 'png',
144
- WEBP = 'webp',
145
- }
146
- ```
147
-
148
- ---
149
-
150
- ## Interfaces
52
+ import { FileUrlService } from '@flusys/ng-shared';
151
53
 
152
- ### Upload
153
-
154
- ```typescript
155
- interface IUploadOptionsDto {
156
- storageConfigId?: string; // Storage config to use (uses default if not set)
157
- folderPath?: string; // Target folder path
158
- maxWidth?: number; // Image max width (default: 1280)
159
- maxHeight?: number; // Image max height (default: 1280)
160
- quality?: number; // Image quality 1-100 (default: 85)
161
- format?: ImageFormat; // Output format
162
- compress?: boolean; // Enable compression (default: true)
163
- }
54
+ @Component({ ... })
55
+ export class MyComponent {
56
+ private readonly fileUrlService = inject(FileUrlService);
164
57
 
165
- interface IUploadedFileInfo {
166
- name: string; // Original filename
167
- key: string; // Storage key/path
168
- size: number; // File size in bytes
169
- contentType: string; // MIME type
58
+ async loadAvatar(fileId: string) {
59
+ // POST /file-manager/get-files → returns presigned URL
60
+ const files = await firstValueFrom(this.fileUrlService.getFileUrls([fileId]));
61
+ const url = files?.data?.[0]?.url ?? null;
62
+ }
170
63
  }
171
64
  ```
172
65
 
173
- ### File Manager
174
-
175
- ```typescript
176
- interface IFileManager {
177
- id: string;
178
- createdAt: Date;
179
- updatedAt: Date;
180
- name: string;
181
- contentType: string;
182
- size: string; // In KB (string)
183
- key: string; // File key/path in storage
184
- url: string | null; // Presigned URL (regenerated by backend)
185
- location: FileLocationEnum;
186
- storageConfigId: string | null;
187
- expiresAt: Date | null; // URL expiration time
188
- isPrivate: boolean;
189
- companyId?: string; // Only in company mode
190
- folderId?: string | null;
191
- }
192
-
193
- interface ICreateFileManagerDto {
194
- name: string;
195
- key: string;
196
- size: string;
197
- contentType: string;
198
- isPrivate: boolean;
199
- folderId?: string;
200
- storageConfigId?: string;
201
- location?: FileLocationEnum;
202
- }
203
-
204
- interface IUpdateFileManagerDto {
205
- id: string;
206
- name?: string;
207
- isPrivate?: boolean;
208
- folderId?: string | null;
209
- }
210
-
211
- // For fetching files with valid presigned URLs
212
- interface IGetFilesRequestDto { id: string; }
213
- interface IFilesResponseDto { id: string; name: string; contentType: string; url: string; }
214
- ```
215
-
216
- ### Folder
217
-
218
- ```typescript
219
- interface IFolder extends IBaseEntity {
220
- name: string;
221
- slug: string; // URL-friendly name
222
- companyId?: string | null;
223
- }
224
-
225
- interface ICreateFolderDto { name: string; }
226
- interface IUpdateFolderDto { id: string; name?: string; }
227
- ```
228
-
229
- ### Storage Config
230
-
231
- ```typescript
232
- interface IStorageConfig extends IBaseEntity {
233
- name: string;
234
- storage: FileLocationEnum;
235
- config: Record<string, any>; // Provider-specific configuration
236
- isActive: boolean; // Whether config is active and usable
237
- isDefault: boolean; // Set as default configuration
238
- companyId?: string | null;
239
- }
240
-
241
- interface ICreateStorageConfigDto {
242
- name: string;
243
- storage: FileLocationEnum;
244
- config: Record<string, any>;
245
- isActive?: boolean;
246
- isDefault?: boolean;
247
- }
248
-
249
- interface IUpdateStorageConfigDto {
250
- id: string;
251
- name?: string;
252
- storage?: FileLocationEnum;
253
- config?: Record<string, any>;
254
- isActive?: boolean;
255
- isDefault?: boolean;
256
- }
257
- ```
258
-
259
- ### Provider-Specific Configs
260
-
261
- These define the shape of `IStorageConfig.config` for each provider:
262
-
263
- ```typescript
264
- interface IAwsS3Config {
265
- region: string;
266
- bucket: string;
267
- accessKeyId: string;
268
- secretAccessKey: string;
269
- endpoint?: string; // Custom S3-compatible endpoint
270
- }
271
-
272
- interface IAzureBlobConfig {
273
- accountName: string;
274
- accountKey: string;
275
- containerName: string;
276
- }
277
-
278
- interface ISftpConfig {
279
- host: string;
280
- port: number;
281
- username: string;
282
- password?: string;
283
- privateKey?: string;
284
- basePath: string;
285
- }
286
-
287
- interface ILocalStorageConfig {
288
- basePath: string;
289
- }
290
- ```
291
-
292
- ---
293
-
294
- ## Services
295
-
296
- All services are `providedIn: 'root'`. Company scoping is automatic when the company feature is enabled.
297
-
298
- ### UploadService
299
-
300
- Handles file upload and deletion. Extends `BaseApiService` (from ng-core).
301
-
302
- | Method | Endpoint | Description |
303
- |--------|----------|-------------|
304
- | `uploadSingleFile(file, options?)` | `POST /storage/upload/single-file` | Upload single file |
305
- | `uploadMultipleFiles(files, options?)` | `POST /storage/upload/multiple-file` | Upload multiple files (max 50) |
306
- | `deleteSingleFile(key, storageConfigId?)` | `POST /storage/upload/delete-single-file` | Delete single file from storage |
307
- | `deleteMultipleFiles(keys, storageConfigId?)` | `POST /storage/upload/delete-multiple-file` | Delete multiple files |
308
- | `getFileUrl(key)` | `GET /storage/upload/file/:key` | Get direct file download URL |
309
-
310
- Upload options are sent as **query parameters**, not form data:
311
-
312
- ```typescript
313
- // POST /storage/upload/single-file?storageConfigId=abc&folderPath=docs&compress=true
314
- this.uploadService.uploadSingleFile(file, {
315
- storageConfigId: 'abc',
316
- folderPath: 'docs',
317
- compress: true,
318
- quality: 85,
319
- format: ImageFormat.WEBP,
320
- });
321
- ```
322
-
323
- ### FileManagerApiService
324
-
325
- File metadata CRUD. Extends `ApiResourceService<IUpdateFileManagerDto, IFileManager>`.
326
-
327
- **Inherited CRUD methods** (from ApiResourceService): `insert`, `update`, `findById`, `getAll`, `delete` and their `*Async` variants.
328
-
329
- **Additional methods:**
330
-
331
- | Method | Endpoint | Description |
332
- |--------|----------|-------------|
333
- | `getFiles(fileIds)` | `POST /storage/file-manager/get-files` | Get files with valid presigned URLs |
334
- | `getFilesByFolder(folderId, page?, limit?)` | `POST /storage/file-manager/get-all` | Filter files by folder |
335
- | `getPrivateFiles(page?, limit?)` | `POST /storage/file-manager/get-all` | Filter by `isPrivate: true` |
336
-
337
- **Presigned URL pattern:** Always use `getFiles()` to get valid URLs. Backend regenerates expired presigned URLs for cloud storage.
338
-
339
- ```typescript
340
- const response = await firstValueFrom(
341
- this.fileService.getFiles(['file-id-1', 'file-id-2'])
342
- );
343
- // response.data → [{ id, name, contentType, url }]
344
- ```
345
-
346
- ### FolderApiService
347
-
348
- Folder CRUD. Extends `ApiResourceService<IUpdateFolderDto, IFolder>`. Standard CRUD operations only, no custom methods.
349
-
350
- ### StorageConfigApiService
351
-
352
- Storage provider configuration CRUD. Extends `ApiResourceService<IUpdateStorageConfigDto, IStorageConfig>`. Standard CRUD operations only, no custom methods.
353
-
354
- ---
355
-
356
- ## Components
357
-
358
- All components are standalone, use Angular 21 signal forms, and lazy-load via routes.
359
-
360
- ### StorageContainerComponent
361
-
362
- Main container with tab navigation between Files, Folders, and Configs sections. Uses inline CSS with theme variables (`--primary-color`, `--surface-ground`, etc.).
363
-
364
- **Selector:** `lib-storage-container`
66
+ Manual URL construction breaks with S3/Azure (presigned URLs expire) and does not enforce access control.
365
67
 
366
- ### List Components
367
-
368
- All list components share:
369
- - **Lazy pagination** via `p-datatable`
370
- - **Company info display** when company feature enabled (via `APP_CONFIG`)
371
- - **Delete confirmation** via `ConfirmationService`
372
- - **Signal-based state:** `isLoading`, `files`/`folders`/`configs`, `totalRecords`, `pageSize`, `currentPage`
373
-
374
- **FileManagerListComponent** additionally supports:
375
- - File content type icons (image, video, audio, PDF, Word, Excel, generic)
376
- - View file (opens presigned URL in new tab)
377
- - **Soft delete** - marks as deleted (recoverable)
378
- - **Permanent delete** - removes from storage provider (irreversible)
379
-
380
- ### Form Components
381
-
382
- All form components share:
383
- - **Signal Forms** using Angular 21 `form()` helper with `required()` validators
384
- - **Create/Edit mode** auto-detection based on route param (`:id`)
385
- - **Navigation** back to list on save/cancel
386
-
387
- **FileManagerFormComponent** additionally supports:
388
- - PrimeNG file upload with drag-drop
389
- - Storage config selection dropdown
390
- - Folder assignment
391
- - Auto-filling filename from uploaded file
392
-
393
- **StorageConfigFormComponent** has dynamic form fields based on selected provider:
394
- - AWS S3: region, bucket, accessKeyId, secretAccessKey, endpoint
395
- - Azure Blob: accountName, accountKey, containerName
396
- - SFTP: host, port, username, password, basePath
397
- - Local: basePath
398
- - **Active toggle** - enables/disables the configuration
399
- - **Set as Default toggle** - marks configuration as the default for uploads
400
-
401
- **Default Configuration:**
402
- When `isDefault: true`, this configuration will be used automatically when no `storageConfigId` is provided in upload requests.
403
-
404
- ---
405
-
406
- ## Usage Examples
407
-
408
- ### Upload a File
409
-
410
- ```typescript
411
- import { UploadService, ImageFormat } from '@flusys/ng-storage';
412
-
413
- private readonly uploadService = inject(UploadService);
414
-
415
- async uploadImage(file: File): Promise<IUploadedFileInfo | null> {
416
- const response = await firstValueFrom(
417
- this.uploadService.uploadSingleFile(file, {
418
- storageConfigId: 'my-config-id',
419
- folderPath: 'images/avatars',
420
- compress: true,
421
- maxWidth: 800,
422
- maxHeight: 800,
423
- quality: 80,
424
- format: ImageFormat.WEBP,
425
- })
426
- );
427
- return response.success ? response.data : null;
428
- }
429
- ```
430
-
431
- ### Get Files with Presigned URLs
432
-
433
- ```typescript
434
- import { FileManagerApiService } from '@flusys/ng-storage';
435
-
436
- private readonly fileService = inject(FileManagerApiService);
437
-
438
- async getFileUrls(ids: string[]): Promise<IFilesResponseDto[]> {
439
- const response = await firstValueFrom(this.fileService.getFiles(ids));
440
- return response.data ?? [];
441
- }
442
- ```
443
-
444
- ### Delete with Confirmation
445
-
446
- Two delete modes are available:
447
-
448
- ```typescript
449
- // Soft delete - marks as deleted, recoverable
450
- onSoftDelete(file: IFileManager): void {
451
- this.confirmationService.confirm({
452
- message: `Delete "${file.name}"?`,
453
- header: 'Delete File',
454
- acceptButtonStyleClass: 'p-button-danger',
455
- accept: async () => {
456
- await this.fileService.deleteAsync({ id: file.id, type: 'delete' });
457
- this.loadFiles();
458
- },
459
- });
460
- }
461
-
462
- // Permanent delete - removes from storage provider, irreversible
463
- onPermanentDelete(file: IFileManager): void {
464
- this.confirmationService.confirm({
465
- message: `Permanently delete "${file.name}"? This cannot be undone.`,
466
- header: 'Permanent Delete',
467
- acceptButtonStyleClass: 'p-button-danger',
468
- accept: async () => {
469
- await firstValueFrom(
470
- this.uploadService.deleteSingleFile(file.key, file.storageConfigId ?? undefined)
471
- );
472
- await this.fileService.deleteAsync({ id: file.id, type: 'permanent' });
473
- this.loadFiles();
474
- },
475
- });
476
- }
477
- ```
478
-
479
- ---
480
-
481
- ## Backend Integration
482
-
483
- All endpoints use **POST-only RPC** style (not REST).
484
-
485
- | Service | Endpoint | Description |
486
- |---------|----------|-------------|
487
- | Upload | `POST /storage/upload/single-file` | Upload single file |
488
- | Upload | `POST /storage/upload/multiple-file` | Upload multiple files |
489
- | Upload | `POST /storage/upload/delete-single-file` | Delete file from storage |
490
- | Upload | `POST /storage/upload/delete-multiple-file` | Delete multiple files |
491
- | Upload | `GET /storage/upload/file/:filePath` | Direct file download |
492
- | FileManager | `POST /storage/file-manager/get-files` | Get files with presigned URLs |
493
- | FileManager | `POST /storage/file-manager/insert` | Create file metadata |
494
- | FileManager | `POST /storage/file-manager/get/:id` | Get file by ID |
495
- | FileManager | `POST /storage/file-manager/get-all` | List files (paginated) |
496
- | FileManager | `POST /storage/file-manager/update` | Update file metadata |
497
- | FileManager | `POST /storage/file-manager/delete` | Delete file |
498
- | Folder | `POST /storage/folder/insert` | Create folder |
499
- | Folder | `POST /storage/folder/get/:id` | Get folder by ID |
500
- | Folder | `POST /storage/folder/get-all` | List folders |
501
- | Folder | `POST /storage/folder/update` | Update folder |
502
- | Folder | `POST /storage/folder/delete` | Delete folder |
503
- | StorageConfig | `POST /storage/storage-config/insert` | Create config |
504
- | StorageConfig | `POST /storage/storage-config/get/:id` | Get config by ID |
505
- | StorageConfig | `POST /storage/storage-config/get-all` | List configs |
506
- | StorageConfig | `POST /storage/storage-config/update` | Update config |
507
- | StorageConfig | `POST /storage/storage-config/delete` | Delete config |
508
-
509
- ---
510
-
511
- ## Best Practices
512
-
513
- ### 1. Always Use Presigned URLs
514
-
515
- Never construct file URLs manually. Use `FileManagerApiService.getFiles()` or `FileUrlService` from ng-shared.
516
-
517
- ```typescript
518
- // Wrong: manual URL
519
- const url = `${apiBaseUrl}/storage/${fileId}`;
520
-
521
- // Correct: backend-generated presigned URL
522
- const files = await firstValueFrom(this.fileService.getFiles([fileId]));
523
- const url = files.data?.[0]?.url ?? null;
524
- ```
525
-
526
- ### 2. Specify Storage Config for Multi-Provider Setups
527
-
528
- ```typescript
529
- // Specify which storage provider to use
530
- await firstValueFrom(
531
- this.uploadService.uploadSingleFile(file, {
532
- storageConfigId: 'aws-media-bucket',
533
- folderPath: 'images',
534
- })
535
- );
536
- ```
537
-
538
- ### 3. Compress Images for Web
539
-
540
- ```typescript
541
- const options: IUploadOptionsDto = {
542
- compress: true,
543
- maxWidth: 1920,
544
- maxHeight: 1080,
545
- quality: 85,
546
- format: ImageFormat.WEBP,
547
- };
548
- ```
549
-
550
- ### 4. Provide ConfirmationService at App Level
551
-
552
- Storage list components use `ConfirmationService` for delete dialogs. Provide it in `app.config.ts`:
553
-
554
- ```typescript
555
- export const appConfig: ApplicationConfig = {
556
- providers: [ConfirmationService, MessageService],
557
- };
558
- ```
559
-
560
- ### 5. Enable Storage in APP_CONFIG
561
-
562
- ```typescript
563
- // environment.ts
564
- services: {
565
- storage: { baseUrl: 'http://localhost:2002/storage', enabled: true },
566
- }
567
- ```
568
-
569
- ---
570
-
571
- ## Provider Functions
572
-
573
- ### provideStorageProviders()
574
-
575
- Registers provider adapters that enable other packages (ng-auth) to access storage functionality without direct dependencies.
576
-
577
- ```typescript
578
- import { provideStorageProviders } from '@flusys/ng-storage';
579
-
580
- // app.config.ts
581
- export const appConfig: ApplicationConfig = {
582
- providers: [
583
- ...provideStorageProviders(), // Register storage providers
584
- ],
585
- };
586
- ```
587
-
588
- **Registers:**
589
-
590
- | Token | Adapter | Purpose |
591
- |-------|---------|---------|
592
- | `PROFILE_UPLOAD_PROVIDER` | `ProfileUploadProviderAdapter` | Profile picture upload for ng-auth |
593
-
594
- ### ProfileUploadProviderAdapter
595
-
596
- Implements `IProfileUploadProvider` from ng-shared. Enables ng-auth's profile page to upload profile pictures.
597
-
598
- ```typescript
599
- interface IProfileUploadProvider {
600
- uploadProfilePicture(
601
- file: File,
602
- options?: IProfileUploadOptions
603
- ): Observable<ISingleResponse<IProfileUploadResult>>;
604
- }
605
- ```
606
-
607
- **Usage in ng-auth profile page:**
608
-
609
- ```typescript
610
- // Optional injection - graceful degradation when storage disabled
611
- private readonly uploadProvider = inject(PROFILE_UPLOAD_PROVIDER, { optional: true });
612
-
613
- // Upload profile picture
614
- if (this.uploadProvider) {
615
- this.uploadProvider.uploadProfilePicture(file, { compress: true }).subscribe(response => {
616
- // response.data.id contains the file manager ID
617
- this.updateUserProfile({ profilePictureId: response.data.id });
618
- });
619
- }
620
- ```
621
-
622
- ---
623
-
624
- ## Public API Exports
625
-
626
- ```typescript
627
- // Enums
628
- export { FileLocationEnum, ImageFormat } from '@flusys/ng-storage';
629
-
630
- // Interfaces (all from interfaces/)
631
- export {
632
- IFileManager, ICreateFileManagerDto, IUpdateFileManagerDto,
633
- IGetFilesRequestDto, IFilesResponseDto,
634
- IFolder, ICreateFolderDto, IUpdateFolderDto,
635
- IStorageConfig, ICreateStorageConfigDto, IUpdateStorageConfigDto,
636
- IAwsS3Config, IAzureBlobConfig, ISftpConfig, ILocalStorageConfig,
637
- IUploadOptionsDto, IUploadedFileInfo,
638
- } from '@flusys/ng-storage';
639
-
640
- // Services
641
- export {
642
- FileManagerApiService, FolderApiService,
643
- StorageConfigApiService, UploadService,
644
- } from '@flusys/ng-storage';
645
-
646
- // Routes & Components
647
- export { STORAGE_ROUTES } from '@flusys/ng-storage';
648
- export { StorageContainerComponent } from '@flusys/ng-storage';
649
-
650
- // Provider Functions
651
- export { provideStorageProviders } from '@flusys/ng-storage';
652
- ```
653
-
654
- ---
68
+ ## License
655
69
 
656
- **Last Updated:** 2026-02-16
657
- **Angular Version:** 21
70
+ MIT © FLUSYS