@flusys/ng-storage 0.1.0-beta.3 → 1.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 +209 -5
- package/fesm2022/flusys-ng-storage-file-manager-form.component-CMS_ddbs.mjs +485 -0
- package/fesm2022/flusys-ng-storage-file-manager-form.component-CMS_ddbs.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-file-manager-list.component-DDOFAPRD.mjs +305 -0
- package/fesm2022/flusys-ng-storage-file-manager-list.component-DDOFAPRD.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-folder-form.component-ClYATZkh.mjs +157 -0
- package/fesm2022/flusys-ng-storage-folder-form.component-ClYATZkh.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-folder-list.component-CzONANHt.mjs +200 -0
- package/fesm2022/flusys-ng-storage-folder-list.component-CzONANHt.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-storage-config-form.component-DHzsQ2Mc.mjs → flusys-ng-storage-storage-config-form.component-CODLLCtg.mjs} +211 -238
- package/fesm2022/flusys-ng-storage-storage-config-form.component-CODLLCtg.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-storage-config-list.component-BbBx0iSL.mjs +213 -0
- package/fesm2022/flusys-ng-storage-storage-config-list.component-BbBx0iSL.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage.mjs +391 -103
- package/fesm2022/flusys-ng-storage.mjs.map +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-storage.d.ts +187 -8
- package/fesm2022/flusys-ng-storage-file-manager-form.component-BI0hgXeI.mjs +0 -716
- package/fesm2022/flusys-ng-storage-file-manager-form.component-BI0hgXeI.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-file-manager-list.component-5gqfPzR3.mjs +0 -475
- package/fesm2022/flusys-ng-storage-file-manager-list.component-5gqfPzR3.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-form.component-Cw2aLZkb.mjs +0 -253
- package/fesm2022/flusys-ng-storage-folder-form.component-Cw2aLZkb.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-list.component-CN_mTtS5.mjs +0 -267
- package/fesm2022/flusys-ng-storage-folder-list.component-CN_mTtS5.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-form.component-DHzsQ2Mc.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-list.component-tmiE2CpM.mjs +0 -328
- package/fesm2022/flusys-ng-storage-storage-config-list.component-tmiE2CpM.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
|
|
@@ -233,6 +242,8 @@ interface IStorageConfig extends IBaseEntity {
|
|
|
233
242
|
name: string;
|
|
234
243
|
storage: FileLocationEnum;
|
|
235
244
|
config: Record<string, any>; // Provider-specific configuration
|
|
245
|
+
isActive: boolean; // Whether config is active and usable
|
|
246
|
+
isDefault: boolean; // Set as default configuration
|
|
236
247
|
companyId?: string | null;
|
|
237
248
|
}
|
|
238
249
|
|
|
@@ -240,6 +251,8 @@ interface ICreateStorageConfigDto {
|
|
|
240
251
|
name: string;
|
|
241
252
|
storage: FileLocationEnum;
|
|
242
253
|
config: Record<string, any>;
|
|
254
|
+
isActive?: boolean;
|
|
255
|
+
isDefault?: boolean;
|
|
243
256
|
}
|
|
244
257
|
|
|
245
258
|
interface IUpdateStorageConfigDto {
|
|
@@ -247,6 +260,8 @@ interface IUpdateStorageConfigDto {
|
|
|
247
260
|
name?: string;
|
|
248
261
|
storage?: FileLocationEnum;
|
|
249
262
|
config?: Record<string, any>;
|
|
263
|
+
isActive?: boolean;
|
|
264
|
+
isDefault?: boolean;
|
|
250
265
|
}
|
|
251
266
|
```
|
|
252
267
|
|
|
@@ -297,9 +312,11 @@ Handles file upload and deletion. Extends `BaseApiService` (from ng-core).
|
|
|
297
312
|
|--------|----------|-------------|
|
|
298
313
|
| `uploadSingleFile(file, options?)` | `POST /storage/upload/single-file` | Upload single file |
|
|
299
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 |
|
|
300
316
|
| `deleteSingleFile(key, storageConfigId?)` | `POST /storage/upload/delete-single-file` | Delete single file from storage |
|
|
301
317
|
| `deleteMultipleFiles(keys, storageConfigId?)` | `POST /storage/upload/delete-multiple-file` | Delete multiple files |
|
|
302
318
|
| `getFileUrl(key)` | `GET /storage/upload/file/:key` | Get direct file download URL |
|
|
319
|
+
| `getDefaultConfigId()` | - | Get default storage config ID from APP_CONFIG |
|
|
303
320
|
|
|
304
321
|
Upload options are sent as **query parameters**, not form data:
|
|
305
322
|
|
|
@@ -351,19 +368,58 @@ Storage provider configuration CRUD. Extends `ApiResourceService<IUpdateStorageC
|
|
|
351
368
|
|
|
352
369
|
All components are standalone, use Angular 21 signal forms, and lazy-load via routes.
|
|
353
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
|
+
|
|
354
401
|
### StorageContainerComponent
|
|
355
402
|
|
|
356
|
-
Main container with tab navigation between Files, Folders, and Configs sections.
|
|
403
|
+
Main container with tab navigation between Files, Folders, and Configs sections.
|
|
357
404
|
|
|
358
405
|
**Selector:** `lib-storage-container`
|
|
359
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
|
+
|
|
360
412
|
### List Components
|
|
361
413
|
|
|
362
414
|
All list components share:
|
|
363
|
-
- **
|
|
364
|
-
- **
|
|
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
|
|
365
419
|
- **Delete confirmation** via `ConfirmationService`
|
|
366
|
-
- **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`
|
|
367
423
|
|
|
368
424
|
**FileManagerListComponent** additionally supports:
|
|
369
425
|
- File content type icons (image, video, audio, PDF, Word, Excel, generic)
|
|
@@ -377,6 +433,11 @@ All form components share:
|
|
|
377
433
|
- **Signal Forms** using Angular 21 `form()` helper with `required()` validators
|
|
378
434
|
- **Create/Edit mode** auto-detection based on route param (`:id`)
|
|
379
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`
|
|
380
441
|
|
|
381
442
|
**FileManagerFormComponent** additionally supports:
|
|
382
443
|
- PrimeNG file upload with drag-drop
|
|
@@ -389,6 +450,46 @@ All form components share:
|
|
|
389
450
|
- Azure Blob: accountName, accountKey, containerName
|
|
390
451
|
- SFTP: host, port, username, password, basePath
|
|
391
452
|
- Local: basePath
|
|
453
|
+
- **Active toggle** - enables/disables the configuration
|
|
454
|
+
- **Set as Default toggle** - marks configuration as the default for uploads
|
|
455
|
+
|
|
456
|
+
**Default Configuration:**
|
|
457
|
+
When `isDefault: true`, this configuration will be used automatically when no `storageConfigId` is provided in upload requests.
|
|
458
|
+
|
|
459
|
+
---
|
|
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
|
+
```
|
|
392
493
|
|
|
393
494
|
---
|
|
394
495
|
|
|
@@ -417,6 +518,28 @@ async uploadImage(file: File): Promise<IUploadedFileInfo | null> {
|
|
|
417
518
|
}
|
|
418
519
|
```
|
|
419
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
|
+
|
|
420
543
|
### Get Files with Presigned URLs
|
|
421
544
|
|
|
422
545
|
```typescript
|
|
@@ -555,6 +678,84 @@ services: {
|
|
|
555
678
|
}
|
|
556
679
|
```
|
|
557
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
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
708
|
+
## Provider Functions
|
|
709
|
+
|
|
710
|
+
### provideStorageProviders()
|
|
711
|
+
|
|
712
|
+
Registers provider adapters that enable other packages (ng-auth) to access storage functionality without direct dependencies.
|
|
713
|
+
|
|
714
|
+
```typescript
|
|
715
|
+
import { provideStorageProviders } from '@flusys/ng-storage';
|
|
716
|
+
|
|
717
|
+
// app.config.ts
|
|
718
|
+
export const appConfig: ApplicationConfig = {
|
|
719
|
+
providers: [
|
|
720
|
+
...provideStorageProviders(), // Register storage providers
|
|
721
|
+
],
|
|
722
|
+
};
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
**Registers:**
|
|
726
|
+
|
|
727
|
+
| Token | Adapter | Purpose |
|
|
728
|
+
|-------|---------|---------|
|
|
729
|
+
| `PROFILE_UPLOAD_PROVIDER` | `ProfileUploadProviderAdapter` | Profile picture upload for ng-auth |
|
|
730
|
+
|
|
731
|
+
### ProfileUploadProviderAdapter
|
|
732
|
+
|
|
733
|
+
Implements `IProfileUploadProvider` from ng-shared. Enables ng-auth's profile page to upload profile pictures.
|
|
734
|
+
|
|
735
|
+
```typescript
|
|
736
|
+
interface IProfileUploadProvider {
|
|
737
|
+
uploadProfilePicture(
|
|
738
|
+
file: File,
|
|
739
|
+
options?: IProfileUploadOptions
|
|
740
|
+
): Observable<ISingleResponse<IProfileUploadResult>>;
|
|
741
|
+
}
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
**Usage in ng-auth profile page:**
|
|
745
|
+
|
|
746
|
+
```typescript
|
|
747
|
+
// Optional injection - graceful degradation when storage disabled
|
|
748
|
+
private readonly uploadProvider = inject(PROFILE_UPLOAD_PROVIDER, { optional: true });
|
|
749
|
+
|
|
750
|
+
// Upload profile picture
|
|
751
|
+
if (this.uploadProvider) {
|
|
752
|
+
this.uploadProvider.uploadProfilePicture(file, { compress: true }).subscribe(response => {
|
|
753
|
+
// response.data.id contains the file manager ID
|
|
754
|
+
this.updateUserProfile({ profilePictureId: response.data.id });
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
558
759
|
---
|
|
559
760
|
|
|
560
761
|
## Public API Exports
|
|
@@ -582,9 +783,12 @@ export {
|
|
|
582
783
|
// Routes & Components
|
|
583
784
|
export { STORAGE_ROUTES } from '@flusys/ng-storage';
|
|
584
785
|
export { StorageContainerComponent } from '@flusys/ng-storage';
|
|
786
|
+
|
|
787
|
+
// Provider Functions
|
|
788
|
+
export { provideStorageProviders } from '@flusys/ng-storage';
|
|
585
789
|
```
|
|
586
790
|
|
|
587
791
|
---
|
|
588
792
|
|
|
589
|
-
**Last Updated:** 2026-02-
|
|
793
|
+
**Last Updated:** 2026-02-18
|
|
590
794
|
**Angular Version:** 21
|