@flusys/ng-storage 1.0.0-beta → 1.0.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 (28) hide show
  1. package/README.md +209 -5
  2. package/fesm2022/flusys-ng-storage-file-manager-form.component-Bv8ER8J0.mjs +484 -0
  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-Bc95TVD0.mjs → flusys-ng-storage-storage-config-form.component-DEMexjmg.mjs} +242 -292
  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 +363 -199
  15. package/fesm2022/flusys-ng-storage.mjs.map +1 -1
  16. package/package.json +9 -9
  17. package/types/flusys-ng-storage.d.ts +150 -127
  18. package/fesm2022/flusys-ng-storage-file-manager-form.component-DVZsFYrj.mjs +0 -715
  19. package/fesm2022/flusys-ng-storage-file-manager-form.component-DVZsFYrj.mjs.map +0 -1
  20. package/fesm2022/flusys-ng-storage-file-manager-list.component-CwnyNoYb.mjs +0 -475
  21. package/fesm2022/flusys-ng-storage-file-manager-list.component-CwnyNoYb.mjs.map +0 -1
  22. package/fesm2022/flusys-ng-storage-folder-form.component-DH-KCz21.mjs +0 -253
  23. package/fesm2022/flusys-ng-storage-folder-form.component-DH-KCz21.mjs.map +0 -1
  24. package/fesm2022/flusys-ng-storage-folder-list.component-iIys4NvL.mjs +0 -267
  25. package/fesm2022/flusys-ng-storage-folder-list.component-iIys4NvL.mjs.map +0 -1
  26. package/fesm2022/flusys-ng-storage-storage-config-form.component-Bc95TVD0.mjs.map +0 -1
  27. package/fesm2022/flusys-ng-storage-storage-config-list.component-Bfomqyr3.mjs +0 -328
  28. package/fesm2022/flusys-ng-storage-storage-config-list.component-Bfomqyr3.mjs.map +0 -1
@@ -1,80 +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
- import * as i2 from 'primeng/inputtext';
11
- import * as i3 from 'primeng/button';
9
+ import * as i1$1 from 'primeng/button';
10
+ import * as i3 from 'primeng/inputtext';
11
+ import * as i4 from 'primeng/toggleswitch';
12
12
 
13
- /**
14
- * Storage Config Form Component
15
- * Create and edit storage configurations
16
- */
17
- class StorageConfigFormComponent {
18
- 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 {
19
35
  route = inject(ActivatedRoute);
20
- messageService = inject(MessageService);
21
36
  configService = inject(StorageConfigApiService);
22
- appConfig = inject(APP_CONFIG);
37
+ routeParams = toSignal(this.route.paramMap);
38
+ initialized = false;
23
39
  fileLocationEnum = FileLocationEnum;
24
- isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
40
+ storageProviders = STORAGE_PROVIDERS;
25
41
  existingConfig = signal(null, ...(ngDevMode ? [{ debugName: "existingConfig" }] : []));
26
42
  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 */
43
+ formModel = signal({ ...DEFAULT_FORM_MODEL }, ...(ngDevMode ? [{ debugName: "formModel" }] : []));
63
44
  configForm = form(this.formModel, (f) => {
64
45
  required(f.name, { message: 'Configuration name is required' });
65
46
  });
66
- /** Selected provider */
67
47
  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
- }
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
+ });
78
61
  }
79
62
  async loadConfig(id) {
80
63
  this.isLoading.set(true);
@@ -83,45 +66,20 @@ class StorageConfigFormComponent {
83
66
  if (response.success && response.data) {
84
67
  const config = response.data;
85
68
  this.existingConfig.set(config);
86
- // Base form values
87
- const formData = {
69
+ this.formModel.update((m) => ({
70
+ ...m,
88
71
  id: config.id,
89
72
  name: config.name,
90
73
  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 }));
74
+ isActive: config.isActive ?? true,
75
+ isDefault: config.isDefault ?? false,
76
+ ...this.extractProviderConfig(config),
77
+ }));
116
78
  }
117
79
  }
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']);
80
+ catch {
81
+ this.showError('Failed to load storage configuration.');
82
+ this.navigateTo(['/storage/configs']);
125
83
  }
126
84
  finally {
127
85
  this.isLoading.set(false);
@@ -133,381 +91,373 @@ class StorageConfigFormComponent {
133
91
  this.isLoading.set(true);
134
92
  try {
135
93
  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
- }
94
+ const config = this.buildProviderConfig(formValue);
168
95
  if (this.isEditMode()) {
169
96
  await this.configService.updateAsync({
170
97
  id: formValue.id,
171
98
  name: formValue.name,
172
99
  storage: formValue.storage,
173
100
  config,
101
+ isActive: formValue.isActive,
102
+ isDefault: formValue.isDefault,
174
103
  });
175
- this.messageService.add({
176
- severity: 'success',
177
- summary: 'Success',
178
- detail: 'Storage configuration updated successfully.',
179
- });
104
+ this.showSuccess('Storage configuration updated successfully.');
180
105
  }
181
106
  else {
182
107
  await this.configService.insertAsync({
183
108
  name: formValue.name,
184
109
  storage: formValue.storage,
185
110
  config,
111
+ isActive: formValue.isActive,
112
+ isDefault: formValue.isDefault,
186
113
  });
187
- this.messageService.add({
188
- severity: 'success',
189
- summary: 'Success',
190
- detail: 'Storage configuration created successfully.',
191
- });
114
+ this.showSuccess('Storage configuration created successfully.');
192
115
  }
193
- this.router.navigate(['/storage/configs']);
116
+ this.navigateTo(['/storage/configs']);
194
117
  }
195
- catch (error) {
196
- this.messageService.add({
197
- severity: 'error',
198
- summary: 'Error',
199
- detail: `Failed to ${this.isEditMode() ? 'update' : 'create'} storage configuration.`,
200
- });
118
+ catch {
119
+ this.showError(`Failed to ${this.isEditMode() ? 'update' : 'create'} storage configuration.`);
201
120
  }
202
121
  finally {
203
122
  this.isLoading.set(false);
204
123
  }
205
124
  }
206
125
  onCancel() {
207
- 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
+ }
208
188
  }
209
189
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: StorageConfigFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
210
- 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: `
211
191
  <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>
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
+ }
230
198
 
231
199
  <form (ngSubmit)="onSubmit()">
232
200
  <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" />
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" />
242
204
  </div>
243
205
 
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">
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">
251
209
  @for (provider of storageProviders; track provider.value) {
252
210
  <option [value]="provider.value">{{ provider.label }}</option>
253
211
  }
254
212
  </select>
255
213
  </div>
214
+
215
+ <div class="field flex items-center gap-2">
216
+ <p-toggleswitch [formField]="configForm.isActive" />
217
+ <label class="text-sm sm:text-base">Active</label>
218
+ </div>
219
+
220
+ <div class="field flex items-center gap-2">
221
+ <p-toggleswitch [formField]="configForm.isDefault" />
222
+ <label class="text-sm sm:text-base">Set as Default</label>
223
+ </div>
256
224
  </div>
257
225
 
258
- <!-- AWS S3 Fields -->
259
226
  @if (selectedProvider() === fileLocationEnum.AWS) {
260
- <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>
261
231
  <div class="field">
262
- <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>
263
233
  <input pInputText id="awsRegion" [formField]="configForm.awsRegion" placeholder="us-east-1" class="w-full" />
264
234
  </div>
265
235
  <div class="field">
266
- <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>
267
237
  <input pInputText id="awsBucket" [formField]="configForm.awsBucket" placeholder="my-bucket" class="w-full" />
268
238
  </div>
269
239
  <div class="field">
270
- <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>
271
241
  <input pInputText id="awsAccessKeyId" [formField]="configForm.awsAccessKeyId" class="w-full" />
272
242
  </div>
273
243
  <div class="field">
274
- <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>
275
245
  <input type="password" pInputText id="awsSecretAccessKey" [formField]="configForm.awsSecretAccessKey" class="w-full" />
276
246
  </div>
277
247
  <div class="field md:col-span-2">
278
- <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>
279
249
  <input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" placeholder="https://s3.custom-endpoint.com" class="w-full" />
280
250
  </div>
281
251
  </div>
282
252
  }
283
253
 
284
- <!-- Azure Blob Fields -->
285
254
  @if (selectedProvider() === fileLocationEnum.AZURE) {
286
- <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>
287
259
  <div class="field">
288
- <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>
289
261
  <input pInputText id="azureAccountName" [formField]="configForm.azureAccountName" class="w-full" />
290
262
  </div>
291
263
  <div class="field">
292
- <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>
293
265
  <input pInputText id="azureContainerName" [formField]="configForm.azureContainerName" class="w-full" />
294
266
  </div>
295
267
  <div class="field md:col-span-2">
296
- <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>
297
269
  <input type="password" pInputText id="azureAccountKey" [formField]="configForm.azureAccountKey" class="w-full" />
298
270
  </div>
299
271
  </div>
300
272
  }
301
273
 
302
- <!-- SFTP Fields -->
303
274
  @if (selectedProvider() === fileLocationEnum.SFTP) {
304
- <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>
305
279
  <div class="field">
306
- <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>
307
281
  <input pInputText id="sftpHost" [formField]="configForm.sftpHost" placeholder="sftp.example.com" class="w-full" />
308
282
  </div>
309
283
  <div class="field">
310
- <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>
311
285
  <input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" placeholder="22" class="w-full" />
312
286
  </div>
313
287
  <div class="field">
314
- <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>
315
289
  <input pInputText id="sftpUsername" [formField]="configForm.sftpUsername" class="w-full" />
316
290
  </div>
317
291
  <div class="field">
318
- <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>
319
293
  <input type="password" pInputText id="sftpPassword" [formField]="configForm.sftpPassword" class="w-full" />
320
294
  </div>
321
295
  <div class="field md:col-span-2">
322
- <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>
323
297
  <input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" placeholder="/uploads" class="w-full" />
324
298
  </div>
325
299
  </div>
326
300
  }
327
301
 
328
- <!-- Local Fields -->
329
302
  @if (selectedProvider() === fileLocationEnum.LOCAL) {
330
- <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>
331
307
  <div class="field">
332
- <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>
333
309
  <input pInputText id="localBasePath" [formField]="configForm.localBasePath" placeholder="/var/www/uploads" class="w-full" />
334
310
  </div>
335
311
  </div>
336
312
  }
337
313
 
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()" />
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()" />
352
317
  </div>
353
318
  </form>
354
319
  </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"] }] });
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 });
356
321
  }
357
322
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: StorageConfigFormComponent, decorators: [{
358
323
  type: Component,
359
324
  args: [{
360
325
  selector: 'lib-storage-config-form',
361
- standalone: true,
326
+ changeDetection: ChangeDetectionStrategy.OnPush,
362
327
  imports: [AngularModule, PrimeModule, FormField],
363
328
  template: `
364
329
  <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>
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
+ }
383
336
 
384
337
  <form (ngSubmit)="onSubmit()">
385
338
  <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" />
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" />
395
342
  </div>
396
343
 
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">
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">
404
347
  @for (provider of storageProviders; track provider.value) {
405
348
  <option [value]="provider.value">{{ provider.label }}</option>
406
349
  }
407
350
  </select>
408
351
  </div>
352
+
353
+ <div class="field flex items-center gap-2">
354
+ <p-toggleswitch [formField]="configForm.isActive" />
355
+ <label class="text-sm sm:text-base">Active</label>
356
+ </div>
357
+
358
+ <div class="field flex items-center gap-2">
359
+ <p-toggleswitch [formField]="configForm.isDefault" />
360
+ <label class="text-sm sm:text-base">Set as Default</label>
361
+ </div>
409
362
  </div>
410
363
 
411
- <!-- AWS S3 Fields -->
412
364
  @if (selectedProvider() === fileLocationEnum.AWS) {
413
- <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>
414
369
  <div class="field">
415
- <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>
416
371
  <input pInputText id="awsRegion" [formField]="configForm.awsRegion" placeholder="us-east-1" class="w-full" />
417
372
  </div>
418
373
  <div class="field">
419
- <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>
420
375
  <input pInputText id="awsBucket" [formField]="configForm.awsBucket" placeholder="my-bucket" class="w-full" />
421
376
  </div>
422
377
  <div class="field">
423
- <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>
424
379
  <input pInputText id="awsAccessKeyId" [formField]="configForm.awsAccessKeyId" class="w-full" />
425
380
  </div>
426
381
  <div class="field">
427
- <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>
428
383
  <input type="password" pInputText id="awsSecretAccessKey" [formField]="configForm.awsSecretAccessKey" class="w-full" />
429
384
  </div>
430
385
  <div class="field md:col-span-2">
431
- <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>
432
387
  <input pInputText id="awsEndpoint" [formField]="configForm.awsEndpoint" placeholder="https://s3.custom-endpoint.com" class="w-full" />
433
388
  </div>
434
389
  </div>
435
390
  }
436
391
 
437
- <!-- Azure Blob Fields -->
438
392
  @if (selectedProvider() === fileLocationEnum.AZURE) {
439
- <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>
440
397
  <div class="field">
441
- <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>
442
399
  <input pInputText id="azureAccountName" [formField]="configForm.azureAccountName" class="w-full" />
443
400
  </div>
444
401
  <div class="field">
445
- <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>
446
403
  <input pInputText id="azureContainerName" [formField]="configForm.azureContainerName" class="w-full" />
447
404
  </div>
448
405
  <div class="field md:col-span-2">
449
- <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>
450
407
  <input type="password" pInputText id="azureAccountKey" [formField]="configForm.azureAccountKey" class="w-full" />
451
408
  </div>
452
409
  </div>
453
410
  }
454
411
 
455
- <!-- SFTP Fields -->
456
412
  @if (selectedProvider() === fileLocationEnum.SFTP) {
457
- <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>
458
417
  <div class="field">
459
- <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>
460
419
  <input pInputText id="sftpHost" [formField]="configForm.sftpHost" placeholder="sftp.example.com" class="w-full" />
461
420
  </div>
462
421
  <div class="field">
463
- <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>
464
423
  <input type="number" pInputText id="sftpPort" [formField]="configForm.sftpPort" placeholder="22" class="w-full" />
465
424
  </div>
466
425
  <div class="field">
467
- <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>
468
427
  <input pInputText id="sftpUsername" [formField]="configForm.sftpUsername" class="w-full" />
469
428
  </div>
470
429
  <div class="field">
471
- <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>
472
431
  <input type="password" pInputText id="sftpPassword" [formField]="configForm.sftpPassword" class="w-full" />
473
432
  </div>
474
433
  <div class="field md:col-span-2">
475
- <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>
476
435
  <input pInputText id="sftpBasePath" [formField]="configForm.sftpBasePath" placeholder="/uploads" class="w-full" />
477
436
  </div>
478
437
  </div>
479
438
  }
480
439
 
481
- <!-- Local Fields -->
482
440
  @if (selectedProvider() === fileLocationEnum.LOCAL) {
483
- <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>
484
445
  <div class="field">
485
- <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>
486
447
  <input pInputText id="localBasePath" [formField]="configForm.localBasePath" placeholder="/var/www/uploads" class="w-full" />
487
448
  </div>
488
449
  </div>
489
450
  }
490
451
 
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()" />
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()" />
505
455
  </div>
506
456
  </form>
507
457
  </div>
508
458
  `,
509
459
  }]
510
- }] });
460
+ }], ctorParameters: () => [] });
511
461
 
512
462
  export { StorageConfigFormComponent };
513
- //# sourceMappingURL=flusys-ng-storage-storage-config-form.component-Bc95TVD0.mjs.map
463
+ //# sourceMappingURL=flusys-ng-storage-storage-config-form.component-DEMexjmg.mjs.map