created seperate render modes for widgets

added widget pane
This commit is contained in:
Nikhil Nandgopal 2019-03-18 20:40:30 +05:30
parent 9921154045
commit 3d7b7cef32
18 changed files with 176 additions and 38 deletions

View File

@ -1,11 +1,13 @@
import ContainerWidget from "../widgets/ContainerWidget" 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 } = { export const ActionTypes: { [id: string]: ActionType } = {
LOAD_CANVAS: "LOAD_CANVAS", LOAD_CANVAS: "LOAD_CANVAS",
CLEAR_CANVAS: "CLEAR_CANVAS", CLEAR_CANVAS: "CLEAR_CANVAS",
DROP_WIDGET_CANVAS: "DROP_WIDGET_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<T> { export interface ReduxAction<T> {
@ -15,4 +17,8 @@ export interface ReduxAction<T> {
export interface LoadCanvasPayload { export interface LoadCanvasPayload {
containerWidget: ContainerWidget containerWidget: ContainerWidget
}
export interface LoadWidgetPanePayload {
widgets: IWidgetProps[]
} }

View File

@ -27,6 +27,15 @@ export type CSSUnit =
| "vmax" | "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 } = { export const CSSUnits: { [id: string]: CSSUnit } = {
PIXEL: "px", PIXEL: "px",
RELATIVE_FONTSIZE: "em", RELATIVE_FONTSIZE: "em",

View File

@ -3,6 +3,7 @@ import { IWidgetProps } from "../widgets/BaseWidget";
import ContainerWidget, { import ContainerWidget, {
IContainerWidgetProps IContainerWidgetProps
} from "../widgets/ContainerWidget"; } from "../widgets/ContainerWidget";
import { RenderModes } from "../constants/WidgetConstants";
const CanvasResponse: IContainerWidgetProps<any> = { const CanvasResponse: IContainerWidgetProps<any> = {
widgetId: "0", widgetId: "0",
@ -15,6 +16,7 @@ const CanvasResponse: IContainerWidgetProps<any> = {
rightColumn: 1200, rightColumn: 1200,
parentColumnSpace: 1, parentColumnSpace: 1,
parentRowSpace: 1, parentRowSpace: 1,
renderMode: RenderModes.CANVAS,
children: [ children: [
{ {
widgetId: "1", widgetId: "1",
@ -23,7 +25,18 @@ const CanvasResponse: IContainerWidgetProps<any> = {
leftColumn: 5, leftColumn: 5,
bottomRow: 5, bottomRow: 5,
rightColumn: 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", widgetId: "2",
@ -32,7 +45,8 @@ const CanvasResponse: IContainerWidgetProps<any> = {
leftColumn: 1, leftColumn: 1,
bottomRow: 5, bottomRow: 5,
rightColumn: 5, rightColumn: 5,
placeholder: "Lorem Ipsum" placeholder: "Lorem Ipsum",
renderMode: RenderModes.CANVAS
}, },
{ {
widgetId: "3", widgetId: "3",
@ -46,7 +60,8 @@ const CanvasResponse: IContainerWidgetProps<any> = {
description: 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 <div> element.", "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 <div> element.",
icon: "", icon: "",
intent: "success" intent: "success",
renderMode: RenderModes.CANVAS
}, },
{ {
widgetId: "4", widgetId: "4",
@ -57,7 +72,8 @@ const CanvasResponse: IContainerWidgetProps<any> = {
rightColumn: 5, rightColumn: 5,
icon: "globe", icon: "globe",
iconSize: "20", iconSize: "20",
intent: "warning" intent: "warning",
renderMode: RenderModes.CANVAS
}, },
{ {
widgetId: "5", widgetId: "5",
@ -66,7 +82,8 @@ const CanvasResponse: IContainerWidgetProps<any> = {
leftColumn: 6, leftColumn: 6,
bottomRow: 5, bottomRow: 5,
rightColumn: 5, rightColumn: 5,
size: 20 size: 20,
renderMode: RenderModes.CANVAS
} }
] ]
}; };

View File

@ -0,0 +1,13 @@
import { WidgetPaneReduxState } from "../reducers/uiReducers/widgetPaneReducer";
const WidgetPaneResponse: WidgetPaneReduxState = {
widgets: [
{
widgetType: "BUTTON_WIDGET",
text: "lorem ipsum",
}
]
}
export default WidgetPaneResponse

View File

@ -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<WidgetPaneReduxState> {
render() {
return (<div>
{this.props.widgets.map((widget: IWidgetProps) => {
return WidgetFactory.createWidget(widget)
})}
</div>)
}
}
const mapStateToProps = (state: AppState, props: any): WidgetPaneReduxState => {
return {
widgets: state.ui.widgetPaneReducer.widgets
}
}
const mapDispatchToProps = (dispatch: any) => {
return {}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(WidgetPane)

View File

@ -3,6 +3,7 @@ import entityReducer from "./entityReducers"
import uiReducer from "./uiReducers" import uiReducer from "./uiReducers"
import { CanvasReduxState } from "./uiReducers/canvasReducer" import { CanvasReduxState } from "./uiReducers/canvasReducer"
import { CanvasWidgetsReduxState } from "./entityReducers/canvasWidgetsReducers" import { CanvasWidgetsReduxState } from "./entityReducers/canvasWidgetsReducers"
import { WidgetPaneReduxState } from "./uiReducers/widgetPaneReducer";
const appReducer = combineReducers({ const appReducer = combineReducers({
entities: entityReducer, entities: entityReducer,
@ -13,7 +14,8 @@ export default appReducer
export interface AppState { export interface AppState {
ui: { ui: {
canvas: CanvasReduxState<any> canvas: CanvasReduxState<any>,
widgetPaneReducer: WidgetPaneReduxState
} }
entities: { entities: {
canvasWidgets: CanvasWidgetsReduxState canvasWidgets: CanvasWidgetsReduxState

View File

@ -1,5 +1,6 @@
import { combineReducers } from "redux" import { combineReducers } from "redux"
import canvasReducer from "./canvasReducer" import canvasReducer from "./canvasReducer"
import widgetPaneReducer from "./widgetPaneReducer";
const uiReducer = combineReducers({ canvas: canvasReducer }) const uiReducer = combineReducers({ canvas: canvasReducer, componentPane: widgetPaneReducer })
export default uiReducer export default uiReducer

View File

@ -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<LoadWidgetPanePayload>
) => {
return { widgets: action.payload.widgets }
}
})
export interface WidgetPaneReduxState {
widgets: Partial<IWidgetProps | any>[]
}
export default widgetPaneReducer

View File

@ -31,6 +31,12 @@ class WidgetBuilderRegistry {
} }
}); });
WidgetFactory.registerWidgetBuilder("BUTTON_WIDGET", {
buildWidget(widgetData: IButtonWidgetProps): JSX.Element {
return <ButtonWidget {...widgetData} />;
}
});
WidgetFactory.registerWidgetBuilder("CALLOUT_WIDGET", { WidgetFactory.registerWidgetBuilder("CALLOUT_WIDGET", {
buildWidget(widgetData: ICalloutWidgetProps): JSX.Element { buildWidget(widgetData: ICalloutWidgetProps): JSX.Element {
return <CalloutWidget {...widgetData} />; return <CalloutWidget {...widgetData} />;

View File

@ -3,8 +3,12 @@
* spawing components based on those props * spawing components based on those props
* Widgets are also responsible for dispatching actions and updating the state tree * Widgets are also responsible for dispatching actions and updating the state tree
*/ */
import { WidgetType } from "../constants/WidgetConstants"; import {
import { Component } from "react"; WidgetType,
RenderMode,
RenderModes
} from "../constants/WidgetConstants"
import { Component } from "react"
abstract class BaseWidget< abstract class BaseWidget<
T extends IWidgetProps, T extends IWidgetProps,
@ -18,7 +22,7 @@ abstract class BaseWidget<
this.props.bottomRow, this.props.bottomRow,
this.props.parentColumnSpace, this.props.parentColumnSpace,
this.props.parentRowSpace this.props.parentRowSpace
); )
} }
componentWillReceiveProps(prevProps: T, nextProps: T) { componentWillReceiveProps(prevProps: T, nextProps: T) {
@ -29,7 +33,7 @@ abstract class BaseWidget<
nextProps.bottomRow, nextProps.bottomRow,
nextProps.parentColumnSpace, nextProps.parentColumnSpace,
nextProps.parentRowSpace nextProps.parentRowSpace
); )
} }
calculateWidgetBounds( calculateWidgetBounds(
@ -43,38 +47,60 @@ abstract class BaseWidget<
const widgetState: IWidgetState = { const widgetState: IWidgetState = {
width: (rightColumn - leftColumn) * parentColumnSpace, width: (rightColumn - leftColumn) * parentColumnSpace,
height: (bottomRow - topRow) * parentRowSpace height: (bottomRow - topRow) * parentRowSpace
}; }
this.setState(widgetState); this.setState(widgetState)
} }
render() { 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 { export interface IWidgetState {
height: number; height: number
width: number; width: number
} }
export interface IWidgetBuilder<T extends IWidgetProps> { export interface IWidgetBuilder<T extends IWidgetProps> {
buildWidget(data: T): JSX.Element; buildWidget(data: T): JSX.Element
} }
export interface IWidgetProps { export interface IWidgetProps {
widgetType: WidgetType; widgetType: WidgetType
key?: string; key?: string
widgetId: string; widgetId: string
topRow: number; topRow: number
leftColumn: number; leftColumn: number
bottomRow: number; bottomRow: number
rightColumn: number; rightColumn: number
parentColumnSpace: number; parentColumnSpace: number
parentRowSpace: number; parentRowSpace: number
renderMode: RenderMode
} }
export default BaseWidget; export default BaseWidget

View File

@ -10,7 +10,7 @@ class ButtonWidget extends BaseWidget<IButtonWidgetProps, IWidgetState> {
super(widgetProps) super(widgetProps)
} }
getWidgetView() { getPageView() {
return ( return (
<ButtonComponent <ButtonComponent
style={{ style={{

View File

@ -10,7 +10,7 @@ class CalloutWidget extends BaseWidget<ICalloutWidgetProps, IWidgetState> {
super(widgetProps); super(widgetProps);
} }
getWidgetView() { getPageView() {
return ( return (
<CalloutComponent <CalloutComponent
style={{ style={{

View File

@ -47,7 +47,7 @@ class ContainerWidget extends BaseWidget<
return WidgetFactory.createWidget(childWidgetData); return WidgetFactory.createWidget(childWidgetData);
} }
getWidgetView() { getPageView() {
return ( return (
<ContainerComponent <ContainerComponent
widgetId={this.props.widgetId} widgetId={this.props.widgetId}

View File

@ -11,7 +11,7 @@ class IconWidget extends BaseWidget<IIconWidgetProps, IWidgetState> {
super(widgetProps); super(widgetProps);
} }
getWidgetView() { getPageView() {
return ( return (
<IconComponent <IconComponent
style={{ style={{

View File

@ -13,7 +13,7 @@ class InputGroupWidget extends BaseWidget<
super(widgetProps); super(widgetProps);
} }
getWidgetView() { getPageView() {
return ( return (
<InputGroupComponent <InputGroupComponent
style={{ style={{

View File

@ -10,7 +10,7 @@ class SpinnerWidget extends BaseWidget<ISpinnerWidgetProps, IWidgetState> {
super(widgetProps); super(widgetProps);
} }
getWidgetView() { getPageView() {
return ( return (
<SpinnerComponent <SpinnerComponent
style={{ style={{

View File

@ -9,7 +9,7 @@ class TextWidget extends BaseWidget<ITextWidgetProps, IWidgetState> {
super(widgetProps) super(widgetProps)
} }
getWidgetView() { getPageView() {
return ( return (
<TextComponent <TextComponent
style={{ style={{