@flusys/ng-storage 4.1.1 → 5.0.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.
- package/README.md +17 -382
- package/fesm2022/{flusys-ng-storage-file-manager-form.component-AM7JE-s5.mjs → flusys-ng-storage-file-manager-form.component-BLJDAvBX.mjs} +287 -74
- package/fesm2022/flusys-ng-storage-file-manager-form.component-BLJDAvBX.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-file-manager-list.component-bj6oOzOL.mjs → flusys-ng-storage-file-manager-list.component-Dn5hVksO.mjs} +210 -70
- package/fesm2022/flusys-ng-storage-file-manager-list.component-Dn5hVksO.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-folder-form.component-Cc2ybTwu.mjs → flusys-ng-storage-folder-form.component-B8vRSb1T.mjs} +88 -31
- package/fesm2022/flusys-ng-storage-folder-form.component-B8vRSb1T.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-folder-list.component-B2Q41I1g.mjs → flusys-ng-storage-folder-list.component-B4yCKvAV.mjs} +96 -30
- package/fesm2022/flusys-ng-storage-folder-list.component-B4yCKvAV.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-storage-config-form.component-CMeTif8p.mjs +880 -0
- package/fesm2022/flusys-ng-storage-storage-config-form.component-CMeTif8p.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-storage-config-list.component-DBH_qf9o.mjs → flusys-ng-storage-storage-config-list.component-C7OYYyrQ.mjs} +126 -33
- package/fesm2022/flusys-ng-storage-storage-config-list.component-C7OYYyrQ.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage.mjs +143 -256
- package/fesm2022/flusys-ng-storage.mjs.map +1 -1
- package/package.json +4 -4
- package/types/flusys-ng-storage.d.ts +4 -2
- package/fesm2022/flusys-ng-storage-file-manager-form.component-AM7JE-s5.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-file-manager-list.component-bj6oOzOL.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-form.component-Cc2ybTwu.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-list.component-B2Q41I1g.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-form.component-a88XhuPH.mjs +0 -465
- package/fesm2022/flusys-ng-storage-storage-config-form.component-a88XhuPH.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-list.component-DBH_qf9o.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,69 +1,9 @@
|
|
|
1
1
|
# @flusys/ng-storage
|
|
2
2
|
|
|
3
|
-
|
|
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.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@flusys/ng-storage)
|
|
6
|
-
[](https://www.typescriptlang.org)
|
|
8
|
-
[](LICENSE)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Table of Contents
|
|
13
|
-
|
|
14
|
-
- [Overview](#overview)
|
|
15
|
-
- [Features](#features)
|
|
16
|
-
- [Compatibility](#compatibility)
|
|
17
|
-
- [Installation](#installation)
|
|
18
|
-
- [Quick Start](#quick-start)
|
|
19
|
-
- [Module Registration](#module-registration)
|
|
20
|
-
- [File URL Rule](#file-url-rule)
|
|
21
|
-
- [Services](#services)
|
|
22
|
-
- [FileManagerApiService](#filemanagerapiservice)
|
|
23
|
-
- [FolderApiService](#folderapiservice)
|
|
24
|
-
- [UploadService](#uploadservice)
|
|
25
|
-
- [Components](#components)
|
|
26
|
-
- [FileManagerComponent](#filemanagercomponent)
|
|
27
|
-
- [FileSelectorDialogComponent](#fileselectordialogcomponent)
|
|
28
|
-
- [FileUploaderComponent](#fileuploadercomponent)
|
|
29
|
-
- [Storage Routes](#storage-routes)
|
|
30
|
-
- [File Location Enum](#file-location-enum)
|
|
31
|
-
- [API Endpoints](#api-endpoints)
|
|
32
|
-
- [Configuration Reference](#configuration-reference)
|
|
33
|
-
- [Troubleshooting](#troubleshooting)
|
|
34
|
-
- [License](#license)
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Overview
|
|
39
|
-
|
|
40
|
-
`@flusys/ng-storage` provides the complete file management UI for FLUSYS applications. It supports all four storage backends (Local, S3, Azure Blob, SFTP) transparently — the backend generates the correct presigned URLs for each provider.
|
|
41
|
-
|
|
42
|
-
**Critical rule:** Never construct file URLs manually. Always use `FileUrlService` (from `ng-shared`) or the `FILE_PROVIDER` token. The backend generates presigned URLs that are provider-agnostic and access-controlled.
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Features
|
|
47
|
-
|
|
48
|
-
- ✅ File browser with folder navigation
|
|
49
|
-
- ✅ Drag-and-drop upload with progress
|
|
50
|
-
- ✅ Multi-file selection dialog (`FileSelectorDialogComponent`)
|
|
51
|
-
- ✅ Image preview thumbnails
|
|
52
|
-
- ✅ Download and delete actions
|
|
53
|
-
- ✅ `UploadService` — typed multi-part file upload
|
|
54
|
-
- ✅ `provideStorageProviders()` — registers `FILE_PROVIDER` for shared components
|
|
55
|
-
- ✅ Presigned URL fetching via `FileUrlService`
|
|
56
|
-
- ✅ Support for `LOCAL`, `S3`, `AZURE`, `SFTP` backends
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Compatibility
|
|
61
|
-
|
|
62
|
-
| Package | Version |
|
|
63
|
-
|---------|---------|
|
|
64
|
-
| Angular | 21+ |
|
|
65
|
-
| @flusys/ng-core | 4.x |
|
|
66
|
-
| @flusys/ng-shared | 4.x |
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
67
7
|
|
|
68
8
|
---
|
|
69
9
|
|
|
@@ -73,22 +13,7 @@
|
|
|
73
13
|
npm install @flusys/ng-storage @flusys/ng-core @flusys/ng-shared
|
|
74
14
|
```
|
|
75
15
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
## Quick Start
|
|
79
|
-
|
|
80
|
-
### 1. Enable Storage in Config
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
// environments/environment.ts
|
|
84
|
-
export const environment = {
|
|
85
|
-
services: {
|
|
86
|
-
storage: { enabled: true },
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### 2. Register Storage Providers
|
|
16
|
+
## 1. Register Providers
|
|
92
17
|
|
|
93
18
|
```typescript
|
|
94
19
|
// app.config.ts
|
|
@@ -96,13 +21,14 @@ import { provideStorageProviders } from '@flusys/ng-storage';
|
|
|
96
21
|
|
|
97
22
|
export const appConfig: ApplicationConfig = {
|
|
98
23
|
providers: [
|
|
99
|
-
...provideStorageProviders(),
|
|
100
|
-
// Provides: FILE_PROVIDER (IFileProvider) — used by FileSelectorDialogComponent, FileUrlService
|
|
24
|
+
...provideStorageProviders(), // registers FILE_PROVIDER for ng-shared's file picker and FileUrlService
|
|
101
25
|
],
|
|
102
26
|
};
|
|
103
27
|
```
|
|
104
28
|
|
|
105
|
-
|
|
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.
|
|
30
|
+
|
|
31
|
+
## 2. Add Storage Routes (Optional)
|
|
106
32
|
|
|
107
33
|
```typescript
|
|
108
34
|
// app.routes.ts
|
|
@@ -116,319 +42,28 @@ export const routes: Routes = [
|
|
|
116
42
|
];
|
|
117
43
|
```
|
|
118
44
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
## Module Registration
|
|
45
|
+
Routes included (all protected by `permissionGuard`):
|
|
122
46
|
|
|
123
|
-
|
|
47
|
+
## 4. Fetch File URLs (Critical Rule)
|
|
124
48
|
|
|
125
|
-
|
|
49
|
+
Never construct file URLs manually. Always use `FileUrlService` from `ng-shared` — the backend generates presigned, access-controlled URLs for all storage providers.
|
|
126
50
|
|
|
127
51
|
```typescript
|
|
128
|
-
import { provideStorageProviders } from '@flusys/ng-storage';
|
|
129
|
-
|
|
130
|
-
providers: [
|
|
131
|
-
...provideStorageProviders(),
|
|
132
|
-
]
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
This enables:
|
|
136
|
-
- `FileSelectorDialogComponent` (from `ng-shared`) to list/browse files
|
|
137
|
-
- `FileUrlService.fetchSingleFileUrl()` to work correctly
|
|
138
|
-
- `HasPermissionDirective` to show storage-gated content
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## File URL Rule
|
|
143
|
-
|
|
144
|
-
**CRITICAL:** Never construct file URLs manually. The backend handles URL generation for all storage providers (Local, S3, Azure, SFTP) including presigned URL rotation.
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
// ❌ WRONG — breaks with S3, Azure, SFTP
|
|
148
|
-
const url = `${apiBaseUrl}/uploads/${fileId}`;
|
|
149
|
-
const url = `https://my-bucket.s3.amazonaws.com/${path}`;
|
|
150
|
-
|
|
151
|
-
// ✅ CORRECT — always use FileUrlService
|
|
152
52
|
import { FileUrlService } from '@flusys/ng-shared';
|
|
153
53
|
|
|
154
|
-
const file = await this.fileUrlService.fetchSingleFileUrl(fileId);
|
|
155
|
-
const url = file?.url ?? null; // Presigned, access-controlled, provider-agnostic
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
**Why backend URLs:**
|
|
159
|
-
- S3/Azure require presigned URLs that expire
|
|
160
|
-
- URLs are access-controlled (user must have permission)
|
|
161
|
-
- Works transparently across all 4 storage providers
|
|
162
|
-
- Automatic URL refresh on expiry
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## Services
|
|
167
|
-
|
|
168
|
-
### FileManagerApiService
|
|
169
|
-
|
|
170
|
-
Typed API client for file management operations:
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
import { FileManagerApiService } from '@flusys/ng-storage';
|
|
174
|
-
|
|
175
|
-
@Injectable({ ... })
|
|
176
|
-
export class MyService {
|
|
177
|
-
private fileApi = inject(FileManagerApiService);
|
|
178
|
-
|
|
179
|
-
getFiles(folderId?: string): Observable<IListResponse<IFile>> {
|
|
180
|
-
return this.fileApi.getAll({ filters: { folderId } });
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
getFileUrls(fileIds: string[]): Observable<ISingleResponse<IFileWithUrl[]>> {
|
|
184
|
-
return this.fileApi.getFiles(fileIds);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
deleteFile(id: string): Observable<IMessageResponse> {
|
|
188
|
-
return this.fileApi.delete(id);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
**FileManagerApiService Methods:**
|
|
194
|
-
|
|
195
|
-
| Method | Endpoint | Description |
|
|
196
|
-
|--------|----------|-------------|
|
|
197
|
-
| `getAll(params)` | `POST /file-manager/get-all` | List files with pagination |
|
|
198
|
-
| `getById(id)` | `POST /file-manager/get/:id` | Get file metadata |
|
|
199
|
-
| `getFiles(ids[])` | `POST /file-manager/get-files` | Batch fetch with presigned URLs |
|
|
200
|
-
| `delete(id)` | `POST /file-manager/delete` | Delete file |
|
|
201
|
-
| `bulkDelete(ids[])` | `POST /file-manager/bulk-delete` | Delete multiple files |
|
|
202
|
-
| `move(id, folderId)` | `POST /file-manager/move` | Move file to folder |
|
|
203
|
-
|
|
204
|
-
### FolderApiService
|
|
205
|
-
|
|
206
|
-
Typed API client for folder management:
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
import { FolderApiService } from '@flusys/ng-storage';
|
|
210
|
-
|
|
211
|
-
@Injectable({ ... })
|
|
212
|
-
export class MyService {
|
|
213
|
-
private folderApi = inject(FolderApiService);
|
|
214
|
-
|
|
215
|
-
getFolders(parentId?: string): Observable<IListResponse<IFolder>> {
|
|
216
|
-
return this.folderApi.getAll({ filters: { parentId } });
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
createFolder(name: string, parentId?: string): Observable<ISingleResponse<IFolder>> {
|
|
220
|
-
return this.folderApi.insert({ name, parentId });
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
**FolderApiService Methods:**
|
|
226
|
-
|
|
227
|
-
| Method | Endpoint | Description |
|
|
228
|
-
|--------|----------|-------------|
|
|
229
|
-
| `getAll(params)` | `POST /folder/get-all` | List folders |
|
|
230
|
-
| `getById(id)` | `POST /folder/get/:id` | Get folder |
|
|
231
|
-
| `insert(dto)` | `POST /folder/insert` | Create folder |
|
|
232
|
-
| `update(dto)` | `POST /folder/update` | Rename folder |
|
|
233
|
-
| `delete(id)` | `POST /folder/delete` | Delete folder |
|
|
234
|
-
|
|
235
|
-
### UploadService
|
|
236
|
-
|
|
237
|
-
Handles multi-part file uploads with progress tracking:
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
import { UploadService } from '@flusys/ng-storage';
|
|
241
|
-
|
|
242
54
|
@Component({ ... })
|
|
243
|
-
export class
|
|
244
|
-
private
|
|
55
|
+
export class MyComponent {
|
|
56
|
+
private readonly fileUrlService = inject(FileUrlService);
|
|
245
57
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
console.log(`Progress: ${event.percent}%`);
|
|
251
|
-
}
|
|
252
|
-
if (event.type === 'complete') {
|
|
253
|
-
console.log('Uploaded:', event.file);
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
error: (err) => console.error('Upload failed:', err),
|
|
257
|
-
});
|
|
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;
|
|
258
62
|
}
|
|
259
|
-
|
|
260
|
-
uploadMultiple(files: File[]): void {
|
|
261
|
-
this.uploadService.uploadBatch(files).subscribe(results => {
|
|
262
|
-
console.log(`Uploaded ${results.length} files`);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
**UploadService API:**
|
|
269
|
-
|
|
270
|
-
| Method | Description |
|
|
271
|
-
|--------|-------------|
|
|
272
|
-
| `upload(file, options?)` | Single file upload with progress events |
|
|
273
|
-
| `uploadBatch(files, options?)` | Multiple file upload (sequential) |
|
|
274
|
-
| `cancel(uploadId)` | Cancel in-progress upload |
|
|
275
|
-
|
|
276
|
-
---
|
|
277
|
-
|
|
278
|
-
## Components
|
|
279
|
-
|
|
280
|
-
### FileManagerComponent
|
|
281
|
-
|
|
282
|
-
Full-page file browser with folder tree, grid/list view, upload, and actions.
|
|
283
|
-
|
|
284
|
-
```html
|
|
285
|
-
<!-- Full file manager -->
|
|
286
|
-
<flusys-file-manager />
|
|
287
|
-
|
|
288
|
-
<!-- With pre-selected folder -->
|
|
289
|
-
<flusys-file-manager [initialFolderId]="rootFolderId" />
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
Features:
|
|
293
|
-
- Folder tree (left panel)
|
|
294
|
-
- File grid with thumbnails (right panel)
|
|
295
|
-
- Drag-and-drop upload zone
|
|
296
|
-
- Right-click context menu (rename, move, delete)
|
|
297
|
-
- Breadcrumb navigation
|
|
298
|
-
- Search files
|
|
299
|
-
|
|
300
|
-
### FileSelectorDialogComponent
|
|
301
|
-
|
|
302
|
-
Dialog for selecting one or multiple files. Used by other packages (`ng-form-builder`, `ng-email`) to pick files.
|
|
303
|
-
|
|
304
|
-
```html
|
|
305
|
-
<flusys-file-selector-dialog
|
|
306
|
-
[visible]="showPicker"
|
|
307
|
-
[multiple]="true"
|
|
308
|
-
[accept]="'image/*'"
|
|
309
|
-
(fileSelected)="onFilesSelected($event)"
|
|
310
|
-
(cancel)="showPicker = false"
|
|
311
|
-
/>
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
| Input | Type | Description |
|
|
315
|
-
|-------|------|-------------|
|
|
316
|
-
| `visible` | `boolean` | Show/hide dialog |
|
|
317
|
-
| `multiple` | `boolean` | Allow multi-select (default: false) |
|
|
318
|
-
| `accept` | `string` | MIME type filter |
|
|
319
|
-
| `folderId` | `string` | Pre-open specific folder |
|
|
320
|
-
|
|
321
|
-
| Output | Type | Description |
|
|
322
|
-
|--------|------|-------------|
|
|
323
|
-
| `fileSelected` | `IFile \| IFile[]` | Selected file(s) |
|
|
324
|
-
| `cancel` | `void` | Dialog dismissed |
|
|
325
|
-
|
|
326
|
-
### FileUploaderComponent
|
|
327
|
-
|
|
328
|
-
Lightweight standalone upload component (without the full browser):
|
|
329
|
-
|
|
330
|
-
```html
|
|
331
|
-
<flusys-file-uploader
|
|
332
|
-
[multiple]="false"
|
|
333
|
-
[accept]="'image/jpeg,image/png'"
|
|
334
|
-
[maxSizeMb]="5"
|
|
335
|
-
[folderId]="profilePicturesFolderId"
|
|
336
|
-
(uploaded)="onAvatarUploaded($event)"
|
|
337
|
-
/>
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## Storage Routes
|
|
343
|
-
|
|
344
|
-
Lazy-loaded pages for the full file manager:
|
|
345
|
-
|
|
346
|
-
```typescript
|
|
347
|
-
import { STORAGE_ROUTES } from '@flusys/ng-storage';
|
|
348
|
-
|
|
349
|
-
{ path: 'storage', loadChildren: () => STORAGE_ROUTES }
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
| Route | Component | Description |
|
|
353
|
-
|-------|-----------|-------------|
|
|
354
|
-
| `/storage` | `FileManagerPageComponent` | Full file manager page |
|
|
355
|
-
| `/storage/folder/:id` | `FileManagerPageComponent` | Open specific folder |
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
|
-
## File Location Enum
|
|
360
|
-
|
|
361
|
-
```typescript
|
|
362
|
-
import { FileLocationEnum } from '@flusys/ng-storage';
|
|
363
|
-
|
|
364
|
-
enum FileLocationEnum {
|
|
365
|
-
LOCAL = 'LOCAL',
|
|
366
|
-
S3 = 'S3',
|
|
367
|
-
AZURE = 'AZURE',
|
|
368
|
-
SFTP = 'SFTP',
|
|
369
63
|
}
|
|
370
64
|
```
|
|
371
65
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
## API Endpoints
|
|
377
|
-
|
|
378
|
-
| Method | Endpoint | Description |
|
|
379
|
-
|--------|----------|-------------|
|
|
380
|
-
| POST | `/file-manager/get-all` | List files with pagination |
|
|
381
|
-
| POST | `/file-manager/get/:id` | Get file metadata |
|
|
382
|
-
| POST | `/file-manager/get-files` | Batch fetch with presigned URLs |
|
|
383
|
-
| POST | `/file-manager/upload` | Upload file (multipart) |
|
|
384
|
-
| POST | `/file-manager/delete` | Delete file |
|
|
385
|
-
| POST | `/file-manager/bulk-delete` | Delete multiple files |
|
|
386
|
-
| POST | `/file-manager/move` | Move file to folder |
|
|
387
|
-
| POST | `/folder/get-all` | List folders |
|
|
388
|
-
| POST | `/folder/get/:id` | Get folder metadata |
|
|
389
|
-
| POST | `/folder/insert` | Create folder |
|
|
390
|
-
| POST | `/folder/update` | Rename folder |
|
|
391
|
-
| POST | `/folder/delete` | Delete folder |
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## Configuration Reference
|
|
396
|
-
|
|
397
|
-
| Config Key | Type | Default | Description |
|
|
398
|
-
|------------|------|---------|-------------|
|
|
399
|
-
| `services.storage.enabled` | `boolean` | `false` | Enable storage module |
|
|
400
|
-
|
|
401
|
-
The storage backend (LOCAL/S3/AZURE/SFTP) is configured server-side in `nestjs-storage`. The Angular client doesn't need to know which provider is active.
|
|
402
|
-
|
|
403
|
-
---
|
|
404
|
-
|
|
405
|
-
## Troubleshooting
|
|
406
|
-
|
|
407
|
-
**File thumbnails don't load**
|
|
408
|
-
|
|
409
|
-
Images are loaded via presigned URLs. Ensure `FileUrlService.fetchSingleFileUrl()` is used (not manual URL construction). Check the browser network tab — are the URLs returning 403?
|
|
410
|
-
|
|
411
|
-
**Upload fails with 413 Payload Too Large**
|
|
412
|
-
|
|
413
|
-
The backend has a file size limit. Configure `maxBodySize` in `nestjs-storage` on the server. On the Angular side, validate client-side before upload:
|
|
414
|
-
|
|
415
|
-
```html
|
|
416
|
-
<flusys-file-uploader [maxSizeMb]="10" />
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
**`No provider for FILE_PROVIDER`**
|
|
420
|
-
|
|
421
|
-
Add `provideStorageProviders()` to `app.config.ts` providers.
|
|
422
|
-
|
|
423
|
-
**FileSelectorDialog is empty (no files)**
|
|
424
|
-
|
|
425
|
-
Ensure the user has permission to list files (`file:read`) and the backend storage is configured. Check the network tab for errors on `POST /file-manager/get-all`.
|
|
426
|
-
|
|
427
|
-
**Files visible but download fails**
|
|
428
|
-
|
|
429
|
-
The presigned URL may have expired. Call `FileUrlService.clearCache(fileId)` to force a fresh URL fetch.
|
|
430
|
-
|
|
431
|
-
---
|
|
66
|
+
Manual URL construction breaks with S3/Azure (presigned URLs expire) and does not enforce access control.
|
|
432
67
|
|
|
433
68
|
## License
|
|
434
69
|
|