Merge branch 'fix/url-valid' into 'release'

Nav to Url validation fixed

See merge request theappsmith/internal-tools-client!419
This commit is contained in:
Satbir Singh 2020-03-31 10:40:53 +00:00
commit f472cfb835
18 changed files with 720 additions and 609 deletions

View File

@ -1,7 +1,7 @@
var widgetsPage = require("../../locators/Widgets.json");
var loginPage = require("../../locators/LoginPage.json");
const widgetsPage = require("../../locators/Widgets.json");
const loginPage = require("../../locators/LoginPage.json");
const loginData = require("../../fixtures/user.json");
var commonlocators = require("../../locators/commonlocators.json");
const commonlocators = require("../../locators/commonlocators.json");
context("Cypress test", function() {
it("Container Widget Functionality", function() {

View File

@ -1,7 +1,7 @@
var widgetsPage = require("../../locators/Widgets.json");
var loginPage = require("../../locators/LoginPage.json");
const widgetsPage = require("../../locators/Widgets.json");
const loginPage = require("../../locators/LoginPage.json");
const loginData = require("../../fixtures/user.json");
var commonlocators = require("../../locators/commonlocators.json");
const commonlocators = require("../../locators/commonlocators.json");
context("Cypress test", function() {
it("Text Widget Functionality", function() {

View File

@ -134,7 +134,7 @@ const getPageNameSelectedValue = (value: string) => {
return matches.length ? matches[0][2] : "none";
};
const getTextArgValue = (value: string) => {
export const getTextArgValue = (value: string) => {
const matches = [...value.matchAll(ACTION_TRIGGER_REGEX)];
if (matches.length) {
const stringValue = matches[0][2];
@ -279,6 +279,8 @@ type ReduxStateProps = {
interface Props {
value: string;
isValid: boolean;
validationMessage?: string;
onValueChange: (newValue: string) => void;
}
@ -426,7 +428,8 @@ class DynamicActionCreator extends React.Component<Props & ReduxStateProps> {
label={arg.label}
value={arg.getSelectedValue(value, false)}
onChange={e => handleUpdate(e, arg.valueChangeHandler)}
isValid={true}
isValid={this.props.isValid}
validationMessage={this.props.validationMessage}
/>
</ControlWrapper>
);

View File

@ -14,6 +14,8 @@ class ActionSelectorControl extends BaseControl<ControlProps> {
return (
<DynamicActionCreator
value={propertyValue}
isValid={this.props.isValid}
validationMessage={this.props.validationMessage}
onValueChange={this.handleValueUpdate}
/>
);

View File

@ -55,6 +55,8 @@ class ColumnActionSelectorControl extends BaseControl<
/>
<DynamicActionCreator
value={columnAction.dynamicTrigger}
isValid={(columnAction as any).isValid}
validationMessage={(columnAction as any).message}
onValueChange={this.updateColumnActionFunction.bind(
this,
columnAction,

View File

@ -11,6 +11,8 @@ export const VALIDATION_TYPES = {
OPTIONS_DATA: "OPTIONS_DATA",
DATE: "DATE",
CHART_DATA: "CHART_DATA",
ACTION_SELECTOR: "ACTION_SELECTOR",
ARRAY_ACTION_SELECTOR: "ARRAY_ACTION_SELECTOR",
};
export type ValidationResponse = {

View File

@ -82,6 +82,7 @@ export const ERROR_401 =
export const ERROR_403 =
"Permission Denied. Please contact your admin to gain access.";
export const WIDGET_TYPE_VALIDATION_ERROR = "Value does not match type";
export const URL_HTTP_VALIDATION_ERROR = "Please enter a valid URL";
export const INVITE_USERS_VALIDATION_EMAIL_LIST =
"Invalid Email address(es) found:";

File diff suppressed because it is too large Load Diff

View File

@ -50,12 +50,12 @@ export const getWidgetPropsForPropertyPane = createSelector(
if (evaluatedWidget.invalidProps) {
const { invalidProps, validationMessages } = evaluatedWidget;
return {
...widget,
...evaluatedWidget,
invalidProps,
validationMessages,
};
}
return widget;
return evaluatedWidget;
},
);

View File

@ -6,7 +6,12 @@ import {
Validator,
} from "constants/WidgetValidation";
import moment from "moment";
import { WIDGET_TYPE_VALIDATION_ERROR } from "constants/messages";
import {
WIDGET_TYPE_VALIDATION_ERROR,
URL_HTTP_VALIDATION_ERROR,
} from "constants/messages";
import { getTextArgValue } from "components/editorComponents/DynamicActionCreator";
const URL_REGEX = /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/;
export const VALIDATORS: Record<ValidationType, Validator> = {
[VALIDATION_TYPES.TEXT]: (value: any): ValidationResponse => {
@ -230,4 +235,54 @@ export const VALIDATORS: Record<ValidationType, Validator> = {
message: isValid ? "" : `${WIDGET_TYPE_VALIDATION_ERROR}: Date`,
};
},
[VALIDATION_TYPES.ACTION_SELECTOR]: (value: any): ValidationResponse => {
if (_.isString(value)) {
if (value.indexOf("navigateToUrl") !== -1) {
const url = getTextArgValue(value);
const isValidUrl = URL_REGEX.test(url);
console.log(url, isValidUrl);
debugger;
if (!isValidUrl) {
return {
isValid: false,
parsed: value,
message: `${URL_HTTP_VALIDATION_ERROR}`,
};
}
}
}
return {
isValid: true,
parsed: value,
};
},
[VALIDATION_TYPES.ARRAY_ACTION_SELECTOR]: (
value: any,
): ValidationResponse => {
const { isValid, parsed, message } = VALIDATORS[VALIDATION_TYPES.ARRAY](
value,
);
let isValidFinal = isValid;
let finalParsed = parsed.slice();
if (isValid) {
finalParsed = parsed.map((value: any) => {
const { isValid, message } = VALIDATORS[
VALIDATION_TYPES.ACTION_SELECTOR
](value.dynamicTrigger);
isValidFinal = isValidFinal && isValid;
return {
...value,
message: message,
isValid: isValid,
};
});
}
return {
isValid: isValidFinal,
parsed: finalParsed,
message: message,
};
},
};

View File

@ -16,6 +16,7 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
...BASE_WIDGET_VALIDATION,
label: VALIDATION_TYPES.TEXT,
defaultCheckedState: VALIDATION_TYPES.BOOLEAN,
onCheckChange: VALIDATION_TYPES.ACTION_SELECTOR,
};
}

View File

@ -26,6 +26,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
maxDate: VALIDATION_TYPES.DATE,
minDate: VALIDATION_TYPES.DATE,
isRequired: VALIDATION_TYPES.BOOLEAN,
onDateSelected: VALIDATION_TYPES.ACTION_SELECTOR,
};
}

View File

@ -23,6 +23,7 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
selectionType: VALIDATION_TYPES.TEXT,
selectedIndexArr: VALIDATION_TYPES.ARRAY,
isRequired: VALIDATION_TYPES.BOOLEAN,
onOptionChange: VALIDATION_TYPES.ACTION_SELECTOR,
defaultOptionValue: (value: string | string[], props?: WidgetProps) => {
let values = value;

View File

@ -37,6 +37,7 @@ class FilePickerWidget extends BaseWidget<FilePickerWidgetProps, WidgetState> {
allowedFileTypes: VALIDATION_TYPES.ARRAY,
files: VALIDATION_TYPES.ARRAY,
isRequired: VALIDATION_TYPES.BOOLEAN,
onFilesSelected: VALIDATION_TYPES.ACTION_SELECTOR,
};
}

View File

@ -33,6 +33,7 @@ class FormButtonWidget extends BaseWidget<
disabledWhenInvalid: VALIDATION_TYPES.BOOLEAN,
buttonStyle: VALIDATION_TYPES.TEXT,
buttonType: VALIDATION_TYPES.TEXT,
onClick: VALIDATION_TYPES.ACTION_SELECTOR,
};
}

View File

@ -17,9 +17,9 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
label: VALIDATION_TYPES.TEXT,
options: VALIDATION_TYPES.OPTIONS_DATA,
selectedOptionValue: VALIDATION_TYPES.TEXT,
onSelectionChange: VALIDATION_TYPES.TEXT,
defaultOptionValue: VALIDATION_TYPES.TEXT,
isRequired: VALIDATION_TYPES.BOOLEAN,
onSelectionChange: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDerivedPropertiesMap() {

View File

@ -17,6 +17,7 @@ class RichTextEditorWidget extends BaseWidget<
defaultValue: VALIDATION_TYPES.TEXT,
isDisabled: VALIDATION_TYPES.BOOLEAN,
isVisible: VALIDATION_TYPES.BOOLEAN,
onTextChange: VALIDATION_TYPES.ACTION_SELECTOR,
};
}

View File

@ -42,7 +42,9 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
prevPageKey: VALIDATION_TYPES.TEXT,
label: VALIDATION_TYPES.TEXT,
selectedRowIndex: VALIDATION_TYPES.NUMBER,
columnActions: VALIDATION_TYPES.ARRAY,
columnActions: VALIDATION_TYPES.ARRAY_ACTION_SELECTOR,
onRowSelected: VALIDATION_TYPES.ACTION_SELECTOR,
onPageChange: VALIDATION_TYPES.ACTION_SELECTOR,
};
}
static getDerivedPropertiesMap() {