</div>
@if( isTierMatch(TIER_TYPE.LOCAL )){
<ng-container *ngTemplateOutlet="storageClassField"></ng-container>
- <div class="form-item">
+ <div class="form-item clipboard">
<cd-alert-panel type="info"
[showTitle]="false"
spacingClass="mb-2"
<cds-text-label labelInputID="storage_class"
i18n
[disabled]="editing"
- [invalid]="storageClassForm.controls.storage_class.invalid && storageClassForm.controls.storage_class.dirty"
+ [invalid]="storageClass.isInvalid"
[invalidText]="storageClassError"
>Name
<input cdsText
+ cdValidate
+ #storageClass="cdValidate"
type="text"
id="storage_class"
formControlName="storage_class"
- [invalid]="storageClassForm.showError('storage_class', formDir, 'required')"/>
+ [invalid]="storageClass.isInvalid"/>
</cds-text-label>
<ng-template #storageClassError>
+ @if (storageClassForm.showError('storage_class', formDir, 'required')) {
<span class="invalid-feedback"
- *ngIf="storageClassForm.showError('storage_class', formDir, 'required')"
i18n>This field is required.</span>
+ } @else if (storageClassForm.showError('storage_class', formDir, 'uniqueName')) {
+ <span class="invalid-feedback"
+ i18n>The Storage Class name is already in use.</span>
+ }
</ng-template>
</ng-template>
expect(component).toBeTruthy();
});
+ it('should mark duplicate storage class names as invalid', () => {
+ component.existingStorageClasses = [
+ {
+ storage_class: 'storageClass1',
+ placement_target: 'placement1',
+ zonegroup_name: 'zonegroup1'
+ }
+ ];
+
+ const control = component.storageClassForm.get('storage_class');
+ control.setValue('storageClass1');
+ control.updateValueAndValidity();
+
+ expect(control.hasError('uniqueName')).toBe(true);
+ });
+
it('should set required validators for CLOUD_TIER fields', () => {
(component as any).updateValidatorsBasedOnStorageClass(TIER_TYPE_DISPLAY.CLOUD_TIER);
const requiredFields = ['region', 'target_endpoint', 'access_key', 'secret_key', 'target_path'];
defaultZonegroup: ZoneGroup;
zoneGroupDetails: ZoneGroupDetails;
storageClassInfo: StorageClass;
+ existingStorageClasses: StorageClass[] = [];
tierTargetInfo: TierTarget;
glacierStorageClassDetails: S3Glacier;
allowReadThrough: boolean = false;
});
this.storageClassForm = this.formBuilder.group({
storage_class: new FormControl('', {
- validators: [Validators.required]
+ validators: [
+ Validators.required,
+ CdValidators.custom('uniqueName', (storageClassName: string) => {
+ return this.existingStorageClasses.some(
+ (storageClass: StorageClass) => storageClass.storage_class === storageClassName
+ );
+ })
+ ]
}),
zonegroup: new FormControl(this.selectedZoneGroup, {
validators: [Validators.required]
this.rgwZoneGroupService.getAllZonegroupsInfo().subscribe(
(data: ZoneGroupDetails) => {
this.zoneGroupDetails = data;
+ this.existingStorageClasses = BucketTieringUtils.filterAndMapTierTargets(data);
+ this.storageClassForm.get('storage_class')?.updateValueAndValidity({ emitEvent: false });
this.zonegroupNames = [];
this.zones = [];
if (data.zonegroups && data.zonegroups.length > 0) {