Widget validation for nested property paths (#3947)

This commit is contained in:
Hetu Nandu 2021-04-21 20:04:25 +05:30 committed by GitHub
parent 14ceab809a
commit 4d73e7e0b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 507 additions and 713 deletions

View File

@ -1,4 +1,5 @@
import { getPropertyControlTypes } from "components/propertyControls";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
const ControlTypes = getPropertyControlTypes();
export type ControlType = typeof ControlTypes[keyof typeof ControlTypes];
@ -42,6 +43,7 @@ export type PropertyPaneControlConfig = {
hidden?: (props: any, propertyPath: string) => boolean;
isBindProperty: boolean;
isTriggerProperty: boolean;
validation?: VALIDATION_TYPES;
useValidationMessage?: boolean;
additionalAutoComplete?: (
props: any,

View File

@ -2,34 +2,34 @@ import { WidgetProps } from "widgets/BaseWidget";
import { DataTree } from "entities/DataTree/dataTreeFactory";
import { EXECUTION_PARAM_KEY } from "constants/AppsmithActionConstants/ActionConstants";
// Always add a validator function in ./Validators for these types
export const VALIDATION_TYPES = {
TEXT: "TEXT",
REGEX: "REGEX",
NUMBER: "NUMBER",
BOOLEAN: "BOOLEAN",
OBJECT: "OBJECT",
ARRAY: "ARRAY",
TABLE_DATA: "TABLE_DATA",
OPTIONS_DATA: "OPTIONS_DATA",
DATE_ISO_STRING: "DATE_ISO_STRING",
DEFAULT_DATE: "DEFAULT_DATE",
MIN_DATE: "MIN_DATE",
MAX_DATE: "MAX_DATE",
TABS_DATA: "TABS_DATA",
CHART_DATA: "CHART_DATA",
CUSTOM_FUSION_CHARTS_DATA: "CUSTOM_FUSION_CHARTS_DATA",
MARKERS: "MARKERS",
ACTION_SELECTOR: "ACTION_SELECTOR",
ARRAY_ACTION_SELECTOR: "ARRAY_ACTION_SELECTOR",
SELECTED_TAB: "SELECTED_TAB",
DEFAULT_OPTION_VALUE: "DEFAULT_OPTION_VALUE",
DEFAULT_SELECTED_ROW: "DEFAULT_SELECTED_ROW",
COLUMN_PROPERTIES_ARRAY: "COLUMN_PROPERTIES_ARRAY",
LAT_LONG: "LAT_LONG",
TABLE_PAGE_NO: "TABLE_PAGE_NO",
ROW_INDICES: "ROW_INDICES",
};
// Always add a validator function in ./worker/validation for these types
export enum VALIDATION_TYPES {
TEXT = "TEXT",
REGEX = "REGEX",
NUMBER = "NUMBER",
BOOLEAN = "BOOLEAN",
OBJECT = "OBJECT",
ARRAY = "ARRAY",
TABLE_DATA = "TABLE_DATA",
OPTIONS_DATA = "OPTIONS_DATA",
DATE_ISO_STRING = "DATE_ISO_STRING",
DEFAULT_DATE = "DEFAULT_DATE",
MIN_DATE = "MIN_DATE",
MAX_DATE = "MAX_DATE",
TABS_DATA = "TABS_DATA",
CHART_DATA = "CHART_DATA",
CUSTOM_FUSION_CHARTS_DATA = "CUSTOM_FUSION_CHARTS_DATA",
MARKERS = "MARKERS",
ACTION_SELECTOR = "ACTION_SELECTOR",
ARRAY_ACTION_SELECTOR = "ARRAY_ACTION_SELECTOR",
SELECTED_TAB = "SELECTED_TAB",
DEFAULT_OPTION_VALUE = "DEFAULT_OPTION_VALUE",
DEFAULT_SELECTED_ROW = "DEFAULT_SELECTED_ROW",
COLUMN_PROPERTIES_ARRAY = "COLUMN_PROPERTIES_ARRAY",
LAT_LONG = "LAT_LONG",
TABLE_PAGE_NO = "TABLE_PAGE_NO",
ROW_INDICES = "ROW_INDICES",
}
export type ValidationResponse = {
isValid: boolean;
@ -38,7 +38,6 @@ export type ValidationResponse = {
transformed?: any;
};
export type ValidationType = typeof VALIDATION_TYPES[keyof typeof VALIDATION_TYPES];
export type Validator = (
value: any,
props: WidgetProps,

View File

@ -12,6 +12,7 @@ import { AppDataState } from "reducers/entityReducers/appReducer";
import { DynamicPath } from "utils/DynamicBindingUtils";
import { generateDataTreeAction } from "entities/DataTree/dataTreeAction";
import { generateDataTreeWidget } from "entities/DataTree/dataTreeWidget";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
export type ActionDescription<T> = {
type: string;
@ -52,6 +53,7 @@ export interface DataTreeAction extends Omit<ActionData, "data" | "config"> {
export interface DataTreeWidget extends WidgetProps {
bindingPaths: Record<string, boolean>;
triggerPaths: Record<string, boolean>;
validationPaths: Record<string, VALIDATION_TYPES>;
ENTITY_TYPE: ENTITY_TYPE.WIDGET;
}

View File

@ -0,0 +1,245 @@
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
import { generateDataTreeWidget } from "entities/DataTree/dataTreeWidget";
import { DataTreeWidget, ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
import { RenderModes, WidgetTypes } from "constants/WidgetConstants";
import WidgetFactory from "utils/WidgetFactory";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
describe("generateDataTreeWidget", () => {
beforeEach(() => {
const getMetaProps = jest.spyOn(
WidgetFactory,
"getWidgetMetaPropertiesMap",
);
getMetaProps.mockReturnValueOnce({
text: undefined,
isDirty: false,
isFocused: false,
});
const getDerivedProps = jest.spyOn(
WidgetFactory,
"getWidgetDerivedPropertiesMap",
);
getDerivedProps.mockReturnValueOnce({
isValid: "{{true}}",
value: "{{this.text}}",
});
const getDefaultProps = jest.spyOn(
WidgetFactory,
"getWidgetDefaultPropertiesMap",
);
getDefaultProps.mockReturnValueOnce({
text: "defaultText",
});
const getPropertyConfig = jest.spyOn(
WidgetFactory,
"getWidgetPropertyPaneConfig",
);
getPropertyConfig.mockReturnValueOnce([
{
sectionName: "General",
children: [
{
propertyName: "inputType",
label: "Data Type",
controlType: "DROP_DOWN",
isBindProperty: false,
isTriggerProperty: false,
},
{
propertyName: "defaultText",
label: "Default Text",
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "placeholderText",
label: "Placeholder",
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "regex",
label: "Regex",
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.REGEX,
},
{
propertyName: "errorMessage",
label: "Error Message",
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "isRequired",
label: "Required",
controlType: "SWITCH",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
label: "Visible",
controlType: "SWITCH",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
label: "Disabled",
controlType: "SWITCH",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "resetOnSubmit",
label: "Reset on submit",
controlType: "SWITCH",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
{
sectionName: "Actions",
children: [
{
propertyName: "onTextChanged",
label: "onTextChanged",
controlType: "ACTION_SELECTOR",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: true,
},
{
propertyName: "onSubmit",
label: "onSubmit",
controlType: "ACTION_SELECTOR",
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: true,
},
],
},
]);
});
afterEach(() => {
jest.clearAllMocks();
});
it("generates enhanced widget with the right properties", () => {
const widget: FlattenedWidgetProps = {
bottomRow: 0,
isLoading: false,
leftColumn: 0,
parentColumnSpace: 0,
parentRowSpace: 0,
renderMode: RenderModes.CANVAS,
rightColumn: 0,
topRow: 0,
type: WidgetTypes.INPUT_WIDGET,
version: 0,
widgetId: "123",
widgetName: "Input1",
defaultText: "Testing",
};
const widgetMetaProps: Record<string, unknown> = {
text: "Tester",
isDirty: true,
};
const getMetaProps = jest.spyOn(
WidgetFactory,
"getWidgetMetaPropertiesMap",
);
getMetaProps.mockReturnValueOnce({
text: true,
isDirty: true,
});
const expected: DataTreeWidget = {
bindingPaths: {
defaultText: true,
errorMessage: true,
isDirty: true,
isDisabled: true,
isFocused: true,
isRequired: true,
isValid: true,
isVisible: true,
placeholderText: true,
regex: true,
resetOnSubmit: true,
text: true,
value: true,
},
triggerPaths: {
onSubmit: true,
onTextChanged: true,
},
validationPaths: {
defaultText: VALIDATION_TYPES.TEXT,
errorMessage: VALIDATION_TYPES.TEXT,
isDisabled: VALIDATION_TYPES.BOOLEAN,
isRequired: VALIDATION_TYPES.BOOLEAN,
isVisible: VALIDATION_TYPES.BOOLEAN,
placeholderText: VALIDATION_TYPES.TEXT,
regex: VALIDATION_TYPES.REGEX,
resetOnSubmit: VALIDATION_TYPES.BOOLEAN,
},
dynamicBindingPathList: [
{
key: "isValid",
},
{
key: "value",
},
],
value: "{{Input1.text}}",
isDirty: true,
isFocused: false,
isValid: "{{true}}",
text: "Tester",
bottomRow: 0,
isLoading: false,
leftColumn: 0,
parentColumnSpace: 0,
parentRowSpace: 0,
renderMode: RenderModes.CANVAS,
rightColumn: 0,
topRow: 0,
type: WidgetTypes.INPUT_WIDGET,
version: 0,
widgetId: "123",
widgetName: "Input1",
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
defaultText: "Testing",
};
const result = generateDataTreeWidget(widget, widgetMetaProps);
expect(result).toStrictEqual(expected);
});
});

View File

@ -19,7 +19,11 @@ export const generateDataTreeWidget = (
const propertyPaneConfigs = WidgetFactory.getWidgetPropertyPaneConfig(
widget.type,
);
const { bindingPaths, triggerPaths } = getAllPathsFromPropertyConfig(
const {
bindingPaths,
triggerPaths,
validationPaths,
} = getAllPathsFromPropertyConfig(
widget,
propertyPaneConfigs,
Object.fromEntries(
@ -67,6 +71,7 @@ export const generateDataTreeWidget = (
dynamicBindingPathList,
bindingPaths,
triggerPaths,
validationPaths,
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
};
};

View File

@ -145,6 +145,12 @@ describe("getAllPathsFromPropertyConfig", () => {
onPageSizeChange: true,
"primaryColumns.status.onClick": true,
},
validationPaths: {
defaultSearchText: "TEXT",
defaultSelectedRow: "DEFAULT_SELECTED_ROW",
isVisible: "BOOLEAN",
tableData: "TABLE_DATA",
},
};
const result = getAllPathsFromPropertyConfig(widget, config, {
@ -202,6 +208,14 @@ describe("getAllPathsFromPropertyConfig", () => {
triggerPaths: {
onDataPointClick: true,
},
validationPaths: {
"chartData[0].data": "CHART_DATA",
"chartData[0].seriesName": "TEXT",
chartName: "TEXT",
isVisible: "BOOLEAN",
xAxisName: "TEXT",
yAxisName: "TEXT",
},
};
const result = getAllPathsFromPropertyConfig(widget, config, {});

View File

@ -2,6 +2,7 @@ import { WidgetProps } from "widgets/BaseWidget";
import { PropertyPaneConfig } from "constants/PropertyControlConstants";
import { get } from "lodash";
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
export const getAllPathsFromPropertyConfig = (
widget: WidgetProps,
@ -10,9 +11,11 @@ export const getAllPathsFromPropertyConfig = (
): {
bindingPaths: Record<string, true>;
triggerPaths: Record<string, true>;
validationPaths: Record<string, VALIDATION_TYPES>;
} => {
const bindingPaths: Record<string, true> = derivedProperties;
const triggerPaths: Record<string, true> = {};
const validationPaths: Record<any, VALIDATION_TYPES> = {};
widgetConfig.forEach((config) => {
if (config.children) {
config.children.forEach((controlConfig: any) => {
@ -27,6 +30,10 @@ export const getAllPathsFromPropertyConfig = (
!controlConfig.isTriggerProperty
) {
bindingPaths[controlConfig.propertyName] = true;
if (controlConfig.validation) {
validationPaths[controlConfig.propertyName] =
controlConfig.validation;
}
} else if (
controlConfig.isBindProperty &&
controlConfig.isTriggerProperty
@ -66,6 +73,10 @@ export const getAllPathsFromPropertyConfig = (
!panelColumnControlConfig.isTriggerProperty
) {
bindingPaths[panelPropertyPath] = true;
if (panelColumnControlConfig.validation) {
validationPaths[panelPropertyPath] =
panelColumnControlConfig.validation;
}
} else if (
panelColumnControlConfig.isBindProperty &&
panelColumnControlConfig.isTriggerProperty
@ -97,6 +108,10 @@ export const getAllPathsFromPropertyConfig = (
!childPropertyConfig.isTriggerProperty
) {
bindingPaths[childArrayPropertyPath] = true;
if (childPropertyConfig.validation) {
validationPaths[childArrayPropertyPath] =
childPropertyConfig.validation;
}
} else if (
childPropertyConfig.isBindProperty &&
childPropertyConfig.isTriggerProperty
@ -112,7 +127,7 @@ export const getAllPathsFromPropertyConfig = (
}
});
return { bindingPaths, triggerPaths };
return { bindingPaths, triggerPaths, validationPaths };
};
export const nextAvailableRowInContainer = (

View File

@ -199,16 +199,6 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
widgetName: "RadioGroup",
version: 1,
},
ALERT_WIDGET: {
alertType: "NOTIFICATION",
intent: "SUCCESS",
rows: 3,
columns: 3,
header: "",
message: "",
widgetName: "Alert",
version: 1,
},
FILE_PICKER_WIDGET: {
rows: 1,
files: [],

View File

@ -14,7 +14,6 @@ import { TableWidgetProps } from "../../widgets/TableWidget/TableWidgetConstants
import { DropdownWidgetProps } from "../../widgets/DropdownWidget";
import { CheckboxWidgetProps } from "../../widgets/CheckboxWidget";
import { RadioGroupWidgetProps } from "../../widgets/RadioGroupWidget";
import { AlertWidgetProps } from "../../widgets/AlertWidget";
import { FilePickerWidgetProps } from "../../widgets/FilepickerWidget";
import {
TabsWidgetProps,
@ -67,7 +66,6 @@ export interface WidgetConfigReducerState {
CHECKBOX_WIDGET: Partial<CheckboxWidgetProps> & WidgetConfigProps;
SWITCH_WIDGET: Partial<SwitchWidgetProps> & WidgetConfigProps;
RADIO_GROUP_WIDGET: Partial<RadioGroupWidgetProps> & WidgetConfigProps;
ALERT_WIDGET: Partial<AlertWidgetProps> & WidgetConfigProps;
FILE_PICKER_WIDGET: Partial<FilePickerWidgetProps> & WidgetConfigProps;
TABS_WIDGET: Partial<TabsWidgetProps<TabContainerWidgetProps>> &
WidgetConfigProps;

View File

@ -23,7 +23,6 @@ import {
EvalErrorTypes,
} from "utils/DynamicBindingUtils";
import log from "loglevel";
import { WidgetType } from "constants/WidgetConstants";
import { WidgetProps } from "widgets/BaseWidget";
import PerformanceTracker, {
PerformanceTransactionName,
@ -209,17 +208,17 @@ export function* clearEvalPropertyCacheOfWidget(widgetName: string) {
}
export function* validateProperty(
widgetType: WidgetType,
property: string,
value: any,
props: WidgetProps,
) {
const unevalTree = yield select(getUnevaluatedDataTree);
const validation = unevalTree[props.widgetName].validationPaths[property];
return yield call(worker.request, EVAL_WORKER_ACTIONS.VALIDATE_PROPERTY, {
widgetTypeConfigMap,
widgetType,
property,
value,
props,
validation,
});
}

View File

@ -817,7 +817,6 @@ function* setWidgetDynamicPropertySaga(
});
const { parsed } = yield call(
validateProperty,
widget.type,
propertyPath,
propertyValue,
widget,

View File

@ -262,6 +262,7 @@ const createLoadingWidget = (
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
bindingPaths: {},
triggerPaths: {},
validationPaths: {},
isLoading: true,
};
};

View File

@ -5,10 +5,6 @@ import {
WidgetDataProps,
WidgetState,
} from "widgets/BaseWidget";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "./WidgetValidation";
import React from "react";
import {
PropertyPaneConfig,
@ -49,10 +45,6 @@ class WidgetFactory {
WidgetType,
WidgetBuilder<WidgetProps, WidgetState>
> = new Map();
static widgetPropValidationMap: Map<
WidgetType,
WidgetPropertyValidationType
> = new Map();
static widgetDerivedPropertiesGetterMap: Map<
WidgetType,
WidgetDerivedPropertyType
@ -74,14 +66,12 @@ class WidgetFactory {
static registerWidgetBuilder(
widgetType: WidgetType,
widgetBuilder: WidgetBuilder<WidgetProps, WidgetState>,
widgetPropertyValidation: WidgetPropertyValidationType,
derivedPropertiesMap: DerivedPropertiesMap,
defaultPropertiesMap: Record<string, string>,
metaPropertiesMap: Record<string, any>,
propertyPaneConfig?: PropertyPaneConfig[],
) {
this.widgetMap.set(widgetType, widgetBuilder);
this.widgetPropValidationMap.set(widgetType, widgetPropertyValidation);
this.derivedPropertiesMap.set(widgetType, derivedPropertiesMap);
this.defaultPropertiesMap.set(widgetType, defaultPropertiesMap);
this.metaPropertiesMap.set(widgetType, metaPropertiesMap);
@ -122,17 +112,6 @@ class WidgetFactory {
return Array.from(this.widgetMap.keys());
}
static getWidgetPropertyValidationMap(
widgetType: WidgetType,
): WidgetPropertyValidationType {
const map = this.widgetPropValidationMap.get(widgetType);
if (!map) {
console.error("Widget type validation is not defined");
return BASE_WIDGET_VALIDATION;
}
return map;
}
static getWidgetDerivedPropertiesMap(
widgetType: WidgetType,
): DerivedPropertiesMap {
@ -181,7 +160,6 @@ class WidgetFactory {
const typeConfigMap: WidgetTypeConfigMap = {};
WidgetFactory.getWidgetTypes().forEach((type) => {
typeConfigMap[type] = {
validations: WidgetFactory.getWidgetPropertyValidationMap(type),
defaultProperties: WidgetFactory.getWidgetDefaultPropertiesMap(type),
derivedProperties: WidgetFactory.getWidgetDerivedPropertiesMap(type),
metaProperties: WidgetFactory.getWidgetMetaPropertiesMap(type),
@ -194,7 +172,6 @@ class WidgetFactory {
export type WidgetTypeConfigMap = Record<
string,
{
validations: WidgetPropertyValidationType;
derivedProperties: WidgetDerivedPropertyType;
defaultProperties: Record<string, string>;
metaProperties: Record<string, any>;

View File

@ -105,7 +105,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledContainerWidget {...widgetData} />;
},
},
ContainerWidget.getPropertyValidationMap(),
ContainerWidget.getDerivedPropertiesMap(),
ContainerWidget.getDefaultPropertiesMap(),
ContainerWidget.getMetaPropertiesMap(),
@ -119,7 +118,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledTextWidget {...widgetData} />;
},
},
TextWidget.getPropertyValidationMap(),
TextWidget.getDerivedPropertiesMap(),
TextWidget.getDefaultPropertiesMap(),
TextWidget.getMetaPropertiesMap(),
@ -133,7 +131,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledButtonWidget {...widgetData} />;
},
},
ButtonWidget.getPropertyValidationMap(),
ButtonWidget.getDerivedPropertiesMap(),
ButtonWidget.getDefaultPropertiesMap(),
ButtonWidget.getMetaPropertiesMap(),
@ -147,7 +144,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledInputWidget {...widgetData} />;
},
},
InputWidget.getPropertyValidationMap(),
InputWidget.getDerivedPropertiesMap(),
InputWidget.getDefaultPropertiesMap(),
InputWidget.getMetaPropertiesMap(),
@ -161,7 +157,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledCheckboxWidget {...widgetData} />;
},
},
CheckboxWidget.getPropertyValidationMap(),
CheckboxWidget.getDerivedPropertiesMap(),
CheckboxWidget.getDefaultPropertiesMap(),
CheckboxWidget.getMetaPropertiesMap(),
@ -175,7 +170,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledSwitchWidget {...widgetData} />;
},
},
SwitchWidget.getPropertyValidationMap(),
SwitchWidget.getDerivedPropertiesMap(),
SwitchWidget.getDefaultPropertiesMap(),
SwitchWidget.getMetaPropertiesMap(),
@ -189,7 +183,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledDropDownWidget {...widgetData} />;
},
},
DropdownWidget.getPropertyValidationMap(),
DropdownWidget.getDerivedPropertiesMap(),
DropdownWidget.getDefaultPropertiesMap(),
DropdownWidget.getMetaPropertiesMap(),
@ -203,7 +196,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledRadioGroupWidget {...widgetData} />;
},
},
RadioGroupWidget.getPropertyValidationMap(),
RadioGroupWidget.getDerivedPropertiesMap(),
RadioGroupWidget.getDefaultPropertiesMap(),
RadioGroupWidget.getMetaPropertiesMap(),
@ -217,7 +209,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledImageWidget {...widgetData} />;
},
},
ImageWidget.getPropertyValidationMap(),
ImageWidget.getDerivedPropertiesMap(),
ImageWidget.getDefaultPropertiesMap(),
ImageWidget.getMetaPropertiesMap(),
@ -230,7 +221,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledTableWidget {...widgetData} />;
},
},
TableWidget.getPropertyValidationMap(),
TableWidget.getDerivedPropertiesMap(),
TableWidget.getDefaultPropertiesMap(),
TableWidget.getMetaPropertiesMap(),
@ -244,7 +234,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledVideoWidget {...widgetData} />;
},
},
VideoWidget.getPropertyValidationMap(),
VideoWidget.getDerivedPropertiesMap(),
VideoWidget.getDefaultPropertiesMap(),
VideoWidget.getMetaPropertiesMap(),
@ -258,7 +247,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledFilePickerWidget {...widgetData} />;
},
},
FilePickerWidget.getPropertyValidationMap(),
FilePickerWidget.getDerivedPropertiesMap(),
FilePickerWidget.getDefaultPropertiesMap(),
FilePickerWidget.getMetaPropertiesMap(),
@ -271,7 +259,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledDatePickerWidget {...widgetData} />;
},
},
DatePickerWidget.getPropertyValidationMap(),
DatePickerWidget.getDerivedPropertiesMap(),
DatePickerWidget.getDefaultPropertiesMap(),
DatePickerWidget.getMetaPropertiesMap(),
@ -284,7 +271,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledDatePickerWidget2 {...widgetData} />;
},
},
DatePickerWidget2.getPropertyValidationMap(),
DatePickerWidget2.getDerivedPropertiesMap(),
DatePickerWidget2.getDefaultPropertiesMap(),
DatePickerWidget2.getMetaPropertiesMap(),
@ -299,7 +285,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledTabsWidget {...widgetProps} />;
},
},
TabsWidget.getPropertyValidationMap(),
TabsWidget.getDerivedPropertiesMap(),
TabsWidget.getDefaultPropertiesMap(),
TabsWidget.getMetaPropertiesMap(),
@ -312,7 +297,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledModalWidget {...widgetProps} />;
},
},
BaseWidget.getPropertyValidationMap(),
BaseWidget.getDerivedPropertiesMap(),
BaseWidget.getDefaultPropertiesMap(),
BaseWidget.getMetaPropertiesMap(),
@ -325,7 +309,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledRichTextEditorWidget {...widgetData} />;
},
},
RichTextEditorWidget.getPropertyValidationMap(),
RichTextEditorWidget.getDerivedPropertiesMap(),
RichTextEditorWidget.getDefaultPropertiesMap(),
RichTextEditorWidget.getMetaPropertiesMap(),
@ -338,7 +321,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledChartWidget {...widgetData} />;
},
},
ChartWidget.getPropertyValidationMap(),
ChartWidget.getDerivedPropertiesMap(),
ChartWidget.getDefaultPropertiesMap(),
ChartWidget.getMetaPropertiesMap(),
@ -353,7 +335,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledFormWidget {...widgetProps} />;
},
},
FormWidget.getPropertyValidationMap(),
FormWidget.getDerivedPropertiesMap(),
FormWidget.getDefaultPropertiesMap(),
FormWidget.getMetaPropertiesMap(),
@ -367,7 +348,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledFormButtonWidget {...widgetProps} />;
},
},
FormButtonWidget.getPropertyValidationMap(),
FormButtonWidget.getDerivedPropertiesMap(),
FormButtonWidget.getDefaultPropertiesMap(),
FormButtonWidget.getMetaPropertiesMap(),
@ -381,7 +361,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledMapWidget {...widgetProps} />;
},
},
MapWidget.getPropertyValidationMap(),
MapWidget.getDerivedPropertiesMap(),
MapWidget.getDefaultPropertiesMap(),
MapWidget.getMetaPropertiesMap(),
@ -397,7 +376,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledCanvasWidget {...widgetData} />;
},
},
CanvasWidget.getPropertyValidationMap(),
CanvasWidget.getDerivedPropertiesMap(),
CanvasWidget.getDefaultPropertiesMap(),
CanvasWidget.getMetaPropertiesMap(),
@ -411,7 +389,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledIconWidget {...widgetProps} />;
},
},
IconWidget.getPropertyValidationMap(),
IconWidget.getDerivedPropertiesMap(),
IconWidget.getDefaultPropertiesMap(),
IconWidget.getMetaPropertiesMap(),
@ -425,7 +402,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledSkeletonWidget {...widgetProps} />;
},
},
SkeletonWidget.getPropertyValidationMap(),
SkeletonWidget.getDerivedPropertiesMap(),
SkeletonWidget.getDefaultPropertiesMap(),
SkeletonWidget.getMetaPropertiesMap(),
@ -439,7 +415,6 @@ export default class WidgetBuilderRegistry {
return <ProfiledModalWidget {...widgetData} />;
},
},
ModalWidget.getPropertyValidationMap(),
ModalWidget.getDerivedPropertiesMap(),
ModalWidget.getDefaultPropertiesMap(),
ModalWidget.getMetaPropertiesMap(),

View File

@ -1,16 +0,0 @@
import {
VALIDATION_TYPES,
ValidationType,
Validator,
} from "constants/WidgetValidation";
export const BASE_WIDGET_VALIDATION = {
isLoading: VALIDATION_TYPES.BOOLEAN,
isVisible: VALIDATION_TYPES.BOOLEAN,
isDisabled: VALIDATION_TYPES.BOOLEAN,
};
export type WidgetPropertyValidationType = Record<
string,
ValidationType | Validator
>;

View File

@ -31,6 +31,7 @@ describe("dataTreeTypeDefCreator", () => {
triggerPaths: {
onTextChange: true,
},
validationPaths: {},
},
};
const def = dataTreeTypeDefCreator(dataTree);

View File

@ -1,20 +0,0 @@
import React, { Component } from "react";
import { WidgetProps } from "./BaseWidget";
class AlertWidget extends Component {
getPageView() {
return <div />;
}
}
export type AlertType = "DIALOG" | "NOTIFICATION";
export type MessageIntent = "SUCCESS" | "ERROR" | "INFO" | "WARNING";
export interface AlertWidgetProps extends WidgetProps {
alertType: AlertType;
intent: MessageIntent;
header: string;
message: string;
}
export default AlertWidget;

View File

@ -24,10 +24,6 @@ import shallowequal from "shallowequal";
import { PositionTypes } from "constants/WidgetConstants";
import { EditorContext } from "components/editorComponents/EditorContextProvider";
import ErrorBoundary from "components/editorComponents/ErrorBoundry";
import {
BASE_WIDGET_VALIDATION,
WidgetPropertyValidationType,
} from "utils/WidgetValidation";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import {
WidgetDynamicPathListProps,
@ -57,11 +53,6 @@ abstract class BaseWidget<
static getPropertyPaneConfig(): PropertyPaneConfig[] {
return [];
}
// Needed to send a default no validation option. In case a widget needs
// validation implement this in the widget class again
static getPropertyValidationMap(): WidgetPropertyValidationType {
return BASE_WIDGET_VALIDATION;
}
static getDerivedPropertiesMap(): DerivedPropertiesMap {
return {};

View File

@ -5,10 +5,6 @@ import ButtonComponent, {
ButtonType,
} from "components/designSystems/blueprint/ButtonComponent";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import * as Sentry from "@sentry/react";
import withMeta, { WithMeta } from "./MetaHOC";
@ -38,6 +34,7 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
placeholderText: "Enter label text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "buttonStyle",
@ -69,6 +66,7 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -78,6 +76,7 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "googleRecaptchaKey",
@ -87,6 +86,7 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
placeholderText: "Enter google recaptcha key",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
],
},
@ -107,14 +107,6 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
text: VALIDATION_TYPES.TEXT,
buttonStyle: VALIDATION_TYPES.TEXT,
// onClick: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getMetaPropertiesMap(): Record<string, any> {
return {
recaptchaToken: undefined,

View File

@ -1,8 +1,6 @@
import React, { lazy, Suspense } from "react";
import BaseWidget, { WidgetProps, WidgetState } from "widgets/BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import { WidgetPropertyValidationType } from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import Skeleton from "components/utils/Skeleton";
import * as Sentry from "@sentry/react";
import { retryPromise } from "utils/AppsmithUtils";
@ -20,17 +18,6 @@ const ChartComponent = lazy(() =>
);
class ChartWidget extends BaseWidget<ChartWidgetProps, WidgetState> {
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
xAxisName: VALIDATION_TYPES.TEXT,
yAxisName: VALIDATION_TYPES.TEXT,
chartName: VALIDATION_TYPES.TEXT,
isVisible: VALIDATION_TYPES.BOOLEAN,
chartData: VALIDATION_TYPES.CHART_DATA,
customFusionChartConfig: VALIDATION_TYPES.CUSTOM_FUSION_CHARTS_DATA,
};
}
static getMetaPropertiesMap(): Record<string, undefined> {
return {
selectedDataPoint: undefined,

View File

@ -1,4 +1,5 @@
import { ChartWidgetProps } from "widgets/ChartWidget";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
export default [
{
@ -12,6 +13,7 @@ export default [
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Changes the visualisation of the chart data",
@ -56,6 +58,7 @@ export default [
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -69,6 +72,7 @@ export default [
isBindProperty: true,
isTriggerProperty: false,
hidden: (x: any) => x.chartType !== "CUSTOM_FUSION_CHART",
validation: VALIDATION_TYPES.CUSTOM_FUSION_CHARTS_DATA,
},
{
sectionName: "Chart Data",
@ -92,6 +96,7 @@ export default [
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Series data",
@ -100,6 +105,7 @@ export default [
controlType: "INPUT_TEXT_AREA",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.CHART_DATA,
},
],
},
@ -118,6 +124,7 @@ export default [
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Specifies the label of the y-axis",
@ -127,6 +134,7 @@ export default [
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Enables scrolling inside the chart",

View File

@ -4,10 +4,6 @@ import { WidgetType } from "constants/WidgetConstants";
import CheckboxComponent from "components/designSystems/blueprint/CheckboxComponent";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import * as Sentry from "@sentry/react";
import withMeta, { WithMeta } from "./MetaHOC";
@ -27,6 +23,7 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
placeholderText: "Enter label text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "alignWidget",
@ -55,6 +52,7 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isRequired",
@ -64,6 +62,7 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
@ -73,6 +72,7 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -82,6 +82,7 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -101,14 +102,6 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
label: VALIDATION_TYPES.TEXT,
defaultCheckedState: VALIDATION_TYPES.BOOLEAN,
// onCheckChange: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDefaultPropertiesMap(): Record<string, string> {
return {

View File

@ -14,6 +14,7 @@ import {
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import * as Sentry from "@sentry/react";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
class ContainerWidget extends BaseWidget<
ContainerWidgetProps<WidgetProps>,
@ -37,6 +38,7 @@ class ContainerWidget extends BaseWidget<
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Controls the visibility of the widget",
@ -46,6 +48,7 @@ class ContainerWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "shouldScrollContents",

View File

@ -3,10 +3,6 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import DatePickerComponent from "components/designSystems/blueprint/DatePickerComponent";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import * as Sentry from "@sentry/react";
@ -29,6 +25,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.DEFAULT_DATE,
},
{
helpText: "Sets the format of the selected date",
@ -60,6 +57,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
],
isBindProperty: true,
isTriggerProperty: false,
dateFormat: VALIDATION_TYPES.TEXT,
},
{
propertyName: "isRequired",
@ -69,6 +67,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
@ -78,6 +77,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -87,6 +87,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "minDate",
@ -96,6 +97,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.MIN_DATE,
},
{
propertyName: "maxDate",
@ -105,6 +107,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.MAX_DATE,
},
],
},
@ -123,22 +126,6 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
defaultDate: VALIDATION_TYPES.DEFAULT_DATE,
timezone: VALIDATION_TYPES.TEXT,
enableTimePicker: VALIDATION_TYPES.BOOLEAN,
dateFormat: VALIDATION_TYPES.TEXT,
label: VALIDATION_TYPES.TEXT,
datePickerType: VALIDATION_TYPES.TEXT,
maxDate: VALIDATION_TYPES.MAX_DATE,
minDate: VALIDATION_TYPES.MIN_DATE,
isRequired: VALIDATION_TYPES.BOOLEAN,
// onDateSelected: VALIDATION_TYPES.ACTION_SELECTOR,
// onDateRangeSelected: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDerivedPropertiesMap(): DerivedPropertiesMap {
return {

View File

@ -3,10 +3,6 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import DatePickerComponent from "components/designSystems/blueprint/DatePickerComponent2";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import * as Sentry from "@sentry/react";
@ -30,6 +26,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.DEFAULT_DATE,
},
{
helpText: "Sets the format of the selected date",
@ -122,6 +119,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
],
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "isRequired",
@ -131,6 +129,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
@ -140,6 +139,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -149,6 +149,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "minDate",
@ -159,6 +160,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.DATE_ISO_STRING,
},
{
propertyName: "maxDate",
@ -169,6 +171,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.DATE_ISO_STRING,
},
],
},
@ -188,23 +191,6 @@ class DatePickerWidget extends BaseWidget<DatePickerWidget2Props, WidgetState> {
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
defaultDate: VALIDATION_TYPES.DEFAULT_DATE,
timezone: VALIDATION_TYPES.TEXT,
enableTimePicker: VALIDATION_TYPES.BOOLEAN,
dateFormat: VALIDATION_TYPES.TEXT,
label: VALIDATION_TYPES.TEXT,
datePickerType: VALIDATION_TYPES.TEXT,
maxDate: VALIDATION_TYPES.DATE_ISO_STRING,
minDate: VALIDATION_TYPES.DATE_ISO_STRING,
isRequired: VALIDATION_TYPES.BOOLEAN,
// onDateSelected: VALIDATION_TYPES.ACTION_SELECTOR,
// onDateRangeSelected: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDerivedPropertiesMap(): DerivedPropertiesMap {
return {
isValid: `{{ this.isRequired ? !!this.selectedDate : true }}`,

View File

@ -4,10 +4,6 @@ import { WidgetType } from "constants/WidgetConstants";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import DropDownComponent from "components/designSystems/blueprint/DropdownComponent";
import _ from "lodash";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { Intent as BlueprintIntent } from "@blueprintjs/core";
import * as Sentry from "@sentry/react";
@ -48,6 +44,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
placeholderText: 'Enter [{label: "label1", value: "value2"}]',
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.OPTIONS_DATA,
},
{
helpText: "Selects the option with value by default",
@ -57,6 +54,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
placeholderText: "Enter option value",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.DEFAULT_OPTION_VALUE,
},
{
propertyName: "isRequired",
@ -66,6 +64,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Controls the visibility of the widget",
@ -75,6 +74,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -84,6 +84,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -103,21 +104,6 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
placeholderText: VALIDATION_TYPES.TEXT,
label: VALIDATION_TYPES.TEXT,
options: VALIDATION_TYPES.OPTIONS_DATA,
selectionType: VALIDATION_TYPES.TEXT,
isRequired: VALIDATION_TYPES.BOOLEAN,
// onOptionChange: VALIDATION_TYPES.ACTION_SELECTOR,
selectedOptionValues: VALIDATION_TYPES.ARRAY,
selectedOptionLabels: VALIDATION_TYPES.ARRAY,
selectedOptionLabel: VALIDATION_TYPES.TEXT,
defaultOptionValue: VALIDATION_TYPES.DEFAULT_OPTION_VALUE,
};
}
static getDerivedPropertiesMap() {
return {

View File

@ -7,10 +7,6 @@ import GoogleDrive from "@uppy/google-drive";
import Webcam from "@uppy/webcam";
import Url from "@uppy/url";
import OneDrive from "@uppy/onedrive";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import {
EventType,
@ -50,6 +46,7 @@ class FilePickerWidget extends BaseWidget<
inputType: "TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "maxNumFiles",
@ -61,6 +58,7 @@ class FilePickerWidget extends BaseWidget<
inputType: "INTEGER",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.NUMBER,
},
{
propertyName: "maxFileSize",
@ -115,6 +113,7 @@ class FilePickerWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.ARRAY,
},
{
helpText: "Set the format of the data read from the files",
@ -146,6 +145,7 @@ class FilePickerWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
@ -155,6 +155,7 @@ class FilePickerWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "uploadedFileUrlPaths",
@ -175,6 +176,7 @@ class FilePickerWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -195,17 +197,6 @@ class FilePickerWidget extends BaseWidget<
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
label: VALIDATION_TYPES.TEXT,
maxNumFiles: VALIDATION_TYPES.NUMBER,
allowedFileTypes: VALIDATION_TYPES.ARRAY,
selectedFiles: VALIDATION_TYPES.ARRAY,
isRequired: VALIDATION_TYPES.BOOLEAN,
// onFilesSelected: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDerivedPropertiesMap(): DerivedPropertiesMap {
return {

View File

@ -8,10 +8,6 @@ import {
EventType,
ExecutionResult,
} from "constants/AppsmithActionConstants/ActionConstants";
import {
BASE_WIDGET_VALIDATION,
WidgetPropertyValidationType,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import * as Sentry from "@sentry/react";
import withMeta, { WithMeta } from "./MetaHOC";
@ -45,6 +41,7 @@ class FormButtonWidget extends BaseWidget<
placeholderText: "Enter label text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "buttonStyle",
@ -86,6 +83,7 @@ class FormButtonWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
@ -95,6 +93,7 @@ class FormButtonWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "googleRecaptchaKey",
@ -104,6 +103,7 @@ class FormButtonWidget extends BaseWidget<
placeholderText: "Enter google recaptcha key",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
],
},
@ -130,16 +130,6 @@ class FormButtonWidget extends BaseWidget<
};
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
text: VALIDATION_TYPES.TEXT,
disabledWhenInvalid: VALIDATION_TYPES.BOOLEAN,
buttonStyle: VALIDATION_TYPES.TEXT,
buttonType: VALIDATION_TYPES.TEXT,
};
}
clickWithRecaptcha(token: string) {
if (this.props.onClick) {
this.setState({

View File

@ -6,6 +6,7 @@ import ContainerWidget, { ContainerWidgetProps } from "widgets/ContainerWidget";
import { ContainerComponentProps } from "components/designSystems/appsmith/ContainerComponent";
import * as Sentry from "@sentry/react";
import withMeta from "./MetaHOC";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
class FormWidget extends ContainerWidget {
static getPropertyPaneConfig() {
@ -21,6 +22,7 @@ class FormWidget extends ContainerWidget {
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Controls the visibility of the widget",
@ -30,6 +32,7 @@ class FormWidget extends ContainerWidget {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "shouldScrollContents",

View File

@ -2,10 +2,6 @@ import * as React from "react";
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType, RenderModes } from "constants/WidgetConstants";
import ImageComponent from "components/designSystems/appsmith/ImageComponent";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import * as Sentry from "@sentry/react";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
@ -28,6 +24,7 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
placeholderText: "Enter URL / Base64",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Renders the url or Base64 when no image is provided",
@ -37,6 +34,7 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
placeholderText: "Enter URL / Base64",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Controls the visibility of the widget",
@ -46,6 +44,7 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Controls the max zoom of the widget",
@ -77,6 +76,7 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.NUMBER,
},
],
},
@ -97,15 +97,6 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
image: VALIDATION_TYPES.TEXT,
imageShape: VALIDATION_TYPES.TEXT,
defaultImage: VALIDATION_TYPES.TEXT,
maxZoomLevel: VALIDATION_TYPES.NUMBER,
};
}
getPageView() {
const { maxZoomLevel } = this.props;
return (

View File

@ -8,10 +8,6 @@ import {
EventType,
ExecutionResult,
} from "constants/AppsmithActionConstants/ActionConstants";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { createMessage, FIELD_REQUIRED_ERROR } from "constants/messages";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
@ -65,6 +61,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
placeholderText: "Enter default text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Sets a placeholder text for the input",
@ -74,6 +71,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
placeholderText: "Enter placeholder text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText:
@ -85,6 +83,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
inputType: "TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.REGEX,
},
{
helpText:
@ -96,6 +95,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
inputType: "TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "isRequired",
@ -105,6 +105,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Controls the visibility of the widget",
@ -114,6 +115,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Disables input to this widget",
@ -123,6 +125,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Clears the input value after submit",
@ -132,6 +135,7 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -161,29 +165,6 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
inputType: VALIDATION_TYPES.TEXT,
defaultText: VALIDATION_TYPES.TEXT,
isDisabled: VALIDATION_TYPES.BOOLEAN,
text: VALIDATION_TYPES.TEXT,
regex: VALIDATION_TYPES.REGEX,
errorMessage: VALIDATION_TYPES.TEXT,
placeholderText: VALIDATION_TYPES.TEXT,
maxChars: VALIDATION_TYPES.NUMBER,
minNum: VALIDATION_TYPES.NUMBER,
maxNum: VALIDATION_TYPES.NUMBER,
label: VALIDATION_TYPES.TEXT,
inputValidators: VALIDATION_TYPES.ARRAY,
focusIndex: VALIDATION_TYPES.NUMBER,
isAutoFocusEnabled: VALIDATION_TYPES.BOOLEAN,
// onTextChanged: VALIDATION_TYPES.ACTION_SELECTOR,
isRequired: VALIDATION_TYPES.BOOLEAN,
isValid: VALIDATION_TYPES.BOOLEAN,
resetOnSubmit: VALIDATION_TYPES.BOOLEAN,
};
}
static getDerivedPropertiesMap(): DerivedPropertiesMap {
return {

View File

@ -2,7 +2,6 @@ import React from "react";
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import MapComponent from "components/designSystems/appsmith/MapComponent";
import { WidgetPropertyValidationType } from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import { getAppsmithConfigs } from "configs";
@ -52,6 +51,7 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
controlType: "LOCATION_SEARCH",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.LAT_LONG,
},
{
propertyName: "defaultMarkers",
@ -62,6 +62,7 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
placeholderText: 'Enter [{ "lat": "val1", "long": "val2" }]',
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.MARKERS,
},
{
propertyName: "enableSearch",
@ -104,6 +105,7 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -130,19 +132,6 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
defaultMarkers: VALIDATION_TYPES.MARKERS,
isDisabled: VALIDATION_TYPES.BOOLEAN,
isVisible: VALIDATION_TYPES.BOOLEAN,
enableSearch: VALIDATION_TYPES.BOOLEAN,
enablePickLocation: VALIDATION_TYPES.BOOLEAN,
enableCreateMarker: VALIDATION_TYPES.BOOLEAN,
allowZoom: VALIDATION_TYPES.BOOLEAN,
zoomLevel: VALIDATION_TYPES.NUMBER,
mapCenter: VALIDATION_TYPES.LAT_LONG,
};
}
static getDefaultPropertiesMap(): Record<string, string> {
return {

View File

@ -3,10 +3,6 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import RadioGroupComponent from "components/designSystems/blueprint/RadioGroupComponent";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import * as Sentry from "@sentry/react";
import withMeta, { WithMeta } from "./MetaHOC";
@ -26,6 +22,7 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.OPTIONS_DATA,
},
{
helpText: "Selects a value of the options entered by default",
@ -35,6 +32,7 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "isRequired",
@ -44,6 +42,7 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Controls the visibility of the widget",
@ -53,6 +52,7 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -62,6 +62,7 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -82,17 +83,6 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
label: VALIDATION_TYPES.TEXT,
options: VALIDATION_TYPES.OPTIONS_DATA,
selectedOptionValue: VALIDATION_TYPES.TEXT,
defaultOptionValue: VALIDATION_TYPES.TEXT,
isRequired: VALIDATION_TYPES.BOOLEAN,
// onSelectionChange: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDerivedPropertiesMap() {
return {
selectedOption:

View File

@ -2,7 +2,6 @@ import React, { lazy, Suspense } from "react";
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import { WidgetPropertyValidationType } from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import Skeleton from "components/utils/Skeleton";
@ -60,6 +59,7 @@ class RichTextEditorWidget extends BaseWidget<
placeholderText: "Enter HTML",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "isVisible",
@ -69,6 +69,7 @@ class RichTextEditorWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -78,6 +79,7 @@ class RichTextEditorWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -97,14 +99,6 @@ class RichTextEditorWidget extends BaseWidget<
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
placeholder: VALIDATION_TYPES.TEXT,
defaultText: VALIDATION_TYPES.TEXT,
isDisabled: VALIDATION_TYPES.BOOLEAN,
isVisible: VALIDATION_TYPES.BOOLEAN,
};
}
static getMetaPropertiesMap(): Record<string, any> {
return {

View File

@ -3,10 +3,6 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import * as Sentry from "@sentry/react";
import withMeta, { WithMeta } from "./MetaHOC";
import {
BASE_WIDGET_VALIDATION,
WidgetPropertyValidationType,
} from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { SwitchComponent } from "components/designSystems/blueprint/SwitchComponent";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
@ -26,6 +22,7 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
placeholderText: "Enter label text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "alignWidget",
@ -54,6 +51,7 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isVisible",
@ -63,6 +61,7 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "isDisabled",
@ -72,6 +71,7 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -110,14 +110,6 @@ class SwitchWidget extends BaseWidget<SwitchWidgetProps, WidgetState> {
return "SWITCH_WIDGET";
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
label: VALIDATION_TYPES.TEXT,
defaultSwitchState: VALIDATION_TYPES.BOOLEAN,
};
}
static getDefaultPropertiesMap(): Record<string, string> {
return {
isSwitchedOn: "defaultSwitchState",

View File

@ -2,6 +2,7 @@ import { get } from "lodash";
import { Colors } from "constants/Colors";
import { ColumnProperties } from "components/designSystems/appsmith/TableComponent/Constants";
import { TableWidgetProps } from "./TableWidgetConstants";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
// A hook to update all column styles when global table styles are updated
const updateColumnStyles = (
@ -142,6 +143,7 @@ export default [
inputType: "ARRAY",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TABLE_DATA,
},
{
helpText: "Columns",
@ -637,6 +639,7 @@ export default [
placeholderText: "Enter default search text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
helpText: "Selects the default selected row",
@ -646,6 +649,7 @@ export default [
placeholderText: "Enter row index",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.DEFAULT_SELECTED_ROW,
},
{
helpText:
@ -664,6 +668,7 @@ export default [
controlType: "SWITCH",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
propertyName: "multiRowSelection",

View File

@ -10,11 +10,6 @@ import {
renderActions,
} from "components/designSystems/appsmith/TableComponent/TableUtilities";
import { getAllTableColumnKeys } from "components/designSystems/appsmith/TableComponent/TableHelpers";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import {
BASE_WIDGET_VALIDATION,
WidgetPropertyValidationType,
} from "utils/WidgetValidation";
import Skeleton from "components/utils/Skeleton";
import moment from "moment";
import { isNumber, isString, isNil, isEqual, xor, without } from "lodash";
@ -45,22 +40,6 @@ const ReactTableComponent = lazy(() =>
);
class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
tableData: VALIDATION_TYPES.TABLE_DATA,
nextPageKey: VALIDATION_TYPES.TEXT,
prevPageKey: VALIDATION_TYPES.TEXT,
label: VALIDATION_TYPES.TEXT,
searchText: VALIDATION_TYPES.TEXT,
defaultSearchText: VALIDATION_TYPES.TEXT,
defaultSelectedRow: VALIDATION_TYPES.DEFAULT_SELECTED_ROW,
pageSize: VALIDATION_TYPES.NUMBER,
selectedRowIndices: VALIDATION_TYPES.ROW_INDICES,
pageNo: VALIDATION_TYPES.TABLE_PAGE_NO,
};
}
static getPropertyPaneConfig() {
return tablePropertyPaneConfig;
}

View File

@ -3,7 +3,6 @@ import TabsComponent from "components/designSystems/appsmith/TabsComponent";
import { WidgetType, WidgetTypes } from "constants/WidgetConstants";
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import WidgetFactory from "utils/WidgetFactory";
import { WidgetPropertyValidationType } from "utils/WidgetValidation";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import _ from "lodash";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
@ -29,6 +28,7 @@ class TabsWidget extends BaseWidget<
controlType: "TABS_INPUT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TABS_DATA,
},
{
propertyName: "defaultTab",
@ -38,6 +38,7 @@ class TabsWidget extends BaseWidget<
controlType: "INPUT_TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.SELECTED_TAB,
},
{
propertyName: "shouldShowTabs",
@ -63,6 +64,7 @@ class TabsWidget extends BaseWidget<
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -82,12 +84,6 @@ class TabsWidget extends BaseWidget<
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
tabs: VALIDATION_TYPES.TABS_DATA,
defaultTab: VALIDATION_TYPES.SELECTED_TAB,
};
}
onTabChange = (tabWidgetId: string) => {
this.props.updateWidgetMetaProperty("selectedTabWidgetId", tabWidgetId, {

View File

@ -3,10 +3,6 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType, TextSize } from "constants/WidgetConstants";
import TextComponent from "components/designSystems/blueprint/TextComponent";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import { DerivedPropertiesMap } from "utils/WidgetFactory";
import * as Sentry from "@sentry/react";
@ -24,6 +20,7 @@ class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
placeholderText: "Enter text",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "shouldScroll",
@ -41,6 +38,7 @@ class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -143,14 +141,6 @@ class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
},
];
}
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
text: VALIDATION_TYPES.TEXT,
textStyle: VALIDATION_TYPES.TEXT,
shouldScroll: VALIDATION_TYPES.BOOLEAN,
};
}
getPageView() {
return (

View File

@ -3,10 +3,6 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
import {
WidgetPropertyValidationType,
BASE_WIDGET_VALIDATION,
} from "utils/WidgetValidation";
import Skeleton from "components/utils/Skeleton";
import * as Sentry from "@sentry/react";
import { retryPromise } from "utils/AppsmithUtils";
@ -40,6 +36,7 @@ class VideoWidget extends BaseWidget<VideoWidgetProps, WidgetState> {
inputType: "TEXT",
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.TEXT,
},
{
propertyName: "autoPlay",
@ -49,6 +46,7 @@ class VideoWidget extends BaseWidget<VideoWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
{
helpText: "Controls the visibility of the widget",
@ -58,6 +56,7 @@ class VideoWidget extends BaseWidget<VideoWidgetProps, WidgetState> {
isJSConvertible: true,
isBindProperty: true,
isTriggerProperty: false,
validation: VALIDATION_TYPES.BOOLEAN,
},
],
},
@ -96,12 +95,6 @@ class VideoWidget extends BaseWidget<VideoWidgetProps, WidgetState> {
];
}
private _player = React.createRef<ReactPlayer>();
static getPropertyValidationMap(): WidgetPropertyValidationType {
return {
...BASE_WIDGET_VALIDATION,
url: VALIDATION_TYPES.TEXT,
};
}
static getMetaPropertiesMap(): Record<string, any> {
return {

View File

@ -24,6 +24,7 @@ import {
CrashingError,
DataTreeDiffEvent,
getAllPaths,
getEntityNameAndPropertyPath,
getImmediateParentsOfPropertyPaths,
getValidatedTree,
makeParentsDependOnChildren,
@ -86,7 +87,7 @@ export default class DataTreeEvaluator {
const evaluateEnd = performance.now();
// Validate Widgets
const validateStart = performance.now();
this.evalTree = getValidatedTree(this.widgetConfigMap, evaluatedTree);
this.evalTree = getValidatedTree(evaluatedTree);
const validateEnd = performance.now();
this.oldUnEvalTree = unEvalTree;
@ -350,24 +351,25 @@ export default class DataTreeEvaluator {
const tree = _.cloneDeep(oldUnevalTree);
try {
return sortedDependencies.reduce(
(currentTree: DataTree, propertyPath: string) => {
this.logs.push(`evaluating ${propertyPath}`);
const entityName = propertyPath.split(".")[0];
(currentTree: DataTree, fullPropertyPath: string) => {
this.logs.push(`evaluating ${fullPropertyPath}`);
const { entityName, propertyPath } = getEntityNameAndPropertyPath(
fullPropertyPath,
);
const entity: DataTreeEntity = currentTree[entityName];
const unEvalPropertyValue = _.get(currentTree as any, propertyPath);
const unEvalPropertyValue = _.get(
currentTree as any,
fullPropertyPath,
);
const isABindingPath =
(isAction(entity) || isWidget(entity)) &&
isPathADynamicBinding(
entity,
propertyPath.substring(propertyPath.indexOf(".") + 1),
);
isPathADynamicBinding(entity, propertyPath);
let evalPropertyValue;
const requiresEval =
isABindingPath && isDynamicValue(unEvalPropertyValue);
if (requiresEval) {
try {
evalPropertyValue = this.evaluateDynamicProperty(
propertyPath,
currentTree,
unEvalPropertyValue,
);
@ -376,7 +378,7 @@ export default class DataTreeEvaluator {
type: EvalErrorTypes.EVAL_PROPERTY_ERROR,
message: e.message,
context: {
propertyPath,
propertyPath: fullPropertyPath,
},
});
evalPropertyValue = undefined;
@ -386,42 +388,37 @@ export default class DataTreeEvaluator {
}
if (isWidget(entity)) {
const widgetEntity = entity;
// TODO fix for nested properties
// For nested properties like Table1.selectedRow.email
// The following line will calculated the property name to be selectedRow
// instead of selectedRow.email
const propertyName = propertyPath.split(".")[1];
const defaultPropertyMap = this.widgetConfigMap[widgetEntity.type]
.defaultProperties;
const isDefaultProperty = !!Object.values(
defaultPropertyMap,
).filter(
(defaultPropertyName) => propertyName === defaultPropertyName,
(defaultPropertyName) => propertyPath === defaultPropertyName,
).length;
if (propertyName) {
if (propertyPath) {
let parsedValue = this.validateAndParseWidgetProperty(
propertyPath,
fullPropertyPath,
widgetEntity,
currentTree,
evalPropertyValue,
unEvalPropertyValue,
isDefaultProperty,
);
const hasDefaultProperty = propertyName in defaultPropertyMap;
const hasDefaultProperty = propertyPath in defaultPropertyMap;
if (hasDefaultProperty) {
const defaultProperty = defaultPropertyMap[propertyName];
const defaultProperty = defaultPropertyMap[propertyPath];
parsedValue = this.overwriteDefaultDependentProps(
defaultProperty,
parsedValue,
propertyPath,
fullPropertyPath,
widgetEntity,
);
}
return _.set(currentTree, propertyPath, parsedValue);
return _.set(currentTree, fullPropertyPath, parsedValue);
}
return _.set(currentTree, propertyPath, evalPropertyValue);
return _.set(currentTree, fullPropertyPath, evalPropertyValue);
} else {
return _.set(currentTree, propertyPath, evalPropertyValue);
return _.set(currentTree, fullPropertyPath, evalPropertyValue);
}
},
tree,
@ -573,7 +570,6 @@ export default class DataTreeEvaluator {
}
evaluateDynamicProperty(
propertyPath: string,
currentTree: DataTree,
unEvalPropertyValue: any,
): any {
@ -581,14 +577,14 @@ export default class DataTreeEvaluator {
}
validateAndParseWidgetProperty(
propertyPath: string,
fullPropertyPath: string,
widget: DataTreeWidget,
currentTree: DataTree,
evalPropertyValue: any,
unEvalPropertyValue: string,
isDefaultProperty: boolean,
): any {
const entityPropertyName = _.drop(propertyPath.split(".")).join(".");
const { propertyPath } = getEntityNameAndPropertyPath(fullPropertyPath);
let valueToValidate = evalPropertyValue;
if (isPathADynamicTrigger(widget, propertyPath)) {
const { triggers } = this.getDynamicValue(
@ -599,12 +595,12 @@ export default class DataTreeEvaluator {
);
valueToValidate = triggers;
}
const validation = widget.validationPaths[propertyPath];
const { parsed, isValid, message, transformed } = validateWidgetProperty(
this.widgetConfigMap,
widget.type,
entityPropertyName,
propertyPath,
valueToValidate,
widget,
validation,
currentTree,
);
const evaluatedValue = isValid
@ -613,23 +609,23 @@ export default class DataTreeEvaluator {
? evalPropertyValue
: transformed;
const safeEvaluatedValue = removeFunctions(evaluatedValue);
_.set(widget, `evaluatedValues.${entityPropertyName}`, safeEvaluatedValue);
_.set(widget, `evaluatedValues.${propertyPath}`, safeEvaluatedValue);
if (!isValid) {
_.set(widget, `invalidProps.${entityPropertyName}`, true);
_.set(widget, `validationMessages.${entityPropertyName}`, message);
_.set(widget, `invalidProps.${propertyPath}`, true);
_.set(widget, `validationMessages.${propertyPath}`, message);
} else {
_.set(widget, `invalidProps.${entityPropertyName}`, false);
_.set(widget, `validationMessages.${entityPropertyName}`, "");
_.set(widget, `invalidProps.${propertyPath}`, false);
_.set(widget, `validationMessages.${propertyPath}`, "");
}
if (isPathADynamicTrigger(widget, entityPropertyName)) {
if (isPathADynamicTrigger(widget, propertyPath)) {
return unEvalPropertyValue;
} else {
const parsedCache = this.getParsedValueCache(propertyPath);
const parsedCache = this.getParsedValueCache(fullPropertyPath);
// In case this is a default property, always set the cache even if the value remains the same so that the version
// in cache gets updated and the property dependent on default property updates accordingly.
if (!equal(parsedCache.value, parsed) || isDefaultProperty) {
this.parsedValueCache.set(propertyPath, {
this.parsedValueCache.set(fullPropertyPath, {
value: parsed,
version: Date.now(),
});

View File

@ -24,6 +24,7 @@ describe("evaluate", () => {
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
bindingPaths: {},
triggerPaths: {},
validationPaths: {},
};
const dataTree: DataTree = {
Input1: widget,

View File

@ -7,27 +7,15 @@ import { WidgetTypeConfigMap } from "../utils/WidgetFactory";
import { RenderModes, WidgetTypes } from "../constants/WidgetConstants";
import { PluginType } from "../entities/Action";
import DataTreeEvaluator from "workers/DataTreeEvaluator";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
CONTAINER_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
TEXT_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
text: "TEXT",
textStyle: "TEXT",
shouldScroll: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {
value: "{{ this.text }}",
@ -35,38 +23,11 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
BUTTON_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
text: "TEXT",
buttonStyle: "TEXT",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
INPUT_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
inputType: "TEXT",
defaultText: "TEXT",
text: "TEXT",
regex: "REGEX",
errorMessage: "TEXT",
placeholderText: "TEXT",
maxChars: "NUMBER",
minNum: "NUMBER",
maxNum: "NUMBER",
label: "TEXT",
inputValidators: "ARRAY",
focusIndex: "NUMBER",
isAutoFocusEnabled: "BOOLEAN",
isRequired: "BOOLEAN",
isValid: "BOOLEAN",
},
defaultProperties: {
text: "defaultText",
},
@ -81,13 +42,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
},
},
CHECKBOX_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
label: "TEXT",
defaultCheckedState: "BOOLEAN",
},
defaultProperties: {
isChecked: "defaultCheckedState",
},
@ -97,18 +51,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
DROP_DOWN_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
placeholderText: "TEXT",
label: "TEXT",
options: "OPTIONS_DATA",
selectionType: "TEXT",
isRequired: "BOOLEAN",
selectedOptionValues: "ARRAY",
defaultOptionValue: "DEFAULT_OPTION_VALUE",
},
defaultProperties: {
selectedOptionValue: "defaultOptionValue",
selectedOptionValueArr: "defaultOptionValue",
@ -131,16 +73,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
RADIO_GROUP_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
label: "TEXT",
options: "OPTIONS_DATA",
selectedOptionValue: "TEXT",
defaultOptionValue: "TEXT",
isRequired: "BOOLEAN",
},
defaultProperties: {
selectedOptionValue: "defaultOptionValue",
},
@ -153,32 +85,11 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
IMAGE_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
image: "TEXT",
imageShape: "TEXT",
defaultImage: "TEXT",
maxZoomLevel: "NUMBER",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
TABLE_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
tableData: "TABLE_DATA",
nextPageKey: "TEXT",
prevPageKey: "TEXT",
label: "TEXT",
searchText: "TEXT",
defaultSearchText: "TEXT",
defaultSelectedRow: "DEFAULT_SELECTED_ROW",
},
defaultProperties: {
searchText: "defaultSearchText",
selectedRowIndex: "defaultSelectedRow",
@ -195,12 +106,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
},
},
VIDEO_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
url: "TEXT",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {
@ -208,16 +113,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
},
},
FILE_PICKER_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
label: "TEXT",
maxNumFiles: "NUMBER",
allowedFileTypes: "ARRAY",
files: "ARRAY",
isRequired: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {
isValid: "{{ this.isRequired ? this.files.length > 0 : true }}",
@ -229,20 +124,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
},
},
DATE_PICKER_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
defaultDate: "DATE",
timezone: "TEXT",
enableTimePicker: "BOOLEAN",
dateFormat: "TEXT",
label: "TEXT",
datePickerType: "TEXT",
maxDate: "DATE",
minDate: "DATE",
isRequired: "BOOLEAN",
},
defaultProperties: {
selectedDate: "defaultDate",
},
@ -253,20 +134,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
DATE_PICKER_WIDGET2: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
defaultDate: "DATE",
timezone: "TEXT",
enableTimePicker: "BOOLEAN",
dateFormat: "TEXT",
label: "TEXT",
datePickerType: "TEXT",
maxDate: "DATE",
minDate: "DATE",
isRequired: "BOOLEAN",
},
defaultProperties: {
selectedDate: "defaultDate",
},
@ -277,10 +144,6 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
TABS_WIDGET: {
validations: {
tabs: "TABS_DATA",
defaultTab: "SELECTED_TAB",
},
defaultProperties: {},
derivedProperties: {
selectedTab:
@ -289,23 +152,11 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
MODAL_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
RICH_TEXT_EDITOR_WIDGET: {
validations: {
text: "TEXT",
placeholder: "TEXT",
defaultValue: "TEXT",
isDisabled: "BOOLEAN",
isVisible: "BOOLEAN",
},
defaultProperties: {
text: "defaultText",
},
@ -315,52 +166,21 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
CHART_WIDGET: {
validations: {
xAxisName: "TEXT",
yAxisName: "TEXT",
chartName: "TEXT",
isVisible: "BOOLEAN",
chartData: "CHART_DATA",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
FORM_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
FORM_BUTTON_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
text: "TEXT",
disabledWhenInvalid: "BOOLEAN",
buttonStyle: "TEXT",
buttonType: "TEXT",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
MAP_WIDGET: {
validations: {
defaultMarkers: "MARKERS",
isDisabled: "BOOLEAN",
isVisible: "BOOLEAN",
enableSearch: "BOOLEAN",
enablePickLocation: "BOOLEAN",
allowZoom: "BOOLEAN",
zoomLevel: "NUMBER",
mapCenter: "OBJECT",
},
defaultProperties: {
markers: "defaultMarkers",
center: "mapCenter",
@ -369,31 +189,16 @@ const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
metaProperties: {},
},
CANVAS_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
ICON_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
},
SKELETON_WIDGET: {
validations: {
isLoading: "BOOLEAN",
isVisible: "BOOLEAN",
isDisabled: "BOOLEAN",
},
defaultProperties: {},
derivedProperties: {},
metaProperties: {},
@ -416,6 +221,7 @@ const BASE_WIDGET: DataTreeWidget = {
version: 1,
bindingPaths: {},
triggerPaths: {},
validationPaths: {},
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
};
@ -457,6 +263,9 @@ describe("DataTreeEvaluator", () => {
bindingPaths: {
text: true,
},
validationPaths: {
text: VALIDATION_TYPES.TEXT,
},
},
Text3: {
...BASE_WIDGET,
@ -467,6 +276,9 @@ describe("DataTreeEvaluator", () => {
bindingPaths: {
text: true,
},
validationPaths: {
text: VALIDATION_TYPES.TEXT,
},
},
Dropdown1: {
...BASE_WIDGET,
@ -506,6 +318,9 @@ describe("DataTreeEvaluator", () => {
selectedRow: true,
selectedRows: true,
},
validationPaths: {
tableData: VALIDATION_TYPES.TABLE_DATA,
},
},
Text4: {
...BASE_WIDGET,
@ -515,6 +330,9 @@ describe("DataTreeEvaluator", () => {
bindingPaths: {
text: true,
},
validationPaths: {
text: VALIDATION_TYPES.TEXT,
},
},
};
const evaluator = new DataTreeEvaluator(WIDGET_CONFIG_MAP);

View File

@ -73,7 +73,7 @@ ctx.addEventListener(
});
console.error(e);
}
dataTree = getValidatedTree(widgetTypeConfigMap, unevalTree);
dataTree = getValidatedTree(unevalTree);
dataTreeEvaluator = undefined;
}
return {
@ -148,21 +148,9 @@ ctx.addEventListener(
return true;
}
case EVAL_WORKER_ACTIONS.VALIDATE_PROPERTY: {
const {
widgetType,
widgetTypeConfigMap,
property,
value,
props,
} = requestData;
const { property, value, props, validation } = requestData;
return removeFunctions(
validateWidgetProperty(
widgetTypeConfigMap,
widgetType,
property,
value,
props,
),
validateWidgetProperty(property, value, props, validation),
);
}
default: {

View File

@ -3,9 +3,7 @@ import {
isChildPropertyPath,
isDynamicValue,
} from "utils/DynamicBindingUtils";
import { WidgetType } from "constants/WidgetConstants";
import { WidgetProps } from "widgets/BaseWidget";
import { WidgetTypeConfigMap } from "utils/WidgetFactory";
import { VALIDATORS } from "./validations";
import { Diff } from "deep-diff";
import {
@ -16,6 +14,7 @@ import {
ENTITY_TYPE,
} from "entities/DataTree/dataTreeFactory";
import _ from "lodash";
import { VALIDATION_TYPES } from "constants/WidgetValidation";
// Dropdown1.options[1].value -> Dropdown1.options[1]
// Dropdown1.options[1] -> Dropdown1.options
@ -61,6 +60,16 @@ function isInt(val: string | number): boolean {
return !isNaN(parseInt(val));
}
// Removes the entity name from the property path
export function getEntityNameAndPropertyPath(
fullPath: string,
): { entityName: string; propertyPath: string } {
const indexOfFirstDot = fullPath.indexOf(".");
const entityName = fullPath.substring(0, indexOfFirstDot);
const propertyPath = fullPath.substring(fullPath.indexOf(".") + 1);
return { entityName, propertyPath };
}
export const translateDiffEventToDataTreeDiffEvent = (
difference: Diff<any, any>,
): DataTreeDiff => {
@ -244,73 +253,53 @@ export const getImmediateParentsOfPropertyPaths = (
};
export function validateWidgetProperty(
widgetConfigMap: WidgetTypeConfigMap,
widgetType: WidgetType,
property: string,
value: any,
props: WidgetProps,
validation?: VALIDATION_TYPES,
dataTree?: DataTree,
) {
const propertyValidationTypes = widgetConfigMap[widgetType].validations;
const validationTypeOrValidator = propertyValidationTypes[property];
let validator;
if (typeof validationTypeOrValidator === "function") {
validator = validationTypeOrValidator;
} else {
validator = VALIDATORS[validationTypeOrValidator];
}
if (validator) {
return validator(value, props, dataTree);
} else {
if (!validation) {
return { isValid: true, parsed: value };
}
const validator = VALIDATORS[validation];
if (!validator) {
return { isValid: true, parsed: value };
}
return validator(value, props, dataTree);
}
export function getValidatedTree(
widgetConfigMap: WidgetTypeConfigMap,
tree: DataTree,
) {
export function getValidatedTree(tree: DataTree) {
return Object.keys(tree).reduce((tree, entityKey: string) => {
const entity = tree[entityKey] as DataTreeWidget;
if (!isWidget(entity)) {
return tree;
}
const parsedEntity = { ...entity };
Object.keys(entity).forEach((property: string) => {
const validationProperties = widgetConfigMap[entity.type].validations;
if (property in validationProperties) {
const value = _.get(entity, property);
// Pass it through parse
const {
parsed,
isValid,
message,
transformed,
} = validateWidgetProperty(
widgetConfigMap,
entity.type,
property,
value,
entity,
tree,
);
parsedEntity[property] = parsed;
const evaluatedValue = isValid
? parsed
: _.isUndefined(transformed)
? value
: transformed;
const safeEvaluatedValue = removeFunctions(evaluatedValue);
_.set(parsedEntity, `evaluatedValues.${property}`, safeEvaluatedValue);
if (!isValid) {
_.set(parsedEntity, `invalidProps.${property}`, true);
_.set(parsedEntity, `validationMessages.${property}`, message);
} else {
_.set(parsedEntity, `invalidProps.${property}`, false);
_.set(parsedEntity, `validationMessages.${property}`, "");
}
Object.entries(entity.validationPaths).forEach(([property, validation]) => {
const value = _.get(entity, property);
// Pass it through parse
const { parsed, isValid, message, transformed } = validateWidgetProperty(
property,
value,
entity,
validation,
tree,
);
_.set(parsedEntity, property, parsed);
const evaluatedValue = isValid
? parsed
: _.isUndefined(transformed)
? value
: transformed;
const safeEvaluatedValue = removeFunctions(evaluatedValue);
_.set(parsedEntity, `evaluatedValues.${property}`, safeEvaluatedValue);
if (!isValid) {
_.set(parsedEntity, `invalidProps.${property}`, true);
_.set(parsedEntity, `validationMessages.${property}`, message);
} else {
_.set(parsedEntity, `invalidProps.${property}`, false);
_.set(parsedEntity, `validationMessages.${property}`, "");
}
});
return { ...tree, [entityKey]: parsedEntity };

View File

@ -2,7 +2,6 @@ import {
ISO_DATE_FORMAT,
VALIDATION_TYPES,
ValidationResponse,
ValidationType,
Validator,
} from "../constants/WidgetValidation";
import { DataTree } from "../entities/DataTree/dataTreeFactory";
@ -48,7 +47,7 @@ export function validateDateString(
const WIDGET_TYPE_VALIDATION_ERROR = "Value does not match type"; // TODO: Lot's of changes in validations.ts file
export const VALIDATORS: Record<ValidationType, Validator> = {
export const VALIDATORS: Record<VALIDATION_TYPES, Validator> = {
[VALIDATION_TYPES.TEXT]: (value: any): ValidationResponse => {
let parsed = value;
if (isUndefined(value) || value === null) {