From 703081154ca0ea2ebb50feb78eea88390d7c2e3a Mon Sep 17 00:00:00 2001 From: Abhinav Jha Date: Tue, 17 Sep 2019 20:39:55 +0530 Subject: [PATCH] WIP: Fix fetch page. Add save page boilerplate. Add widget property change boilerplate. --- app/client/src/actions/pageActions.tsx | 61 +++++++++++++++++- app/client/src/api/PageApi.tsx | 11 ++-- .../src/constants/ReduxActionConstants.tsx | 58 ++++++++++------- .../editorComponents/DraggableComponent.tsx | 35 +--------- .../editorComponents/DropTargetComponent.tsx | 13 +++- .../normalizers/CanvasWidgetsNormalizer.tsx | 6 +- app/client/src/pages/Editor/Canvas.tsx | 2 +- .../src/pages/Editor/EditorDragLayer.tsx | 49 ++------------ app/client/src/pages/Editor/WidgetCard.tsx | 2 +- app/client/src/pages/Editor/index.tsx | 32 ++++++---- .../entityReducers/canvasWidgetsReducer.tsx | 2 +- .../src/reducers/entityReducers/index.tsx | 28 ++++---- app/client/src/reducers/index.tsx | 3 - .../src/reducers/uiReducers/canvasReducer.tsx | 25 -------- .../src/reducers/uiReducers/editorReducer.tsx | 16 ++--- app/client/src/reducers/uiReducers/index.tsx | 2 - app/client/src/sagas/ActionSagas.tsx | 11 ++-- app/client/src/sagas/PageSagas.tsx | 64 +++++++++++++------ app/client/src/sagas/index.tsx | 4 +- app/client/src/utils/WidgetFactory.tsx | 1 + app/client/src/widgets/BaseWidget.tsx | 9 +++ app/client/src/widgets/ContainerWidget.tsx | 2 +- 22 files changed, 230 insertions(+), 206 deletions(-) delete mode 100644 app/client/src/reducers/uiReducers/canvasReducer.tsx diff --git a/app/client/src/actions/pageActions.tsx b/app/client/src/actions/pageActions.tsx index 09fb6f6c81..7521b4dc97 100644 --- a/app/client/src/actions/pageActions.tsx +++ b/app/client/src/actions/pageActions.tsx @@ -1,15 +1,23 @@ -import { PageRequest } from "../api/PageApi"; +import { FetchPageRequest } from "../api/PageApi"; import { RenderMode } from "../constants/WidgetConstants"; -import { WidgetProps } from "../widgets/BaseWidget"; +import { + WidgetProps, + WidgetDynamicProperty, + WidgetDynamicProperties, +} from "../widgets/BaseWidget"; import { ReduxActionTypes, ReduxAction, + LoadCanvasWidgetsPayload, + SavePagePayload, + SavePageErrorPayload, + SavePageSuccessPayload, } from "../constants/ReduxActionConstants"; export const fetchPage = ( pageId: string, renderMode: RenderMode, -): ReduxAction => { +): ReduxAction => { return { type: ReduxActionTypes.FETCH_PAGE, payload: { @@ -44,3 +52,50 @@ export const removeWidget = ( }, }; }; + +export const loadCanvasWidgets = ( + payload: LoadCanvasWidgetsPayload, +): ReduxAction => { + return { + type: ReduxActionTypes.LOAD_CANVAS_WIDGETS, + payload, + }; +}; + +export const savePage = (payload: SavePagePayload) => { + return { + type: ReduxActionTypes.SAVE_PAGE_INIT, + payload, + }; +}; + +export const savePageSuccess = (payload: SavePageSuccessPayload) => { + return { + type: ReduxActionTypes.SAVE_PAGE_SUCCESS, + payload, + }; +}; + +export const savePageError = (payload: SavePageErrorPayload) => { + return { + type: ReduxActionTypes.SAVE_PAGE_ERROR, + payload, + }; +}; + +export const updateWidget = ( + property: WidgetDynamicProperty, + widget: WidgetProps, + payload: any, +) => { + switch (property) { + case WidgetDynamicProperties.CHILDREN: + return; + case WidgetDynamicProperties.EXISTENCE: + return; + case WidgetDynamicProperties.POSITION: + return; + case WidgetDynamicProperties.SIZE: + return; + } +}; diff --git a/app/client/src/api/PageApi.tsx b/app/client/src/api/PageApi.tsx index 546a1ce1b8..c4b2876514 100644 --- a/app/client/src/api/PageApi.tsx +++ b/app/client/src/api/PageApi.tsx @@ -1,16 +1,17 @@ import Api from "./Api"; import { ContainerWidgetProps } from "../widgets/ContainerWidget"; import { ApiResponse } from "./ApiResponses"; +import { WidgetProps } from "../widgets/BaseWidget"; import { RenderMode } from "../constants/WidgetConstants"; import { PageAction } from "../constants/ActionConstants"; -export interface PageRequest { +export interface FetchPageRequest { pageId: string; renderMode: RenderMode; } export interface SavePageRequest { - pageWidget: ContainerWidgetProps; + pageWidget: ContainerWidgetProps; } export interface PageLayout { @@ -18,7 +19,7 @@ export interface PageLayout { actions: PageAction[]; } -export interface PageResponse extends ApiResponse { +export interface FetchPageResponse extends ApiResponse { layout: PageLayout; } @@ -29,11 +30,11 @@ export interface SavePageResponse { class PageApi extends Api { static url = "/page"; - static fetchPage(pageRequest: PageRequest): Promise { + static fetchPage(pageRequest: FetchPageRequest): Promise { return Api.get(PageApi.url + "/" + pageRequest.pageId, pageRequest); } - static savePage(savePageRequest: SavePageRequest): Promise { + static savePage(savePageRequest: SavePageRequest): Promise { return Api.post(PageApi.url, undefined, savePageRequest); } } diff --git a/app/client/src/constants/ReduxActionConstants.tsx b/app/client/src/constants/ReduxActionConstants.tsx index 386fbd0291..f2464f1266 100644 --- a/app/client/src/constants/ReduxActionConstants.tsx +++ b/app/client/src/constants/ReduxActionConstants.tsx @@ -1,31 +1,32 @@ // import ContainerWidget from "../widgets/ContainerWidget" import { WidgetProps, WidgetCardProps } from "../widgets/BaseWidget"; -export type ReduxActionType = - | "LOAD_CANVAS_WIDGETS" - | "FETCH_CANVAS" - | "CLEAR_CANVAS" - | "DROP_WIDGET_CANVAS" - | "REMOVE_WIDGET_CANVAS" - | "LOAD_WIDGET_PANE" - | "FETCH_PAGE" - | "ZOOM_IN_CANVAS" - | "ZOOM_OUT_CANVAS" - | "PUBLISH" - | "UNDO_CANVAS_ACTION" - | "REDO_CANVAS_ACTION" - | "FETCH_WIDGET_CARDS" - | "SUCCESS_FETCHING_WIDGET_CARDS" - | "ERROR_FETCHING_WIDGET_CARDS" - | "ADD_PAGE_WIDGET" - | "REMOVE_PAGE_WIDGET" - | "LOAD_WIDGET_CONFIG" - | "LOAD_API_RESPONSE" - | "LOAD_QUERY_RESPONSE" - | "EXECUTE_ACTION" - | "LOAD_CANVAS_ACTIONS"; +// export type ReduxActionType = +// | "LOAD_CANVAS_WIDGETS" +// | "UPDATE_CANVAS" +// | "FETCH_CANVAS" +// | "CLEAR_CANVAS" +// | "DROP_WIDGET_CANVAS" +// | "REMOVE_WIDGET_CANVAS" +// | "LOAD_WIDGET_PANE" +// | "FETCH_PAGE" +// | "ZOOM_IN_CANVAS" +// | "ZOOM_OUT_CANVAS" +// | "PUBLISH" +// | "UNDO_CANVAS_ACTION" +// | "REDO_CANVAS_ACTION" +// | "FETCH_WIDGET_CARDS" +// | "SUCCESS_FETCHING_WIDGET_CARDS" +// | "ERROR_FETCHING_WIDGET_CARDS" +// | "ADD_PAGE_WIDGET" +// | "REMOVE_PAGE_WIDGET" +// | "LOAD_WIDGET_CONFIG" +// | "LOAD_API_RESPONSE" +// | "LOAD_QUERY_RESPONSE" +// | "EXECUTE_ACTION" +// | "LOAD_CANVAS_ACTIONS"; -export const ReduxActionTypes: { [id: string]: ReduxActionType } = { +export const ReduxActionTypes = { LOAD_CANVAS_WIDGETS: "LOAD_CANVAS_WIDGETS", FETCH_CANVAS: "FETCH_CANVAS", CLEAR_CANVAS: "CLEAR_CANVAS", @@ -48,8 +49,13 @@ export const ReduxActionTypes: { [id: string]: ReduxActionType } = { LOAD_QUERY_RESPONSE: "LOAD_QUERY_RESPONSE", EXECUTE_ACTION: "EXECUTE_ACTION", LOAD_CANVAS_ACTIONS: "LOAD_CANVAS_ACTIONS", + SAVE_PAGE_INIT: "SAVE_PAGE_INIT", + SAVE_PAGE_SUCCESS: "SAVE_PAGE_SUCCESS", + SAVE_PAGE_ERROR: "SAVE_PAGE_ERROR", }; +export type ReduxActionType = (typeof ReduxActionTypes)[keyof typeof ReduxActionTypes]; + export interface ReduxAction { type: ReduxActionType; payload: T; @@ -75,3 +81,7 @@ export interface LoadWidgetPanePayload { export interface LoadWidgetCardsPanePayload { cards: { [id: string]: WidgetCardProps[] }; } + +export type SavePagePayload = {}; +export type SavePageErrorPayload = {}; +export type SavePageSuccessPayload = {}; diff --git a/app/client/src/editorComponents/DraggableComponent.tsx b/app/client/src/editorComponents/DraggableComponent.tsx index 74209fefa4..1eb23cfede 100644 --- a/app/client/src/editorComponents/DraggableComponent.tsx +++ b/app/client/src/editorComponents/DraggableComponent.tsx @@ -7,7 +7,7 @@ import { ContainerProps } from "./ContainerComponent"; type DraggableComponentProps = WidgetProps & ContainerProps; const DraggableComponent = (props: DraggableComponentProps) => { - const [{ isDragging }, drag, preview] = useDrag({ + const [, drag, preview] = useDrag({ item: props, collect: (monitor: DragSourceMonitor) => ({ isDragging: monitor.isDragging(), @@ -17,6 +17,7 @@ const DraggableComponent = (props: DraggableComponentProps) => {
{ ); }; -// class DraggableComponent extends React.Component { -// render() { -// return props.connectDragSource( -// , -// ); -// } -// } - -// const widgetSource = { -// beginDrag(props: WidgetProps) { -// return { -// widgetId: props.widgetId, -// widgetType: props.type, -// }; -// }, -// }; - -const widgetType = (props: WidgetProps) => { - return props.type; -}; - -// function collect(connect: DragSourceConnector, monitor: DragSourceMonitor) { -// return { -// connectDragSource: connect.dragSource(), -// isDragging: monitor.isDragging(), -// }; -// } - -// export default DragSource(widgetType, widgetSource, collect)( -// DraggableComponent, -// ); - export default DraggableComponent; diff --git a/app/client/src/editorComponents/DropTargetComponent.tsx b/app/client/src/editorComponents/DropTargetComponent.tsx index 99edd6fecf..637ee35025 100644 --- a/app/client/src/editorComponents/DropTargetComponent.tsx +++ b/app/client/src/editorComponents/DropTargetComponent.tsx @@ -1,9 +1,11 @@ import React, { useState } from "react"; -import { WidgetProps } from "../widgets/BaseWidget"; +import { WidgetProps, WidgetDynamicProperties } from "../widgets/BaseWidget"; import { useDrop, XYCoord } from "react-dnd"; import { ContainerProps } from "./ContainerComponent"; import WidgetFactory from "../utils/WidgetFactory"; -type DropTargetComponentProps = ContainerProps & { onDrop: Function }; +type DropTargetComponentProps = ContainerProps & { + onPropertyChange?: Function; +}; export const DropTargetComponent = (props: DropTargetComponentProps) => { const [isOver, setIsOver] = useState(false); const [, drop] = useDrop({ @@ -14,7 +16,12 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => { const delta = monitor.getDifferenceFromInitialOffset() as XYCoord; const left = Math.round(item.left + delta.x); const top = Math.round(item.top + delta.y); - props.onDrop && props.onDrop({ item, left, top }); + props.onPropertyChange && + props.onPropertyChange(WidgetDynamicProperties.CHILDREN, props, { + item, + left, + top, + }); } return undefined; }, diff --git a/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx b/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx index da1f3f4896..12a3a5fc35 100644 --- a/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx +++ b/app/client/src/normalizers/CanvasWidgetsNormalizer.tsx @@ -1,5 +1,5 @@ import { normalize, schema, denormalize } from "normalizr"; -import { PageResponse } from "../api/PageApi"; +import { FetchPageResponse } from "../api/PageApi"; import { ContainerWidgetProps } from "../widgets/ContainerWidget"; export const widgetSchema = new schema.Entity( @@ -10,7 +10,9 @@ export const widgetSchema = new schema.Entity( widgetSchema.define({ children: [widgetSchema] }); class CanvasWidgetsNormalizer { - static normalize(pageResponse: PageResponse): { entities: any; result: any } { + static normalize( + pageResponse: FetchPageResponse, + ): { entities: any; result: any } { return normalize(pageResponse.layout.dsl, widgetSchema); } diff --git a/app/client/src/pages/Editor/Canvas.tsx b/app/client/src/pages/Editor/Canvas.tsx index 49ccdd9183..e7b73dd9ac 100644 --- a/app/client/src/pages/Editor/Canvas.tsx +++ b/app/client/src/pages/Editor/Canvas.tsx @@ -19,7 +19,7 @@ const Canvas = (props: CanvasProps) => { return ( - {props.layout && WidgetFactory.createWidget(props.layout)} + {props.layout.widgetId && WidgetFactory.createWidget(props.layout)} ); diff --git a/app/client/src/pages/Editor/EditorDragLayer.tsx b/app/client/src/pages/Editor/EditorDragLayer.tsx index 79fa2d9d97..71f2506f60 100644 --- a/app/client/src/pages/Editor/EditorDragLayer.tsx +++ b/app/client/src/pages/Editor/EditorDragLayer.tsx @@ -1,9 +1,6 @@ import React from "react"; import styled from "styled-components"; -import { XYCoord, useDragLayer } from "react-dnd"; -import snapToGrid from "./snapToGrid"; -import WidgetFactory from "../../utils/WidgetFactory"; -import { RenderModes, WidgetType } from "../../constants/WidgetConstants"; +import { useDragLayer } from "react-dnd"; const WrappedDragLayer = styled.div` position: absolute; @@ -13,51 +10,17 @@ const WrappedDragLayer = styled.div` top: 0; width: 100%; height: 100%; + cursor: grab; `; -function getItemStyles( - initialOffset: XYCoord | null, - currentOffset: XYCoord | null, -) { - if (!initialOffset || !currentOffset) { - return { - display: "none", - }; - } - - let { x, y } = currentOffset; - - x -= initialOffset.x; - y -= initialOffset.y; - [x, y] = snapToGrid(64, x, y); - x += initialOffset.x; - y += initialOffset.y; - - const transform = `translate(${x}px, ${y}px)`; - return { - transform, - WebkitTransform: transform, - }; -} - const EditorDragLayer = () => { - const { isDragging, initialOffset, currentOffset } = useDragLayer( - monitor => ({ - item: monitor.getItem(), - itemType: monitor.getItemType(), - initialOffset: monitor.getInitialSourceClientOffset(), - currentOffset: monitor.getSourceClientOffset(), - isDragging: monitor.isDragging(), - }), - ); + const { isDragging } = useDragLayer(monitor => ({ + isDragging: monitor.isDragging(), + })); if (!isDragging) { return null; } - return ( - -
-
- ); + return ; }; export default EditorDragLayer; diff --git a/app/client/src/pages/Editor/WidgetCard.tsx b/app/client/src/pages/Editor/WidgetCard.tsx index 32511eb49d..f139772123 100644 --- a/app/client/src/pages/Editor/WidgetCard.tsx +++ b/app/client/src/pages/Editor/WidgetCard.tsx @@ -43,7 +43,7 @@ export const IconLabel = styled.h5` /* eslint-disable @typescript-eslint/no-unused-vars */ const WidgetCard = (props: CardProps) => { - const [{ isDragging }, drag, preview] = useDrag({ + const [, drag, preview] = useDrag({ item: props.details, collect: (monitor: DragSourceMonitor) => ({ isDragging: monitor.isDragging(), diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index 0f577de899..723e02d202 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -2,14 +2,18 @@ import React, { Component } from "react"; import { connect } from "react-redux"; import styled from "styled-components"; import Canvas from "./Canvas"; -import { WidgetCardProps, WidgetProps } from "../../widgets/BaseWidget"; +import { + WidgetCardProps, + WidgetProps, + WidgetDynamicProperty, +} from "../../widgets/BaseWidget"; import { AppState } from "../../reducers"; import { EditorReduxState } from "../../reducers/uiReducers/editorReducer"; import WidgetCardsPane from "./WidgetCardsPane"; import EditorHeader from "./EditorHeader"; import CanvasWidgetsNormalizer from "../../normalizers/CanvasWidgetsNormalizer"; import { ContainerWidgetProps } from "../../widgets/ContainerWidget"; -import { fetchPage, addWidget } from "../../actions/pageActions"; +import { fetchPage, updateWidget } from "../../actions/pageActions"; import { RenderModes } from "../../constants/WidgetConstants"; import EditorDragLayer from "./EditorDragLayer"; @@ -43,10 +47,10 @@ const EditorWrapper = styled.div` `; type EditorProps = { - pageWidget: ContainerWidgetProps | any; + layout: ContainerWidgetProps | any; fetchCanvasWidgets: Function; cards: { [id: string]: WidgetCardProps[] } | any; - addPageWidget: Function; + updateWidgetProperty: Function; page: string; }; @@ -55,8 +59,6 @@ class Editor extends Component { this.props.fetchCanvasWidgets("1"); } - addWidgetToCanvas = (): void => {}; - public render() { return ( @@ -67,8 +69,8 @@ class Editor extends Component { @@ -79,13 +81,14 @@ class Editor extends Component { } const mapStateToProps = (state: AppState): EditorReduxState => { - const pageWidget = CanvasWidgetsNormalizer.denormalize( - state.ui.canvas.pageWidgetId, + const layout = CanvasWidgetsNormalizer.denormalize( + state.ui.editor.pageWidgetId, state.entities, ); return { cards: state.ui.widgetCardsPane.cards, - pageWidget, + layout, + pageWidgetId: state.ui.editor.pageWidgetId, }; }; @@ -93,8 +96,11 @@ const mapDispatchToProps = (dispatch: any) => { return { fetchCanvasWidgets: (pageId: string) => dispatch(fetchPage(pageId, RenderModes.CANVAS)), - addPageWidget: (pageId: string, widgetProps: WidgetProps) => - dispatch(addWidget(pageId, widgetProps)), + updateWidgetProperty: ( + propertyType: WidgetDynamicProperty, + widgetProps: WidgetProps, + payload: any, + ) => dispatch(updateWidget(propertyType, widgetProps, payload)), }; }; diff --git a/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx b/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx index 439fdb4a32..e259bd54db 100644 --- a/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx +++ b/app/client/src/reducers/entityReducers/canvasWidgetsReducer.tsx @@ -14,7 +14,7 @@ export interface FlattenedWidgetProps extends WidgetProps { } const canvasWidgetsReducer = createReducer(initialState, { - [ReduxActionTypes.UPDATE_CANVAS]: ( + [ReduxActionTypes.LOAD_CANVAS_WIDGETS]: ( state: CanvasWidgetsReduxState, action: ReduxAction, ) => { diff --git a/app/client/src/reducers/entityReducers/index.tsx b/app/client/src/reducers/entityReducers/index.tsx index a87cb372f7..4b8bca3947 100644 --- a/app/client/src/reducers/entityReducers/index.tsx +++ b/app/client/src/reducers/entityReducers/index.tsx @@ -1,15 +1,15 @@ -import { combineReducers } from "redux" -import canvasWidgetsReducer from "./canvasWidgetsReducer" -import apiDataReducer from './apiDataReducer'; -import queryDataReducer from './queryDataReducer'; -import widgetConfigReducer from './widgetConfigReducer.tsx'; -import actionsReducer from './actionsReducer'; +import { combineReducers } from "redux"; +import canvasWidgetsReducer from "./canvasWidgetsReducer"; +import apiDataReducer from "./apiDataReducer"; +import queryDataReducer from "./queryDataReducer"; +import widgetConfigReducer from "./widgetConfigReducer.tsx"; +import actionsReducer from "./actionsReducer"; -const entityReducer = combineReducers({ - canvasWidgets: canvasWidgetsReducer, - apiData: apiDataReducer, - queryData: queryDataReducer, - widgetConfig: widgetConfigReducer, - actions: actionsReducer -}) -export default entityReducer +const entityReducer = combineReducers({ + canvasWidgets: canvasWidgetsReducer, + apiData: apiDataReducer, + queryData: queryDataReducer, + widgetConfig: widgetConfigReducer, + actions: actionsReducer, +}); +export default entityReducer; diff --git a/app/client/src/reducers/index.tsx b/app/client/src/reducers/index.tsx index 007bab65ff..4251d8237f 100644 --- a/app/client/src/reducers/index.tsx +++ b/app/client/src/reducers/index.tsx @@ -1,7 +1,6 @@ import { combineReducers } from "redux"; import entityReducer from "./entityReducers"; import uiReducer from "./uiReducers"; -import { CanvasReduxState } from "./uiReducers/canvasReducer"; import { CanvasWidgetsReduxState } from "./entityReducers/canvasWidgetsReducer"; import { WidgetCardsPaneReduxState } from "./uiReducers/widgetCardsPaneReducer"; import { EditorReduxState } from "./uiReducers/editorReducer"; @@ -18,9 +17,7 @@ export default appReducer; export interface AppState { ui: { - canvas: CanvasReduxState; widgetCardsPane: WidgetCardsPaneReduxState; - // editorHeader: EditorHeaderReduxState; editor: EditorReduxState; }; entities: { diff --git a/app/client/src/reducers/uiReducers/canvasReducer.tsx b/app/client/src/reducers/uiReducers/canvasReducer.tsx deleted file mode 100644 index dabbbdd3ea..0000000000 --- a/app/client/src/reducers/uiReducers/canvasReducer.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { createReducer } from "../../utils/AppsmithUtils"; -import { - ReduxActionTypes, - LoadCanvasWidgetsPayload, - ReduxAction, -} from "../../constants/ReduxActionConstants"; - -const initialState: CanvasReduxState = { - pageWidgetId: "0", -}; - -const canvasReducer = createReducer(initialState, { - [ReduxActionTypes.UPDATE_CANVAS]: ( - state: CanvasReduxState, - action: ReduxAction, - ) => { - return { pageWidgetId: action.payload.pageWidgetId }; - }, -}); - -export interface CanvasReduxState { - pageWidgetId: string; -} - -export default canvasReducer; diff --git a/app/client/src/reducers/uiReducers/editorReducer.tsx b/app/client/src/reducers/uiReducers/editorReducer.tsx index 59cc19dafc..094013ea23 100644 --- a/app/client/src/reducers/uiReducers/editorReducer.tsx +++ b/app/client/src/reducers/uiReducers/editorReducer.tsx @@ -8,22 +8,21 @@ import { import { WidgetCardProps, WidgetProps } from "../../widgets/BaseWidget"; import { ContainerWidgetProps } from "../../widgets/ContainerWidget"; -const initialState: EditorReduxState = {}; +const initialState: EditorReduxState = { + pageWidgetId: "0", +}; const editorReducer = createReducer(initialState, { [ReduxActionTypes.SUCCESS_FETCHING_WIDGET_CARDS]: ( state: EditorReduxState, action: ReduxAction, ) => { - return { ...state.pageWidget, ...action.payload }; + return { ...state.layout, ...action.payload }; }, - [ReduxActionTypes.ADD_PAGE_WIDGET]: ( - state: EditorReduxState, - action: ReduxAction<{ pageId: string; widget: WidgetProps }>, - ) => { + [ReduxActionTypes.ADD_PAGE_WIDGET]: (state: EditorReduxState) => { return state; }, - [ReduxActionTypes.UPDATE_CANVAS]: ( + [ReduxActionTypes.LOAD_CANVAS_WIDGETS]: ( state: EditorReduxState, action: ReduxAction, ) => { @@ -32,10 +31,11 @@ const editorReducer = createReducer(initialState, { }); export interface EditorReduxState { - pageWidget?: ContainerWidgetProps; + layout?: ContainerWidgetProps; cards?: { [id: string]: WidgetCardProps[]; }; + pageWidgetId: string; } export default editorReducer; diff --git a/app/client/src/reducers/uiReducers/index.tsx b/app/client/src/reducers/uiReducers/index.tsx index afe61a3bbf..2f32248aaf 100644 --- a/app/client/src/reducers/uiReducers/index.tsx +++ b/app/client/src/reducers/uiReducers/index.tsx @@ -1,11 +1,9 @@ import { combineReducers } from "redux"; -import canvasReducer from "./canvasReducer"; import widgetCardsPaneReducer from "./widgetCardsPaneReducer"; import editorHeaderReducer from "./editorHeaderReducer"; import editorReducer from "./editorReducer"; const uiReducer = combineReducers({ - canvas: canvasReducer, widgetCardsPane: widgetCardsPaneReducer, editorHeader: editorHeaderReducer, editor: editorReducer, diff --git a/app/client/src/sagas/ActionSagas.tsx b/app/client/src/sagas/ActionSagas.tsx index 29654f5ebf..2f706d2b29 100644 --- a/app/client/src/sagas/ActionSagas.tsx +++ b/app/client/src/sagas/ActionSagas.tsx @@ -3,7 +3,7 @@ import { ReduxActionTypes, ReduxAction, } from "../constants/ReduxActionConstants"; -import PageApi, { PageResponse, PageRequest } from "../api/PageApi"; +import PageApi, { FetchPageResponse, FetchPageRequest } from "../api/PageApi"; import { call, put, takeEvery, select, all } from "redux-saga/effects"; import { RenderModes } from "../constants/WidgetConstants"; import { @@ -71,10 +71,12 @@ export function* executeQueryAction(queryAction: QueryActionPayload) { }); } -export function* executeAction(pageRequestAction: ReduxAction) { +export function* executeAction( + pageRequestAction: ReduxAction, +) { const pageRequest = pageRequestAction.payload; try { - const pageResponse: PageResponse = yield call( + const pageResponse: FetchPageResponse = yield call( PageApi.fetchPage, pageRequest, ); @@ -86,9 +88,10 @@ export function* executeAction(pageRequestAction: ReduxAction) { pageWidgetId: normalizedResponse.result, widgets: normalizedResponse.entities.canvasWidgets, }; - yield put({ type: ReduxActionTypes.UPDATE_CANVAS, payload }); + yield put({ type: ReduxActionTypes.LOAD_CANVAS_WIDGETS, payload }); } } catch (err) { + console.log(err); //TODO(abhinav): REFACTOR THIS } } diff --git a/app/client/src/sagas/PageSagas.tsx b/app/client/src/sagas/PageSagas.tsx index 5a1850d32a..e3b1208281 100644 --- a/app/client/src/sagas/PageSagas.tsx +++ b/app/client/src/sagas/PageSagas.tsx @@ -4,11 +4,21 @@ import { ReduxAction, LoadCanvasWidgetsPayload, } from "../constants/ReduxActionConstants"; -import PageApi, { PageResponse, PageRequest } from "../api/PageApi"; -import { call, put, takeEvery, all } from "redux-saga/effects"; +import { + loadCanvasWidgets, + savePageError, + savePageSuccess, +} from "../actions/pageActions"; +import PageApi, { + FetchPageResponse, + SavePageResponse, + FetchPageRequest, + SavePageRequest, +} from "../api/PageApi"; +import { call, put, takeLatest, all } from "redux-saga/effects"; import { RenderModes } from "../constants/WidgetConstants"; -export function* fetchPageSaga(pageRequestAction: ReduxAction) { +export function* fetchPage(pageRequestAction: ReduxAction) { const pageRequest = pageRequestAction.payload; try { // const pageResponse: PageResponse = yield call( @@ -22,12 +32,12 @@ export function* fetchPageSaga(pageRequestAction: ReduxAction) { "dsl": { "widgetId": "0", "type": "CONTAINER_WIDGET", - "snapColumns": 1000, - "snapRows": 1500, + "snapColumns": 16, + "snapRows": 100, "topRow": 0, - "bottomRow": 2, + "bottomRow": 2000, "leftColumn": 0, - "rightColumn": 2, + "rightColumn": 1000, "parentColumnSpace": 1, "parentRowSpace": 1, "backgroundColor": "#ffffff", @@ -39,9 +49,9 @@ export function* fetchPageSaga(pageRequestAction: ReduxAction) { "snapColumns": 10, "snapRows": 10, "topRow": 1, - "bottomRow": 2, + "bottomRow": 20, "leftColumn": 1, - "rightColumn": 2, + "rightColumn": 16, "backgroundColor": "#000000", "renderMode": "CANVAS", "children": [] @@ -57,19 +67,37 @@ export function* fetchPageSaga(pageRequestAction: ReduxAction) { pageWidgetId: normalizedResponse.result, widgets: normalizedResponse.entities.canvasWidgets, }; - yield all([ - put({ type: ReduxActionTypes.UPDATE_CANVAS, canvasWidgetsPayload }), - put({ - type: ReduxActionTypes.LOAD_CANVAS_ACTIONS, - payload: pageResponse.layout.actions, - }), - ]); + + yield put(loadCanvasWidgets(canvasWidgetsPayload)); + yield put({ + type: ReduxActionTypes.LOAD_CANVAS_ACTIONS, + payload: pageResponse.layout.actions, + }); } } catch (err) { + console.log(err); //TODO(abhinav): REFACTOR THIS } } -export function* watchFetchPage() { - yield takeEvery(ReduxActionTypes.FETCH_PAGE, fetchPageSaga); +export function* savePage(savePageAction: ReduxAction) { + const savePageRequest = savePageAction.payload; + + try { + const savePageResponse: SavePageResponse = yield call( + PageApi.savePage, + savePageRequest, + ); + yield put(savePageSuccess(savePageResponse)); + } catch (err) { + console.log(err); + yield put(savePageError(err)); + } +} + +export default function* pageSagas() { + yield all([ + takeLatest(ReduxActionTypes.FETCH_PAGE, fetchPage), + takeLatest(ReduxActionTypes.SAVE_PAGE_INIT, savePage), + ]); } diff --git a/app/client/src/sagas/index.tsx b/app/client/src/sagas/index.tsx index 1f213ed84c..7799af0359 100644 --- a/app/client/src/sagas/index.tsx +++ b/app/client/src/sagas/index.tsx @@ -1,11 +1,11 @@ import { all, spawn } from "redux-saga/effects"; -import { watchFetchPage } from "../sagas/PageSagas"; +import pageSagas from "../sagas/PageSagas"; import { fetchWidgetCardsSaga } from "./WidgetCardsPaneSagas"; import { watchExecuteAction } from "./ActionSagas"; export function* rootSaga() { yield all([ - spawn(watchFetchPage), + spawn(pageSagas), spawn(fetchWidgetCardsSaga), spawn(watchExecuteAction), ]); diff --git a/app/client/src/utils/WidgetFactory.tsx b/app/client/src/utils/WidgetFactory.tsx index cece03229e..244221ba49 100644 --- a/app/client/src/utils/WidgetFactory.tsx +++ b/app/client/src/utils/WidgetFactory.tsx @@ -14,6 +14,7 @@ class WidgetFactory { static createWidget(widgetData: WidgetProps): JSX.Element { widgetData.key = widgetData.widgetId; const widgetBuilder = this.widgetMap.get(widgetData.type); + if (widgetBuilder) return widgetBuilder.buildWidget(widgetData); else { const ex: WidgetCreationException = { diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index 33f003c17e..87d6c5bacf 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -172,4 +172,13 @@ export interface WidgetCardProps { icon: string; } +export const WidgetDynamicProperties = { + POSITION: "POSITION", + SIZE: "SIZE", + CHILDREN: "CHILDREN", + EXISTENCE: "EXISTENCE", +}; + +export type WidgetDynamicProperty = (typeof WidgetDynamicProperties)[keyof typeof WidgetDynamicProperties]; + export default BaseWidget; diff --git a/app/client/src/widgets/ContainerWidget.tsx b/app/client/src/widgets/ContainerWidget.tsx index e3b3d5af71..ce2e3a2c67 100644 --- a/app/client/src/widgets/ContainerWidget.tsx +++ b/app/client/src/widgets/ContainerWidget.tsx @@ -96,7 +96,7 @@ export interface ContainerWidgetProps snapRows?: number; orientation?: ContainerOrientation; backgroundColor?: Color; - onDrop?: Function; + onPropertyChange?: Function; } export default ContainerWidget;