@flusys/ng-storage 1.1.1-beta → 2.0.0-rc.0

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