Enable save button on page pages (#2325)

* Enable save button on page edit pages

* Update e2e page create tests

* Update page create tests snapshots

* Update changelog with enable save button

* Update messages of pages views

* Update page details messages
This commit is contained in:
Dawid 2022-10-04 16:02:17 +02:00 committed by GitHub
parent aceae75ce7
commit 43fb52bc56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 469 additions and 176 deletions

View file

@ -13,6 +13,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Handle form errors before product creation - #2299 by @orzechdev
- Fix no product error on unconfirmed order lines - #2324 by @orzechdev
- Enable save button on discount pages - #2319 by @orzechdev
- Enable save button on page pages - #2325 by @orzechdev
## 3.4

View file

@ -1,3 +1,4 @@
export const PAGES_LIST = {
createPageButton: '[data-test-id="create-page"]'
createPageButton: '[data-test-id="create-page"]',
dialogPageTypeInput: "[data-test-id='dialog-page-type']",
};

View file

@ -11,6 +11,17 @@ export const attributesTypes = {
BOOLEAN: addBooleanAttributeValue,
NUMERIC: addNumericAttributeValue,
};
export function fillUpPageTypeDialog({ pageTypeName }) {
const organization = {};
return cy
.fillAutocompleteSelect(PAGES_LIST.dialogPageTypeInput, pageTypeName)
.then(selected => {
organization.pageType = selected;
return organization;
});
}
export function createPage({
pageName,
pageTypeName,
@ -52,6 +63,9 @@ function openCreatePageAndFillUpGeneralFields({
}) {
cy.visit(urlList.pages)
.get(PAGES_LIST.createPageButton)
.click();
fillUpPageTypeDialog({ pageTypeName });
cy.get(BUTTON_SELECTORS.submit)
.click()
.get(PAGE_DETAILS.nameInput)
.type(pageName);

View file

@ -2059,6 +2059,10 @@
"context": "invoice create date prefix",
"string": "created"
},
"F0N1SC": {
"context": "dialog header",
"string": "Select a page type"
},
"F3Upht": {
"string": "Product type deleted"
},
@ -2596,6 +2600,10 @@
"context": "section header",
"string": "You are about to install {name}"
},
"Id9vlh": {
"context": "page seo options description",
"string": "Add search engine title and description to make this page easier to find"
},
"IeoGgH": {
"context": "variant created success message",
"string": "Variant created"
@ -4211,6 +4219,10 @@
"context": "dialog content",
"string": "Removed sale"
},
"V45+rx": {
"context": "input label",
"string": "Page type"
},
"V8FhTt": {
"context": "collection label",
"string": "Hidden"
@ -5890,9 +5902,6 @@
"context": "product availability",
"string": "Hide in product listings"
},
"jZbT0O": {
"string": "Add search engine title and description to make this page easier to find"
},
"jd/LWa": {
"string": "Voucher applies to all countries"
},

View file

@ -35,6 +35,7 @@ import { useIntl } from "react-intl";
import PageInfo from "../PageInfo";
import PageOrganizeContent from "../PageOrganizeContent";
import PageForm, { PageData, PageUpdateHandlers } from "./form";
import { messages } from "./messages";
export interface PageDetailsPageProps {
loading: boolean;
@ -68,7 +69,7 @@ export interface PageDetailsPageProps {
const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
loading,
errors,
errors: apiErrors,
page,
pageTypes: pageTypeChoiceList,
referencePages,
@ -142,24 +143,21 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
{({
change,
data,
validationErrors,
handlers,
submit,
isSaveDisabled,
attributeRichTextGetters,
}) => (
}) => {
const errors = [...apiErrors, ...validationErrors];
return (
<Container>
<Backlink href={pageListUrl()}>
{intl.formatMessage(sectionNames.pages)}
</Backlink>
<PageHeader
title={
!pageExists
? intl.formatMessage({
id: "gr53VQ",
defaultMessage: "Create Page",
description: "page header",
})
: page?.title
!pageExists ? intl.formatMessage(messages.title) : page?.title
}
/>
<Grid>
@ -182,11 +180,9 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
slugPlaceholder={data.title}
title={data.seoTitle}
titlePlaceholder={data.title}
helperText={intl.formatMessage({
id: "jZbT0O",
defaultMessage:
"Add search engine title and description to make this page easier to find",
})}
helperText={intl.formatMessage(
messages.seoOptionsDescription,
)}
/>
<CardSpacer />
{data.attributes.length > 0 && (
@ -217,26 +213,14 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
errors={errors}
disabled={loading}
messages={{
hiddenLabel: intl.formatMessage({
id: "/TK7QD",
defaultMessage: "Hidden",
description: "page label",
}),
hiddenLabel: intl.formatMessage(messages.hiddenLabel),
hiddenSecondLabel: intl.formatMessage(
{
id: "GZgjK7",
defaultMessage: "will be visible from {date}",
description: "page",
},
messages.hiddenSecondLabel,
{
date: localizeDate(data.publicationDate),
},
),
visibleLabel: intl.formatMessage({
id: "X26jCC",
defaultMessage: "Visible",
description: "page label",
}),
visibleLabel: intl.formatMessage(messages.visibleLabel),
}}
onChange={change}
/>
@ -256,7 +240,7 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
</div>
</Grid>
<Savebar
disabled={isSaveDisabled}
disabled={loading}
state={saveButtonBarState}
onCancel={() => navigate(pageListUrl())}
onDelete={page === null ? undefined : onRemove}
@ -278,12 +262,17 @@ const PageDetailsPage: React.FC<PageDetailsPageProps> = ({
loading={handlers.fetchMoreReferences?.loading}
onClose={onCloseDialog}
onSubmit={attributeValues =>
handleAssignReferenceAttribute(attributeValues, data, handlers)
handleAssignReferenceAttribute(
attributeValues,
data,
handlers,
)
}
/>
)}
</Container>
)}
);
}}
</PageForm>
);
};

View file

@ -20,6 +20,7 @@ import { useExitFormDialog } from "@saleor/components/Form/useExitFormDialog";
import { MetadataFormData } from "@saleor/components/Metadata";
import {
PageDetailsFragment,
PageErrorWithAttributesFragment,
SearchPagesQuery,
SearchPageTypesQuery,
SearchProductsQuery,
@ -39,6 +40,7 @@ import {
getAttributeInputFromPageType,
} from "@saleor/pages/utils/data";
import { createPageTypeSelectHandler } from "@saleor/pages/utils/handlers";
import { validatePageCreateData } from "@saleor/pages/utils/validation";
import { FetchMoreProps, RelayToFlat, ReorderEvent } from "@saleor/types";
import getPublicationData from "@saleor/utils/data/getPublicationData";
import { mapMetadataItemToInput } from "@saleor/utils/maps";
@ -47,7 +49,7 @@ import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTr
import { RichTextContext } from "@saleor/utils/richText/context";
import { useMultipleRichText } from "@saleor/utils/richText/useMultipleRichText";
import useRichText from "@saleor/utils/richText/useRichText";
import React, { useEffect } from "react";
import React, { useEffect, useState } from "react";
export interface PageFormData extends MetadataFormData {
isPublished: boolean;
@ -85,6 +87,7 @@ export interface UsePageUpdateFormOutput
extends CommonUseFormResultWithHandlers<PageData, PageUpdateHandlers>,
RichTextProps {
valid: boolean;
validationErrors: PageErrorWithAttributesFragment[];
}
export type UsePageUpdateFormRenderProps = Omit<
@ -142,6 +145,9 @@ function usePageForm(
confirmLeave: true,
},
);
const [validationErrors, setValidationErrors] = useState<
PageErrorWithAttributesFragment[]
>([]);
const attributes = useFormset(
pageExists
@ -160,7 +166,11 @@ function usePageForm(
});
const attributesWithNewFileValue = useFormset<null, File>([]);
const { setExitDialogSubmitRef, setIsSubmitDisabled } = useExitFormDialog({
const {
setExitDialogSubmitRef,
setIsSubmitDisabled,
setIsDirty,
} = useExitFormDialog({
formId,
});
@ -247,7 +257,15 @@ function usePageForm(
});
const handleSubmit = async (data: PageData) => {
const errors = await onSubmit(data);
let errors = validatePageCreateData(data);
setValidationErrors(errors);
if (errors.length) {
return errors;
}
errors = await onSubmit(data);
if (!errors?.length && pageExists) {
attributesWithNewFileValue.set([]);
@ -261,18 +279,34 @@ function usePageForm(
onSubmit: handleSubmit,
});
const submit = async () => handleFormSubmit(await getSubmitData());
const submit = async () => {
const errors = await handleFormSubmit(await getSubmitData());
if (errors.length) {
setIsSubmitDisabled(isSaveDisabled);
setIsDirty(true);
}
return errors;
};
useEffect(() => setExitDialogSubmitRef(submit), [submit]);
const valid = pageExists || !!opts.selectedPageType;
const isSaveDisabled = disabled || !valid;
useEffect(() => {
setIsSubmitDisabled(isSaveDisabled);
if (!pageExists) {
setIsDirty(true);
}
}, [isSaveDisabled]);
return {
change: handleChange,
data,
validationErrors,
valid,
handlers: {
changeMetadata,

View file

@ -0,0 +1,30 @@
import { defineMessages } from "react-intl";
export const messages = defineMessages({
title: {
id: "gr53VQ",
defaultMessage: "Create Page",
description: "page header",
},
seoOptionsDescription: {
id: "Id9vlh",
defaultMessage:
"Add search engine title and description to make this page easier to find",
description: "page seo options description",
},
hiddenLabel: {
id: "/TK7QD",
defaultMessage: "Hidden",
description: "page label",
},
hiddenSecondLabel: {
id: "GZgjK7",
defaultMessage: "will be visible from {date}",
description: "page",
},
visibleLabel: {
id: "X26jCC",
defaultMessage: "Visible",
description: "page label",
},
});

View file

@ -5,7 +5,6 @@ import PageHeader from "@saleor/components/PageHeader";
import { PageFragment } from "@saleor/graphql";
import { sectionNames } from "@saleor/intl";
import {
pageCreateUrl,
PageListUrlDialog,
PageListUrlQueryParams,
PageListUrlSortField,
@ -28,11 +27,13 @@ export interface PageListPageProps
pages: PageFragment[];
params: PageListUrlQueryParams;
actionDialogOpts: PageListActionDialogOpts;
onAdd: () => void;
}
const PageListPage: React.FC<PageListPageProps> = ({
params,
actionDialogOpts,
onAdd,
...listProps
}) => {
const intl = useIntl();
@ -40,11 +41,7 @@ const PageListPage: React.FC<PageListPageProps> = ({
return (
<Container>
<PageHeader title={intl.formatMessage(sectionNames.pages)}>
<Button
href={pageCreateUrl()}
variant="primary"
data-test-id="create-page"
>
<Button onClick={onAdd} variant="primary" data-test-id="create-page">
<FormattedMessage
id="AHRDWt"
defaultMessage="Create page"

View file

@ -0,0 +1,29 @@
import Decorator from "@saleor/storybook/Decorator";
import { mapNodeToChoice } from "@saleor/utils/maps";
import { storiesOf } from "@storybook/react";
import React from "react";
import { pageTypesList } from "../../fixtures";
import PageTypePickerDialog, {
PageTypePickerDialogProps,
} from "./PageTypePickerDialog";
const pageTypes = mapNodeToChoice(pageTypesList);
const props: PageTypePickerDialogProps = {
pageTypes,
confirmButtonState: "default",
fetchPageTypes: () => undefined,
fetchMorePageTypes: {
hasMore: false,
loading: false,
onFetchMore: () => undefined,
},
onClose: () => undefined,
onConfirm: () => undefined,
open: true,
};
storiesOf("Views / Pages / Page type dialog", module)
.addDecorator(Decorator)
.add("default", () => <PageTypePickerDialog {...props} />);

View file

@ -0,0 +1,70 @@
import ActionDialog from "@saleor/components/ActionDialog";
import SingleAutocompleteSelectField, {
SingleAutocompleteChoiceType,
} from "@saleor/components/SingleAutocompleteSelectField";
import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen";
import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { FetchMoreProps } from "@saleor/types";
import React from "react";
import { useIntl } from "react-intl";
import { messages } from "./messages";
export interface PageTypePickerDialogProps {
confirmButtonState: ConfirmButtonTransitionState;
open: boolean;
pageTypes?: SingleAutocompleteChoiceType[];
fetchPageTypes: (data: string) => void;
fetchMorePageTypes: FetchMoreProps;
onClose: () => void;
onConfirm: (choice: string) => void;
}
const PageTypePickerDialog: React.FC<PageTypePickerDialogProps> = ({
confirmButtonState,
open,
pageTypes,
fetchPageTypes,
fetchMorePageTypes,
onClose,
onConfirm,
}) => {
const intl = useIntl();
const [choice, setChoice] = useStateFromProps("");
const pageTypeDisplayValue = pageTypes.find(
pageType => pageType.value === choice,
)?.label;
useModalDialogOpen(open, {
onClose: () => {
setChoice("");
fetchPageTypes("");
},
});
return (
<ActionDialog
confirmButtonState={confirmButtonState}
open={open}
onClose={onClose}
onConfirm={() => onConfirm(choice)}
title={intl.formatMessage(messages.selectPageType)}
disabled={!choice}
>
<SingleAutocompleteSelectField
displayValue={pageTypeDisplayValue}
name="pageType"
label={intl.formatMessage(messages.pageType)}
choices={pageTypes}
value={choice}
onChange={e => setChoice(e.target.value)}
fetchChoices={fetchPageTypes}
data-test-id="dialog-page-type"
{...fetchMorePageTypes}
/>
</ActionDialog>
);
};
PageTypePickerDialog.displayName = "PageTypePickerDialog";
export default PageTypePickerDialog;

View file

@ -0,0 +1,2 @@
export * from "./PageTypePickerDialog";
export { default } from "./PageTypePickerDialog";

View file

@ -0,0 +1,14 @@
import { defineMessages } from "react-intl";
export const messages = defineMessages({
pageType: {
id: "V45+rx",
defaultMessage: "Page type",
description: "input label",
},
selectPageType: {
id: "F0N1SC",
defaultMessage: "Select a page type",
description: "dialog header",
},
});

View file

@ -3,6 +3,7 @@ import {
PageDetailsFragment,
PageFragment,
} from "@saleor/graphql";
import { PageType } from "@saleor/sdk/dist/apollo/types";
import * as richTextEditorFixtures from "../components/RichTextEditor/fixtures.json";
@ -440,3 +441,18 @@ export const page: PageDetailsFragment = {
slug: "about",
title: "About",
};
export const pageTypesList: Array<Pick<PageType, "id" | "name">> = [
{
id: "1111ZHVjdFR5cGU6Nw==",
name: "General",
},
{
id: "2222ZHVjdFR5cGU6Nw==",
name: "Subpages",
},
{
id: "3333ZHVjdFR5cGU6Nw==",
name: "Blog",
},
];

View file

@ -8,6 +8,7 @@ import { Route, RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import {
pageCreatePath,
PageCreateUrlQueryParams,
pageListPath,
PageListUrlQueryParams,
PageListUrlSortField,
@ -30,7 +31,7 @@ const PageList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const PageCreate: React.FC<RouteComponentProps<any>> = ({ match }) => {
const qs = parseQs(location.search.substr(1));
const params: PageUrlQueryParams = qs;
const params: PageCreateUrlQueryParams = qs;
return (
<PageCreateComponent

View file

@ -20,6 +20,7 @@ export type PageListUrlDialog =
| "publish"
| "unpublish"
| "remove"
| "create-page"
| TabActionDialog;
export enum PageListUrlSortField {
title = "title",
@ -49,10 +50,16 @@ export const pageListUrl = (params?: PageListUrlQueryParams) =>
export const pagePath = (id: string) => urlJoin(pagesSection, id);
export type PageUrlDialog = "remove" | "assign-attribute-value";
export interface PageCreateUrlPageType {
"page-type-id"?: string;
}
export type PageUrlQueryParams = Dialog<PageUrlDialog> & SingleAction;
export type PageCreateUrlQueryParams = Dialog<PageUrlDialog> &
SingleAction &
PageCreateUrlPageType;
export const pageUrl = (id: string, params?: PageUrlQueryParams) =>
pagePath(encodeURIComponent(id)) + "?" + stringifyQs(params);
export const pageCreatePath = urlJoin(pagesSection, "add");
export const pageCreateUrl = (params?: PageUrlQueryParams) =>
export const pageCreateUrl = (params?: PageCreateUrlQueryParams) =>
pageCreatePath + "?" + stringifyQs(params);

View file

@ -0,0 +1,30 @@
import {
PageErrorCode,
PageErrorWithAttributesFragment,
} from "@saleor/graphql";
import { PageData } from "../components/PageDetailsPage/form";
const createEmptyRequiredError = (
field: string,
): PageErrorWithAttributesFragment => ({
__typename: "PageError",
code: PageErrorCode.REQUIRED,
field,
message: null,
attributes: [],
});
export const validatePageCreateData = (data: PageData) => {
let errors: PageErrorWithAttributesFragment[] = [];
if (!data.pageType) {
errors = [...errors, createEmptyRequiredError("pageType")];
}
if (!data.title) {
errors = [...errors, createEmptyRequiredError("title")];
}
return errors;
};

View file

@ -10,6 +10,7 @@ import {
VALUES_PAGINATE_BY,
} from "@saleor/config";
import {
PageErrorWithAttributesFragment,
useFileUploadMutation,
usePageCreateMutation,
usePageTypeQuery,
@ -31,11 +32,11 @@ import { useIntl } from "react-intl";
import PageDetailsPage from "../components/PageDetailsPage";
import { PageSubmitData } from "../components/PageDetailsPage/form";
import { pageCreateUrl, pageUrl, PageUrlQueryParams } from "../urls";
import { pageCreateUrl, PageCreateUrlQueryParams, pageUrl } from "../urls";
export interface PageCreateProps {
id: string;
params: PageUrlQueryParams;
params: PageCreateUrlQueryParams;
}
export const PageCreate: React.FC<PageCreateProps> = ({ params }) => {
@ -45,7 +46,15 @@ export const PageCreate: React.FC<PageCreateProps> = ({ params }) => {
const [updateMetadata] = useUpdateMetadataMutation({});
const [updatePrivateMetadata] = useUpdatePrivateMetadataMutation({});
const [selectedPageTypeId, setSelectedPageTypeId] = React.useState<string>();
const selectedPageTypeId = params["page-type-id"];
const handleSelectPageTypeId = (pageTypeId: string) =>
navigate(
pageCreateUrl({
...params,
"page-type-id": pageTypeId,
}),
);
const {
loadMore: loadMorePageTypes,
@ -178,6 +187,10 @@ export const PageCreate: React.FC<PageCreateProps> = ({ params }) => {
onFetchMore: loadMoreAttributeValues,
};
const errors = getMutationErrors(
pageCreateOpts,
) as PageErrorWithAttributesFragment[];
return (
<>
<WindowTitle
@ -189,7 +202,7 @@ export const PageCreate: React.FC<PageCreateProps> = ({ params }) => {
/>
<PageDetailsPage
loading={pageCreateOpts.loading || uploadFileOpts.loading}
errors={pageCreateOpts.data?.pageCreate.errors || []}
errors={errors}
saveButtonBarState={pageCreateOpts.status}
page={null}
attributeValues={attributeValues}
@ -214,7 +227,7 @@ export const PageCreate: React.FC<PageCreateProps> = ({ params }) => {
fetchMoreAttributeValues={fetchMoreAttributeValues}
onCloseDialog={() => navigate(pageCreateUrl())}
selectedPageType={selectedPageType?.pageType}
onSelectPageType={id => setSelectedPageTypeId(id)}
onSelectPageType={handleSelectPageTypeId}
onAttributeSelectBlur={searchAttributeReset}
/>
</>

View file

@ -1,6 +1,7 @@
import { DialogContentText } from "@material-ui/core";
import ActionDialog from "@saleor/components/ActionDialog";
import { Button } from "@saleor/components/Button";
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
import {
usePageBulkPublishMutation,
usePageBulkRemoveMutation,
@ -17,16 +18,19 @@ import usePaginator, {
} from "@saleor/hooks/usePaginator";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
import { maybe } from "@saleor/misc";
import PageTypePickerDialog from "@saleor/pages/components/PageTypePickerDialog";
import usePageTypeSearch from "@saleor/searches/usePageTypeSearch";
import { ListViews } from "@saleor/types";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import createSortHandler from "@saleor/utils/handlers/sortHandler";
import { mapEdgesToItems } from "@saleor/utils/maps";
import { mapEdgesToItems, mapNodeToChoice } from "@saleor/utils/maps";
import { getSortParams } from "@saleor/utils/sort";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import PageListPage from "../../components/PageListPage/PageListPage";
import {
pageCreateUrl,
pageListUrl,
PageListUrlDialog,
PageListUrlQueryParams,
@ -114,6 +118,20 @@ export const PageList: React.FC<PageListProps> = ({ params }) => {
const handleSort = createSortHandler(navigate, pageListUrl, params);
const {
loadMore: loadMoreDialogPageTypes,
search: searchDialogPageTypes,
result: searchDialogPageTypesOpts,
} = usePageTypeSearch({
variables: DEFAULT_INITIAL_SEARCH_DATA,
});
const fetchMoreDialogPageTypes = {
hasMore: searchDialogPageTypesOpts.data?.search?.pageInfo?.hasNextPage,
loading: searchDialogPageTypesOpts.loading,
onFetchMore: loadMoreDialogPageTypes,
};
return (
<PaginatorContext.Provider value={paginationValues}>
<PageListPage
@ -121,6 +139,7 @@ export const PageList: React.FC<PageListProps> = ({ params }) => {
settings={settings}
pages={mapEdgesToItems(data?.pages)}
onUpdateListSettings={updateListSettings}
onAdd={() => openModal("create-page")}
onSort={handleSort}
actionDialogOpts={{
open: openModal,
@ -262,6 +281,23 @@ export const PageList: React.FC<PageListProps> = ({ params }) => {
}}
/>
</ActionDialog>
<PageTypePickerDialog
confirmButtonState="success"
open={params.action === "create-page"}
pageTypes={mapNodeToChoice(
mapEdgesToItems(searchDialogPageTypesOpts?.data?.search),
)}
fetchPageTypes={searchDialogPageTypes}
fetchMorePageTypes={fetchMoreDialogPageTypes}
onClose={closeModal}
onConfirm={pageTypeId =>
navigate(
pageCreateUrl({
"page-type-id": pageTypeId,
}),
)
}
/>
</PaginatorContext.Provider>
);
};

View file

@ -158149,20 +158149,18 @@ exports[`Storyshots Views / Pages / Page list default 1`] = `
<div
class="PageHeader-root-id"
>
<a
aria-disabled="false"
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-page"
href="/pages/add"
role="button"
tabindex="0"
type="button"
>
<span
class="MuiButton-label-id"
>
Create page
</span>
</a>
</button>
</div>
</div>
</div>
@ -158741,20 +158739,18 @@ exports[`Storyshots Views / Pages / Page list loading 1`] = `
<div
class="PageHeader-root-id"
>
<a
aria-disabled="false"
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-page"
href="/pages/add"
role="button"
tabindex="0"
type="button"
>
<span
class="MuiButton-label-id"
>
Create page
</span>
</a>
</button>
</div>
</div>
</div>
@ -159136,20 +159132,18 @@ exports[`Storyshots Views / Pages / Page list no data 1`] = `
<div
class="PageHeader-root-id"
>
<a
aria-disabled="false"
<button
class="MuiButtonBase-root-id MuiButton-root-id MuiButton-contained-id MuiButton-containedPrimary-id"
data-test-id="create-page"
href="/pages/add"
role="button"
tabindex="0"
type="button"
>
<span
class="MuiButton-label-id"
>
Create page
</span>
</a>
</button>
</div>
</div>
</div>
@ -159402,6 +159396,12 @@ exports[`Storyshots Views / Pages / Page list no data 1`] = `
</div>
`;
exports[`Storyshots Views / Pages / Page type dialog default 1`] = `
<div
style="padding:24px"
/>
`;
exports[`Storyshots Views / Permission Groups / Permission Group Create default 1`] = `
<div
style="padding:24px"