Skip to content

Commit 8135518

Browse files
authored
Issue/6880 refactor jsons are compatible function in question adoner (#6891)
* #6880 Refactor jsonsAreCompatible function in Question adoner Fixes #6880 * #6880 - optimize * #6880 add test
1 parent 4c0d78c commit 8135518

File tree

3 files changed

+58
-13
lines changed

3 files changed

+58
-13
lines changed

packages/survey-creator-core/src/components/question.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -479,25 +479,35 @@ export class QuestionAdornerViewModel extends SurveyElementAdornerBase {
479479
return newAction;
480480
}
481481

482-
private jsonsAreCompatible(objJson: any, json: any): boolean {
483-
let question = this.element;
484-
if (!!objJson && !!objJson.type && question.getType() !== objJson.type) {
485-
question = QuestionFactory.Instance.createQuestion(objJson.type, "question") || this.element;
486-
}
482+
public static checkForNeedDefaultSubitems(items: QuestionToolboxItem[]) {
483+
items.filter(i => i.needDefaultSubitem === undefined).forEach((item: QuestionToolboxItem) => {
484+
item.needDefaultSubitem = false;
485+
if (item.items?.length > 0) {
486+
item.needDefaultSubitem = true;
487+
item.items.forEach(subitem => {
488+
const question = QuestionFactory.Instance.createQuestion(item.json.type, "question");
489+
if (QuestionAdornerViewModel.jsonsAreCompatible(question, subitem.json)) item.needDefaultSubitem = false;
490+
});
491+
}
492+
});
493+
}
494+
495+
private static jsonsAreCompatible(element: SurveyElement, json: any): boolean {
496+
let question = element;
487497
const keys = Object.keys(json);
488498
for (let i = 0; i < keys.length; i++) {
489499
const p = keys[i];
490-
if (!objJson && p === "type") continue;
491-
let propertyValue = !!objJson ? objJson[p] : question.getPropertyValue(p);
492-
if (!!objJson && propertyValue === undefined) {
500+
if (p === "type") continue;
501+
let propertyValue = question.getPropertyValue(p);
502+
if (propertyValue === undefined) {
493503
propertyValue = p === "type" ? question.getType() : question.getDefaultPropertyValue(p);
494504
}
495505
if (!Helpers.isTwoValueEquals(json[p], propertyValue)) return false;
496506
}
497507
return true;
498508
}
499509
private jsonIsCorresponded(json: any) {
500-
return this.jsonsAreCompatible(undefined, json);
510+
return QuestionAdornerViewModel.jsonsAreCompatible(this.element, json);
501511
}
502512

503513
private toolboxItemIsCorresponded(toolboxItem: QuestionToolboxItem, someItemSelectedAlready: boolean) {
@@ -525,6 +535,7 @@ export class QuestionAdornerViewModel extends SurveyElementAdornerBase {
525535

526536
protected updateQuestionTypeOrSubtypeListModel(listModel: ListModel, subtypeOnly: boolean) {
527537
const availableItems = this.getConvertToTypes();
538+
QuestionAdornerViewModel.checkForNeedDefaultSubitems(availableItems);
528539
const defaultJsons = this.buildDefaultJsonMap(availableItems);
529540
const newItems: Array<IAction> = [];
530541
let lastItem: QuestionToolboxItem;
@@ -548,14 +559,12 @@ export class QuestionAdornerViewModel extends SurveyElementAdornerBase {
548559
if (item.items?.length > 0 && this.creator.toolbox.showSubitems) {
549560
const subactions = [];
550561
let selectedSubactionLocal: IAction = undefined;
551-
let allChildsAreCompatibleToParent = false;
552562
item.items.forEach(subitem => {
553563
const subaction = toolboxItemToAction(subitem,);
554564
if (this.toolboxItemIsCorresponded(subitem, !!selectedAction)) selectedSubactionLocal = subitem;
555-
if (this.jsonsAreCompatible(item.json, subitem.json)) allChildsAreCompatibleToParent = true;
556565
subactions.push(subaction);
557566
});
558-
if (!allChildsAreCompatibleToParent && subactions.length > 0) {
567+
if (item.needDefaultSubitem && subactions.length > 0) {
559568
const defaultSubaction = toolboxItemToAction(item);
560569
defaultSubaction.id = action.id + "-default";
561570
defaultSubaction.iconName = undefined;

packages/survey-creator-core/src/toolbox.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export class QuestionToolboxItem extends Action implements IQuestionToolboxItem
139139
public propName: string;
140140
public propValue: string;
141141
public showInToolboxOnly: boolean = false;
142+
public needDefaultSubitem: boolean = undefined;
142143
static getItemClassNames(iconName?: string): string {
143144
return new CssClassBuilder()
144145
.append("svc-toolbox__item")
@@ -278,6 +279,7 @@ export class QuestionToolboxItem extends Action implements IQuestionToolboxItem
278279
*/
279280
public clearSubitems(): void {
280281
if (this.hasSubItems) {
282+
this.needDefaultSubitem = undefined;
281283
this.items = [];
282284
this.component = "";
283285
this.popupModel.dispose();
@@ -294,6 +296,7 @@ export class QuestionToolboxItem extends Action implements IQuestionToolboxItem
294296
*/
295297
public addSubitem(subitem: IQuestionToolboxItem, index: number = -1): void {
296298
if (!subitem) return;
299+
this.needDefaultSubitem = undefined;
297300
const newItem: QuestionToolboxItem = new QuestionToolboxItem(subitem);
298301
newItem.iconName = "";
299302
if (!newItem.className) newItem.className = QuestionToolboxItem.getItemClassNames(newItem.iconName);
@@ -316,7 +319,7 @@ export class QuestionToolboxItem extends Action implements IQuestionToolboxItem
316319
*/
317320
public removeSubitem(subitem: IQuestionToolboxItem | string): void {
318321
if (!this.hasSubItems || !subitem) return;
319-
322+
this.needDefaultSubitem = undefined;
320323
const id: string = (subitem as IQuestionToolboxItem)?.id || subitem as string;
321324
if (!id) return;
322325

packages/survey-creator-core/tests/question-adorner.tests.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,5 +1135,38 @@ test("Check question converter subitems", (): any => {
11351135
const subitems = getQuestionConverterList(creator, "q1").getActionById("rating").items;
11361136
expect(subitems.length).toBe(3);
11371137

1138+
surveySettings.animationEnabled = true;
1139+
});
1140+
1141+
test("Check question converter subitems", (): any => {
1142+
surveySettings.animationEnabled = false;
1143+
const creator = new CreatorTester();
1144+
1145+
// create subitems from new items (the same type, different json)
1146+
const text = creator.toolbox.getItemByName("text") as QuestionToolboxItem;
1147+
const number = text.getSubitem("number");
1148+
1149+
expect(text.needDefaultSubitem).toBeUndefined();
1150+
QuestionAdornerViewModel.checkForNeedDefaultSubitems(creator.toolbox.items);
1151+
expect(text.needDefaultSubitem).toBeFalsy();
1152+
1153+
text.needDefaultSubitem = true;
1154+
QuestionAdornerViewModel.checkForNeedDefaultSubitems(creator.toolbox.items);
1155+
expect(text.needDefaultSubitem).toBeTruthy(); // needDefaultSubitem is not recalculated
1156+
1157+
text.removeSubitem(number);
1158+
QuestionAdornerViewModel.checkForNeedDefaultSubitems(creator.toolbox.items);
1159+
expect(text.needDefaultSubitem).toBeFalsy(); // needDefaultSubitem is recalculated after removeSubitem
1160+
1161+
text.needDefaultSubitem = true;
1162+
text.addSubitem(number);
1163+
QuestionAdornerViewModel.checkForNeedDefaultSubitems(creator.toolbox.items);
1164+
expect(text.needDefaultSubitem).toBeFalsy(); // needDefaultSubitem is recalculated after addSubitem
1165+
1166+
text.needDefaultSubitem = true;
1167+
text.clearSubitems();
1168+
QuestionAdornerViewModel.checkForNeedDefaultSubitems(creator.toolbox.items);
1169+
expect(text.needDefaultSubitem).toBeFalsy(); // needDefaultSubitem is recalculated after clearSubitems
1170+
11381171
surveySettings.animationEnabled = true;
11391172
});

0 commit comments

Comments
 (0)