Merge branch 'release' of gitlab.com:theappsmith/internal-tools-client into fix/chart-component-title-align
This commit is contained in:
commit
9021e6edb1
|
|
@ -1,5 +1,4 @@
|
|||
.git
|
||||
.idea
|
||||
node_modules
|
||||
build
|
||||
build.tgz
|
||||
3
app/client/.gitignore
vendored
3
app/client/.gitignore
vendored
|
|
@ -29,4 +29,5 @@ yarn-error.log*
|
|||
.idea
|
||||
.storybook-out/
|
||||
cypress/videos
|
||||
results/
|
||||
cypress/screenshots
|
||||
results/
|
||||
|
|
|
|||
|
|
@ -4,6 +4,17 @@
|
|||
- master
|
||||
- merge_requests
|
||||
|
||||
.set_env_variables: &set_env_variables
|
||||
- |
|
||||
if [ "$CI_COMMIT_BRANCH" == "master" ]; then
|
||||
REACT_APP_ENVIRONMENT="PRODUCTION"
|
||||
elif [ "$CI_COMMIT_BRANCH" == "release" ]; then
|
||||
REACT_APP_ENVIRONMENT="STAGING"
|
||||
REACT_APP_BASE_URL="https://release-api.appsmith.com"
|
||||
else
|
||||
REACT_APP_ENVIRONMENT="DEVELOPMENT"
|
||||
REACT_APP_BASE_URL="https://release-api.appsmith.com"
|
||||
fi
|
||||
image: cypress/base:10.16.3
|
||||
|
||||
variables:
|
||||
|
|
@ -25,32 +36,38 @@ stages:
|
|||
- package
|
||||
- deploy
|
||||
|
||||
react-build:
|
||||
react-build-release:
|
||||
stage: build
|
||||
script:
|
||||
- *set_env_variables
|
||||
- yarn install
|
||||
# show where the Cypress test runner binaries are cached
|
||||
- $(npm bin)/cypress cache path
|
||||
# show all installed versions of Cypress binary
|
||||
- $(npm bin)/cypress cache list
|
||||
- $(npm bin)/cypress verify
|
||||
- REACT_APP_ENVIRONMENT=$REACT_APP_ENVIRONMENT REACT_APP_BASE_URL=$REACT_APP_BASE_URL GIT_SHA=$CI_COMMIT_SHORT_SHA yarn build
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build/
|
||||
only:
|
||||
- release
|
||||
- merge_requests
|
||||
|
||||
cypress-test:
|
||||
cypress-test-release:
|
||||
stage: test
|
||||
script:
|
||||
- REACT_APP_ENVIRONMENT=DEVELOPMENT REACT_APP_BASE_URL="https://release-api.appsmith.com" GIT_SHA=$CI_COMMIT_SHORT_SHA yarn build
|
||||
- *set_env_variables
|
||||
- yarn global add serve
|
||||
- serve -s build -p 3000 &
|
||||
# This is required in order to ensure that all the test cases pass
|
||||
- echo "127.0.0.1 dev.appsmith.com" >> /etc/hosts
|
||||
- yarn test
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build/
|
||||
- cypress/screenshots
|
||||
- cypress/videos
|
||||
only:
|
||||
|
|
@ -61,22 +78,38 @@ cypress-test:
|
|||
docker-package-release:
|
||||
image: docker:dind
|
||||
services:
|
||||
- docker:dind
|
||||
- docker:dind
|
||||
stage: package
|
||||
script:
|
||||
- docker build --build-arg REACT_APP_ENVIRONMENT=STAGING --build-arg GIT_SHA=$CI_COMMIT_SHORT_SHA -t appsmith/appsmith-editor:release .
|
||||
- *set_env_variables
|
||||
- docker build -t appsmith/appsmith-editor:release .
|
||||
- docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_ACCESS_TOKEN
|
||||
- docker push appsmith/appsmith-editor:release
|
||||
only:
|
||||
- release
|
||||
|
||||
react-build-prod:
|
||||
stage: build
|
||||
script:
|
||||
- *set_env_variables
|
||||
- yarn install
|
||||
- REACT_APP_ENVIRONMENT=$REACT_APP_ENVIRONMENT GIT_SHA=$CI_COMMIT_SHORT_SHA yarn build
|
||||
artifacts:
|
||||
when: on_success
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build/
|
||||
only:
|
||||
- master
|
||||
|
||||
docker-package-prod:
|
||||
image: docker:dind
|
||||
services:
|
||||
- docker:dind
|
||||
stage: package
|
||||
script:
|
||||
- docker build --build-arg REACT_APP_ENVIRONMENT=PRODUCTION --build-arg GIT_SHA=$CI_COMMIT_SHORT_SHA -t appsmith/appsmith-editor:latest .
|
||||
script:
|
||||
- *set_env_variables
|
||||
- docker build -t appsmith/appsmith-editor:latest .
|
||||
- docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_ACCESS_TOKEN
|
||||
- docker push appsmith/appsmith-editor:latest
|
||||
only:
|
||||
|
|
|
|||
|
|
@ -1,22 +1,7 @@
|
|||
FROM node:10.19-alpine as build-deps
|
||||
FROM nginx:1.17.9-alpine
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
ARG REACT_APP_ENVIRONMENT="DEVELOPMENT"
|
||||
ARG GIT_SHA=""
|
||||
|
||||
ENV REACT_APP_ENVIRONMENT=${REACT_APP_ENVIRONMENT}
|
||||
ENV REACT_APP_BASE_URL=${REACT_APP_BASE_URL}
|
||||
ENV GIT_SHA=${GIT_SHA}
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY . ./
|
||||
RUN yarn install && yarn build
|
||||
|
||||
# Use the output from the previous Docker build to create the nginx container
|
||||
FROM nginx:1.17.9-alpine as final-image
|
||||
COPY --from=build-deps /usr/src/app/docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build-deps /usr/src/app/build /var/www/appsmith
|
||||
COPY ./build /var/www/appsmith
|
||||
RUN ls -al /var/www/appsmith
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
#!/bin/sh
|
||||
# GIT_SHA=$(eval git rev-parse HEAD)
|
||||
# GIT_BRANCH=$(git branch --no-color | grep -E '^\*' | sed 's/\*[^a-z]*//g')
|
||||
|
||||
# RELEASE="${GIT_BRANCH}_${GIT_SHA}"
|
||||
|
||||
|
||||
# RELEASE=$(echo "$RELEASE" | sed -e 's/[\/\\\ .]/\-/g')
|
||||
# echo $RELEASE
|
||||
|
||||
GIT_SHA=$(eval git rev-parse HEAD)
|
||||
echo $GIT_SHA
|
||||
REACT_APP_SENTRY_RELEASE=$GIT_SHA craco --max-old-space-size=4096 build --config craco.build.config.js
|
||||
|
||||
rm ./build/static/js/*.js.map
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
"@blueprintjs/timezone": "^3.6.0",
|
||||
"@craco/craco": "^5.6.1",
|
||||
"@sentry/browser": "^5.6.3",
|
||||
"@sentry/webpack-plugin": "^1.10.0",
|
||||
"@syncfusion/ej2-react-grids": "^17.4.40",
|
||||
"@types/chance": "^1.0.7",
|
||||
"@types/fontfaceobserver": "^0.0.6",
|
||||
|
|
@ -117,7 +118,6 @@
|
|||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.4",
|
||||
"@sentry/webpack-plugin": "^1.10.0",
|
||||
"@storybook/addon-contexts": "^5.2.6",
|
||||
"@storybook/addon-docs": "^5.2.8",
|
||||
"@storybook/addon-knobs": "^5.2.6",
|
||||
|
|
@ -158,8 +158,7 @@
|
|||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged",
|
||||
"pre-push": "yarn run test"
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,14 +71,14 @@ class DatePickerComponent extends React.Component<DatePickerComponentProps> {
|
|||
this.props.enableTimePicker
|
||||
? {
|
||||
useAmPm: true,
|
||||
value: this.props.selectedDate || this.props.defaultDate,
|
||||
value: this.props.selectedDate,
|
||||
showArrowButtons: true,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
closeOnSelection={true}
|
||||
onChange={this.onDateSelected}
|
||||
value={this.props.selectedDate || this.props.defaultDate}
|
||||
value={this.props.selectedDate}
|
||||
/>
|
||||
) : (
|
||||
<DateRangeInput
|
||||
|
|
@ -121,7 +121,6 @@ class DatePickerComponent extends React.Component<DatePickerComponentProps> {
|
|||
|
||||
export interface DatePickerComponentProps extends ComponentProps {
|
||||
label: string;
|
||||
defaultDate?: Date;
|
||||
dateFormat: string;
|
||||
enableTimePicker?: boolean;
|
||||
selectedDate?: Date;
|
||||
|
|
|
|||
|
|
@ -228,7 +228,8 @@ class DropDownComponent extends React.Component<DropDownComponentProps> {
|
|||
rightIcon={IconNames.CHEVRON_DOWN}
|
||||
text={
|
||||
!_.isEmpty(this.props.options) &&
|
||||
this.props.selectedIndex !== undefined
|
||||
this.props.selectedIndex !== undefined &&
|
||||
this.props.selectedIndex > -1
|
||||
? this.props.options[this.props.selectedIndex].label
|
||||
: "-- Empty --"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,10 +144,19 @@ const DraggableComponent = (props: DraggableComponentProps) => {
|
|||
props.widgetId === propertyPaneState.widgetId) ||
|
||||
props.widgetId !== propertyPaneState.widgetId
|
||||
) {
|
||||
AnalyticsUtil.logEvent("PROPERTY_PANE_OPEN_CLICK", {
|
||||
widgetType: props.type,
|
||||
widgetId: props.widgetId,
|
||||
});
|
||||
showPropertyPane && showPropertyPane(props.widgetId, undefined, true);
|
||||
} else {
|
||||
AnalyticsUtil.logEvent("PROPERTY_PANE_CLOSE_CLICK", {
|
||||
widgetType: props.type,
|
||||
widgetId: props.widgetId,
|
||||
});
|
||||
showPropertyPane && showPropertyPane();
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ class DynamicActionCreator extends React.Component<Props & ReduxStateProps> {
|
|||
) => void,
|
||||
) => {
|
||||
return (
|
||||
<div style={{ paddingLeft: 5 }}>
|
||||
<div>
|
||||
{selectedOption.arguments.map(arg => {
|
||||
switch (arg.field) {
|
||||
case "ACTION_SELECTOR_FIELD":
|
||||
|
|
@ -357,14 +357,15 @@ class DynamicActionCreator extends React.Component<Props & ReduxStateProps> {
|
|||
);
|
||||
case "TEXT_FIELD":
|
||||
return (
|
||||
<React.Fragment key={arg.label}>
|
||||
<ControlWrapper key={arg.label}>
|
||||
<label>{arg.label}</label>
|
||||
<InputText
|
||||
label={arg.label}
|
||||
value={arg.getSelectedValue(value, false)}
|
||||
onChange={e => handleUpdate(e, arg.valueChangeHandler)}
|
||||
isValid={true}
|
||||
/>
|
||||
</React.Fragment>
|
||||
</ControlWrapper>
|
||||
);
|
||||
case "ALERT_TYPE_SELECTOR_FIELD":
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ export interface ControlData {
|
|||
id: string;
|
||||
label: string;
|
||||
propertyName: string;
|
||||
helpText?: string;
|
||||
isJSConvertible?: boolean;
|
||||
controlType: ControlType;
|
||||
propertyValue?: any;
|
||||
isValid: boolean;
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ export function InputText(props: {
|
|||
onChange: (event: React.ChangeEvent<HTMLTextAreaElement> | string) => void;
|
||||
isValid: boolean;
|
||||
validationMessage?: string;
|
||||
placeholder?: string;
|
||||
}) {
|
||||
const { validationMessage, value, isValid, onChange } = props;
|
||||
const { validationMessage, value, isValid, onChange, placeholder } = props;
|
||||
return (
|
||||
<StyledDynamicInput>
|
||||
<DynamicAutocompleteInput
|
||||
|
|
@ -26,6 +27,7 @@ export function InputText(props: {
|
|||
}}
|
||||
theme={"DARK"}
|
||||
singleLine={false}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
</StyledDynamicInput>
|
||||
);
|
||||
|
|
@ -33,7 +35,13 @@ export function InputText(props: {
|
|||
|
||||
class InputTextControl extends BaseControl<InputControlProps> {
|
||||
render() {
|
||||
const { validationMessage, propertyValue, isValid, label } = this.props;
|
||||
const {
|
||||
validationMessage,
|
||||
propertyValue,
|
||||
isValid,
|
||||
label,
|
||||
placeholderText,
|
||||
} = this.props;
|
||||
return (
|
||||
<InputText
|
||||
label={label}
|
||||
|
|
@ -41,6 +49,7 @@ class InputTextControl extends BaseControl<InputControlProps> {
|
|||
onChange={this.onTextChange}
|
||||
isValid={isValid}
|
||||
validationMessage={validationMessage}
|
||||
placeholder={placeholderText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { ControlType } from "constants/PropertyControlConstants";
|
|||
import styled from "constants/DefaultTheme";
|
||||
import { FormIcons } from "icons/FormIcons";
|
||||
import { AnyStyledComponent } from "styled-components";
|
||||
import { generateReactKey } from "utils/generators";
|
||||
|
||||
const StyledDeleteIcon = styled(FormIcons.DELETE_ICON as AnyStyledComponent)`
|
||||
padding: 5px 5px;
|
||||
|
|
@ -28,16 +29,64 @@ const StyledOptionControlWrapper = styled(ControlWrapper)`
|
|||
padding-right: 16px;
|
||||
`;
|
||||
|
||||
class OptionControl extends BaseControl<ControlProps> {
|
||||
function updateOptionLabel<T>(
|
||||
options: Array<T>,
|
||||
index: number,
|
||||
updatedLabel: string,
|
||||
) {
|
||||
return options.map((option: T, optionIndex) => {
|
||||
if (index !== optionIndex) {
|
||||
return option;
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
label: updatedLabel,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function updateOptionValue<T>(
|
||||
options: Array<T>,
|
||||
index: number,
|
||||
updatedValue: string,
|
||||
) {
|
||||
return options.map((option, optionIndex) => {
|
||||
if (index !== optionIndex) {
|
||||
return option;
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
value: updatedValue,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
type DropDownOptionWithKey = DropdownOption & {
|
||||
key: string;
|
||||
};
|
||||
|
||||
class OptionControl extends BaseControl<
|
||||
ControlProps,
|
||||
{
|
||||
renderOptions: DropDownOptionWithKey[];
|
||||
}
|
||||
> {
|
||||
constructor(props: ControlProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
renderOptions: [],
|
||||
};
|
||||
}
|
||||
render() {
|
||||
const options: DropdownOption[] = this.props.propertyValue || [{}];
|
||||
const { renderOptions } = this.state;
|
||||
debugger;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{options.map((option, index) => {
|
||||
{renderOptions.map((option, index) => {
|
||||
return (
|
||||
<StyledOptionControlWrapper
|
||||
orientation={"HORIZONTAL"}
|
||||
key={option.value}
|
||||
key={option.key}
|
||||
>
|
||||
<StyledOptionControlInputGroup
|
||||
type={"text"}
|
||||
|
|
@ -76,49 +125,100 @@ class OptionControl extends BaseControl<ControlProps> {
|
|||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { propertyValue } = this.props;
|
||||
|
||||
const options: DropdownOption[] = Array.isArray(propertyValue)
|
||||
? propertyValue
|
||||
: [{}];
|
||||
|
||||
options.map(option => {
|
||||
return {
|
||||
...option,
|
||||
key: generateReactKey(),
|
||||
};
|
||||
});
|
||||
this.setState({
|
||||
renderOptions: options.map(option => {
|
||||
return {
|
||||
...option,
|
||||
key: generateReactKey(),
|
||||
};
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
deleteOption = (index: number) => {
|
||||
const options: DropdownOption[] = this.props.propertyValue.slice();
|
||||
options.splice(index, 1);
|
||||
this.updateProperty("options", options);
|
||||
const { propertyValue } = this.props;
|
||||
const options: DropdownOption[] = Array.isArray(propertyValue)
|
||||
? propertyValue
|
||||
: [{}];
|
||||
const { renderOptions } = this.state;
|
||||
|
||||
const newOptions = options.filter((o, i) => i !== index);
|
||||
const newRenderOptions = renderOptions.filter((o, i) => i !== index);
|
||||
|
||||
this.updateProperty("options", newOptions);
|
||||
this.setState({
|
||||
renderOptions: newRenderOptions,
|
||||
});
|
||||
};
|
||||
|
||||
updateOptionLabel = (index: number, updatedLabel: string) => {
|
||||
const options: DropdownOption[] = this.props.propertyValue;
|
||||
const { propertyValue } = this.props;
|
||||
const options: DropdownOption[] = Array.isArray(propertyValue)
|
||||
? propertyValue
|
||||
: [{}];
|
||||
this.updateProperty(
|
||||
"options",
|
||||
options.map((option, optionIndex) => {
|
||||
if (index !== optionIndex) {
|
||||
return option;
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
label: updatedLabel,
|
||||
};
|
||||
}),
|
||||
updateOptionLabel(options, index, updatedLabel),
|
||||
);
|
||||
|
||||
this.setState({
|
||||
renderOptions: updateOptionLabel(
|
||||
this.state.renderOptions,
|
||||
index,
|
||||
updatedLabel,
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
updateOptionValue = (index: number, updatedValue: string) => {
|
||||
const options: DropdownOption[] = this.props.propertyValue;
|
||||
const { propertyValue } = this.props;
|
||||
const options: DropdownOption[] = Array.isArray(propertyValue)
|
||||
? propertyValue
|
||||
: [{}];
|
||||
this.updateProperty(
|
||||
"options",
|
||||
options.map((option, optionIndex) => {
|
||||
if (index !== optionIndex) {
|
||||
return option;
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
value: updatedValue,
|
||||
};
|
||||
}),
|
||||
updateOptionValue(options, index, updatedValue),
|
||||
);
|
||||
|
||||
this.setState({
|
||||
renderOptions: updateOptionValue(
|
||||
this.state.renderOptions,
|
||||
index,
|
||||
updatedValue,
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
addOption = () => {
|
||||
const options: DropdownOption[] = this.props.propertyValue
|
||||
? this.props.propertyValue.slice()
|
||||
: [];
|
||||
const { propertyValue } = this.props;
|
||||
const options: DropdownOption[] = Array.isArray(propertyValue)
|
||||
? propertyValue
|
||||
: [{}];
|
||||
const { renderOptions } = this.state;
|
||||
|
||||
options.push({ label: "", value: "" });
|
||||
renderOptions.push({
|
||||
label: "",
|
||||
value: "",
|
||||
key: generateReactKey(),
|
||||
});
|
||||
|
||||
this.setState({
|
||||
renderOptions: renderOptions,
|
||||
});
|
||||
this.updateProperty("options", options);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,3 @@ export type ControlType =
|
|||
| "TIME_ZONE"
|
||||
| "CODE_EDITOR"
|
||||
| "COLUMN_ACTION_SELECTOR";
|
||||
|
||||
export const CONVERTIBLE_CONTROLS = [
|
||||
"SWITCH",
|
||||
"OPTION_INPUT",
|
||||
"ACTION_SELECTOR",
|
||||
"DATE_PICKER",
|
||||
];
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
|||
FILE_PICKER_WIDGET: {
|
||||
rows: 1,
|
||||
files: [],
|
||||
label: "Select Files",
|
||||
columns: 4,
|
||||
widgetName: "FilePicker",
|
||||
isDefaultClickDisabled: true,
|
||||
|
|
@ -201,14 +202,14 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
|||
isDefaultClickDisabled: true,
|
||||
},
|
||||
FORM_WIDGET: {
|
||||
rows: 10,
|
||||
columns: 10,
|
||||
rows: 13,
|
||||
columns: 6,
|
||||
widgetName: "Form",
|
||||
blueprint: {
|
||||
view: [
|
||||
{
|
||||
type: "TEXT_WIDGET",
|
||||
size: { rows: 1, cols: 4 },
|
||||
size: { rows: 1, cols: 12 },
|
||||
position: { top: 0, left: 0 },
|
||||
props: {
|
||||
text: "Title",
|
||||
|
|
@ -217,8 +218,8 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
|||
},
|
||||
{
|
||||
type: "FORM_BUTTON_WIDGET",
|
||||
size: { rows: 1, cols: 3 },
|
||||
position: { top: 8, left: 13 },
|
||||
size: { rows: 1, cols: 4 },
|
||||
position: { top: 11, left: 12 },
|
||||
props: {
|
||||
text: "Submit",
|
||||
buttonStyle: "PRIMARY_BUTTON",
|
||||
|
|
@ -228,8 +229,8 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
|
|||
},
|
||||
{
|
||||
type: "FORM_BUTTON_WIDGET",
|
||||
size: { rows: 1, cols: 3 },
|
||||
position: { top: 8, left: 10 },
|
||||
size: { rows: 1, cols: 4 },
|
||||
position: { top: 11, left: 8 },
|
||||
props: {
|
||||
text: "Reset",
|
||||
buttonStyle: "SECONDARY_BUTTON",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React from "react";
|
||||
import _ from "lodash";
|
||||
import { CONVERTIBLE_CONTROLS } from "constants/PropertyControlConstants";
|
||||
import {
|
||||
ControlPropertyLabelContainer,
|
||||
ControlWrapper,
|
||||
|
|
@ -10,6 +9,7 @@ import { ControlIcons } from "icons/ControlIcons";
|
|||
import PropertyControlFactory from "utils/PropertyControlFactory";
|
||||
import { WidgetProps } from "widgets/BaseWidget";
|
||||
import { ControlConfig } from "reducers/entityReducers/propertyPaneConfigReducer";
|
||||
import { Tooltip } from "@blueprintjs/core";
|
||||
|
||||
type Props = {
|
||||
widgetProperties: WidgetProps;
|
||||
|
|
@ -18,6 +18,47 @@ type Props = {
|
|||
onPropertyChange: (propertyName: string, propertyValue: any) => void;
|
||||
};
|
||||
|
||||
function UnderlinedLabel({
|
||||
tooltip,
|
||||
label,
|
||||
}: {
|
||||
tooltip?: string;
|
||||
label: string;
|
||||
}) {
|
||||
const toolTipDefined = tooltip !== undefined;
|
||||
return (
|
||||
<Tooltip disabled={!toolTipDefined} content={tooltip} hoverOpenDelay={200}>
|
||||
<div
|
||||
style={
|
||||
toolTipDefined
|
||||
? {
|
||||
height: "20px",
|
||||
cursor: "help",
|
||||
}
|
||||
: {
|
||||
height: "20px",
|
||||
}
|
||||
}
|
||||
>
|
||||
{label}
|
||||
<span
|
||||
style={
|
||||
toolTipDefined
|
||||
? {
|
||||
borderBottom: "1px dashed",
|
||||
width: "100%",
|
||||
display: "inline-block",
|
||||
position: "relative",
|
||||
top: "-15px",
|
||||
}
|
||||
: {}
|
||||
}
|
||||
></span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
const PropertyControl = (props: Props) => {
|
||||
const {
|
||||
widgetProperties,
|
||||
|
|
@ -54,7 +95,7 @@ const PropertyControl = (props: Props) => {
|
|||
["dynamicProperties", propertyName],
|
||||
false,
|
||||
);
|
||||
const isConvertible = CONVERTIBLE_CONTROLS.indexOf(config.controlType) > -1;
|
||||
const isConvertible = !!propertyConfig.isJSConvertible;
|
||||
const className = propertyConfig.label
|
||||
.split(" ")
|
||||
.join("")
|
||||
|
|
@ -71,7 +112,11 @@ const PropertyControl = (props: Props) => {
|
|||
}
|
||||
>
|
||||
<ControlPropertyLabelContainer>
|
||||
<label>{label}</label>
|
||||
<UnderlinedLabel
|
||||
tooltip={propertyConfig.helpText}
|
||||
label={label}
|
||||
></UnderlinedLabel>
|
||||
|
||||
{isConvertible && (
|
||||
<JSToggleButton
|
||||
active={isDynamic}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,12 @@ class PropertyPane extends Component<
|
|||
|
||||
<CloseButton
|
||||
onClick={(e: any) => {
|
||||
AnalyticsUtil.logEvent("PROPERTY_PANE_CLOSE_CLICK", {
|
||||
widgetType: this.props.widgetProperties
|
||||
? this.props.widgetProperties.type
|
||||
: "",
|
||||
widgetId: this.props.widgetId,
|
||||
});
|
||||
this.props.hidePropertyPane();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
@ -167,6 +173,40 @@ class PropertyPane extends Component<
|
|||
}
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps: PropertyPaneProps & PropertyPaneFunctions) {
|
||||
if (
|
||||
this.props.widgetId !== prevProps.widgetId &&
|
||||
this.props.widgetId !== undefined
|
||||
) {
|
||||
if (prevProps.widgetId && prevProps.widgetProperties) {
|
||||
AnalyticsUtil.logEvent("PROPERTY_PANE_CLOSE", {
|
||||
widgetType: prevProps.widgetProperties.type,
|
||||
widgetId: prevProps.widgetId,
|
||||
});
|
||||
}
|
||||
if (this.props.widgetProperties) {
|
||||
AnalyticsUtil.logEvent("PROPERTY_PANE_OPEN", {
|
||||
widgetType: this.props.widgetProperties.type,
|
||||
widgetId: this.props.widgetId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.props.widgetId === prevProps.widgetId &&
|
||||
this.props.isVisible &&
|
||||
!prevProps.isVisible &&
|
||||
this.props.widgetProperties !== undefined
|
||||
) {
|
||||
AnalyticsUtil.logEvent("PROPERTY_PANE_OPEN", {
|
||||
widgetType: this.props.widgetProperties.type,
|
||||
widgetId: this.props.widgetId,
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
onPropertyChange(propertyName: string, propertyValue: any) {
|
||||
this.props.updateWidgetProperty(
|
||||
this.props.widgetId,
|
||||
|
|
|
|||
|
|
@ -134,12 +134,10 @@ export function* evaluateDynamicBoundValueSaga(path: string): any {
|
|||
|
||||
export function* getActionParams(jsonPathKeys: string[] | undefined) {
|
||||
if (_.isNil(jsonPathKeys)) return [];
|
||||
const values: any = _.flatten(
|
||||
yield all(
|
||||
jsonPathKeys.map((jsonPath: string) => {
|
||||
return call(evaluateDynamicBoundValueSaga, jsonPath);
|
||||
}),
|
||||
),
|
||||
const values: any = yield all(
|
||||
jsonPathKeys.map((jsonPath: string) => {
|
||||
return call(evaluateDynamicBoundValueSaga, jsonPath);
|
||||
}),
|
||||
);
|
||||
const dynamicBindings: Record<string, string> = {};
|
||||
jsonPathKeys.forEach((key, i) => {
|
||||
|
|
@ -302,7 +300,13 @@ export function* executeActionTriggers(
|
|||
AnalyticsUtil.logEvent("NAVIGATE", {
|
||||
navUrl: trigger.payload.url,
|
||||
});
|
||||
window.location.href = trigger.payload.url;
|
||||
// Add a default protocol if it doesn't exist.
|
||||
let url = trigger.payload.url;
|
||||
if (url.indexOf("://") === -1) {
|
||||
url = "https://" + url;
|
||||
}
|
||||
window.location.assign(url);
|
||||
|
||||
if (event.callback) event.callback({ success: true });
|
||||
} else {
|
||||
if (event.callback) event.callback({ success: false });
|
||||
|
|
@ -329,10 +333,12 @@ export function* executeAppAction(action: ReduxAction<ExecuteActionPayload>) {
|
|||
const { dynamicString, event, responseData } = action.payload;
|
||||
const tree = yield select(evaluateDataTree);
|
||||
const { triggers } = getDynamicValue(dynamicString, tree, responseData, true);
|
||||
if (triggers) {
|
||||
if (triggers && triggers.length) {
|
||||
yield all(
|
||||
triggers.map(trigger => call(executeActionTriggers, trigger, event)),
|
||||
);
|
||||
} else {
|
||||
if (event.callback) event.callback({ success: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -585,8 +591,7 @@ function* executePageLoadActionsSaga(action: ReduxAction<PageAction[][]>) {
|
|||
const pageActions = action.payload;
|
||||
for (const actionSet of pageActions) {
|
||||
const apiResponses = yield select(getActionResponses);
|
||||
const filteredSet = actionSet.filter(action => !apiResponses[action.id]);
|
||||
yield* yield all(filteredSet.map(a => call(executePageLoadAction, a)));
|
||||
yield* yield all(actionSet.map(a => call(executePageLoadAction, a)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -687,7 +692,7 @@ function* copyActionSaga(
|
|||
export function* watchActionSagas() {
|
||||
yield all([
|
||||
takeEvery(ReduxActionTypes.FETCH_ACTIONS_INIT, fetchActionsSaga),
|
||||
takeLatest(ReduxActionTypes.EXECUTE_ACTION, executeAppAction),
|
||||
takeEvery(ReduxActionTypes.EXECUTE_ACTION, executeAppAction),
|
||||
takeLatest(ReduxActionTypes.RUN_API_REQUEST, runApiActionSaga),
|
||||
takeLatest(ReduxActionTypes.CREATE_ACTION_INIT, createActionSaga),
|
||||
takeLatest(ReduxActionTypes.UPDATE_ACTION_INIT, updateActionSaga),
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ export function* errorSaga(
|
|||
type,
|
||||
payload: { error, show = true },
|
||||
} = errorAction;
|
||||
const message = error.message || ActionErrorDisplayMap[type](error);
|
||||
const message =
|
||||
error && error.message ? error.message : ActionErrorDisplayMap[type](error);
|
||||
if (show) AppToaster.show({ message, type: ToastType.ERROR });
|
||||
yield put({
|
||||
type: ReduxActionTypes.REPORT_ERROR,
|
||||
|
|
|
|||
|
|
@ -123,12 +123,12 @@ export function* fetchPageSaga(
|
|||
if (isValidResponse) {
|
||||
// Get Canvas payload
|
||||
const canvasWidgetsPayload = getCanvasWidgetsPayload(fetchPageResponse);
|
||||
// Execute page load actions
|
||||
yield put(executePageLoadActions(canvasWidgetsPayload.pageActions));
|
||||
// Update the canvas
|
||||
yield put(updateCanvas(canvasWidgetsPayload));
|
||||
// dispatch fetch page success
|
||||
yield put(fetchPageSuccess());
|
||||
// Execute page load actions
|
||||
yield put(executePageLoadActions(canvasWidgetsPayload.pageActions));
|
||||
}
|
||||
} catch (error) {
|
||||
yield put({
|
||||
|
|
@ -155,8 +155,6 @@ export function* fetchPublishedPageSaga(
|
|||
const isValidResponse = yield validateResponse(response);
|
||||
if (isValidResponse) {
|
||||
const canvasWidgetsPayload = getCanvasWidgetsPayload(response);
|
||||
// Execute page load actions
|
||||
yield put(executePageLoadActions(canvasWidgetsPayload.pageActions));
|
||||
yield put(updateCanvas(canvasWidgetsPayload));
|
||||
yield put({
|
||||
type: ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS,
|
||||
|
|
@ -167,6 +165,8 @@ export function* fetchPublishedPageSaga(
|
|||
pageWidgetId: canvasWidgetsPayload.pageWidgetId,
|
||||
},
|
||||
});
|
||||
// Execute page load actions
|
||||
yield put(executePageLoadActions(canvasWidgetsPayload.pageActions));
|
||||
}
|
||||
} catch (error) {
|
||||
yield put({
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import {
|
|||
takeLatest,
|
||||
all,
|
||||
} from "redux-saga/effects";
|
||||
import { getNextEntityName } from "utils/AppsmithUtils";
|
||||
import { convertToString, getNextEntityName } from "utils/AppsmithUtils";
|
||||
import {
|
||||
SetWidgetDynamicPropertyPayload,
|
||||
updateWidgetProperty,
|
||||
|
|
@ -262,7 +262,8 @@ function* setWidgetDynamicPropertySaga(
|
|||
};
|
||||
if (isDynamic) {
|
||||
dynamicProperties[propertyName] = true;
|
||||
yield put(updateWidgetProperty(widgetId, propertyName, "{{}}"));
|
||||
const value = convertToString(widget[propertyName]);
|
||||
yield put(updateWidgetProperty(widgetId, propertyName, value));
|
||||
} else {
|
||||
delete dynamicProperties[propertyName];
|
||||
yield put(updateWidgetProperty(widgetId, propertyName, undefined));
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import {
|
|||
getResponseErrorMessage,
|
||||
callAPI,
|
||||
} from "./ErrorSagas";
|
||||
import * as Sentry from "@sentry/browser";
|
||||
|
||||
import { fetchOrgsSaga } from "./OrgSagas";
|
||||
|
||||
|
|
@ -295,6 +296,9 @@ export function* setCurrentUserSaga(action: ReduxAction<FetchUserRequest>) {
|
|||
const me = yield call(fetchUserSaga, action);
|
||||
if (me) {
|
||||
AnalyticsUtil.identifyUser(me.id, me);
|
||||
Sentry.configureScope(function(scope) {
|
||||
scope.setUser({ email: me.email, id: me.id });
|
||||
});
|
||||
resetAuthExpiration();
|
||||
yield put({
|
||||
type: ReduxActionTypes.SET_CURRENT_USER_SUCCESS,
|
||||
|
|
|
|||
|
|
@ -42,7 +42,11 @@ export type EventName =
|
|||
| "SAVE_DATA_SOURCE"
|
||||
| "NAVIGATE"
|
||||
| "PAGE_LOAD"
|
||||
| "NAVIGATE_EDITOR";
|
||||
| "NAVIGATE_EDITOR"
|
||||
| "PROPERTY_PANE_OPEN"
|
||||
| "PROPERTY_PANE_CLOSE"
|
||||
| "PROPERTY_PANE_OPEN_CLICK"
|
||||
| "PROPERTY_PANE_CLOSE_CLICK";
|
||||
|
||||
export type Gender = "MALE" | "FEMALE";
|
||||
export interface User {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ReduxAction } from "../constants/ReduxActionConstants";
|
||||
import { ReduxAction } from "constants/ReduxActionConstants";
|
||||
import { getAppsmithConfigs } from "configs";
|
||||
import * as Sentry from "@sentry/browser";
|
||||
import AnalyticsUtil from "./AnalyticsUtil";
|
||||
|
|
@ -77,3 +77,14 @@ export const getNextEntityName = (prefix: string, existingNames: string[]) => {
|
|||
export const noop = () => {
|
||||
console.log("noop");
|
||||
};
|
||||
|
||||
export const convertToString = (value: any): string => {
|
||||
if (_.isUndefined(value)) {
|
||||
return "";
|
||||
}
|
||||
if (_.isObject(value)) {
|
||||
return JSON.stringify(value, null, 2);
|
||||
}
|
||||
if (_.isString(value)) return value;
|
||||
return value.toString();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
import { WidgetType } from "constants/WidgetConstants";
|
||||
import WidgetFactory from "./WidgetFactory";
|
||||
import {
|
||||
VALIDATION_TYPES,
|
||||
ValidationResponse,
|
||||
ValidationType,
|
||||
Validator,
|
||||
} from "constants/WidgetValidation";
|
||||
|
||||
// TODO: need to be strict about what the key can be
|
||||
export const BASE_WIDGET_VALIDATION = {
|
||||
isLoading: VALIDATION_TYPES.BOOLEAN,
|
||||
isVisible: VALIDATION_TYPES.BOOLEAN,
|
||||
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
||||
};
|
||||
|
||||
export type WidgetPropertyValidationType = Record<string, ValidationType>;
|
||||
|
||||
class ValidationFactory {
|
||||
|
|
|
|||
|
|
@ -84,20 +84,16 @@ export const VALIDATORS: Record<ValidationType, Validator> = {
|
|||
message: `${WIDGET_TYPE_VALIDATION_ERROR}: boolean`,
|
||||
};
|
||||
}
|
||||
let isValid = _.isBoolean(value);
|
||||
const isBoolean = _.isBoolean(value);
|
||||
const isStringTrueFalse = value === "true" || value === "false";
|
||||
const isValid = isBoolean || isStringTrueFalse;
|
||||
if (isStringTrueFalse) parsed = value !== "false";
|
||||
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,
|
||||
message: `${WIDGET_TYPE_VALIDATION_ERROR}: boolean`,
|
||||
};
|
||||
}
|
||||
return {
|
||||
isValid: isValid,
|
||||
parsed: parsed,
|
||||
message: `${WIDGET_TYPE_VALIDATION_ERROR}: boolean`,
|
||||
};
|
||||
}
|
||||
return { isValid, parsed };
|
||||
},
|
||||
|
|
@ -217,6 +213,15 @@ export const VALIDATORS: Record<ValidationType, Validator> = {
|
|||
return { isValid, parsed };
|
||||
},
|
||||
[VALIDATION_TYPES.DATE]: (value: any): ValidationResponse => {
|
||||
if (value === undefined) {
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0);
|
||||
return {
|
||||
isValid: false,
|
||||
parsed: today,
|
||||
message: `${WIDGET_TYPE_VALIDATION_ERROR}: Date`,
|
||||
};
|
||||
}
|
||||
const isValid = moment(value).isValid();
|
||||
const parsed = isValid ? moment(value).toDate() : new Date();
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ import {
|
|||
WidgetProps,
|
||||
WidgetDataProps,
|
||||
} from "widgets/BaseWidget";
|
||||
import { WidgetPropertyValidationType } from "./ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "./ValidationFactory";
|
||||
import React from "react";
|
||||
|
||||
type WidgetDerivedPropertyType = any;
|
||||
|
|
@ -78,7 +81,7 @@ class WidgetFactory {
|
|||
const map = this.widgetPropValidationMap.get(widgetType);
|
||||
if (!map) {
|
||||
console.error("Widget type validation is not defined");
|
||||
return {};
|
||||
return BASE_WIDGET_VALIDATION;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,10 @@ import { EditorContext } from "components/editorComponents/EditorContextProvider
|
|||
import { PositionTypes } from "constants/WidgetConstants";
|
||||
|
||||
import ErrorBoundary from "components/editorComponents/ErrorBoundry";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
BASE_WIDGET_VALIDATION,
|
||||
WidgetPropertyValidationType,
|
||||
} from "utils/ValidationFactory";
|
||||
import {
|
||||
DerivedPropertiesMap,
|
||||
TriggerPropertiesMap,
|
||||
|
|
@ -66,7 +69,7 @@ abstract class BaseWidget<
|
|||
// 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 {};
|
||||
return BASE_WIDGET_VALIDATION;
|
||||
}
|
||||
|
||||
static getDerivedPropertiesMap(): DerivedPropertiesMap {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import ButtonComponent, {
|
|||
ButtonType,
|
||||
} from "components/designSystems/blueprint/ButtonComponent";
|
||||
import { EventType } from "constants/ActionConstants";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { TriggerPropertiesMap } from "utils/WidgetFactory";
|
||||
|
||||
|
|
@ -30,9 +33,8 @@ class ButtonWidget extends BaseWidget<
|
|||
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
text: VALIDATION_TYPES.TEXT,
|
||||
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
||||
isVisible: VALIDATION_TYPES.BOOLEAN,
|
||||
buttonStyle: VALIDATION_TYPES.TEXT,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,16 @@ import { WidgetType } from "constants/WidgetConstants";
|
|||
import CheckboxComponent from "components/designSystems/blueprint/CheckboxComponent";
|
||||
import { EventType } from "constants/ActionConstants";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { TriggerPropertiesMap } from "utils/WidgetFactory";
|
||||
|
||||
class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
isDisabled: VALIDATION_TYPES.BOOLEAN,
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
label: VALIDATION_TYPES.TEXT,
|
||||
defaultCheckedState: VALIDATION_TYPES.BOOLEAN,
|
||||
};
|
||||
|
|
@ -34,18 +37,16 @@ class CheckboxWidget extends BaseWidget<CheckboxWidgetProps, WidgetState> {
|
|||
|
||||
componentDidUpdate(prevProps: CheckboxWidgetProps) {
|
||||
super.componentDidUpdate(prevProps);
|
||||
if (this.props.defaultCheckedState.toString()) {
|
||||
if (
|
||||
(this.props.isChecked !== prevProps.isChecked &&
|
||||
this.props.isChecked === undefined) ||
|
||||
this.props.defaultCheckedState.toString() !==
|
||||
prevProps.defaultCheckedState.toString()
|
||||
) {
|
||||
this.updateWidgetMetaProperty(
|
||||
"isChecked",
|
||||
this.props.defaultCheckedState,
|
||||
);
|
||||
}
|
||||
if (
|
||||
(this.props.isChecked !== prevProps.isChecked &&
|
||||
this.props.isChecked === undefined) ||
|
||||
this.props.defaultCheckedState.toString() !==
|
||||
prevProps.defaultCheckedState.toString()
|
||||
) {
|
||||
this.updateWidgetMetaProperty(
|
||||
"isChecked",
|
||||
this.props.defaultCheckedState,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
|||
import { WidgetType } from "constants/WidgetConstants";
|
||||
import { EventType } from "constants/ActionConstants";
|
||||
import DatePickerComponent from "components/designSystems/blueprint/DatePickerComponent";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import {
|
||||
DerivedPropertiesMap,
|
||||
|
|
@ -13,8 +16,8 @@ import {
|
|||
class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
defaultDate: VALIDATION_TYPES.DATE,
|
||||
selectedDate: VALIDATION_TYPES.DATE,
|
||||
timezone: VALIDATION_TYPES.TEXT,
|
||||
enableTimePicker: VALIDATION_TYPES.BOOLEAN,
|
||||
dateFormat: VALIDATION_TYPES.TEXT,
|
||||
|
|
@ -37,6 +40,21 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
|||
onDateSelected: true,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: DatePickerWidgetProps) {
|
||||
super.componentDidUpdate(prevProps);
|
||||
if (this.props.defaultDate) {
|
||||
if (
|
||||
(this.props.selectedDate !== prevProps.selectedDate &&
|
||||
this.props.selectedDate === undefined) ||
|
||||
this.props.defaultDate.toDateString() !==
|
||||
prevProps.defaultDate.toDateString()
|
||||
) {
|
||||
this.updateWidgetMetaProperty("selectedDate", this.props.defaultDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<DatePickerComponent
|
||||
|
|
@ -45,7 +63,6 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
|||
widgetId={this.props.widgetId}
|
||||
timezone={this.props.timezone}
|
||||
enableTimePicker={this.props.enableTimePicker}
|
||||
defaultDate={this.props.defaultDate}
|
||||
datePickerType={"DATE_PICKER"}
|
||||
onDateSelected={this.onDateSelected}
|
||||
selectedDate={this.props.selectedDate}
|
||||
|
|
@ -74,7 +91,7 @@ class DatePickerWidget extends BaseWidget<DatePickerWidgetProps, WidgetState> {
|
|||
export type DatePickerType = "DATE_PICKER" | "DATE_RANGE_PICKER";
|
||||
|
||||
export interface DatePickerWidgetProps extends WidgetProps {
|
||||
defaultDate?: Date;
|
||||
defaultDate: Date;
|
||||
selectedDate: Date;
|
||||
timezone?: string;
|
||||
enableTimePicker: boolean;
|
||||
|
|
|
|||
|
|
@ -4,19 +4,24 @@ import { WidgetType } from "constants/WidgetConstants";
|
|||
import { EventType } from "constants/ActionConstants";
|
||||
import DropDownComponent from "components/designSystems/blueprint/DropdownComponent";
|
||||
import _ from "lodash";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { TriggerPropertiesMap } from "utils/WidgetFactory";
|
||||
|
||||
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,
|
||||
selectedIndexArr: VALIDATION_TYPES.ARRAY,
|
||||
isRequired: VALIDATION_TYPES.BOOLEAN,
|
||||
defaultOptionValue: VALIDATION_TYPES.TEXT,
|
||||
};
|
||||
}
|
||||
static getDerivedPropertiesMap() {
|
||||
|
|
@ -60,7 +65,8 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
|||
) {
|
||||
this.updateWidgetMetaProperty("selectedIndex", undefined);
|
||||
this.updateWidgetMetaProperty("selectedIndexArr", []);
|
||||
} else if (this.props.defaultOptionValue) {
|
||||
}
|
||||
if (this.props.defaultOptionValue) {
|
||||
if (
|
||||
(this.props.selectedIndex !== prevProps.selectedIndex &&
|
||||
this.props.selectedIndex === undefined) ||
|
||||
|
|
@ -69,7 +75,11 @@ class DropdownWidget extends BaseWidget<DropdownWidgetProps, WidgetState> {
|
|||
const selectedIndex = _.findIndex(this.props.options, option => {
|
||||
return option.value === this.props.defaultOptionValue;
|
||||
});
|
||||
this.updateWidgetMetaProperty("selectedIndex", selectedIndex);
|
||||
if (selectedIndex > -1) {
|
||||
this.updateWidgetMetaProperty("selectedIndex", selectedIndex);
|
||||
} else {
|
||||
this.updateWidgetMetaProperty("selectedIndex", undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ import Webcam from "@uppy/webcam";
|
|||
import Url from "@uppy/url";
|
||||
import OneDrive from "@uppy/onedrive";
|
||||
import FilePickerComponent from "components/designSystems/appsmith/FilePickerComponent";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { EventType, ExecutionResult } from "constants/ActionConstants";
|
||||
import {
|
||||
|
|
@ -28,9 +31,11 @@ class FilePickerWidget extends BaseWidget<FilePickerWidgetProps, WidgetState> {
|
|||
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
label: VALIDATION_TYPES.TEXT,
|
||||
maxNumFiles: VALIDATION_TYPES.NUMBER,
|
||||
allowedFileTypes: VALIDATION_TYPES.ARRAY,
|
||||
files: VALIDATION_TYPES.ARRAY,
|
||||
isRequired: VALIDATION_TYPES.BOOLEAN,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import ButtonComponent, {
|
|||
ButtonType,
|
||||
} from "components/designSystems/blueprint/ButtonComponent";
|
||||
import { EventType, ExecutionResult } from "constants/ActionConstants";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
BASE_WIDGET_VALIDATION,
|
||||
WidgetPropertyValidationType,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { TriggerPropertiesMap } from "utils/WidgetFactory";
|
||||
|
||||
|
|
@ -30,10 +33,11 @@ class FormButtonWidget extends BaseWidget<
|
|||
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
text: VALIDATION_TYPES.TEXT,
|
||||
disabledWhenInvalid: VALIDATION_TYPES.BOOLEAN,
|
||||
isVisible: VALIDATION_TYPES.BOOLEAN,
|
||||
buttonStyle: VALIDATION_TYPES.TEXT,
|
||||
buttonType: VALIDATION_TYPES.TEXT,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@ import * as React from "react";
|
|||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||
import { WidgetType } from "constants/WidgetConstants";
|
||||
import ImageComponent from "components/designSystems/appsmith/ImageComponent";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import InputComponent, {
|
|||
InputComponentProps,
|
||||
} from "components/designSystems/blueprint/InputComponent";
|
||||
import { EventType } from "constants/ActionConstants";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { FIELD_REQUIRED_ERROR } from "constants/messages";
|
||||
import {
|
||||
|
|
@ -16,6 +19,7 @@ import {
|
|||
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,
|
||||
|
|
@ -30,7 +34,9 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
|||
inputValidators: VALIDATION_TYPES.ARRAY,
|
||||
focusIndex: VALIDATION_TYPES.NUMBER,
|
||||
isAutoFocusEnabled: VALIDATION_TYPES.BOOLEAN,
|
||||
onTextChanged: VALIDATION_TYPES.TEXT,
|
||||
isRequired: VALIDATION_TYPES.BOOLEAN,
|
||||
isValid: VALIDATION_TYPES.BOOLEAN,
|
||||
};
|
||||
}
|
||||
static getTriggerPropertyMap(): TriggerPropertiesMap {
|
||||
|
|
@ -59,20 +65,17 @@ class InputWidget extends BaseWidget<InputWidgetProps, WidgetState> {
|
|||
|
||||
componentDidMount() {
|
||||
super.componentDidMount();
|
||||
if (this.props.defaultText) {
|
||||
this.updateWidgetMetaProperty("text", this.props.defaultText);
|
||||
}
|
||||
const text = this.props.defaultText || "";
|
||||
this.updateWidgetMetaProperty("text", text);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: InputWidgetProps) {
|
||||
super.componentDidUpdate(prevProps);
|
||||
if (this.props.defaultText) {
|
||||
if (
|
||||
(this.props.text !== prevProps.text && this.props.text === undefined) ||
|
||||
this.props.defaultText !== prevProps.defaultText
|
||||
) {
|
||||
this.updateWidgetMetaProperty("text", this.props.defaultText);
|
||||
}
|
||||
if (
|
||||
(this.props.text !== prevProps.text && this.props.text === undefined) ||
|
||||
this.props.defaultText !== prevProps.defaultText
|
||||
) {
|
||||
this.updateWidgetMetaProperty("text", this.props.defaultText);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,16 +3,22 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
|||
import { WidgetType } from "constants/WidgetConstants";
|
||||
import RadioGroupComponent from "components/designSystems/blueprint/RadioGroupComponent";
|
||||
import { EventType } from "constants/ActionConstants";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { TriggerPropertiesMap } from "utils/WidgetFactory";
|
||||
|
||||
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,
|
||||
onSelectionChange: VALIDATION_TYPES.TEXT,
|
||||
defaultOptionValue: VALIDATION_TYPES.TEXT,
|
||||
isRequired: VALIDATION_TYPES.BOOLEAN,
|
||||
};
|
||||
}
|
||||
|
|
@ -41,17 +47,15 @@ class RadioGroupWidget extends BaseWidget<RadioGroupWidgetProps, WidgetState> {
|
|||
|
||||
componentDidUpdate(prevProps: RadioGroupWidgetProps) {
|
||||
super.componentDidUpdate(prevProps);
|
||||
if (this.props.defaultOptionValue) {
|
||||
if (
|
||||
(this.props.selectedOptionValue !== prevProps.selectedOptionValue &&
|
||||
this.props.selectedOptionValue === undefined) ||
|
||||
this.props.defaultOptionValue !== prevProps.defaultOptionValue
|
||||
) {
|
||||
this.updateWidgetMetaProperty(
|
||||
"selectedOptionValue",
|
||||
this.props.defaultOptionValue,
|
||||
);
|
||||
}
|
||||
if (
|
||||
(this.props.selectedOptionValue !== prevProps.selectedOptionValue &&
|
||||
this.props.selectedOptionValue === undefined) ||
|
||||
this.props.defaultOptionValue !== prevProps.defaultOptionValue
|
||||
) {
|
||||
this.updateWidgetMetaProperty(
|
||||
"selectedOptionValue",
|
||||
this.props.defaultOptionValue,
|
||||
);
|
||||
}
|
||||
}
|
||||
getPageView() {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,16 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
|||
import { WidgetType } from "constants/WidgetConstants";
|
||||
import { Intent } from "@blueprintjs/core";
|
||||
import SpinnerComponent from "components/designSystems/blueprint/SpinnerComponent";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
|
||||
class SpinnerWidget extends BaseWidget<SpinnerWidgetProps, WidgetState> {
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
size: VALIDATION_TYPES.NUMBER,
|
||||
value: VALIDATION_TYPES.NUMBER,
|
||||
ellipsize: VALIDATION_TYPES.BOOLEAN,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ import { forIn } from "lodash";
|
|||
import TableComponent from "components/designSystems/syncfusion/TableComponent";
|
||||
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
import { ColumnModel } from "@syncfusion/ej2-grids";
|
||||
import { ColumnDirTypecast } from "@syncfusion/ej2-react-grids";
|
||||
import { ColumnAction } from "components/propertyControls/ColumnActionSelectorControl";
|
||||
|
|
@ -30,6 +33,7 @@ function constructColumns(data: object[]): ColumnModel[] | ColumnDirTypecast[] {
|
|||
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,
|
||||
|
|
@ -156,11 +160,6 @@ class TableWidget extends BaseWidget<TableWidgetProps, WidgetState> {
|
|||
}
|
||||
}
|
||||
|
||||
type RowData = {
|
||||
rowIndex: number;
|
||||
};
|
||||
type SelectedRow = object & RowData;
|
||||
|
||||
export interface TableWidgetProps extends WidgetProps {
|
||||
nextPageKey?: string;
|
||||
prevPageKey?: string;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
|||
import { WidgetType } from "constants/WidgetConstants";
|
||||
import TextComponent from "components/designSystems/blueprint/TextComponent";
|
||||
import { VALIDATION_TYPES } from "constants/WidgetValidation";
|
||||
import { WidgetPropertyValidationType } from "utils/ValidationFactory";
|
||||
import {
|
||||
WidgetPropertyValidationType,
|
||||
BASE_WIDGET_VALIDATION,
|
||||
} from "utils/ValidationFactory";
|
||||
|
||||
const LINE_HEIGHTS: { [key in TextStyle]: number } = {
|
||||
// The following values are arrived at by multiplying line-height with font-size
|
||||
|
|
@ -16,9 +19,10 @@ const LINE_HEIGHTS: { [key in TextStyle]: number } = {
|
|||
class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
|
||||
static getPropertyValidationMap(): WidgetPropertyValidationType {
|
||||
return {
|
||||
...BASE_WIDGET_VALIDATION,
|
||||
text: VALIDATION_TYPES.TEXT,
|
||||
textStyle: VALIDATION_TYPES.TEXT,
|
||||
isVisible: VALIDATION_TYPES.BOOLEAN,
|
||||
shouldScroll: VALIDATION_TYPES.BOOLEAN,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user