diff --git a/app/client/src/constants/ActionConstants.tsx b/app/client/src/constants/ActionConstants.tsx index 1e7d67a946..a2f96e9c53 100644 --- a/app/client/src/constants/ActionConstants.tsx +++ b/app/client/src/constants/ActionConstants.tsx @@ -1,11 +1,13 @@ import ContainerWidget from "../widgets/ContainerWidget" +import { IWidgetProps } from "../widgets/BaseWidget"; -export type ActionType = "LOAD_CANVAS" | "CLEAR_CANVAS" | "DROP_WIDGET_CANVAS" | "REMOVE_WIDGET_CANVAS" +export type ActionType = "LOAD_CANVAS" | "CLEAR_CANVAS" | "DROP_WIDGET_CANVAS" | "REMOVE_WIDGET_CANVAS" | "LOAD_WIDGET_PANE" export const ActionTypes: { [id: string]: ActionType } = { LOAD_CANVAS: "LOAD_CANVAS", CLEAR_CANVAS: "CLEAR_CANVAS", DROP_WIDGET_CANVAS: "DROP_WIDGET_CANVAS", - REMOVE_WIDGET_CANVAS: "REMOVE_WIDGET_CANVAS" + REMOVE_WIDGET_CANVAS: "REMOVE_WIDGET_CANVAS", + LOAD_WIDGET_PANE: "LOAD_WIDGET_PANE", } export interface ReduxAction { @@ -15,4 +17,8 @@ export interface ReduxAction { export interface LoadCanvasPayload { containerWidget: ContainerWidget +} + +export interface LoadWidgetPanePayload { + widgets: IWidgetProps[] } \ No newline at end of file diff --git a/app/client/src/constants/WidgetConstants.tsx b/app/client/src/constants/WidgetConstants.tsx index 186aafb325..373ad65148 100644 --- a/app/client/src/constants/WidgetConstants.tsx +++ b/app/client/src/constants/WidgetConstants.tsx @@ -27,6 +27,15 @@ export type CSSUnit = | "vmax" | "%" +export type RenderMode = "COMPONENT_PANE" | "CANVAS" | "PAGE" | "CANVAS_SELECTED" + +export const RenderModes: { [id: string]: RenderMode } = { + COMPONENT_PANE: "COMPONENT_PANE", + CANVAS: "CANVAS", + PAGE: "PAGE", + CANVAS_SELECTED: "CANVAS_SELECTED" +} + export const CSSUnits: { [id: string]: CSSUnit } = { PIXEL: "px", RELATIVE_FONTSIZE: "em", diff --git a/app/client/src/mockResponses/CanvasResponse.ts b/app/client/src/mockResponses/CanvasResponse.tsx similarity index 72% rename from app/client/src/mockResponses/CanvasResponse.ts rename to app/client/src/mockResponses/CanvasResponse.tsx index d2365356f2..a6be622c81 100644 --- a/app/client/src/mockResponses/CanvasResponse.ts +++ b/app/client/src/mockResponses/CanvasResponse.tsx @@ -3,6 +3,7 @@ import { IWidgetProps } from "../widgets/BaseWidget"; import ContainerWidget, { IContainerWidgetProps } from "../widgets/ContainerWidget"; +import { RenderModes } from "../constants/WidgetConstants"; const CanvasResponse: IContainerWidgetProps = { widgetId: "0", @@ -15,6 +16,7 @@ const CanvasResponse: IContainerWidgetProps = { rightColumn: 1200, parentColumnSpace: 1, parentRowSpace: 1, + renderMode: RenderModes.CANVAS, children: [ { widgetId: "1", @@ -23,7 +25,18 @@ const CanvasResponse: IContainerWidgetProps = { leftColumn: 5, bottomRow: 5, rightColumn: 5, - text: "Lorem Ipsum" + text: "Lorem Ipsum", + renderMode: RenderModes.CANVAS + }, + { + widgetId: "1", + widgetType: "BUTTON_WIDGET", + topRow: 2, + leftColumn: 7, + bottomRow: 5, + rightColumn: 5, + text: "Lorem Ipsum", + renderMode: RenderModes.CANVAS }, { widgetId: "2", @@ -32,7 +45,8 @@ const CanvasResponse: IContainerWidgetProps = { leftColumn: 1, bottomRow: 5, rightColumn: 5, - placeholder: "Lorem Ipsum" + placeholder: "Lorem Ipsum", + renderMode: RenderModes.CANVAS }, { widgetId: "3", @@ -46,7 +60,8 @@ const CanvasResponse: IContainerWidgetProps = { description: "The component is a simple wrapper around the CSS API that provides props for modifiers and optional title element. Any additional HTML props will be spread to the rendered
element.", icon: "", - intent: "success" + intent: "success", + renderMode: RenderModes.CANVAS }, { widgetId: "4", @@ -57,7 +72,8 @@ const CanvasResponse: IContainerWidgetProps = { rightColumn: 5, icon: "globe", iconSize: "20", - intent: "warning" + intent: "warning", + renderMode: RenderModes.CANVAS }, { widgetId: "5", @@ -66,7 +82,8 @@ const CanvasResponse: IContainerWidgetProps = { leftColumn: 6, bottomRow: 5, rightColumn: 5, - size: 20 + size: 20, + renderMode: RenderModes.CANVAS } ] }; diff --git a/app/client/src/mockResponses/WidgetPaneResponse.tsx b/app/client/src/mockResponses/WidgetPaneResponse.tsx new file mode 100644 index 0000000000..a563f9daf1 --- /dev/null +++ b/app/client/src/mockResponses/WidgetPaneResponse.tsx @@ -0,0 +1,13 @@ +import { WidgetPaneReduxState } from "../reducers/uiReducers/widgetPaneReducer"; + +const WidgetPaneResponse: WidgetPaneReduxState = { + widgets: [ + { + widgetType: "BUTTON_WIDGET", + text: "lorem ipsum", + } + ] + +} + +export default WidgetPaneResponse \ No newline at end of file diff --git a/app/client/src/pages/Editor/ComponentPane.tsx b/app/client/src/pages/Editor/ComponentPane.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/client/src/pages/Editor/WidgetPane.tsx b/app/client/src/pages/Editor/WidgetPane.tsx new file mode 100644 index 0000000000..2e4ea8a01b --- /dev/null +++ b/app/client/src/pages/Editor/WidgetPane.tsx @@ -0,0 +1,31 @@ +import React, { Component } from "react" +import { connect } from "react-redux" +import { AppState } from "../../reducers" +import WidgetFactory from "../../utils/WidgetFactory" +import { WidgetPaneReduxState } from "../../reducers/uiReducers/widgetPaneReducer"; +import { IWidgetProps } from "../../widgets/BaseWidget"; + +class WidgetPane extends Component { + render() { + return (
+ {this.props.widgets.map((widget: IWidgetProps) => { + return WidgetFactory.createWidget(widget) + })} +
) + } +} + +const mapStateToProps = (state: AppState, props: any): WidgetPaneReduxState => { + return { + widgets: state.ui.widgetPaneReducer.widgets + } +} + +const mapDispatchToProps = (dispatch: any) => { + return {} +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(WidgetPane) diff --git a/app/client/src/reducers/index.tsx b/app/client/src/reducers/index.tsx index 486101a656..24e024a9ca 100644 --- a/app/client/src/reducers/index.tsx +++ b/app/client/src/reducers/index.tsx @@ -3,6 +3,7 @@ import entityReducer from "./entityReducers" import uiReducer from "./uiReducers" import { CanvasReduxState } from "./uiReducers/canvasReducer" import { CanvasWidgetsReduxState } from "./entityReducers/canvasWidgetsReducers" +import { WidgetPaneReduxState } from "./uiReducers/widgetPaneReducer"; const appReducer = combineReducers({ entities: entityReducer, @@ -13,7 +14,8 @@ export default appReducer export interface AppState { ui: { - canvas: CanvasReduxState + canvas: CanvasReduxState, + widgetPaneReducer: WidgetPaneReduxState } entities: { canvasWidgets: CanvasWidgetsReduxState diff --git a/app/client/src/reducers/uiReducers/index.tsx b/app/client/src/reducers/uiReducers/index.tsx index ef8f90a8e1..27aec57d30 100644 --- a/app/client/src/reducers/uiReducers/index.tsx +++ b/app/client/src/reducers/uiReducers/index.tsx @@ -1,5 +1,6 @@ import { combineReducers } from "redux" import canvasReducer from "./canvasReducer" +import widgetPaneReducer from "./widgetPaneReducer"; -const uiReducer = combineReducers({ canvas: canvasReducer }) +const uiReducer = combineReducers({ canvas: canvasReducer, componentPane: widgetPaneReducer }) export default uiReducer diff --git a/app/client/src/reducers/uiReducers/widgetPaneReducer.tsx b/app/client/src/reducers/uiReducers/widgetPaneReducer.tsx new file mode 100644 index 0000000000..e929d4de68 --- /dev/null +++ b/app/client/src/reducers/uiReducers/widgetPaneReducer.tsx @@ -0,0 +1,27 @@ +import { createReducer } from "../../utils/PicassoUtils" +import { + ActionTypes, + ReduxAction, + LoadWidgetPanePayload +} from "../../constants/ActionConstants" +import { IWidgetProps } from "../../widgets/BaseWidget"; +import WidgetPaneResponse from "../../mockResponses/WidgetPaneResponse" + +const initialState: WidgetPaneReduxState = { + widgets: WidgetPaneResponse.widgets +} + +const widgetPaneReducer = createReducer(initialState, { + [ActionTypes.LOAD_CANVAS]: ( + state: WidgetPaneReduxState, + action: ReduxAction + ) => { + return { widgets: action.payload.widgets } + } +}) + +export interface WidgetPaneReduxState { + widgets: Partial[] +} + +export default widgetPaneReducer diff --git a/app/client/src/utils/WidgetRegistry.tsx b/app/client/src/utils/WidgetRegistry.tsx index 7dac4d4061..6eb7fc2036 100644 --- a/app/client/src/utils/WidgetRegistry.tsx +++ b/app/client/src/utils/WidgetRegistry.tsx @@ -31,6 +31,12 @@ class WidgetBuilderRegistry { } }); + WidgetFactory.registerWidgetBuilder("BUTTON_WIDGET", { + buildWidget(widgetData: IButtonWidgetProps): JSX.Element { + return ; + } + }); + WidgetFactory.registerWidgetBuilder("CALLOUT_WIDGET", { buildWidget(widgetData: ICalloutWidgetProps): JSX.Element { return ; diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index 08839f835e..95296362d2 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -3,8 +3,12 @@ * spawing components based on those props * Widgets are also responsible for dispatching actions and updating the state tree */ -import { WidgetType } from "../constants/WidgetConstants"; -import { Component } from "react"; +import { + WidgetType, + RenderMode, + RenderModes +} from "../constants/WidgetConstants" +import { Component } from "react" abstract class BaseWidget< T extends IWidgetProps, @@ -18,7 +22,7 @@ abstract class BaseWidget< this.props.bottomRow, this.props.parentColumnSpace, this.props.parentRowSpace - ); + ) } componentWillReceiveProps(prevProps: T, nextProps: T) { @@ -29,7 +33,7 @@ abstract class BaseWidget< nextProps.bottomRow, nextProps.parentColumnSpace, nextProps.parentRowSpace - ); + ) } calculateWidgetBounds( @@ -43,38 +47,60 @@ abstract class BaseWidget< const widgetState: IWidgetState = { width: (rightColumn - leftColumn) * parentColumnSpace, height: (bottomRow - topRow) * parentRowSpace - }; - this.setState(widgetState); + } + this.setState(widgetState) } render() { - return this.getWidgetView(); + return this.getWidgetView() } - abstract getWidgetView(): JSX.Element; + getWidgetView(): JSX.Element { + switch (this.props.renderMode) { + case RenderModes.CANVAS: + return this.getCanvasView() + case RenderModes.COMPONENT_PANE: + return this.getComponentPaneView() + case RenderModes.PAGE: + return this.getPageView() + default: + return this.getPageView() + } + } - abstract getWidgetType(): WidgetType; + abstract getPageView(): JSX.Element + + getCanvasView(): JSX.Element { + return this.getPageView() + } + + getComponentPaneView(): JSX.Element { + return this.getPageView() + } + + abstract getWidgetType(): WidgetType } export interface IWidgetState { - height: number; - width: number; + height: number + width: number } export interface IWidgetBuilder { - buildWidget(data: T): JSX.Element; + buildWidget(data: T): JSX.Element } export interface IWidgetProps { - widgetType: WidgetType; - key?: string; - widgetId: string; - topRow: number; - leftColumn: number; - bottomRow: number; - rightColumn: number; - parentColumnSpace: number; - parentRowSpace: number; + widgetType: WidgetType + key?: string + widgetId: string + topRow: number + leftColumn: number + bottomRow: number + rightColumn: number + parentColumnSpace: number + parentRowSpace: number + renderMode: RenderMode } -export default BaseWidget; +export default BaseWidget diff --git a/app/client/src/widgets/ButtonWidget.tsx b/app/client/src/widgets/ButtonWidget.tsx index 6dabcd26b0..8e81e750d4 100644 --- a/app/client/src/widgets/ButtonWidget.tsx +++ b/app/client/src/widgets/ButtonWidget.tsx @@ -10,7 +10,7 @@ class ButtonWidget extends BaseWidget { super(widgetProps) } - getWidgetView() { + getPageView() { return ( { super(widgetProps); } - getWidgetView() { + getPageView() { return ( { super(widgetProps); } - getWidgetView() { + getPageView() { return ( { super(widgetProps); } - getWidgetView() { + getPageView() { return ( { super(widgetProps) } - getWidgetView() { + getPageView() { return (