@flusys/ng-storage 0.1.0-alpha.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.
- package/fesm2022/flusys-ng-storage-file-manager-form.component-BI0hgXeI.mjs +716 -0
- package/fesm2022/flusys-ng-storage-file-manager-form.component-BI0hgXeI.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-file-manager-list.component-C3C7Y8-n.mjs +445 -0
- package/fesm2022/flusys-ng-storage-file-manager-list.component-C3C7Y8-n.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-folder-form.component-Cw2aLZkb.mjs +253 -0
- package/fesm2022/flusys-ng-storage-folder-form.component-Cw2aLZkb.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-folder-list.component-CN_mTtS5.mjs +267 -0
- package/fesm2022/flusys-ng-storage-folder-list.component-CN_mTtS5.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-storage-config-form.component-DHzsQ2Mc.mjs +513 -0
- package/fesm2022/flusys-ng-storage-storage-config-form.component-DHzsQ2Mc.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage-storage-config-list.component-tmiE2CpM.mjs +328 -0
- package/fesm2022/flusys-ng-storage-storage-config-list.component-tmiE2CpM.mjs.map +1 -0
- package/fesm2022/flusys-ng-storage.mjs +415 -0
- package/fesm2022/flusys-ng-storage.mjs.map +1 -0
- package/package.json +28 -0
- package/types/flusys-ng-storage.d.ts +343 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, signal, computed, Component } from '@angular/core';
|
|
3
|
+
import { form, required, FormField } from '@angular/forms/signals';
|
|
4
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
5
|
+
import { AngularModule, PrimeModule } from '@flusys/ng-shared';
|
|
6
|
+
import { APP_CONFIG } from '@flusys/ng-core';
|
|
7
|
+
import { MessageService } from 'primeng/api';
|
|
8
|
+
import { StorageConfigApiService, FileLocationEnum } from './flusys-ng-storage.mjs';
|
|
9
|
+
import * as i1 from '@angular/forms';
|
|
10
|
+
import * as i2 from 'primeng/inputtext';
|
|
11
|
+
import * as i3 from 'primeng/button';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Storage Config Form Component
|
|
15
|
+
* Create and edit storage configurations
|
|
16
|
+
*/
|
|
17
|
+
class StorageConfigFormComponent {
|
|
18
|
+
router = inject(Router);
|
|
19
|
+
route = inject(ActivatedRoute);
|
|
20
|
+
messageService = inject(MessageService);
|
|
21
|
+
configService = inject(StorageConfigApiService);
|
|
22
|
+
appConfig = inject(APP_CONFIG);
|
|
23
|
+
fileLocationEnum = FileLocationEnum;
|
|
24
|
+
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
25
|
+
existingConfig = signal(null, ...(ngDevMode ? [{ debugName: "existingConfig" }] : []));
|
|
26
|
+
isEditMode = computed(() => !!this.existingConfig(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
|
|
27
|
+
showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature, ...(ngDevMode ? [{ debugName: "showCompanyInfo" }] : []));
|
|
28
|
+
currentCompanyName = computed(() => 'Current Company', ...(ngDevMode ? [{ debugName: "currentCompanyName" }] : []));
|
|
29
|
+
storageProviders = [
|
|
30
|
+
{ label: 'AWS S3', value: FileLocationEnum.AWS },
|
|
31
|
+
{ label: 'Azure Blob Storage', value: FileLocationEnum.AZURE },
|
|
32
|
+
{ label: 'SFTP', value: FileLocationEnum.SFTP },
|
|
33
|
+
{ label: 'Local Storage', value: FileLocationEnum.LOCAL },
|
|
34
|
+
];
|
|
35
|
+
// ============================================
|
|
36
|
+
// Form (Signal Forms)
|
|
37
|
+
// ============================================
|
|
38
|
+
/** Form model */
|
|
39
|
+
formModel = signal({
|
|
40
|
+
id: '',
|
|
41
|
+
name: '',
|
|
42
|
+
storage: FileLocationEnum.AWS,
|
|
43
|
+
// AWS S3
|
|
44
|
+
awsRegion: '',
|
|
45
|
+
awsBucket: '',
|
|
46
|
+
awsAccessKeyId: '',
|
|
47
|
+
awsSecretAccessKey: '',
|
|
48
|
+
awsEndpoint: '',
|
|
49
|
+
// Azure
|
|
50
|
+
azureAccountName: '',
|
|
51
|
+
azureAccountKey: '',
|
|
52
|
+
azureContainerName: '',
|
|
53
|
+
// SFTP
|
|
54
|
+
sftpHost: '',
|
|
55
|
+
sftpPort: '22',
|
|
56
|
+
sftpUsername: '',
|
|
57
|
+
sftpPassword: '',
|
|
58
|
+
sftpBasePath: '',
|
|
59
|
+
// Local
|
|
60
|
+
localBasePath: '',
|
|
61
|
+
}, ...(ngDevMode ? [{ debugName: "formModel" }] : []));
|
|
62
|
+
/** Form with validation schema */
|
|
63
|
+
configForm = form(this.formModel, (f) => {
|
|
64
|
+
required(f.name, { message: 'Configuration name is required' });
|
|
65
|
+
});
|
|
66
|
+
/** Selected provider */
|
|
67
|
+
selectedProvider = computed(() => this.formModel().storage, ...(ngDevMode ? [{ debugName: "selectedProvider" }] : []));
|
|
68
|
+
/** Check if form is valid */
|
|
69
|
+
isFormValid = computed(() => {
|
|
70
|
+
const model = this.formModel();
|
|
71
|
+
return model.name.trim().length > 0;
|
|
72
|
+
}, ...(ngDevMode ? [{ debugName: "isFormValid" }] : []));
|
|
73
|
+
ngOnInit() {
|
|
74
|
+
const configId = this.route.snapshot.paramMap.get('id');
|
|
75
|
+
if (configId) {
|
|
76
|
+
this.loadConfig(configId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async loadConfig(id) {
|
|
80
|
+
this.isLoading.set(true);
|
|
81
|
+
try {
|
|
82
|
+
const response = await this.configService.findByIdAsync(id);
|
|
83
|
+
if (response.success && response.data) {
|
|
84
|
+
const config = response.data;
|
|
85
|
+
this.existingConfig.set(config);
|
|
86
|
+
// Base form values
|
|
87
|
+
const formData = {
|
|
88
|
+
id: config.id,
|
|
89
|
+
name: config.name,
|
|
90
|
+
storage: config.storage,
|
|
91
|
+
};
|
|
92
|
+
// Load provider-specific config
|
|
93
|
+
if (config.storage === FileLocationEnum.AWS && config.config) {
|
|
94
|
+
formData.awsRegion = config.config['region'] || '';
|
|
95
|
+
formData.awsBucket = config.config['bucket'] || '';
|
|
96
|
+
formData.awsAccessKeyId = config.config['accessKeyId'] || '';
|
|
97
|
+
formData.awsSecretAccessKey = config.config['secretAccessKey'] || '';
|
|
98
|
+
formData.awsEndpoint = config.config['endpoint'] || '';
|
|
99
|
+
}
|
|
100
|
+
else if (config.storage === FileLocationEnum.AZURE && config.config) {
|
|
101
|
+
formData.azureAccountName = config.config['accountName'] || '';
|
|
102
|
+
formData.azureAccountKey = config.config['accountKey'] || '';
|
|
103
|
+
formData.azureContainerName = config.config['containerName'] || '';
|
|
104
|
+
}
|
|
105
|
+
else if (config.storage === FileLocationEnum.SFTP && config.config) {
|
|
106
|
+
formData.sftpHost = config.config['host'] || '';
|
|
107
|
+
formData.sftpPort = (config.config['port'] || 22).toString();
|
|
108
|
+
formData.sftpUsername = config.config['username'] || '';
|
|
109
|
+
formData.sftpPassword = config.config['password'] || '';
|
|
110
|
+
formData.sftpBasePath = config.config['basePath'] || '';
|
|
111
|
+
}
|
|
112
|
+
else if (config.storage === FileLocationEnum.LOCAL && config.config) {
|
|
113
|
+
formData.localBasePath = config.config['basePath'] || '';
|
|
114
|
+
}
|
|
115
|
+
this.formModel.update((m) => ({ ...m, ...formData }));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.messageService.add({
|
|
120
|
+
severity: 'error',
|
|
121
|
+
summary: 'Error',
|
|
122
|
+
detail: 'Failed to load storage configuration.',
|
|
123
|
+
});
|
|
124
|
+
this.router.navigate(['/storage/configs']);
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
this.isLoading.set(false);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async onSubmit() {
|
|
131
|
+
if (!this.isFormValid())
|
|
132
|
+
return;
|
|
133
|
+
this.isLoading.set(true);
|
|
134
|
+
try {
|
|
135
|
+
const formValue = this.formModel();
|
|
136
|
+
let config = {};
|
|
137
|
+
// Build provider-specific config
|
|
138
|
+
if (formValue.storage === FileLocationEnum.AWS) {
|
|
139
|
+
config = {
|
|
140
|
+
region: formValue.awsRegion,
|
|
141
|
+
bucket: formValue.awsBucket,
|
|
142
|
+
accessKeyId: formValue.awsAccessKeyId,
|
|
143
|
+
secretAccessKey: formValue.awsSecretAccessKey,
|
|
144
|
+
...(formValue.awsEndpoint && { endpoint: formValue.awsEndpoint }),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else if (formValue.storage === FileLocationEnum.AZURE) {
|
|
148
|
+
config = {
|
|
149
|
+
accountName: formValue.azureAccountName,
|
|
150
|
+
accountKey: formValue.azureAccountKey,
|
|
151
|
+
containerName: formValue.azureContainerName,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
else if (formValue.storage === FileLocationEnum.SFTP) {
|
|
155
|
+
config = {
|
|
156
|
+
host: formValue.sftpHost,
|
|
157
|
+
port: formValue.sftpPort ? parseInt(formValue.sftpPort, 10) : 22,
|
|
158
|
+
username: formValue.sftpUsername,
|
|
159
|
+
password: formValue.sftpPassword,
|
|
160
|
+
basePath: formValue.sftpBasePath,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
else if (formValue.storage === FileLocationEnum.LOCAL) {
|
|
164
|
+
config = {
|
|
165
|
+
basePath: formValue.localBasePath,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (this.isEditMode()) {
|
|
169
|
+
await this.configService.updateAsync({
|
|
170
|
+
id: formValue.id,
|
|
171
|
+
name: formValue.name,
|
|
172
|
+
storage: formValue.storage,
|
|
173
|
+
config,
|
|
174
|
+
});
|
|
175
|
+
this.messageService.add({
|
|
176
|
+
severity: 'success',
|
|
177
|
+
summary: 'Success',
|
|
178
|
+
detail: 'Storage configuration updated successfully.',
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
await this.configService.insertAsync({
|
|
183
|
+
name: formValue.name,
|
|
184
|
+
storage: formValue.storage,
|
|
185
|
+
config,
|
|
186
|
+
});
|
|
187
|
+
this.messageService.add({
|
|
188
|
+
severity: 'success',
|
|
189
|
+
summary: 'Success',
|
|
190
|
+
detail: 'Storage configuration created successfully.',
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
this.router.navigate(['/storage/configs']);
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
this.messageService.add({
|
|
197
|
+
severity: 'error',
|
|
198
|
+
summary: 'Error',
|
|
199
|
+
detail: `Failed to ${this.isEditMode() ? 'update' : 'create'} storage configuration.`,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
this.isLoading.set(false);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
onCancel() {
|
|
207
|
+
this.router.navigate(['/storage/configs']);
|
|
208
|
+
}
|
|
209
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: StorageConfigFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
210
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: StorageConfigFormComponent, isStandalone: true, selector: "lib-storage-config-form", ngImport: i0, template: `
|
|
211
|
+
<div class="card">
|
|
212
|
+
<div class="flex justify-between items-center mb-4">
|
|
213
|
+
<div>
|
|
214
|
+
<h3 class="text-xl font-semibold">
|
|
215
|
+
{{ isEditMode() ? 'Edit Storage Configuration' : 'New Storage Configuration' }}
|
|
216
|
+
</h3>
|
|
217
|
+
@if (showCompanyInfo()) {
|
|
218
|
+
<p class="text-sm text-gray-600 mt-1">
|
|
219
|
+
Company: {{ currentCompanyName() }}
|
|
220
|
+
</p>
|
|
221
|
+
}
|
|
222
|
+
</div>
|
|
223
|
+
<p-button
|
|
224
|
+
label="Back"
|
|
225
|
+
icon="pi pi-arrow-left"
|
|
226
|
+
severity="secondary"
|
|
227
|
+
[text]="true"
|
|
228
|
+
(onClick)="onCancel()" />
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<form (ngSubmit)="onSubmit()">
|
|
232
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
233
|
+
<!-- Name -->
|
|
234
|
+
<div class="field md:col-span-2">
|
|
235
|
+
<label for="name" class="block font-medium mb-2">Configuration Name *</label>
|
|
236
|
+
<input
|
|
237
|
+
pInputText
|
|
238
|
+
id="name"
|
|
239
|
+
[formField]="configForm.name"
|
|
240
|
+
placeholder="e.g., Production AWS S3"
|
|
241
|
+
class="w-full" />
|
|
242
|
+
</div>
|
|
243
|
+
|
|
244
|
+
<!-- Storage Provider -->
|
|
245
|
+
<div class="field md:col-span-2">
|
|
246
|
+
<label for="storage" class="block font-medium mb-2">Storage Provider *</label>
|
|
247
|
+
<select
|
|
248
|
+
id="storage"
|
|
249
|
+
class="p-select-native"
|
|
250
|
+
[formField]="configForm.storage">
|
|
251
|
+
@for (provider of storageProviders; track provider.value) {
|
|
252
|
+
<option [value]="provider.value">{{ provider.label }}</option>
|
|
253
|
+
}
|
|
254
|
+
</select>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<!-- AWS S3 Fields -->
|
|
259
|
+
@if (selectedProvider() === fileLocationEnum.AWS) {
|
|
260
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
|
261
|
+
<div class="field">
|
|
262
|
+
<label for="awsRegion" class="block font-medium mb-2">AWS Region *</label>
|
|
263
|
+
<input pInputText id="awsRegion" [formField]="configForm.awsRegion" placeholder="us-east-1" class="w-full" />
|
|
264
|
+
</div>
|
|
265
|
+
<div class="field">
|
|
266
|
+
<label for="awsBucket" class="block font-medium mb-2">Bucket Name *</label>
|
|
267
|
+
<input pInputText id="awsBucket" [formField]="configForm.awsBucket" placeholder="my-bucket" class="w-full" />
|
|
268
|
+
</div>
|
|
269
|
+
<div class="field">
|
|
270
|
+
<label for="awsAccessKeyId" class="block font-medium mb-2">Access Key ID *</label>
|
|
271
|
+
<input pInputText id="awsAccessKeyId" [formField]="configForm.awsAccessKeyId" class="w-full" />
|
|
272
|
+
</div>
|
|
273
|
+
<div class="field">
|
|
274
|
+
<label for="awsSecretAccessKey" class="block font-medium mb-2">Secret Access Key *</label>
|
|
275
|
+
<input type="password" pInputText id="awsSecretAccessKey" [formField]="configForm.awsSecretAccessKey" class="w-full" />
|
|
276
|
+
</div>
|
|
277
|
+
<div class="field md:col-span-2">
|
|
278
|
+
<label for="awsEndpoint" class="block font-medium mb-2">Custom Endpoint (Optional)</label>
|
|
279
|
+
<input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" placeholder="https://s3.custom-endpoint.com" class="w-full" />
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
<!-- Azure Blob Fields -->
|
|
285
|
+
@if (selectedProvider() === fileLocationEnum.AZURE) {
|
|
286
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
|
287
|
+
<div class="field">
|
|
288
|
+
<label for="azureAccountName" class="block font-medium mb-2">Account Name *</label>
|
|
289
|
+
<input pInputText id="azureAccountName" [formField]="configForm.azureAccountName" class="w-full" />
|
|
290
|
+
</div>
|
|
291
|
+
<div class="field">
|
|
292
|
+
<label for="azureContainerName" class="block font-medium mb-2">Container Name *</label>
|
|
293
|
+
<input pInputText id="azureContainerName" [formField]="configForm.azureContainerName" class="w-full" />
|
|
294
|
+
</div>
|
|
295
|
+
<div class="field md:col-span-2">
|
|
296
|
+
<label for="azureAccountKey" class="block font-medium mb-2">Account Key *</label>
|
|
297
|
+
<input type="password" pInputText id="azureAccountKey" [formField]="configForm.azureAccountKey" class="w-full" />
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
<!-- SFTP Fields -->
|
|
303
|
+
@if (selectedProvider() === fileLocationEnum.SFTP) {
|
|
304
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
|
305
|
+
<div class="field">
|
|
306
|
+
<label for="sftpHost" class="block font-medium mb-2">Host *</label>
|
|
307
|
+
<input pInputText id="sftpHost" [formField]="configForm.sftpHost" placeholder="sftp.example.com" class="w-full" />
|
|
308
|
+
</div>
|
|
309
|
+
<div class="field">
|
|
310
|
+
<label for="sftpPort" class="block font-medium mb-2">Port *</label>
|
|
311
|
+
<input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" placeholder="22" class="w-full" />
|
|
312
|
+
</div>
|
|
313
|
+
<div class="field">
|
|
314
|
+
<label for="sftpUsername" class="block font-medium mb-2">Username *</label>
|
|
315
|
+
<input pInputText id="sftpUsername" [formField]="configForm.sftpUsername" class="w-full" />
|
|
316
|
+
</div>
|
|
317
|
+
<div class="field">
|
|
318
|
+
<label for="sftpPassword" class="block font-medium mb-2">Password *</label>
|
|
319
|
+
<input type="password" pInputText id="sftpPassword" [formField]="configForm.sftpPassword" class="w-full" />
|
|
320
|
+
</div>
|
|
321
|
+
<div class="field md:col-span-2">
|
|
322
|
+
<label for="sftpBasePath" class="block font-medium mb-2">Base Path *</label>
|
|
323
|
+
<input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" placeholder="/uploads" class="w-full" />
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
<!-- Local Fields -->
|
|
329
|
+
@if (selectedProvider() === fileLocationEnum.LOCAL) {
|
|
330
|
+
<div class="grid grid-cols-1 gap-4 mt-4">
|
|
331
|
+
<div class="field">
|
|
332
|
+
<label for="localBasePath" class="block font-medium mb-2">Base Path *</label>
|
|
333
|
+
<input pInputText id="localBasePath" [formField]="configForm.localBasePath" placeholder="/var/www/uploads" class="w-full" />
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
<div class="flex gap-2 mt-4">
|
|
339
|
+
<p-button
|
|
340
|
+
type="submit"
|
|
341
|
+
[label]="isEditMode() ? 'Update' : 'Create'"
|
|
342
|
+
icon="pi pi-check"
|
|
343
|
+
[loading]="isLoading()"
|
|
344
|
+
[disabled]="!isFormValid() || isLoading()" />
|
|
345
|
+
<p-button
|
|
346
|
+
type="button"
|
|
347
|
+
label="Cancel"
|
|
348
|
+
severity="secondary"
|
|
349
|
+
icon="pi pi-times"
|
|
350
|
+
[text]="true"
|
|
351
|
+
(onClick)="onCancel()" />
|
|
352
|
+
</div>
|
|
353
|
+
</form>
|
|
354
|
+
</div>
|
|
355
|
+
`, 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: i2.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i3.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: FormField, selector: "[formField]", inputs: ["formField"] }] });
|
|
356
|
+
}
|
|
357
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: StorageConfigFormComponent, decorators: [{
|
|
358
|
+
type: Component,
|
|
359
|
+
args: [{
|
|
360
|
+
selector: 'lib-storage-config-form',
|
|
361
|
+
standalone: true,
|
|
362
|
+
imports: [AngularModule, PrimeModule, FormField],
|
|
363
|
+
template: `
|
|
364
|
+
<div class="card">
|
|
365
|
+
<div class="flex justify-between items-center mb-4">
|
|
366
|
+
<div>
|
|
367
|
+
<h3 class="text-xl font-semibold">
|
|
368
|
+
{{ isEditMode() ? 'Edit Storage Configuration' : 'New Storage Configuration' }}
|
|
369
|
+
</h3>
|
|
370
|
+
@if (showCompanyInfo()) {
|
|
371
|
+
<p class="text-sm text-gray-600 mt-1">
|
|
372
|
+
Company: {{ currentCompanyName() }}
|
|
373
|
+
</p>
|
|
374
|
+
}
|
|
375
|
+
</div>
|
|
376
|
+
<p-button
|
|
377
|
+
label="Back"
|
|
378
|
+
icon="pi pi-arrow-left"
|
|
379
|
+
severity="secondary"
|
|
380
|
+
[text]="true"
|
|
381
|
+
(onClick)="onCancel()" />
|
|
382
|
+
</div>
|
|
383
|
+
|
|
384
|
+
<form (ngSubmit)="onSubmit()">
|
|
385
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
386
|
+
<!-- Name -->
|
|
387
|
+
<div class="field md:col-span-2">
|
|
388
|
+
<label for="name" class="block font-medium mb-2">Configuration Name *</label>
|
|
389
|
+
<input
|
|
390
|
+
pInputText
|
|
391
|
+
id="name"
|
|
392
|
+
[formField]="configForm.name"
|
|
393
|
+
placeholder="e.g., Production AWS S3"
|
|
394
|
+
class="w-full" />
|
|
395
|
+
</div>
|
|
396
|
+
|
|
397
|
+
<!-- Storage Provider -->
|
|
398
|
+
<div class="field md:col-span-2">
|
|
399
|
+
<label for="storage" class="block font-medium mb-2">Storage Provider *</label>
|
|
400
|
+
<select
|
|
401
|
+
id="storage"
|
|
402
|
+
class="p-select-native"
|
|
403
|
+
[formField]="configForm.storage">
|
|
404
|
+
@for (provider of storageProviders; track provider.value) {
|
|
405
|
+
<option [value]="provider.value">{{ provider.label }}</option>
|
|
406
|
+
}
|
|
407
|
+
</select>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<!-- AWS S3 Fields -->
|
|
412
|
+
@if (selectedProvider() === fileLocationEnum.AWS) {
|
|
413
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
|
414
|
+
<div class="field">
|
|
415
|
+
<label for="awsRegion" class="block font-medium mb-2">AWS Region *</label>
|
|
416
|
+
<input pInputText id="awsRegion" [formField]="configForm.awsRegion" placeholder="us-east-1" class="w-full" />
|
|
417
|
+
</div>
|
|
418
|
+
<div class="field">
|
|
419
|
+
<label for="awsBucket" class="block font-medium mb-2">Bucket Name *</label>
|
|
420
|
+
<input pInputText id="awsBucket" [formField]="configForm.awsBucket" placeholder="my-bucket" class="w-full" />
|
|
421
|
+
</div>
|
|
422
|
+
<div class="field">
|
|
423
|
+
<label for="awsAccessKeyId" class="block font-medium mb-2">Access Key ID *</label>
|
|
424
|
+
<input pInputText id="awsAccessKeyId" [formField]="configForm.awsAccessKeyId" class="w-full" />
|
|
425
|
+
</div>
|
|
426
|
+
<div class="field">
|
|
427
|
+
<label for="awsSecretAccessKey" class="block font-medium mb-2">Secret Access Key *</label>
|
|
428
|
+
<input type="password" pInputText id="awsSecretAccessKey" [formField]="configForm.awsSecretAccessKey" class="w-full" />
|
|
429
|
+
</div>
|
|
430
|
+
<div class="field md:col-span-2">
|
|
431
|
+
<label for="awsEndpoint" class="block font-medium mb-2">Custom Endpoint (Optional)</label>
|
|
432
|
+
<input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" placeholder="https://s3.custom-endpoint.com" class="w-full" />
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
<!-- Azure Blob Fields -->
|
|
438
|
+
@if (selectedProvider() === fileLocationEnum.AZURE) {
|
|
439
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
|
440
|
+
<div class="field">
|
|
441
|
+
<label for="azureAccountName" class="block font-medium mb-2">Account Name *</label>
|
|
442
|
+
<input pInputText id="azureAccountName" [formField]="configForm.azureAccountName" class="w-full" />
|
|
443
|
+
</div>
|
|
444
|
+
<div class="field">
|
|
445
|
+
<label for="azureContainerName" class="block font-medium mb-2">Container Name *</label>
|
|
446
|
+
<input pInputText id="azureContainerName" [formField]="configForm.azureContainerName" class="w-full" />
|
|
447
|
+
</div>
|
|
448
|
+
<div class="field md:col-span-2">
|
|
449
|
+
<label for="azureAccountKey" class="block font-medium mb-2">Account Key *</label>
|
|
450
|
+
<input type="password" pInputText id="azureAccountKey" [formField]="configForm.azureAccountKey" class="w-full" />
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
<!-- SFTP Fields -->
|
|
456
|
+
@if (selectedProvider() === fileLocationEnum.SFTP) {
|
|
457
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
|
|
458
|
+
<div class="field">
|
|
459
|
+
<label for="sftpHost" class="block font-medium mb-2">Host *</label>
|
|
460
|
+
<input pInputText id="sftpHost" [formField]="configForm.sftpHost" placeholder="sftp.example.com" class="w-full" />
|
|
461
|
+
</div>
|
|
462
|
+
<div class="field">
|
|
463
|
+
<label for="sftpPort" class="block font-medium mb-2">Port *</label>
|
|
464
|
+
<input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" placeholder="22" class="w-full" />
|
|
465
|
+
</div>
|
|
466
|
+
<div class="field">
|
|
467
|
+
<label for="sftpUsername" class="block font-medium mb-2">Username *</label>
|
|
468
|
+
<input pInputText id="sftpUsername" [formField]="configForm.sftpUsername" class="w-full" />
|
|
469
|
+
</div>
|
|
470
|
+
<div class="field">
|
|
471
|
+
<label for="sftpPassword" class="block font-medium mb-2">Password *</label>
|
|
472
|
+
<input type="password" pInputText id="sftpPassword" [formField]="configForm.sftpPassword" class="w-full" />
|
|
473
|
+
</div>
|
|
474
|
+
<div class="field md:col-span-2">
|
|
475
|
+
<label for="sftpBasePath" class="block font-medium mb-2">Base Path *</label>
|
|
476
|
+
<input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" placeholder="/uploads" class="w-full" />
|
|
477
|
+
</div>
|
|
478
|
+
</div>
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
<!-- Local Fields -->
|
|
482
|
+
@if (selectedProvider() === fileLocationEnum.LOCAL) {
|
|
483
|
+
<div class="grid grid-cols-1 gap-4 mt-4">
|
|
484
|
+
<div class="field">
|
|
485
|
+
<label for="localBasePath" class="block font-medium mb-2">Base Path *</label>
|
|
486
|
+
<input pInputText id="localBasePath" [formField]="configForm.localBasePath" placeholder="/var/www/uploads" class="w-full" />
|
|
487
|
+
</div>
|
|
488
|
+
</div>
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
<div class="flex gap-2 mt-4">
|
|
492
|
+
<p-button
|
|
493
|
+
type="submit"
|
|
494
|
+
[label]="isEditMode() ? 'Update' : 'Create'"
|
|
495
|
+
icon="pi pi-check"
|
|
496
|
+
[loading]="isLoading()"
|
|
497
|
+
[disabled]="!isFormValid() || isLoading()" />
|
|
498
|
+
<p-button
|
|
499
|
+
type="button"
|
|
500
|
+
label="Cancel"
|
|
501
|
+
severity="secondary"
|
|
502
|
+
icon="pi pi-times"
|
|
503
|
+
[text]="true"
|
|
504
|
+
(onClick)="onCancel()" />
|
|
505
|
+
</div>
|
|
506
|
+
</form>
|
|
507
|
+
</div>
|
|
508
|
+
`,
|
|
509
|
+
}]
|
|
510
|
+
}] });
|
|
511
|
+
|
|
512
|
+
export { StorageConfigFormComponent };
|
|
513
|
+
//# sourceMappingURL=flusys-ng-storage-storage-config-form.component-DHzsQ2Mc.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-storage-storage-config-form.component-DHzsQ2Mc.mjs","sources":["../../../projects/ng-storage/pages/storage-config/storage-config-form.component.ts"],"sourcesContent":["import { Component, computed, inject, OnInit, signal } from '@angular/core';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { AngularModule, PrimeModule } from '@flusys/ng-shared';\nimport { APP_CONFIG, isFeatureEnabled } from '@flusys/ng-core'\nimport { MessageService } from 'primeng/api';\nimport { StorageConfigApiService } from '../../services/storage-config-api.service';\nimport { IStorageConfig } from '../../interfaces/storage-config.interface';\nimport { FileLocationEnum } from '../../enums/file-location.enum';\n\n/** Storage config form model interface */\ninterface IStorageConfigFormModel {\n id: string;\n name: string;\n storage: FileLocationEnum;\n // AWS S3\n awsRegion: string;\n awsBucket: string;\n awsAccessKeyId: string;\n awsSecretAccessKey: string;\n awsEndpoint: string;\n // Azure Blob\n azureAccountName: string;\n azureAccountKey: string;\n azureContainerName: string;\n // SFTP\n sftpHost: string;\n sftpPort: string;\n sftpUsername: string;\n sftpPassword: string;\n sftpBasePath: string;\n // Local\n localBasePath: string;\n}\n\n/**\n * Storage Config Form Component\n * Create and edit storage configurations\n */\n@Component({\n selector: 'lib-storage-config-form',\n standalone: true,\n imports: [AngularModule, PrimeModule, FormField],\n template: `\n <div class=\"card\">\n <div class=\"flex justify-between items-center mb-4\">\n <div>\n <h3 class=\"text-xl font-semibold\">\n {{ isEditMode() ? 'Edit Storage Configuration' : 'New Storage Configuration' }}\n </h3>\n @if (showCompanyInfo()) {\n <p class=\"text-sm text-gray-600 mt-1\">\n Company: {{ currentCompanyName() }}\n </p>\n }\n </div>\n <p-button\n label=\"Back\"\n icon=\"pi pi-arrow-left\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onCancel()\" />\n </div>\n\n <form (ngSubmit)=\"onSubmit()\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <!-- Name -->\n <div class=\"field md:col-span-2\">\n <label for=\"name\" class=\"block font-medium mb-2\">Configuration Name *</label>\n <input\n pInputText\n id=\"name\"\n [formField]=\"configForm.name\"\n placeholder=\"e.g., Production AWS S3\"\n class=\"w-full\" />\n </div>\n\n <!-- Storage Provider -->\n <div class=\"field md:col-span-2\">\n <label for=\"storage\" class=\"block font-medium mb-2\">Storage Provider *</label>\n <select\n id=\"storage\"\n class=\"p-select-native\"\n [formField]=\"configForm.storage\">\n @for (provider of storageProviders; track provider.value) {\n <option [value]=\"provider.value\">{{ provider.label }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- AWS S3 Fields -->\n @if (selectedProvider() === fileLocationEnum.AWS) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4\">\n <div class=\"field\">\n <label for=\"awsRegion\" class=\"block font-medium mb-2\">AWS Region *</label>\n <input pInputText id=\"awsRegion\" [formField]=\"configForm.awsRegion\" placeholder=\"us-east-1\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"awsBucket\" class=\"block font-medium mb-2\">Bucket Name *</label>\n <input pInputText id=\"awsBucket\" [formField]=\"configForm.awsBucket\" placeholder=\"my-bucket\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"awsAccessKeyId\" class=\"block font-medium mb-2\">Access Key ID *</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\">Secret Access Key *</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\">Custom Endpoint (Optional)</label>\n <input pInputText id=\"awsEndpoint\" [formField]=\"configForm.awsEndpoint\" placeholder=\"https://s3.custom-endpoint.com\" class=\"w-full\" />\n </div>\n </div>\n }\n\n <!-- Azure Blob Fields -->\n @if (selectedProvider() === fileLocationEnum.AZURE) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4\">\n <div class=\"field\">\n <label for=\"azureAccountName\" class=\"block font-medium mb-2\">Account Name *</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\">Container Name *</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\">Account Key *</label>\n <input type=\"password\" pInputText id=\"azureAccountKey\" [formField]=\"configForm.azureAccountKey\" class=\"w-full\" />\n </div>\n </div>\n }\n\n <!-- SFTP Fields -->\n @if (selectedProvider() === fileLocationEnum.SFTP) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4\">\n <div class=\"field\">\n <label for=\"sftpHost\" class=\"block font-medium mb-2\">Host *</label>\n <input pInputText id=\"sftpHost\" [formField]=\"configForm.sftpHost\" placeholder=\"sftp.example.com\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"sftpPort\" class=\"block font-medium mb-2\">Port *</label>\n <input type=\"number\" pInputText id=\"sftpPort\" [formField]=\"configForm.sftpPort\" placeholder=\"22\" class=\"w-full\" />\n </div>\n <div class=\"field\">\n <label for=\"sftpUsername\" class=\"block font-medium mb-2\">Username *</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\">Password *</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\">Base Path *</label>\n <input pInputText id=\"sftpBasePath\" [formField]=\"configForm.sftpBasePath\" placeholder=\"/uploads\" class=\"w-full\" />\n </div>\n </div>\n }\n\n <!-- Local Fields -->\n @if (selectedProvider() === fileLocationEnum.LOCAL) {\n <div class=\"grid grid-cols-1 gap-4 mt-4\">\n <div class=\"field\">\n <label for=\"localBasePath\" class=\"block font-medium mb-2\">Base Path *</label>\n <input pInputText id=\"localBasePath\" [formField]=\"configForm.localBasePath\" placeholder=\"/var/www/uploads\" class=\"w-full\" />\n </div>\n </div>\n }\n\n <div class=\"flex gap-2 mt-4\">\n <p-button\n type=\"submit\"\n [label]=\"isEditMode() ? 'Update' : 'Create'\"\n icon=\"pi pi-check\"\n [loading]=\"isLoading()\"\n [disabled]=\"!isFormValid() || isLoading()\" />\n <p-button\n type=\"button\"\n label=\"Cancel\"\n severity=\"secondary\"\n icon=\"pi pi-times\"\n [text]=\"true\"\n (onClick)=\"onCancel()\" />\n </div>\n </form>\n </div>\n `,\n})\nexport class StorageConfigFormComponent implements OnInit {\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly configService = inject(StorageConfigApiService);\n private readonly appConfig = inject(APP_CONFIG);\n\n readonly fileLocationEnum = FileLocationEnum;\n readonly isLoading = signal(false);\n readonly existingConfig = signal<IStorageConfig | null>(null);\n readonly isEditMode = computed(() => !!this.existingConfig());\n\n readonly showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature);\n readonly currentCompanyName = computed(() => 'Current Company');\n\n readonly storageProviders = [\n { label: 'AWS S3', value: FileLocationEnum.AWS },\n { label: 'Azure Blob Storage', value: FileLocationEnum.AZURE },\n { label: 'SFTP', value: FileLocationEnum.SFTP },\n { label: 'Local Storage', value: FileLocationEnum.LOCAL },\n ];\n\n // ============================================\n // Form (Signal Forms)\n // ============================================\n\n /** Form model */\n readonly formModel = signal<IStorageConfigFormModel>({\n id: '',\n name: '',\n storage: FileLocationEnum.AWS,\n // AWS S3\n awsRegion: '',\n awsBucket: '',\n awsAccessKeyId: '',\n awsSecretAccessKey: '',\n awsEndpoint: '',\n // Azure\n azureAccountName: '',\n azureAccountKey: '',\n azureContainerName: '',\n // SFTP\n sftpHost: '',\n sftpPort: '22',\n sftpUsername: '',\n sftpPassword: '',\n sftpBasePath: '',\n // Local\n localBasePath: '',\n });\n\n /** Form with validation schema */\n readonly configForm = form(this.formModel, (f) => {\n required(f.name, { message: 'Configuration name is required' });\n });\n\n /** Selected provider */\n readonly selectedProvider = computed(() => this.formModel().storage);\n\n /** Check if form is valid */\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return model.name.trim().length > 0;\n });\n\n ngOnInit(): void {\n const configId = this.route.snapshot.paramMap.get('id');\n if (configId) {\n this.loadConfig(configId);\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\n // Base form values\n const formData: Partial<IStorageConfigFormModel> = {\n id: config.id,\n name: config.name,\n storage: config.storage,\n };\n\n // Load provider-specific config\n if (config.storage === FileLocationEnum.AWS && config.config) {\n formData.awsRegion = config.config['region'] || '';\n formData.awsBucket = config.config['bucket'] || '';\n formData.awsAccessKeyId = config.config['accessKeyId'] || '';\n formData.awsSecretAccessKey = config.config['secretAccessKey'] || '';\n formData.awsEndpoint = config.config['endpoint'] || '';\n } else if (config.storage === FileLocationEnum.AZURE && config.config) {\n formData.azureAccountName = config.config['accountName'] || '';\n formData.azureAccountKey = config.config['accountKey'] || '';\n formData.azureContainerName = config.config['containerName'] || '';\n } else if (config.storage === FileLocationEnum.SFTP && config.config) {\n formData.sftpHost = config.config['host'] || '';\n formData.sftpPort = (config.config['port'] || 22).toString();\n formData.sftpUsername = config.config['username'] || '';\n formData.sftpPassword = config.config['password'] || '';\n formData.sftpBasePath = config.config['basePath'] || '';\n } else if (config.storage === FileLocationEnum.LOCAL && config.config) {\n formData.localBasePath = config.config['basePath'] || '';\n }\n\n this.formModel.update((m) => ({ ...m, ...formData }));\n }\n } catch (error) {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: 'Failed to load storage configuration.',\n });\n this.router.navigate(['/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 let config: Record<string, any> = {};\n\n // Build provider-specific config\n if (formValue.storage === FileLocationEnum.AWS) {\n config = {\n region: formValue.awsRegion,\n bucket: formValue.awsBucket,\n accessKeyId: formValue.awsAccessKeyId,\n secretAccessKey: formValue.awsSecretAccessKey,\n ...(formValue.awsEndpoint && { endpoint: formValue.awsEndpoint }),\n };\n } else if (formValue.storage === FileLocationEnum.AZURE) {\n config = {\n accountName: formValue.azureAccountName,\n accountKey: formValue.azureAccountKey,\n containerName: formValue.azureContainerName,\n };\n } else if (formValue.storage === FileLocationEnum.SFTP) {\n config = {\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 } else if (formValue.storage === FileLocationEnum.LOCAL) {\n config = {\n basePath: formValue.localBasePath,\n };\n }\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 });\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Storage configuration updated successfully.',\n });\n } else {\n await this.configService.insertAsync({\n name: formValue.name,\n storage: formValue.storage,\n config,\n } as any);\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: 'Storage configuration created successfully.',\n });\n }\n\n this.router.navigate(['/storage/configs']);\n } catch (error) {\n this.messageService.add({\n severity: 'error',\n summary: 'Error',\n detail: `Failed to ${this.isEditMode() ? 'update' : 'create'} storage configuration.`,\n });\n } finally {\n this.isLoading.set(false);\n }\n }\n\n onCancel(): void {\n this.router.navigate(['/storage/configs']);\n }\n}\n"],"names":[],"mappings":"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"}
|