Refactor ObjectTable and ObjectTableNavigationButtons for improved state management
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good

- Updated imports in ObjectTable and ObjectTableNavigationButtons to include getActiveFilterValues from TableStateContext.
- Simplified the useTableStatePersistence hook calls by removing unnecessary destructured values.
- Enhanced navigation button handlers with useCallback for better performance and readability.
- Added keyboard shortcuts for previous and next navigation, improving user experience.
This commit is contained in:
Tom Butcher 2026-08-09 13:28:23 +01:00
parent 68aed21cc5
commit 2068b7470b
4 changed files with 36 additions and 18 deletions

View File

@ -47,7 +47,10 @@ import { useActions } from '../context/ActionsContext'
import ActionsIcon from '../../Icons/ActionsIcon'
import FilterIcon from '../../Icons/FilterIcon'
import ScrollBox from './ScrollBox'
import { useTableStatePersistence } from '../context/TableStateContext'
import {
getActiveFilterValues,
useTableStatePersistence
} from '../context/TableStateContext'
const logger = loglevel.getLogger('DasboardTable')
logger.setLevel(config.logLevel)
@ -154,8 +157,7 @@ const ObjectTable = forwardRef(
getPersistedSorter,
persistFilter,
persistTableState,
registerPageFilter,
getActiveFilterValues
registerPageFilter
} = useTableStatePersistence({
scope: type,
pagePath: location.pathname,

View File

@ -6,7 +6,10 @@ import ArrowRightIcon from '../../Icons/ArrowRightIcon.jsx'
import PropTypes from 'prop-types'
import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import { useTableStatePersistence } from '../context/TableStateContext'
import {
getActiveFilterValues,
useTableStatePersistence
} from '../context/TableStateContext'
import KeyboardShortcut from './KeyboardShortcut.jsx'
const ObjectTableNavigationButtons = ({
@ -21,8 +24,7 @@ const ObjectTableNavigationButtons = ({
const [neighbors, setNeighbors] = useState({ next: null, previous: null })
const [loading, setLoading] = useState(false)
const { getPersistedFilter, getPersistedSorter, getActiveFilterValues } =
useTableStatePersistence({
const { getPersistedFilter, getPersistedSorter } = useTableStatePersistence({
scope: objectType,
useFilterInSession: true,
useSortInSession: true
@ -87,8 +89,25 @@ const ObjectTableNavigationButtons = ({
[searchParams, setSearchParams, objectType]
)
const handlePrevious = () => navigateToNeighbor(neighbors.previous)
const handleNext = () => navigateToNeighbor(neighbors.next)
const handlePrevious = useCallback(() => {
navigateToNeighbor(neighbors.previous)
}, [navigateToNeighbor, neighbors.previous])
const handleNext = useCallback(() => {
navigateToNeighbor(neighbors.next)
}, [navigateToNeighbor, neighbors.next])
const handlePreviousShortcut = useCallback(() => {
if (!disabled && !loading && neighbors.previous?._id) {
handlePrevious()
}
}, [disabled, loading, neighbors.previous?._id, handlePrevious])
const handleNextShortcut = useCallback(() => {
if (!disabled && !loading && neighbors.next?._id) {
handleNext()
}
}, [disabled, loading, neighbors.next?._id, handleNext])
return (
<Flex gap='small' align='center'>
@ -99,11 +118,7 @@ const ObjectTableNavigationButtons = ({
<KeyboardShortcut
shortcut='alt+arrowleft'
hint='ALT ←'
onTrigger={useCallback(() => {
if (!disabled && !loading && neighbors.previous?._id) {
handlePrevious()
}
}, [disabled, loading, neighbors.previous?._id])}
onTrigger={handlePreviousShortcut}
>
<Button
icon={<ArrowLeftIcon />}
@ -114,11 +129,7 @@ const ObjectTableNavigationButtons = ({
<KeyboardShortcut
shortcut='alt+arrowright'
hint='ALT →'
onTrigger={useCallback(() => {
if (!disabled && !loading && neighbors.next?._id) {
handleNext()
}
}, [disabled, loading, neighbors.next?._id])}
onTrigger={handleNextShortcut}
>
<Button
icon={<ArrowRightIcon />}

View File

@ -27,6 +27,7 @@ const DEFAULT_UPDATE_ENGINE = 'native'
const CURRENT_BUILD_NUMBER = import.meta.env.VITE_BUILD_NUMBER
const APP_UPDATE_DISMISSED_KEY = 'appUpdateDismissed'
// eslint-disable-next-line react-refresh/only-export-components
export const normalizeAppUpdateEngine = (engine) => {
const value = String(engine || '')
.trim()

View File

@ -16,6 +16,7 @@ export const SORT_URL_PARAM = 'sort'
const getSessionFilterKey = (scope) => `tableState:${scope}:filter`
const getSessionSortKey = (scope) => `tableState:${scope}:sort`
// eslint-disable-next-line react-refresh/only-export-components
export const getActiveFilterValues = (filterState) => {
const active = {}
Object.entries(filterState || {}).forEach(([k, v]) => {
@ -51,6 +52,7 @@ const readFilterFromSession = (scope) => {
}
}
// eslint-disable-next-line react-refresh/only-export-components
export const hasStoredSessionFilter = (scope) => {
if (!scope) return false
return Object.keys(getActiveFilterValues(readFilterFromSession(scope) || {})).length > 0
@ -268,6 +270,7 @@ export const TableStateProvider = ({ children }) => {
)
}
// eslint-disable-next-line react-refresh/only-export-components
export const useTableState = () => {
const context = useContext(TableStateContext)
if (!context) {
@ -276,6 +279,7 @@ export const useTableState = () => {
return context
}
// eslint-disable-next-line react-refresh/only-export-components
export const useTableStatePersistence = ({
scope,
pagePath,