PromucFlow_constructor/app/client/src/widgets/BaseWidget.tsx

177 lines
4.1 KiB
TypeScript
Raw Normal View History

/***
* Widget are responsible for accepting the abstraction layer inputs, interpretting them into rederable props and
* spawing components based on those props
* Widgets are also responsible for dispatching actions and updating the state tree
*/
import {
WidgetType,
RenderMode,
2019-03-19 14:05:48 +00:00
RenderModes,
CSSUnits
} from "../constants/WidgetConstants"
import { Component } from "react"
import { BaseStyle } from "../editorComponents/BaseComponent"
import _ from "lodash"
2019-04-01 07:08:00 +00:00
import * as React from "react"
import ContainerWidget from "./ContainerWidget"
import ContainerComponent from "../editorComponents/ContainerComponent"
import DraggableComponent from "../editorComponents/DraggableComponent"
abstract class BaseWidget<
T extends IWidgetProps,
K extends IWidgetState
> extends Component<T, K> {
constructor(props: T) {
super(props)
const initialState: IWidgetState = {
height: 0,
width: 0
}
2019-03-19 15:21:27 +00:00
initialState.height = 0
initialState.width = 0
this.state = initialState as K
}
componentDidMount(): void {
this.calculateWidgetBounds(
this.props.rightColumn,
this.props.leftColumn,
this.props.topRow,
this.props.bottomRow,
this.props.parentColumnSpace,
this.props.parentRowSpace
)
}
componentDidUpdate(prevProps: T) {
this.calculateWidgetBounds(
this.props.rightColumn,
this.props.leftColumn,
this.props.topRow,
this.props.bottomRow,
this.props.parentColumnSpace,
this.props.parentRowSpace
)
}
calculateWidgetBounds(
rightColumn: number,
leftColumn: number,
topRow: number,
bottomRow: number,
parentColumnSpace: number,
parentRowSpace: number
) {
const widgetState: IWidgetState = {
width: (rightColumn - leftColumn) * parentColumnSpace,
height: (bottomRow - topRow) * parentRowSpace
}
if (
_.isNil(this.state) ||
widgetState.height !== this.state.height ||
widgetState.width !== this.state.width
) {
2019-08-26 12:41:21 +00:00
// console.log("*** " + this.props.widgetId + " " + JSON.stringify(widgetState))
this.setState(widgetState)
}
}
render() {
return this.getWidgetView()
}
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 getPageView(): JSX.Element
getCanvasView(): JSX.Element {
return this.getPageView()
}
getComponentPaneView(): JSX.Element {
2019-04-01 07:08:00 +00:00
return (
<DraggableComponent
2019-04-01 07:08:00 +00:00
{...this.props}
style={{
...this.getPositionStyle()
}}
orientation={"VERTICAL"}
>
{this.getPageView()}
</DraggableComponent>
2019-04-01 07:08:00 +00:00
)
}
abstract getWidgetType(): WidgetType
2019-03-19 14:05:48 +00:00
getPositionStyle(): BaseStyle {
return {
positionType:
this.props.renderMode !== RenderModes.PAGE
? "CONTAINER_DIRECTION"
: "ABSOLUTE",
2019-03-19 15:21:27 +00:00
height: this.state.height,
width: this.state.width,
2019-03-19 14:05:48 +00:00
yPosition: this.props.topRow * this.props.parentRowSpace,
xPosition: this.props.leftColumn * this.props.parentColumnSpace,
xPositionUnit: CSSUnits.PIXEL,
yPositionUnit: CSSUnits.PIXEL
}
}
static defaultProps: Partial<IWidgetProps> = {
parentRowSpace: 1,
parentColumnSpace: 1,
topRow: 0,
leftColumn: 0
}
}
export interface IWidgetState {
height: number
width: number
}
2019-08-26 12:41:21 +00:00
export interface DraggableWidget {
type: string,
widget: IWidgetProps
}
export interface IWidgetBuilder<T extends IWidgetProps> {
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
renderMode: RenderMode
}
2019-08-21 12:49:16 +00:00
export interface IWidgetCardProps {
widgetType: WidgetType
key?: string
label: string
icon: string
groups: string[]
}
export default BaseWidget