fix(ui): propagates sort change events through list query provider (#7968)
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FieldBase } from 'payload'
|
import type { FieldBase } from 'payload'
|
||||||
|
|
||||||
// TODO: abstract the `next/navigation` dependency out from this component
|
import React from 'react'
|
||||||
import React, { useCallback } from 'react'
|
|
||||||
|
|
||||||
import { ChevronIcon } from '../../icons/Chevron/index.js'
|
import { ChevronIcon } from '../../icons/Chevron/index.js'
|
||||||
import { useListQuery } from '../../providers/ListQuery/index.js'
|
import { useListQuery } from '../../providers/ListQuery/index.js'
|
||||||
@@ -11,10 +10,10 @@ import { useTranslation } from '../../providers/Translation/index.js'
|
|||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
export type SortColumnProps = {
|
export type SortColumnProps = {
|
||||||
Label: React.ReactNode
|
readonly Label: React.ReactNode
|
||||||
disable?: boolean
|
readonly disable?: boolean
|
||||||
label?: FieldBase['label']
|
readonly label?: FieldBase['label']
|
||||||
name: string
|
readonly name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseClass = 'sort-column'
|
const baseClass = 'sort-column'
|
||||||
@@ -22,7 +21,7 @@ const baseClass = 'sort-column'
|
|||||||
export const SortColumn: React.FC<SortColumnProps> = (props) => {
|
export const SortColumn: React.FC<SortColumnProps> = (props) => {
|
||||||
const { name, Label, disable = false, label } = props
|
const { name, Label, disable = false, label } = props
|
||||||
const { searchParams } = useSearchParams()
|
const { searchParams } = useSearchParams()
|
||||||
const { refineListData } = useListQuery()
|
const { handleSortChange } = useListQuery()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const { sort } = searchParams
|
const { sort } = searchParams
|
||||||
@@ -40,15 +39,6 @@ export const SortColumn: React.FC<SortColumnProps> = (props) => {
|
|||||||
descClasses.push(`${baseClass}--active`)
|
descClasses.push(`${baseClass}--active`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setSort = useCallback(
|
|
||||||
async (newSort: string) => {
|
|
||||||
await refineListData({
|
|
||||||
sort: newSort,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
[refineListData],
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
<span className={`${baseClass}__label`}>{Label}</span>
|
<span className={`${baseClass}__label`}>{Label}</span>
|
||||||
@@ -60,7 +50,7 @@ export const SortColumn: React.FC<SortColumnProps> = (props) => {
|
|||||||
label,
|
label,
|
||||||
})}
|
})}
|
||||||
className={[...ascClasses, `${baseClass}__button`].filter(Boolean).join(' ')}
|
className={[...ascClasses, `${baseClass}__button`].filter(Boolean).join(' ')}
|
||||||
onClick={() => void setSort(asc)}
|
onClick={() => void handleSortChange(asc)}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<ChevronIcon direction="up" />
|
<ChevronIcon direction="up" />
|
||||||
@@ -71,7 +61,7 @@ export const SortColumn: React.FC<SortColumnProps> = (props) => {
|
|||||||
label,
|
label,
|
||||||
})}
|
})}
|
||||||
className={[...descClasses, `${baseClass}__button`].filter(Boolean).join(' ')}
|
className={[...descClasses, `${baseClass}__button`].filter(Boolean).join(' ')}
|
||||||
onClick={() => void setSort(desc)}
|
onClick={() => void handleSortChange(desc)}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<ChevronIcon />
|
<ChevronIcon />
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ type PropHandlers = {
|
|||||||
handleSortChange?: (sort: string) => Promise<void> | void
|
handleSortChange?: (sort: string) => Promise<void> | void
|
||||||
handleWhereChange?: (where: Where) => Promise<void> | void
|
handleWhereChange?: (where: Where) => Promise<void> | void
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContextHandlers = {
|
type ContextHandlers = {
|
||||||
handlePageChange?: (page: number) => Promise<void>
|
handlePageChange?: (page: number) => Promise<void>
|
||||||
handlePerPageChange?: (limit: number) => Promise<void>
|
handlePerPageChange?: (limit: number) => Promise<void>
|
||||||
@@ -29,12 +30,12 @@ type ContextHandlers = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ListQueryProps = {
|
export type ListQueryProps = {
|
||||||
children: React.ReactNode
|
readonly children: React.ReactNode
|
||||||
data: PaginatedDocs
|
readonly data: PaginatedDocs
|
||||||
defaultLimit?: number
|
readonly defaultLimit?: number
|
||||||
defaultSort?: string
|
readonly defaultSort?: string
|
||||||
modifySearchParams?: boolean
|
readonly modifySearchParams?: boolean
|
||||||
preferenceKey?: string
|
readonly preferenceKey?: string
|
||||||
} & PropHandlers
|
} & PropHandlers
|
||||||
|
|
||||||
export type ListQueryContext = {
|
export type ListQueryContext = {
|
||||||
@@ -81,6 +82,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pageQuery = 'page' in query ? query.page : currentQuery?.page
|
let pageQuery = 'page' in query ? query.page : currentQuery?.page
|
||||||
|
|
||||||
if ('where' in query || 'search' in query) {
|
if ('where' in query || 'search' in query) {
|
||||||
pageQuery = '1'
|
pageQuery = '1'
|
||||||
}
|
}
|
||||||
@@ -92,10 +94,12 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
|||||||
updatedPreferences.limit = query.limit
|
updatedPreferences.limit = query.limit
|
||||||
updatePreferences = true
|
updatePreferences = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('sort' in query) {
|
if ('sort' in query) {
|
||||||
updatedPreferences.sort = query.sort
|
updatedPreferences.sort = query.sort
|
||||||
updatePreferences = true
|
updatePreferences = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updatePreferences && preferenceKey) {
|
if (updatePreferences && preferenceKey) {
|
||||||
await setPreference(preferenceKey, updatedPreferences)
|
await setPreference(preferenceKey, updatedPreferences)
|
||||||
}
|
}
|
||||||
@@ -118,42 +122,51 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
|||||||
if (typeof handlePageChangeFromProps === 'function') {
|
if (typeof handlePageChangeFromProps === 'function') {
|
||||||
await handlePageChangeFromProps(arg)
|
await handlePageChangeFromProps(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
await refineListData({ page: String(arg) })
|
await refineListData({ page: String(arg) })
|
||||||
},
|
},
|
||||||
[refineListData, handlePageChangeFromProps],
|
[refineListData, handlePageChangeFromProps],
|
||||||
)
|
)
|
||||||
|
|
||||||
const handlePerPageChange = React.useCallback(
|
const handlePerPageChange = React.useCallback(
|
||||||
async (arg: number) => {
|
async (arg: number) => {
|
||||||
if (typeof handlePerPageChangeFromProps === 'function') {
|
if (typeof handlePerPageChangeFromProps === 'function') {
|
||||||
await handlePerPageChangeFromProps(arg)
|
await handlePerPageChangeFromProps(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
await refineListData({ limit: String(arg) })
|
await refineListData({ limit: String(arg) })
|
||||||
},
|
},
|
||||||
[refineListData, handlePerPageChangeFromProps],
|
[refineListData, handlePerPageChangeFromProps],
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleSearchChange = React.useCallback(
|
const handleSearchChange = React.useCallback(
|
||||||
async (arg: string) => {
|
async (arg: string) => {
|
||||||
if (typeof handleSearchChangeFromProps === 'function') {
|
if (typeof handleSearchChangeFromProps === 'function') {
|
||||||
await handleSearchChangeFromProps(arg)
|
await handleSearchChangeFromProps(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
await refineListData({ search: arg })
|
await refineListData({ search: arg })
|
||||||
},
|
},
|
||||||
[refineListData, handleSearchChangeFromProps],
|
[refineListData, handleSearchChangeFromProps],
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleSortChange = React.useCallback(
|
const handleSortChange = React.useCallback(
|
||||||
async (arg: string) => {
|
async (arg: string) => {
|
||||||
if (typeof handleSortChangeFromProps === 'function') {
|
if (typeof handleSortChangeFromProps === 'function') {
|
||||||
await handleSortChangeFromProps(arg)
|
await handleSortChangeFromProps(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
await refineListData({ sort: arg })
|
await refineListData({ sort: arg })
|
||||||
},
|
},
|
||||||
[refineListData, handleSortChangeFromProps],
|
[refineListData, handleSortChangeFromProps],
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleWhereChange = React.useCallback(
|
const handleWhereChange = React.useCallback(
|
||||||
async (arg: Where) => {
|
async (arg: Where) => {
|
||||||
if (typeof handleWhereChangeFromProps === 'function') {
|
if (typeof handleWhereChangeFromProps === 'function') {
|
||||||
await handleWhereChangeFromProps(arg)
|
await handleWhereChangeFromProps(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
await refineListData({ where: arg })
|
await refineListData({ where: arg })
|
||||||
},
|
},
|
||||||
[refineListData, handleWhereChangeFromProps],
|
[refineListData, handleWhereChangeFromProps],
|
||||||
@@ -168,10 +181,12 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
|
|||||||
currentQuery.limit = String(defaultLimit)
|
currentQuery.limit = String(defaultLimit)
|
||||||
shouldUpdateQueryString = true
|
shouldUpdateQueryString = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultSort && !('sort' in currentQuery)) {
|
if (defaultSort && !('sort' in currentQuery)) {
|
||||||
currentQuery.sort = defaultSort
|
currentQuery.sort = defaultSort
|
||||||
shouldUpdateQueryString = true
|
shouldUpdateQueryString = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldUpdateQueryString) {
|
if (shouldUpdateQueryString) {
|
||||||
router.replace(`?${qs.stringify(currentQuery)}`)
|
router.replace(`?${qs.stringify(currentQuery)}`)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user