diff --git a/packages/app-page-builder/src/PageBuilder.tsx b/packages/app-page-builder/src/PageBuilder.tsx
index 5c4fce184a2..92222dc4566 100644
--- a/packages/app-page-builder/src/PageBuilder.tsx
+++ b/packages/app-page-builder/src/PageBuilder.tsx
@@ -64,6 +64,11 @@ const PageBuilderMenu: React.FC = () => {
label={"Categories"}
path="/page-builder/block-categories"
/>
+
diff --git a/packages/app-page-builder/src/admin/plugins/routes.tsx b/packages/app-page-builder/src/admin/plugins/routes.tsx
index 6057c3ea8ab..8f9e1cd2148 100644
--- a/packages/app-page-builder/src/admin/plugins/routes.tsx
+++ b/packages/app-page-builder/src/admin/plugins/routes.tsx
@@ -11,6 +11,7 @@ import Menus from "../views/Menus/Menus";
import Pages from "../views/Pages/Pages";
import Editor from "../views/Pages/Editor";
import BlockCategories from "../views/BlockCategories/BlockCategories";
+import PageBlocks from "../views/PageBlocks/PageBlocks";
const ROLE_PB_CATEGORY = "pb.category";
const ROLE_PB_MENUS = "pb.menu";
@@ -111,6 +112,24 @@ const plugins: RoutePlugin[] = [
)}
/>
)
+ },
+ {
+ name: "route-pb-page-blocks",
+ type: "route",
+ route: (
+ (
+
+
+
+
+
+
+ )}
+ />
+ )
}
];
diff --git a/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesDataList.tsx b/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesDataList.tsx
index 18e059ecc66..4a1e696d877 100644
--- a/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesDataList.tsx
+++ b/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesDataList.tsx
@@ -28,7 +28,7 @@ import { ReactComponent as AddIcon } from "@webiny/app-admin/assets/icons/add-18
import { ReactComponent as FilterIcon } from "@webiny/app-admin/assets/icons/filter-24px.svg";
import { PageBuilderSecurityPermission, PbBlockCategory } from "~/types";
-const t = i18n.ns("app-page-builder/admin/categories/data-list");
+const t = i18n.ns("app-page-builder/admin/block-categories/data-list");
interface CreatableItem {
createdBy?: {
diff --git a/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesForm.tsx b/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesForm.tsx
index eb441328504..27facff39e1 100644
--- a/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesForm.tsx
+++ b/packages/app-page-builder/src/admin/views/BlockCategories/BlockCategoriesForm.tsx
@@ -38,7 +38,7 @@ import isEmpty from "lodash/isEmpty";
import EmptyView from "@webiny/app-admin/components/EmptyView";
import { ReactComponent as AddIcon } from "@webiny/app-admin/assets/icons/add-18px.svg";
-const t = i18n.ns("app-page-builder/admin/categories/form");
+const t = i18n.ns("app-page-builder/admin/block-categories/form");
const ButtonWrapper = styled("div")({
display: "flex",
diff --git a/packages/app-page-builder/src/admin/views/BlockCategories/graphql.ts b/packages/app-page-builder/src/admin/views/BlockCategories/graphql.ts
index 40ac2be3578..a582fdfd7b2 100644
--- a/packages/app-page-builder/src/admin/views/BlockCategories/graphql.ts
+++ b/packages/app-page-builder/src/admin/views/BlockCategories/graphql.ts
@@ -1,7 +1,7 @@
import gql from "graphql-tag";
import { PbBlockCategory, PbErrorResponse } from "~/types";
-const BASE_FIELDS = `
+export const PAGE_BLOCK_CATEGORY_BASE_FIELDS = `
slug
name
createdOn
@@ -16,7 +16,7 @@ export const LIST_BLOCK_CATEGORIES = gql`
pageBuilder {
listBlockCategories {
data {
- ${BASE_FIELDS}
+ ${PAGE_BLOCK_CATEGORY_BASE_FIELDS}
}
error {
data
@@ -47,7 +47,7 @@ export const GET_BLOCK_CATEGORY = gql`
pageBuilder {
getBlockCategory(slug: $slug){
data {
- ${BASE_FIELDS}
+ ${PAGE_BLOCK_CATEGORY_BASE_FIELDS}
}
error {
code
@@ -81,7 +81,7 @@ export const CREATE_BLOCK_CATEGORY = gql`
pageBuilder {
blockCategory: createBlockCategory(data: $data) {
data {
- ${BASE_FIELDS}
+ ${PAGE_BLOCK_CATEGORY_BASE_FIELDS}
}
error {
code
@@ -117,7 +117,7 @@ export const UPDATE_BLOCK_CATEGORY = gql`
pageBuilder {
blockCategory: updateBlockCategory(slug: $slug, data: $data) {
data {
- ${BASE_FIELDS}
+ ${PAGE_BLOCK_CATEGORY_BASE_FIELDS}
}
error {
code
diff --git a/packages/app-page-builder/src/admin/views/PageBlocks/BlocksByCategoriesDataList.tsx b/packages/app-page-builder/src/admin/views/PageBlocks/BlocksByCategoriesDataList.tsx
new file mode 100644
index 00000000000..2be05c90455
--- /dev/null
+++ b/packages/app-page-builder/src/admin/views/PageBlocks/BlocksByCategoriesDataList.tsx
@@ -0,0 +1,168 @@
+import React, { useCallback, useMemo, useState } from "react";
+import { i18n } from "@webiny/app/i18n";
+import { useRouter } from "@webiny/react-router";
+import { useQuery } from "@apollo/react-hooks";
+import orderBy from "lodash/orderBy";
+
+import {
+ DataList,
+ DataListModalOverlay,
+ DataListModalOverlayAction,
+ ScrollList,
+ ListItem,
+ ListItemText,
+ ListItemTextSecondary
+} from "@webiny/ui/List";
+import { Cell, Grid } from "@webiny/ui/Grid";
+import { Select } from "@webiny/ui/Select";
+import SearchUI from "@webiny/app-admin/components/SearchUI";
+import { ReactComponent as FilterIcon } from "@webiny/app-admin/assets/icons/filter-24px.svg";
+
+import { PbBlockCategory, PbPageBlock } from "~/types";
+import { LIST_PAGE_BLOCKS_AND_CATEGORIES } from "./graphql";
+
+const t = i18n.ns("app-page-builder/admin/page-blocks/by-categories-data-list");
+
+interface Sorter {
+ label: string;
+ sort: string;
+}
+const SORTERS: Sorter[] = [
+ {
+ label: t`Newest to oldest`,
+ sort: "createdOn_DESC"
+ },
+ {
+ label: t`Oldest to newest`,
+ sort: "createdOn_ASC"
+ },
+ {
+ label: t`Name A-Z`,
+ sort: "name_ASC"
+ },
+ {
+ label: t`Name Z-A`,
+ sort: "name_DESC"
+ }
+];
+
+const BlocksByCategoriesDataList = () => {
+ const [filter, setFilter] = useState("");
+ const [sort, setSort] = useState(SORTERS[0].sort);
+ const { history } = useRouter();
+ const listQuery = useQuery(LIST_PAGE_BLOCKS_AND_CATEGORIES);
+
+ const blockCategoriesData: PbBlockCategory[] =
+ listQuery?.data?.pageBuilder?.listBlockCategories?.data || [];
+ const pageBlocksData: PbPageBlock[] = listQuery?.data?.pageBuilder?.listPageBlocks?.data || [];
+
+ const filterData = useCallback(
+ ({ slug, name }) => {
+ return slug.toLowerCase().includes(filter) || name.toLowerCase().includes(filter);
+ },
+ [filter]
+ );
+
+ const sortData = useCallback(
+ categories => {
+ if (!sort) {
+ return categories;
+ }
+ const [field, order] = sort.split("_");
+ return orderBy(categories, field, order.toLowerCase() as "asc" | "desc");
+ },
+ [sort]
+ );
+
+ const selectedBlocksCategory = new URLSearchParams(location.search).get("category");
+ const loading = [listQuery].find(item => item.loading);
+
+ const blockCategoriesDataListModalOverlay = useMemo(
+ () => (
+
+
+
+
+ |
+
+
+ ),
+ [sort]
+ );
+
+ const filteredBlockCategoriesData: PbBlockCategory[] =
+ filter === "" ? blockCategoriesData : blockCategoriesData.filter(filterData);
+ const categoryList: PbBlockCategory[] = sortData(filteredBlockCategoriesData);
+
+ return (
+
+ }
+ modalOverlay={blockCategoriesDataListModalOverlay}
+ modalOverlayAction={
+ }
+ data-testid={"default-data-list.filter"}
+ />
+ }
+ refresh={() => {
+ if (!listQuery.refetch) {
+ return;
+ }
+ listQuery.refetch();
+ }}
+ >
+ {({ data }: { data: PbBlockCategory[] }) => (
+
+ {data.map(item => {
+ const numberOfBlocks = pageBlocksData.filter(
+ pageBlock => pageBlock.blockCategory === item.slug
+ ).length;
+ return (
+
+
+ history.push(
+ `/page-builder/page-blocks?category=${item.slug}`
+ )
+ }
+ >
+ {item.name}
+ {`${numberOfBlocks} ${
+ numberOfBlocks === 1 ? "block" : "blocks"
+ } in the category`}
+
+
+ );
+ })}
+
+ )}
+
+ );
+};
+
+export default BlocksByCategoriesDataList;
diff --git a/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocks.tsx b/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocks.tsx
new file mode 100644
index 00000000000..3d7077d95a5
--- /dev/null
+++ b/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocks.tsx
@@ -0,0 +1,63 @@
+import React, { useMemo, useCallback } from "react";
+import { SplitView, LeftPanel, RightPanel } from "@webiny/app-admin/components/SplitView";
+import { useSecurity } from "@webiny/app-security";
+
+import { PageBuilderSecurityPermission } from "~/types";
+import BlocksByCategoriesDataList from "./BlocksByCategoriesDataList";
+import PageBlocksDataList from "./PageBlocksDataList";
+
+export interface CreatableItem {
+ createdBy?: {
+ id?: string;
+ };
+}
+
+const PageBlocks: React.FC = () => {
+ const { identity, getPermission } = useSecurity();
+ const pbPageBlockPermission = useMemo((): PageBuilderSecurityPermission | null => {
+ return getPermission("pb.block");
+ }, [identity]);
+
+ const canEdit = useCallback((item: CreatableItem): boolean => {
+ if (!pbPageBlockPermission) {
+ return false;
+ }
+ if (pbPageBlockPermission.own) {
+ const identityId = identity ? identity.id || identity.login : null;
+ return item.createdBy?.id === identityId;
+ }
+ if (typeof pbPageBlockPermission.rwd === "string") {
+ return pbPageBlockPermission.rwd.includes("w");
+ }
+
+ return true;
+ }, []);
+
+ const canDelete = useCallback((item: CreatableItem): boolean => {
+ if (!pbPageBlockPermission) {
+ return false;
+ }
+ if (pbPageBlockPermission.own) {
+ const identityId = identity ? identity.id || identity.login : null;
+ return item.createdBy?.id === identityId;
+ }
+ if (typeof pbPageBlockPermission.rwd === "string") {
+ return pbPageBlockPermission.rwd.includes("d");
+ }
+
+ return true;
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+export default PageBlocks;
diff --git a/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocksDataList.tsx b/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocksDataList.tsx
new file mode 100644
index 00000000000..5bf49f4b479
--- /dev/null
+++ b/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocksDataList.tsx
@@ -0,0 +1,195 @@
+import React, { useCallback, useEffect } from "react";
+import styled from "@emotion/styled";
+import { useQuery, useMutation } from "@apollo/react-hooks";
+import isEmpty from "lodash/isEmpty";
+
+import { useRouter } from "@webiny/react-router";
+import { DeleteIcon, EditIcon } from "@webiny/ui/List/DataList/icons";
+import { CircularProgress } from "@webiny/ui/Progress";
+import EmptyView from "@webiny/app-admin/components/EmptyView";
+import { Typography } from "@webiny/ui/Typography";
+import { i18n } from "@webiny/app/i18n";
+import { useSnackbar } from "@webiny/app-admin/hooks/useSnackbar";
+import { useConfirmationDialog } from "@webiny/app-admin/hooks/useConfirmationDialog";
+
+import { PbPageBlock } from "~/types";
+import { LIST_PAGE_BLOCKS, LIST_PAGE_BLOCKS_AND_CATEGORIES, DELETE_PAGE_BLOCK } from "./graphql";
+import { CreatableItem } from "./PageBlocks";
+import PageBlocksForm from "./PageBlocksForm";
+
+const t = i18n.ns("app-page-builder/admin/page-blocks/data-list");
+
+const List = styled("div")({
+ display: "grid",
+ rowGap: "8px",
+ padding: "8px",
+ margin: "17px 50px",
+ backgroundColor: "white",
+ boxShadow:
+ "0px 2px 1px -1px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%)"
+});
+
+const ListItem = styled("div")({
+ position: "relative",
+ display: "flex",
+ alignItems: "end",
+ border: "1px solid rgba(212, 212, 212, 0.5)",
+ boxShadow:
+ "0px 2px 1px -1px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%)",
+ height: "120px",
+ padding: "24px"
+});
+
+const ListItemText = styled("span")({
+ textTransform: "uppercase"
+});
+
+const Controls = styled("div")({
+ position: "absolute",
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ opacity: 0,
+ backgroundColor: "rgba(0,0,0,0.5)",
+ transition: "opacity 0.2s ease-out",
+
+ "&:hover": {
+ opacity: 1
+ }
+});
+
+const DeleteButton = styled(DeleteIcon)({
+ position: "absolute",
+ top: "10px",
+ right: "10px",
+
+ "& svg": {
+ fill: "white"
+ }
+});
+
+const EditButton = styled(EditIcon)({
+ position: "absolute",
+ top: "10px",
+ left: "10px",
+
+ "& svg": {
+ fill: "white"
+ }
+});
+
+const NoRecordsWrapper = styled("div")({
+ textAlign: "center",
+ padding: 100,
+ color: "var(--mdc-theme-on-surface)"
+});
+
+type PageBlocksDataListProps = {
+ canEdit: (item: CreatableItem) => boolean;
+ canDelete: (item: CreatableItem) => boolean;
+};
+
+const PageBlocksDataList = ({ canEdit, canDelete }: PageBlocksDataListProps) => {
+ const { history, location } = useRouter();
+ const { showSnackbar } = useSnackbar();
+ const { showConfirmation } = useConfirmationDialog();
+
+ const selectedBlocksCategory = new URLSearchParams(location.search).get("category");
+
+ const { data, loading, refetch } = useQuery(LIST_PAGE_BLOCKS, {
+ variables: { blockCategory: selectedBlocksCategory as string },
+ skip: !selectedBlocksCategory,
+ onCompleted: data => {
+ const error = data?.pageBuilder?.listPageBlocks?.error;
+ if (error) {
+ history.push("/page-builder/page-blocks");
+ showSnackbar(error.message);
+ }
+ }
+ });
+
+ useEffect(() => {
+ if (selectedBlocksCategory) {
+ refetch();
+ }
+ }, [selectedBlocksCategory]);
+
+ const [deleteIt, deleteMutation] = useMutation(DELETE_PAGE_BLOCK, {
+ refetchQueries: [{ query: LIST_PAGE_BLOCKS_AND_CATEGORIES }], //To update block counters on the left side
+ onCompleted: () => refetch()
+ });
+
+ const pageBlocksData: PbPageBlock[] = data?.pageBuilder?.listPageBlocks?.data || [];
+
+ const deleteItem = useCallback(
+ item => {
+ showConfirmation(async () => {
+ const response = await deleteIt({
+ variables: item
+ });
+
+ const error = response?.data?.pageBuilder?.deletePageBlock?.error;
+ if (error) {
+ return showSnackbar(error.message);
+ }
+
+ showSnackbar(t`Block "{name}" deleted.`({ name: item.name }));
+ });
+ },
+ [selectedBlocksCategory]
+ );
+
+ const isLoading = [deleteMutation].find(item => item.loading) || loading;
+
+ const showEmptyView = !isLoading && !selectedBlocksCategory;
+ // Render "No content selected" view.
+ if (showEmptyView) {
+ return (
+
+ );
+ }
+
+ const showNoRecordsView = !isLoading && isEmpty(pageBlocksData);
+ // Render "No records found" view.
+ if (showNoRecordsView) {
+ return (
+
+ No records found.
+
+ );
+ }
+
+ return (
+ <>
+
+ {isLoading && }
+ {pageBlocksData.map(pageBlock => (
+
+ {pageBlock.name}
+
+ {canEdit(pageBlock) && (
+
+ history.push(
+ `/page-builder/page-blocks?category=${selectedBlocksCategory}&id=${pageBlock.id}`
+ )
+ }
+ />
+ )}
+ {canDelete(pageBlock) && (
+ deleteItem(pageBlock)} />
+ )}
+
+
+ ))}
+
+
+ >
+ );
+};
+
+export default PageBlocksDataList;
diff --git a/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocksForm.tsx b/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocksForm.tsx
new file mode 100644
index 00000000000..7fa9714928b
--- /dev/null
+++ b/packages/app-page-builder/src/admin/views/PageBlocks/PageBlocksForm.tsx
@@ -0,0 +1,156 @@
+import React, { useCallback } from "react";
+import styled from "@emotion/styled";
+import { useMutation, useQuery } from "@apollo/react-hooks";
+import pick from "lodash/pick";
+
+import { i18n } from "@webiny/app/i18n";
+import { Form } from "@webiny/form";
+import { Grid, Cell } from "@webiny/ui/Grid";
+import { ButtonPrimary } from "@webiny/ui/Button";
+import { CircularProgress } from "@webiny/ui/Progress";
+import { SimpleFormContent } from "@webiny/app-admin/components/SimpleForm";
+import { validation } from "@webiny/validation";
+import { useRouter } from "@webiny/react-router";
+import { Input } from "@webiny/ui/Input";
+import { Select } from "@webiny/ui/Select";
+import { Checkbox } from "@webiny/ui/Checkbox";
+import { useSnackbar } from "@webiny/app-admin/hooks/useSnackbar";
+import { Dialog, DialogCancel, DialogTitle, DialogActions, DialogContent } from "@webiny/ui/Dialog";
+
+import {
+ LIST_PAGE_BLOCKS_AND_CATEGORIES,
+ LIST_BLOCK_CATEGORIES,
+ UPDATE_PAGE_BLOCK,
+ UpdatePageBlockMutationResponse,
+ UpdatePageBlockMutationVariables
+} from "./graphql";
+import { PbPageBlock, PbBlockCategory } from "~/types";
+
+const t = i18n.ns("app-page-builder/admin/page-blocks/form");
+
+const ButtonWrapper = styled("div")({
+ display: "flex",
+ justifyContent: "space-between",
+ width: "100%"
+});
+
+interface PageBlocksFormProps {
+ pageBlocksData: PbPageBlock[];
+ refetch: () => {};
+}
+
+const PageBlocksForm: React.FC = ({ pageBlocksData, refetch }) => {
+ const { history } = useRouter();
+ const { showSnackbar } = useSnackbar();
+
+ const id = new URLSearchParams(location.search).get("id");
+ const category = new URLSearchParams(location.search).get("category");
+
+ const listQuery = useQuery(LIST_BLOCK_CATEGORIES);
+ const blockCategories: PbBlockCategory[] =
+ listQuery?.data?.pageBuilder?.listBlockCategories?.data || [];
+
+ const [update, updateMutation] = useMutation<
+ UpdatePageBlockMutationResponse,
+ UpdatePageBlockMutationVariables
+ >(UPDATE_PAGE_BLOCK, {
+ refetchQueries: [{ query: LIST_PAGE_BLOCKS_AND_CATEGORIES }], //To update block counters on the left side
+ onCompleted: () => refetch()
+ });
+
+ const onSubmit = useCallback(
+ async formData => {
+ const data = pick(formData, ["name", "blockCategory"]);
+
+ const response = await update({
+ variables: { id: id as string, data }
+ });
+
+ const error = response?.data?.pageBuilder?.pageBlock?.error;
+ if (error) {
+ showSnackbar(error.message);
+ return;
+ }
+
+ history.push(`/page-builder/page-blocks?category=${category}`);
+
+ showSnackbar(t`Block saved successfully.`);
+ },
+ [id]
+ );
+
+ const data = pageBlocksData.find(pageBlock => pageBlock.id === id);
+
+ const loading = [updateMutation].find(item => item.loading);
+
+ return (
+
+ );
+};
+
+export default PageBlocksForm;
diff --git a/packages/app-page-builder/src/admin/views/PageBlocks/graphql.ts b/packages/app-page-builder/src/admin/views/PageBlocks/graphql.ts
new file mode 100644
index 00000000000..cca49f3342e
--- /dev/null
+++ b/packages/app-page-builder/src/admin/views/PageBlocks/graphql.ts
@@ -0,0 +1,155 @@
+import gql from "graphql-tag";
+
+import { PbPageBlock, PbErrorResponse } from "~/types";
+
+import { PAGE_BLOCK_CATEGORY_BASE_FIELDS } from "~/admin/views/BlockCategories/graphql";
+export { LIST_BLOCK_CATEGORIES } from "~/admin/views/BlockCategories/graphql";
+
+const PAGE_BLOCK_BASE_FIELDS = `
+ id
+ blockCategory
+ preview
+ name
+ content
+ createdOn
+ createdBy {
+ id
+ displayName
+ type
+ }
+`;
+
+export const LIST_PAGE_BLOCKS_AND_CATEGORIES = gql`
+ query ListBlockCategories {
+ pageBuilder {
+ listBlockCategories {
+ data {
+ ${PAGE_BLOCK_CATEGORY_BASE_FIELDS}
+ }
+ error {
+ code
+ data
+ message
+ }
+ }
+ listPageBlocks {
+ data {
+ ${PAGE_BLOCK_BASE_FIELDS}
+ }
+ error {
+ code
+ data
+ message
+ }
+ }
+ }
+ }
+`;
+/**
+ * ##############################
+ * List Page Blocks Query
+ */
+export interface ListPageBlocksQueryResponse {
+ pageBuilder: {
+ data?: PbPageBlock[];
+ error?: PbErrorResponse;
+ };
+}
+export interface ListPageBlocksQueryVariables {
+ blockCategory: string;
+}
+export const LIST_PAGE_BLOCKS = gql`
+ query ListPageBlocks($blockCategory: String) {
+ pageBuilder {
+ listPageBlocks(where: {blockCategory:$blockCategory}) {
+ data {
+ ${PAGE_BLOCK_BASE_FIELDS}
+ }
+ error {
+ code
+ data
+ message
+ }
+ }
+ }
+ }
+`;
+/**
+ * ###########################
+ * Create Page Block Mutation Response
+ */
+export interface CreatePageBlockMutationResponse {
+ pageBuilder: {
+ pageBlock: {
+ data: PbPageBlock | null;
+ error: PbErrorResponse | null;
+ };
+ };
+}
+export interface CreatePageBlockMutationVariables {
+ data: PbPageBlock;
+}
+export const CREATE_PAGE_BLOCK = gql`
+ mutation CreatePageBlock($data: PbCreatePageBlockInput!){
+ pageBuilder {
+ pageBlock: createPageBlock(data: $data) {
+ data {
+ ${PAGE_BLOCK_BASE_FIELDS}
+ }
+ error {
+ code
+ message
+ data
+ }
+ }
+ }
+ }
+`;
+/**
+ * ###########################
+ * Update Page Block Mutation Response
+ */
+export interface UpdatePageBlockMutationResponse {
+ pageBuilder: {
+ pageBlock: {
+ data: PbPageBlock | null;
+ error: PbErrorResponse | null;
+ };
+ };
+}
+export interface UpdatePageBlockMutationVariables {
+ id: string;
+ data: {
+ name: string;
+ blockCategory: string;
+ };
+}
+export const UPDATE_PAGE_BLOCK = gql`
+ mutation UpdatePageBlock($id: ID!, $data: PbUpdatePageBlockInput!){
+ pageBuilder {
+ pageBlock: updatePageBlock(id: $id, data: $data) {
+ data {
+ ${PAGE_BLOCK_BASE_FIELDS}
+ }
+ error {
+ code
+ message
+ data
+ }
+ }
+ }
+ }
+`;
+
+export const DELETE_PAGE_BLOCK = gql`
+ mutation DeletePageBlock($id: ID!) {
+ pageBuilder {
+ deletePageBlock(id: $id) {
+ error {
+ code
+ message
+ }
+ }
+ }
+ }
+`;
diff --git a/packages/app-page-builder/src/types.ts b/packages/app-page-builder/src/types.ts
index cee2c4e984e..3abb47d00f4 100644
--- a/packages/app-page-builder/src/types.ts
+++ b/packages/app-page-builder/src/types.ts
@@ -820,6 +820,16 @@ export interface PbBlockCategory {
createdBy: PbIdentity;
}
+export interface PbPageBlock {
+ id: string;
+ name: string;
+ blockCategory: string;
+ content: File;
+ preview: File;
+ createdOn: string;
+ createdBy: PbIdentity;
+}
+
/**
* TODO: have types for both API and app in the same package?
* GraphQL response types