import React, { Component } from "react"; import { Helmet } from "react-helmet"; import { connect } from "react-redux"; import { RouteComponentProps, withRouter } from "react-router-dom"; import { BuilderRouteParams } from "constants/routes"; import { AppState } from "reducers"; import MainContainer from "./MainContainer"; import { DndProvider } from "react-dnd"; import TouchBackend from "react-dnd-touch-backend"; import { getCurrentApplicationId, getCurrentPageId, getIsEditorInitialized, getIsEditorLoading, getIsPublishingApplication, getPublishingError, } from "selectors/editorSelectors"; import { Hotkey, Hotkeys, Spinner } from "@blueprintjs/core"; import { HotkeysTarget } from "@blueprintjs/core/lib/esnext/components/hotkeys/hotkeysTarget.js"; import { initEditor } from "actions/initActions"; import { editorInitializer } from "utils/EditorUtils"; import { ENTITY_EXPLORER_SEARCH_ID, WIDGETS_SEARCH_ID, } from "constants/Explorer"; import CenteredWrapper from "components/designSystems/appsmith/CenteredWrapper"; import { getCurrentUser } from "selectors/usersSelectors"; import { User } from "constants/userConstants"; import ConfirmRunModal from "pages/Editor/ConfirmRunModal"; import * as Sentry from "@sentry/react"; import { copyWidget, cutWidget, deleteSelectedWidget, pasteWidget, } from "actions/widgetActions"; import { isMac } from "utils/helpers"; import { getSelectedWidget } from "selectors/ui"; import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; import Welcome from "./Welcome"; import { getThemeDetails, ThemeMode } from "selectors/themeSelectors"; import { ThemeProvider } from "styled-components"; import { Theme } from "constants/DefaultTheme"; type EditorProps = { currentApplicationId?: string; currentPageId?: string; initEditor: (applicationId: string, pageId: string) => void; isPublishing: boolean; isEditorLoading: boolean; isEditorInitialized: boolean; isEditorInitializeError: boolean; errorPublishing: boolean; creatingOnboardingDatabase: boolean; copySelectedWidget: () => void; pasteCopiedWidget: () => void; deleteSelectedWidget: () => void; cutSelectedWidget: () => void; user?: User; selectedWidget?: string; lightTheme: Theme; }; type Props = EditorProps & RouteComponentProps; const getSelectedText = () => { if (typeof window.getSelection === "function") { const selectionObj = window.getSelection(); return selectionObj && selectionObj.toString(); } }; @HotkeysTarget class Editor extends Component { public stopPropagationIfWidgetSelected(e: KeyboardEvent): boolean { if ( this.props.selectedWidget && this.props.selectedWidget != MAIN_CONTAINER_WIDGET_ID && !getSelectedText() ) { e.preventDefault(); e.stopPropagation(); return true; } return false; } public renderHotkeys() { return ( { const entitySearchInput = document.getElementById( ENTITY_EXPLORER_SEARCH_ID, ); const widgetSearchInput = document.getElementById( WIDGETS_SEARCH_ID, ); if (entitySearchInput) entitySearchInput.focus(); if (widgetSearchInput) widgetSearchInput.focus(); e.preventDefault(); e.stopPropagation(); }} /> { if (this.stopPropagationIfWidgetSelected(e)) { this.props.copySelectedWidget(); } }} /> { this.props.pasteCopiedWidget(); }} /> { if (this.stopPropagationIfWidgetSelected(e) && isMac()) { this.props.deleteSelectedWidget(); } }} /> { if (this.stopPropagationIfWidgetSelected(e)) { this.props.deleteSelectedWidget(); } }} /> { if (this.stopPropagationIfWidgetSelected(e)) { this.props.cutSelectedWidget(); } }} /> ); } public state = { registered: false, }; componentDidMount() { editorInitializer().then(() => { this.setState({ registered: true }); }); const { applicationId, pageId } = this.props.match.params; if (applicationId && pageId) { this.props.initEditor(applicationId, pageId); } } shouldComponentUpdate(nextProps: Props, nextState: { registered: boolean }) { return ( nextProps.currentPageId !== this.props.currentPageId || nextProps.currentApplicationId !== this.props.currentApplicationId || nextProps.isEditorInitialized !== this.props.isEditorInitialized || nextProps.isPublishing !== this.props.isPublishing || nextProps.isEditorLoading !== this.props.isEditorLoading || nextProps.errorPublishing !== this.props.errorPublishing || nextProps.isEditorInitializeError !== this.props.isEditorInitializeError || nextProps.creatingOnboardingDatabase !== this.props.creatingOnboardingDatabase || nextState.registered !== this.state.registered ); } public render() { if (this.props.creatingOnboardingDatabase) { return ; } if (!this.props.isEditorInitialized || !this.state.registered) { return ( ); } return (
Editor | Appsmith
); } } const mapStateToProps = (state: AppState) => ({ currentApplicationId: getCurrentApplicationId(state), currentPageId: getCurrentPageId(state), errorPublishing: getPublishingError(state), isPublishing: getIsPublishingApplication(state), isEditorLoading: getIsEditorLoading(state), isEditorInitialized: getIsEditorInitialized(state), user: getCurrentUser(state), selectedWidget: getSelectedWidget(state), creatingOnboardingDatabase: state.ui.onBoarding.showOnboardingLoader, lightTheme: getThemeDetails(state, ThemeMode.LIGHT), }); const mapDispatchToProps = (dispatch: any) => { return { initEditor: (applicationId: string, pageId: string) => dispatch(initEditor(applicationId, pageId)), copySelectedWidget: () => dispatch(copyWidget(true)), pasteCopiedWidget: () => dispatch(pasteWidget()), deleteSelectedWidget: () => dispatch(deleteSelectedWidget(true)), cutSelectedWidget: () => dispatch(cutWidget()), }; }; export default withRouter( connect(mapStateToProps, mapDispatchToProps)(Sentry.withProfiler(Editor)), );