@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
@@ -0,0 +1,671 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, effect, Component } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { form, required, FormField } from '@angular/forms/signals';
5
+ import { ActivatedRoute } from '@angular/router';
6
+ import { TranslateService, AngularModule, TranslatePipe } from '@flusys/ng-shared';
7
+ import { firstValueFrom } from 'rxjs';
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';
11
+ import * as i1 from '@angular/forms';
12
+
13
+ class FileManagerFormComponent extends BaseStoragePage {
14
+ route = inject(ActivatedRoute);
15
+ fileService = inject(FileManagerApiService);
16
+ uploadService = inject(UploadService);
17
+ configService = inject(StorageConfigApiService);
18
+ folderService = inject(FolderApiService);
19
+ translateService = inject(TranslateService);
20
+ routeParams = toSignal(this.route.paramMap);
21
+ initialized = false;
22
+ isLoadingConfigs = signal(false, /* @ts-ignore */
23
+ ...(ngDevMode ? [{ debugName: "isLoadingConfigs" }] : /* istanbul ignore next */ []));
24
+ isLoadingFolders = signal(false, /* @ts-ignore */
25
+ ...(ngDevMode ? [{ debugName: "isLoadingFolders" }] : /* istanbul ignore next */ []));
26
+ existingFile = signal(null, /* @ts-ignore */
27
+ ...(ngDevMode ? [{ debugName: "existingFile" }] : /* istanbul ignore next */ []));
28
+ isEditMode = computed(() => !!this.existingFile(), /* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "isEditMode" }] : /* istanbul ignore next */ []));
30
+ selectedFile = signal(null, /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "selectedFile" }] : /* istanbul ignore next */ []));
32
+ availableConfigs = signal([], /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "availableConfigs" }] : /* istanbul ignore next */ []));
34
+ availableFolders = signal([], /* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "availableFolders" }] : /* istanbul ignore next */ []));
36
+ formatFileSize = formatFileSize;
37
+ getProviderLabelKey = getProviderLabelKey;
38
+ formModel = signal({
39
+ id: '',
40
+ name: '',
41
+ isPrivate: false,
42
+ folderId: '',
43
+ storageConfigId: '',
44
+ }, /* @ts-ignore */
45
+ ...(ngDevMode ? [{ debugName: "formModel" }] : /* istanbul ignore next */ []));
46
+ fileForm = form(this.formModel, (f) => {
47
+ required(f.name, {
48
+ message: this.translateService.translate('storage.validation.file.name.required'),
49
+ });
50
+ });
51
+ isFormValid = computed(() => this.formModel().name.trim().length > 0, /* @ts-ignore */
52
+ ...(ngDevMode ? [{ debugName: "isFormValid" }] : /* istanbul ignore next */ []));
53
+ constructor() {
54
+ super();
55
+ effect(() => {
56
+ const params = this.routeParams();
57
+ if (!params || this.initialized)
58
+ return;
59
+ this.initialized = true;
60
+ const fileId = params.get('id');
61
+ if (fileId) {
62
+ this.loadFile(fileId);
63
+ }
64
+ else {
65
+ this.loadStorageConfigs();
66
+ }
67
+ this.loadFolders();
68
+ });
69
+ }
70
+ async loadStorageConfigs() {
71
+ this.isLoadingConfigs.set(true);
72
+ try {
73
+ const response = await this.configService.getAll({
74
+ pagination: { currentPage: 0, pageSize: 100 },
75
+ filter: {},
76
+ select: [],
77
+ sort: {},
78
+ });
79
+ if (response.success && response.data) {
80
+ this.availableConfigs.set(response.data);
81
+ if (response.data.length === 1) {
82
+ this.formModel.update((m) => ({
83
+ ...m,
84
+ storageConfigId: response.data[0].id,
85
+ }));
86
+ }
87
+ }
88
+ }
89
+ finally {
90
+ this.isLoadingConfigs.set(false);
91
+ }
92
+ }
93
+ async loadFolders() {
94
+ this.isLoadingFolders.set(true);
95
+ try {
96
+ const response = await this.folderService.getAll({
97
+ pagination: { currentPage: 0, pageSize: 100 },
98
+ filter: {},
99
+ select: [],
100
+ sort: {},
101
+ });
102
+ if (response.success && response.data) {
103
+ this.availableFolders.set(response.data);
104
+ }
105
+ }
106
+ catch {
107
+ // Silently fail - folders are optional
108
+ }
109
+ finally {
110
+ this.isLoadingFolders.set(false);
111
+ }
112
+ }
113
+ async loadFile(id) {
114
+ this.isLoading.set(true);
115
+ try {
116
+ const response = await this.fileService.findById(id);
117
+ if (response.success && response.data) {
118
+ const file = response.data;
119
+ this.existingFile.set(file);
120
+ this.formModel.set({
121
+ id: file.id,
122
+ name: file.name,
123
+ isPrivate: file.isPrivate ?? false,
124
+ folderId: file.folderId ?? '',
125
+ storageConfigId: '',
126
+ });
127
+ }
128
+ }
129
+ catch {
130
+ this.navigateTo(['/storage/files']);
131
+ }
132
+ finally {
133
+ this.isLoading.set(false);
134
+ }
135
+ }
136
+ onFileSelect(event) {
137
+ const file = event.files?.[0] || event.currentFiles?.[0];
138
+ if (file) {
139
+ this.selectedFile.set(file);
140
+ this.formModel.update((m) => ({ ...m, name: file.name }));
141
+ }
142
+ }
143
+ async onSubmit() {
144
+ if (!this.isFormValid())
145
+ return;
146
+ this.isLoading.set(true);
147
+ try {
148
+ const formValue = this.formModel();
149
+ if (this.isEditMode()) {
150
+ const response = await this.fileService.update({
151
+ id: formValue.id,
152
+ name: formValue.name,
153
+ isPrivate: formValue.isPrivate,
154
+ folderId: formValue.folderId || null,
155
+ });
156
+ this.showSuccess(response.messageKey
157
+ ? this.translateService.translate(response.messageKey, response.messageVariables)
158
+ : (response.message ?? ''));
159
+ }
160
+ else {
161
+ const file = this.selectedFile();
162
+ if (!file) {
163
+ this.showError(this.translateService.translate('storage.error.no.file'));
164
+ return;
165
+ }
166
+ if (!formValue.storageConfigId) {
167
+ this.showError(this.translateService.translate('storage.error.no.config'));
168
+ return;
169
+ }
170
+ const uploadResponse = await firstValueFrom(this.uploadService.uploadSingleFile(file, {
171
+ compress: true,
172
+ quality: 85,
173
+ storageConfigId: formValue.storageConfigId,
174
+ }));
175
+ if (uploadResponse.success && uploadResponse.data) {
176
+ const uploadedFileInfo = uploadResponse.data;
177
+ const createResponse = await firstValueFrom(this.fileService.createFile({
178
+ name: formValue.name,
179
+ key: uploadedFileInfo.key,
180
+ contentType: file.type || 'application/octet-stream',
181
+ size: Math.round(file.size / 1024).toString(),
182
+ isPrivate: formValue.isPrivate,
183
+ folderId: formValue.folderId || undefined,
184
+ storageConfigId: formValue.storageConfigId,
185
+ }));
186
+ this.showSuccess(createResponse?.messageKey
187
+ ? this.translateService.translate(createResponse.messageKey, createResponse.messageVariables)
188
+ : (createResponse?.message ?? ''));
189
+ }
190
+ else {
191
+ throw new Error(this.translateService.translate('storage.upload.failed'));
192
+ }
193
+ }
194
+ this.navigateTo(['/storage/files']);
195
+ }
196
+ catch {
197
+ this.showError(this.translateService.translate('storage.upload.failed'));
198
+ }
199
+ finally {
200
+ this.isLoading.set(false);
201
+ }
202
+ }
203
+ onCancel() {
204
+ this.navigateTo(['/storage/files']);
205
+ }
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: `
208
+ <div class="card">
209
+ <div class="mb-4">
210
+ <h3 class="text-lg sm:text-xl font-semibold">
211
+ {{
212
+ (isEditMode()
213
+ ? 'storage.file.manager.edit.file'
214
+ : 'storage.file.manager.upload.file'
215
+ ) | translate
216
+ }}
217
+ </h3>
218
+ @if (showCompanyInfo()) {
219
+ <p class="text-sm text-muted-color mt-1">
220
+ {{ 'shared.company' | translate }}: {{ currentCompanyName() }}
221
+ </p>
222
+ }
223
+ </div>
224
+
225
+ <form (ngSubmit)="onSubmit()">
226
+ @if (!isEditMode()) {
227
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
228
+ <div class="field">
229
+ <label
230
+ for="storageConfig"
231
+ class="block font-medium mb-2 text-sm sm:text-base"
232
+ >{{ 'storage.config.provider.required' | translate }}</label
233
+ >
234
+ <f-select
235
+ inputId="storageConfig"
236
+ [options]="availableConfigs()"
237
+ optionValue="id"
238
+ [formField]="fileForm.storageConfigId"
239
+ [placeholder]="'storage.config.select.config' | translate"
240
+ >
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>
244
+ @if (availableConfigs().length === 0 && !isLoadingConfigs()) {
245
+ <small class="text-warn block mt-2">
246
+ <ui-icon name="exclamation-triangle" class="mr-1"></ui-icon>
247
+ {{ 'storage.config.no.configs' | translate }}
248
+ </small>
249
+ }
250
+ </div>
251
+
252
+ <div class="field">
253
+ <label
254
+ for="folder"
255
+ class="block font-medium mb-2 text-sm sm:text-base"
256
+ >{{ 'storage.folder.optional' | translate }}</label
257
+ >
258
+ <f-select
259
+ inputId="folder"
260
+ [options]="availableFolders()"
261
+ optionLabel="name"
262
+ optionValue="id"
263
+ [formField]="fileForm.folderId"
264
+ [placeholder]="'storage.folder.no.folder' | translate"
265
+ />
266
+ @if (availableFolders().length === 0 && !isLoadingFolders()) {
267
+ <small class="text-muted-color block mt-2">
268
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
269
+ {{ 'storage.folder.no.folders.available' | translate }}
270
+ </small>
271
+ }
272
+ </div>
273
+ </div>
274
+ } @else {
275
+ <div class="field mb-4">
276
+ <label
277
+ for="folder"
278
+ class="block font-medium mb-2 text-sm sm:text-base"
279
+ >{{ 'storage.folder.optional' | translate }}</label
280
+ >
281
+ <f-select
282
+ inputId="folder"
283
+ [options]="availableFolders()"
284
+ optionLabel="name"
285
+ optionValue="id"
286
+ [formField]="fileForm.folderId"
287
+ [placeholder]="'storage.folder.no.folder' | translate"
288
+ />
289
+ @if (availableFolders().length === 0 && !isLoadingFolders()) {
290
+ <small class="text-muted-color block mt-2">
291
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
292
+ {{ 'storage.folder.no.folders.edit' | translate }}
293
+ </small>
294
+ }
295
+ </div>
296
+ }
297
+
298
+ @if (!isEditMode()) {
299
+ <div class="field mb-4">
300
+ <label class="block font-medium mb-2 text-sm sm:text-base">{{
301
+ 'storage.file.select.required' | translate
302
+ }}</label>
303
+ <f-fileupload
304
+ #fileUpload
305
+ [customUpload]="true"
306
+ (onSelect)="onFileSelect($event)"
307
+ [multiple]="false"
308
+ [maxFileSize]="50000000"
309
+ [showUploadButton]="false"
310
+ [showCancelButton]="false"
311
+ [chooseLabel]="'storage.button.choose.file' | translate"
312
+ chooseIcon="upload"
313
+ accept="*/*"
314
+ class="w-full"
315
+ >
316
+ <ng-template #content let-files>
317
+ @if (files && files.length > 0) {
318
+ <div class="flex flex-col gap-2">
319
+ @for (file of files; track file.name) {
320
+ <div
321
+ class="flex items-center gap-3 p-3 border border-surface rounded-lg bg-surface-ground"
322
+ >
323
+ <ui-icon name="file" class="text-xl sm:text-2xl text-primary"></ui-icon>
324
+ <div class="flex-1 min-w-0">
325
+ <div class="font-medium truncate">
326
+ {{ file.name }}
327
+ </div>
328
+ <div class="text-sm text-muted-color">
329
+ {{ formatFileSize(file.size) }}
330
+ </div>
331
+ </div>
332
+ <button
333
+ fButton
334
+ [text]="true"
335
+ severity="danger"
336
+ size="small"
337
+ (click)="fileUpload.clear()"
338
+ >
339
+ <ui-icon pButtonIcon name="times"></ui-icon>
340
+ </button>
341
+ </div>
342
+ }
343
+ </div>
344
+ } @else {
345
+ <div
346
+ class="flex items-center justify-center flex-col p-6 sm:p-8 border-2 border-dashed border-surface rounded-lg"
347
+ >
348
+ <ui-icon name="cloud-upload" class="text-3xl sm:text-4xl text-muted-color mb-3"></ui-icon>
349
+ <p
350
+ class="text-muted-color text-center text-sm sm:text-base"
351
+ >
352
+ {{ 'storage.upload.drag.drop' | translate }}
353
+ </p>
354
+ <p class="text-xs sm:text-sm text-muted-color mt-2">
355
+ {{
356
+ 'storage.upload.max.size' | translate: { size: '50MB' }
357
+ }}
358
+ </p>
359
+ </div>
360
+ }
361
+ </ng-template>
362
+ </f-fileupload>
363
+ @if (!selectedFile() && !isEditMode()) {
364
+ <small class="text-muted-color">{{
365
+ 'storage.upload.please.select' | translate
366
+ }}</small>
367
+ }
368
+ </div>
369
+ }
370
+
371
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
372
+ <div class="field md:col-span-2">
373
+ <label
374
+ for="name"
375
+ class="block font-medium mb-2 text-sm sm:text-base"
376
+ >{{ 'storage.file.name.required' | translate }}</label
377
+ >
378
+ <input
379
+ fInputText
380
+ id="name"
381
+ [formField]="fileForm.name"
382
+ [placeholder]="
383
+ (isEditMode()
384
+ ? 'storage.file.placeholder.edit'
385
+ : 'storage.file.placeholder'
386
+ ) | translate
387
+ "
388
+ class="w-full"
389
+ />
390
+ </div>
391
+
392
+ <div class="field">
393
+ <f-checkbox [formField]="fileForm.isPrivate" [label]="'storage.file.private' | translate" />
394
+ <small class="text-muted-color block mt-2">
395
+ {{
396
+ (formModel().isPrivate
397
+ ? 'storage.file.private.hint'
398
+ : 'storage.file.public.hint'
399
+ ) | translate
400
+ }}
401
+ </small>
402
+ </div>
403
+ </div>
404
+
405
+ <div class="flex justify-end gap-2 mt-4">
406
+ <button
407
+ fButton
408
+ severity="secondary"
409
+ [outlined]="true"
410
+ (click)="onCancel()"
411
+ >
412
+ <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
413
+ </button>
414
+ <button
415
+ fButton
416
+ type="submit"
417
+ [disabled]="
418
+ !isFormValid() ||
419
+ (!isEditMode() && !selectedFile()) ||
420
+ isLoading()
421
+ "
422
+ >
423
+ @if (isLoading()) {
424
+ <ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
425
+ }
426
+ <span pButtonLabel>{{
427
+ (isEditMode() ? 'shared.update' : 'shared.upload') | translate
428
+ }}</span>
429
+ </button>
430
+ </div>
431
+ </form>
432
+ </div>
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", "variant", "rounded", "raised", "fluid", "disabled", "loading", "loadingIcon", "size", "label", "icon", "iconPos", "ariaLabel", "plain"] }, { kind: "component", type: i1$1.CheckboxComponent, selector: "f-checkbox", inputs: ["label", "binary", "disabled", "readonly", "inputId", "invalid", "indeterminate", "variant", "size", "touched", "styleClass", "style", "checked"], outputs: ["onChange", "onBlur", "touch", "checkedChange"] }, { kind: "component", type: i1$1.FileUploadComponent, selector: "f-fileupload", inputs: ["name", "accept", "multiple", "auto", "maxFileSize", "fileLimit", "disabled", "url", "headers", "customUpload", "showUploadButton", "showCancelButton", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "previewWidth", "styleClass", "style", "mode"], outputs: ["onSelect", "onRemove", "onClear", "onError", "onUpload", "onProgress", "uploadHandler"] }, { kind: "directive", type: i1$1.InputTextDirective, selector: "[fInputText]", inputs: ["invalid", "touched", "variant", "size", "fluid"] }, { kind: "component", type: i1$1.SelectComponent, selector: "f-select", inputs: ["options", "optionLabel", "optionValue", "placeholder", "disabled", "filter", "filterBy", "filterMatchMode", "filterLocale", "filterPlaceholder", "resetFilterOnHide", "autofocusFilter", "emptyMessage", "emptyFilterMessage", "showClear", "loading", "loadingIcon", "dropdownIcon", "clearIcon", "inputId", "invalid", "touched", "styleClass", "style", "editable", "readonly", "autofocus", "checkmark", "group", "optionGroupLabel", "optionGroupChildren", "virtualScroll", "virtualScrollItemSize", "lazy"], outputs: ["onFilter", "onChange", "onShow", "onHide", "onBlur", "onFocus", "onClear", "onLazyLoad"] }, { kind: "component", type: i1$1.UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
434
+ }
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: FileManagerFormComponent, decorators: [{
436
+ type: Component,
437
+ args: [{
438
+ selector: 'lib-file-manager-form',
439
+ imports: [AngularModule, UiModule, FormField, TranslatePipe],
440
+ template: `
441
+ <div class="card">
442
+ <div class="mb-4">
443
+ <h3 class="text-lg sm:text-xl font-semibold">
444
+ {{
445
+ (isEditMode()
446
+ ? 'storage.file.manager.edit.file'
447
+ : 'storage.file.manager.upload.file'
448
+ ) | translate
449
+ }}
450
+ </h3>
451
+ @if (showCompanyInfo()) {
452
+ <p class="text-sm text-muted-color mt-1">
453
+ {{ 'shared.company' | translate }}: {{ currentCompanyName() }}
454
+ </p>
455
+ }
456
+ </div>
457
+
458
+ <form (ngSubmit)="onSubmit()">
459
+ @if (!isEditMode()) {
460
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
461
+ <div class="field">
462
+ <label
463
+ for="storageConfig"
464
+ class="block font-medium mb-2 text-sm sm:text-base"
465
+ >{{ 'storage.config.provider.required' | translate }}</label
466
+ >
467
+ <f-select
468
+ inputId="storageConfig"
469
+ [options]="availableConfigs()"
470
+ optionValue="id"
471
+ [formField]="fileForm.storageConfigId"
472
+ [placeholder]="'storage.config.select.config' | translate"
473
+ >
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>
477
+ @if (availableConfigs().length === 0 && !isLoadingConfigs()) {
478
+ <small class="text-warn block mt-2">
479
+ <ui-icon name="exclamation-triangle" class="mr-1"></ui-icon>
480
+ {{ 'storage.config.no.configs' | translate }}
481
+ </small>
482
+ }
483
+ </div>
484
+
485
+ <div class="field">
486
+ <label
487
+ for="folder"
488
+ class="block font-medium mb-2 text-sm sm:text-base"
489
+ >{{ 'storage.folder.optional' | translate }}</label
490
+ >
491
+ <f-select
492
+ inputId="folder"
493
+ [options]="availableFolders()"
494
+ optionLabel="name"
495
+ optionValue="id"
496
+ [formField]="fileForm.folderId"
497
+ [placeholder]="'storage.folder.no.folder' | translate"
498
+ />
499
+ @if (availableFolders().length === 0 && !isLoadingFolders()) {
500
+ <small class="text-muted-color block mt-2">
501
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
502
+ {{ 'storage.folder.no.folders.available' | translate }}
503
+ </small>
504
+ }
505
+ </div>
506
+ </div>
507
+ } @else {
508
+ <div class="field mb-4">
509
+ <label
510
+ for="folder"
511
+ class="block font-medium mb-2 text-sm sm:text-base"
512
+ >{{ 'storage.folder.optional' | translate }}</label
513
+ >
514
+ <f-select
515
+ inputId="folder"
516
+ [options]="availableFolders()"
517
+ optionLabel="name"
518
+ optionValue="id"
519
+ [formField]="fileForm.folderId"
520
+ [placeholder]="'storage.folder.no.folder' | translate"
521
+ />
522
+ @if (availableFolders().length === 0 && !isLoadingFolders()) {
523
+ <small class="text-muted-color block mt-2">
524
+ <ui-icon name="info-circle" class="mr-1"></ui-icon>
525
+ {{ 'storage.folder.no.folders.edit' | translate }}
526
+ </small>
527
+ }
528
+ </div>
529
+ }
530
+
531
+ @if (!isEditMode()) {
532
+ <div class="field mb-4">
533
+ <label class="block font-medium mb-2 text-sm sm:text-base">{{
534
+ 'storage.file.select.required' | translate
535
+ }}</label>
536
+ <f-fileupload
537
+ #fileUpload
538
+ [customUpload]="true"
539
+ (onSelect)="onFileSelect($event)"
540
+ [multiple]="false"
541
+ [maxFileSize]="50000000"
542
+ [showUploadButton]="false"
543
+ [showCancelButton]="false"
544
+ [chooseLabel]="'storage.button.choose.file' | translate"
545
+ chooseIcon="upload"
546
+ accept="*/*"
547
+ class="w-full"
548
+ >
549
+ <ng-template #content let-files>
550
+ @if (files && files.length > 0) {
551
+ <div class="flex flex-col gap-2">
552
+ @for (file of files; track file.name) {
553
+ <div
554
+ class="flex items-center gap-3 p-3 border border-surface rounded-lg bg-surface-ground"
555
+ >
556
+ <ui-icon name="file" class="text-xl sm:text-2xl text-primary"></ui-icon>
557
+ <div class="flex-1 min-w-0">
558
+ <div class="font-medium truncate">
559
+ {{ file.name }}
560
+ </div>
561
+ <div class="text-sm text-muted-color">
562
+ {{ formatFileSize(file.size) }}
563
+ </div>
564
+ </div>
565
+ <button
566
+ fButton
567
+ [text]="true"
568
+ severity="danger"
569
+ size="small"
570
+ (click)="fileUpload.clear()"
571
+ >
572
+ <ui-icon pButtonIcon name="times"></ui-icon>
573
+ </button>
574
+ </div>
575
+ }
576
+ </div>
577
+ } @else {
578
+ <div
579
+ class="flex items-center justify-center flex-col p-6 sm:p-8 border-2 border-dashed border-surface rounded-lg"
580
+ >
581
+ <ui-icon name="cloud-upload" class="text-3xl sm:text-4xl text-muted-color mb-3"></ui-icon>
582
+ <p
583
+ class="text-muted-color text-center text-sm sm:text-base"
584
+ >
585
+ {{ 'storage.upload.drag.drop' | translate }}
586
+ </p>
587
+ <p class="text-xs sm:text-sm text-muted-color mt-2">
588
+ {{
589
+ 'storage.upload.max.size' | translate: { size: '50MB' }
590
+ }}
591
+ </p>
592
+ </div>
593
+ }
594
+ </ng-template>
595
+ </f-fileupload>
596
+ @if (!selectedFile() && !isEditMode()) {
597
+ <small class="text-muted-color">{{
598
+ 'storage.upload.please.select' | translate
599
+ }}</small>
600
+ }
601
+ </div>
602
+ }
603
+
604
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
605
+ <div class="field md:col-span-2">
606
+ <label
607
+ for="name"
608
+ class="block font-medium mb-2 text-sm sm:text-base"
609
+ >{{ 'storage.file.name.required' | translate }}</label
610
+ >
611
+ <input
612
+ fInputText
613
+ id="name"
614
+ [formField]="fileForm.name"
615
+ [placeholder]="
616
+ (isEditMode()
617
+ ? 'storage.file.placeholder.edit'
618
+ : 'storage.file.placeholder'
619
+ ) | translate
620
+ "
621
+ class="w-full"
622
+ />
623
+ </div>
624
+
625
+ <div class="field">
626
+ <f-checkbox [formField]="fileForm.isPrivate" [label]="'storage.file.private' | translate" />
627
+ <small class="text-muted-color block mt-2">
628
+ {{
629
+ (formModel().isPrivate
630
+ ? 'storage.file.private.hint'
631
+ : 'storage.file.public.hint'
632
+ ) | translate
633
+ }}
634
+ </small>
635
+ </div>
636
+ </div>
637
+
638
+ <div class="flex justify-end gap-2 mt-4">
639
+ <button
640
+ fButton
641
+ severity="secondary"
642
+ [outlined]="true"
643
+ (click)="onCancel()"
644
+ >
645
+ <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>
646
+ </button>
647
+ <button
648
+ fButton
649
+ type="submit"
650
+ [disabled]="
651
+ !isFormValid() ||
652
+ (!isEditMode() && !selectedFile()) ||
653
+ isLoading()
654
+ "
655
+ >
656
+ @if (isLoading()) {
657
+ <ui-icon pButtonIcon name="spinner" [spin]="true"></ui-icon>
658
+ }
659
+ <span pButtonLabel>{{
660
+ (isEditMode() ? 'shared.update' : 'shared.upload') | translate
661
+ }}</span>
662
+ </button>
663
+ </div>
664
+ </form>
665
+ </div>
666
+ `,
667
+ }]
668
+ }], ctorParameters: () => [] });
669
+
670
+ export { FileManagerFormComponent };
671
+ //# sourceMappingURL=flusys-ng-storage-file-manager-form.component-DhqZmpuX.mjs.map