Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 69x 69x 69x 1388x 1388x 1388x 1388x 6854x 6854x 1388x 1388x 1388x 1670x 66x 66x 66x 66x 5x 2x 1x 1x 2x 3x 2x 2x 1x 1388x 6x 6x 6x 66x 9x 6x 6x 6x 1x 6x 6x 6x 2x 1x 5x 5x 1x 1x 4x 6x 3x 2x 2x 1x 1x 9x 1x 66x 1388x | import { useCallback } from 'react'
import { useNavigate } from 'react-router-dom'
import { CrudSurface } from '../surfaces/CrudSurface'
import { useEntityCoordinator } from '../../L2W/coordinatorResolver'
import { useRouteContext } from '../../L2W/routes/routeContextStore'
import type { CrudConfig, CrudFieldConfig, CrudVisualOverrides } from '../../interfaces'
export interface CrudProps {
config: CrudConfig
}
const FALLBACK_CONTEXT = { page: 'collection' } as const
export function Crud({ config }: CrudProps) {
const navigate = useNavigate()
const rawContext = useRouteContext()
const routeContext = rawContext ?? FALLBACK_CONTEXT
const fieldNames = config.fieldSet.map(f => f.field)
const fieldConfigMap = Object.fromEntries(
config.fieldSet.map(fc => [fc.field, fc]),
) as Record<string, CrudFieldConfig>
const { snapshot, updateField, cancel } =
useEntityCoordinator(config.entityPath, fieldNames, routeContext, config.entitySelectSources)
const { cancelTarget, onCancel, successTarget, onSuccess } = config
const titleOverride = config.title ? { labels: { title: config.title } } : undefined
const handleClose = useCallback(() => {
if (cancelTarget) {
if (snapshot.activeCrud?.mode === 'edit' && routeContext.page === 'detail') {
navigate(cancelTarget.replace(':id', routeContext.id), { replace: true })
} else {
navigate(cancelTarget, { replace: true })
}
return
}
if (onCancel) {
onCancel()
return
}
Iif (routeContext.page === 'detail' && routeContext.id) {
navigate('/' + config.entityPath + '/' + routeContext.id, { replace: true })
} else {
navigate(-1)
E }
}, [cancelTarget, onCancel, navigate, snapshot.activeCrud, routeContext, config.entityPath])
const handleSuccess = useCallback(() => {
if (successTarget) {
const result = snapshot.lastMutationData as Record<string, unknown> | null
const resultId = typeof result?.id === 'string' ? result.id : undefined
E const routeId = routeContext.page === 'detail' ? routeContext.id : undefined
const resolvedId =
snapshot.activeCrud?.mode === 'edit' ? (routeId ?? resultId) : resultId
const needsId = successTarget.includes(':id')
if (needsId && !resolvedId) {
if (cancelTarget) {
navigate(cancelTarget, { replace: true })
return
}
navigate('/' + config.entityPath, { replace: true })
return
}
navigate(successTarget.replace(':id', resolvedId ?? ''), { replace: true })
return
}
if (onSuccess) {
onSuccess()
return
}
const mutationResult = snapshot.lastMutationData as Record<string, unknown> | null
const mutationResultId = typeof mutationResult?.id === 'string' ? mutationResult.id : undefined
if (snapshot.activeCrud?.mode === 'add' && mutationResultId) {
navigate('/' + config.entityPath + '/' + mutationResultId, { replace: true })
} else Eif (snapshot.activeCrud?.mode === 'edit' && routeContext.page === 'detail' && routeContext.id) {
navigate('/' + config.entityPath + '/' + routeContext.id, { replace: true })
}
}, [successTarget, cancelTarget, onSuccess, navigate, snapshot.lastMutationData, snapshot.activeCrud, routeContext, config.entityPath])
return (
<CrudSurface
coordinatorSnapshot={snapshot}
routeContext={routeContext}
onClose={handleClose}
onSuccess={handleSuccess}
updateField={updateField}
cancel={cancel}
fieldTypes={config.fieldTypes}
fieldLints={config.fieldLints}
fieldHelp={config.fieldHelp}
fieldConfigs={fieldConfigMap}
entitySelectData={snapshot.entitySelectData}
overrides={titleOverride as CrudVisualOverrides | undefined}
/>
)
}
|