2019-10-03 16:24:29 +00:00
|
|
|
import React, { Component, Context, createContext } from "react";
|
2019-09-09 10:30:22 +00:00
|
|
|
import { connect } from "react-redux";
|
|
|
|
|
import styled from "styled-components";
|
|
|
|
|
import Canvas from "./Canvas";
|
2019-09-17 15:09:55 +00:00
|
|
|
import {
|
|
|
|
|
WidgetCardProps,
|
|
|
|
|
WidgetProps,
|
2019-09-19 22:25:37 +00:00
|
|
|
WidgetOperation,
|
2019-10-03 16:24:29 +00:00
|
|
|
WidgetFunctions,
|
2019-09-17 15:09:55 +00:00
|
|
|
} from "../../widgets/BaseWidget";
|
2019-09-09 10:30:22 +00:00
|
|
|
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";
|
2019-09-18 10:48:56 +00:00
|
|
|
import { fetchPage, updateWidget, savePage } from "../../actions/pageActions";
|
2019-09-09 10:30:22 +00:00
|
|
|
import { RenderModes } from "../../constants/WidgetConstants";
|
2019-09-18 10:58:21 +00:00
|
|
|
import { executeAction } from "../../actions/widgetActions";
|
2019-09-17 10:11:50 +00:00
|
|
|
import { ActionPayload } from "../../constants/ActionConstants";
|
2019-09-18 10:19:50 +00:00
|
|
|
import PropertyPane from "./PropertyPane";
|
2019-08-20 13:19:19 +00:00
|
|
|
|
2019-08-29 11:22:09 +00:00
|
|
|
const CanvasContainer = styled.section`
|
2019-08-20 13:19:19 +00:00
|
|
|
height: 100%;
|
|
|
|
|
width: 100%;
|
|
|
|
|
position: relative;
|
2019-09-25 17:24:23 +00:00
|
|
|
overflow-x: auto;
|
2019-08-20 13:19:19 +00:00
|
|
|
overflow-y: auto;
|
|
|
|
|
margin: 0px 10px;
|
2019-08-26 12:41:21 +00:00
|
|
|
&:before {
|
|
|
|
|
position: absolute;
|
2019-09-09 09:08:54 +00:00
|
|
|
top: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
2019-08-26 12:41:21 +00:00
|
|
|
pointer-events: none;
|
|
|
|
|
}
|
2019-08-20 13:19:19 +00:00
|
|
|
`;
|
2019-02-07 05:07:09 +00:00
|
|
|
|
2019-08-26 12:41:21 +00:00
|
|
|
const EditorWrapper = styled.div`
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
align-items: stretch;
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
width: 100vw;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
height: calc(100vh - 60px);
|
2019-08-29 11:22:09 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
type EditorProps = {
|
2019-09-19 22:25:37 +00:00
|
|
|
dsl: ContainerWidgetProps<WidgetProps> | any;
|
2019-08-29 11:22:09 +00:00
|
|
|
fetchCanvasWidgets: Function;
|
2019-09-17 10:11:50 +00:00
|
|
|
executeAction: (actionPayloads?: ActionPayload[]) => void;
|
2019-09-19 22:25:37 +00:00
|
|
|
updateWidget: Function;
|
2019-09-06 09:30:22 +00:00
|
|
|
cards: { [id: string]: WidgetCardProps[] } | any;
|
2019-09-18 10:48:56 +00:00
|
|
|
savePageLayout: Function;
|
2019-09-27 08:08:31 +00:00
|
|
|
currentPageName: string;
|
2019-09-18 10:48:56 +00:00
|
|
|
currentPageId: string;
|
|
|
|
|
currentLayoutId: string;
|
2019-09-23 10:27:45 +00:00
|
|
|
isSaving: boolean;
|
2019-09-09 10:30:22 +00:00
|
|
|
};
|
2019-08-26 12:41:21 +00:00
|
|
|
|
2019-10-03 16:24:29 +00:00
|
|
|
export const WidgetFunctionsContext: Context<WidgetFunctions> = createContext(
|
|
|
|
|
{},
|
|
|
|
|
);
|
|
|
|
|
|
2019-08-29 11:22:09 +00:00
|
|
|
class Editor extends Component<EditorProps> {
|
2019-08-26 12:41:21 +00:00
|
|
|
componentDidMount() {
|
2019-09-18 10:48:56 +00:00
|
|
|
this.props.fetchCanvasWidgets(this.props.currentPageId);
|
2019-08-26 12:41:21 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-29 11:22:09 +00:00
|
|
|
public render() {
|
2019-02-07 05:07:09 +00:00
|
|
|
return (
|
2019-10-03 16:24:29 +00:00
|
|
|
<WidgetFunctionsContext.Provider
|
|
|
|
|
value={{
|
|
|
|
|
executeAction: this.props.executeAction,
|
|
|
|
|
updateWidget: this.props.updateWidget,
|
|
|
|
|
}}
|
|
|
|
|
>
|
2019-09-27 08:08:31 +00:00
|
|
|
<EditorHeader
|
|
|
|
|
notificationText={this.props.isSaving ? "Saving page..." : undefined}
|
|
|
|
|
pageName={this.props.currentPageName}
|
|
|
|
|
/>
|
2019-08-26 12:41:21 +00:00
|
|
|
<EditorWrapper>
|
|
|
|
|
<WidgetCardsPane cards={this.props.cards} />
|
2019-08-29 11:22:09 +00:00
|
|
|
<CanvasContainer>
|
2019-10-03 16:24:29 +00:00
|
|
|
{this.props.dsl && <Canvas dsl={this.props.dsl} />}
|
2019-08-29 11:22:09 +00:00
|
|
|
</CanvasContainer>
|
2019-09-18 10:19:50 +00:00
|
|
|
<PropertyPane />
|
2019-08-26 12:41:21 +00:00
|
|
|
</EditorWrapper>
|
2019-10-03 16:24:29 +00:00
|
|
|
</WidgetFunctionsContext.Provider>
|
2019-09-09 10:30:22 +00:00
|
|
|
);
|
2019-02-07 05:07:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-09 10:30:22 +00:00
|
|
|
const mapStateToProps = (state: AppState): EditorReduxState => {
|
2019-09-25 17:24:23 +00:00
|
|
|
// TODO(abhinav) : Benchmark this, see how many times this is called in the application
|
|
|
|
|
// lifecycle. Move to using flattend redux state for widgets if necessary.
|
|
|
|
|
|
|
|
|
|
// Also, try to merge the widgetCards and widgetConfigs in the fetch Saga.
|
|
|
|
|
// No point in storing widgetCards, without widgetConfig
|
|
|
|
|
// Alternatively, try to see if we can continue to use only WidgetConfig and eliminate WidgetCards
|
|
|
|
|
|
2019-09-19 22:25:37 +00:00
|
|
|
const dsl = CanvasWidgetsNormalizer.denormalize(
|
2019-09-17 15:09:55 +00:00
|
|
|
state.ui.editor.pageWidgetId,
|
2019-09-09 10:30:22 +00:00
|
|
|
state.entities,
|
|
|
|
|
);
|
2019-09-25 17:24:23 +00:00
|
|
|
|
2019-09-27 16:05:33 +00:00
|
|
|
const cards = state.ui.editor.cards;
|
|
|
|
|
const groups: string[] = Object.keys(cards);
|
|
|
|
|
groups.forEach((group: string) => {
|
2019-10-02 18:13:04 +00:00
|
|
|
cards[group] = cards[group].map((widget: WidgetCardProps) => {
|
|
|
|
|
const { rows, columns } = state.entities.widgetConfig.config[widget.type];
|
|
|
|
|
return { ...widget, rows, columns };
|
|
|
|
|
});
|
2019-09-25 17:24:23 +00:00
|
|
|
});
|
|
|
|
|
|
2019-08-26 12:41:21 +00:00
|
|
|
return {
|
2019-09-25 17:24:23 +00:00
|
|
|
cards,
|
2019-09-19 22:25:37 +00:00
|
|
|
dsl,
|
2019-09-17 15:09:55 +00:00
|
|
|
pageWidgetId: state.ui.editor.pageWidgetId,
|
2019-09-18 10:48:56 +00:00
|
|
|
currentPageId: state.ui.editor.currentPageId,
|
|
|
|
|
currentLayoutId: state.ui.editor.currentLayoutId,
|
2019-09-27 08:08:31 +00:00
|
|
|
currentPageName: state.ui.editor.currentPageName,
|
2019-09-23 10:27:45 +00:00
|
|
|
isSaving: state.ui.editor.isSaving,
|
2019-09-09 10:30:22 +00:00
|
|
|
};
|
|
|
|
|
};
|
2019-08-26 12:41:21 +00:00
|
|
|
|
|
|
|
|
const mapDispatchToProps = (dispatch: any) => {
|
|
|
|
|
return {
|
2019-09-17 10:11:50 +00:00
|
|
|
executeAction: (actionPayloads?: ActionPayload[]) =>
|
|
|
|
|
dispatch(executeAction(actionPayloads)),
|
2019-09-09 10:30:22 +00:00
|
|
|
fetchCanvasWidgets: (pageId: string) =>
|
|
|
|
|
dispatch(fetchPage(pageId, RenderModes.CANVAS)),
|
2019-09-19 22:25:37 +00:00
|
|
|
updateWidget: (
|
|
|
|
|
operation: WidgetOperation,
|
|
|
|
|
widgetId: string,
|
2019-09-17 15:09:55 +00:00
|
|
|
payload: any,
|
2019-09-19 22:25:37 +00:00
|
|
|
) => dispatch(updateWidget(operation, widgetId, payload)),
|
2019-09-18 10:48:56 +00:00
|
|
|
savePageLayout: (
|
|
|
|
|
pageId: string,
|
|
|
|
|
layoutId: string,
|
|
|
|
|
dsl: ContainerWidgetProps<WidgetProps>,
|
|
|
|
|
) => dispatch(savePage(pageId, layoutId, dsl)),
|
2019-09-09 10:30:22 +00:00
|
|
|
};
|
|
|
|
|
};
|
2019-08-26 12:41:21 +00:00
|
|
|
|
|
|
|
|
export default connect(
|
|
|
|
|
mapStateToProps,
|
2019-09-09 10:30:22 +00:00
|
|
|
mapDispatchToProps,
|
|
|
|
|
)(Editor);
|