Merge branch 'feature/actions' into 'release'
Feature/actions See merge request theappsmith/internal-tools-client!22
This commit is contained in:
commit
d19c747228
|
|
@ -77,9 +77,11 @@
|
|||
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||
"@typescript-eslint/parser": "^2.0.0",
|
||||
"dotenv": "^8.1.0",
|
||||
"eslint": "^6.4.0",
|
||||
"eslint-config-prettier": "^6.1.0",
|
||||
"eslint-config-react": "^1.1.7",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"eslint-plugin-react": "^7.14.3",
|
||||
"icon-font-generator": "^2.1.10",
|
||||
"redux-devtools": "^3.5.0"
|
||||
},
|
||||
|
|
|
|||
14
app/client/src/actions/widgetActions.tsx
Normal file
14
app/client/src/actions/widgetActions.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxAction,
|
||||
} from "../constants/ReduxActionConstants";
|
||||
import { ActionPayload } from "../constants/ActionConstants";
|
||||
|
||||
export const executeAction = (
|
||||
actionPayloads?: ActionPayload[],
|
||||
): ReduxAction<ActionPayload[] | undefined> => {
|
||||
return {
|
||||
type: ReduxActionTypes.EXECUTE_ACTION,
|
||||
payload: actionPayloads,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,71 +1,120 @@
|
|||
import Api, { HttpMethod } from "./Api"
|
||||
import { ApiResponse } from "./ApiResponses"
|
||||
import { APIRequest } from './ApiRequests';
|
||||
import API, { HttpMethod } from "./Api";
|
||||
import { ApiResponse } from "./ApiResponses";
|
||||
import { APIRequest } from "./ApiRequests";
|
||||
import _ from "lodash";
|
||||
|
||||
export interface CreateActionRequest<T> extends APIRequest {
|
||||
resourceId: string
|
||||
actionConfiguration: T
|
||||
resourceId: string;
|
||||
actionName: string;
|
||||
actionConfiguration: T;
|
||||
}
|
||||
|
||||
export interface UpdateActionRequest<T> extends CreateActionRequest<T> {
|
||||
actionId: string
|
||||
actionId: string;
|
||||
}
|
||||
|
||||
export interface APIConfig {
|
||||
requestHeaders: Record<string, string>
|
||||
method: HttpMethod
|
||||
path: string
|
||||
APIName: string
|
||||
body: JSON
|
||||
queryParams: Record<string, string>
|
||||
resourceId: string;
|
||||
actionName: string;
|
||||
requestHeaders: Record<string, string>;
|
||||
method: HttpMethod;
|
||||
path: string;
|
||||
body: JSON;
|
||||
queryParams: Record<string, string>;
|
||||
actionId: string;
|
||||
}
|
||||
|
||||
export interface Property {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface APIConfigRequest {
|
||||
headers: Property[];
|
||||
httpMethod: HttpMethod;
|
||||
path: string;
|
||||
body: JSON;
|
||||
queryParameters: Property[];
|
||||
}
|
||||
|
||||
export interface QueryConfig {
|
||||
queryString: string
|
||||
queryString: string;
|
||||
}
|
||||
|
||||
export interface ActionCreatedResponse extends ApiResponse {
|
||||
actionId: string
|
||||
dynamicBindingMap: Record<string, string>
|
||||
}
|
||||
|
||||
export interface ActionUpdatedResponse extends ActionCreatedResponse {
|
||||
|
||||
export interface ActionCreateUpdateResponse extends ApiResponse {
|
||||
actionId: string;
|
||||
dynamicBindingMap: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface ExecuteActionRequest extends APIRequest {
|
||||
actionId: string
|
||||
dynamicBindingMap: Record<string, any>
|
||||
actionId: string;
|
||||
dynamicBindingMap: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface ExecuteActionResponse extends ApiResponse {
|
||||
actionId: string
|
||||
data: any
|
||||
actionId: string;
|
||||
data: any;
|
||||
}
|
||||
|
||||
class ActionAPI extends Api {
|
||||
static url = "/actions"
|
||||
|
||||
static createAPI(createAPI: CreateActionRequest<APIConfig>): Promise<ActionCreatedResponse> {
|
||||
return Api.post(ActionAPI.url, createAPI)
|
||||
class ActionAPI extends API {
|
||||
static url = "v1/actions";
|
||||
|
||||
static createAPI(apiConfig: APIConfig): Promise<ActionCreateUpdateResponse> {
|
||||
const createAPI: CreateActionRequest<APIConfigRequest> = {
|
||||
resourceId: apiConfig.resourceId,
|
||||
actionName: apiConfig.actionName,
|
||||
actionConfiguration: {
|
||||
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 };
|
||||
}),
|
||||
},
|
||||
};
|
||||
return API.post(ActionAPI.url, createAPI);
|
||||
}
|
||||
|
||||
static updateAPI(updateAPI: UpdateActionRequest<APIConfig>): Promise<ActionUpdatedResponse> {
|
||||
return Api.post(ActionAPI.url, updateAPI)
|
||||
static updateAPI(apiConfig: APIConfig): Promise<ActionCreateUpdateResponse> {
|
||||
const updateAPI: UpdateActionRequest<APIConfigRequest> = {
|
||||
resourceId: apiConfig.resourceId,
|
||||
actionName: apiConfig.actionName,
|
||||
actionId: apiConfig.actionId,
|
||||
actionConfiguration: {
|
||||
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 };
|
||||
}),
|
||||
},
|
||||
};
|
||||
return API.post(ActionAPI.url, updateAPI);
|
||||
}
|
||||
|
||||
static createQuery(createQuery: CreateActionRequest<QueryConfig>): Promise<ActionCreatedResponse> {
|
||||
return Api.post(ActionAPI.url, createQuery)
|
||||
static createQuery(
|
||||
createQuery: CreateActionRequest<QueryConfig>,
|
||||
): Promise<ActionCreateUpdateResponse> {
|
||||
return API.post(ActionAPI.url, createQuery);
|
||||
}
|
||||
|
||||
static updateQuery(updateQuery: UpdateActionRequest<QueryConfig>): Promise<ActionUpdatedResponse> {
|
||||
return Api.post(ActionAPI.url, updateQuery)
|
||||
static updateQuery(
|
||||
updateQuery: UpdateActionRequest<QueryConfig>,
|
||||
): Promise<ActionCreateUpdateResponse> {
|
||||
return API.post(ActionAPI.url, updateQuery);
|
||||
}
|
||||
|
||||
static executeAction(executeAction: ExecuteActionRequest): Promise<ActionUpdatedResponse> {
|
||||
return Api.post(ActionAPI.url, executeAction)
|
||||
static executeAction(
|
||||
executeAction: ExecuteActionRequest,
|
||||
): Promise<ActionCreateUpdateResponse> {
|
||||
return API.post(ActionAPI.url, executeAction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ActionAPI
|
||||
export default ActionAPI;
|
||||
|
|
|
|||
|
|
@ -1,75 +1,75 @@
|
|||
import { AlertType, MessageIntent } from "../widgets/AlertWidget";
|
||||
|
||||
export type EventType =
|
||||
| "ON_CLICK"
|
||||
| "ON_HOVER"
|
||||
| "ON_TOGGLE"
|
||||
| "ON_LOAD"
|
||||
| "ON_TEXT_CHANGE"
|
||||
| "ON_SUBMIT"
|
||||
| "ON_CHECK_CHANGE"
|
||||
| "ON_SELECT"
|
||||
| "ON_DATE_SELECTED"
|
||||
| "ON_DATE_RANGE_SELECTED"
|
||||
export type EventType =
|
||||
| "ON_CLICK"
|
||||
| "ON_HOVER"
|
||||
| "ON_TOGGLE"
|
||||
| "ON_LOAD"
|
||||
| "ON_TEXT_CHANGE"
|
||||
| "ON_SUBMIT"
|
||||
| "ON_CHECK_CHANGE"
|
||||
| "ON_SELECT"
|
||||
| "ON_DATE_SELECTED"
|
||||
| "ON_DATE_RANGE_SELECTED";
|
||||
|
||||
export type ActionType =
|
||||
export type ActionType =
|
||||
| "API"
|
||||
| "QUERY"
|
||||
| "NAVIGATION"
|
||||
| "ALERT"
|
||||
| "JS_FUNCTION"
|
||||
| "SET_VALUE"
|
||||
| "DOWNLOAD"
|
||||
| "QUERY"
|
||||
| "NAVIGATION"
|
||||
| "ALERT"
|
||||
| "JS_FUNCTION"
|
||||
| "SET_VALUE"
|
||||
| "DOWNLOAD";
|
||||
|
||||
export interface ActionPayload {
|
||||
actionType: ActionType
|
||||
contextParams: Record<string, string>
|
||||
actionType: ActionType;
|
||||
contextParams: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface APIActionPayload extends ActionPayload {
|
||||
apiId: string
|
||||
apiId: string;
|
||||
}
|
||||
|
||||
export interface QueryActionPayload extends ActionPayload {
|
||||
queryId: string
|
||||
queryId: string;
|
||||
}
|
||||
|
||||
export type NavigationType = "NEW_TAB" | "INLINE"
|
||||
export type NavigationType = "NEW_TAB" | "INLINE";
|
||||
|
||||
export interface NavigateActionPayload extends ActionPayload {
|
||||
pageUrl: string
|
||||
navigationType: NavigationType
|
||||
pageUrl: string;
|
||||
navigationType: NavigationType;
|
||||
}
|
||||
|
||||
export interface ShowAlertActionPayload extends ActionPayload {
|
||||
header: string
|
||||
message: string
|
||||
alertType: AlertType
|
||||
intent: MessageIntent
|
||||
header: string;
|
||||
message: string;
|
||||
alertType: AlertType;
|
||||
intent: MessageIntent;
|
||||
}
|
||||
|
||||
export interface SetValueActionPayload extends ActionPayload {
|
||||
header: string
|
||||
message: string
|
||||
alertType: AlertType
|
||||
intent: MessageIntent
|
||||
header: string;
|
||||
message: string;
|
||||
alertType: AlertType;
|
||||
intent: MessageIntent;
|
||||
}
|
||||
|
||||
export interface ExecuteJSActionPayload extends ActionPayload {
|
||||
jsFunctionId: string
|
||||
jsFunctionId: string;
|
||||
}
|
||||
|
||||
export type DownloadFiletype = "CSV" | "XLS" | "JSON" | "TXT"
|
||||
export type DownloadFiletype = "CSV" | "XLS" | "JSON" | "TXT";
|
||||
|
||||
export interface DownloadDataActionPayload extends ActionPayload {
|
||||
data: JSON
|
||||
fileName: string
|
||||
fileType: DownloadFiletype
|
||||
data: JSON;
|
||||
fileName: string;
|
||||
fileType: DownloadFiletype;
|
||||
}
|
||||
|
||||
export interface PageAction {
|
||||
actionId: string
|
||||
actionType: ActionType
|
||||
actionName: string
|
||||
dynamicBindings: string[]
|
||||
}
|
||||
actionId: string;
|
||||
actionType: ActionType;
|
||||
actionName: string;
|
||||
dynamicBindings: string[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ class ButtonComponent extends React.Component<ButtonComponentProps> {
|
|||
render() {
|
||||
return (
|
||||
<Container {...this.props}>
|
||||
<Button icon={this.props.icon}>{this.props.text}</Button>
|
||||
<Button icon={this.props.icon} onClick={this.props.onClick}>
|
||||
{this.props.text}
|
||||
</Button>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
@ -15,6 +17,7 @@ class ButtonComponent extends React.Component<ButtonComponentProps> {
|
|||
|
||||
interface ButtonComponentProps extends TextComponentProps {
|
||||
icon?: MaybeElement;
|
||||
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
export default ButtonComponent;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import WidgetFactory from "../../utils/WidgetFactory";
|
||||
import { WidgetTypes } from "../../constants/WidgetConstants";
|
||||
import { WidgetTypes, RenderModes } from "../../constants/WidgetConstants";
|
||||
import { WidgetFunctions } from "../../widgets/BaseWidget";
|
||||
import { useDrop } from "react-dnd";
|
||||
import { ContainerWidgetProps } from "../../widgets/ContainerWidget";
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ const ArtBoard = styled.div`
|
|||
interface CanvasProps {
|
||||
pageWidget: ContainerWidgetProps<any>;
|
||||
addWidget: Function;
|
||||
widgetFunctions: WidgetFunctions;
|
||||
}
|
||||
|
||||
const Canvas = (props: CanvasProps) => {
|
||||
|
|
@ -25,7 +27,12 @@ const Canvas = (props: CanvasProps) => {
|
|||
return (
|
||||
<React.Fragment>
|
||||
<ArtBoard ref={drop}>
|
||||
{props.pageWidget && WidgetFactory.createWidget(props.pageWidget)}
|
||||
{props.pageWidget &&
|
||||
WidgetFactory.createWidget(
|
||||
props.pageWidget,
|
||||
props.widgetFunctions,
|
||||
RenderModes.CANVAS,
|
||||
)}
|
||||
</ArtBoard>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { XYCoord, useDragLayer } from "react-dnd";
|
|||
import snapToGrid from "./snapToGrid";
|
||||
import WidgetFactory from "../../utils/WidgetFactory";
|
||||
import { RenderModes, WidgetType } from "../../constants/WidgetConstants";
|
||||
import { ActionPayload } from "../../constants/ActionConstants";
|
||||
|
||||
const WrappedDragLayer = styled.div`
|
||||
position: absolute;
|
||||
|
|
@ -57,18 +58,21 @@ const EditorDragLayer: React.FC = () => {
|
|||
}));
|
||||
|
||||
function renderItem() {
|
||||
return WidgetFactory.createWidget({
|
||||
widgetType: itemType as WidgetType,
|
||||
widgetName: "",
|
||||
widgetId: item.key,
|
||||
topRow: 10,
|
||||
leftColumn: 10,
|
||||
bottomRow: 14,
|
||||
rightColumn: 20,
|
||||
parentColumnSpace: 1,
|
||||
parentRowSpace: 1,
|
||||
renderMode: RenderModes.CANVAS,
|
||||
});
|
||||
return WidgetFactory.createWidget(
|
||||
{
|
||||
widgetType: itemType as WidgetType,
|
||||
widgetName: "",
|
||||
widgetId: item.key,
|
||||
topRow: 10,
|
||||
leftColumn: 10,
|
||||
bottomRow: 14,
|
||||
rightColumn: 20,
|
||||
parentColumnSpace: 1,
|
||||
parentRowSpace: 1,
|
||||
},
|
||||
{ executeAction: (actionPayload?: ActionPayload[]) => {} },
|
||||
RenderModes.CANVAS,
|
||||
);
|
||||
}
|
||||
|
||||
if (!isDragging) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import EditorHeader from "./EditorHeader";
|
|||
import CanvasWidgetsNormalizer from "../../normalizers/CanvasWidgetsNormalizer";
|
||||
import { ContainerWidgetProps } from "../../widgets/ContainerWidget";
|
||||
import { fetchPage, addWidget } from "../../actions/pageActions";
|
||||
import { executeAction } from "../../actions/widgetActions";
|
||||
import { RenderModes } from "../../constants/WidgetConstants";
|
||||
import { ActionPayload } from "../../constants/ActionConstants";
|
||||
|
||||
const CanvasContainer = styled.section`
|
||||
height: 100%;
|
||||
|
|
@ -44,6 +46,7 @@ const EditorWrapper = styled.div`
|
|||
type EditorProps = {
|
||||
pageWidget: ContainerWidgetProps<any> | any;
|
||||
fetchCanvasWidgets: Function;
|
||||
executeAction: (actionPayloads?: ActionPayload[]) => void;
|
||||
cards: { [id: string]: WidgetCardProps[] } | any;
|
||||
addPageWidget: Function;
|
||||
page: string;
|
||||
|
|
@ -66,6 +69,7 @@ class Editor extends Component<EditorProps> {
|
|||
<Canvas
|
||||
pageWidget={this.props.pageWidget}
|
||||
addWidget={this.addWidgetToCanvas}
|
||||
widgetFunctions={{ executeAction: this.props.executeAction }}
|
||||
/>
|
||||
</CanvasContainer>
|
||||
</EditorWrapper>
|
||||
|
|
@ -87,6 +91,8 @@ const mapStateToProps = (state: AppState): EditorReduxState => {
|
|||
|
||||
const mapDispatchToProps = (dispatch: any) => {
|
||||
return {
|
||||
executeAction: (actionPayloads?: ActionPayload[]) =>
|
||||
dispatch(executeAction(actionPayloads)),
|
||||
fetchCanvasWidgets: (pageId: string) =>
|
||||
dispatch(fetchPage(pageId, RenderModes.CANVAS)),
|
||||
addPageWidget: (pageId: string, widgetProps: WidgetProps) =>
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
import { createReducer } from "../../utils/AppsmithUtils"
|
||||
import { createReducer } from "../../utils/AppsmithUtils";
|
||||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxAction,
|
||||
} from "../../constants/ReduxActionConstants"
|
||||
import _ from "lodash"
|
||||
import { ActionCreatedResponse } from '../../api/ActionAPI'
|
||||
import { PageAction } from '../../constants/ActionConstants';
|
||||
} from "../../constants/ReduxActionConstants";
|
||||
import _ from "lodash";
|
||||
import { ActionCreateUpdateResponse } from "../../api/ActionAPI";
|
||||
import { PageAction } from "../../constants/ActionConstants";
|
||||
|
||||
const initialState: ActionDataState = {
|
||||
|
||||
}
|
||||
const initialState: ActionDataState = {};
|
||||
|
||||
export interface ActionDataState {
|
||||
[name: string]: ActionCreatedResponse
|
||||
[name: string]: ActionCreateUpdateResponse;
|
||||
}
|
||||
|
||||
const actionsReducer = createReducer(initialState, {
|
||||
[ReduxActionTypes.LOAD_CANVAS_ACTIONS]: (
|
||||
state: ActionDataState,
|
||||
action: ReduxAction<PageAction[]>
|
||||
action: ReduxAction<PageAction[]>,
|
||||
) => {
|
||||
const actionMap = _.mapKeys(action.payload, (action: PageAction) => { return action.actionId })
|
||||
return { ...state, ...actionMap }
|
||||
}
|
||||
})
|
||||
const actionMap = _.mapKeys(action.payload, (action: PageAction) => {
|
||||
return action.actionId;
|
||||
});
|
||||
return { ...state, ...actionMap };
|
||||
},
|
||||
});
|
||||
|
||||
export default actionsReducer
|
||||
export default actionsReducer;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
import CanvasWidgetsNormalizer from "../normalizers/CanvasWidgetsNormalizer";
|
||||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxAction,
|
||||
} from "../constants/ReduxActionConstants";
|
||||
import PageApi, { PageResponse, PageRequest } from "../api/PageApi";
|
||||
import { call, put, takeEvery, select, all } from "redux-saga/effects";
|
||||
import { RenderModes } from "../constants/WidgetConstants";
|
||||
import { call, takeEvery, select, all } from "redux-saga/effects";
|
||||
import {
|
||||
APIActionPayload,
|
||||
QueryActionPayload,
|
||||
PageAction,
|
||||
ActionPayload,
|
||||
} from "../constants/ActionConstants";
|
||||
import ActionAPI, { ActionCreatedResponse } from "../api/ActionAPI";
|
||||
import ActionAPI, { ActionCreateUpdateResponse } from "../api/ActionAPI";
|
||||
import { AppState } from "../reducers";
|
||||
import { JSONPath } from "jsonpath-plus";
|
||||
import _ from "lodash";
|
||||
|
|
@ -23,21 +21,21 @@ const getDataTree = (state: AppState) => {
|
|||
const getAction = (
|
||||
state: AppState,
|
||||
actionId: string,
|
||||
): ActionCreatedResponse => {
|
||||
): ActionCreateUpdateResponse => {
|
||||
return state.entities.actions[actionId];
|
||||
};
|
||||
|
||||
export function* evaluateJSONPath(jsonPath: string): any {
|
||||
export function* evaluateJSONPathSaga(jsonPath: string): any {
|
||||
const dataTree = yield select(getDataTree);
|
||||
const result = JSONPath({ path: jsonPath, json: dataTree });
|
||||
return result;
|
||||
}
|
||||
|
||||
export function* executeAPIAction(apiAction: APIActionPayload) {
|
||||
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(evaluateJSONPath, jsonPath);
|
||||
return call(evaluateJSONPathSaga, jsonPath);
|
||||
}),
|
||||
);
|
||||
const dynamicBindingMap: Record<string, any> = _.keyBy(
|
||||
|
|
@ -52,11 +50,11 @@ export function* executeAPIAction(apiAction: APIActionPayload) {
|
|||
});
|
||||
}
|
||||
|
||||
export function* executeQueryAction(queryAction: QueryActionPayload) {
|
||||
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(evaluateJSONPath, jsonPath);
|
||||
return call(evaluateJSONPathSaga, jsonPath);
|
||||
}),
|
||||
);
|
||||
const dynamicBindingMap: Record<string, any> = _.keyBy(
|
||||
|
|
@ -71,28 +69,21 @@ export function* executeQueryAction(queryAction: QueryActionPayload) {
|
|||
});
|
||||
}
|
||||
|
||||
export function* executeAction(pageRequestAction: ReduxAction<PageRequest>) {
|
||||
const pageRequest = pageRequestAction.payload;
|
||||
try {
|
||||
const pageResponse: PageResponse = yield call(
|
||||
PageApi.fetchPage,
|
||||
pageRequest,
|
||||
export function* executeActionSaga(action: ReduxAction<ActionPayload[]>) {
|
||||
if (!_.isNil(action.payload)) {
|
||||
yield all(
|
||||
action.payload.map((actionPayload: ActionPayload) => {
|
||||
switch (actionPayload.actionType) {
|
||||
case "API":
|
||||
const apiActionPaylod: APIActionPayload = actionPayload as APIActionPayload;
|
||||
return call(executeAPIActionSaga, apiActionPaylod);
|
||||
}
|
||||
return undefined;
|
||||
}),
|
||||
);
|
||||
if (pageRequest.renderMode === RenderModes.CANVAS) {
|
||||
const normalizedResponse = CanvasWidgetsNormalizer.normalize(
|
||||
pageResponse,
|
||||
);
|
||||
const payload = {
|
||||
pageWidgetId: normalizedResponse.result,
|
||||
widgets: normalizedResponse.entities.canvasWidgets,
|
||||
};
|
||||
yield put({ type: ReduxActionTypes.UPDATE_CANVAS, payload });
|
||||
}
|
||||
} catch (err) {
|
||||
//TODO(abhinav): REFACTOR THIS
|
||||
}
|
||||
}
|
||||
|
||||
export function* watchExecuteAction() {
|
||||
yield takeEvery(ReduxActionTypes.EXECUTE_ACTION, executeAction);
|
||||
export function* watchExecuteActionSaga() {
|
||||
yield takeEvery(ReduxActionTypes.EXECUTE_ACTION, executeActionSaga);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,6 @@ export function* fetchPageSaga(pageRequestAction: ReduxAction<PageRequest>) {
|
|||
}
|
||||
}
|
||||
|
||||
export function* watchFetchPage() {
|
||||
export function* watchFetchPageSaga() {
|
||||
yield takeEvery(ReduxActionTypes.FETCH_PAGE, fetchPageSaga);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { all, spawn } from "redux-saga/effects";
|
||||
import { watchFetchPage } from "../sagas/PageSagas";
|
||||
import { watchFetchPageSaga } from "../sagas/PageSagas";
|
||||
import { fetchWidgetCardsSaga } from "./WidgetCardsPaneSagas";
|
||||
import { watchExecuteAction } from "./ActionSagas";
|
||||
import { watchExecuteActionSaga } from "./ActionSagas";
|
||||
|
||||
export function* rootSaga() {
|
||||
yield all([
|
||||
spawn(watchFetchPage),
|
||||
spawn(watchFetchPageSaga),
|
||||
spawn(fetchWidgetCardsSaga),
|
||||
spawn(watchExecuteAction),
|
||||
spawn(watchExecuteActionSaga),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
import { WidgetType } from "../constants/WidgetConstants";
|
||||
import { WidgetBuilder, WidgetProps } from "../widgets/BaseWidget";
|
||||
import { WidgetType, RenderMode } from "../constants/WidgetConstants";
|
||||
import {
|
||||
WidgetBuilder,
|
||||
WidgetProps,
|
||||
WidgetFunctions,
|
||||
WidgetDataProps,
|
||||
} from "../widgets/BaseWidget";
|
||||
|
||||
class WidgetFactory {
|
||||
static widgetMap: Map<WidgetType, WidgetBuilder<WidgetProps>> = new Map();
|
||||
|
|
@ -11,11 +16,22 @@ class WidgetFactory {
|
|||
this.widgetMap.set(widgetType, widgetBuilder);
|
||||
}
|
||||
|
||||
static createWidget(widgetData: WidgetProps): JSX.Element {
|
||||
widgetData.key = widgetData.widgetId;
|
||||
static createWidget(
|
||||
widgetData: WidgetDataProps,
|
||||
widgetFunctions: WidgetFunctions,
|
||||
renderMode: RenderMode,
|
||||
): JSX.Element {
|
||||
const widgetProps: WidgetProps = {
|
||||
key: widgetData.widgetId,
|
||||
renderMode: renderMode,
|
||||
...widgetData,
|
||||
...widgetFunctions,
|
||||
};
|
||||
const widgetBuilder = this.widgetMap.get(widgetData.widgetType);
|
||||
if (widgetBuilder) return widgetBuilder.buildWidget(widgetData);
|
||||
else {
|
||||
if (widgetBuilder) {
|
||||
const widget = widgetBuilder.buildWidget(widgetProps);
|
||||
return widget;
|
||||
} else {
|
||||
const ex: WidgetCreationException = {
|
||||
message:
|
||||
"Widget Builder not registered for widget type" +
|
||||
|
|
|
|||
|
|
@ -14,9 +14,10 @@ import { BaseStyle } from "../editorComponents/BaseComponent";
|
|||
import _ from "lodash";
|
||||
import React from "react";
|
||||
import DraggableComponent from "../editorComponents/DraggableComponent";
|
||||
import { ActionPayload } from "../constants/ActionConstants";
|
||||
|
||||
abstract class BaseWidget<
|
||||
T extends WidgetProps,
|
||||
T extends WidgetProps & WidgetFunctions,
|
||||
K extends WidgetState
|
||||
> extends Component<T, K> {
|
||||
constructor(props: T) {
|
||||
|
|
@ -147,24 +148,31 @@ export interface DraggableWidget {
|
|||
}
|
||||
|
||||
export interface WidgetBuilder<T extends WidgetProps> {
|
||||
buildWidget(data: T): JSX.Element;
|
||||
buildWidget(widgetProps: T): JSX.Element;
|
||||
}
|
||||
|
||||
export interface WidgetProps {
|
||||
export interface WidgetProps extends WidgetFunctions, WidgetDataProps {
|
||||
key?: string;
|
||||
renderMode: RenderMode;
|
||||
}
|
||||
|
||||
export interface WidgetDataProps {
|
||||
widgetId: string;
|
||||
widgetType: WidgetType;
|
||||
widgetName: string;
|
||||
key?: string;
|
||||
topRow: number;
|
||||
leftColumn: number;
|
||||
bottomRow: number;
|
||||
rightColumn: number;
|
||||
parentColumnSpace: number;
|
||||
parentRowSpace: number;
|
||||
renderMode: RenderMode;
|
||||
isVisible?: boolean;
|
||||
}
|
||||
|
||||
export interface WidgetFunctions {
|
||||
executeAction: (actionPayloads?: ActionPayload[]) => void;
|
||||
}
|
||||
|
||||
export interface WidgetCardProps {
|
||||
widgetType: WidgetType;
|
||||
key?: string;
|
||||
|
|
|
|||
|
|
@ -5,13 +5,20 @@ import ButtonComponent from "../editorComponents/ButtonComponent";
|
|||
import { ActionPayload } from "../constants/ActionConstants";
|
||||
|
||||
class ButtonWidget extends BaseWidget<ButtonWidgetProps, WidgetState> {
|
||||
onButtonClick() {
|
||||
this.props.executeAction(this.props.onClick);
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
return (
|
||||
<ButtonComponent
|
||||
style={this.getPositionStyle()}
|
||||
widgetId={this.props.widgetId}
|
||||
key={this.props.widgetId}
|
||||
text={this.props.text || "Button"}
|
||||
text={this.props.text}
|
||||
onClick={() => {
|
||||
this.onButtonClick();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import React from "react";
|
||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||
import BaseWidget, {
|
||||
WidgetProps,
|
||||
WidgetState,
|
||||
WidgetFunctions,
|
||||
} from "./BaseWidget";
|
||||
import ContainerComponent from "../editorComponents/ContainerComponent";
|
||||
import { ContainerOrientation, WidgetType } from "../constants/WidgetConstants";
|
||||
import WidgetFactory from "../utils/WidgetFactory";
|
||||
|
|
@ -49,7 +53,12 @@ class ContainerWidget extends BaseWidget<
|
|||
renderChildWidget(childWidgetData: WidgetProps) {
|
||||
childWidgetData.parentColumnSpace = this.state.snapColumnSpace;
|
||||
childWidgetData.parentRowSpace = this.state.snapRowSpace;
|
||||
return WidgetFactory.createWidget(childWidgetData);
|
||||
const widgetFunctions: WidgetFunctions = this.props as WidgetFunctions;
|
||||
return WidgetFactory.createWidget(
|
||||
childWidgetData,
|
||||
widgetFunctions,
|
||||
this.props.renderMode,
|
||||
);
|
||||
}
|
||||
|
||||
getPageView() {
|
||||
|
|
|
|||
|
|
@ -4411,7 +4411,7 @@ eslint-plugin-react-hooks@^1.6.1:
|
|||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04"
|
||||
integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==
|
||||
|
||||
eslint-plugin-react@7.14.3:
|
||||
eslint-plugin-react@7.14.3, eslint-plugin-react@^7.14.3:
|
||||
version "7.14.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13"
|
||||
integrity sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==
|
||||
|
|
@ -4505,6 +4505,49 @@ eslint@^6.1.0, eslint@^6.4.0:
|
|||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
eslint@^6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a"
|
||||
integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
ajv "^6.10.0"
|
||||
chalk "^2.1.0"
|
||||
cross-spawn "^6.0.5"
|
||||
debug "^4.0.1"
|
||||
doctrine "^3.0.0"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^1.4.2"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
espree "^6.1.1"
|
||||
esquery "^1.0.1"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^5.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^5.0.0"
|
||||
globals "^11.7.0"
|
||||
ignore "^4.0.6"
|
||||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^6.4.1"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^3.13.1"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.3.0"
|
||||
lodash "^4.17.14"
|
||||
minimatch "^3.0.4"
|
||||
mkdirp "^0.5.1"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.8.2"
|
||||
progress "^2.0.0"
|
||||
regexpp "^2.0.1"
|
||||
semver "^6.1.2"
|
||||
strip-ansi "^5.2.0"
|
||||
strip-json-comments "^3.0.1"
|
||||
table "^5.2.3"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user