All files / layers / L2R / slots Crud.tsx

73.72% Statements 87/118
55.66% Branches 59/106
86.66% Functions 13/15
80.23% Lines 69/86

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}
    />
  )
}