83 lines
2.3 KiB
JavaScript

import React, { useEffect, useRef } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import PropTypes from 'prop-types'
const ActionHandler = ({
children,
actions = {},
actionParam = 'action',
clearAfterExecute = true,
onAction,
loading = true
}) => {
const location = useLocation()
const navigate = useNavigate()
const action = new URLSearchParams(location.search).get(actionParam)
// Ref to track last executed action
const lastExecutedAction = useRef(null)
// Method to add action as URL param
const callAction = (actionName) => {
const searchParams = new URLSearchParams(location.search)
searchParams.set(actionParam, actionName)
const newSearch = searchParams.toString()
const newPath = location.pathname + (newSearch ? `?${newSearch}` : '')
navigate(newPath, { replace: true })
}
// Execute action and clear from URL
useEffect(() => {
if (
!loading &&
action &&
actions[action] &&
lastExecutedAction.current !== action
) {
// Execute the action
const result = actions[action]()
// Mark this action as executed
lastExecutedAction.current = action
// Call optional callback
if (onAction) {
onAction(action, result)
}
// Clear action from URL if requested and result is true
if (clearAfterExecute && result == true) {
const searchParams = new URLSearchParams(location.search)
searchParams.delete(actionParam)
const newSearch = searchParams.toString()
const newPath = location.pathname + (newSearch ? `?${newSearch}` : '')
navigate(newPath, { replace: true })
}
} else if (!action) {
// Reset lastExecutedAction if no action is present
lastExecutedAction.current = null
}
}, [
loading,
action,
actions,
actionParam,
clearAfterExecute,
onAction,
location.pathname,
location.search,
navigate
])
// Return null as this is a utility component
return <>{children({ callAction })}</>
}
ActionHandler.propTypes = {
children: PropTypes.func,
actions: PropTypes.objectOf(PropTypes.func),
actionParam: PropTypes.string,
clearAfterExecute: PropTypes.bool,
onAction: PropTypes.func,
loading: PropTypes.bool
}
export default ActionHandler