PromucFlow_constructor/app/client/src/pages/Editor/routes.tsx
2022-12-02 11:19:51 +05:30

193 lines
5.8 KiB
TypeScript

import React, { useEffect, ReactNode, useCallback } from "react";
import { Switch, Route } from "react-router-dom";
import { useLocation, useRouteMatch } from "react-router";
import ApiEditor from "./APIEditor";
import IntegrationEditor from "./IntegrationEditor";
import QueryEditor from "./QueryEditor";
import DataSourceEditor from "./DataSourceEditor";
import JSEditor from "./JSEditor";
import GeneratePage from "./GeneratePage";
import CurlImportForm from "./APIEditor/CurlImportForm";
import ProviderTemplates from "./APIEditor/ProviderTemplates";
import {
INTEGRATION_EDITOR_PATH,
API_EDITOR_ID_PATH,
QUERIES_EDITOR_ID_PATH,
JS_COLLECTION_EDITOR_PATH,
JS_COLLECTION_ID_PATH,
CURL_IMPORT_PAGE_PATH,
DATA_SOURCES_EDITOR_ID_PATH,
PROVIDER_TEMPLATE_PATH,
GENERATE_TEMPLATE_FORM_PATH,
matchBuilderPath,
BUILDER_CHECKLIST_PATH,
} from "constants/routes";
import styled from "styled-components";
import { useShowPropertyPane } from "utils/hooks/dragResizeHooks";
import { closeAllModals } from "actions/widgetActions";
import { useDispatch, useSelector } from "react-redux";
import PerformanceTracker, {
PerformanceTransactionName,
} from "utils/PerformanceTracker";
import * as Sentry from "@sentry/react";
const SentryRoute = Sentry.withSentryRouting(Route);
import { SaaSEditorRoutes } from "./SaaSEditor/routes";
import { useWidgetSelection } from "utils/hooks/useWidgetSelection";
import { builderURL } from "RouteBuilder";
import history from "utils/history";
import OnboardingChecklist from "./FirstTimeUserOnboarding/Checklist";
import { getCurrentPageId } from "selectors/editorSelectors";
const Wrapper = styled.div<{ isVisible: boolean }>`
position: absolute;
top: 0;
left: 0;
width: ${(props) => (!props.isVisible ? "0px" : "100%")};
height: 100%;
background-color: ${(props) =>
props.isVisible ? "rgba(0, 0, 0, 0.26)" : "transparent"};
z-index: ${(props) => (props.isVisible ? 2 : -1)};
`;
const DrawerWrapper = styled.div<{
isVisible: boolean;
}>`
background-color: white;
width: ${(props) => (!props.isVisible ? "0" : "100%")};
height: 100%;
display: flex;
flex-direction: column;
`;
function EditorsRouter() {
const { path } = useRouteMatch();
const { pathname } = useLocation();
const [isVisible, setIsVisible] = React.useState(
() => !matchBuilderPath(pathname),
);
const pageId = useSelector(getCurrentPageId);
useEffect(() => {
const isOnBuilder = matchBuilderPath(pathname);
setIsVisible(!isOnBuilder);
}, [pathname]);
const handleClose = useCallback(
(e: React.MouseEvent) => {
PerformanceTracker.startTracking(
PerformanceTransactionName.CLOSE_SIDE_PANE,
{ path: pathname },
);
e.stopPropagation();
setIsVisible(false);
history.replace(builderURL({ pageId }));
},
[pathname, pageId],
);
const preventClose = useCallback((e: React.MouseEvent) => {
e.stopPropagation();
}, []);
return (
<Wrapper isVisible={isVisible} onClick={handleClose}>
<PaneDrawer isVisible={isVisible} onClick={preventClose}>
<Switch key={path}>
<SentryRoute
component={IntegrationEditor}
exact
path={`${path}${INTEGRATION_EDITOR_PATH}`}
/>
<SentryRoute
component={OnboardingChecklist}
exact
path={`${path}${BUILDER_CHECKLIST_PATH}`}
/>
<SentryRoute
component={ApiEditor}
exact
path={`${path}${API_EDITOR_ID_PATH}`}
/>
<SentryRoute
component={QueryEditor}
exact
path={`${path}${QUERIES_EDITOR_ID_PATH}`}
/>
<SentryRoute
component={JSEditor}
exact
path={`${path}${JS_COLLECTION_EDITOR_PATH}`}
/>
<SentryRoute
component={JSEditor}
exact
path={`${path}${JS_COLLECTION_ID_PATH}`}
/>
<SentryRoute
component={CurlImportForm}
exact
path={`${path}${CURL_IMPORT_PAGE_PATH}`}
/>
{SaaSEditorRoutes.map(({ component, path: childPath }) => (
<SentryRoute
component={component}
exact
key={path}
path={`${path}${childPath}`}
/>
))}
<SentryRoute
component={DataSourceEditor}
exact
path={`${path}${DATA_SOURCES_EDITOR_ID_PATH}`}
/>
<SentryRoute
component={ProviderTemplates}
exact
path={`${path}${PROVIDER_TEMPLATE_PATH}`}
/>
<SentryRoute
component={GeneratePage}
exact
path={`${path}${GENERATE_TEMPLATE_FORM_PATH}`}
/>
</Switch>
</PaneDrawer>
</Wrapper>
);
}
type PaneDrawerProps = {
isVisible: boolean;
onClick: (e: React.MouseEvent) => void;
children: ReactNode;
};
function PaneDrawer(props: PaneDrawerProps) {
const showPropertyPane = useShowPropertyPane();
const { focusWidget, selectWidget } = useWidgetSelection();
const dispatch = useDispatch();
useEffect(() => {
// This pane drawer is only open when NOT on canvas.
// De-select all widgets
// Un-focus all widgets
// Hide property pane
// Close all modals
if (props.isVisible) {
showPropertyPane();
dispatch(closeAllModals());
// delaying setting select and focus state,
// so that the focus history has time to store the selected values
setTimeout(() => {
selectWidget(undefined);
focusWidget(undefined);
}, 0);
}
}, [dispatch, props.isVisible, selectWidget, showPropertyPane, focusWidget]);
return <DrawerWrapper {...props}>{props.children}</DrawerWrapper>;
}
PaneDrawer.displayName = "PaneDrawer";
export default EditorsRouter;