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 | 216x 216x 216x 3944x 3944x 3944x 3944x 18370x 18370x 3944x 3944x 3944x 4226x 66x 66x 66x 66x 5x 2x 1x 1x 2x 3x 2x 2x 1x 3944x 18x 18x 18x 66x 18x 18x 18x 6x 3x 6x 6x 6x 2x 1x 15x 15x 1x 1x 4x 6x 3x 2x 2x 1x 1x 9x 1x 66x 3944x | 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}
/>
)
}
|