ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
136 lines (124 loc) • 4.91 kB
text/typescript
import { RaRecord, TranslateFunction } from '../../types';
import { MatchingReferencesError } from './types';
import { ControllerRenderProps } from 'react-hook-form';
interface GetStatusForInputParams<RecordType extends RaRecord = RaRecord> {
field: Pick<ControllerRenderProps, 'value'>;
matchingReferences: RecordType[] | MatchingReferencesError;
referenceRecord: RecordType;
translate: TranslateFunction;
}
const isMatchingReferencesError = (
matchingReferences?: any
): matchingReferences is MatchingReferencesError =>
matchingReferences && matchingReferences.error !== undefined;
export const getStatusForInput = <RecordType extends RaRecord = RaRecord>({
field,
matchingReferences,
referenceRecord,
translate = x => x,
}: GetStatusForInputParams<RecordType>) => {
const matchingReferencesError = isMatchingReferencesError(
matchingReferences
)
? translate(matchingReferences.error, {
_: matchingReferences.error,
})
: null;
const selectedReferenceError =
field.value && !referenceRecord
? translate('ra.input.references.single_missing', {
_: 'ra.input.references.single_missing',
})
: null;
return {
waiting:
(field.value && selectedReferenceError && !matchingReferences) ||
(!field.value && !matchingReferences),
error:
(field.value &&
selectedReferenceError &&
matchingReferencesError) ||
(!field.value && matchingReferencesError)
? field.value
? selectedReferenceError
: matchingReferencesError
: null,
warning: selectedReferenceError || matchingReferencesError,
choices: Array.isArray(matchingReferences)
? matchingReferences
: [referenceRecord].filter(choice => choice),
};
};
export const REFERENCES_STATUS_READY = 'REFERENCES_STATUS_READY';
export const REFERENCES_STATUS_INCOMPLETE = 'REFERENCES_STATUS_INCOMPLETE';
export const REFERENCES_STATUS_EMPTY = 'REFERENCES_STATUS_EMPTY';
export const getSelectedReferencesStatus = <RecordType extends RaRecord = any>(
field: Pick<ControllerRenderProps, 'value'>,
referenceRecords: RecordType[]
) =>
!field.value || field.value.length === referenceRecords.length
? REFERENCES_STATUS_READY
: referenceRecords.length > 0
? REFERENCES_STATUS_INCOMPLETE
: REFERENCES_STATUS_EMPTY;
interface GetStatusForArrayInputParams<RecordType extends RaRecord = any> {
field: ControllerRenderProps;
matchingReferences: RecordType[] | MatchingReferencesError;
referenceRecords: RecordType[];
translate: TranslateFunction;
}
export const getStatusForArrayInput = <RecordType extends RaRecord = any>({
field,
matchingReferences,
referenceRecords,
translate = x => x,
}: GetStatusForArrayInputParams<RecordType>) => {
// selectedReferencesDataStatus can be "empty" (no data was found for references from input.value)
// or "incomplete" (Not all of the reference data was found)
// or "ready" (all references data was found or there is no references from input.value)
const selectedReferencesDataStatus = getSelectedReferencesStatus(
field,
referenceRecords
);
const matchingReferencesError = isMatchingReferencesError(
matchingReferences
)
? translate(matchingReferences.error, {
_: matchingReferences.error,
})
: null;
const choices = Array.isArray(matchingReferences)
? referenceRecords.concat(
matchingReferences.filter(
choice =>
referenceRecords.findIndex(c => c.id === choice.id) === -1
)
)
: referenceRecords;
return {
waiting:
(!matchingReferences &&
field.value &&
selectedReferencesDataStatus === REFERENCES_STATUS_EMPTY) ||
(!matchingReferences && !field.value),
error:
matchingReferencesError &&
(!field.value ||
(field.value &&
selectedReferencesDataStatus === REFERENCES_STATUS_EMPTY))
? translate('ra.input.references.all_missing', {
_: 'ra.input.references.all_missing',
})
: null,
warning:
matchingReferencesError ||
(field.value &&
selectedReferencesDataStatus !== REFERENCES_STATUS_READY)
? matchingReferencesError ||
translate('ra.input.references.many_missing', {
_: 'ra.input.references.many_missing',
})
: null,
choices,
};
};