@flusys/ng-storage 5.5.0 → 6.0.0-beta.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 (22) hide show
  1. package/fesm2022/{flusys-ng-storage-file-manager-form.component--W6sWv7W.mjs → flusys-ng-storage-file-manager-form.component-V-ZDWkKU.mjs} +83 -126
  2. package/fesm2022/flusys-ng-storage-file-manager-form.component-V-ZDWkKU.mjs.map +1 -0
  3. package/fesm2022/{flusys-ng-storage-file-manager-list.component-D_shqU2a.mjs → flusys-ng-storage-file-manager-list.component-DqHH9lI0.mjs} +76 -74
  4. package/fesm2022/flusys-ng-storage-file-manager-list.component-DqHH9lI0.mjs.map +1 -0
  5. package/fesm2022/{flusys-ng-storage-folder-form.component-BK2EWeV4.mjs → flusys-ng-storage-folder-form.component-Up9luV7j.mjs} +17 -17
  6. package/fesm2022/flusys-ng-storage-folder-form.component-Up9luV7j.mjs.map +1 -0
  7. package/fesm2022/{flusys-ng-storage-folder-list.component-aQXBRZiN.mjs → flusys-ng-storage-folder-list.component-B52N1JaK.mjs} +32 -35
  8. package/fesm2022/flusys-ng-storage-folder-list.component-B52N1JaK.mjs.map +1 -0
  9. package/fesm2022/{flusys-ng-storage-storage-config-form.component-ByRs-CSx.mjs → flusys-ng-storage-storage-config-form.component-CEW5gpSt.mjs} +63 -68
  10. package/fesm2022/flusys-ng-storage-storage-config-form.component-CEW5gpSt.mjs.map +1 -0
  11. package/fesm2022/{flusys-ng-storage-storage-config-list.component-cjiA8k2G.mjs → flusys-ng-storage-storage-config-list.component-C-jaO7xD.mjs} +34 -38
  12. package/fesm2022/flusys-ng-storage-storage-config-list.component-C-jaO7xD.mjs.map +1 -0
  13. package/fesm2022/flusys-ng-storage.mjs +72 -83
  14. package/fesm2022/flusys-ng-storage.mjs.map +1 -1
  15. package/package.json +5 -7
  16. package/types/flusys-ng-storage.d.ts +5 -11
  17. package/fesm2022/flusys-ng-storage-file-manager-form.component--W6sWv7W.mjs.map +0 -1
  18. package/fesm2022/flusys-ng-storage-file-manager-list.component-D_shqU2a.mjs.map +0 -1
  19. package/fesm2022/flusys-ng-storage-folder-form.component-BK2EWeV4.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-storage-folder-list.component-aQXBRZiN.mjs.map +0 -1
  21. package/fesm2022/flusys-ng-storage-storage-config-form.component-ByRs-CSx.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-storage-storage-config-list.component-cjiA8k2G.mjs.map +0 -1
@@ -3,13 +3,12 @@ import { inject, signal, computed, effect, Component } from '@angular/core';
3
3
  import { toSignal } from '@angular/core/rxjs-interop';
4
4
  import { form, required, FormField } from '@angular/forms/signals';
5
5
  import { ActivatedRoute } from '@angular/router';
6
- import { TranslateService, AngularModule, PrimeModule, TranslatePipe } from '@flusys/ng-shared';
6
+ import { TranslateService, AngularModule, TranslatePipe } from '@flusys/ng-shared';
7
7
  import { firstValueFrom } from 'rxjs';
8
8
  import { BaseStoragePage, FileManagerApiService, UploadService, StorageConfigApiService, FolderApiService, formatFileSize, getProviderLabelKey } from './flusys-ng-storage.mjs';
9
+ import * as i1$1 from '@flusys/ng-ui';
10
+ import { UiModule } from '@flusys/ng-ui';
9
11
  import * as i1 from '@angular/forms';
10
- import * as i1$1 from 'primeng/button';
11
- import * as i3 from 'primeng/fileupload';
12
- import * as i3$1 from 'primeng/inputtext';
13
12
 
14
13
  class FileManagerFormComponent extends BaseStoragePage {
15
14
  route = inject(ActivatedRoute);
@@ -204,8 +203,8 @@ class FileManagerFormComponent extends BaseStoragePage {
204
203
  onCancel() {
205
204
  this.navigateTo(['/storage/files']);
206
205
  }
207
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: FileManagerFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
208
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: FileManagerFormComponent, isStandalone: true, selector: "lib-file-manager-form", usesInheritance: true, ngImport: i0, template: `
206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: FileManagerFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
207
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: FileManagerFormComponent, isStandalone: true, selector: "lib-file-manager-form", usesInheritance: true, ngImport: i0, template: `
209
208
  <div class="card">
210
209
  <div class="mb-4">
211
210
  <h3 class="text-lg sm:text-xl font-semibold">
@@ -232,25 +231,19 @@ class FileManagerFormComponent extends BaseStoragePage {
232
231
  class="block font-medium mb-2 text-sm sm:text-base"
233
232
  >{{ 'storage.config.provider.required' | translate }}</label
234
233
  >
235
- <select
236
- id="storageConfig"
237
- class="p-select-native w-full"
234
+ <f-select
235
+ inputId="storageConfig"
236
+ [options]="availableConfigs()"
237
+ optionValue="id"
238
238
  [formField]="fileForm.storageConfigId"
239
+ [placeholder]="'storage.config.select.config' | translate"
239
240
  >
240
- <option value="">
241
- {{ 'storage.config.select.config' | translate }}
242
- </option>
243
- @for (config of availableConfigs(); track config.id) {
244
- <option [value]="config.id">
245
- {{ config.name }} ({{
246
- getProviderLabelKey(config.storage) | translate
247
- }})
248
- </option>
249
- }
250
- </select>
241
+ <ng-template #item let-config>{{ config.name }} ({{ getProviderLabelKey(config.storage) | translate }})</ng-template>
242
+ <ng-template #selectedItem let-config>{{ config.name }} ({{ getProviderLabelKey(config.storage) | translate }})</ng-template>
243
+ </f-select>
251
244
  @if (availableConfigs().length === 0 && !isLoadingConfigs()) {
252
245
  <small class="text-warn block mt-2">
253
- <i class="pi pi-exclamation-triangle mr-1"></i>
246
+ <ui-icon name="exclamation-triangle" class="mr-1"></ui-icon>
254
247
  {{ 'storage.config.no.configs' | translate }}
255
248
  </small>
256
249
  }
@@ -262,21 +255,17 @@ class FileManagerFormComponent extends BaseStoragePage {
262
255
  class="block font-medium mb-2 text-sm sm:text-base"
263
256
  >{{ 'storage.folder.optional' | translate }}</label
264
257
  >
265
- <select
266
- id="folder"
267
- class="p-select-native w-full"
258
+ <f-select
259
+ inputId="folder"
260
+ [options]="availableFolders()"
261
+ optionLabel="name"
262
+ optionValue="id"
268
263
  [formField]="fileForm.folderId"
269
- >
270
- <option value="">
271
- {{ 'storage.folder.no.folder' | translate }}
272
- </option>
273
- @for (folder of availableFolders(); track folder.id) {
274
- <option [value]="folder.id">{{ folder.name }}</option>
275
- }
276
- </select>
264
+ [placeholder]="'storage.folder.no.folder' | translate"
265
+ />
277
266
  @if (availableFolders().length === 0 && !isLoadingFolders()) {
278
267
  <small class="text-muted-color block mt-2">
279
- <i class="pi pi-info-circle mr-1"></i>
268
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
280
269
  {{ 'storage.folder.no.folders.available' | translate }}
281
270
  </small>
282
271
  }
@@ -289,21 +278,17 @@ class FileManagerFormComponent extends BaseStoragePage {
289
278
  class="block font-medium mb-2 text-sm sm:text-base"
290
279
  >{{ 'storage.folder.optional' | translate }}</label
291
280
  >
292
- <select
293
- id="folder"
294
- class="p-select-native w-full"
281
+ <f-select
282
+ inputId="folder"
283
+ [options]="availableFolders()"
284
+ optionLabel="name"
285
+ optionValue="id"
295
286
  [formField]="fileForm.folderId"
296
- >
297
- <option value="">
298
- {{ 'storage.folder.no.folder' | translate }}
299
- </option>
300
- @for (folder of availableFolders(); track folder.id) {
301
- <option [value]="folder.id">{{ folder.name }}</option>
302
- }
303
- </select>
287
+ [placeholder]="'storage.folder.no.folder' | translate"
288
+ />
304
289
  @if (availableFolders().length === 0 && !isLoadingFolders()) {
305
290
  <small class="text-muted-color block mt-2">
306
- <i class="pi pi-info-circle mr-1"></i>
291
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
307
292
  {{ 'storage.folder.no.folders.edit' | translate }}
308
293
  </small>
309
294
  }
@@ -315,7 +300,7 @@ class FileManagerFormComponent extends BaseStoragePage {
315
300
  <label class="block font-medium mb-2 text-sm sm:text-base">{{
316
301
  'storage.file.select.required' | translate
317
302
  }}</label>
318
- <p-fileupload
303
+ <f-fileupload
319
304
  #fileUpload
320
305
  [customUpload]="true"
321
306
  (onSelect)="onFileSelect($event)"
@@ -324,7 +309,7 @@ class FileManagerFormComponent extends BaseStoragePage {
324
309
  [showUploadButton]="false"
325
310
  [showCancelButton]="false"
326
311
  [chooseLabel]="'storage.button.choose.file' | translate"
327
- chooseIcon="pi pi-upload"
312
+ chooseIcon="upload"
328
313
  accept="*/*"
329
314
  class="w-full"
330
315
  >
@@ -335,9 +320,7 @@ class FileManagerFormComponent extends BaseStoragePage {
335
320
  <div
336
321
  class="flex items-center gap-3 p-3 border border-surface rounded-lg bg-surface-ground"
337
322
  >
338
- <i
339
- class="pi pi-file text-xl sm:text-2xl text-primary"
340
- ></i>
323
+ <ui-icon name="file" class="text-xl sm:text-2xl text-primary"></ui-icon>
341
324
  <div class="flex-1 min-w-0">
342
325
  <div class="font-medium truncate">
343
326
  {{ file.name }}
@@ -347,13 +330,13 @@ class FileManagerFormComponent extends BaseStoragePage {
347
330
  </div>
348
331
  </div>
349
332
  <button
350
- pButton
333
+ fButton
351
334
  [text]="true"
352
335
  severity="danger"
353
336
  size="small"
354
337
  (click)="fileUpload.clear()"
355
338
  >
356
- <span pButtonIcon class="pi pi-times"></span>
339
+ <ui-icon pButtonIcon name="times"></ui-icon>
357
340
  </button>
358
341
  </div>
359
342
  }
@@ -362,9 +345,7 @@ class FileManagerFormComponent extends BaseStoragePage {
362
345
  <div
363
346
  class="flex items-center justify-center flex-col p-6 sm:p-8 border-2 border-dashed border-surface rounded-lg"
364
347
  >
365
- <i
366
- class="pi pi-cloud-upload text-3xl sm:text-4xl text-muted-color mb-3"
367
- ></i>
348
+ <ui-icon name="cloud-upload" class="text-3xl sm:text-4xl text-muted-color mb-3"></ui-icon>
368
349
  <p
369
350
  class="text-muted-color text-center text-sm sm:text-base"
370
351
  >
@@ -378,7 +359,7 @@ class FileManagerFormComponent extends BaseStoragePage {
378
359
  </div>
379
360
  }
380
361
  </ng-template>
381
- </p-fileupload>
362
+ </f-fileupload>
382
363
  @if (!selectedFile() && !isEditMode()) {
383
364
  <small class="text-muted-color">{{
384
365
  'storage.upload.please.select' | translate
@@ -395,7 +376,7 @@ class FileManagerFormComponent extends BaseStoragePage {
395
376
  >{{ 'storage.file.name.required' | translate }}</label
396
377
  >
397
378
  <input
398
- pInputText
379
+ fInputText
399
380
  id="name"
400
381
  [formField]="fileForm.name"
401
382
  [placeholder]="
@@ -409,10 +390,7 @@ class FileManagerFormComponent extends BaseStoragePage {
409
390
  </div>
410
391
 
411
392
  <div class="field">
412
- <label class="p-checkbox-native flex items-center gap-2">
413
- <input type="checkbox" [formField]="fileForm.isPrivate" />
414
- <span>{{ 'storage.file.private' | translate }}</span>
415
- </label>
393
+ <f-checkbox [formField]="fileForm.isPrivate" [label]="'storage.file.private' | translate" />
416
394
  <small class="text-muted-color block mt-2">
417
395
  {{
418
396
  (formModel().isPrivate
@@ -426,7 +404,7 @@ class FileManagerFormComponent extends BaseStoragePage {
426
404
 
427
405
  <div class="flex justify-end gap-2 mt-4">
428
406
  <button
429
- pButton
407
+ fButton
430
408
  severity="secondary"
431
409
  [outlined]="true"
432
410
  (click)="onCancel()"
@@ -434,7 +412,7 @@ class FileManagerFormComponent extends BaseStoragePage {
434
412
  <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
435
413
  </button>
436
414
  <button
437
- pButton
415
+ fButton
438
416
  type="submit"
439
417
  [disabled]="
440
418
  !isFormValid() ||
@@ -443,7 +421,7 @@ class FileManagerFormComponent extends BaseStoragePage {
443
421
  "
444
422
  >
445
423
  @if (isLoading()) {
446
- <span pButtonIcon class="pi pi-spinner pi-spin"></span>
424
+ <ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
447
425
  }
448
426
  <span pButtonLabel>{{
449
427
  (isEditMode() ? 'shared.update' : 'shared.upload') | translate
@@ -452,13 +430,13 @@ class FileManagerFormComponent extends BaseStoragePage {
452
430
  </div>
453
431
  </form>
454
432
  </div>
455
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PrimeModule }, { kind: "directive", type: i1$1.ButtonDirective, selector: "[pButton]", inputs: ["pButton", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "link", "rounded", "fluid", "variant", "iconOnly", "loading", "severity"] }, { kind: "directive", type: i1$1.ButtonLabel, selector: "[pButtonLabel]", inputs: ["pButtonLabelPT", "pButtonLabelUnstyled"] }, { kind: "directive", type: i1$1.ButtonIcon, selector: "[pButtonIcon]", inputs: ["pButtonIconPT", "pButtonUnstyled"] }, { kind: "component", type: i3.FileUpload, selector: "p-fileupload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "directive", type: i3$1.InputText, selector: "[pInputText]", inputs: ["hostName", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
433
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AngularModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: UiModule }, { kind: "directive", type: i1$1.FButtonDirective, selector: "[fButton]", inputs: ["severity", "text", "outlined", "link", "rounded", "raised", "fluid", "disabled", "loading", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i1$1.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "inputId", "invalid", "indeterminate", "touched", "styleClass", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "component", type: i1$1.FileUploadComponent, selector: "f-fileupload", inputs: ["name", "accept", "multiple", "auto", "maxFileSize", "fileLimit", "disabled", "url", "customUpload", "showUploadButton", "showCancelButton", "chooseLabel", "chooseIcon", "styleClass", "mode"], outputs: ["onSelect", "onRemove", "onClear", "onError"] }, { kind: "directive", type: i1$1.InputTextDirective, selector: "[fInputText]", inputs: ["invalid", "touched"] }, { kind: "component", type: i1$1.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "showClear", "loading", "inputId", "invalid", "touched", "styleClass", "editable"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur"] }, { kind: "component", type: i1$1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
456
434
  }
457
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: FileManagerFormComponent, decorators: [{
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: FileManagerFormComponent, decorators: [{
458
436
  type: Component,
459
437
  args: [{
460
438
  selector: 'lib-file-manager-form',
461
- imports: [AngularModule, PrimeModule, FormField, TranslatePipe],
439
+ imports: [AngularModule, UiModule, FormField, TranslatePipe],
462
440
  template: `
463
441
  <div class="card">
464
442
  <div class="mb-4">
@@ -486,25 +464,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
486
464
  class="block font-medium mb-2 text-sm sm:text-base"
487
465
  >{{ 'storage.config.provider.required' | translate }}</label
488
466
  >
489
- <select
490
- id="storageConfig"
491
- class="p-select-native w-full"
467
+ <f-select
468
+ inputId="storageConfig"
469
+ [options]="availableConfigs()"
470
+ optionValue="id"
492
471
  [formField]="fileForm.storageConfigId"
472
+ [placeholder]="'storage.config.select.config' | translate"
493
473
  >
494
- <option value="">
495
- {{ 'storage.config.select.config' | translate }}
496
- </option>
497
- @for (config of availableConfigs(); track config.id) {
498
- <option [value]="config.id">
499
- {{ config.name }} ({{
500
- getProviderLabelKey(config.storage) | translate
501
- }})
502
- </option>
503
- }
504
- </select>
474
+ <ng-template #item let-config>{{ config.name }} ({{ getProviderLabelKey(config.storage) | translate }})</ng-template>
475
+ <ng-template #selectedItem let-config>{{ config.name }} ({{ getProviderLabelKey(config.storage) | translate }})</ng-template>
476
+ </f-select>
505
477
  @if (availableConfigs().length === 0 && !isLoadingConfigs()) {
506
478
  <small class="text-warn block mt-2">
507
- <i class="pi pi-exclamation-triangle mr-1"></i>
479
+ <ui-icon name="exclamation-triangle" class="mr-1"></ui-icon>
508
480
  {{ 'storage.config.no.configs' | translate }}
509
481
  </small>
510
482
  }
@@ -516,21 +488,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
516
488
  class="block font-medium mb-2 text-sm sm:text-base"
517
489
  >{{ 'storage.folder.optional' | translate }}</label
518
490
  >
519
- <select
520
- id="folder"
521
- class="p-select-native w-full"
491
+ <f-select
492
+ inputId="folder"
493
+ [options]="availableFolders()"
494
+ optionLabel="name"
495
+ optionValue="id"
522
496
  [formField]="fileForm.folderId"
523
- >
524
- <option value="">
525
- {{ 'storage.folder.no.folder' | translate }}
526
- </option>
527
- @for (folder of availableFolders(); track folder.id) {
528
- <option [value]="folder.id">{{ folder.name }}</option>
529
- }
530
- </select>
497
+ [placeholder]="'storage.folder.no.folder' | translate"
498
+ />
531
499
  @if (availableFolders().length === 0 && !isLoadingFolders()) {
532
500
  <small class="text-muted-color block mt-2">
533
- <i class="pi pi-info-circle mr-1"></i>
501
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
534
502
  {{ 'storage.folder.no.folders.available' | translate }}
535
503
  </small>
536
504
  }
@@ -543,21 +511,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
543
511
  class="block font-medium mb-2 text-sm sm:text-base"
544
512
  >{{ 'storage.folder.optional' | translate }}</label
545
513
  >
546
- <select
547
- id="folder"
548
- class="p-select-native w-full"
514
+ <f-select
515
+ inputId="folder"
516
+ [options]="availableFolders()"
517
+ optionLabel="name"
518
+ optionValue="id"
549
519
  [formField]="fileForm.folderId"
550
- >
551
- <option value="">
552
- {{ 'storage.folder.no.folder' | translate }}
553
- </option>
554
- @for (folder of availableFolders(); track folder.id) {
555
- <option [value]="folder.id">{{ folder.name }}</option>
556
- }
557
- </select>
520
+ [placeholder]="'storage.folder.no.folder' | translate"
521
+ />
558
522
  @if (availableFolders().length === 0 && !isLoadingFolders()) {
559
523
  <small class="text-muted-color block mt-2">
560
- <i class="pi pi-info-circle mr-1"></i>
524
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
561
525
  {{ 'storage.folder.no.folders.edit' | translate }}
562
526
  </small>
563
527
  }
@@ -569,7 +533,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
569
533
  <label class="block font-medium mb-2 text-sm sm:text-base">{{
570
534
  'storage.file.select.required' | translate
571
535
  }}</label>
572
- <p-fileupload
536
+ <f-fileupload
573
537
  #fileUpload
574
538
  [customUpload]="true"
575
539
  (onSelect)="onFileSelect($event)"
@@ -578,7 +542,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
578
542
  [showUploadButton]="false"
579
543
  [showCancelButton]="false"
580
544
  [chooseLabel]="'storage.button.choose.file' | translate"
581
- chooseIcon="pi pi-upload"
545
+ chooseIcon="upload"
582
546
  accept="*/*"
583
547
  class="w-full"
584
548
  >
@@ -589,9 +553,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
589
553
  <div
590
554
  class="flex items-center gap-3 p-3 border border-surface rounded-lg bg-surface-ground"
591
555
  >
592
- <i
593
- class="pi pi-file text-xl sm:text-2xl text-primary"
594
- ></i>
556
+ <ui-icon name="file" class="text-xl sm:text-2xl text-primary"></ui-icon>
595
557
  <div class="flex-1 min-w-0">
596
558
  <div class="font-medium truncate">
597
559
  {{ file.name }}
@@ -601,13 +563,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
601
563
  </div>
602
564
  </div>
603
565
  <button
604
- pButton
566
+ fButton
605
567
  [text]="true"
606
568
  severity="danger"
607
569
  size="small"
608
570
  (click)="fileUpload.clear()"
609
571
  >
610
- <span pButtonIcon class="pi pi-times"></span>
572
+ <ui-icon pButtonIcon name="times"></ui-icon>
611
573
  </button>
612
574
  </div>
613
575
  }
@@ -616,9 +578,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
616
578
  <div
617
579
  class="flex items-center justify-center flex-col p-6 sm:p-8 border-2 border-dashed border-surface rounded-lg"
618
580
  >
619
- <i
620
- class="pi pi-cloud-upload text-3xl sm:text-4xl text-muted-color mb-3"
621
- ></i>
581
+ <ui-icon name="cloud-upload" class="text-3xl sm:text-4xl text-muted-color mb-3"></ui-icon>
622
582
  <p
623
583
  class="text-muted-color text-center text-sm sm:text-base"
624
584
  >
@@ -632,7 +592,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
632
592
  </div>
633
593
  }
634
594
  </ng-template>
635
- </p-fileupload>
595
+ </f-fileupload>
636
596
  @if (!selectedFile() && !isEditMode()) {
637
597
  <small class="text-muted-color">{{
638
598
  'storage.upload.please.select' | translate
@@ -649,7 +609,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
649
609
  >{{ 'storage.file.name.required' | translate }}</label
650
610
  >
651
611
  <input
652
- pInputText
612
+ fInputText
653
613
  id="name"
654
614
  [formField]="fileForm.name"
655
615
  [placeholder]="
@@ -663,10 +623,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
663
623
  </div>
664
624
 
665
625
  <div class="field">
666
- <label class="p-checkbox-native flex items-center gap-2">
667
- <input type="checkbox" [formField]="fileForm.isPrivate" />
668
- <span>{{ 'storage.file.private' | translate }}</span>
669
- </label>
626
+ <f-checkbox [formField]="fileForm.isPrivate" [label]="'storage.file.private' | translate" />
670
627
  <small class="text-muted-color block mt-2">
671
628
  {{
672
629
  (formModel().isPrivate
@@ -680,7 +637,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
680
637
 
681
638
  <div class="flex justify-end gap-2 mt-4">
682
639
  <button
683
- pButton
640
+ fButton
684
641
  severity="secondary"
685
642
  [outlined]="true"
686
643
  (click)="onCancel()"
@@ -688,7 +645,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
688
645
  <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
689
646
  </button>
690
647
  <button
691
- pButton
648
+ fButton
692
649
  type="submit"
693
650
  [disabled]="
694
651
  !isFormValid() ||
@@ -697,7 +654,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
697
654
  "
698
655
  >
699
656
  @if (isLoading()) {
700
- <span pButtonIcon class="pi pi-spinner pi-spin"></span>
657
+ <ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
701
658
  }
702
659
  <span pButtonLabel>{{
703
660
  (isEditMode() ? 'shared.update' : 'shared.upload') | translate
@@ -711,4 +668,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
711
668
  }], ctorParameters: () => [] });
712
669
 
713
670
  export { FileManagerFormComponent };
714
- //# sourceMappingURL=flusys-ng-storage-file-manager-form.component--W6sWv7W.mjs.map
671
+ //# sourceMappingURL=flusys-ng-storage-file-manager-form.component-V-ZDWkKU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-storage-file-manager-form.component-V-ZDWkKU.mjs","sources":["../../../projects/ng-storage/pages/file-manager/file-manager-form.component.ts"],"sourcesContent":["import { Component, computed, effect, inject, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute } from '@angular/router';\nimport {\n AngularModule,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport { IFileManager } from '../../interfaces/file-manager.interface';\nimport { IFolder } from '../../interfaces/folder.interface';\nimport { IStorageConfig } from '../../interfaces/storage-config.interface';\nimport { FileManagerApiService } from '../../services/file-manager-api.service';\nimport { FolderApiService } from '../../services/folder-api.service';\nimport { StorageConfigApiService } from '../../services/storage-config-api.service';\nimport { UploadService } from '../../services/upload.service';\nimport { BaseStoragePage } from '../../utils/base-storage-page';\nimport { formatFileSize, getProviderLabelKey } from '../../utils/storage-utils';\nimport { FileSelectEvent, UiModule } from '@flusys/ng-ui';\n\ninterface IFileManagerFormModel {\n id: string;\n name: string;\n isPrivate: boolean;\n folderId: string;\n storageConfigId: string;\n}\n\n@Component({\n selector: 'lib-file-manager-form',\n imports: [AngularModule, UiModule, FormField, TranslatePipe],\n template: `\n <div class=\"card\">\n <div class=\"mb-4\">\n <h3 class=\"text-lg sm:text-xl font-semibold\">\n {{\n (isEditMode()\n ? 'storage.file.manager.edit.file'\n : 'storage.file.manager.upload.file'\n ) | translate\n }}\n </h3>\n @if (showCompanyInfo()) {\n <p class=\"text-sm text-muted-color mt-1\">\n {{ 'shared.company' | translate }}: {{ currentCompanyName() }}\n </p>\n }\n </div>\n\n <form (ngSubmit)=\"onSubmit()\">\n @if (!isEditMode()) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div class=\"field\">\n <label\n for=\"storageConfig\"\n class=\"block font-medium mb-2 text-sm sm:text-base\"\n >{{ 'storage.config.provider.required' | translate }}</label\n >\n <f-select\n inputId=\"storageConfig\"\n [options]=\"availableConfigs()\"\n optionValue=\"id\"\n [formField]=\"fileForm.storageConfigId\"\n [placeholder]=\"'storage.config.select.config' | translate\"\n >\n <ng-template #item let-config>{{ config.name }} ({{ getProviderLabelKey(config.storage) | translate }})</ng-template>\n <ng-template #selectedItem let-config>{{ config.name }} ({{ getProviderLabelKey(config.storage) | translate }})</ng-template>\n </f-select>\n @if (availableConfigs().length === 0 && !isLoadingConfigs()) {\n <small class=\"text-warn block mt-2\">\n <ui-icon name=\"exclamation-triangle\" class=\"mr-1\"></ui-icon>\n {{ 'storage.config.no.configs' | translate }}\n </small>\n }\n </div>\n\n <div class=\"field\">\n <label\n for=\"folder\"\n class=\"block font-medium mb-2 text-sm sm:text-base\"\n >{{ 'storage.folder.optional' | translate }}</label\n >\n <f-select\n inputId=\"folder\"\n [options]=\"availableFolders()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [formField]=\"fileForm.folderId\"\n [placeholder]=\"'storage.folder.no.folder' | translate\"\n />\n @if (availableFolders().length === 0 && !isLoadingFolders()) {\n <small class=\"text-muted-color block mt-2\">\n <ui-icon name=\"info-circle\" class=\"mr-1\"></ui-icon>\n {{ 'storage.folder.no.folders.available' | translate }}\n </small>\n }\n </div>\n </div>\n } @else {\n <div class=\"field mb-4\">\n <label\n for=\"folder\"\n class=\"block font-medium mb-2 text-sm sm:text-base\"\n >{{ 'storage.folder.optional' | translate }}</label\n >\n <f-select\n inputId=\"folder\"\n [options]=\"availableFolders()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [formField]=\"fileForm.folderId\"\n [placeholder]=\"'storage.folder.no.folder' | translate\"\n />\n @if (availableFolders().length === 0 && !isLoadingFolders()) {\n <small class=\"text-muted-color block mt-2\">\n <ui-icon name=\"info-circle\" class=\"mr-1\"></ui-icon>\n {{ 'storage.folder.no.folders.edit' | translate }}\n </small>\n }\n </div>\n }\n\n @if (!isEditMode()) {\n <div class=\"field mb-4\">\n <label class=\"block font-medium mb-2 text-sm sm:text-base\">{{\n 'storage.file.select.required' | translate\n }}</label>\n <f-fileupload\n #fileUpload\n [customUpload]=\"true\"\n (onSelect)=\"onFileSelect($event)\"\n [multiple]=\"false\"\n [maxFileSize]=\"50000000\"\n [showUploadButton]=\"false\"\n [showCancelButton]=\"false\"\n [chooseLabel]=\"'storage.button.choose.file' | translate\"\n chooseIcon=\"upload\"\n accept=\"*/*\"\n class=\"w-full\"\n >\n <ng-template #content let-files>\n @if (files && files.length > 0) {\n <div class=\"flex flex-col gap-2\">\n @for (file of files; track file.name) {\n <div\n class=\"flex items-center gap-3 p-3 border border-surface rounded-lg bg-surface-ground\"\n >\n <ui-icon name=\"file\" class=\"text-xl sm:text-2xl text-primary\"></ui-icon>\n <div class=\"flex-1 min-w-0\">\n <div class=\"font-medium truncate\">\n {{ file.name }}\n </div>\n <div class=\"text-sm text-muted-color\">\n {{ formatFileSize(file.size) }}\n </div>\n </div>\n <button\n fButton\n [text]=\"true\"\n severity=\"danger\"\n size=\"small\"\n (click)=\"fileUpload.clear()\"\n >\n <ui-icon pButtonIcon name=\"times\"></ui-icon>\n </button>\n </div>\n }\n </div>\n } @else {\n <div\n class=\"flex items-center justify-center flex-col p-6 sm:p-8 border-2 border-dashed border-surface rounded-lg\"\n >\n <ui-icon name=\"cloud-upload\" class=\"text-3xl sm:text-4xl text-muted-color mb-3\"></ui-icon>\n <p\n class=\"text-muted-color text-center text-sm sm:text-base\"\n >\n {{ 'storage.upload.drag.drop' | translate }}\n </p>\n <p class=\"text-xs sm:text-sm text-muted-color mt-2\">\n {{\n 'storage.upload.max.size' | translate: { size: '50MB' }\n }}\n </p>\n </div>\n }\n </ng-template>\n </f-fileupload>\n @if (!selectedFile() && !isEditMode()) {\n <small class=\"text-muted-color\">{{\n 'storage.upload.please.select' | translate\n }}</small>\n }\n </div>\n }\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div class=\"field md:col-span-2\">\n <label\n for=\"name\"\n class=\"block font-medium mb-2 text-sm sm:text-base\"\n >{{ 'storage.file.name.required' | translate }}</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"fileForm.name\"\n [placeholder]=\"\n (isEditMode()\n ? 'storage.file.placeholder.edit'\n : 'storage.file.placeholder'\n ) | translate\n \"\n class=\"w-full\"\n />\n </div>\n\n <div class=\"field\">\n <f-checkbox [formField]=\"fileForm.isPrivate\" [label]=\"'storage.file.private' | translate\" />\n <small class=\"text-muted-color block mt-2\">\n {{\n (formModel().isPrivate\n ? 'storage.file.private.hint'\n : 'storage.file.public.hint'\n ) | translate\n }}\n </small>\n </div>\n </div>\n\n <div class=\"flex justify-end gap-2 mt-4\">\n <button\n fButton\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"onCancel()\"\n >\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button\n fButton\n type=\"submit\"\n [disabled]=\"\n !isFormValid() ||\n (!isEditMode() && !selectedFile()) ||\n isLoading()\n \"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ \n (isEditMode() ? 'shared.update' : 'shared.upload') | translate\n }}</span>\n </button>\n </div>\n </form>\n </div>\n `,\n})\nexport class FileManagerFormComponent extends BaseStoragePage {\n private readonly route = inject(ActivatedRoute);\n private readonly fileService = inject(FileManagerApiService);\n private readonly uploadService = inject(UploadService);\n private readonly configService = inject(StorageConfigApiService);\n private readonly folderService = inject(FolderApiService);\n private readonly translateService = inject(TranslateService);\n\n private readonly routeParams = toSignal(this.route.paramMap);\n private initialized = false;\n\n readonly isLoadingConfigs = signal(false);\n readonly isLoadingFolders = signal(false);\n readonly existingFile = signal<IFileManager | null>(null);\n readonly isEditMode = computed(() => !!this.existingFile());\n readonly selectedFile = signal<File | null>(null);\n readonly availableConfigs = signal<IStorageConfig[]>([]);\n readonly availableFolders = signal<IFolder[]>([]);\n\n readonly formatFileSize = formatFileSize;\n readonly getProviderLabelKey = getProviderLabelKey;\n\n readonly formModel = signal<IFileManagerFormModel>({\n id: '',\n name: '',\n isPrivate: false,\n folderId: '',\n storageConfigId: '',\n });\n\n readonly fileForm = form(this.formModel, (f) => {\n required(f.name, {\n message: this.translateService.translate(\n 'storage.validation.file.name.required',\n ),\n });\n });\n\n readonly isFormValid = computed(\n () => this.formModel().name.trim().length > 0,\n );\n\n constructor() {\n super();\n effect(() => {\n const params = this.routeParams();\n if (!params || this.initialized) return;\n\n this.initialized = true;\n const fileId = params.get('id');\n if (fileId) {\n this.loadFile(fileId);\n } else {\n this.loadStorageConfigs();\n }\n this.loadFolders();\n });\n }\n\n async loadStorageConfigs(): Promise<void> {\n this.isLoadingConfigs.set(true);\n try {\n const response = await this.configService.getAll({\n pagination: { currentPage: 0, pageSize: 100 },\n filter: {},\n select: [],\n sort: {},\n });\n if (response.success && response.data) {\n this.availableConfigs.set(response.data);\n if (response.data.length === 1) {\n this.formModel.update((m) => ({\n ...m,\n storageConfigId: response.data![0].id,\n }));\n }\n }\n } finally {\n this.isLoadingConfigs.set(false);\n }\n }\n\n async loadFolders(): Promise<void> {\n this.isLoadingFolders.set(true);\n try {\n const response = await this.folderService.getAll({\n pagination: { currentPage: 0, pageSize: 100 },\n filter: {},\n select: [],\n sort: {},\n });\n if (response.success && response.data) {\n this.availableFolders.set(response.data);\n }\n } catch {\n // Silently fail - folders are optional\n } finally {\n this.isLoadingFolders.set(false);\n }\n }\n\n async loadFile(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.fileService.findById(id);\n if (response.success && response.data) {\n const file = response.data;\n this.existingFile.set(file);\n this.formModel.set({\n id: file.id,\n name: file.name,\n isPrivate: file.isPrivate ?? false,\n folderId: file.folderId ?? '',\n storageConfigId: '',\n });\n }\n } catch {\n this.navigateTo(['/storage/files']);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onFileSelect(event: FileSelectEvent): void {\n const file = event.files?.[0] || event.currentFiles?.[0];\n if (file) {\n this.selectedFile.set(file);\n this.formModel.update((m) => ({ ...m, name: file.name }));\n }\n }\n\n async onSubmit(): Promise<void> {\n if (!this.isFormValid()) return;\n\n this.isLoading.set(true);\n try {\n const formValue = this.formModel();\n\n if (this.isEditMode()) {\n const response = await this.fileService.update({\n id: formValue.id,\n name: formValue.name,\n isPrivate: formValue.isPrivate,\n folderId: formValue.folderId || null,\n });\n this.showSuccess(\n response.messageKey\n ? this.translateService.translate(\n response.messageKey,\n response.messageVariables as Record<string, string | number>,\n )\n : (response.message ?? ''),\n );\n } else {\n const file = this.selectedFile();\n if (!file) {\n this.showError(\n this.translateService.translate('storage.error.no.file'),\n );\n return;\n }\n\n if (!formValue.storageConfigId) {\n this.showError(\n this.translateService.translate('storage.error.no.config'),\n );\n return;\n }\n\n const uploadResponse = await firstValueFrom(\n this.uploadService.uploadSingleFile(file, {\n compress: true,\n quality: 85,\n storageConfigId: formValue.storageConfigId,\n }),\n );\n\n if (uploadResponse.success && uploadResponse.data) {\n const uploadedFileInfo = uploadResponse.data;\n const createResponse = await firstValueFrom(\n this.fileService.createFile({\n name: formValue.name,\n key: uploadedFileInfo.key,\n contentType: file.type || 'application/octet-stream',\n size: Math.round(file.size / 1024).toString(),\n isPrivate: formValue.isPrivate,\n folderId: formValue.folderId || undefined,\n storageConfigId: formValue.storageConfigId,\n }),\n );\n this.showSuccess(\n createResponse?.messageKey\n ? this.translateService.translate(\n createResponse.messageKey,\n createResponse.messageVariables as Record<\n string,\n string | number\n >,\n )\n : (createResponse?.message ?? ''),\n );\n } else {\n throw new Error(\n this.translateService.translate('storage.upload.failed'),\n );\n }\n }\n\n this.navigateTo(['/storage/files']);\n } catch {\n this.showError(this.translateService.translate('storage.upload.failed'));\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onCancel(): void {\n this.navigateTo(['/storage/files']);\n }\n}\n"],"names":["i2"],"mappings":"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"}