diff --git a/app/client/src/api/ActionAPI.tsx b/app/client/src/api/ActionAPI.tsx index c5c0b4059c..76568925b8 100644 --- a/app/client/src/api/ActionAPI.tsx +++ b/app/client/src/api/ActionAPI.tsx @@ -1,7 +1,7 @@ import API, { HttpMethod } from "./Api"; import { ApiResponse } from "./ApiResponses"; import { APIRequest } from "./ApiRequests"; -import _ from "lodash"; +import { mapToPropList } from "../utils/AppsmithUtils"; export interface CreateActionRequest extends APIRequest { resourceId: string; @@ -48,7 +48,7 @@ export interface ActionCreateUpdateResponse extends ApiResponse { export interface ExecuteActionRequest extends APIRequest { actionId: string; - dynamicBindingMap: Record; + dynamicBindingList?: Property[]; } export interface ExecuteActionResponse extends ApiResponse { @@ -67,12 +67,8 @@ class ActionAPI extends API { httpMethod: apiConfig.method, path: apiConfig.path, body: apiConfig.body, - headers: _.map(apiConfig.requestHeaders, (value, key) => { - return { key: key, value: value }; - }), - queryParameters: _.map(apiConfig.queryParams, (value, key) => { - return { key: key, value: value }; - }), + headers: mapToPropList(apiConfig.requestHeaders), + queryParameters: mapToPropList(apiConfig.queryParams), }, }; return API.post(ActionAPI.url, createAPI); @@ -87,12 +83,8 @@ class ActionAPI extends API { httpMethod: apiConfig.method, path: apiConfig.path, body: apiConfig.body, - headers: _.map(apiConfig.requestHeaders, (value, key) => { - return { key: key, value: value }; - }), - queryParameters: _.map(apiConfig.queryParams, (value, key) => { - return { key: key, value: value }; - }), + headers: mapToPropList(apiConfig.requestHeaders), + queryParameters: mapToPropList(apiConfig.queryParams), }, }; return API.post(ActionAPI.url, updateAPI); @@ -113,7 +105,7 @@ class ActionAPI extends API { static executeAction( executeAction: ExecuteActionRequest, ): Promise { - return API.post(ActionAPI.url, executeAction); + return API.post(ActionAPI.url + "/execute", executeAction); } } diff --git a/app/client/src/api/Api.tsx b/app/client/src/api/Api.tsx index 3dc1825820..f4ef15a439 100644 --- a/app/client/src/api/Api.tsx +++ b/app/client/src/api/Api.tsx @@ -47,7 +47,7 @@ class Api { ); } - static post(url: string, queryParams?: any, body?: any) { + static post(url: string, body?: any, queryParams?: any) { return axiosInstance.post( url + this.convertObjectToQueryParams(queryParams), body, diff --git a/app/client/src/api/PageApi.tsx b/app/client/src/api/PageApi.tsx index 546a1ce1b8..51ca52c317 100644 --- a/app/client/src/api/PageApi.tsx +++ b/app/client/src/api/PageApi.tsx @@ -14,7 +14,7 @@ export interface SavePageRequest { } export interface PageLayout { - dsl: ContainerWidgetProps; + dsl: Partial>; actions: PageAction[]; } diff --git a/app/client/src/constants/ActionConstants.tsx b/app/client/src/constants/ActionConstants.tsx index 80d4f0bbc8..147baa1741 100644 --- a/app/client/src/constants/ActionConstants.tsx +++ b/app/client/src/constants/ActionConstants.tsx @@ -22,18 +22,11 @@ export type ActionType = | "DOWNLOAD"; export interface ActionPayload { + actionId: string; actionType: ActionType; contextParams: Record; } -export interface APIActionPayload extends ActionPayload { - apiId: string; -} - -export interface QueryActionPayload extends ActionPayload { - queryId: string; -} - export type NavigationType = "NEW_TAB" | "INLINE"; export interface NavigateActionPayload extends ActionPayload { @@ -71,5 +64,5 @@ export interface PageAction { actionId: string; actionType: ActionType; actionName: string; - dynamicBindings: string[]; + dynamicBindings?: string[]; } diff --git a/app/client/src/constants/ApiConstants.tsx b/app/client/src/constants/ApiConstants.tsx index 8e0e33b930..d98c885f6d 100644 --- a/app/client/src/constants/ApiConstants.tsx +++ b/app/client/src/constants/ApiConstants.tsx @@ -9,9 +9,8 @@ export type EncodingType = "gzip"; export const PROD_BASE_URL = "https://mobtools.com/api/"; export const MOCK_BASE_URL = "https://f78ff9dd-2c08-45f1-9bf9-8c670a1bb696.mock.pstmn.io"; -export const STAGE_BASE_URL = - "https://14157cb0-190f-4082-a791-886a8df05930.mock.pstmn.io"; -export const BASE_URL = MOCK_BASE_URL; +export const STAGE_BASE_URL = "https://appsmith-test.herokuapp.com"; +export const BASE_URL = STAGE_BASE_URL; export const REQUEST_TIMEOUT_MS = 2000; export const REQUEST_HEADERS: APIHeaders = { Accept: "application/json", diff --git a/app/client/src/constants/PropertyControlConstants.tsx b/app/client/src/constants/PropertyControlConstants.tsx index f6de8ad16e..527133dd72 100644 --- a/app/client/src/constants/PropertyControlConstants.tsx +++ b/app/client/src/constants/PropertyControlConstants.tsx @@ -7,4 +7,11 @@ export type ControlType = | "DATE_PICKER" | "DROP_DOWN" | "COLOR_PICKER" + | "TIMEZONE_PICKER" + | "ACTION_SELECTOR" + | "RECORD_ACTION_SELECTOR" + | "OPTION_INPUT" + | "IMAGE_PICKER" + | "SHAPE_PICKER" + | "VALIDATION_INPUT" | "ZOOM"; diff --git a/app/client/src/constants/ReduxActionConstants.tsx b/app/client/src/constants/ReduxActionConstants.tsx index cd8584ae92..c38570ac49 100644 --- a/app/client/src/constants/ReduxActionConstants.tsx +++ b/app/client/src/constants/ReduxActionConstants.tsx @@ -2,7 +2,7 @@ import { WidgetProps, WidgetCardProps } from "../widgets/BaseWidget"; export type ReduxActionType = - | "LOAD_CANVAS_WIDGETS" + | "UPDATE_CANVAS" | "FETCH_CANVAS" | "CLEAR_CANVAS" | "DROP_WIDGET_CANVAS" @@ -29,7 +29,7 @@ export type ReduxActionType = | "SHOW_PROPERTY_PANE"; export const ReduxActionTypes: { [id: string]: ReduxActionType } = { - LOAD_CANVAS_WIDGETS: "LOAD_CANVAS_WIDGETS", + UPDATE_CANVAS: "UPDATE_CANVAS", FETCH_CANVAS: "FETCH_CANVAS", CLEAR_CANVAS: "CLEAR_CANVAS", FETCH_PAGE: "FETCH_PAGE", diff --git a/app/client/src/constants/WidgetConstants.tsx b/app/client/src/constants/WidgetConstants.tsx index 097240b1ea..4de6424909 100644 --- a/app/client/src/constants/WidgetConstants.tsx +++ b/app/client/src/constants/WidgetConstants.tsx @@ -10,8 +10,7 @@ export type WidgetType = | "CHECKBOX_WIDGET" | "RADIO_GROUP_WIDGET" | "INPUT_WIDGET" - | "SWITCH_WIDGET" - | "ALERT_WIDGET"; + | "SWITCH_WIDGET"; export const WidgetTypes: { [id: string]: WidgetType } = { BUTTON_WIDGET: "BUTTON_WIDGET", @@ -26,7 +25,6 @@ export const WidgetTypes: { [id: string]: WidgetType } = { DROP_DOWN_WIDGET: "DROP_DOWN_WIDGET", CHECKBOX_WIDGET: "CHECKBOX_WIDGET", RADIO_GROUP_WIDGET: "RADIO_GROUP_WIDGET", - ALERT_WIDGET: "ALERT_WIDGET", }; export type ContainerOrientation = "HORIZONTAL" | "VERTICAL"; diff --git a/app/client/src/mockResponses/PageMockResponse.tsx b/app/client/src/mockResponses/PageMockResponse.tsx new file mode 100644 index 0000000000..8b85877166 --- /dev/null +++ b/app/client/src/mockResponses/PageMockResponse.tsx @@ -0,0 +1,44 @@ +import { PageResponse } from "../api/PageApi"; + +const PageMockResponse: PageResponse = { + responseMeta: { + responseCode: "SUCCESS", + }, + layout: { + dsl: { + widgetId: "0", + widgetType: "CONTAINER_WIDGET", + topRow: 2, + leftColumn: 2, + rightColumn: 10, + bottomRow: 10, + children: [ + { + widgetId: "1", + widgetType: "BUTTON_WIDGET", + topRow: 2, + leftColumn: 2, + text: "submit", + rightColumn: 10, + bottomRow: 10, + onClick: [ + { + actionId: "5d8082e2795dc6000482bc84", + actionType: "API", + }, + ], + }, + ], + }, + actions: [ + { + actionId: "5d8082e2795dc6000482bc84", + actionType: "API", + actionName: "getUsers", + dynamicBindings: ["$.apiData.0.name"], + }, + ], + }, +}; + +export default PageMockResponse; diff --git a/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx b/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx index 01efa1b491..57e07c31d0 100644 --- a/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx +++ b/app/client/src/mockResponses/PropertyPaneConfigResponse.tsx @@ -8,14 +8,14 @@ const PropertyPaneConfigResponse: PropertyPaneConfigState = { id: "1", children: [ { - id: "1", + id: "1.1", propertyName: "text", label: "Button Text", controlType: "INPUT_TEXT", placeholderText: "Enter button text here", }, { - id: "2", + id: "1.2", propertyName: "buttonStyle", label: "Button Style", controlType: "DROP_DOWN", @@ -24,18 +24,29 @@ const PropertyPaneConfigResponse: PropertyPaneConfigState = { { label: "Secondary Button", value: "SECONDARY_BUTTON" }, ], }, + { + id: "1.3", + propertyName: "isDisabled", + label: "Disabled", + controlType: "SWITCH", + }, + { + id: "1.4", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, ], }, { - sectionName: "Action", + sectionName: "Actions", id: "2", children: [ { - id: "3", - propertyName: "text", - label: "Button Text", - controlType: "INPUT_TEXT", - placeholderText: "Enter button text here", + id: "2.1", + propertyName: "onClick", + label: "onClick", + controlType: "ACTION_SELECTOR", }, ], }, @@ -44,84 +55,497 @@ const PropertyPaneConfigResponse: PropertyPaneConfigState = { { sectionName: "General", id: "3", - children: [], + children: [ + { + id: "3.1", + propertyName: "text", + label: "Text", + controlType: "INPUT_TEXT", + placeholderText: "Enter your text here", + }, + { + id: "3.2", + propertyName: "textStyle", + label: "Text Style", + controlType: "DROP_DOWN", + options: [ + { label: "Heading", value: "HEADING" }, + { label: "Label", value: "LABEL" }, + { label: "Body", value: "BODY" }, + { label: "Sub text", value: "SUB_TEXT" }, + ], + }, + { + id: "3.3", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], }, ], IMAGE_WIDGET: [ { sectionName: "General", id: "4", - children: [], + children: [ + { + id: "4.1", + propertyName: "image", + label: "Image", + controlType: "IMAGE_PICKER", + }, + { + id: "4.2", + propertyName: "defaultImage", + label: "Default Image", + controlType: "IMAGE_PICKER", + }, + { + id: "4.3", + propertyName: "imageShape", + label: "Shape", + controlType: "SHAPE_PICKER", + }, + { + id: "4.4", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], }, ], INPUT_WIDGET: [ { sectionName: "General", id: "5", - children: [], + children: [ + { + id: "5.1", + propertyName: "label", + label: "Label", + controlType: "INPUT_TEXT", + inputType: "TEXT", + placeholderText: "Label the widget", + }, + { + id: "5.2", + propertyName: "inputType", + label: "Data Type", + controlType: "DROP_DOWN", + options: [ + { label: "Text", value: "TEXT" }, + { label: "Number", value: "NUMBER" }, + { label: "Integer", value: "INTEGER" }, + { label: "Phone Number", value: "PHONE_NUMBER" }, + { label: "Email", value: "EMAIL" }, + { label: "Passwork", value: "PASSWORD" }, + { label: "Currency", value: "CURRENCY" }, + { label: "Search", value: "SEARCH" }, + ], + }, + { + id: "5.3", + propertyName: "placeholderText", + label: "Placeholder", + controlType: "INPUT_TEXT", + placeholderText: "Enter your text here", + }, + { + id: "5.4", + propertyName: "maxChars", + label: "Max Chars", + controlType: "INPUT_TEXT", + inputType: "INTEGER", + placeholderText: "Maximum character length", + }, + { + id: "5.5", + propertyName: "validators", + label: "Validators", + controlType: "VALIDATION_INPUT", + }, + { + id: "5.6", + children: [ + { + id: "5.6.1", + propertyName: "focusIndexx", + label: "Focus Index", + controlType: "INPUT_TEXT", + inputType: "INTEGER", + placeholderText: "Enter the order of tab focus", + }, + { + id: "5.6.2", + propertyName: "autoFocus", + label: "Auto Focus", + controlType: "SWITCH", + }, + ], + }, + { + id: "5.7", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + { + id: "5.8", + propertyName: "isDisabled", + label: "Disabled", + controlType: "SWITCH", + }, + ], }, ], SWITCH_WIDGET: [ { sectionName: "General", id: "6", - children: [], + children: [ + { + id: "6.1", + propertyName: "label", + label: "Label", + controlType: "INPUT_TEXT", + inputType: "TEXT", + placeholderText: "Label the widget", + }, + { + id: "6.2", + propertyName: "isOn", + label: "Default State", + controlType: "SWITCH", + }, + { + id: "6.3", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + { + id: "6.4", + propertyName: "isDisabled", + label: "Disabled", + controlType: "SWITCH", + }, + ], }, ], CONTAINER_WIDGET: [ { sectionName: "General", id: "7", - children: [], + children: [ + { + id: "7.1", + propertyName: "backgroundColor", + label: "Background Color", + controlType: "COLOR_PICKER", + }, + { + id: "6.3", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], }, ], SPINNER_WIDGET: [ { sectionName: "General", id: "8", - children: [], + children: [ + { + id: "8.1", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], }, ], DATE_PICKER_WIDGET: [ { sectionName: "General", id: "9", - children: [], + children: [ + { + id: "9.1", + propertyName: "datePickerType", + label: "Picker Type", + controlType: "DROP_DOWN", + options: [ + { label: "Single Date", value: "DATE_PICKER" }, + { label: "Date Range", value: "DATE_RANGE_PICKER" }, + ], + }, + { + id: "9.4", + propertyName: "label", + label: "Enter Date Label", + controlType: "INPUT_TEXT", + }, + { + id: "9.1", + propertyName: "defaultDate", + label: "Default Date", + controlType: "DATE_PICKER", + }, + { + id: "9.2", + propertyName: "defaultTimezone", + label: "Default Timezone", + controlType: "TIMEZONE_PICKER", + }, + { + id: "9.3", + propertyName: "enableTime", + label: "Enable Pick Time", + controlType: "SWITCH", + }, + { + id: "9.5", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + { + id: "9.6", + propertyName: "isDisabled", + label: "Disabled", + controlType: "SWITCH", + }, + ], + }, + { + sectionName: "Actions", + id: "10", + children: [ + { + id: "10.1", + propertyName: "onDateSelected", + label: "onDateSelected", + controlType: "ACTION_SELECTOR", + }, + { + id: "10.2", + propertyName: "onDateRangeSelected", + label: "onDateRangeSelected", + controlType: "ACTION_SELECTOR", + }, + ], }, ], TABLE_WIDGET: [ { sectionName: "General", - id: "9", - children: [], + id: "11", + children: [ + { + id: "11.1", + propertyName: "label", + label: "Enter Table Label", + controlType: "INPUT_TEXT", + }, + { + id: "11.2", + propertyName: "tableData", + label: "Enter data array", + controlType: "INPUT_TEXT", + }, + { + id: "11.3", + propertyName: "nextPageKey", + label: "Next Pagination Key", + controlType: "INPUT_TEXT", + }, + { + id: "11.4", + propertyName: "prevPageKey", + label: "Previous Pagination Key", + controlType: "INPUT_TEXT", + }, + { + id: "11.5", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], + }, + { + sectionName: "Actions", + id: "12", + children: [ + { + id: "12.1", + propertyName: "tableActions", + label: "Record action", + controlType: "RECORD_ACTION_SELECTOR", + }, + { + id: "12.2", + propertyName: "onRowSelected", + label: "onRowSelected", + controlType: "ACTION_SELECTOR", + }, + { + id: "12.3", + propertyName: "onPageChange", + label: "onPageChange", + controlType: "ACTION_SELECTOR", + }, + ], }, ], DROP_DOWN_WIDGET: [ { sectionName: "General", - id: "10", - children: [], + id: "13", + children: [ + { + id: "13.1", + propertyName: "type", + label: "Selection Type", + controlType: "DROP_DOWN", + options: [ + { label: "Single Select", value: "SINGLE_SELECT" }, + { label: "Multi Select", value: "MULTI_SELECT" }, + ], + }, + { + id: "13.2", + propertyName: "label", + label: "Label", + controlType: "INPUT_TEXT", + placeholderText: "Enter the label", + }, + { + id: "13.3", + propertyName: "placeholderText", + label: "Placeholder", + controlType: "INPUT_TEXT", + placeholderText: "Enter the placeholder", + }, + { + id: "13.4", + propertyName: "options", + label: "Options", + controlType: "OPTION_INPUT", + }, + { + id: "13.5", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], + }, + { + sectionName: "Actions", + id: "14", + children: [ + { + id: "14.1", + propertyName: "onOptionSelected", + label: "onOptionSelected", + controlType: "ACTION_SELECTOR", + }, + ], }, ], CHECKBOX_WIDGET: [ { sectionName: "General", - id: "11", - children: [], + id: "15", + children: [ + { + id: "15.1", + propertyName: "label", + label: "Label", + controlType: "INPUT_TEXT", + placeholderText: "Enter the label", + }, + { + id: "15.2", + propertyName: "defaultCheckedState", + label: "Default State", + controlType: "SWITCH", + }, + { + id: "13.5", + propertyName: "isDisabled", + label: "Disabled", + controlType: "SWITCH", + }, + { + id: "13.5", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], + }, + { + sectionName: "Actions", + id: "16", + children: [ + { + id: "16.1", + propertyName: "onCheckChange", + label: "onCheckChange", + controlType: "ACTION_SELECTOR", + }, + ], }, ], RADIO_GROUP_WIDGET: [ { sectionName: "General", - id: "12", - children: [], + id: "16", + children: [ + { + id: "16.1", + propertyName: "label", + label: "Label", + controlType: "INPUT_TEXT", + placeholderText: "Enter the label", + }, + { + id: "16.2", + propertyName: "defaultOptionValue", + label: "Default Selected Value", + controlType: "SWITCH", + }, + { + id: "16.3", + propertyName: "options", + label: "Options", + controlType: "OPTION_INPUT", + }, + { + id: "13.5", + propertyName: "isVisible", + label: "Visibile", + controlType: "SWITCH", + }, + ], }, - ], - ALERT_WIDGET: [ { - sectionName: "General", - id: "13", - children: [], + sectionName: "Actions", + id: "17", + children: [ + { + id: "17.1", + propertyName: "onOptionSelected", + label: "onOptionSelected", + controlType: "ACTION_SELECTOR", + }, + ], }, ], }, diff --git a/app/client/src/pages/Editor/PropertyPane.tsx b/app/client/src/pages/Editor/PropertyPane.tsx index 76aeca4be6..2467895364 100644 --- a/app/client/src/pages/Editor/PropertyPane.tsx +++ b/app/client/src/pages/Editor/PropertyPane.tsx @@ -37,11 +37,7 @@ class PropertyPane extends Component< } } - renderPropertySection( - propertySection: PropertySection, - key: string, - isHorizontal?: boolean, - ) { + renderPropertySection(propertySection: PropertySection, key: string) { return (
{!_.isNil(propertySection) ? ( @@ -51,7 +47,7 @@ class PropertyPane extends Component< )}
{ render() { @@ -19,6 +20,8 @@ class InputTextControl extends BaseControl { export interface InputControlProps extends ControlProps { placeholderText: string; + inputType: InputType; + isDisabled?: boolean; } export default InputTextControl; diff --git a/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx b/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx index 9b24b6ae58..fa7f9b3a8e 100644 --- a/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx +++ b/app/client/src/reducers/entityReducers/propertyPaneConfigReducer.tsx @@ -6,17 +6,22 @@ import { import PropertyPaneConfigResponse from "../../mockResponses/PropertyPaneConfigResponse"; import { InputControlProps } from "../../pages/propertyControls/InputTextControl"; import { DropDownControlProps } from "../../pages/propertyControls/DropDownControl"; +import { ControlProps } from "../../pages/propertyControls/BaseControl"; const initialState: PropertyPaneConfigState = PropertyPaneConfigResponse; export type ControlConfig = | InputControlProps | DropDownControlProps - | InputControlProps; + | InputControlProps + | ControlProps; + +export type SectionOrientation = "HORIZONTAL" | "VERTICAL"; export interface PropertySection { id: string; - sectionName: string; + sectionName?: string; + orientation?: SectionOrientation; children: (ControlConfig | PropertySection)[]; } @@ -34,7 +39,6 @@ export interface PropertyPaneConfigState { DROP_DOWN_WIDGET: PropertySection[]; CHECKBOX_WIDGET: PropertySection[]; RADIO_GROUP_WIDGET: PropertySection[]; - ALERT_WIDGET: PropertySection[]; }; configVersion: number; } diff --git a/app/client/src/sagas/ActionSagas.tsx b/app/client/src/sagas/ActionSagas.tsx index 3d85cc8404..7f9e11168d 100644 --- a/app/client/src/sagas/ActionSagas.tsx +++ b/app/client/src/sagas/ActionSagas.tsx @@ -3,16 +3,15 @@ import { ReduxAction, } from "../constants/ReduxActionConstants"; import { call, takeEvery, select, all } from "redux-saga/effects"; -import { - APIActionPayload, - QueryActionPayload, - PageAction, - ActionPayload, -} from "../constants/ActionConstants"; -import ActionAPI, { ActionCreateUpdateResponse } from "../api/ActionAPI"; +import { PageAction, ActionPayload } from "../constants/ActionConstants"; +import ActionAPI, { + ActionCreateUpdateResponse, + ExecuteActionRequest, +} from "../api/ActionAPI"; import { AppState } from "../reducers"; import { JSONPath } from "jsonpath-plus"; import _ from "lodash"; +import { mapToPropList } from "../utils/AppsmithUtils"; const getDataTree = (state: AppState) => { return state.entities; @@ -31,52 +30,37 @@ export function* evaluateJSONPathSaga(jsonPath: string): any { return result; } -export function* executeAPIActionSaga(apiAction: APIActionPayload) { - const api: PageAction = yield select(getAction, apiAction.apiId); - const responses: any = yield all( - api.dynamicBindings.map((jsonPath: string) => { - return call(evaluateJSONPathSaga, jsonPath); - }), - ); - const dynamicBindingMap: Record = _.keyBy( - responses, - (response: string, index: number) => { - return api.dynamicBindings[index]; - }, - ); - yield ActionAPI.executeAction({ - actionId: apiAction.apiId, - dynamicBindingMap: dynamicBindingMap, - }); -} - -export function* executeQueryActionSaga(queryAction: QueryActionPayload) { - const query: PageAction = yield select(getAction, queryAction.queryId); - const responses: any = yield all( - query.dynamicBindings.map((jsonPath: string) => { - return call(evaluateJSONPathSaga, jsonPath); - }), - ); - const dynamicBindingMap: Record = _.keyBy( - responses, - (response: string, index: number) => { - return query.dynamicBindings[index]; - }, - ); - yield ActionAPI.executeAction({ - actionId: query.actionId, - dynamicBindingMap: dynamicBindingMap, - }); +export function* executeAPIQueryActionSaga(apiAction: ActionPayload) { + const api: PageAction = yield select(getAction, apiAction.actionId); + const executeActionRequest: ExecuteActionRequest = { + actionId: apiAction.actionId, + }; + if (!_.isNil(api.dynamicBindings)) { + const responses: any = yield all( + api.dynamicBindings.map((jsonPath: string) => { + return call(evaluateJSONPathSaga, jsonPath); + }), + ); + const dynamicBindingMap: Record = _.keyBy( + responses, + (response: string, index: number) => { + return api.dynamicBindings ? api.dynamicBindings[index] : undefined; + }, + ); + executeActionRequest.dynamicBindingList = mapToPropList(dynamicBindingMap); + } + yield ActionAPI.executeAction(executeActionRequest); } export function* executeActionSaga(action: ReduxAction) { if (!_.isNil(action.payload)) { yield all( - action.payload.map((actionPayload: ActionPayload) => { + _.map(action.payload, (actionPayload: ActionPayload) => { switch (actionPayload.actionType) { case "API": - const apiActionPaylod: APIActionPayload = actionPayload as APIActionPayload; - return call(executeAPIActionSaga, apiActionPaylod); + return call(executeAPIQueryActionSaga, actionPayload); + case "QUERY": + return call(executeAPIQueryActionSaga, actionPayload); } return undefined; }), diff --git a/app/client/src/sagas/PageSagas.tsx b/app/client/src/sagas/PageSagas.tsx index cf03835f0f..79c1e91c83 100644 --- a/app/client/src/sagas/PageSagas.tsx +++ b/app/client/src/sagas/PageSagas.tsx @@ -24,7 +24,10 @@ export function* fetchPageSaga(pageRequestAction: ReduxAction) { widgets: normalizedResponse.entities.canvasWidgets, }; yield all([ - put({ type: ReduxActionTypes.UPDATE_CANVAS, canvasWidgetsPayload }), + put({ + type: ReduxActionTypes.UPDATE_CANVAS, + payload: canvasWidgetsPayload, + }), put({ type: ReduxActionTypes.LOAD_CANVAS_ACTIONS, payload: pageResponse.layout.actions, diff --git a/app/client/src/utils/AppsmithUtils.tsx b/app/client/src/utils/AppsmithUtils.tsx index 801bd4c34c..af48741e0f 100644 --- a/app/client/src/utils/AppsmithUtils.tsx +++ b/app/client/src/utils/AppsmithUtils.tsx @@ -11,6 +11,8 @@ import netlifyIdentity from "netlify-identity-widget"; import FontFaceObserver from "fontfaceobserver"; import PropertyControlRegistry from "./PropertyControlRegistry"; import WidgetBuilderRegistry from "./WidgetRegistry"; +import { Property } from "../api/ActionAPI"; +import _ from "lodash"; export const createReducer = ( initialState: any, @@ -52,3 +54,9 @@ export const appInitializer = () => { console.log(err); }); }; + +export const mapToPropList = (map: Record): Property[] => { + return _.map(map, (value, key) => { + return { key: key, value: value }; + }); +}; diff --git a/app/client/src/widgets/AlertWidget.tsx b/app/client/src/widgets/AlertWidget.tsx index e4b24d8518..d6e50380e3 100644 --- a/app/client/src/widgets/AlertWidget.tsx +++ b/app/client/src/widgets/AlertWidget.tsx @@ -1,16 +1,12 @@ -import React from "react"; +import React, { Component } from "react"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; import { WidgetType } from "../constants/WidgetConstants"; import { ActionPayload } from "../constants/ActionConstants"; -class AlertWidget extends BaseWidget { +class AlertWidget extends Component { getPageView() { return
; } - - getWidgetType(): WidgetType { - return "ALERT_WIDGET"; - } } export type AlertType = "DIALOG" | "NOTIFICATION"; diff --git a/app/client/src/widgets/ButtonWidget.tsx b/app/client/src/widgets/ButtonWidget.tsx index 8fe7cfb350..63e4a04c92 100644 --- a/app/client/src/widgets/ButtonWidget.tsx +++ b/app/client/src/widgets/ButtonWidget.tsx @@ -38,6 +38,7 @@ export interface ButtonWidgetProps extends WidgetProps { text?: string; buttonStyle?: ButtonStyle; onClick?: ActionPayload[]; + isDisabled?: boolean; } export default ButtonWidget; diff --git a/app/client/src/widgets/DatePickerWidget.tsx b/app/client/src/widgets/DatePickerWidget.tsx index f4c9b7a108..8e0d5e056a 100644 --- a/app/client/src/widgets/DatePickerWidget.tsx +++ b/app/client/src/widgets/DatePickerWidget.tsx @@ -19,7 +19,7 @@ export type DatePickerType = "DATE_PICKER" | "DATE_RANGE_PICKER"; export interface DatePickerWidgetProps extends WidgetProps { defaultDate?: Date; - timezone?: TimeZone; + defaultTimezone?: TimeZone; enableTime: boolean; label: string; datePickerType: DatePickerType; diff --git a/app/client/src/widgets/DropdownWidget.tsx b/app/client/src/widgets/DropdownWidget.tsx index 0678814162..bc62abdf23 100644 --- a/app/client/src/widgets/DropdownWidget.tsx +++ b/app/client/src/widgets/DropdownWidget.tsx @@ -20,7 +20,7 @@ export interface DropdownOption { } export interface DropdownWidgetProps extends WidgetProps { - placeholder?: string; + placeholderText?: string; label?: string; type: SelectionType; options?: DropdownOption[]; diff --git a/app/client/src/widgets/InputWidget.tsx b/app/client/src/widgets/InputWidget.tsx index f6a836c9f7..13ec32403e 100644 --- a/app/client/src/widgets/InputWidget.tsx +++ b/app/client/src/widgets/InputWidget.tsx @@ -22,13 +22,19 @@ export type InputType = | "CURRENCY" | "SEARCH"; +export interface InputValidator { + validationRegex: string; + errorMessage: string; +} export interface InputWidgetProps extends WidgetProps { - errorMessage?: string; inputType: InputType; defaultText?: string; - placeholder?: string; + placeholderText?: string; + maxChars?: number; label: string; + inputValidators: InputValidator[]; focusIndex?: number; + isAutoFocusEnabled?: boolean; } export default InputWidget; diff --git a/app/client/src/widgets/TableWidget.tsx b/app/client/src/widgets/TableWidget.tsx index baea6ea7be..fb82b32237 100644 --- a/app/client/src/widgets/TableWidget.tsx +++ b/app/client/src/widgets/TableWidget.tsx @@ -15,13 +15,18 @@ class TableWidget extends BaseWidget { export type PaginationType = "PAGES" | "INFINITE_SCROLL"; +export interface TableAction extends ActionPayload { + actionName: string; +} + export interface TableWidgetProps extends WidgetProps { - pageKey?: string; + nextPageKey?: string; + prevPageKey?: string; label: string; tableData?: object[]; + recordActions?: TableAction[]; onPageChange?: ActionPayload[]; onRowSelected?: ActionPayload[]; - onColumnActionClick?: Record; } export default TableWidget; diff --git a/app/client/src/widgets/TextWidget.tsx b/app/client/src/widgets/TextWidget.tsx index fcf3f24249..f75bff2254 100644 --- a/app/client/src/widgets/TextWidget.tsx +++ b/app/client/src/widgets/TextWidget.tsx @@ -11,7 +11,6 @@ class TextWidget extends BaseWidget { widgetId={this.props.widgetId} key={this.props.widgetId} text={this.props.text} - tagName={this.props.tagName} /> ); } @@ -26,7 +25,6 @@ export type TextStyle = "BODY" | "HEADING" | "LABEL" | "SUB_TEXT"; export interface TextWidgetProps extends WidgetProps { text?: string; textStyle?: TextStyle; - tagName?: keyof JSX.IntrinsicElements; } export default TextWidget;