Compare commits

...

9 Commits

Author SHA1 Message Date
Jacob Fletcher
69d9205b6b Merge branch 'main' into perf/prefs 2024-11-25 13:58:16 -05:00
Jacob Fletcher
81b647b17e perf: uses upsert on prefs when building table state 2024-11-25 13:14:02 -05:00
Jacob Fletcher
98f0b244ba resets website template lockfile 2024-11-25 12:45:23 -05:00
Jacob Fletcher
bacca65ad0 exposes findPreferenceByKey 2024-11-25 12:41:17 -05:00
Jacob Fletcher
bfff24d160 resets website template lockfile 2024-11-25 12:26:22 -05:00
Jacob Fletcher
fb51aaf740 removes from db adapter bc upsert exists 2024-11-25 12:14:12 -05:00
Jacob Fletcher
e993216c2c Merge branch 'main' into feat/update-prefs 2024-11-25 12:01:22 -05:00
Jacob Fletcher
2d425f8331 fix return type 2024-11-25 11:56:27 -05:00
Jacob Fletcher
cd8a1a6b9c feat: exposes updatePreference operation 2024-11-25 11:51:43 -05:00
19 changed files with 86 additions and 220 deletions

View File

@@ -1,36 +1,27 @@
import type { NavPreferences, Payload, User } from 'payload'
import type { NavPreferences, Payload, PayloadRequest, User } from 'payload'
import { cache } from 'react'
export const getNavPrefs = cache(
async ({ payload, user }: { payload: Payload; user: User }): Promise<NavPreferences> =>
async ({
payload,
req,
user,
}: {
payload: Payload
req: PayloadRequest
user: User
}): Promise<NavPreferences> =>
user
? await payload
.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
user,
where: {
and: [
{
key: {
equals: 'nav',
},
},
{
'user.relationTo': {
equals: user.collection,
},
},
{
'user.value': {
equals: user.id,
},
},
],
.findPreferenceByKey({
key: 'nav',
req: {
...(req || ({} as PayloadRequest)),
payload, // do this for backward compatibility, `req` is a _new_ argument, but `payload` is not
},
user,
})
?.then((res) => res?.docs?.[0]?.value)
?.then((res) => res?.value)
: null,
)

View File

@@ -1,5 +1,5 @@
import type { EntityToGroup } from '@payloadcms/ui/shared'
import type { ServerProps } from 'payload'
import type { PayloadRequest, ServerProps } from 'payload'
import { Logout } from '@payloadcms/ui'
import { RenderServerComponent } from '@payloadcms/ui/elements/RenderServerComponent'
@@ -15,10 +15,13 @@ const baseClass = 'nav'
import { getNavPrefs } from './getNavPrefs.js'
import { DefaultNavClient } from './index.client.js'
export type NavProps = ServerProps
export type NavProps = {
req?: PayloadRequest
} & ServerProps
export const DefaultNav: React.FC<NavProps> = async (props) => {
const { i18n, locale, params, payload, permissions, searchParams, user, visibleEntities } = props
const { i18n, locale, params, payload, permissions, req, searchParams, user, visibleEntities } =
props
if (!payload?.config) {
return null
@@ -57,7 +60,7 @@ export const DefaultNav: React.FC<NavProps> = async (props) => {
i18n,
)
const navPreferences = await getNavPrefs({ payload, user })
const navPreferences = await getNavPrefs({ payload, req, user })
const LogoutComponent = RenderServerComponent({
Component: logout?.Button,

View File

@@ -84,7 +84,7 @@ export const RootLayout = async ({
})
}
const navPrefs = await getNavPrefs({ payload, user })
const navPrefs = await getNavPrefs({ payload, req, user })
const clientConfig = await getClientConfig({
config,

View File

@@ -1,4 +1,4 @@
import type { CustomComponent, ServerProps, VisibleEntities } from 'payload'
import type { CustomComponent, PayloadRequest, ServerProps, VisibleEntities } from 'payload'
import {
ActionsProvider,
@@ -20,6 +20,7 @@ const baseClass = 'template-default'
export type DefaultTemplateProps = {
children?: React.ReactNode
className?: string
req?: PayloadRequest
viewActions?: CustomComponent[]
visibleEntities: VisibleEntities
} & ServerProps
@@ -32,6 +33,7 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
params,
payload,
permissions,
req,
searchParams,
user,
viewActions,
@@ -85,6 +87,7 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
params,
payload,
permissions,
req,
searchParams,
user,
visibleEntities,

View File

@@ -84,33 +84,13 @@ export const initPage = async ({
if (!localeCode) {
try {
localeCode = await payload
.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
.findPreferenceByKey({
key: 'locale',
req,
user,
where: {
and: [
{
'user.relationTo': {
equals: payload.config.admin.user,
},
},
{
'user.value': {
equals: user.id,
},
},
{
key: {
equals: 'locale',
},
},
],
},
})
?.then((res) => res.docs?.[0]?.value as string)
} catch (error) {} // eslint-disable-line no-empty
?.then((res) => res?.value as string)
} catch (_err) {} // eslint-disable-line no-empty
}
locale = findLocaleFromCode(localization, localeCode)

View File

@@ -63,6 +63,7 @@ export const Account: React.FC<AdminViewProps> = async ({
id: user.id,
collectionSlug: collectionConfig.slug,
payload,
req,
user,
})

View File

@@ -41,6 +41,7 @@ export const CreateFirstUserView: React.FC<AdminViewProps> = async ({ initPageRe
const docPreferences = await getDocPreferences({
collectionSlug: collectionConfig.slug,
payload: req.payload,
req,
user: req.user,
})

View File

@@ -1,4 +1,4 @@
import type { DocumentPreferences, Payload, TypedUser } from 'payload'
import type { DocumentPreferences, Payload, PayloadRequest, TypedUser } from 'payload'
import { sanitizeID } from '@payloadcms/ui/shared'
@@ -7,6 +7,7 @@ type Args = {
globalSlug?: string
id?: number | string
payload: Payload
req: PayloadRequest
user: TypedUser
}
@@ -15,6 +16,7 @@ export const getDocPreferences = async ({
collectionSlug,
globalSlug,
payload,
req,
user,
}: Args): Promise<DocumentPreferences> => {
let preferencesKey
@@ -28,33 +30,14 @@ export const getDocPreferences = async ({
}
if (preferencesKey) {
const preferencesResult = (await payload.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
where: {
and: [
{
key: {
equals: preferencesKey,
},
},
{
'user.relationTo': {
equals: user.collection,
},
},
{
'user.value': {
equals: sanitizeID(user.id),
},
},
],
},
})) as unknown as { docs: { value: DocumentPreferences }[] }
const preferencesResult = (await payload.findPreferenceByKey({
key: preferencesKey,
req,
user,
})) as unknown as { value: DocumentPreferences }
if (preferencesResult?.docs?.[0]?.value) {
return preferencesResult.docs[0].value
if (preferencesResult?.value) {
return preferencesResult.value
}
}

View File

@@ -124,31 +124,12 @@ export const renderDocumentHandler = async (args: {
const preferencesKey = `${collectionSlug}-edit-${docID}`
preferences = await payload
.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
where: {
and: [
{
key: {
equals: preferencesKey,
},
},
{
'user.relationTo': {
equals: user.collection,
},
},
{
'user.value': {
equals: user.id,
},
},
],
},
.findPreferenceByKey({
key: preferencesKey,
req,
user,
})
.then((res) => res.docs[0]?.value as DocumentPreferences)
.then((res) => res?.value as DocumentPreferences)
}
const visibleEntities: VisibleEntities = {

View File

@@ -108,6 +108,7 @@ export const renderDocument = async ({
collectionSlug,
globalSlug,
payload,
req,
user,
}),

View File

@@ -123,31 +123,12 @@ export const renderListHandler = async (args: {
const preferencesKey = `${collectionSlug}-list`
const preferences = await payload
.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
where: {
and: [
{
key: {
equals: preferencesKey,
},
},
{
'user.relationTo': {
equals: user.collection,
},
},
{
'user.value': {
equals: user.id,
},
},
],
},
.findPreferenceByKey({
key: preferencesKey,
req,
user,
})
.then((res) => res.docs[0]?.value as ListPreferences)
.then((res) => res?.value as ListPreferences)
const visibleEntities: VisibleEntities = {
collections: payload.config.collections

View File

@@ -77,33 +77,12 @@ export const renderListView = async (
try {
listPreferences = (await payload
.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
.findPreferenceByKey({
key: preferenceKey,
req,
user,
where: {
and: [
{
key: {
equals: preferenceKey,
},
},
{
'user.relationTo': {
equals: user.collection,
},
},
{
'user.value': {
equals: user?.id,
},
},
],
},
})
?.then((res) => res?.docs?.[0]?.value)) as ListPreferences
?.then((res) => res?.value)) as ListPreferences
} catch (_err) {} // eslint-disable-line no-empty
const {

View File

@@ -78,6 +78,7 @@ export const NotFoundPage = async ({
params={params}
payload={initPageResult.req.payload}
permissions={initPageResult.permissions}
req={initPageResult.req}
searchParams={searchParams}
user={initPageResult.req.user}
visibleEntities={initPageResult.visibleEntities}

View File

@@ -151,6 +151,7 @@ export const RootPage = async ({
params={params}
payload={initPageResult?.req.payload}
permissions={initPageResult?.permissions}
req={initPageResult?.req}
searchParams={searchParams}
user={initPageResult?.req.user}
viewActions={serverProps.viewActions}

View File

@@ -1,5 +1,7 @@
/* eslint-disable no-restricted-exports */
import auth from '../../../auth/operations/local/index.js'
import { findOne as findPreferenceByKey } from '../../../preferences/operations/findOne.js'
import { update as updatePreference } from '../../../preferences/operations/update.js'
import count from './count.js'
import countVersions from './countVersions.js'
import create from './create.js'
@@ -21,8 +23,10 @@ export default {
duplicate,
find: findLocal,
findByID,
findPreferenceByKey,
findVersionByID,
findVersions,
restoreVersion,
update,
updatePreference,
}

View File

@@ -54,6 +54,7 @@ import type { Options as FindGlobalVersionByIDOptions } from './globals/operatio
import type { Options as FindGlobalVersionsOptions } from './globals/operations/local/findVersions.js'
import type { Options as RestoreGlobalVersionOptions } from './globals/operations/local/restoreVersion.js'
import type { Options as UpdateGlobalOptions } from './globals/operations/local/update.js'
import type { PreferenceRequest, PreferenceUpdateRequest } from './preferences/types.js'
import type {
ApplyDisableErrors,
JsonObject,
@@ -375,6 +376,8 @@ export class BasePayload {
return findVersions<TSlug>(this, options)
}
findPreferenceByKey = async (args: PreferenceRequest) => localOperations.findPreferenceByKey(args)
/**
* @description Find version by ID
* @param options
@@ -486,6 +489,8 @@ export class BasePayload {
return update<TSlug, TSelect>(this, options)
}
updatePreference = async (args: PreferenceUpdateRequest) => localOperations.updatePreference(args)
validationRules: (args: OperationArgs<any>) => ValidationRule[]
verifyEmail = async <TSlug extends CollectionSlug>(

View File

@@ -1,9 +1,12 @@
import type { TypedCollection } from '../../index.js'
import type { Where } from '../../types/index.js'
import type { PreferenceUpdateRequest } from '../types.js'
import { UnauthorizedError } from '../../errors/UnathorizedError.js'
export async function update(args: PreferenceUpdateRequest) {
export async function update(
args: PreferenceUpdateRequest,
): Promise<TypedCollection['_preference']> {
const {
key,
req: { payload },

View File

@@ -10,7 +10,6 @@ import type {
SanitizedConfig,
} from 'payload'
import { dequal } from 'dequal/lite'
import { createClientConfig, formatErrors } from 'payload'
import type { Column } from '../elements/Table/index.js'
@@ -165,65 +164,14 @@ export const buildTableState = async (
// get prefs, then set update them using the columns that we just received
const preferencesKey = `${collectionSlug}-list`
const preferencesResult = await payload
.find({
collection: 'payload-preferences',
depth: 0,
limit: 1,
pagination: false,
where: {
and: [
{
key: {
equals: preferencesKey,
},
},
{
'user.relationTo': {
equals: user.collection,
},
},
{
'user.value': {
equals: user.id,
},
},
],
},
})
.then((res) => res.docs[0] ?? { id: null, value: {} })
let newPrefs = preferencesResult.value
if (!preferencesResult.id || !dequal(columns, preferencesResult?.columns)) {
const preferencesArgs = {
collection: 'payload-preferences',
data: {
key: preferencesKey,
user: {
collection: user.collection,
value: user.id,
},
value: {
...(preferencesResult?.value || {}),
columns,
},
},
depth: 0,
req,
}
if (preferencesResult.id) {
newPrefs = await payload
.update({
...preferencesArgs,
id: preferencesResult.id,
})
?.then((res) => res.value as ListPreferences)
} else {
newPrefs = await payload.create(preferencesArgs)?.then((res) => res.value as ListPreferences)
}
}
const preferencesResult = await payload.updatePreference({
key: preferencesKey,
req,
user,
value: {
columns,
},
})
const fields = collectionConfig.fields
@@ -263,7 +211,7 @@ export const buildTableState = async (
return {
data,
preferences: newPrefs,
preferences: preferencesResult?.value,
renderedFilters,
state: columnState,
Table,

View File

@@ -40,9 +40,9 @@ export interface Config {
user: User & {
collection: 'users';
};
jobs?: {
jobs: {
tasks: unknown;
workflows?: unknown;
workflows: unknown;
};
}
export interface UserAuthOperations {