管理用户偏好设置

当用户与管理面板交互时,你可能希望以持久化的方式存储他们的偏好设置,这样当他们从不同会话或不同设备重新访问管理面板时,可以立即回到上次离开时的状态。

Payload 默认提供了多种方式来持久化存储用户偏好设置,包括:

  1. 集合列表视图中的列:它们的激活状态和排序顺序
  2. 用户最后使用的语言环境
  3. blocksarraycollapsible 字段的"折叠"状态
  4. Nav 组件最后已知的状态等

重要提示:

所有偏好设置都是基于单个用户存储的。Payload 会自动识别通过所有提供的认证方法读取或设置偏好的用户。

使用场景

如上所述,该 API 主要用于管理面板的内部操作。但如果你正在为管理面板构建自己的 React 组件,你可以允许用户根据他们使用组件的情况来设置自己的偏好。例如:

  • 如果你构建了一个"颜色选择器",可以"记住"用户上次设置的颜色,方便下次快速访问
  • 如果你构建了一个自定义的 Nav 组件,并且实现了"手风琴式"UI,你可能希望存储每个导航可折叠项的 collapsed 状态。这样,当编辑者返回面板时,他们的 Nav 状态会自动保持
  • 你可能希望存储 recentlyAccessed 文档,为管理员编辑提供快捷方式,方便他们快速回到最近访问的文档(在 Dashboard 或类似界面中)
  • 还有许多其他使用场景。发挥你的创意!为你的编辑者提供智能且持久的编辑体验。

数据库

Payload 会自动创建一个内部使用的 payload-preferences Collection 来存储用户偏好设置。payload-preferences Collection 中的每个文档包含以下结构:

键名描述
id每个存储偏好的唯一 ID。
key对应偏好的唯一 key
user.value存储偏好的 user 的 ID。
user.relationTo用户登录时所属 Collection 的 slug
value偏好的值。可以是任何你需要的数据结构。
createdAt偏好创建时的时间戳。
updatedAt偏好最后一次更新时间的时间戳。

API

偏好设置功能在 GraphQLREST API 中均可使用。

在自定义组件中添加或读取偏好设置

Payload 管理面板提供了 usePreferences 钩子。该钩子仅限在管理面板内部使用,它提供了两个方法:

getPreference

这个异步方法提供了一种简单的方式来通过 key 获取用户偏好。它将返回一个包含偏好值的 Promise。

参数

  • key: 要获取的偏好设置的 key

setPreference

同样是异步方法,它提供了一种简单的方式来设置用户偏好。返回值为 void

参数:

  • key: 要设置的偏好 key
  • value: 你想要设置的偏好 value

示例

以下示例展示了如何在自定义 Admin Panel 组件中使用 usePreferences。请注意 - 这个示例本身并不完全实用,主要是作为 Preferences API 使用方式的参考。在这个例子中,我们演示了如何在 ColorPicker 或类似组件中设置和获取用户最近使用的颜色历史。

'use client'
import React, { Fragment, useState, useEffect, useCallback } from 'react'
import { usePreferences } from '@payloadcms/ui'

const lastUsedColorsPreferenceKey = 'last-used-colors'

export function CustomComponent() {
  const { getPreference, setPreference } = usePreferences()

  // 在本地状态中存储最近使用的颜色
  const [lastUsedColors, setLastUsedColors] = useState([])

  // 添加颜色到最近使用列表的回调函数
  const updateLastUsedColors = useCallback(
    (color) => {
      // 首先检查颜色是否已存在于最近使用列表中
      // 如果已存在,则无需更新偏好设置
      const colorAlreadyExists = lastUsedColors.indexOf(color) > -1

      if (!colorAlreadyExists) {
        const newLastUsedColors = [...lastUsedColors, color]

        setLastUsedColors(newLastUsedColors)
        setPreference(lastUsedColorsPreferenceKey, newLastUsedColors)
      }
    },
    [lastUsedColors, setPreference],
  )

  // 在组件挂载时获取偏好设置
  // 这只会运行一次,因为 `getPreference` 方法永远不会改变
  useEffect(() => {
    const asyncGetPreference = async () => {
      const lastUsedColorsFromPreferences = await getPreference(
        lastUsedColorsPreferenceKey,
      )
      setLastUsedColors(lastUsedColorsFromPreferences)
    }

    asyncGetPreference()
  }, [getPreference])

  return (
    <div>
      <button type="button" onClick={() => updateLastUsedColors('red')}>
        使用红色
      </button>
      <button type="button" onClick={() => updateLastUsedColors('blue')}>
        使用蓝色
      </button>
      <button type="button" onClick={() => updateLastUsedColors('purple')}>
        使用紫色
      </button>
      <button type="button" onClick={() => updateLastUsedColors('yellow')}>
        使用黄色
      </button>
      {lastUsedColors && (
        <Fragment>
          <h5>最近使用的颜色:</h5>
          <ul>
            {lastUsedColors?.map((color) => <li key={color}>{color}</li>)}
          </ul>
        </Fragment>
      )}
    </div>
  )
}