@flusys/ng-storage 3.0.1 → 4.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 +12 -6
- package/fesm2022/{flusys-ng-storage-file-manager-form.component-CXVB9G-f.mjs → flusys-ng-storage-file-manager-form.component-AM7JE-s5.mjs} +67 -74
- package/fesm2022/flusys-ng-storage-file-manager-form.component-AM7JE-s5.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-file-manager-list.component-0O_b4EjN.mjs → flusys-ng-storage-file-manager-list.component-bj6oOzOL.mjs} +66 -74
- package/fesm2022/flusys-ng-storage-file-manager-list.component-bj6oOzOL.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-folder-form.component-BTQGEqNu.mjs → flusys-ng-storage-folder-form.component-Cc2ybTwu.mjs} +25 -34
- package/fesm2022/flusys-ng-storage-folder-form.component-Cc2ybTwu.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-folder-list.component-B8GoIh6Z.mjs → flusys-ng-storage-folder-list.component-B2Q41I1g.mjs} +34 -39
- package/fesm2022/flusys-ng-storage-folder-list.component-B2Q41I1g.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-storage-config-form.component-CorNWrmF.mjs → flusys-ng-storage-storage-config-form.component-a88XhuPH.mjs} +87 -85
- package/fesm2022/flusys-ng-storage-storage-config-form.component-a88XhuPH.mjs.map +1 -0
- package/fesm2022/{flusys-ng-storage-storage-config-list.component-YXzz3Tvo.mjs → flusys-ng-storage-storage-config-list.component-DBH_qf9o.mjs} +36 -35
- package/fesm2022/flusys-ng-storage-storage-config-list.component-DBH_qf9o.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage.mjs +490 -151
- package/fesm2022/flusys-ng-storage.mjs.map +1 -1
- package/package.json +4 -4
- package/types/flusys-ng-storage.d.ts +56 -36
- package/fesm2022/flusys-ng-storage-file-manager-form.component-CXVB9G-f.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-file-manager-list.component-0O_b4EjN.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-form.component-BTQGEqNu.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-folder-list.component-B8GoIh6Z.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-form.component-CorNWrmF.mjs.map +0 -1
- package/fesm2022/flusys-ng-storage-storage-config-list.component-YXzz3Tvo.mjs.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, computed, effect,
|
|
2
|
+
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 {
|
|
7
|
-
import {
|
|
6
|
+
import { TranslateService } from '@flusys/ng-localization';
|
|
7
|
+
import { AngularModule, PrimeModule, TranslatePipe } from '@flusys/ng-shared';
|
|
8
|
+
import { FileLocationEnum, BaseStoragePage, StorageConfigApiService, STORAGE_PROVIDER_OPTIONS } from './flusys-ng-storage.mjs';
|
|
8
9
|
import * as i1 from '@angular/forms';
|
|
9
10
|
import * as i1$1 from 'primeng/button';
|
|
10
11
|
import * as i3 from 'primeng/inputtext';
|
|
@@ -34,15 +35,16 @@ const DEFAULT_FORM_MODEL = {
|
|
|
34
35
|
class StorageConfigFormComponent extends BaseStoragePage {
|
|
35
36
|
route = inject(ActivatedRoute);
|
|
36
37
|
configService = inject(StorageConfigApiService);
|
|
38
|
+
translateService = inject(TranslateService);
|
|
37
39
|
routeParams = toSignal(this.route.paramMap);
|
|
38
40
|
initialized = false;
|
|
39
41
|
fileLocationEnum = FileLocationEnum;
|
|
40
|
-
|
|
42
|
+
storageProviderOptions = STORAGE_PROVIDER_OPTIONS;
|
|
41
43
|
existingConfig = signal(null, ...(ngDevMode ? [{ debugName: "existingConfig" }] : []));
|
|
42
44
|
isEditMode = computed(() => !!this.existingConfig(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
|
|
43
45
|
formModel = signal({ ...DEFAULT_FORM_MODEL }, ...(ngDevMode ? [{ debugName: "formModel" }] : []));
|
|
44
46
|
configForm = form(this.formModel, (f) => {
|
|
45
|
-
required(f.name, { message: '
|
|
47
|
+
required(f.name, { message: this.translateService.translate('storage.validation.config.name.required') });
|
|
46
48
|
});
|
|
47
49
|
selectedProvider = computed(() => this.formModel().storage, ...(ngDevMode ? [{ debugName: "selectedProvider" }] : []));
|
|
48
50
|
isFormValid = computed(() => this.formModel().name.trim().length > 0, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
|
|
@@ -78,7 +80,7 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
catch {
|
|
81
|
-
this.showError('
|
|
83
|
+
this.showError(this.translateService.translate('storage.config.load.config.failed'));
|
|
82
84
|
this.navigateTo(['/storage/configs']);
|
|
83
85
|
}
|
|
84
86
|
finally {
|
|
@@ -101,7 +103,7 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
101
103
|
isActive: formValue.isActive,
|
|
102
104
|
isDefault: formValue.isDefault,
|
|
103
105
|
});
|
|
104
|
-
this.showSuccess('
|
|
106
|
+
this.showSuccess(this.translateService.translate('storage.config.update.success'));
|
|
105
107
|
}
|
|
106
108
|
else {
|
|
107
109
|
await this.configService.insertAsync({
|
|
@@ -111,12 +113,13 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
111
113
|
isActive: formValue.isActive,
|
|
112
114
|
isDefault: formValue.isDefault,
|
|
113
115
|
});
|
|
114
|
-
this.showSuccess('
|
|
116
|
+
this.showSuccess(this.translateService.translate('storage.config.create.success'));
|
|
115
117
|
}
|
|
116
118
|
this.navigateTo(['/storage/configs']);
|
|
117
119
|
}
|
|
118
120
|
catch {
|
|
119
|
-
|
|
121
|
+
const action = this.isEditMode() ? 'update' : 'create';
|
|
122
|
+
this.showError(this.translateService.translate(`storage.config.${action}.failed`));
|
|
120
123
|
}
|
|
121
124
|
finally {
|
|
122
125
|
this.isLoading.set(false);
|
|
@@ -190,63 +193,63 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
190
193
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: StorageConfigFormComponent, isStandalone: true, selector: "lib-storage-config-form", usesInheritance: true, ngImport: i0, template: `
|
|
191
194
|
<div class="card">
|
|
192
195
|
<h3 class="text-lg sm:text-xl font-semibold mb-4">
|
|
193
|
-
{{ isEditMode() ? '
|
|
196
|
+
{{ (isEditMode() ? 'storage.config.edit.config' : 'storage.config.new.config') | translate }}
|
|
194
197
|
</h3>
|
|
195
198
|
@if (showCompanyInfo()) {
|
|
196
|
-
<p class="text-sm text-muted-color mb-4">
|
|
199
|
+
<p class="text-sm text-muted-color mb-4">{{ 'storage.company' | translate }}: {{ currentCompanyName() }}</p>
|
|
197
200
|
}
|
|
198
201
|
|
|
199
202
|
<form (ngSubmit)="onSubmit()">
|
|
200
203
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
201
204
|
<div class="field">
|
|
202
|
-
<label for="name" class="block font-medium mb-2 text-sm sm:text-base">
|
|
203
|
-
<input pInputText id="name" [formField]="configForm.name" placeholder="
|
|
205
|
+
<label for="name" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.config.name.required' | translate }}</label>
|
|
206
|
+
<input pInputText id="name" [formField]="configForm.name" [placeholder]="'storage.config.config.name.placeholder' | translate" class="w-full" />
|
|
204
207
|
</div>
|
|
205
208
|
|
|
206
209
|
<div class="field">
|
|
207
|
-
<label for="storage" class="block font-medium mb-2 text-sm sm:text-base">
|
|
210
|
+
<label for="storage" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.provider.required' | translate }}</label>
|
|
208
211
|
<select id="storage" class="p-select-native w-full" [formField]="configForm.storage">
|
|
209
|
-
@for (provider of
|
|
210
|
-
<option [value]="provider.value">{{ provider.
|
|
212
|
+
@for (provider of storageProviderOptions; track provider.value) {
|
|
213
|
+
<option [value]="provider.value">{{ provider.labelKey | translate }}</option>
|
|
211
214
|
}
|
|
212
215
|
</select>
|
|
213
216
|
</div>
|
|
214
217
|
|
|
215
218
|
<div class="field flex items-center gap-2">
|
|
216
219
|
<p-toggleswitch [formField]="configForm.isActive" />
|
|
217
|
-
<label class="text-sm sm:text-base">
|
|
220
|
+
<label class="text-sm sm:text-base">{{ 'storage.active' | translate }}</label>
|
|
218
221
|
</div>
|
|
219
222
|
|
|
220
223
|
<div class="field flex items-center gap-2">
|
|
221
224
|
<p-toggleswitch [formField]="configForm.isDefault" />
|
|
222
|
-
<label class="text-sm sm:text-base">
|
|
225
|
+
<label class="text-sm sm:text-base">{{ 'storage.set.as.default' | translate }}</label>
|
|
223
226
|
</div>
|
|
224
227
|
</div>
|
|
225
228
|
|
|
226
229
|
@if (selectedProvider() === fileLocationEnum.AWS) {
|
|
227
230
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
228
231
|
<div class="md:col-span-2 mb-2">
|
|
229
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
232
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.aws.title' | translate }}</span>
|
|
230
233
|
</div>
|
|
231
234
|
<div class="field">
|
|
232
|
-
<label for="awsRegion" class="block font-medium mb-2 text-sm sm:text-base">
|
|
233
|
-
<input pInputText id="awsRegion" [formField]="configForm.awsRegion" placeholder="
|
|
235
|
+
<label for="awsRegion" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.region.required' | translate }}</label>
|
|
236
|
+
<input pInputText id="awsRegion" [formField]="configForm.awsRegion" [placeholder]="'storage.aws.region.placeholder' | translate" class="w-full" />
|
|
234
237
|
</div>
|
|
235
238
|
<div class="field">
|
|
236
|
-
<label for="awsBucket" class="block font-medium mb-2 text-sm sm:text-base">
|
|
237
|
-
<input pInputText id="awsBucket" [formField]="configForm.awsBucket" placeholder="
|
|
239
|
+
<label for="awsBucket" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.bucket.required' | translate }}</label>
|
|
240
|
+
<input pInputText id="awsBucket" [formField]="configForm.awsBucket" [placeholder]="'storage.aws.bucket.placeholder' | translate" class="w-full" />
|
|
238
241
|
</div>
|
|
239
242
|
<div class="field">
|
|
240
|
-
<label for="awsAccessKeyId" class="block font-medium mb-2 text-sm sm:text-base">
|
|
243
|
+
<label for="awsAccessKeyId" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.access.key.required' | translate }}</label>
|
|
241
244
|
<input pInputText id="awsAccessKeyId" [formField]="configForm.awsAccessKeyId" class="w-full" />
|
|
242
245
|
</div>
|
|
243
246
|
<div class="field">
|
|
244
|
-
<label for="awsSecretAccessKey" class="block font-medium mb-2 text-sm sm:text-base">
|
|
247
|
+
<label for="awsSecretAccessKey" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.secret.key.required' | translate }}</label>
|
|
245
248
|
<input type="password" pInputText id="awsSecretAccessKey" [formField]="configForm.awsSecretAccessKey" class="w-full" />
|
|
246
249
|
</div>
|
|
247
250
|
<div class="field md:col-span-2">
|
|
248
|
-
<label for="awsEndpoint" class="block font-medium mb-2 text-sm sm:text-base">
|
|
249
|
-
<input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" placeholder="
|
|
251
|
+
<label for="awsEndpoint" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.endpoint.optional' | translate }}</label>
|
|
252
|
+
<input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" [placeholder]="'storage.config.endpoint.placeholder' | translate" class="w-full" />
|
|
250
253
|
</div>
|
|
251
254
|
</div>
|
|
252
255
|
}
|
|
@@ -254,18 +257,18 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
254
257
|
@if (selectedProvider() === fileLocationEnum.AZURE) {
|
|
255
258
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
256
259
|
<div class="md:col-span-2 mb-2">
|
|
257
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
260
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.azure.title' | translate }}</span>
|
|
258
261
|
</div>
|
|
259
262
|
<div class="field">
|
|
260
|
-
<label for="azureAccountName" class="block font-medium mb-2 text-sm sm:text-base">
|
|
263
|
+
<label for="azureAccountName" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.azure.account.name.required' | translate }}</label>
|
|
261
264
|
<input pInputText id="azureAccountName" [formField]="configForm.azureAccountName" class="w-full" />
|
|
262
265
|
</div>
|
|
263
266
|
<div class="field">
|
|
264
|
-
<label for="azureContainerName" class="block font-medium mb-2 text-sm sm:text-base">
|
|
267
|
+
<label for="azureContainerName" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.azure.container.name.required' | translate }}</label>
|
|
265
268
|
<input pInputText id="azureContainerName" [formField]="configForm.azureContainerName" class="w-full" />
|
|
266
269
|
</div>
|
|
267
270
|
<div class="field md:col-span-2">
|
|
268
|
-
<label for="azureAccountKey" class="block font-medium mb-2 text-sm sm:text-base">
|
|
271
|
+
<label for="azureAccountKey" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.azure.account.key.required' | translate }}</label>
|
|
269
272
|
<input type="password" pInputText id="azureAccountKey" [formField]="configForm.azureAccountKey" class="w-full" />
|
|
270
273
|
</div>
|
|
271
274
|
</div>
|
|
@@ -274,27 +277,27 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
274
277
|
@if (selectedProvider() === fileLocationEnum.SFTP) {
|
|
275
278
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
276
279
|
<div class="md:col-span-2 mb-2">
|
|
277
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
280
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.sftp.title' | translate }}</span>
|
|
278
281
|
</div>
|
|
279
282
|
<div class="field">
|
|
280
|
-
<label for="sftpHost" class="block font-medium mb-2 text-sm sm:text-base">
|
|
281
|
-
<input pInputText id="sftpHost" [formField]="configForm.sftpHost" placeholder="sftp.
|
|
283
|
+
<label for="sftpHost" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.host.required' | translate }}</label>
|
|
284
|
+
<input pInputText id="sftpHost" [formField]="configForm.sftpHost" [placeholder]="'storage.sftp.host.placeholder' | translate" class="w-full" />
|
|
282
285
|
</div>
|
|
283
286
|
<div class="field">
|
|
284
|
-
<label for="sftpPort" class="block font-medium mb-2 text-sm sm:text-base">
|
|
285
|
-
<input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" placeholder="
|
|
287
|
+
<label for="sftpPort" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.port.required' | translate }}</label>
|
|
288
|
+
<input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" [placeholder]="'storage.sftp.port.placeholder' | translate" class="w-full" />
|
|
286
289
|
</div>
|
|
287
290
|
<div class="field">
|
|
288
|
-
<label for="sftpUsername" class="block font-medium mb-2 text-sm sm:text-base">
|
|
291
|
+
<label for="sftpUsername" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.username.required' | translate }}</label>
|
|
289
292
|
<input pInputText id="sftpUsername" [formField]="configForm.sftpUsername" class="w-full" />
|
|
290
293
|
</div>
|
|
291
294
|
<div class="field">
|
|
292
|
-
<label for="sftpPassword" class="block font-medium mb-2 text-sm sm:text-base">
|
|
295
|
+
<label for="sftpPassword" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.password.required' | translate }}</label>
|
|
293
296
|
<input type="password" pInputText id="sftpPassword" [formField]="configForm.sftpPassword" class="w-full" />
|
|
294
297
|
</div>
|
|
295
298
|
<div class="field md:col-span-2">
|
|
296
|
-
<label for="sftpBasePath" class="block font-medium mb-2 text-sm sm:text-base">
|
|
297
|
-
<input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" placeholder="
|
|
299
|
+
<label for="sftpBasePath" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.base.path.required' | translate }}</label>
|
|
300
|
+
<input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" [placeholder]="'storage.sftp.base.path.placeholder' | translate" class="w-full" />
|
|
298
301
|
</div>
|
|
299
302
|
</div>
|
|
300
303
|
}
|
|
@@ -302,89 +305,88 @@ class StorageConfigFormComponent extends BaseStoragePage {
|
|
|
302
305
|
@if (selectedProvider() === fileLocationEnum.LOCAL) {
|
|
303
306
|
<div class="grid grid-cols-1 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
304
307
|
<div class="mb-2">
|
|
305
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
308
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.local.title' | translate }}</span>
|
|
306
309
|
</div>
|
|
307
310
|
<div class="field">
|
|
308
|
-
<label for="localBasePath" class="block font-medium mb-2 text-sm sm:text-base">
|
|
309
|
-
<input pInputText id="localBasePath" [formField]="configForm.localBasePath" placeholder="
|
|
311
|
+
<label for="localBasePath" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.local.base.path.required' | translate }}</label>
|
|
312
|
+
<input pInputText id="localBasePath" [formField]="configForm.localBasePath" [placeholder]="'storage.local.base.path.placeholder' | translate" class="w-full" />
|
|
310
313
|
</div>
|
|
311
314
|
</div>
|
|
312
315
|
}
|
|
313
316
|
|
|
314
317
|
<div class="flex justify-end gap-2 mt-4">
|
|
315
|
-
<p-button label="
|
|
316
|
-
<p-button type="submit" [label]="isEditMode() ? '
|
|
318
|
+
<p-button [label]="'shared.cancel' | translate" severity="secondary" [outlined]="true" (onClick)="onCancel()" />
|
|
319
|
+
<p-button type="submit" [label]="(isEditMode() ? 'shared.update' : 'shared.create') | translate" [loading]="isLoading()" [disabled]="!isFormValid() || isLoading()" />
|
|
317
320
|
</div>
|
|
318
321
|
</form>
|
|
319
322
|
</div>
|
|
320
|
-
`, 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: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }
|
|
323
|
+
`, 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: "component", type: i1$1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
321
324
|
}
|
|
322
325
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: StorageConfigFormComponent, decorators: [{
|
|
323
326
|
type: Component,
|
|
324
327
|
args: [{
|
|
325
328
|
selector: 'lib-storage-config-form',
|
|
326
|
-
|
|
327
|
-
imports: [AngularModule, PrimeModule, FormField],
|
|
329
|
+
imports: [AngularModule, PrimeModule, FormField, TranslatePipe],
|
|
328
330
|
template: `
|
|
329
331
|
<div class="card">
|
|
330
332
|
<h3 class="text-lg sm:text-xl font-semibold mb-4">
|
|
331
|
-
{{ isEditMode() ? '
|
|
333
|
+
{{ (isEditMode() ? 'storage.config.edit.config' : 'storage.config.new.config') | translate }}
|
|
332
334
|
</h3>
|
|
333
335
|
@if (showCompanyInfo()) {
|
|
334
|
-
<p class="text-sm text-muted-color mb-4">
|
|
336
|
+
<p class="text-sm text-muted-color mb-4">{{ 'storage.company' | translate }}: {{ currentCompanyName() }}</p>
|
|
335
337
|
}
|
|
336
338
|
|
|
337
339
|
<form (ngSubmit)="onSubmit()">
|
|
338
340
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
339
341
|
<div class="field">
|
|
340
|
-
<label for="name" class="block font-medium mb-2 text-sm sm:text-base">
|
|
341
|
-
<input pInputText id="name" [formField]="configForm.name" placeholder="
|
|
342
|
+
<label for="name" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.config.name.required' | translate }}</label>
|
|
343
|
+
<input pInputText id="name" [formField]="configForm.name" [placeholder]="'storage.config.config.name.placeholder' | translate" class="w-full" />
|
|
342
344
|
</div>
|
|
343
345
|
|
|
344
346
|
<div class="field">
|
|
345
|
-
<label for="storage" class="block font-medium mb-2 text-sm sm:text-base">
|
|
347
|
+
<label for="storage" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.provider.required' | translate }}</label>
|
|
346
348
|
<select id="storage" class="p-select-native w-full" [formField]="configForm.storage">
|
|
347
|
-
@for (provider of
|
|
348
|
-
<option [value]="provider.value">{{ provider.
|
|
349
|
+
@for (provider of storageProviderOptions; track provider.value) {
|
|
350
|
+
<option [value]="provider.value">{{ provider.labelKey | translate }}</option>
|
|
349
351
|
}
|
|
350
352
|
</select>
|
|
351
353
|
</div>
|
|
352
354
|
|
|
353
355
|
<div class="field flex items-center gap-2">
|
|
354
356
|
<p-toggleswitch [formField]="configForm.isActive" />
|
|
355
|
-
<label class="text-sm sm:text-base">
|
|
357
|
+
<label class="text-sm sm:text-base">{{ 'storage.active' | translate }}</label>
|
|
356
358
|
</div>
|
|
357
359
|
|
|
358
360
|
<div class="field flex items-center gap-2">
|
|
359
361
|
<p-toggleswitch [formField]="configForm.isDefault" />
|
|
360
|
-
<label class="text-sm sm:text-base">
|
|
362
|
+
<label class="text-sm sm:text-base">{{ 'storage.set.as.default' | translate }}</label>
|
|
361
363
|
</div>
|
|
362
364
|
</div>
|
|
363
365
|
|
|
364
366
|
@if (selectedProvider() === fileLocationEnum.AWS) {
|
|
365
367
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
366
368
|
<div class="md:col-span-2 mb-2">
|
|
367
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
369
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.aws.title' | translate }}</span>
|
|
368
370
|
</div>
|
|
369
371
|
<div class="field">
|
|
370
|
-
<label for="awsRegion" class="block font-medium mb-2 text-sm sm:text-base">
|
|
371
|
-
<input pInputText id="awsRegion" [formField]="configForm.awsRegion" placeholder="
|
|
372
|
+
<label for="awsRegion" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.region.required' | translate }}</label>
|
|
373
|
+
<input pInputText id="awsRegion" [formField]="configForm.awsRegion" [placeholder]="'storage.aws.region.placeholder' | translate" class="w-full" />
|
|
372
374
|
</div>
|
|
373
375
|
<div class="field">
|
|
374
|
-
<label for="awsBucket" class="block font-medium mb-2 text-sm sm:text-base">
|
|
375
|
-
<input pInputText id="awsBucket" [formField]="configForm.awsBucket" placeholder="
|
|
376
|
+
<label for="awsBucket" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.bucket.required' | translate }}</label>
|
|
377
|
+
<input pInputText id="awsBucket" [formField]="configForm.awsBucket" [placeholder]="'storage.aws.bucket.placeholder' | translate" class="w-full" />
|
|
376
378
|
</div>
|
|
377
379
|
<div class="field">
|
|
378
|
-
<label for="awsAccessKeyId" class="block font-medium mb-2 text-sm sm:text-base">
|
|
380
|
+
<label for="awsAccessKeyId" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.access.key.required' | translate }}</label>
|
|
379
381
|
<input pInputText id="awsAccessKeyId" [formField]="configForm.awsAccessKeyId" class="w-full" />
|
|
380
382
|
</div>
|
|
381
383
|
<div class="field">
|
|
382
|
-
<label for="awsSecretAccessKey" class="block font-medium mb-2 text-sm sm:text-base">
|
|
384
|
+
<label for="awsSecretAccessKey" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.secret.key.required' | translate }}</label>
|
|
383
385
|
<input type="password" pInputText id="awsSecretAccessKey" [formField]="configForm.awsSecretAccessKey" class="w-full" />
|
|
384
386
|
</div>
|
|
385
387
|
<div class="field md:col-span-2">
|
|
386
|
-
<label for="awsEndpoint" class="block font-medium mb-2 text-sm sm:text-base">
|
|
387
|
-
<input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" placeholder="
|
|
388
|
+
<label for="awsEndpoint" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.config.endpoint.optional' | translate }}</label>
|
|
389
|
+
<input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" [placeholder]="'storage.config.endpoint.placeholder' | translate" class="w-full" />
|
|
388
390
|
</div>
|
|
389
391
|
</div>
|
|
390
392
|
}
|
|
@@ -392,18 +394,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
392
394
|
@if (selectedProvider() === fileLocationEnum.AZURE) {
|
|
393
395
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
394
396
|
<div class="md:col-span-2 mb-2">
|
|
395
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
397
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.azure.title' | translate }}</span>
|
|
396
398
|
</div>
|
|
397
399
|
<div class="field">
|
|
398
|
-
<label for="azureAccountName" class="block font-medium mb-2 text-sm sm:text-base">
|
|
400
|
+
<label for="azureAccountName" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.azure.account.name.required' | translate }}</label>
|
|
399
401
|
<input pInputText id="azureAccountName" [formField]="configForm.azureAccountName" class="w-full" />
|
|
400
402
|
</div>
|
|
401
403
|
<div class="field">
|
|
402
|
-
<label for="azureContainerName" class="block font-medium mb-2 text-sm sm:text-base">
|
|
404
|
+
<label for="azureContainerName" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.azure.container.name.required' | translate }}</label>
|
|
403
405
|
<input pInputText id="azureContainerName" [formField]="configForm.azureContainerName" class="w-full" />
|
|
404
406
|
</div>
|
|
405
407
|
<div class="field md:col-span-2">
|
|
406
|
-
<label for="azureAccountKey" class="block font-medium mb-2 text-sm sm:text-base">
|
|
408
|
+
<label for="azureAccountKey" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.azure.account.key.required' | translate }}</label>
|
|
407
409
|
<input type="password" pInputText id="azureAccountKey" [formField]="configForm.azureAccountKey" class="w-full" />
|
|
408
410
|
</div>
|
|
409
411
|
</div>
|
|
@@ -412,27 +414,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
412
414
|
@if (selectedProvider() === fileLocationEnum.SFTP) {
|
|
413
415
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
414
416
|
<div class="md:col-span-2 mb-2">
|
|
415
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
417
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.sftp.title' | translate }}</span>
|
|
416
418
|
</div>
|
|
417
419
|
<div class="field">
|
|
418
|
-
<label for="sftpHost" class="block font-medium mb-2 text-sm sm:text-base">
|
|
419
|
-
<input pInputText id="sftpHost" [formField]="configForm.sftpHost" placeholder="sftp.
|
|
420
|
+
<label for="sftpHost" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.host.required' | translate }}</label>
|
|
421
|
+
<input pInputText id="sftpHost" [formField]="configForm.sftpHost" [placeholder]="'storage.sftp.host.placeholder' | translate" class="w-full" />
|
|
420
422
|
</div>
|
|
421
423
|
<div class="field">
|
|
422
|
-
<label for="sftpPort" class="block font-medium mb-2 text-sm sm:text-base">
|
|
423
|
-
<input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" placeholder="
|
|
424
|
+
<label for="sftpPort" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.port.required' | translate }}</label>
|
|
425
|
+
<input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" [placeholder]="'storage.sftp.port.placeholder' | translate" class="w-full" />
|
|
424
426
|
</div>
|
|
425
427
|
<div class="field">
|
|
426
|
-
<label for="sftpUsername" class="block font-medium mb-2 text-sm sm:text-base">
|
|
428
|
+
<label for="sftpUsername" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.username.required' | translate }}</label>
|
|
427
429
|
<input pInputText id="sftpUsername" [formField]="configForm.sftpUsername" class="w-full" />
|
|
428
430
|
</div>
|
|
429
431
|
<div class="field">
|
|
430
|
-
<label for="sftpPassword" class="block font-medium mb-2 text-sm sm:text-base">
|
|
432
|
+
<label for="sftpPassword" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.password.required' | translate }}</label>
|
|
431
433
|
<input type="password" pInputText id="sftpPassword" [formField]="configForm.sftpPassword" class="w-full" />
|
|
432
434
|
</div>
|
|
433
435
|
<div class="field md:col-span-2">
|
|
434
|
-
<label for="sftpBasePath" class="block font-medium mb-2 text-sm sm:text-base">
|
|
435
|
-
<input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" placeholder="
|
|
436
|
+
<label for="sftpBasePath" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.sftp.base.path.required' | translate }}</label>
|
|
437
|
+
<input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" [placeholder]="'storage.sftp.base.path.placeholder' | translate" class="w-full" />
|
|
436
438
|
</div>
|
|
437
439
|
</div>
|
|
438
440
|
}
|
|
@@ -440,18 +442,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
440
442
|
@if (selectedProvider() === fileLocationEnum.LOCAL) {
|
|
441
443
|
<div class="grid grid-cols-1 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface">
|
|
442
444
|
<div class="mb-2">
|
|
443
|
-
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">
|
|
445
|
+
<span class="text-sm font-semibold text-muted-color uppercase tracking-wide">{{ 'storage.local.title' | translate }}</span>
|
|
444
446
|
</div>
|
|
445
447
|
<div class="field">
|
|
446
|
-
<label for="localBasePath" class="block font-medium mb-2 text-sm sm:text-base">
|
|
447
|
-
<input pInputText id="localBasePath" [formField]="configForm.localBasePath" placeholder="
|
|
448
|
+
<label for="localBasePath" class="block font-medium mb-2 text-sm sm:text-base">{{ 'storage.local.base.path.required' | translate }}</label>
|
|
449
|
+
<input pInputText id="localBasePath" [formField]="configForm.localBasePath" [placeholder]="'storage.local.base.path.placeholder' | translate" class="w-full" />
|
|
448
450
|
</div>
|
|
449
451
|
</div>
|
|
450
452
|
}
|
|
451
453
|
|
|
452
454
|
<div class="flex justify-end gap-2 mt-4">
|
|
453
|
-
<p-button label="
|
|
454
|
-
<p-button type="submit" [label]="isEditMode() ? '
|
|
455
|
+
<p-button [label]="'shared.cancel' | translate" severity="secondary" [outlined]="true" (onClick)="onCancel()" />
|
|
456
|
+
<p-button type="submit" [label]="(isEditMode() ? 'shared.update' : 'shared.create') | translate" [loading]="isLoading()" [disabled]="!isFormValid() || isLoading()" />
|
|
455
457
|
</div>
|
|
456
458
|
</form>
|
|
457
459
|
</div>
|
|
@@ -460,4 +462,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
460
462
|
}], ctorParameters: () => [] });
|
|
461
463
|
|
|
462
464
|
export { StorageConfigFormComponent };
|
|
463
|
-
//# sourceMappingURL=flusys-ng-storage-storage-config-form.component-
|
|
465
|
+
//# sourceMappingURL=flusys-ng-storage-storage-config-form.component-a88XhuPH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-storage-storage-config-form.component-a88XhuPH.mjs","sources":["../../../projects/ng-storage/pages/storage-config/storage-config-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 { TranslateService } from '@flusys/ng-localization';\nimport { AngularModule, PrimeModule, TranslatePipe } from '@flusys/ng-shared';\nimport { FileLocationEnum } from '../../enums/file-location.enum';\nimport { IStorageConfig } from '../../interfaces/storage-config.interface';\nimport { StorageConfigApiService } from '../../services/storage-config-api.service';\nimport { BaseStoragePage } from '../../utils/base-storage-page';\nimport { STORAGE_PROVIDER_OPTIONS } from '../../utils/storage-utils';\n\ninterface IStorageConfigFormModel {\n id: string;\n name: string;\n storage: FileLocationEnum;\n isActive: boolean;\n isDefault: boolean;\n awsRegion: string;\n awsBucket: string;\n awsAccessKeyId: string;\n awsSecretAccessKey: string;\n awsEndpoint: string;\n azureAccountName: string;\n azureAccountKey: string;\n azureContainerName: string;\n sftpHost: string;\n sftpPort: string;\n sftpUsername: string;\n sftpPassword: string;\n sftpBasePath: string;\n localBasePath: string;\n}\n\nconst DEFAULT_FORM_MODEL: IStorageConfigFormModel = {\n id: '',\n name: '',\n storage: FileLocationEnum.AWS,\n isActive: true,\n isDefault: false,\n awsRegion: '',\n awsBucket: '',\n awsAccessKeyId: '',\n awsSecretAccessKey: '',\n awsEndpoint: '',\n azureAccountName: '',\n azureAccountKey: '',\n azureContainerName: '',\n sftpHost: '',\n sftpPort: '22',\n sftpUsername: '',\n sftpPassword: '',\n sftpBasePath: '',\n localBasePath: '',\n};\n\n@Component({\n selector: 'lib-storage-config-form',\n imports: [AngularModule, PrimeModule, FormField, TranslatePipe],\n template: `\n <div class=\"card\">\n <h3 class=\"text-lg sm:text-xl font-semibold mb-4\">\n {{ (isEditMode() ? 'storage.config.edit.config' : 'storage.config.new.config') | translate }}\n </h3>\n @if (showCompanyInfo()) {\n <p class=\"text-sm text-muted-color mb-4\">{{ 'storage.company' | translate }}: {{ currentCompanyName() }}</p>\n }\n\n <form (ngSubmit)=\"onSubmit()\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div class=\"field\">\n <label for=\"name\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.config.name.required' | translate }}</label>\n <input pInputText id=\"name\" [formField]=\"configForm.name\" [placeholder]=\"'storage.config.config.name.placeholder' | translate\" class=\"w-full\" />\n </div>\n\n <div class=\"field\">\n <label for=\"storage\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.provider.required' | translate }}</label>\n <select id=\"storage\" class=\"p-select-native w-full\" [formField]=\"configForm.storage\">\n @for (provider of storageProviderOptions; track provider.value) {\n <option [value]=\"provider.value\">{{ provider.labelKey | translate }}</option>\n }\n </select>\n </div>\n\n <div class=\"field flex items-center gap-2\">\n <p-toggleswitch [formField]=\"configForm.isActive\" />\n <label class=\"text-sm sm:text-base\">{{ 'storage.active' | translate }}</label>\n </div>\n\n <div class=\"field flex items-center gap-2\">\n <p-toggleswitch [formField]=\"configForm.isDefault\" />\n <label class=\"text-sm sm:text-base\">{{ 'storage.set.as.default' | translate }}</label>\n </div>\n </div>\n\n @if (selectedProvider() === fileLocationEnum.AWS) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface\">\n <div class=\"md:col-span-2 mb-2\">\n <span class=\"text-sm font-semibold text-muted-color uppercase tracking-wide\">{{ 'storage.aws.title' | translate }}</span>\n </div>\n <div class=\"field\">\n <label for=\"awsRegion\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.region.required' | translate }}</label>\n <input pInputText id=\"awsRegion\" [formField]=\"configForm.awsRegion\" [placeholder]=\"'storage.aws.region.placeholder' | translate\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"awsBucket\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.bucket.required' | translate }}</label>\n <input pInputText id=\"awsBucket\" [formField]=\"configForm.awsBucket\" [placeholder]=\"'storage.aws.bucket.placeholder' | translate\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"awsAccessKeyId\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.access.key.required' | translate }}</label>\n <input pInputText id=\"awsAccessKeyId\" [formField]=\"configForm.awsAccessKeyId\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"awsSecretAccessKey\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.secret.key.required' | translate }}</label>\n <input type=\"password\" pInputText id=\"awsSecretAccessKey\" [formField]=\"configForm.awsSecretAccessKey\" class=\"w-full\" />\n </div>\n <div class=\"field md:col-span-2\">\n <label for=\"awsEndpoint\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.config.endpoint.optional' | translate }}</label>\n <input pInputText id=\"awsEndpoint\" [formField]=\"configForm.awsEndpoint\" [placeholder]=\"'storage.config.endpoint.placeholder' | translate\" class=\"w-full\" />\n </div>\n </div>\n }\n\n @if (selectedProvider() === fileLocationEnum.AZURE) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface\">\n <div class=\"md:col-span-2 mb-2\">\n <span class=\"text-sm font-semibold text-muted-color uppercase tracking-wide\">{{ 'storage.azure.title' | translate }}</span>\n </div>\n <div class=\"field\">\n <label for=\"azureAccountName\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.azure.account.name.required' | translate }}</label>\n <input pInputText id=\"azureAccountName\" [formField]=\"configForm.azureAccountName\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"azureContainerName\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.azure.container.name.required' | translate }}</label>\n <input pInputText id=\"azureContainerName\" [formField]=\"configForm.azureContainerName\" class=\"w-full\" />\n </div>\n <div class=\"field md:col-span-2\">\n <label for=\"azureAccountKey\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.azure.account.key.required' | translate }}</label>\n <input type=\"password\" pInputText id=\"azureAccountKey\" [formField]=\"configForm.azureAccountKey\" class=\"w-full\" />\n </div>\n </div>\n }\n\n @if (selectedProvider() === fileLocationEnum.SFTP) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface\">\n <div class=\"md:col-span-2 mb-2\">\n <span class=\"text-sm font-semibold text-muted-color uppercase tracking-wide\">{{ 'storage.sftp.title' | translate }}</span>\n </div>\n <div class=\"field\">\n <label for=\"sftpHost\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.sftp.host.required' | translate }}</label>\n <input pInputText id=\"sftpHost\" [formField]=\"configForm.sftpHost\" [placeholder]=\"'storage.sftp.host.placeholder' | translate\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"sftpPort\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.sftp.port.required' | translate }}</label>\n <input type=\"number\" pInputText id=\"sftpPort\" [formField]=\"configForm.sftpPort\" [placeholder]=\"'storage.sftp.port.placeholder' | translate\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"sftpUsername\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.sftp.username.required' | translate }}</label>\n <input pInputText id=\"sftpUsername\" [formField]=\"configForm.sftpUsername\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"sftpPassword\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.sftp.password.required' | translate }}</label>\n <input type=\"password\" pInputText id=\"sftpPassword\" [formField]=\"configForm.sftpPassword\" class=\"w-full\" />\n </div>\n <div class=\"field md:col-span-2\">\n <label for=\"sftpBasePath\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.sftp.base.path.required' | translate }}</label>\n <input pInputText id=\"sftpBasePath\" [formField]=\"configForm.sftpBasePath\" [placeholder]=\"'storage.sftp.base.path.placeholder' | translate\" class=\"w-full\" />\n </div>\n </div>\n }\n\n @if (selectedProvider() === fileLocationEnum.LOCAL) {\n <div class=\"grid grid-cols-1 gap-4 mt-4 p-4 bg-surface-ground rounded-lg border border-surface\">\n <div class=\"mb-2\">\n <span class=\"text-sm font-semibold text-muted-color uppercase tracking-wide\">{{ 'storage.local.title' | translate }}</span>\n </div>\n <div class=\"field\">\n <label for=\"localBasePath\" class=\"block font-medium mb-2 text-sm sm:text-base\">{{ 'storage.local.base.path.required' | translate }}</label>\n <input pInputText id=\"localBasePath\" [formField]=\"configForm.localBasePath\" [placeholder]=\"'storage.local.base.path.placeholder' | translate\" class=\"w-full\" />\n </div>\n </div>\n }\n\n <div class=\"flex justify-end gap-2 mt-4\">\n <p-button [label]=\"'shared.cancel' | translate\" severity=\"secondary\" [outlined]=\"true\" (onClick)=\"onCancel()\" />\n <p-button type=\"submit\" [label]=\"(isEditMode() ? 'shared.update' : 'shared.create') | translate\" [loading]=\"isLoading()\" [disabled]=\"!isFormValid() || isLoading()\" />\n </div>\n </form>\n </div>\n `,\n})\nexport class StorageConfigFormComponent extends BaseStoragePage {\n private readonly route = inject(ActivatedRoute);\n private readonly configService = inject(StorageConfigApiService);\n private readonly translateService = inject(TranslateService);\n private readonly routeParams = toSignal(this.route.paramMap);\n private initialized = false;\n\n readonly fileLocationEnum = FileLocationEnum;\n readonly storageProviderOptions = STORAGE_PROVIDER_OPTIONS;\n\n readonly existingConfig = signal<IStorageConfig | null>(null);\n readonly isEditMode = computed(() => !!this.existingConfig());\n readonly formModel = signal<IStorageConfigFormModel>({ ...DEFAULT_FORM_MODEL });\n\n readonly configForm = form(this.formModel, (f) => {\n required(f.name, { message: this.translateService.translate('storage.validation.config.name.required') });\n });\n\n readonly selectedProvider = computed(() => this.formModel().storage);\n readonly isFormValid = computed(() => this.formModel().name.trim().length > 0);\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 configId = params.get('id');\n if (configId && configId !== 'new') {\n this.loadConfig(configId);\n }\n });\n }\n\n async loadConfig(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.configService.findByIdAsync(id);\n if (response.success && response.data) {\n const config = response.data;\n this.existingConfig.set(config);\n this.formModel.update((m) => ({\n ...m,\n id: config.id,\n name: config.name,\n storage: config.storage,\n isActive: config.isActive ?? true,\n isDefault: config.isDefault ?? false,\n ...this.extractProviderConfig(config),\n }));\n }\n } catch {\n this.showError(this.translateService.translate('storage.config.load.config.failed'));\n this.navigateTo(['/storage/configs']);\n } finally {\n this.isLoading.set(false);\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 const config = this.buildProviderConfig(formValue);\n\n if (this.isEditMode()) {\n await this.configService.updateAsync({\n id: formValue.id,\n name: formValue.name,\n storage: formValue.storage,\n config,\n isActive: formValue.isActive,\n isDefault: formValue.isDefault,\n });\n this.showSuccess(this.translateService.translate('storage.config.update.success'));\n } else {\n await this.configService.insertAsync({\n name: formValue.name,\n storage: formValue.storage,\n config,\n isActive: formValue.isActive,\n isDefault: formValue.isDefault,\n });\n this.showSuccess(this.translateService.translate('storage.config.create.success'));\n }\n this.navigateTo(['/storage/configs']);\n } catch {\n const action = this.isEditMode() ? 'update' : 'create';\n this.showError(this.translateService.translate(`storage.config.${action}.failed`));\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onCancel(): void {\n this.navigateTo(['/storage/configs']);\n }\n\n private extractProviderConfig(config: IStorageConfig): Partial<IStorageConfigFormModel> {\n const c = config.config ?? {};\n switch (config.storage) {\n case FileLocationEnum.AWS:\n return {\n awsRegion: (c['region'] as string) || '',\n awsBucket: (c['bucket'] as string) || '',\n awsAccessKeyId: (c['accessKeyId'] as string) || '',\n awsSecretAccessKey: (c['secretAccessKey'] as string) || '',\n awsEndpoint: (c['endpoint'] as string) || '',\n };\n case FileLocationEnum.AZURE:\n return {\n azureAccountName: (c['accountName'] as string) || '',\n azureAccountKey: (c['accountKey'] as string) || '',\n azureContainerName: (c['containerName'] as string) || '',\n };\n case FileLocationEnum.SFTP:\n return {\n sftpHost: (c['host'] as string) || '',\n sftpPort: ((c['port'] as number) || 22).toString(),\n sftpUsername: (c['username'] as string) || '',\n sftpPassword: (c['password'] as string) || '',\n sftpBasePath: (c['basePath'] as string) || '',\n };\n case FileLocationEnum.LOCAL:\n return { localBasePath: (c['basePath'] as string) || '' };\n default:\n return {};\n }\n }\n\n private buildProviderConfig(formValue: IStorageConfigFormModel): Record<string, unknown> {\n switch (formValue.storage) {\n case FileLocationEnum.AWS:\n return {\n region: formValue.awsRegion,\n bucket: formValue.awsBucket,\n accessKeyId: formValue.awsAccessKeyId,\n secretAccessKey: formValue.awsSecretAccessKey,\n ...(formValue.awsEndpoint && { endpoint: formValue.awsEndpoint }),\n };\n case FileLocationEnum.AZURE:\n return {\n accountName: formValue.azureAccountName,\n accountKey: formValue.azureAccountKey,\n containerName: formValue.azureContainerName,\n };\n case FileLocationEnum.SFTP:\n return {\n host: formValue.sftpHost,\n port: formValue.sftpPort ? parseInt(formValue.sftpPort, 10) : 22,\n username: formValue.sftpUsername,\n password: formValue.sftpPassword,\n basePath: formValue.sftpBasePath,\n };\n case FileLocationEnum.LOCAL:\n return { basePath: formValue.localBasePath };\n default:\n return {};\n }\n }\n}\n"],"names":["i2"],"mappings":"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"}
|