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 | 57x 57x 57x 1026x 1026x 1026x 1026x 3972x 3972x 1026x 1026x 1026x 1100x 42x 42x 42x 42x 5x 2x 1x 1x 2x 3x 2x 2x 1x 1026x 6x 6x 6x 42x 7x 6x 6x 4x 1x 4x 4x 4x 2x 1x 5x 5x 1x 1x 2x 4x 3x 2x 2x 1x 1x 7x 1x 42x 1026x | 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}
fieldConfigs={fieldConfigMap}
entitySelectData={snapshot.entitySelectData}
overrides={titleOverride as CrudVisualOverrides | undefined}
/>
)
}
|