Merge branch '2.0' of github.com:payloadcms/payload into 2.0
This commit is contained in:
@@ -12,6 +12,10 @@ keywords: point, geolocation, geospatial, geojson, 2dsphere, config, configurati
|
||||
related queries.
|
||||
</Banner>
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Note:</strong> The Point field type is currently only supported in MongoDB.
|
||||
</Banner>
|
||||
|
||||
<LightDarkImage
|
||||
srcLight="https://payloadcms.com/images/docs/fields/point.png"
|
||||
srcDark="https://payloadcms.com/images/docs/fields/point-dark.png"
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Live Preview
|
||||
label: Overview
|
||||
order: 10
|
||||
desc: With Live Preview you can render your front-end application directly within the Admin panel. Your changes take effect as you type. No save needed.
|
||||
keywords: 'live preview', 'preview', 'live', 'iframe', 'iframe preview', 'visual editing', 'design'
|
||||
keywords: live preview, preview, live, iframe, iframe preview, visual editing, design
|
||||
---
|
||||
|
||||
**With Live Preview you can render your front-end application directly within the Admin panel. As you type, your changes take effect in real-time. No need to save a draft or publish your changes.**
|
||||
|
||||
@@ -29,13 +29,7 @@ const AccountView: React.FC = () => {
|
||||
const config = useConfig()
|
||||
|
||||
const {
|
||||
admin: {
|
||||
components: {
|
||||
views: { Account: CustomAccount } = {
|
||||
Account: undefined,
|
||||
},
|
||||
} = {},
|
||||
},
|
||||
admin: { components: { views: { Account: CustomAccountComponent } = {} } = {} },
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
@@ -133,7 +127,9 @@ const AccountView: React.FC = () => {
|
||||
|
||||
return (
|
||||
<RenderCustomComponent
|
||||
CustomComponent={CustomAccount}
|
||||
CustomComponent={
|
||||
typeof CustomAccountComponent === 'function' ? CustomAccountComponent : undefined
|
||||
}
|
||||
DefaultComponent={DefaultAccount}
|
||||
componentProps={{
|
||||
action,
|
||||
|
||||
@@ -14,13 +14,7 @@ const Dashboard: React.FC = () => {
|
||||
const [filteredGlobals, setFilteredGlobals] = useState<SanitizedGlobalConfig[]>([])
|
||||
|
||||
const {
|
||||
admin: {
|
||||
components: {
|
||||
views: { Dashboard: CustomDashboard } = {
|
||||
Dashboard: undefined,
|
||||
},
|
||||
} = {},
|
||||
} = {},
|
||||
admin: { components: { views: { Dashboard: CustomDashboardComponent } = {} } = {} } = {},
|
||||
collections,
|
||||
globals,
|
||||
} = useConfig()
|
||||
@@ -37,7 +31,9 @@ const Dashboard: React.FC = () => {
|
||||
|
||||
return (
|
||||
<RenderCustomComponent
|
||||
CustomComponent={CustomDashboard}
|
||||
CustomComponent={
|
||||
typeof CustomDashboardComponent === 'function' ? CustomDashboardComponent : undefined
|
||||
}
|
||||
DefaultComponent={DefaultDashboard}
|
||||
componentProps={{
|
||||
collections: collections.filter(
|
||||
|
||||
@@ -2,21 +2,48 @@ import React from 'react'
|
||||
import { Route } from 'react-router-dom'
|
||||
|
||||
import type { User } from '../../../../auth'
|
||||
import type { SanitizedConfig } from '../../../../exports/config'
|
||||
import type { SanitizedConfig } from '../../../../config/types'
|
||||
|
||||
export type adminViewType = 'Account' | 'Dashboard'
|
||||
|
||||
const internalViews: adminViewType[] = ['Account', 'Dashboard']
|
||||
|
||||
export const customRoutes = (props: {
|
||||
canAccessAdmin?: boolean
|
||||
customRoutes?: SanitizedConfig['admin']['components']['routes']
|
||||
config: SanitizedConfig
|
||||
match: { url: string }
|
||||
user: User | null | undefined
|
||||
}) => {
|
||||
const { canAccessAdmin, customRoutes, match, user } = props
|
||||
const { canAccessAdmin, config, match, user } = props
|
||||
|
||||
if (Array.isArray(customRoutes)) {
|
||||
return customRoutes.map(({ Component, exact, path, sensitive, strict }) => {
|
||||
return (
|
||||
const {
|
||||
admin: { components: { views: customViewConfigs } = {} },
|
||||
} = config
|
||||
|
||||
const customViews = Object.entries(customViewConfigs || {})
|
||||
.filter(([viewKey, view]) => {
|
||||
// Remove internal views from the list of custom views
|
||||
// This way we can easily iterate over the remaining views
|
||||
return Boolean(
|
||||
!internalViews.includes(viewKey as any) &&
|
||||
typeof view !== 'function' &&
|
||||
typeof view === 'object',
|
||||
)
|
||||
})
|
||||
?.map(([, view]) => view)
|
||||
|
||||
if (Array.isArray(customViews)) {
|
||||
return customViews.map((CustomView) => {
|
||||
// You are responsible for ensuring that your own custom route is secure
|
||||
// i.e. return `Unauthorized` in your own component if the user does not have permission
|
||||
|
||||
if (typeof CustomView === 'function') {
|
||||
return <CustomView user={user} />
|
||||
}
|
||||
|
||||
const { Component, exact, path, sensitive, strict } = CustomView
|
||||
|
||||
return (
|
||||
<Route
|
||||
exact={exact}
|
||||
key={`${match.url}${path}`}
|
||||
|
||||
@@ -44,12 +44,7 @@ export const Routes: React.FC = () => {
|
||||
const config = useConfig()
|
||||
|
||||
const {
|
||||
admin: {
|
||||
components: { routes: customRoutesConfig } = {},
|
||||
inactivityRoute: logoutInactivityRoute,
|
||||
logoutRoute,
|
||||
user: userSlug,
|
||||
},
|
||||
admin: { inactivityRoute: logoutInactivityRoute, logoutRoute, user: userSlug },
|
||||
collections,
|
||||
globals,
|
||||
routes,
|
||||
@@ -110,7 +105,7 @@ export const Routes: React.FC = () => {
|
||||
</Route>
|
||||
{customRoutes({
|
||||
canAccessAdmin,
|
||||
customRoutes: customRoutesConfig,
|
||||
config,
|
||||
match,
|
||||
user,
|
||||
})}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import joi from 'joi'
|
||||
|
||||
import { adminViewSchema } from './shared/adminViewSchema'
|
||||
import { livePreviewSchema } from './shared/componentSchema'
|
||||
import { routeSchema } from './shared/routeSchema'
|
||||
|
||||
const component = joi.alternatives().try(joi.object().unknown(), joi.func())
|
||||
|
||||
@@ -53,11 +53,13 @@ export default joi.object({
|
||||
Button: component,
|
||||
}),
|
||||
providers: joi.array().items(component),
|
||||
routes: routeSchema,
|
||||
views: joi.object({
|
||||
Account: component,
|
||||
Dashboard: component,
|
||||
views: joi.alternatives().try(
|
||||
joi.object({
|
||||
Account: joi.alternatives().try(component, adminViewSchema),
|
||||
Dashboard: joi.alternatives().try(component, adminViewSchema),
|
||||
}),
|
||||
joi.object().pattern(joi.string(), component),
|
||||
),
|
||||
}),
|
||||
css: joi.string(),
|
||||
dateFormat: joi.string(),
|
||||
|
||||
@@ -2,7 +2,7 @@ import joi from 'joi'
|
||||
|
||||
import { componentSchema } from './componentSchema'
|
||||
|
||||
export const routeSchema = joi.array().items(
|
||||
export const adminViewSchema = joi.array().items(
|
||||
joi.object().keys({
|
||||
Component: componentSchema,
|
||||
exact: joi.bool(),
|
||||
@@ -232,12 +232,25 @@ export type Endpoint = {
|
||||
root?: boolean
|
||||
}
|
||||
|
||||
export type CustomAdminView = React.ComponentType<{
|
||||
export type AdminViewConfig = {
|
||||
Component: AdminViewComponent
|
||||
/** Whether the path should be matched exactly or as a prefix */
|
||||
exact?: boolean
|
||||
path: string
|
||||
sensitive?: boolean
|
||||
strict?: boolean
|
||||
}
|
||||
|
||||
export type AdminViewProps = {
|
||||
canAccessAdmin?: boolean
|
||||
collection?: SanitizedCollectionConfig
|
||||
global?: SanitizedGlobalConfig
|
||||
user: User | null | undefined
|
||||
}>
|
||||
}
|
||||
|
||||
export type AdminViewComponent = React.ComponentType<AdminViewProps>
|
||||
|
||||
export type AdminView = AdminViewComponent | AdminViewConfig
|
||||
|
||||
export type EditViewConfig = {
|
||||
/**
|
||||
@@ -257,15 +270,6 @@ export type EditViewComponent = React.ComponentType<{
|
||||
|
||||
export type EditView = EditViewComponent | EditViewConfig
|
||||
|
||||
export type AdminRoute = {
|
||||
Component: CustomAdminView
|
||||
/** Whether the path should be matched exactly or as a prefix */
|
||||
exact?: boolean
|
||||
path: string
|
||||
sensitive?: boolean
|
||||
strict?: boolean
|
||||
}
|
||||
|
||||
export type Locale = {
|
||||
/**
|
||||
* value of supported locale
|
||||
@@ -422,15 +426,18 @@ export type Config = {
|
||||
*/
|
||||
providers?: React.ComponentType<{ children: React.ReactNode }>[]
|
||||
/**
|
||||
* Add custom routes in the admin dashboard
|
||||
* Replace or modify top-level admin routes, or add new ones:
|
||||
* + `Account` - `/admin/account`
|
||||
* + `Dashboard` - `/admin`
|
||||
* + `:path` - `/admin/:path`
|
||||
*/
|
||||
routes?: AdminRoute[]
|
||||
/* Replace complete pages */
|
||||
views?: {
|
||||
/** Add custom admin views */
|
||||
[key: string]: AdminView
|
||||
/** Replace the account screen */
|
||||
Account?: React.ComponentType<any>
|
||||
Account?: AdminView
|
||||
/** Replace the admin homepage */
|
||||
Dashboard?: React.ComponentType<any>
|
||||
Dashboard?: AdminView
|
||||
}
|
||||
}
|
||||
/** Absolute path to a stylesheet that you can use to override / customize the Admin panel styling. */
|
||||
|
||||
@@ -30,7 +30,7 @@ const AfterNavLinks: React.FC = () => {
|
||||
<NavLink
|
||||
activeClassName="active"
|
||||
style={{ textDecoration: 'none' }}
|
||||
to={`${adminRoute}/custom-default-route`}
|
||||
to={`${adminRoute}/custom-default-view`}
|
||||
>
|
||||
Default Template
|
||||
</NavLink>
|
||||
@@ -39,7 +39,7 @@ const AfterNavLinks: React.FC = () => {
|
||||
<NavLink
|
||||
activeClassName="active"
|
||||
style={{ textDecoration: 'none' }}
|
||||
to={`${adminRoute}/custom-minimal-route`}
|
||||
to={`${adminRoute}/custom-minimal-view`}
|
||||
>
|
||||
Minimal Template
|
||||
</NavLink>
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
|
||||
import type { CustomAdminView } from '../../../../../packages/payload/src/config/types'
|
||||
|
||||
import Button from '../../../../../packages/payload/src/admin/components/elements/Button'
|
||||
import { useStepNav } from '../../../../../packages/payload/src/admin/components/elements/StepNav'
|
||||
// As this is the demo project, we import our dependencies from the `src` directory.
|
||||
import DefaultTemplate from '../../../../../packages/payload/src/admin/components/templates/Default'
|
||||
import { useConfig } from '../../../../../packages/payload/src/admin/components/utilities/Config'
|
||||
import Meta from '../../../../../packages/payload/src/admin/components/utilities/Meta'
|
||||
|
||||
// In your projects, you can import as follows:
|
||||
// import { DefaultTemplate } from 'payload/components/templates';
|
||||
// import { Button, Eyebrow } from 'payload/components/elements';
|
||||
// import { AdminView } from 'payload/config';
|
||||
// import { useStepNav } from 'payload/components/hooks';
|
||||
// import { useConfig, Meta } from 'payload/components/utilities';
|
||||
|
||||
const CustomDefaultRoute: CustomAdminView = ({ canAccessAdmin, user }) => {
|
||||
const {
|
||||
routes: { admin: adminRoute },
|
||||
} = useConfig()
|
||||
const { setStepNav } = useStepNav()
|
||||
|
||||
// This effect will only run one time and will allow us
|
||||
// to set the step nav to display our custom route name
|
||||
|
||||
useEffect(() => {
|
||||
setStepNav([
|
||||
{
|
||||
label: 'Custom Route with Default Template',
|
||||
},
|
||||
])
|
||||
}, [setStepNav])
|
||||
|
||||
// If an unauthorized user tries to navigate straight to this page,
|
||||
// Boot 'em out
|
||||
if (!user || (user && !canAccessAdmin)) {
|
||||
return <Redirect to={`${adminRoute}/unauthorized`} />
|
||||
}
|
||||
|
||||
return (
|
||||
<DefaultTemplate>
|
||||
<Meta
|
||||
description="Building custom routes into Payload is easy."
|
||||
keywords="Custom React Components, Payload, CMS"
|
||||
title="Custom Route with Default Template"
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
paddingLeft: 'var(--gutter-h)',
|
||||
paddingRight: 'var(--gutter-h)',
|
||||
}}
|
||||
>
|
||||
<h1>Custom Route</h1>
|
||||
<p>
|
||||
Here is a custom route that was added in the Payload config. It uses the Default Template,
|
||||
so the sidebar is rendered.
|
||||
</p>
|
||||
<Button buttonStyle="secondary" el="link" to={`${adminRoute}`}>
|
||||
Go to Dashboard
|
||||
</Button>
|
||||
</div>
|
||||
</DefaultTemplate>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomDefaultRoute
|
||||
27
test/admin/components/views/CustomAccount/index.tsx
Normal file
27
test/admin/components/views/CustomAccount/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React, { Fragment } from 'react'
|
||||
|
||||
import type { AdminViewComponent } from '../../../../../packages/payload/src/config/types'
|
||||
|
||||
const CustomAccountView: AdminViewComponent = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 'calc(var(--base) * 2)',
|
||||
paddingLeft: 'var(--gutter-h)',
|
||||
paddingRight: 'var(--gutter-h)',
|
||||
}}
|
||||
>
|
||||
<h1>Custom Account View</h1>
|
||||
<p>This custom view was added through the Payload config:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>components.views.Account</code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomAccountView
|
||||
27
test/admin/components/views/CustomDashboard/index.tsx
Normal file
27
test/admin/components/views/CustomDashboard/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React, { Fragment } from 'react'
|
||||
|
||||
import { AdminViewComponent } from '../../../../../packages/payload/src/config/types'
|
||||
|
||||
const CustomDashboardView: AdminViewComponent = () => {
|
||||
return (
|
||||
<Fragment>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 'calc(var(--base) * 2)',
|
||||
paddingLeft: 'var(--gutter-h)',
|
||||
paddingRight: 'var(--gutter-h)',
|
||||
}}
|
||||
>
|
||||
<h1>Custom Dashboard View</h1>
|
||||
<p>This custom view was added through the Payload config:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>components.views.Dashboard</code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomDashboardView
|
||||
@@ -4,8 +4,27 @@
|
||||
// In your own projects, you'd import as follows:
|
||||
// @import '~payload/scss';
|
||||
|
||||
.custom-minimal-route {
|
||||
.custom-default-view {
|
||||
&__login-btn {
|
||||
margin-right: base(0.5);
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(1);
|
||||
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: calc(var(--base) / 2);
|
||||
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,30 @@
|
||||
import React, { Fragment, useEffect } from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
|
||||
import type { EditViewComponent } from '../../../../../packages/payload/src/config/types'
|
||||
import type { AdminViewComponent } from '../../../../../packages/payload/src/config/types'
|
||||
|
||||
import Button from '../../../../../packages/payload/src/admin/components/elements/Button'
|
||||
import { useStepNav } from '../../../../../packages/payload/src/admin/components/elements/StepNav'
|
||||
// As this is the demo project, we import our dependencies from the `src` directory.
|
||||
import DefaultTemplate from '../../../../../packages/payload/src/admin/components/templates/Default'
|
||||
import { useConfig } from '../../../../../packages/payload/src/admin/components/utilities/Config'
|
||||
import Meta from '../../../../../packages/payload/src/admin/components/utilities/Meta'
|
||||
|
||||
const CustomDefaultView: EditViewComponent = ({
|
||||
canAccessAdmin,
|
||||
// collection,
|
||||
// global,
|
||||
user,
|
||||
}) => {
|
||||
// In your projects, you can import as follows:
|
||||
// import { DefaultTemplate } from 'payload/components/templates';
|
||||
// import { Button, Eyebrow } from 'payload/components/elements';
|
||||
// import { AdminView } from 'payload/config';
|
||||
// import { useStepNav } from 'payload/components/hooks';
|
||||
// import { useConfig, Meta } from 'payload/components/utilities';
|
||||
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'custom-default-view'
|
||||
|
||||
const CustomDefaultView: AdminViewComponent = ({ canAccessAdmin, user }) => {
|
||||
const {
|
||||
routes: { admin: adminRoute },
|
||||
} = useConfig()
|
||||
|
||||
const { setStepNav } = useStepNav()
|
||||
|
||||
// This effect will only run one time and will allow us
|
||||
@@ -24,7 +33,7 @@ const CustomDefaultView: EditViewComponent = ({
|
||||
useEffect(() => {
|
||||
setStepNav([
|
||||
{
|
||||
label: 'Custom Default View',
|
||||
label: 'Custom Admin View with Default Template',
|
||||
},
|
||||
])
|
||||
}, [setStepNav])
|
||||
@@ -36,39 +45,31 @@ const CustomDefaultView: EditViewComponent = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<DefaultTemplate>
|
||||
<Meta
|
||||
description="Building custom views into Payload is easy."
|
||||
keywords="Custom React Components, Payload, CMS"
|
||||
title="Custom Admin View with Default Template"
|
||||
/>
|
||||
<div
|
||||
className={`${baseClass}__content`}
|
||||
style={{
|
||||
marginTop: 'calc(var(--base) * 2)',
|
||||
paddingLeft: 'var(--gutter-h)',
|
||||
paddingRight: 'var(--gutter-h)',
|
||||
}}
|
||||
>
|
||||
<h1>Custom Default View</h1>
|
||||
<p>This custom Default view was added through one of the following Payload configs:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>components.views.Edit.Default</code>
|
||||
<h1>Custom Admin View</h1>
|
||||
<p>
|
||||
{'This allows you to override only the default edit view specifically, but '}
|
||||
<b>
|
||||
<em>not</em>
|
||||
</b>
|
||||
{
|
||||
' any nested views like versions, etc. The document header will render above this component.'
|
||||
}
|
||||
Here is a custom admin view that was added in the Payload config. It uses the Default
|
||||
Template, so the sidebar is rendered.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<code>components.views.Edit.Default.Component</code>
|
||||
<p>
|
||||
This is the most granular override, allowing you to override only the Default
|
||||
component, or any of its other properties like path and label.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<Button buttonStyle="secondary" el="link" to={`${adminRoute}`}>
|
||||
Go to Dashboard
|
||||
</Button>
|
||||
</div>
|
||||
</Fragment>
|
||||
</div>
|
||||
</DefaultTemplate>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
75
test/admin/components/views/CustomDefaultEdit/index.tsx
Normal file
75
test/admin/components/views/CustomDefaultEdit/index.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import React, { Fragment, useEffect } from 'react'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
|
||||
import type { EditViewComponent } from '../../../../../packages/payload/src/config/types'
|
||||
|
||||
import { useStepNav } from '../../../../../packages/payload/src/admin/components/elements/StepNav'
|
||||
import { useConfig } from '../../../../../packages/payload/src/admin/components/utilities/Config'
|
||||
|
||||
const CustomDefaultView: EditViewComponent = ({
|
||||
canAccessAdmin,
|
||||
// collection,
|
||||
// global,
|
||||
user,
|
||||
}) => {
|
||||
const {
|
||||
routes: { admin: adminRoute },
|
||||
} = useConfig()
|
||||
|
||||
const { setStepNav } = useStepNav()
|
||||
|
||||
// This effect will only run one time and will allow us
|
||||
// to set the step nav to display our custom route name
|
||||
|
||||
useEffect(() => {
|
||||
setStepNav([
|
||||
{
|
||||
label: 'Custom Default View',
|
||||
},
|
||||
])
|
||||
}, [setStepNav])
|
||||
|
||||
// If an unauthorized user tries to navigate straight to this page,
|
||||
// Boot 'em out
|
||||
if (!user || (user && !canAccessAdmin)) {
|
||||
return <Redirect to={`${adminRoute}/unauthorized`} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 'calc(var(--base) * 2)',
|
||||
paddingLeft: 'var(--gutter-h)',
|
||||
paddingRight: 'var(--gutter-h)',
|
||||
}}
|
||||
>
|
||||
<h1>Custom Default View</h1>
|
||||
<p>This custom Default view was added through one of the following Payload configs:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<code>components.views.Edit.Default</code>
|
||||
<p>
|
||||
{'This allows you to override only the default edit view specifically, but '}
|
||||
<b>
|
||||
<em>not</em>
|
||||
</b>
|
||||
{
|
||||
' any nested views like versions, etc. The document header will render above this component.'
|
||||
}
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<code>components.views.Edit.Default.Component</code>
|
||||
<p>
|
||||
This is the most granular override, allowing you to override only the Default
|
||||
component, or any of its other properties like path and label.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomDefaultView
|
||||
30
test/admin/components/views/CustomMinimal/index.scss
Normal file
30
test/admin/components/views/CustomMinimal/index.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
// As this is the demo folder, we import Payload SCSS functions relatively.
|
||||
@import '../../../../../packages/payload/src/exports/scss.scss';
|
||||
|
||||
// In your own projects, you'd import as follows:
|
||||
// @import '~payload/scss';
|
||||
|
||||
.custom-minimal-view {
|
||||
&__login-btn {
|
||||
margin-right: base(0.5);
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: base(1);
|
||||
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
display: flex;
|
||||
gap: calc(var(--base) / 2);
|
||||
|
||||
& > * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,29 @@ import { useConfig } from '../../../../../packages/payload/src/admin/components/
|
||||
|
||||
import './index.scss'
|
||||
|
||||
const baseClass = 'custom-minimal-route'
|
||||
const baseClass = 'custom-minimal-view'
|
||||
|
||||
const CustomMinimalRoute: React.FC = () => {
|
||||
const CustomMinimalView: React.FC = () => {
|
||||
const {
|
||||
routes: { admin: adminRoute },
|
||||
} = useConfig()
|
||||
|
||||
return (
|
||||
<MinimalTemplate className={baseClass}>
|
||||
<h1>Custom Route</h1>
|
||||
<p>Here is a custom route that was added in the Payload config.</p>
|
||||
<div className={`${baseClass}__content`}>
|
||||
<h1>Custom Admin View</h1>
|
||||
<p>Here is a custom admin view that was added in the Payload config.</p>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<Button className={`${baseClass}__login-btn`} el="link" to={`${adminRoute}/login`}>
|
||||
Go to Login
|
||||
</Button>
|
||||
<Button buttonStyle="secondary" el="link" to={`${adminRoute}`}>
|
||||
Go to Dashboard
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</MinimalTemplate>
|
||||
)
|
||||
}
|
||||
|
||||
export default CustomMinimalRoute
|
||||
export default CustomMinimalView
|
||||
@@ -11,10 +11,10 @@ import CustomTabComponent from './components/CustomTabComponent'
|
||||
import DemoUIFieldCell from './components/DemoUIField/Cell'
|
||||
import DemoUIFieldField from './components/DemoUIField/Field'
|
||||
import Logout from './components/Logout'
|
||||
import CustomDefaultRoute from './components/routes/CustomDefault'
|
||||
import CustomMinimalRoute from './components/routes/CustomMinimal'
|
||||
import CustomDefaultView from './components/views/CustomDefault'
|
||||
import CustomDefaultEditView from './components/views/CustomDefaultEdit'
|
||||
import CustomEditView from './components/views/CustomEdit'
|
||||
import CustomMinimalRoute from './components/views/CustomMinimal'
|
||||
import CustomVersionsView from './components/views/CustomVersions'
|
||||
import CustomView from './components/views/CustomView'
|
||||
import { globalSlug, postsSlug, slugPluralLabel, slugSingularLabel } from './shared'
|
||||
@@ -32,16 +32,6 @@ export default buildConfigWithDefaults({
|
||||
css: path.resolve(__dirname, 'styles.scss'),
|
||||
components: {
|
||||
// providers: [CustomProvider, CustomProvider],
|
||||
routes: [
|
||||
{
|
||||
path: '/custom-minimal-route',
|
||||
Component: CustomMinimalRoute,
|
||||
},
|
||||
{
|
||||
path: '/custom-default-route',
|
||||
Component: CustomDefaultRoute,
|
||||
},
|
||||
],
|
||||
afterDashboard: [AfterDashboard],
|
||||
beforeLogin: [BeforeLogin],
|
||||
logout: {
|
||||
@@ -51,6 +41,14 @@ export default buildConfigWithDefaults({
|
||||
views: {
|
||||
// Dashboard: CustomDashboardView,
|
||||
// Account: CustomAccountView,
|
||||
CustomMinimalRoute: {
|
||||
path: '/custom-minimal-view',
|
||||
Component: CustomMinimalRoute,
|
||||
},
|
||||
CustomDefaultRoute: {
|
||||
path: '/custom-default-view',
|
||||
Component: CustomDefaultView,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -184,7 +182,7 @@ export default buildConfigWithDefaults({
|
||||
views: {
|
||||
Edit: {
|
||||
// This will override one specific nested view within the `/edit/:id` route, i.e. `/edit/:id/versions`
|
||||
Default: CustomDefaultView,
|
||||
Default: CustomDefaultEditView,
|
||||
Versions: CustomVersionsView,
|
||||
MyCustomView: {
|
||||
path: '/custom-tab-view',
|
||||
@@ -328,7 +326,7 @@ export default buildConfigWithDefaults({
|
||||
components: {
|
||||
views: {
|
||||
Edit: {
|
||||
Default: CustomDefaultView,
|
||||
Default: CustomDefaultEditView,
|
||||
Versions: CustomVersionsView,
|
||||
MyCustomView: {
|
||||
path: '/custom-tab-view',
|
||||
|
||||
Reference in New Issue
Block a user