@flusys/ng-storage 1.1.1-beta → 3.0.0-rc
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 +142 -5
- package/fesm2022/{flusys-ng-storage-file-manager-form.component-H3OZS0SW.mjs → flusys-ng-storage-file-manager-form.component-Bv8ER8J0.mjs} +110 -341
- package/fesm2022/flusys-ng-storage-file-manager-form.component-Bv8ER8J0.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-file-manager-list.component-McM1zSlE.mjs +304 -0
- package/fesm2022/flusys-ng-storage-file-manager-list.component-McM1zSlE.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-folder-form.component-fRFiMFev.mjs +155 -0
- package/fesm2022/flusys-ng-storage-folder-form.component-fRFiMFev.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-folder-list.component-C4xHI8SO.mjs +194 -0
- package/fesm2022/flusys-ng-storage-folder-list.component-C4xHI8SO.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-storage-config-form.component-CjIAxfHC.mjs → flusys-ng-storage-storage-config-form.component-DEMexjmg.mjs} +217 -300
- package/fesm2022/flusys-ng-storage-storage-config-form.component-DEMexjmg.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-storage-config-list.component-iJez-rII.mjs +187 -0
- package/fesm2022/flusys-ng-storage-storage-config-list.component-iJez-rII.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage.mjs +247 -204
- package/fesm2022/flusys-ng-storage.mjs.map +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-storage.d.ts +101 -151
- package/fesm2022/flusys-ng-storage-file-manager-form.component-H3OZS0SW.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-file-manager-list.component-4pb6TafD.mjs +0 -475
- package/fesm2022/flusys-ng-storage-file-manager-list.component-4pb6TafD.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-form.component-DQ0QY7P0.mjs +0 -253
- package/fesm2022/flusys-ng-storage-folder-form.component-DQ0QY7P0.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-list.component-D-oMaEgl.mjs +0 -267
- package/fesm2022/flusys-ng-storage-folder-list.component-D-oMaEgl.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-form.component-CjIAxfHC.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-list.component-jHk8O9Mx.mjs +0 -328
- package/fesm2022/flusys-ng-storage-storage-config-list.component-jHk8O9Mx.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -48,6 +48,8 @@ readonly currentCompanyName = computed(
|
|
|
48
48
|
|
|
49
49
|
```
|
|
50
50
|
ng-storage/
|
|
51
|
+
├── adapters/
|
|
52
|
+
│ └── profile-upload-provider.adapter.ts # Profile upload adapter for ng-auth
|
|
51
53
|
├── enums/
|
|
52
54
|
│ ├── file-location.enum.ts # FileLocationEnum, ImageFormat
|
|
53
55
|
│ └── public-api.ts
|
|
@@ -57,11 +59,17 @@ ng-storage/
|
|
|
57
59
|
│ ├── storage-config.interface.ts # IStorageConfig, provider-specific configs
|
|
58
60
|
│ ├── upload.interface.ts # IUploadOptionsDto, IUploadedFileInfo
|
|
59
61
|
│ └── public-api.ts
|
|
62
|
+
├── providers/
|
|
63
|
+
│ └── storage-providers.ts # provideStorageProviders()
|
|
60
64
|
├── services/
|
|
61
65
|
│ ├── file-manager-api.service.ts # File metadata CRUD + presigned URLs
|
|
62
66
|
│ ├── folder-api.service.ts # Folder CRUD
|
|
63
67
|
│ ├── storage-config-api.service.ts # Storage config CRUD
|
|
64
68
|
│ └── upload.service.ts # File upload/delete operations
|
|
69
|
+
├── utils/
|
|
70
|
+
│ ├── base-storage-page.ts # BaseStoragePage, BaseStorageListPage base classes
|
|
71
|
+
│ ├── storage-utils.ts # Utility functions (icons, labels, formatters)
|
|
72
|
+
│ └── public-api.ts
|
|
65
73
|
├── pages/
|
|
66
74
|
│ ├── storage-container/
|
|
67
75
|
│ │ └── storage-container.component.ts # Tab container (Files, Folders, Configs)
|
|
@@ -184,6 +192,7 @@ interface IFileManager {
|
|
|
184
192
|
url: string | null; // Presigned URL (regenerated by backend)
|
|
185
193
|
location: FileLocationEnum;
|
|
186
194
|
storageConfigId: string | null;
|
|
195
|
+
providerName?: string; // Storage config name (enriched from storage_config table)
|
|
187
196
|
expiresAt: Date | null; // URL expiration time
|
|
188
197
|
isPrivate: boolean;
|
|
189
198
|
companyId?: string; // Only in company mode
|
|
@@ -303,9 +312,11 @@ Handles file upload and deletion. Extends `BaseApiService` (from ng-core).
|
|
|
303
312
|
|--------|----------|-------------|
|
|
304
313
|
| `uploadSingleFile(file, options?)` | `POST /storage/upload/single-file` | Upload single file |
|
|
305
314
|
| `uploadMultipleFiles(files, options?)` | `POST /storage/upload/multiple-file` | Upload multiple files (max 50) |
|
|
315
|
+
| `uploadAndRegister(file, options?)` | Combined | Upload file and create file manager record |
|
|
306
316
|
| `deleteSingleFile(key, storageConfigId?)` | `POST /storage/upload/delete-single-file` | Delete single file from storage |
|
|
307
317
|
| `deleteMultipleFiles(keys, storageConfigId?)` | `POST /storage/upload/delete-multiple-file` | Delete multiple files |
|
|
308
318
|
| `getFileUrl(key)` | `GET /storage/upload/file/:key` | Get direct file download URL |
|
|
319
|
+
| `getDefaultConfigId()` | - | Get default storage config ID from APP_CONFIG |
|
|
309
320
|
|
|
310
321
|
Upload options are sent as **query parameters**, not form data:
|
|
311
322
|
|
|
@@ -357,19 +368,58 @@ Storage provider configuration CRUD. Extends `ApiResourceService<IUpdateStorageC
|
|
|
357
368
|
|
|
358
369
|
All components are standalone, use Angular 21 signal forms, and lazy-load via routes.
|
|
359
370
|
|
|
371
|
+
### Base Classes
|
|
372
|
+
|
|
373
|
+
Components extend shared base classes from `utils/base-storage-page.ts`:
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
// BaseStoragePage - Common functionality for all storage pages
|
|
377
|
+
abstract class BaseStoragePage {
|
|
378
|
+
readonly isLoading = signal(false);
|
|
379
|
+
readonly showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature);
|
|
380
|
+
readonly currentCompanyName = computed(() =>
|
|
381
|
+
this.companyContext.currentCompanyInfo()?.name ?? DEFAULT_APP_NAME
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
protected showSuccess(detail: string): void;
|
|
385
|
+
protected showError(detail: string): void;
|
|
386
|
+
protected navigateTo(path: string[]): void;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// BaseStorageListPage - Adds pagination support
|
|
390
|
+
abstract class BaseStorageListPage extends BaseStoragePage {
|
|
391
|
+
readonly totalRecords = signal(0);
|
|
392
|
+
readonly pageSize = signal(50);
|
|
393
|
+
readonly currentPage = signal(1);
|
|
394
|
+
|
|
395
|
+
onPageChange(event: { first?: number; rows?: number }): void;
|
|
396
|
+
protected getPaginationParams(): { currentPage: number; pageSize: number };
|
|
397
|
+
abstract loadData(): Promise<void>;
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
360
401
|
### StorageContainerComponent
|
|
361
402
|
|
|
362
|
-
Main container with tab navigation between Files, Folders, and Configs sections.
|
|
403
|
+
Main container with tab navigation between Files, Folders, and Configs sections.
|
|
363
404
|
|
|
364
405
|
**Selector:** `lib-storage-container`
|
|
365
406
|
|
|
407
|
+
**Features:**
|
|
408
|
+
- Tab navigation with `scrollbar-hide` CSS (horizontal scroll without visible scrollbar on mobile)
|
|
409
|
+
- Responsive padding: `p-2 sm:p-4`
|
|
410
|
+
- Dark mode compatible using Tailwind theme classes
|
|
411
|
+
|
|
366
412
|
### List Components
|
|
367
413
|
|
|
368
414
|
All list components share:
|
|
369
|
-
- **
|
|
370
|
-
- **
|
|
415
|
+
- **Extends `BaseStorageListPage`** for common functionality
|
|
416
|
+
- **Lazy pagination** via `p-table` with `[paginator]="totalRecords() > 0"` (hidden when no data)
|
|
417
|
+
- **Responsive columns** with `hidden sm:table-cell`, `hidden md:table-cell`, etc.
|
|
418
|
+
- **Company info display** when company feature enabled
|
|
371
419
|
- **Delete confirmation** via `ConfirmationService`
|
|
372
|
-
- **Signal-based state:** `isLoading`,
|
|
420
|
+
- **Signal-based state:** `isLoading`, data signal, `totalRecords`, `pageSize`, `currentPage`
|
|
421
|
+
- **Responsive title:** `text-lg sm:text-xl`
|
|
422
|
+
- **Responsive buttons:** `w-full sm:w-auto`
|
|
373
423
|
|
|
374
424
|
**FileManagerListComponent** additionally supports:
|
|
375
425
|
- File content type icons (image, video, audio, PDF, Word, Excel, generic)
|
|
@@ -383,6 +433,11 @@ All form components share:
|
|
|
383
433
|
- **Signal Forms** using Angular 21 `form()` helper with `required()` validators
|
|
384
434
|
- **Create/Edit mode** auto-detection based on route param (`:id`)
|
|
385
435
|
- **Navigation** back to list on save/cancel
|
|
436
|
+
- **Button styling pattern:**
|
|
437
|
+
- Cancel: `severity="secondary" [outlined]="true"`
|
|
438
|
+
- Submit: Primary style (no severity attribute)
|
|
439
|
+
- Order: Cancel first, then Submit (right-aligned)
|
|
440
|
+
- Responsive: `flex justify-end gap-4 pt-4`
|
|
386
441
|
|
|
387
442
|
**FileManagerFormComponent** additionally supports:
|
|
388
443
|
- PrimeNG file upload with drag-drop
|
|
@@ -403,6 +458,41 @@ When `isDefault: true`, this configuration will be used automatically when no `s
|
|
|
403
458
|
|
|
404
459
|
---
|
|
405
460
|
|
|
461
|
+
## Utility Functions
|
|
462
|
+
|
|
463
|
+
The `utils/storage-utils.ts` file provides helper functions used across components:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
// Get display label for storage provider
|
|
467
|
+
getProviderLabel(storage: FileLocationEnum): string;
|
|
468
|
+
// Returns: 'AWS S3', 'Azure Blob', 'SFTP', 'Local'
|
|
469
|
+
|
|
470
|
+
// Get icon class for storage provider
|
|
471
|
+
getProviderIcon(storage: FileLocationEnum): string;
|
|
472
|
+
// Returns: 'pi pi-cloud', 'pi pi-server', 'pi pi-folder'
|
|
473
|
+
|
|
474
|
+
// Get severity for p-tag based on provider
|
|
475
|
+
getProviderSeverity(storage: FileLocationEnum): 'success' | 'info' | 'warn' | 'danger' | 'secondary' | 'contrast';
|
|
476
|
+
|
|
477
|
+
// Get file icon based on content type
|
|
478
|
+
getFileIcon(contentType: string): string;
|
|
479
|
+
// Returns: 'pi pi-image', 'pi pi-video', 'pi pi-file-pdf', etc.
|
|
480
|
+
|
|
481
|
+
// Format file size to human readable
|
|
482
|
+
formatFileSize(bytes: number): string;
|
|
483
|
+
// Returns: '1.5 MB', '256 KB', etc.
|
|
484
|
+
|
|
485
|
+
// Storage provider options for dropdowns
|
|
486
|
+
const STORAGE_PROVIDERS = [
|
|
487
|
+
{ label: 'AWS S3', value: FileLocationEnum.AWS },
|
|
488
|
+
{ label: 'Azure Blob Storage', value: FileLocationEnum.AZURE },
|
|
489
|
+
{ label: 'SFTP', value: FileLocationEnum.SFTP },
|
|
490
|
+
{ label: 'Local Storage', value: FileLocationEnum.LOCAL },
|
|
491
|
+
];
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
406
496
|
## Usage Examples
|
|
407
497
|
|
|
408
498
|
### Upload a File
|
|
@@ -428,6 +518,28 @@ async uploadImage(file: File): Promise<IUploadedFileInfo | null> {
|
|
|
428
518
|
}
|
|
429
519
|
```
|
|
430
520
|
|
|
521
|
+
### Upload and Register (Combined)
|
|
522
|
+
|
|
523
|
+
Use `uploadAndRegister` for a single call that uploads and creates the file manager record:
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { UploadService, IFileManager } from '@flusys/ng-storage';
|
|
527
|
+
|
|
528
|
+
private readonly uploadService = inject(UploadService);
|
|
529
|
+
|
|
530
|
+
async uploadProfilePicture(file: File): Promise<IFileManager | null> {
|
|
531
|
+
const response = await firstValueFrom(
|
|
532
|
+
this.uploadService.uploadAndRegister(file, {
|
|
533
|
+
compress: true,
|
|
534
|
+
quality: 85,
|
|
535
|
+
isPrivate: false,
|
|
536
|
+
folderId: 'avatars-folder-id',
|
|
537
|
+
})
|
|
538
|
+
);
|
|
539
|
+
return response.success ? response.data : null;
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
431
543
|
### Get Files with Presigned URLs
|
|
432
544
|
|
|
433
545
|
```typescript
|
|
@@ -566,6 +678,31 @@ services: {
|
|
|
566
678
|
}
|
|
567
679
|
```
|
|
568
680
|
|
|
681
|
+
### 6. Responsive Design Patterns
|
|
682
|
+
|
|
683
|
+
All components follow these responsive patterns:
|
|
684
|
+
|
|
685
|
+
```html
|
|
686
|
+
<!-- Titles: smaller on mobile -->
|
|
687
|
+
<h3 class="text-lg sm:text-xl font-semibold">Title</h3>
|
|
688
|
+
|
|
689
|
+
<!-- Buttons: full width on mobile, auto on larger -->
|
|
690
|
+
<p-button label="New" styleClass="w-full sm:w-auto" />
|
|
691
|
+
|
|
692
|
+
<!-- Form grids: stack on mobile, 2 columns on md+ -->
|
|
693
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
694
|
+
|
|
695
|
+
<!-- Labels: smaller text on mobile -->
|
|
696
|
+
<label class="text-sm sm:text-base">Label</label>
|
|
697
|
+
|
|
698
|
+
<!-- Table columns: hide on smaller screens -->
|
|
699
|
+
<th class="hidden sm:table-cell">Column</th>
|
|
700
|
+
<th class="hidden md:table-cell">Column</th>
|
|
701
|
+
|
|
702
|
+
<!-- Tab navigation: horizontal scroll without visible scrollbar -->
|
|
703
|
+
<div class="scrollbar-hide flex overflow-x-auto">
|
|
704
|
+
```
|
|
705
|
+
|
|
569
706
|
---
|
|
570
707
|
|
|
571
708
|
## Provider Functions
|
|
@@ -653,5 +790,5 @@ export { provideStorageProviders } from '@flusys/ng-storage';
|
|
|
653
790
|
|
|
654
791
|
---
|
|
655
792
|
|
|
656
|
-
**Last Updated:** 2026-02-
|
|
793
|
+
**Last Updated:** 2026-02-21
|
|
657
794
|
**Angular Version:** 21
|