Merge branch 'feature/widget-property-parsing' into 'release'
Validation parse widget property Closes: #298 * Added functionality in validators to provide a parsed value to be used by widgets * Added validation to (almost) all properties of the widgets See merge request theappsmith/internal-tools-client!160
This commit is contained in:
commit
a55ff37ebd
|
|
@ -44,6 +44,7 @@
|
||||||
"jsonpath-plus": "^1.0.0",
|
"jsonpath-plus": "^1.0.0",
|
||||||
"lint-staged": "^9.2.5",
|
"lint-staged": "^9.2.5",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.27",
|
"moment-timezone": "^0.5.27",
|
||||||
"monaco-editor": "^0.15.1",
|
"monaco-editor": "^0.15.1",
|
||||||
"monaco-editor-webpack-plugin": "^1.7.0",
|
"monaco-editor-webpack-plugin": "^1.7.0",
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,7 @@ class InputTextControl extends BaseControl<InputControlProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
onTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
let value: string | number = event.target.value;
|
const value: string = event.target.value;
|
||||||
if (this.isNumberType()) {
|
|
||||||
value = _.toNumber(value);
|
|
||||||
}
|
|
||||||
this.updateProperty(this.props.propertyName, value);
|
this.updateProperty(this.props.propertyName, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,18 @@
|
||||||
|
// Always add a validator function in ./Validators for these types
|
||||||
export const VALIDATION_TYPES = {
|
export const VALIDATION_TYPES = {
|
||||||
TEXT: "TEXT",
|
TEXT: "TEXT",
|
||||||
NUMBER: "NUMBER",
|
NUMBER: "NUMBER",
|
||||||
BOOLEAN: "BOOLEAN",
|
BOOLEAN: "BOOLEAN",
|
||||||
OBJECT: "OBJECT",
|
OBJECT: "OBJECT",
|
||||||
|
ARRAY: "ARRAY",
|
||||||
TABLE_DATA: "TABLE_DATA",
|
TABLE_DATA: "TABLE_DATA",
|
||||||
|
DATE: "DATE",
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ValidationResponse = {
|
||||||
|
isValid: boolean;
|
||||||
|
parsed: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ValidationType = (typeof VALIDATION_TYPES)[keyof typeof VALIDATION_TYPES];
|
export type ValidationType = (typeof VALIDATION_TYPES)[keyof typeof VALIDATION_TYPES];
|
||||||
export type Validator = (value: any) => boolean;
|
export type Validator = (value: any) => ValidationResponse;
|
||||||
|
|
|
||||||
|
|
@ -124,5 +124,8 @@ const mapDispatchToProps = (dispatch: any) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withRouter(
|
export default withRouter(
|
||||||
connect(mapStateToProps, mapDispatchToProps)(Applications),
|
connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
)(Applications),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ export const getDynamicValue = (
|
||||||
export const enhanceWithDynamicValuesAndValidations = (
|
export const enhanceWithDynamicValuesAndValidations = (
|
||||||
widget: WidgetProps,
|
widget: WidgetProps,
|
||||||
entities: DataTree,
|
entities: DataTree,
|
||||||
safeValues: boolean,
|
replaceWithParsed: boolean,
|
||||||
): WidgetProps => {
|
): WidgetProps => {
|
||||||
if (!widget) return widget;
|
if (!widget) return widget;
|
||||||
const properties = { ...widget };
|
const properties = { ...widget };
|
||||||
|
|
@ -86,19 +86,19 @@ export const enhanceWithDynamicValuesAndValidations = (
|
||||||
Object.keys(widget).forEach((property: string) => {
|
Object.keys(widget).forEach((property: string) => {
|
||||||
let value = widget[property];
|
let value = widget[property];
|
||||||
// Check for dynamic bindings
|
// Check for dynamic bindings
|
||||||
if (isDynamicValue(value)) {
|
if (widget.dynamicBindings && property in widget.dynamicBindings) {
|
||||||
value = getDynamicValue(value, entities);
|
value = getDynamicValue(value, entities);
|
||||||
}
|
}
|
||||||
const isValid = ValidationFactory.validateWidgetProperty(
|
// Pass it through validation and parse
|
||||||
|
const { isValid, parsed } = ValidationFactory.validateWidgetProperty(
|
||||||
widget.type,
|
widget.type,
|
||||||
property,
|
property,
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
if (!isValid) {
|
// Store all invalid props
|
||||||
if (safeValues) value = undefined;
|
if (!isValid) invalidProps[property] = true;
|
||||||
invalidProps[property] = true;
|
// Replace if flag is turned on
|
||||||
}
|
if (replaceWithParsed) properties[property] = parsed;
|
||||||
if (safeValues) properties[property] = value;
|
|
||||||
});
|
});
|
||||||
return { ...properties, invalidProps };
|
return { ...properties, invalidProps };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import { WidgetType } from "constants/WidgetConstants";
|
import { WidgetType } from "constants/WidgetConstants";
|
||||||
import WidgetFactory from "./WidgetFactory";
|
import WidgetFactory from "./WidgetFactory";
|
||||||
import { ValidationType, Validator } from "../constants/WidgetValidation";
|
import {
|
||||||
|
ValidationResponse,
|
||||||
|
ValidationType,
|
||||||
|
Validator,
|
||||||
|
} from "../constants/WidgetValidation";
|
||||||
|
|
||||||
// TODO: need to be strict about what the key can be
|
// TODO: need to be strict about what the key can be
|
||||||
export type WidgetPropertyValidationType = Record<string, ValidationType>;
|
export type WidgetPropertyValidationType = Record<string, ValidationType>;
|
||||||
|
|
@ -19,17 +23,17 @@ class ValidationFactory {
|
||||||
widgetType: WidgetType,
|
widgetType: WidgetType,
|
||||||
property: string,
|
property: string,
|
||||||
value: any,
|
value: any,
|
||||||
) {
|
): ValidationResponse {
|
||||||
let isValid = true;
|
|
||||||
const propertyValidationTypes = WidgetFactory.getWidgetPropertyValidationMap(
|
const propertyValidationTypes = WidgetFactory.getWidgetPropertyValidationMap(
|
||||||
widgetType,
|
widgetType,
|
||||||
);
|
);
|
||||||
const validationType = propertyValidationTypes[property];
|
const validationType = propertyValidationTypes[property];
|
||||||
const validator = this.validationMap.get(validationType);
|
const validator = this.validationMap.get(validationType);
|
||||||
if (validator) {
|
if (validator) {
|
||||||
isValid = validator(value);
|
return validator(value);
|
||||||
|
} else {
|
||||||
|
return { isValid: true, parsed: value };
|
||||||
}
|
}
|
||||||
return isValid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,9 @@ import { VALIDATORS } from "./Validators";
|
||||||
|
|
||||||
class ValidationRegistry {
|
class ValidationRegistry {
|
||||||
static registerInternalValidators() {
|
static registerInternalValidators() {
|
||||||
ValidationFactory.registerValidator(
|
Object.keys(VALIDATION_TYPES).forEach(type => {
|
||||||
VALIDATION_TYPES.TEXT,
|
ValidationFactory.registerValidator(type, VALIDATORS[type]);
|
||||||
VALIDATORS[VALIDATION_TYPES.TEXT],
|
});
|
||||||
);
|
|
||||||
|
|
||||||
ValidationFactory.registerValidator(
|
|
||||||
VALIDATION_TYPES.NUMBER,
|
|
||||||
VALIDATORS[VALIDATION_TYPES.NUMBER],
|
|
||||||
);
|
|
||||||
|
|
||||||
ValidationFactory.registerValidator(
|
|
||||||
VALIDATION_TYPES.BOOLEAN,
|
|
||||||
VALIDATORS[VALIDATION_TYPES.BOOLEAN],
|
|
||||||
);
|
|
||||||
|
|
||||||
ValidationFactory.registerValidator(
|
|
||||||
VALIDATION_TYPES.OBJECT,
|
|
||||||
VALIDATORS[VALIDATION_TYPES.OBJECT],
|
|
||||||
);
|
|
||||||
|
|
||||||
ValidationFactory.registerValidator(
|
|
||||||
VALIDATION_TYPES.TABLE_DATA,
|
|
||||||
VALIDATORS[VALIDATION_TYPES.TABLE_DATA],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,115 @@
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import {
|
import {
|
||||||
VALIDATION_TYPES,
|
VALIDATION_TYPES,
|
||||||
|
ValidationResponse,
|
||||||
ValidationType,
|
ValidationType,
|
||||||
Validator,
|
Validator,
|
||||||
} from "../constants/WidgetValidation";
|
} from "../constants/WidgetValidation";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
export const VALIDATORS: Record<ValidationType, Validator> = {
|
export const VALIDATORS: Record<ValidationType, Validator> = {
|
||||||
[VALIDATION_TYPES.TEXT]: (value: any) => _.isString(value),
|
[VALIDATION_TYPES.TEXT]: (value: any): ValidationResponse => {
|
||||||
[VALIDATION_TYPES.NUMBER]: (value: any) => _.isNumber(value),
|
let parsed = value;
|
||||||
[VALIDATION_TYPES.BOOLEAN]: (value: any) => _.isBoolean(value),
|
if (_.isUndefined(value) || _.isObject(value)) {
|
||||||
[VALIDATION_TYPES.OBJECT]: (value: any) => _.isObject(value),
|
return { isValid: false, parsed: "" };
|
||||||
[VALIDATION_TYPES.TABLE_DATA]: (value: any) => {
|
}
|
||||||
try {
|
let isValid = _.isString(value);
|
||||||
let data = value;
|
if (!isValid) {
|
||||||
if (_.isString(data)) {
|
try {
|
||||||
data = JSON.parse(data as string);
|
parsed = _.toString(value);
|
||||||
|
isValid = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error when parsing ${value} to string`);
|
||||||
|
console.error(e);
|
||||||
|
return { isValid: false, parsed: "" };
|
||||||
}
|
}
|
||||||
if (!Array.isArray(data)) return false;
|
}
|
||||||
return _.every(data, datum => _.isObject(datum));
|
return { isValid, parsed };
|
||||||
} catch {
|
},
|
||||||
return false;
|
[VALIDATION_TYPES.NUMBER]: (value: any): ValidationResponse => {
|
||||||
|
let parsed = value;
|
||||||
|
if (_.isUndefined(value)) {
|
||||||
|
return { isValid: false, parsed: 0 };
|
||||||
|
}
|
||||||
|
let isValid = _.isNumber(value);
|
||||||
|
if (!isValid) {
|
||||||
|
try {
|
||||||
|
parsed = _.toNumber(value);
|
||||||
|
isValid = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error when parsing ${value} to number`);
|
||||||
|
console.error(e);
|
||||||
|
return { isValid: false, parsed: 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { isValid, parsed };
|
||||||
|
},
|
||||||
|
[VALIDATION_TYPES.BOOLEAN]: (value: any): ValidationResponse => {
|
||||||
|
let parsed = value;
|
||||||
|
if (_.isUndefined(value)) {
|
||||||
|
return { isValid: false, parsed: false };
|
||||||
|
}
|
||||||
|
let isValid = _.isBoolean(value);
|
||||||
|
if (!isValid) {
|
||||||
|
try {
|
||||||
|
parsed = !!value;
|
||||||
|
isValid = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error when parsing ${value} to boolean`);
|
||||||
|
console.error(e);
|
||||||
|
return { isValid: false, parsed: false };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { isValid, parsed };
|
||||||
|
},
|
||||||
|
[VALIDATION_TYPES.OBJECT]: (value: any): ValidationResponse => {
|
||||||
|
let parsed = value;
|
||||||
|
if (_.isUndefined(value)) {
|
||||||
|
return { isValid: false, parsed: {} };
|
||||||
|
}
|
||||||
|
let isValid = _.isObject(value);
|
||||||
|
if (!isValid) {
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(value);
|
||||||
|
isValid = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error when parsing ${value} to object`);
|
||||||
|
console.error(e);
|
||||||
|
return { isValid: false, parsed: {} };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { isValid, parsed };
|
||||||
|
},
|
||||||
|
[VALIDATION_TYPES.ARRAY]: (value: any): ValidationResponse => {
|
||||||
|
let parsed = value;
|
||||||
|
try {
|
||||||
|
if (_.isUndefined(value)) {
|
||||||
|
return { isValid: false, parsed: [] };
|
||||||
|
}
|
||||||
|
if (_.isString(value)) {
|
||||||
|
parsed = JSON.parse(parsed as string);
|
||||||
|
}
|
||||||
|
if (!Array.isArray(parsed)) {
|
||||||
|
return { isValid: false, parsed: [] };
|
||||||
|
}
|
||||||
|
return { isValid: true, parsed };
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return { isValid: false, parsed: [] };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[VALIDATION_TYPES.TABLE_DATA]: (value: any): ValidationResponse => {
|
||||||
|
const { isValid, parsed } = VALIDATORS[VALIDATION_TYPES.ARRAY](value);
|
||||||
|
if (!isValid) {
|
||||||
|
return { isValid, parsed };
|
||||||
|
} else if (!_.every(parsed, datum => _.isObject(datum))) {
|
||||||
|
return { isValid: false, parsed: [] };
|
||||||
|
}
|
||||||
|
return { isValid, parsed };
|
||||||
|
},
|
||||||
|
[VALIDATION_TYPES.DATE]: (value: any): ValidationResponse => {
|
||||||
|
const isValid = moment(value).isValid();
|
||||||
|
const parsed = isValid ? moment(value).toDate() : new Date();
|
||||||
|
return { isValid, parsed };
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "../constants/WidgetConstants";
|
import { WidgetType } from "../constants/WidgetConstants";
|
||||||
import ButtonComponent from "../components/designSystems/blueprint/ButtonComponent";
|
import ButtonComponent from "../components/designSystems/blueprint/ButtonComponent";
|
||||||
import { ActionPayload } from "../constants/ActionConstants";
|
import { ActionPayload } from "../constants/ActionConstants";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class ButtonWidget extends BaseWidget<ButtonWidgetProps, WidgetState> {
|
class ButtonWidget extends BaseWidget<ButtonWidgetProps, WidgetState> {
|
||||||
onButtonClickBound: (event: React.MouseEvent<HTMLElement>) => void;
|
onButtonClickBound: (event: React.MouseEvent<HTMLElement>) => void;
|
||||||
|
|
@ -12,6 +14,15 @@ class ButtonWidget extends BaseWidget<ButtonWidgetProps, WidgetState> {
|
||||||
this.onButtonClickBound = this.onButtonClick.bind(this);
|
this.onButtonClickBound = this.onButtonClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
text: VALIDATION_TYPES.TEXT,
|
||||||
|
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
||||||
|
isVisible: VALIDATION_TYPES.BOOLEAN,
|
||||||
|
buttonStyle: VALIDATION_TYPES.TEXT,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
onButtonClick() {
|
onButtonClick() {
|
||||||
super.executeAction(this.props.onClick);
|
super.executeAction(this.props.onClick);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
|
||||||
return {
|
return {
|
||||||
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
||||||
label: VALIDATION_TYPES.TEXT,
|
label: VALIDATION_TYPES.TEXT,
|
||||||
|
defaultCheckedState: VALIDATION_TYPES.BOOLEAN,
|
||||||
|
isChecked: VALIDATION_TYPES.BOOLEAN,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,23 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "../constants/WidgetConstants";
|
import { WidgetType } from "../constants/WidgetConstants";
|
||||||
import { ActionPayload } from "../constants/ActionConstants";
|
import { ActionPayload } from "../constants/ActionConstants";
|
||||||
import DatePickerComponent from "../components/designSystems/blueprint/DatePickerComponent";
|
import DatePickerComponent from "../components/designSystems/blueprint/DatePickerComponent";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
defaultDate: VALIDATION_TYPES.DATE,
|
||||||
|
selectedDate: VALIDATION_TYPES.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,
|
||||||
|
minDate: VALIDATION_TYPES.DATE,
|
||||||
|
};
|
||||||
|
}
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<DatePickerComponent
|
<DatePickerComponent
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,20 @@ import { WidgetType } from "../constants/WidgetConstants";
|
||||||
import { ActionPayload } from "../constants/ActionConstants";
|
import { ActionPayload } from "../constants/ActionConstants";
|
||||||
import DropDownComponent from "../components/designSystems/blueprint/DropdownComponent";
|
import DropDownComponent from "../components/designSystems/blueprint/DropdownComponent";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
placeholderText: VALIDATION_TYPES.TEXT,
|
||||||
|
label: VALIDATION_TYPES.TEXT,
|
||||||
|
options: VALIDATION_TYPES.ARRAY,
|
||||||
|
selectionType: VALIDATION_TYPES.TEXT,
|
||||||
|
selectedIndex: VALIDATION_TYPES.NUMBER,
|
||||||
|
selectedIndexArr: VALIDATION_TYPES.ARRAY,
|
||||||
|
};
|
||||||
|
}
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<DropDownComponent
|
<DropDownComponent
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import Webcam from "@uppy/webcam";
|
||||||
import Url from "@uppy/url";
|
import Url from "@uppy/url";
|
||||||
import OneDrive from "@uppy/onedrive";
|
import OneDrive from "@uppy/onedrive";
|
||||||
import FilePickerComponent from "../components/designSystems/appsmith/FilePickerComponent";
|
import FilePickerComponent from "../components/designSystems/appsmith/FilePickerComponent";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class FilePickerWidget extends BaseWidget<FilePickerWidgetProps, WidgetState> {
|
class FilePickerWidget extends BaseWidget<FilePickerWidgetProps, WidgetState> {
|
||||||
uppy: any;
|
uppy: any;
|
||||||
|
|
@ -16,6 +18,14 @@ class FilePickerWidget extends BaseWidget<FilePickerWidgetProps, WidgetState> {
|
||||||
this.refreshUppy(props);
|
this.refreshUppy(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
label: VALIDATION_TYPES.TEXT,
|
||||||
|
maxNumFiles: VALIDATION_TYPES.NUMBER,
|
||||||
|
allowedFileTypes: VALIDATION_TYPES.ARRAY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
refreshUppy = (props: FilePickerWidgetProps) => {
|
refreshUppy = (props: FilePickerWidgetProps) => {
|
||||||
this.uppy = Uppy({
|
this.uppy = Uppy({
|
||||||
id: this.props.widgetId,
|
id: this.props.widgetId,
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,17 @@ import * as React from "react";
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "../constants/WidgetConstants";
|
import { WidgetType } from "../constants/WidgetConstants";
|
||||||
import ImageComponent from "../components/designSystems/appsmith/ImageComponent";
|
import ImageComponent from "../components/designSystems/appsmith/ImageComponent";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
|
class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
image: VALIDATION_TYPES.TEXT,
|
||||||
|
imageShape: VALIDATION_TYPES.TEXT,
|
||||||
|
defaultImage: VALIDATION_TYPES.TEXT,
|
||||||
|
};
|
||||||
|
}
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<ImageComponent
|
<ImageComponent
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,28 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "constants/WidgetConstants";
|
import { WidgetType } from "constants/WidgetConstants";
|
||||||
import InputComponent from "components/designSystems/blueprint/InputComponent";
|
import InputComponent from "components/designSystems/blueprint/InputComponent";
|
||||||
import { ActionPayload } from "constants/ActionConstants";
|
import { ActionPayload } from "constants/ActionConstants";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
inputType: VALIDATION_TYPES.TEXT,
|
||||||
|
defaultText: VALIDATION_TYPES.TEXT,
|
||||||
|
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
||||||
|
text: VALIDATION_TYPES.TEXT,
|
||||||
|
regex: VALIDATION_TYPES.TEXT,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
regex = new RegExp("");
|
regex = new RegExp("");
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,17 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "../constants/WidgetConstants";
|
import { WidgetType } from "../constants/WidgetConstants";
|
||||||
import RadioGroupComponent from "../components/designSystems/blueprint/RadioGroupComponent";
|
import RadioGroupComponent from "../components/designSystems/blueprint/RadioGroupComponent";
|
||||||
import { ActionPayload } from "../constants/ActionConstants";
|
import { ActionPayload } from "../constants/ActionConstants";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
|
class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
label: VALIDATION_TYPES.TEXT,
|
||||||
|
options: VALIDATION_TYPES.ARRAY,
|
||||||
|
selectedOptionValue: VALIDATION_TYPES.TEXT,
|
||||||
|
};
|
||||||
|
}
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<RadioGroupComponent
|
<RadioGroupComponent
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,17 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import { WidgetType } from "../constants/WidgetConstants";
|
import { WidgetType } from "../constants/WidgetConstants";
|
||||||
import { Intent } from "@blueprintjs/core";
|
import { Intent } from "@blueprintjs/core";
|
||||||
import SpinnerComponent from "../components/designSystems/blueprint/SpinnerComponent";
|
import SpinnerComponent from "../components/designSystems/blueprint/SpinnerComponent";
|
||||||
|
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||||
|
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||||
|
|
||||||
class SpinnerWidget extends BaseWidget<SpinnerWidgetProps, WidgetState> {
|
class SpinnerWidget extends BaseWidget<SpinnerWidgetProps, WidgetState> {
|
||||||
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
|
return {
|
||||||
|
size: VALIDATION_TYPES.NUMBER,
|
||||||
|
value: VALIDATION_TYPES.NUMBER,
|
||||||
|
ellipsize: VALIDATION_TYPES.BOOLEAN,
|
||||||
|
};
|
||||||
|
}
|
||||||
getPageView() {
|
getPageView() {
|
||||||
return (
|
return (
|
||||||
<SpinnerComponent
|
<SpinnerComponent
|
||||||
|
|
|
||||||
|
|
@ -29,28 +29,20 @@ function constructColumns(data: object[]): Column[] {
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTableArrayData = (
|
|
||||||
tableData: string | object[] | undefined,
|
|
||||||
): object[] => {
|
|
||||||
if (!tableData) return [];
|
|
||||||
if (_.isString(tableData)) {
|
|
||||||
return JSON.parse(tableData as string);
|
|
||||||
} else {
|
|
||||||
return tableData;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
return {
|
return {
|
||||||
tableData: VALIDATION_TYPES.TABLE_DATA,
|
tableData: VALIDATION_TYPES.TABLE_DATA,
|
||||||
|
nextPageKey: VALIDATION_TYPES.TEXT,
|
||||||
|
prevPageKey: VALIDATION_TYPES.TEXT,
|
||||||
|
label: VALIDATION_TYPES.TEXT,
|
||||||
|
selectedRow: VALIDATION_TYPES.OBJECT,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getPageView() {
|
getPageView() {
|
||||||
const { tableData } = this.props;
|
const { tableData } = this.props;
|
||||||
const data = getTableArrayData(tableData);
|
const columns = constructColumns(tableData);
|
||||||
const columns = constructColumns(data);
|
|
||||||
return (
|
return (
|
||||||
<AutoResizer>
|
<AutoResizer>
|
||||||
{({ width, height }: { width: number; height: number }) => (
|
{({ width, height }: { width: number; height: number }) => (
|
||||||
|
|
@ -58,7 +50,7 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={data}
|
data={tableData}
|
||||||
maxHeight={height}
|
maxHeight={height}
|
||||||
isLoading={this.props.isLoading}
|
isLoading={this.props.isLoading}
|
||||||
selectedRowIndex={
|
selectedRowIndex={
|
||||||
|
|
@ -76,10 +68,12 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
}
|
}
|
||||||
componentDidUpdate(prevProps: TableWidgetProps) {
|
componentDidUpdate(prevProps: TableWidgetProps) {
|
||||||
super.componentDidUpdate(prevProps);
|
super.componentDidUpdate(prevProps);
|
||||||
const newData = getTableArrayData(this.props.tableData);
|
if (
|
||||||
if (prevProps.tableData !== this.props.tableData && prevProps.selectedRow) {
|
!_.isEqual(prevProps.tableData, this.props.tableData) &&
|
||||||
|
prevProps.selectedRow
|
||||||
|
) {
|
||||||
this.updateSelectedRowProperty(
|
this.updateSelectedRowProperty(
|
||||||
newData[prevProps.selectedRow.rowIndex],
|
this.props.tableData[prevProps.selectedRow.rowIndex],
|
||||||
prevProps.selectedRow.rowIndex,
|
prevProps.selectedRow.rowIndex,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +107,7 @@ export interface TableWidgetProps extends WidgetProps {
|
||||||
nextPageKey?: string;
|
nextPageKey?: string;
|
||||||
prevPageKey?: string;
|
prevPageKey?: string;
|
||||||
label: string;
|
label: string;
|
||||||
tableData?: string | object[];
|
tableData: object[];
|
||||||
recordActions?: TableAction[];
|
recordActions?: TableAction[];
|
||||||
onPageChange?: ActionPayload[];
|
onPageChange?: ActionPayload[];
|
||||||
onRowSelected?: ActionPayload[];
|
onRowSelected?: ActionPayload[];
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
|
||||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||||
return {
|
return {
|
||||||
text: VALIDATION_TYPES.TEXT,
|
text: VALIDATION_TYPES.TEXT,
|
||||||
|
textStyle: VALIDATION_TYPES.TEXT,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user