Skip to content

Commit

Permalink
Take information from dynamic type for dynamic properties in the prop… (
Browse files Browse the repository at this point in the history
#5092)

* Take information from dynamic type for dynamic properties in the property grid

* Fix unit tests
  • Loading branch information
andrewtelnov authored Jan 22, 2024
1 parent 13a2369 commit 13f31e0
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 49 deletions.
107 changes: 59 additions & 48 deletions packages/survey-creator-core/src/question-editor/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import {
SurveyQuestionEditorDefinition,
ISurveyQuestionEditorDefinition,
} from "./definition";
import * as Survey from "survey-core";
import { JsonObjectProperty, Serializer, JsonMetadataClass } from "survey-core";
import { SurveyHelper } from "../survey-helper";
import { ISurveyCreatorOptions, settings } from "../creator-settings";

export class SurveyQuestionEditorPropertyDefinition {
public property: Survey.JsonObjectProperty;
public property: JsonObjectProperty;
public title: string;
public category: string;
public createdFromTabName: boolean;
Expand All @@ -29,7 +29,7 @@ const otherTabName = "others";

export class SurveyQuestionProperties {
private showModeValue: string;
private properties: Array<Survey.JsonObjectProperty>;
private properties: Array<JsonObjectProperty>;
private propertiesHash: any;
private tabs: Array<SurveyQuestionEditorTabDefinition> = [];
constructor(
Expand All @@ -38,14 +38,14 @@ export class SurveyQuestionProperties {
className: string = null,
showMode: string = null,
private parentObj: any = null,
private parentProperty: Survey.JsonObjectProperty = null
private parentProperty: JsonObjectProperty = null
) {
this.showModeValue = showMode;
this.properties = Survey.Serializer.getPropertiesByObj(this.obj);
this.properties = Serializer.getPropertiesByObj(this.obj);
this.fillPropertiesHash();
this.buildTabs(className);
}
public getProperty(propertyName: string): Survey.JsonObjectProperty {
public getProperty(propertyName: string): JsonObjectProperty {
var res = this.propertiesHash[propertyName];
return !!res && res.visible ? res.property : null;
}
Expand Down Expand Up @@ -76,7 +76,7 @@ export class SurveyQuestionProperties {
};
}
}
private isJSONPropertyVisible(property: Survey.JsonObjectProperty): boolean {
private isJSONPropertyVisible(property: JsonObjectProperty): boolean {
var res = this.propertiesHash[property.name];
return !!res && res.visible;
}
Expand All @@ -91,7 +91,7 @@ export class SurveyQuestionProperties {
}
public getProperties(
tab: SurveyQuestionEditorTabDefinition
): Array<Survey.JsonObjectProperty> {
): Array<JsonObjectProperty> {
var res = [];
for (var i = 0; i < tab.properties.length; i++) {
res.push(tab.properties[i].property);
Expand Down Expand Up @@ -208,7 +208,7 @@ export class SurveyQuestionProperties {
}
return null;
}
private getNextToNameProperty(property: Survey.JsonObjectProperty): string {
private getNextToNameProperty(property: JsonObjectProperty): string {
if(!property.nextToProperty) return "";
if(this.isPropertyOnSameLine(property.nextToProperty)) return property.nextToProperty.substring(1);
return property.nextToProperty;
Expand Down Expand Up @@ -270,55 +270,66 @@ export class SurveyQuestionProperties {
this.addNonTabProperties(result, usedProperties, true);
return result;
}
var curClassName = className;
var hasNonTabProperties = false;
let hasNonTabProperties = this.getAllDefinitionsByClassCore(className, usedProperties, result);
const dynamicClass = this.obj.isQuestion && !!this.obj.getDynamicType ? this.obj.getDynamicType() : "";
if(dynamicClass) {
hasNonTabProperties = this.getAllDefinitionsByClassCore(dynamicClass, usedProperties, result);
}

if (!hasNonTabProperties) {
this.addNonTabProperties(result, usedProperties);
}
return result;
}
private getAllDefinitionsByClassCore(className: string, usedProperties: any, result: Array<ISurveyQuestionEditorDefinition>): boolean {
let res = false;
let curClassName = className;
while (curClassName) {
let metaClass = <Survey.JsonMetadataClass>(
Survey.Serializer.findClass(curClassName)
let metaClass = <JsonMetadataClass>(
Serializer.findClass(curClassName)
);
if (!metaClass) break;
let classRes = SurveyQuestionEditorDefinition.definition[metaClass.name];
if (classRes) {
if (classRes.properties) {
var i = 0;
while (i < classRes.properties.length) {
var prop = classRes.properties[i];
var propName = typeof prop == "string" ? prop : prop.name;
var tabName = settings.propertyGrid.generalTabName;
if (typeof prop !== "string" && !!prop.tab) {
tabName = prop.tab;
}
var jsonProp = !!this.propertiesHash[propName]
? this.propertiesHash[propName].property
: null;
var jsonPropertyCategory = this.getJsonPropertyCategory(jsonProp);
if (!!jsonPropertyCategory && jsonPropertyCategory !== tabName) {
classRes.properties.splice(i, 1);
} else {
usedProperties[propName] = true;
i++;
}
}
res = this.getAllDefinitionsByClassSingleCore(metaClass.name, usedProperties, result);
curClassName = metaClass.parentName;
}
return res;
}
private getAllDefinitionsByClassSingleCore(className: string, usedProperties: any, result: Array<ISurveyQuestionEditorDefinition>): boolean {
const classRes = SurveyQuestionEditorDefinition.definition[className];
let res = false;
if(!classRes) return res;
if (classRes.properties) {
var i = 0;
while (i < classRes.properties.length) {
var prop = classRes.properties[i];
var propName = typeof prop == "string" ? prop : prop.name;
var tabName = settings.propertyGrid.generalTabName;
if (typeof prop !== "string" && !!prop.tab) {
tabName = prop.tab;
}
if (classRes.tabs) {
for (var i = 0; i < classRes.tabs.length; i++) {
hasNonTabProperties =
hasNonTabProperties || classRes.tabs[i].name === otherTabName;
usedProperties[classRes.tabs[i].name] = true;
}
var jsonProp = !!this.propertiesHash[propName]
? this.propertiesHash[propName].property
: null;
var jsonPropertyCategory = this.getJsonPropertyCategory(jsonProp);
if (!!jsonPropertyCategory && jsonPropertyCategory !== tabName) {
classRes.properties.splice(i, 1);
} else {
usedProperties[propName] = true;
i++;
}
result.unshift(classRes);
}
curClassName = metaClass.parentName;
}

if (!hasNonTabProperties) {
this.addNonTabProperties(result, usedProperties);
if (classRes.tabs) {
for (var i = 0; i < classRes.tabs.length; i++) {
res = res || classRes.tabs[i].name === otherTabName;
usedProperties[classRes.tabs[i].name] = true;
}
}
return result;
result.unshift(classRes);
return res;
}
private getJsonPropertyCategory(
jsonProperty: Survey.JsonObjectProperty
jsonProperty: JsonObjectProperty
): string {
if (!jsonProperty) return null;
if (!!jsonProperty.category) return jsonProperty.category;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import {
surveyLocalization,
AdaptiveActionContainer,
QuestionCommentModel,
QuestionImagePickerModel
QuestionImagePickerModel,
ComponentCollection
} from "survey-core";
import {
EmptySurveyCreatorOptions,
Expand Down Expand Up @@ -2949,3 +2950,29 @@ test("Allow delete all pages by default", () => {
expect(pagesQuestion.canRemoveRow(pagesQuestion.visibleRows[0])).toBeTruthy();
expect(pagesQuestion.canRemoveRow(pagesQuestion.visibleRows[1])).toBeTruthy();
});
test("Setup correct categories for dynamic properties in components", () => {
ComponentCollection.Instance.add({
name: "customdropdown",
inheritBaseProps: ["allowClear", "showOtherItem"],
questionJSON: {
type: "dropdown",
choices: [1, 2, 3]
},
});
const survey = new SurveyModel();
survey.setDesignMode(true);
survey.fromJSON({
elements: [
{ type: "customdropdown", name: "q1", allowClear: false, showOtherItem: true }
]
});
const question = survey.getQuestionByName("q1");
var propertyGrid = new PropertyGridModelTester(question);
const visibleQuestion = propertyGrid.survey.getQuestionByName("visible");
const allowClearQuestion = propertyGrid.survey.getQuestionByName("allowClear");
const showOtherItemQuestion = propertyGrid.survey.getQuestionByName("showOtherItem");
expect(visibleQuestion.parent.name).toBe("general");
expect(allowClearQuestion.parent.name).toBe("choices");
expect(showOtherItemQuestion.parent.name).toBe("choices");
ComponentCollection.Instance.clear();
});

0 comments on commit 13f31e0

Please sign in to comment.