-
Notifications
You must be signed in to change notification settings - Fork 618
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app-headless-cms): enable full-screen editor for content entries (…
- Loading branch information
Showing
24 changed files
with
411 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
...s-cms/src/admin/components/ContentEntryForm/Header/ShowRevisionsList/ShowRevisionList.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from "react"; | ||
import { ReactComponent as ListIcon } from "@material-design-icons/svg/outlined/checklist.svg"; | ||
import { ContentEntryEditorConfig } from "~/admin/config/contentEntries"; | ||
import { useFullScreenContentEntry } from "~/admin/views/contentEntries/ContentEntry/FullScreenContentEntry/useFullScreenContentEntry"; | ||
|
||
export const ShowRevisionList = () => { | ||
const { openRevisionList } = useFullScreenContentEntry(); | ||
const { useOptionsMenuItem } = ContentEntryEditorConfig.Actions.MenuItemAction; | ||
const { OptionsMenuItem } = useOptionsMenuItem(); | ||
|
||
return ( | ||
<OptionsMenuItem | ||
icon={<ListIcon />} | ||
label={"Show entry revisions"} | ||
onAction={() => openRevisionList(true)} | ||
data-testid={"cms.content-form.header.show-revisions"} | ||
/> | ||
); | ||
}; |
1 change: 1 addition & 0 deletions
1
...app-headless-cms/src/admin/components/ContentEntryForm/Header/ShowRevisionsList/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./ShowRevisionList"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
...iews/contentEntries/ContentEntry/FullScreenContentEntry/FullScreenContentEntry.styled.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import styled from "@emotion/styled"; | ||
import { css } from "emotion"; | ||
|
||
export const FullScreenContentEntryContainer = styled.div` | ||
background: var(--mdc-theme-background); | ||
z-index: 4; | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
height: 100vh; | ||
#headerToolbarGrid { | ||
border: 0; | ||
padding: 0; | ||
margin: 0; | ||
} | ||
#cms-content-details-tabs .webiny-ui-tabs__tab-bar { | ||
display: none; | ||
} | ||
`; | ||
|
||
/** | ||
* HEADER | ||
*/ | ||
export const FullScreenContentEntryHeader = styled.div` | ||
background: var(--mdc-theme-surface); | ||
position: fixed; | ||
display: flex; | ||
justify-content: space-between; | ||
box-sizing: border-box; | ||
width: 100%; | ||
z-index: 4; | ||
`; | ||
|
||
export const FullScreenContentEntryHeaderContent = styled.div` | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
padding: 8px 12px; | ||
`; | ||
|
||
export const TitleWrapper = styled.div` | ||
display: flex; | ||
align-items: baseline; | ||
justify-content: flex-start; | ||
flex-direction: column; | ||
color: var(--mdc-theme-text-primary-on-background); | ||
position: relative; | ||
width: 100%; | ||
margin-left: 10px; | ||
`; | ||
|
||
export const EntryTitle = styled.div` | ||
width: 100%; | ||
display: flex; | ||
align-items: center; | ||
`; | ||
|
||
interface EntryNameProps { | ||
isNewEntry?: boolean; | ||
} | ||
|
||
export const EntryName = styled.div<EntryNameProps>` | ||
font-family: var(--mdc-typography-font-family); | ||
font-size: 20px; | ||
line-height: 1.4em; | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
opacity: ${props => (props.isNewEntry ? 0.3 : 1)}; | ||
`; | ||
|
||
export const EntryVersion = styled.span` | ||
font-size: 20px; | ||
color: var(--mdc-theme-text-secondary-on-background); | ||
margin-left: 5px; | ||
line-height: 120%; | ||
@media (max-width: 800px) { | ||
display: none; | ||
} | ||
`; | ||
|
||
export const EntryMeta = styled.div` | ||
height: 20px; | ||
margin: -2px 2px 2px 2px; | ||
@media (max-width: 960px) { | ||
display: none; | ||
} | ||
`; | ||
|
||
/** | ||
* FORM | ||
*/ | ||
export const FullScreenContentEntryContent = styled.div` | ||
overflow-y: scroll; | ||
height: calc(100vh - 64px); | ||
margin-top: 64px; | ||
`; | ||
|
||
export const FullScreenContentEntryContentFormWrapper = styled.div` | ||
display: flex; | ||
justify-content: center; | ||
`; | ||
|
||
export const FullScreenContentEntryContentFormInner = styled.div` | ||
flex-shrink: 1; | ||
flex-basis: 920px; | ||
`; | ||
|
||
export const FullScreenContentEntryContentFormInnerCss = css` | ||
height: 100% !important; | ||
`; |
93 changes: 93 additions & 0 deletions
93
...admin/views/contentEntries/ContentEntry/FullScreenContentEntry/FullScreenContentEntry.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import React, { useState } from "react"; | ||
import { createPortal } from "react-dom"; | ||
import { featureFlags } from "@webiny/feature-flags"; | ||
import { CircularProgress } from "@webiny/ui/Progress"; | ||
import { useContentEntry } from "~/admin/views/contentEntries/hooks"; | ||
import { RevisionListDrawer } from "./RevisionListDrawer"; | ||
import { FullScreenContentEntryHeaderLeft } from "./FullScreenContentEntryHeaderLeft"; | ||
import { | ||
FullScreenContentEntryContainer, | ||
FullScreenContentEntryContent, | ||
FullScreenContentEntryContentFormInner, | ||
FullScreenContentEntryContentFormInnerCss, | ||
FullScreenContentEntryContentFormWrapper, | ||
FullScreenContentEntryHeader, | ||
FullScreenContentEntryHeaderContent | ||
} from "./FullScreenContentEntry.styled"; | ||
import { FullScreenContentEntryProvider } from "./useFullScreenContentEntry"; | ||
import { ContentEntryEditorConfig } from "~/ContentEntryEditorConfig"; | ||
|
||
const { ContentEntry } = ContentEntryEditorConfig; | ||
|
||
const FullScreenContentEntryDecorator = ContentEntry.createDecorator(Original => { | ||
return function ContentEntry() { | ||
const { loading } = useContentEntry(); | ||
const [isRevisionListOpen, openRevisionList] = useState<boolean>(false); | ||
|
||
return ( | ||
<FullScreenContentEntryProvider | ||
openRevisionList={openRevisionList} | ||
isRevisionListOpen={isRevisionListOpen} | ||
> | ||
<FullScreenContentEntryContainer> | ||
<FullScreenContentEntryHeader> | ||
<FullScreenContentEntryHeaderContent style={{ width: "33%" }}> | ||
<FullScreenContentEntryHeaderLeft /> | ||
</FullScreenContentEntryHeaderContent> | ||
<FullScreenContentEntryHeaderContent> | ||
{/* | ||
Empty div to relocate Entry Form Header via React Portal in full-screen mode. | ||
Ensures layout flexibility without disrupting React context and state. | ||
*/} | ||
<div id={"cms-content-entry-header-right"} /> | ||
</FullScreenContentEntryHeaderContent> | ||
</FullScreenContentEntryHeader> | ||
{loading && <CircularProgress style={{ zIndex: 10 }} />} | ||
<FullScreenContentEntryContent> | ||
<FullScreenContentEntryContentFormWrapper> | ||
<FullScreenContentEntryContentFormInner> | ||
<Original /> | ||
</FullScreenContentEntryContentFormInner> | ||
</FullScreenContentEntryContentFormWrapper> | ||
</FullScreenContentEntryContent> | ||
<RevisionListDrawer /> | ||
</FullScreenContentEntryContainer> | ||
</FullScreenContentEntryProvider> | ||
); | ||
}; | ||
}); | ||
|
||
const FullScreenContentEntryFormDecorator = ContentEntry.ContentEntryForm.createDecorator( | ||
Original => { | ||
return function ContentEntryForm(props) { | ||
return <Original {...props} className={FullScreenContentEntryContentFormInnerCss} />; | ||
}; | ||
} | ||
); | ||
|
||
const FullScreenContentEntryFormHeaderDecorator = | ||
ContentEntry.ContentEntryForm.Header.createDecorator(Original => { | ||
return function ContentEntryFormHeader() { | ||
const headerRightElement = document.getElementById("cms-content-entry-header-right"); | ||
|
||
if (!headerRightElement) { | ||
return <Original />; | ||
} | ||
|
||
return createPortal(<Original />, headerRightElement); | ||
}; | ||
}); | ||
|
||
export const FullScreenContentEntry = () => { | ||
if (!featureFlags.allowCmsFullScreenEditor) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<> | ||
<FullScreenContentEntryDecorator /> | ||
<FullScreenContentEntryFormDecorator /> | ||
<FullScreenContentEntryFormHeaderDecorator /> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.