-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow turning off pages from Payload
- Loading branch information
1 parent
3a78aaf
commit 089ae21
Showing
13 changed files
with
172 additions
and
15 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {type User} from 'payload/auth'; | ||
import {type SessionUser} from '../collections/users'; | ||
|
||
export const hiddenUnlessOwner = ({user}: {user: User}) => { | ||
const sessionUser = user as unknown as SessionUser; | ||
const roles = | ||
'roles' in sessionUser ? sessionUser.roles : sessionUser.user.roles; | ||
|
||
return !roles.includes('owner'); | ||
}; |
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,39 @@ | ||
import {type CollectionConfig} from 'payload/types'; | ||
import {hiddenUnlessOwner} from '../access/hidden-unless-owner'; | ||
import {requireOneOf} from '../access/require-one-of'; | ||
|
||
export const Features: CollectionConfig = { | ||
slug: 'feature', | ||
access: { | ||
create: requireOneOf(), | ||
update: requireOneOf(), | ||
delete: requireOneOf(), | ||
}, | ||
admin: { | ||
useAsTitle: 'name', | ||
hidden: hiddenUnlessOwner, | ||
}, | ||
fields: [ | ||
{ | ||
name: 'name', | ||
type: 'text', | ||
required: true, | ||
}, | ||
{ | ||
name: 'pathPrefix', | ||
type: 'text', | ||
required: true, | ||
}, | ||
{ | ||
name: 'navPath', | ||
type: 'text', | ||
hooks: { | ||
beforeValidate: [({value, data}) => value ?? data.pathPrefix], | ||
}, | ||
}, | ||
{ | ||
name: 'enabled', | ||
type: 'checkbox', | ||
}, | ||
], | ||
}; |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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,11 @@ | ||
query Features { | ||
Features { | ||
docs { | ||
id | ||
name | ||
enabled | ||
navPath | ||
pathPrefix | ||
} | ||
} | ||
} |
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,37 @@ | ||
import {notFound} from 'next/navigation'; | ||
import {type NavLinkDefinition} from '../../ui'; | ||
import {type FeaturesQuery, graphqlWithHeaders} from '../graphql/client'; | ||
|
||
type Defined<T> = Exclude<T, null | undefined>; | ||
type Features = Defined<Defined<FeaturesQuery['Features']>['docs']>; | ||
type Feature = Defined<Features[number]>; | ||
|
||
const getFeatures = async (): Promise<Feature[]> => { | ||
const data = await graphqlWithHeaders((sdk) => sdk.Features()); | ||
|
||
return (data.Features?.docs ?? []).filter((f): f is Feature => !!f); | ||
}; | ||
|
||
const isNavEnabled = async (path: string): Promise<boolean> => { | ||
const features = await getFeatures(); | ||
const feature = features.find((f) => path.startsWith(f.pathPrefix)); | ||
|
||
// If not defined otherwise, we consider a page accessible (think legal stuff that isn't setup in payload) | ||
return feature?.enabled ?? true; | ||
}; | ||
|
||
export const getNavRoutes = async (): Promise<NavLinkDefinition[]> => { | ||
const features = await getFeatures(); | ||
|
||
return features | ||
.filter((f) => f.enabled) | ||
.map((f) => ({text: f.name, href: f.navPath ?? '#'})); | ||
}; | ||
|
||
export const ensureNavEnabled = async (path: string) => { | ||
const enabled = await isNavEnabled(path); | ||
|
||
if (!enabled) { | ||
notFound(); | ||
} | ||
}; |