-
Notifications
You must be signed in to change notification settings - Fork 4.5k
chore: decouple editor components #37102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,6 @@ import { | |
| WIDGETS_EDITOR_ID_PATH, | ||
| } from "constants/routes"; | ||
| import CreateNewDatasourceTab from "pages/Editor/IntegrationEditor/CreateNewDatasourceTab"; | ||
| import OnboardingChecklist from "pages/Editor/FirstTimeUserOnboarding/Checklist"; | ||
| import { | ||
| SAAS_EDITOR_API_ID_ADD_PATH, | ||
| SAAS_EDITOR_API_ID_PATH, | ||
|
|
@@ -38,7 +37,28 @@ import GeneratePage from "pages/Editor/GeneratePage"; | |
| import type { RouteProps } from "react-router"; | ||
| import { useSelector } from "react-redux"; | ||
| import { combinedPreviewModeSelector } from "selectors/editorSelectors"; | ||
| import { lazy, Suspense } from "react"; | ||
| import React from "react"; | ||
|
|
||
| import { retryPromise } from "utils/AppsmithUtils"; | ||
| import Skeleton from "widgets/Skeleton"; | ||
|
|
||
| const FirstTimeUserOnboardingChecklist = lazy(async () => | ||
| retryPromise( | ||
| async () => | ||
| import( | ||
| /* webpackChunkName: "FirstTimeUserOnboardingChecklist" */ "pages/Editor/FirstTimeUserOnboarding/Checklist" | ||
| ), | ||
| ), | ||
| ); | ||
|
Comment on lines
+46
to
+53
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider adding an error boundary for lazy loading failures. The lazy loading implementation is solid with retry capability. However, adding an error boundary would provide a better user experience when the chunk fails to load. class LazyLoadErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <div>Failed to load component. Please refresh the page.</div>;
}
return this.props.children;
}
} |
||
|
|
||
| export const LazilyLoadedFirstTimeUserOnboardingChecklist = () => { | ||
| return ( | ||
| <Suspense fallback={<Skeleton />}> | ||
| <FirstTimeUserOnboardingChecklist /> | ||
| </Suspense> | ||
| ); | ||
| }; | ||
|
Comment on lines
+55
to
+61
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider making the wrapper component more reusable. While the implementation is correct, consider creating a generic wrapper to handle lazy loading of components with consistent loading states. -export const LazilyLoadedFirstTimeUserOnboardingChecklist = () => {
+interface LazyComponentProps {
+ Component: React.LazyExoticComponent<any>;
+}
+
+export const LazyLoadWrapper = ({ Component }: LazyComponentProps) => {
return (
<Suspense fallback={<Skeleton />}>
- <FirstTimeUserOnboardingChecklist />
+ <Component />
</Suspense>
);
};
+
+export const LazilyLoadedFirstTimeUserOnboardingChecklist = () => (
+ <LazyLoadWrapper Component={FirstTimeUserOnboardingChecklist} />
+);
|
||
| export interface RouteReturnType extends RouteProps { | ||
| key: string; | ||
| } | ||
|
|
@@ -95,7 +115,9 @@ function useRoutes(path: string): RouteReturnType[] { | |
| }, | ||
| { | ||
| key: "OnboardingChecklist", | ||
| component: isPreviewMode ? WidgetsEditor : OnboardingChecklist, | ||
| component: isPreviewMode | ||
| ? WidgetsEditor | ||
| : FirstTimeUserOnboardingChecklist, | ||
|
Comment on lines
+118
to
+120
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the wrapper component in route configuration. The route is using the lazy component directly instead of the wrapper component. This could lead to inconsistent loading states across routes. - component: isPreviewMode
- ? WidgetsEditor
- : FirstTimeUserOnboardingChecklist,
+ component: isPreviewMode
+ ? WidgetsEditor
+ : LazilyLoadedFirstTimeUserOnboardingChecklist,
|
||
| exact: true, | ||
| path: `${path}${BUILDER_CHECKLIST_PATH}`, | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,29 @@ | ||
| import React from "react"; | ||
| import React, { lazy, Suspense } from "react"; | ||
| import { MenuContent } from "@appsmith/ads"; | ||
| import styled from "styled-components"; | ||
| import Checklist from "./Checklist"; | ||
| import HelpMenu from "./HelpMenu"; | ||
| import { useDispatch } from "react-redux"; | ||
| import { showSignpostingModal } from "actions/onboardingActions"; | ||
|
|
||
| import { retryPromise } from "utils/AppsmithUtils"; | ||
| import Skeleton from "widgets/Skeleton"; | ||
|
|
||
| const Checklist = lazy(async () => | ||
| retryPromise( | ||
| async () => | ||
| import( | ||
| /* webpackChunkName: "FirstTimeUserOnboardingChecklist" */ "./Checklist" | ||
| ), | ||
| ), | ||
| ); | ||
|
|
||
| export const LazilyLoadedChecklist = () => { | ||
| return ( | ||
| <Suspense fallback={<Skeleton />}> | ||
| <Checklist /> | ||
| </Suspense> | ||
| ); | ||
| }; | ||
|
Comment on lines
+20
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider adding error boundary While the Suspense fallback is implemented correctly, consider adding an error boundary to handle loading failures gracefully. export const LazilyLoadedChecklist = () => {
return (
+ <ErrorBoundary fallback={<ErrorState />}>
<Suspense fallback={<Skeleton />}>
<Checklist />
</Suspense>
+ </ErrorBoundary>
);
};
|
||
| const SIGNPOSTING_POPUP_WIDTH = "360px"; | ||
|
|
||
| const StyledMenuContent = styled(MenuContent)<{ animate: boolean }>` | ||
|
|
@@ -48,7 +66,7 @@ function OnboardingModal(props: { | |
| width={SIGNPOSTING_POPUP_WIDTH} | ||
| > | ||
| <Wrapper> | ||
| {!props.showIntercomConsent && <Checklist />} | ||
| {!props.showIntercomConsent && <LazilyLoadedChecklist />} | ||
| <HelpMenu | ||
| setShowIntercomConsent={props.setShowIntercomConsent} | ||
| showIntercomConsent={props.showIntercomConsent} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider enhancing the loading state UX.
The route configuration with Suspense and memoization is well implemented. However, the Skeleton component could benefit from explicit sizing props to match the component it's replacing.
Consider updating the Skeleton implementation:
📝 Committable suggestion