fix(next, ui): exclude expired locks for globals (#8914)

Continued PR off of https://github.com/payloadcms/payload/pull/8899
This commit is contained in:
Patrik
2024-10-28 21:49:50 -04:00
committed by GitHub
parent 1e002acce9
commit e74906f555
10 changed files with 455 additions and 86 deletions

View File

@@ -16,7 +16,11 @@ import './index.scss'
const baseClass = 'dashboard'
export type DashboardProps = {
globalData: Array<{ data: { _isLocked: boolean; _userEditing: ClientUser | null }; slug: string }>
globalData: Array<{
data: { _isLocked: boolean; _lastEditedAt: string; _userEditing: ClientUser | null }
lockDuration?: number
slug: string
}>
Link: React.ComponentType<any>
navGroups?: ReturnType<typeof groupNavItems>
permissions: Permissions
@@ -95,7 +99,7 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
let createHREF: string
let href: string
let hasCreatePermission: boolean
let lockStatus = null
let isLocked = null
let userEditing = null
if (type === EntityType.collection) {
@@ -130,9 +134,24 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
const globalLockData = globalData.find(
(global) => global.slug === entity.slug,
)
if (globalLockData) {
lockStatus = globalLockData.data._isLocked
isLocked = globalLockData.data._isLocked
userEditing = globalLockData.data._userEditing
// Check if the lock is expired
const lockDuration = globalLockData?.lockDuration
const lastEditedAt = new Date(
globalLockData.data?._lastEditedAt,
).getTime()
const lockDurationInMilliseconds = lockDuration * 1000
const lockExpirationTime = lastEditedAt + lockDurationInMilliseconds
if (new Date().getTime() > lockExpirationTime) {
isLocked = false
userEditing = null
}
}
}
@@ -140,7 +159,7 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
<li key={entityIndex}>
<Card
actions={
lockStatus && user?.id !== userEditing?.id ? (
isLocked && user?.id !== userEditing?.id ? (
<Locked className={`${baseClass}__locked`} user={userEditing} />
) : hasCreatePermission && type === EntityType.collection ? (
<Button

View File

@@ -34,6 +34,8 @@ export const Dashboard: React.FC<AdminViewProps> = async ({
visibleEntities,
} = initPageResult
const lockDurationDefault = 300 // Default 5 minutes in seconds
const CustomDashboardComponent = config.admin.components?.views?.Dashboard
const collections = config.collections.filter(
@@ -48,16 +50,26 @@ export const Dashboard: React.FC<AdminViewProps> = async ({
visibleEntities.globals.includes(global.slug),
)
const globalSlugs = config.globals.map((global) => global.slug)
const globalConfigs = config.globals.map((global) => ({
slug: global.slug,
lockDuration:
global.lockDocuments === false
? null // Set lockDuration to null if locking is disabled
: typeof global.lockDocuments === 'object'
? global.lockDocuments.duration
: lockDurationDefault,
}))
// Filter the slugs based on permissions and visibility
const filteredGlobalSlugs = globalSlugs.filter(
(slug) =>
permissions?.globals?.[slug]?.read?.permission && visibleEntities.globals.includes(slug),
const filteredGlobalConfigs = globalConfigs.filter(
({ slug, lockDuration }) =>
lockDuration !== null && // Ensure lockDuration is valid
permissions?.globals?.[slug]?.read?.permission &&
visibleEntities.globals.includes(slug),
)
const globalData = await Promise.all(
filteredGlobalSlugs.map(async (slug) => {
filteredGlobalConfigs.map(async ({ slug, lockDuration }) => {
const data = await payload.findGlobal({
slug,
depth: 0,
@@ -67,6 +79,7 @@ export const Dashboard: React.FC<AdminViewProps> = async ({
return {
slug,
data,
lockDuration,
}
}),
)