Skip to content

Commit

Permalink
fix(app-page-builder): improve editor core (#2536)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel910 committed Jul 17, 2022
1 parent 18f9afd commit 1ae77d2
Show file tree
Hide file tree
Showing 66 changed files with 519 additions and 592 deletions.
5 changes: 4 additions & 1 deletion apps/admin/package.json
Expand Up @@ -19,6 +19,7 @@
"@webiny/cli-plugin-deploy-pulumi": "^5.29.0",
"@webiny/plugins": "^5.29.0",
"@webiny/project-utils": "^5.29.0",
"@webiny/react-properties": "^5.29.0",
"@webiny/serverless-cms-aws": "^5.29.0",
"core-js": "^3.0.1",
"cross-fetch": "^3.0.4",
Expand Down Expand Up @@ -54,7 +55,9 @@
"dependencies": [
"theme",
"theme-1",
"@webiny/cli"
"@webiny/app-apw",
"@webiny/cli",
"@webiny/react-properties"
],
"src": [
"@okta/okta-signin-widget",
Expand Down
2 changes: 0 additions & 2 deletions apps/admin/src/plugins/pageBuilder/editorPlugins.ts
Expand Up @@ -39,7 +39,6 @@ import navigator from "@webiny/app-page-builder/editor/plugins/toolbar/navigator
import saving from "@webiny/app-page-builder/editor/plugins/toolbar/saving";
import { undo, redo } from "@webiny/app-page-builder/editor/plugins/toolbar/undoRedo";
// Element settings
import advanced from "@webiny/app-page-builder/editor/plugins/elementSettings/advanced";
import animation from "@webiny/app-page-builder/editor/plugins/elementSettings/animation";
import deleteElement from "@webiny/app-page-builder/editor/plugins/elementSettings/delete";
import clone from "@webiny/app-page-builder/editor/plugins/elementSettings/clone";
Expand Down Expand Up @@ -108,7 +107,6 @@ export default [
undo,
redo,
// Element settings
advanced,
animation,
background,
border,
Expand Down
@@ -0,0 +1,11 @@
import React, { ComponentProps } from "react";
import { ComposableFC, Compose, HigherOrderComponent } from "@webiny/react-composition";

export function createComponentPlugin<T extends ComposableFC<ComponentProps<T>>>(
Base: T,
hoc: HigherOrderComponent<ComponentProps<T>>
): React.FC {
const ComponentPlugin = () => <Compose component={Base} with={hoc} />;
ComponentPlugin.displayName = Base.displayName;
return ComponentPlugin;
}
@@ -0,0 +1,13 @@
import React from "react";
import { HigherOrderComponent } from "@webiny/react-composition";
import { Provider } from "~/components/core/Provider";

/**
* Creates a component, which, when mounted, will register an admin app provider.
* For more information, visit https://www.webiny.com/docs/admin-area/basics/framework.
*/
export function createProviderPlugin(hoc: HigherOrderComponent): React.FC {
return function ProviderPlugin() {
return <Provider hoc={hoc} />;
};
}
2 changes: 2 additions & 0 deletions packages/app-admin-core/src/index.ts
Expand Up @@ -10,3 +10,5 @@ export * from "./components/core/Plugins";
export * from "./components/core/Provider";
export * from "./components/core/Routes";
export * from "./components/utils/DebounceRender";
export * from "./components/utils/createComponentPlugin";
export * from "./components/utils/createProviderPlugin";
19 changes: 9 additions & 10 deletions packages/app-page-builder/src/PageBuilder.tsx
@@ -1,11 +1,10 @@
import React, { Fragment } from "react";
import { HasPermission } from "@webiny/app-security";
import {
Compose,
Plugins,
AddMenu as Menu,
Provider,
HigherOrderComponent
createProviderPlugin,
createComponentPlugin
} from "@webiny/app-admin";
import { PageBuilderProvider as ContextProvider } from "./contexts/PageBuilder";
import { ReactComponent as PagesIcon } from "./admin/assets/table_chart-24px.svg";
Expand All @@ -18,7 +17,7 @@ import { EditorProps, EditorRenderer } from "./admin/components/Editor";
export type { EditorProps };
export { EditorRenderer };

const PageBuilderProviderHOC = (Component: React.FC): React.FC => {
const PageBuilderProviderPlugin = createProviderPlugin(Component => {
return function PageBuilderProvider({ children }) {
return (
<ContextProvider>
Expand All @@ -28,7 +27,7 @@ const PageBuilderProviderHOC = (Component: React.FC): React.FC => {
</ContextProvider>
);
};
};
});

const PageBuilderMenu: React.FC = () => {
return (
Expand Down Expand Up @@ -74,22 +73,22 @@ const PageBuilderMenu: React.FC = () => {
};

const EditorLoader = React.lazy(() =>
import("./editor").then(m => ({
import("./editor/Editor").then(m => ({
default: m.Editor
}))
);

const EditorRendererHOC: HigherOrderComponent<EditorProps> = () => {
const EditorRendererPlugin = createComponentPlugin(EditorRenderer, () => {
return function Editor(props) {
return <EditorLoader {...props} />;
};
};
});

export const PageBuilder: React.FC = () => {
return (
<Fragment>
<Provider hoc={PageBuilderProviderHOC} />
<Compose component={EditorRenderer} with={EditorRendererHOC} />
<PageBuilderProviderPlugin />
<EditorRendererPlugin />
<Plugins>
<PageBuilderMenu />
<WebsiteSettings />
Expand Down
6 changes: 2 additions & 4 deletions packages/app-page-builder/src/admin/components/Editor.tsx
@@ -1,10 +1,8 @@
import React from "react";
import { RecoilRootProps } from "recoil";
import { makeComposable } from "@webiny/app-admin";
import { EditorProps } from "~/editor/Editor";

export type EditorProps = {
initializeState: RecoilRootProps["initializeState"];
};
export { EditorProps };

export const Editor = makeComposable<EditorProps>("Editor", props => {
return <EditorRenderer {...props} />;
Expand Down
4 changes: 3 additions & 1 deletion packages/app-page-builder/src/blockEditor/Editor.tsx
Expand Up @@ -77,7 +77,9 @@ export const BlockEditor: React.FC = () => {
<React.Suspense fallback={<EditorLoadingScreen />}>
<BlockEditorConfig />
<LoadData>
<PbEditor initializeState={createStateInitializer(block as BlockWithContent)} />
<PbEditor
stateInitializerFactory={createStateInitializer(block as BlockWithContent)}
/>
</LoadData>
</React.Suspense>
);
Expand Down
@@ -1,9 +1,9 @@
import React from "react";
import { EditorSidebarTab, EditorSidebarTabProps } from "~/editor";
import { Compose, HigherOrderComponent } from "@webiny/app-admin";
import { EditorSidebarTab } from "~/editor";
import { createComponentPlugin } from "@webiny/app-admin";
import { useActiveElement } from "~/editor/hooks/useActiveElement";

const DisableBlockElementTab: HigherOrderComponent<EditorSidebarTabProps> = Tab => {
export const BlockElementSidebarPlugin = createComponentPlugin(EditorSidebarTab, Tab => {
return function ElementTab({ children, ...props }) {
const [element] = useActiveElement();

Expand All @@ -18,8 +18,4 @@ const DisableBlockElementTab: HigherOrderComponent<EditorSidebarTabProps> = Tab
</Tab>
);
};
};

export const BlockElementSidebarPlugin = () => {
return <Compose component={EditorSidebarTab} with={DisableBlockElementTab} />;
};
});
@@ -1,16 +1,16 @@
import React from "react";
import { Compose, HigherOrderComponent } from "@webiny/app-admin";
import { ReactComponent as BackIcon } from "./round-arrow_back-24px.svg";
import { css } from "emotion";
import { createComponentPlugin } from "@webiny/app-admin";
import { useRouter } from "@webiny/react-router";
import { IconButton } from "@webiny/ui/Button";
import { EditorBar } from "~/editor";
import { ReactComponent as BackIcon } from "./round-arrow_back-24px.svg";

const backStyles = css({
marginLeft: -10
});

const BackButton: HigherOrderComponent = () => {
export const BackButtonPlugin = createComponentPlugin(EditorBar.BackButton, () => {
return function BackButton() {
const { params, history } = useRouter();

Expand All @@ -30,8 +30,4 @@ const BackButton: HigherOrderComponent = () => {
/>
);
};
};

export const BackButtonPlugin = () => {
return <Compose component={EditorBar.BackButton} with={BackButton} />;
};
});
@@ -1,8 +1,8 @@
import React, { useCallback } from "react";
import { useRouter } from "@webiny/react-router";
import { createComponentPlugin, makeComposable } from "@webiny/app-admin";
import { useSnackbar } from "@webiny/app-admin/hooks/useSnackbar";
import { useRouter } from "@webiny/react-router";
import { ButtonPrimary } from "@webiny/ui/Button";
import { Compose, HigherOrderComponent, makeComposable } from "@webiny/app-admin";
import { EditorBar } from "~/editor";
import { useEventActionHandler } from "~/editor/hooks/useEventActionHandler";
import { UpdateDocumentActionEvent } from "~/editor/recoil/actions";
Expand Down Expand Up @@ -37,7 +37,7 @@ const DefaultSaveBlockButton: React.FC = () => {

export const SaveBlockButton = makeComposable("SaveBlockButton", DefaultSaveBlockButton);

const AddSaveBlockButton: HigherOrderComponent = RightSection => {
export const SaveBlockButtonPlugin = createComponentPlugin(EditorBar.RightSection, RightSection => {
return function AddSaveBlockButton(props) {
return (
<RightSection>
Expand All @@ -46,8 +46,4 @@ const AddSaveBlockButton: HigherOrderComponent = RightSection => {
</RightSection>
);
};
};

export const SaveBlockButtonPlugin = () => {
return <Compose component={EditorBar.RightSection} with={AddSaveBlockButton} />;
};
});
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useCallback, SyntheticEvent } from "react";
import { useSnackbar } from "@webiny/app-admin/hooks/useSnackbar";
import { Input } from "@webiny/ui/Input";
import { Tooltip } from "@webiny/ui/Tooltip";
import { Compose, HigherOrderComponent } from "@webiny/app-admin";
import { createComponentPlugin } from "@webiny/app-admin";
import { BlockTitle, blockTitleWrapper, TitleInputWrapper, TitleWrapper } from "./Styled";
import { useEventActionHandler } from "~/editor/hooks/useEventActionHandler";
import { BlockAtomType } from "~/blockEditor/state";
Expand Down Expand Up @@ -106,7 +106,7 @@ const Title: React.FC = () => {
);
};

const AddTitle: HigherOrderComponent = LeftSection => {
export const TitlePlugin = createComponentPlugin(EditorBar.LeftSection, LeftSection => {
return function AddTitle(props) {
return (
<LeftSection>
Expand All @@ -115,8 +115,4 @@ const AddTitle: HigherOrderComponent = LeftSection => {
</LeftSection>
);
};
};

export const TitlePlugin = () => {
return <Compose component={EditorBar.LeftSection} with={AddTitle} />;
};
});
@@ -1,5 +1,5 @@
import React, { useEffect, useMemo, useRef } from "react";
import { Compose, HigherOrderComponent } from "@webiny/app-admin";
import { ComposableFC, createComponentPlugin } from "@webiny/app-admin";
import {
EventActionHandlerProvider,
EventActionHandlerProviderProps,
Expand All @@ -11,51 +11,50 @@ import { useBlock } from "~/blockEditor/hooks/useBlock";

type ProviderProps = EventActionHandlerProviderProps<BlockEditorEventActionCallableState>;

const PbEventActionHandlerHOC: HigherOrderComponent<ProviderProps> = Component => {
return function PbEventActionHandlerProvider(props) {
const blockAtomValueRef = useRef<BlockAtomType>();
const [blockAtomValue, setBlockAtomValue] = useBlock();

useEffect(() => {
blockAtomValueRef.current = blockAtomValue;
}, [blockAtomValue]);

const saveCallablesResults: ProviderProps["saveCallablesResults"] = useMemo(
() => [
...(props.saveCallablesResults || []),
next => {
return ({ state, history = true }) => {
const res = next({ state, history });
if (res.state.block) {
setBlockAtomValue(res.state.block);
}

return { state, history };
};
}
],
[]
);

const getCallableState: GetCallableState = next => state => {
const callableState = next(state);

return {
block: blockAtomValueRef.current as BlockAtomType,
...callableState
export const EventActionHandlerPlugin = createComponentPlugin(
EventActionHandlerProvider as ComposableFC<ProviderProps>,
Component => {
return function PbEventActionHandlerProvider(props) {
const blockAtomValueRef = useRef<BlockAtomType>();
const [blockAtomValue, setBlockAtomValue] = useBlock();

useEffect(() => {
blockAtomValueRef.current = blockAtomValue;
}, [blockAtomValue]);

const saveCallablesResults: ProviderProps["saveCallablesResults"] = useMemo(
() => [
...(props.saveCallablesResults || []),
next => {
return ({ state, history = true }) => {
const res = next({ state, history });
if (res.state.block) {
setBlockAtomValue(res.state.block);
}

return { state, history };
};
}
],
[]
);

const getCallableState: GetCallableState = next => state => {
const callableState = next(state);

return {
block: blockAtomValueRef.current as BlockAtomType,
...callableState
};
};
};

return (
<Component
{...props}
getCallableState={[...(props.getCallableState || []), getCallableState]}
saveCallablesResults={saveCallablesResults}
/>
);
};
};

export const EventActionHandlerPlugin = () => {
return <Compose component={EventActionHandlerProvider} with={PbEventActionHandlerHOC} />;
};
return (
<Component
{...props}
getCallableState={[...(props.getCallableState || []), getCallableState]}
saveCallablesResults={saveCallablesResults}
/>
);
};
}
);

0 comments on commit 1ae77d2

Please sign in to comment.