Skip to content

Commit 986db05

Browse files
committed
fix(app-page-builder): export Components namespace with composable components
1 parent 57aecf9 commit 986db05

File tree

31 files changed

+492
-302
lines changed

31 files changed

+492
-302
lines changed

packages/app-page-builder/src/admin/components/Table/Preview/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import { DrawerContent, DrawerRight } from "@webiny/ui/Drawer";
3-
import PageDetails from "~/admin/views/Pages/PageDetails";
3+
import { PageDetails } from "~/admin/views/Pages/PageDetails";
44

55
interface PreviewProps {
66
open: boolean;

packages/app-page-builder/src/admin/components/Table/Table/Actions/ChangePageStatus.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { ReactComponent as Unpublish } from "@material-design-icons/svg/outlined
44
import { PageListConfig } from "~/admin/config/pages";
55
import { usePage } from "~/admin/views/Pages/hooks/usePage";
66
import { useChangePageStatus } from "~/admin/views/Pages/hooks/useChangePageStatus";
7+
import { makeComposable } from "@webiny/react-composition";
78

8-
export const ChangePageStatus = () => {
9+
export const ChangePageStatus = makeComposable("ChangePageStatus", () => {
910
const { page } = usePage();
1011
const { openDialogUnpublishPage, openDialogPublishPage } = useChangePageStatus({ page });
1112
const { OptionsMenuItem } = PageListConfig.Browser.PageAction;
@@ -29,4 +30,4 @@ export const ChangePageStatus = () => {
2930
data-testid={"aco.actions.pb.page.publish"}
3031
/>
3132
);
32-
};
33+
});

packages/app-page-builder/src/admin/components/Table/Table/Actions/DeletePage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React from "react";
2+
import { makeComposable } from "@webiny/app-admin";
23
import { ReactComponent as Delete } from "@material-design-icons/svg/outlined/delete.svg";
34
import { PageListConfig } from "~/admin/config/pages";
45
import { usePage } from "~/admin/views/Pages/hooks/usePage";
56
import { useDeletePage } from "~/admin/views/Pages/hooks/useDeletePage";
67

7-
export const DeletePage = () => {
8+
export const DeletePage = makeComposable("DeletePage", () => {
89
const { page } = usePage();
910
const { openDialogDeletePage } = useDeletePage({ page });
1011
const { OptionsMenuItem } = PageListConfig.Browser.PageAction;
@@ -17,4 +18,4 @@ export const DeletePage = () => {
1718
data-testid={"aco.actions.pb.page.delete"}
1819
/>
1920
);
20-
};
21+
});

packages/app-page-builder/src/admin/components/Table/Table/Actions/EditPage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React from "react";
22
import { ReactComponent as Edit } from "@material-design-icons/svg/outlined/edit.svg";
3+
import { makeComposable } from "@webiny/app-admin";
34
import { PageListConfig } from "~/admin/config/pages";
45
import { usePage } from "~/admin/views/Pages/hooks/usePage";
56
import { useCreatePageFrom } from "~/admin/views/Pages/hooks/useCreatePageFrom";
67
import { useNavigatePage } from "~/admin/hooks/useNavigatePage";
78

8-
export const EditPage = () => {
9+
export const EditPage = makeComposable("EditPage", () => {
910
const { page } = usePage();
1011
const { OptionsMenuItem, OptionsMenuLink } = PageListConfig.Browser.PageAction;
1112
const { getPageEditorUrl, navigateToPageEditor } = useNavigatePage();
@@ -34,4 +35,4 @@ export const EditPage = () => {
3435
data-testid={"aco.actions.pb.page.edit"}
3536
/>
3637
);
37-
};
38+
});

packages/app-page-builder/src/admin/components/Table/Table/Actions/MovePage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React from "react";
22
import { ReactComponent as Move } from "@material-design-icons/svg/outlined/drive_file_move.svg";
3+
import { makeComposable } from "@webiny/app-admin";
34
import { PageListConfig } from "~/admin/config/pages";
45
import { usePage } from "~/admin/views/Pages/hooks/usePage";
56
import { useMovePageToFolder } from "~/admin/views/Pages/hooks/useMovePageToFolder";
67

7-
export const MovePage = () => {
8+
export const MovePage = makeComposable("MovePage", () => {
89
const { page } = usePage();
910
const movePageToFolder = useMovePageToFolder({ record: page });
1011
const { OptionsMenuItem } = PageListConfig.Browser.PageAction;
@@ -17,4 +18,4 @@ export const MovePage = () => {
1718
data-testid={"aco.actions.pb.page.move"}
1819
/>
1920
);
20-
};
21+
});

packages/app-page-builder/src/admin/components/Table/Table/Actions/PreviewPage.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import React from "react";
22
import { ReactComponent as Visibility } from "@material-design-icons/svg/outlined/visibility.svg";
3+
import { makeComposable } from "@webiny/app-admin";
34
import { PageListConfig } from "~/admin/config/pages";
45
import { usePage } from "~/admin/views/Pages/hooks/usePage";
5-
import { usePreviewPage } from "~/admin/views/Pages/hooks/usePreviewPage";
6+
import { usePreviewPage } from "~/admin/hooks/usePreviewPage";
67

7-
export const PreviewPage = () => {
8+
export const PreviewPage = makeComposable("PreviewPage", () => {
89
const { page } = usePage();
9-
const { previewPage } = usePreviewPage({ page });
10+
const { previewPage } = usePreviewPage({
11+
id: page.id,
12+
status: page.data.status,
13+
path: page.data.path
14+
});
1015
const { OptionsMenuItem } = PageListConfig.Browser.PageAction;
1116

1217
const label = page.data.status === "published" ? "View" : "Preview";
@@ -19,4 +24,4 @@ export const PreviewPage = () => {
1924
data-testid={"aco.actions.pb.page.preview"}
2025
/>
2126
);
22-
};
27+
});

packages/app-page-builder/src/admin/components/Table/Table/Cells/CellActions.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import React from "react";
22
import { FolderProvider, useAcoConfig } from "@webiny/app-aco";
33
import { OptionsMenu } from "@webiny/app-admin";
44
import { PageListConfig } from "~/admin/config/pages";
5-
import { PageProvider } from "~/admin/views/Pages/hooks/usePage";
5+
import { PageProvider } from "~/admin/contexts/Page";
6+
import { PbPageTableItem } from "~/types";
67

78
export const CellActions = () => {
89
const { useTableRow, isFolderRow } = PageListConfig.Browser.Table.Column;
@@ -26,7 +27,7 @@ export const CellActions = () => {
2627
}
2728

2829
return (
29-
<PageProvider page={row}>
30+
<PageProvider<PbPageTableItem> page={row}>
3031
<OptionsMenu
3132
actions={recordConfig.actions}
3233
data-testid={"table.row.pb.page.menu-action"}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React, { createContext } from "react";
2+
3+
export interface PageContext<T = any> {
4+
page: T;
5+
}
6+
7+
export const PageContext = createContext<PageContext | undefined>(undefined);
8+
9+
interface PageProviderProps<T> {
10+
page: T;
11+
children: React.ReactNode;
12+
}
13+
14+
export function PageProvider<T>({ page, children }: PageProviderProps<T>) {
15+
const value: PageContext = { page };
16+
17+
return <PageContext.Provider value={value}>{children}</PageContext.Provider>;
18+
}
19+
20+
export function createUsePageHook<T>() {
21+
return () => {
22+
const context = React.useContext<PageContext<T>>(
23+
PageContext as unknown as React.Context<PageContext<T>>
24+
);
25+
26+
if (!context) {
27+
throw Error(
28+
`PageContext is missing in the component tree. Are you using "usePage()" hook in the right place?`
29+
);
30+
}
31+
32+
return context;
33+
};
34+
}

packages/app-page-builder/src/admin/graphql/pages.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ export interface PageResponseData {
1717
locked: boolean;
1818
status: string;
1919
revisions: PbPageRevision[];
20+
createdBy: {
21+
id: string;
22+
displayName: string;
23+
};
24+
savedOn: string;
25+
category: {
26+
name: string;
27+
};
28+
content: Record<string, any>;
2029
}
2130

2231
export const DATA_FIELDS = `
@@ -143,10 +152,10 @@ export const LIST_PAGES = gql`
143152
* ##############################
144153
* Get Page Query Response
145154
*/
146-
export interface GetPageQueryResponse {
155+
export interface GetPageQueryResponse<T extends PageResponseData = PageResponseData> {
147156
pageBuilder: {
148157
getPage: {
149-
data: PageResponseData | null;
158+
data: T | null;
150159
error: PbErrorResponse | null;
151160
};
152161
};
@@ -163,7 +172,7 @@ export const GET_PAGE = gql`
163172
data {
164173
${DATA_FIELDS}
165174
createdBy {
166-
id,
175+
id
167176
displayName
168177
}
169178
savedOn

packages/app-page-builder/src/admin/views/Pages/hooks/usePreviewPage.ts renamed to packages/app-page-builder/src/admin/hooks/usePreviewPage.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,31 @@ import { useCallback } from "react";
22
import { usePageBuilderSettings } from "~/admin/hooks/usePageBuilderSettings";
33
import { useSiteStatus } from "~/admin/hooks/useSiteStatus";
44
import { useConfigureWebsiteUrlDialog } from "~/admin/hooks/useConfigureWebsiteUrl";
5-
import { PbPageTableItem } from "~/types";
5+
import { PbPageData } from "~/types";
66

7-
interface UsePreviewPageParams {
8-
page: PbPageTableItem;
9-
}
10-
11-
export const usePreviewPage = ({ page }: UsePreviewPageParams) => {
7+
/**
8+
* This hook handles the logic of loading website preview URL, verifying that it exists, checking that the preview URL
9+
* is accessible, and if not, shows a dialog to the user to either configure or ensure the endpoint is accessible.
10+
*/
11+
export function usePreviewPage(input: Pick<PbPageData, "id" | "status" | "path">) {
1212
const { getPageUrl, getWebsiteUrl } = usePageBuilderSettings();
1313
const [isSiteRunning, refreshSiteStatus] = useSiteStatus(getWebsiteUrl());
14-
1514
const { showConfigureWebsiteUrlDialog } = useConfigureWebsiteUrlDialog(
1615
getWebsiteUrl(),
1716
refreshSiteStatus
1817
);
1918

20-
// We must prevent opening in new tab - Cypress doesn't work with new tabs.
19+
// For test environments, we must not open new tabs. Cypress doesn't work with new tabs.
2120
const target = "Cypress" in window ? "_self" : "_blank";
21+
const url = getPageUrl(input);
2222

23-
const url = getPageUrl(page.data);
24-
25-
const previewPage = useCallback(() => {
23+
const handlePreviewClick = useCallback(() => {
2624
if (isSiteRunning) {
2725
window.open(url, target, "noopener");
2826
} else {
2927
showConfigureWebsiteUrlDialog();
3028
}
3129
}, [url, isSiteRunning]);
3230

33-
return {
34-
previewPage
35-
};
36-
};
31+
return { previewPage: handlePreviewClick, previewUrl: url };
32+
}

packages/app-page-builder/src/admin/plugins/pageDetails/header/Header.tsx

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import React, { useCallback } from "react";
1+
import React from "react";
22
import styled from "@emotion/styled";
33
import { renderPlugins } from "@webiny/app/plugins";
44
import { Typography } from "@webiny/ui/Typography";
5-
import { useConfigureWebsiteUrlDialog } from "~/admin/hooks/useConfigureWebsiteUrl";
6-
import { usePageBuilderSettings } from "~/admin/hooks/usePageBuilderSettings";
7-
import { useSiteStatus } from "~/admin/hooks/useSiteStatus";
85
import { ReactComponent as OpenInNew } from "@material-design-icons/svg/round/open_in_new.svg";
96
import { PbPageData } from "~/types";
7+
import { usePreviewPage } from "~/admin/hooks/usePreviewPage";
108

119
const HeaderTitle = styled.div`
1210
display: flex;
@@ -77,24 +75,11 @@ interface HeaderProps {
7775
}
7876
const Header = (props: HeaderProps) => {
7977
const { page } = props;
80-
const { getPageUrl, getWebsiteUrl } = usePageBuilderSettings();
81-
const [isSiteRunning, refreshSiteStatus] = useSiteStatus(getWebsiteUrl());
82-
const { showConfigureWebsiteUrlDialog } = useConfigureWebsiteUrlDialog(
83-
getWebsiteUrl(),
84-
refreshSiteStatus
85-
);
86-
87-
// We must prevent opening in new tab - Cypress doesn't work with new tabs.
88-
const target = "Cypress" in window ? "_self" : "_blank";
89-
const url = getPageUrl(page);
90-
91-
const handlePreviewClick = useCallback(() => {
92-
if (isSiteRunning) {
93-
window.open(url, target, "noopener");
94-
} else {
95-
showConfigureWebsiteUrlDialog();
96-
}
97-
}, [url, isSiteRunning]);
78+
const { previewPage, previewUrl } = usePreviewPage({
79+
id: page.id,
80+
status: page.status,
81+
path: page.path
82+
});
9883

9984
return (
10085
<React.Fragment>
@@ -103,8 +88,8 @@ const Header = (props: HeaderProps) => {
10388
<PageTitle>
10489
<Typography use="headline6">{page.title}</Typography>
10590
</PageTitle>
106-
<PageLink onClick={handlePreviewClick}>
107-
<Typography use="caption">{url}</Typography>
91+
<PageLink onClick={previewPage}>
92+
<Typography use="caption">{previewUrl}</Typography>
10893
<OpenInNew />
10994
</PageLink>
11095
</PageInfo>

packages/app-page-builder/src/admin/plugins/pageDetails/header/deletePage/DeletePage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { PbPageData } from "~/types";
77
import { useDeletePage } from "~/admin/views/Pages/hooks/useDeletePage";
88
import { useFolders } from "@webiny/app-aco";
99

10-
interface DeletePageProps {
10+
export interface DeletePageProps {
1111
page: PbPageData;
1212
onDelete?: () => void;
1313
}

packages/app-page-builder/src/admin/plugins/pageDetails/header/editRevision/EditRevision.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { useFolders } from "@webiny/app-aco";
1414

1515
const t = i18n.ns("app-headless-cms/app-page-builder/page-details/header/edit");
1616

17-
interface EditRevisionProps {
17+
export interface EditRevisionProps {
1818
page: PbPageData;
1919
}
2020

0 commit comments

Comments
 (0)