Skip to content

Commit 6a88b23

Browse files
sluFicodesSHENGXING LU
andauthored
Optional characteristic with default enablement implemented (Ficodes#185)
* optional characteristic with default enability implemented * FIX: enabled chars in price component selection --------- Co-authored-by: SHENGXING LU <slu@SHENGXINGs-MacBook-Air.local>
1 parent 57f54e7 commit 6a88b23

9 files changed

Lines changed: 149 additions & 248 deletions

File tree

src/app/pages/seller-offerings/offerings/seller-product-spec/create-product-spec/create-product-spec.component.html

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -557,49 +557,42 @@ <h3 class="font-bold text-primary-100 dark:text-primary-50 text-left ml-4">
557557
</div>
558558
} @else {
559559
<form class="m-4 grid grid-cols-2 gap-4" [formGroup]="charsForm">
560-
@if(!booleanCharSelected){
561-
<div>
562-
<label for="prod-name" class="font-bold text-lg dark:text-white">{{ 'UPDATE_PROD_SPEC._product_name' | translate }}</label>
563-
<input data-cy="charName" formControlName="name" type="text" id="prod-name" maxLength="100"
564-
class="mb-2 bg-gray-50 dark:bg-secondary-300 border border-gray-300 dark:border-secondary-200 dark:text-white text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" />
565-
566-
</div>
567-
} @else {
568-
<div>
569-
@if(nonBooleanChars.length>0){
570-
<label for="prod-name" class="font-bold text-lg dark:text-white">Select the related characteristic's name</label>
571-
<select id="type" (change)="onSelectBooleanName($event)"
572-
class="mb-2 bg-gray-50 dark:bg-secondary-300 border border-gray-300 dark:border-secondary-200 dark:text-white text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
573-
@for(charname of nonBooleanChars; track charname){
574-
<option value="{{charname}}">{{charname}}</option>
575-
}
576-
</select>
577-
}@else{
578-
<div class="flex flex-items items-center align-items-middle text-gray-600 dark:text-gray-200 col-span-2">
579-
<svg class="flex-shrink-0 inline w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
580-
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/>
581-
</svg>
582-
<h3 class="text-sm italic text-gray-600 ml-4 dark:text-gray-200">There's no characteristic available.</h3>
583-
</div>
584-
}
585-
586-
</div>
587-
}
560+
<div>
561+
<label for="prod-name" class="font-bold text-lg dark:text-white">{{ 'UPDATE_PROD_SPEC._product_name' | translate }}</label>
562+
<input data-cy="charName" formControlName="name" type="text" id="prod-name" maxLength="100"
563+
class="mb-2 bg-gray-50 dark:bg-secondary-300 border border-gray-300 dark:border-secondary-200 dark:text-white text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" />
564+
</div>
588565
<div>
589566
<label class="font-bold text-lg dark:text-white">{{ 'CREATE_PROD_SPEC._type' | translate }}</label>
590567
<select data-cy="charType" id="type" (change)="onTypeChange($event)"
591568
class="mb-2 bg-gray-50 dark:bg-secondary-300 border border-gray-300 dark:border-secondary-200 dark:text-white text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
592569
<option selected value="string">String</option>
593570
<option value="number">Number</option>
594571
<option value="range">Number range</option>
595-
<option value="boolean">Boolean</option>
596572
</select>
597573
</div>
598574
<div class="col-span-2">
599575
<label for="description" class="font-bold text-lg dark:text-white">{{ 'CREATE_PROD_SPEC._product_description' | translate }}</label>
600576
<textarea data-cy="charDescription" id="description" formControlName="description" rows="4" maxLength="500"
601577
class="mb-2 min-h-fit bg-gray-50 dark:bg-secondary-300 border border-gray-300 dark:border-secondary-200 dark:text-white text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"></textarea>
602-
</div>
578+
</div>
579+
<div class="col-span-2 flex align-items-middle h-fit">
580+
<label for="is-optional" class="font-bold text-lg dark:text-white">{{ 'CREATE_PROD_SPEC._make_optional' | translate }}</label>
581+
<label class="inline-flex items-center me-5 cursor-pointer ml-4">
582+
<input type="checkbox" id="is-optional" [(ngModel)]="isOptional" [ngModelOptions]="{standalone: true}" class="sr-only peer">
583+
<div class="relative w-11 h-6 bg-gray-400 dark:bg-gray-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-primary-100 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-100"></div>
584+
</label>
585+
</div>
586+
@if(isOptional){
587+
<div>
588+
<label class="font-bold text-lg dark:text-white">{{ 'CREATE_PROD_SPEC._default_value' | translate }}</label>
589+
<select [(ngModel)]="optionalDftTrue" [ngModelOptions]="{standalone: true}"
590+
class="mb-2 bg-gray-50 dark:bg-secondary-300 border border-gray-300 dark:border-secondary-200 dark:text-white text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
591+
<option [value]="false">{{ 'CREATE_PROD_SPEC._default_false' | translate }}</option>
592+
<option [value]="true">{{ 'CREATE_PROD_SPEC._default_true' | translate }}</option>
593+
</select>
594+
</div>
595+
}
603596
</form>
604597
<div class="m-4">
605598
@if(creatingChars.length>0){
@@ -642,7 +635,7 @@ <h3 class="text-sm italic text-gray-600 ml-4 dark:text-gray-200">There's no char
642635
}
643636
</div>
644637
}
645-
<label for="values" [ngClass]="rangeCharSelected && creatingChars.length==1 || booleanCharSelected ? 'hidden' : ''" class="font-bold text-lg dark:text-white">{{ 'CREATE_PROD_SPEC._add_values' | translate }}</label>
638+
<label for="values" [ngClass]="rangeCharSelected && creatingChars.length==1 ? 'hidden' : ''" class="font-bold text-lg dark:text-white">{{ 'CREATE_PROD_SPEC._add_values' | translate }}</label>
646639
@if(stringCharSelected){
647640
<div class="flex flex-row items-center align-items-middle">
648641
<input data-cy="charStringValue" type="text" id="value" [(ngModel)]="stringValue"
@@ -707,7 +700,7 @@ <h3 class="text-sm italic text-gray-600 ml-4 dark:text-gray-200">There's no char
707700
</div>
708701
}
709702
<div class="flex w-full justify-items-center justify-center mt-4">
710-
<button data-cy="btnSaveCharacteristic" type="button" (click)="saveChar()" [disabled]="!charsForm.valid || (creatingChars.length==0 && !booleanCharSelected)" [ngClass]="!charsForm.valid || (creatingChars.length==0 && !booleanCharSelected) ? 'opacity-50' : 'hover:bg-primary-50'" class="flex text-white justify-center bg-primary-100 hover:bg-primary-50 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center">
703+
<button data-cy="btnSaveCharacteristic" type="button" (click)="saveChar()" [disabled]="!charsForm.valid || creatingChars.length==0" [ngClass]="!charsForm.valid || creatingChars.length==0 ? 'opacity-50' : 'hover:bg-primary-50'" class="flex text-white justify-center bg-primary-100 hover:bg-primary-50 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center">
711704
{{ 'CREATE_PROD_SPEC._save_char' | translate }}
712705
<svg class="rtl:rotate-180 w-3.5 h-3.5 ms-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
713706
<path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M11 16h2m6.707-9.293-2.414-2.414A1 1 0 0 0 16.586 4H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V7.414a1 1 0 0 0-.293-.707ZM16 20v-6a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v6h8ZM9 4h6v3a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1V4Z"/>

src/app/pages/seller-offerings/offerings/seller-product-spec/create-product-spec/create-product-spec.component.ts

Lines changed: 30 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
9494
stringCharSelected:boolean=true;
9595
numberCharSelected:boolean=false;
9696
rangeCharSelected:boolean=false;
97-
booleanCharSelected:boolean=false;
97+
isOptional:boolean=false;
98+
optionalDftTrue:boolean=false;
9899
prodChars:ProductSpecificationCharacteristic[]=[];
99100
finishChars:ProductSpecificationCharacteristic[]=[];
100101
creatingChars:CharacteristicValueSpecification[]=[];
101102
showCreateChar:boolean=false;
102-
nonBooleanChars:string[]=[];
103103

104104
//BUNDLE INFO:
105105
bundleChecked:boolean=false;
@@ -691,7 +691,6 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
691691
this.stringCharSelected=true;
692692
this.numberCharSelected=false;
693693
this.rangeCharSelected=false;
694-
this.booleanCharSelected=false;
695694
this.showPreview=false;
696695
this.refreshChars();
697696
}
@@ -1019,7 +1018,8 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
10191018
this.stringCharSelected=true;
10201019
this.numberCharSelected=false;
10211020
this.rangeCharSelected=false;
1022-
this.booleanCharSelected=false;
1021+
this.isOptional=false;
1022+
this.optionalDftTrue=false;
10231023
this.creatingChars=[];
10241024
}
10251025

@@ -1083,37 +1083,23 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
10831083
this.stringCharSelected=true;
10841084
this.numberCharSelected=false;
10851085
this.rangeCharSelected=false;
1086-
this.booleanCharSelected=false;
10871086
this.charsForm.reset();
10881087
}else if (event.target.value=='number'){
10891088
this.stringCharSelected=false;
10901089
this.numberCharSelected=true;
10911090
this.rangeCharSelected=false;
1092-
this.booleanCharSelected=false;
10931091
this.charsForm.reset();
10941092
}else if (event.target.value=='range'){
10951093
this.stringCharSelected=false;
10961094
this.numberCharSelected=false;
10971095
this.rangeCharSelected=true;
1098-
this.booleanCharSelected=false;
10991096
this.charsForm.reset();
1100-
} else {
1101-
this.stringCharSelected=false;
1102-
this.numberCharSelected=false;
1103-
this.rangeCharSelected=false;
1104-
this.booleanCharSelected=true;
1105-
// Set default only if not already selected
1106-
if (!this.charsForm.get('name')?.value && this.nonBooleanChars.length > 0) {
1107-
this.charsForm.get('name')?.setValue(this.nonBooleanChars[0]+' - enabled');
1108-
}
11091097
}
1098+
this.isOptional=false;
1099+
this.optionalDftTrue=false;
11101100
this.creatingChars=[];
11111101
}
11121102

1113-
onSelectBooleanName(event: any){
1114-
this.charsForm.get('name')?.setValue(event.target.value+' - enabled');
1115-
}
1116-
11171103
addCharValue(){
11181104
if(this.stringCharSelected){
11191105
console.log('string')
@@ -1196,44 +1182,32 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
11961182
}
11971183

11981184
saveChar(){
1199-
if(this.booleanCharSelected){
1200-
this.creatingChars=[
1201-
{
1202-
isDefault:false,
1203-
value: true as any
1204-
},
1205-
{
1206-
isDefault:true,
1207-
value:false as any
1208-
}
1209-
]
1210-
}
12111185
if(this.charsForm.value.name!=null){
1186+
// Create the main characteristic
12121187
this.prodChars.push({
12131188
id: 'urn:ngsi-ld:characteristic:'+uuidv4(),
12141189
name: this.charsForm.value.name,
12151190
description: this.charsForm.value.description != null ? this.charsForm.value.description : '',
12161191
productSpecCharacteristicValue: this.creatingChars
12171192
})
12181193

1219-
// Check if it's not a boolean-enabled characteristic
1220-
if (!this.charsForm.value.name.endsWith('- enabled')) {
1221-
// Look for a corresponding "enabled" version
1222-
const hasEnabledVersion = this.prodChars.some(
1223-
(item) => item.name === `${name} - enabled`
1224-
);
1225-
1226-
// Only push if there's no "- enabled" variant
1227-
if (!hasEnabledVersion) {
1228-
this.nonBooleanChars.push(this.charsForm.value.name);
1229-
}
1230-
} else {
1231-
const cleanName = this.charsForm.value.name.replace(/- enabled$/, '').trim();
1232-
const nonBooleanIndex = this.nonBooleanChars.findIndex(item => item === cleanName);
1233-
if (nonBooleanIndex !== -1) {
1234-
console.log('eliminar boolean')
1235-
this.nonBooleanChars.splice(nonBooleanIndex, 1);
1236-
}
1194+
// Create the X - enabled characteristic
1195+
if(this.isOptional){
1196+
this.prodChars.push({
1197+
id: 'urn:ngsi-ld:characteristic:'+uuidv4(),
1198+
name: this.charsForm.value.name + ' - enabled',
1199+
description: 'Optional toggle for ' + this.charsForm.value.name,
1200+
productSpecCharacteristicValue: [
1201+
{
1202+
isDefault: this.optionalDftTrue,
1203+
value: true as any
1204+
},
1205+
{
1206+
isDefault: !this.optionalDftTrue,
1207+
value:false as any
1208+
}
1209+
]
1210+
})
12371211
}
12381212
}
12391213

@@ -1243,6 +1217,8 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
12431217
this.stringCharSelected=true;
12441218
this.numberCharSelected=false;
12451219
this.rangeCharSelected=false;
1220+
this.isOptional=false;
1221+
this.optionalDftTrue=false;
12461222
this.refreshChars();
12471223
this.cdr.detectChanges();
12481224
}
@@ -1254,37 +1230,17 @@ export class CreateProductSpecComponent implements OnInit, OnDestroy {
12541230
this.prodChars.splice(index, 1);
12551231
}
12561232

1257-
if(!char.name.endsWith('- enabled')){
1258-
const nonBooleanIndex = this.nonBooleanChars.findIndex(item => item === char.name);
1259-
if (nonBooleanIndex !== -1) {
1260-
console.log('eliminar boolean')
1261-
this.nonBooleanChars.splice(nonBooleanIndex, 1);
1262-
}
1233+
// If deleting a main characteristic, also delete its "- enabled" variant if it exists
1234+
if(!char.name.endsWith('- enabled')){
12631235
const relatedEnabledIndex = this.prodChars.findIndex(item => item.name === char.name+' - enabled');
12641236
if (relatedEnabledIndex !== -1) {
1265-
console.log('eliminar')
1237+
console.log('eliminar related enabled')
12661238
this.prodChars.splice(relatedEnabledIndex, 1);
12671239
}
1268-
} else {
1269-
const cleanName = char.name.replace(/- enabled$/, '').trim();
1270-
const nonBooleanIndex = this.nonBooleanChars.findIndex(item => item === cleanName);
1271-
if (nonBooleanIndex == -1) {
1272-
console.log('añadir boolean')
1273-
this.nonBooleanChars.push(cleanName)
1274-
}
1275-
}
1276-
1277-
if(this.booleanCharSelected){
1278-
// Set default only if not already selected
1279-
if (this.nonBooleanChars.length > 0) {
1280-
this.charsForm.get('name')?.setValue(this.nonBooleanChars[0]+' - enabled');
1281-
} else {
1282-
this.charsForm.reset();
1283-
}
12841240
}
12851241

12861242
this.cdr.detectChanges();
1287-
console.log(this.prodChars)
1243+
console.log(this.prodChars)
12881244
}
12891245

12901246
checkInput(value: string): boolean {

0 commit comments

Comments
 (0)