import { ComponentType, ReactElement, ReactNode } from 'react'; import { FieldPath } from 'react-hook-form'; import { WithPermissionsChildrenParams } from './auth/WithPermissions'; import { AuthActionType } from './auth/types'; /** * data types */ export type Identifier = string | number; export interface RaRecord extends Record { id: IdentifierType; } export interface SortPayload { field: string; order: 'ASC' | 'DESC'; } export interface FilterPayload { [k: string]: any; } export interface PaginationPayload { page: number; perPage: number; } export type ValidUntil = Date; /** * i18nProvider types */ export const I18N_TRANSLATE = 'I18N_TRANSLATE'; export const I18N_CHANGE_LOCALE = 'I18N_CHANGE_LOCALE'; export type TranslateFunction = (key: string, options?: any) => string; export type Locale = { locale: string; name: string; }; export type I18nProvider = { translate: TranslateFunction; changeLocale: (locale: string, options?: any) => Promise; getLocale: () => string; getLocales?: () => Locale[]; [key: string]: any; }; export interface UserIdentity { id: Identifier; fullName?: string; avatar?: string; [key: string]: any; } /** * authProvider types */ export type AuthProvider = { login: ( params: any ) => Promise<{ redirectTo?: string | boolean } | void | any>; logout: (params: any) => Promise; checkAuth: (params: any & QueryFunctionContext) => Promise; checkError: (error: any) => Promise; getIdentity?: (params?: QueryFunctionContext) => Promise; getPermissions?: (params: any & QueryFunctionContext) => Promise; handleCallback?: ( params?: QueryFunctionContext ) => Promise; canAccess?: = Record>( params: QueryFunctionContext & { action: string; resource: string; record?: RecordType; } ) => Promise; [key: string]: any; supportAbortSignal?: boolean; }; export type AuthRedirectResult = { redirectTo?: string | false; logoutOnFailure?: boolean; }; export type LegacyAuthProvider = ( type: AuthActionType, params?: any ) => Promise; /** * dataProvider types */ export type DataProvider = { getList: ( resource: ResourceType, params: GetListParams & QueryFunctionContext ) => Promise>; getOne: ( resource: ResourceType, params: GetOneParams & QueryFunctionContext ) => Promise>; getMany: ( resource: ResourceType, params: GetManyParams & QueryFunctionContext ) => Promise>; getManyReference: ( resource: ResourceType, params: GetManyReferenceParams & QueryFunctionContext ) => Promise>; update: ( resource: ResourceType, params: UpdateParams ) => Promise>; updateMany: ( resource: ResourceType, params: UpdateManyParams ) => Promise>; create: < RecordType extends Omit = any, ResultRecordType extends RaRecord = RecordType & { id: Identifier }, >( resource: ResourceType, params: CreateParams ) => Promise>; delete: ( resource: ResourceType, params: DeleteParams ) => Promise>; deleteMany: ( resource: ResourceType, params: DeleteManyParams ) => Promise>; [key: string]: any; supportAbortSignal?: boolean; }; export interface QueryFunctionContext { signal?: AbortSignal; } export interface GetListParams { pagination?: PaginationPayload; sort?: SortPayload; filter?: any; meta?: any; signal?: AbortSignal; } export interface GetListResult { data: RecordType[]; total?: number; pageInfo?: { hasNextPage?: boolean; hasPreviousPage?: boolean; }; meta?: any; } export interface GetInfiniteListResult extends GetListResult { pageParam: number; } export interface GetOneParams { id: RecordType['id']; meta?: any; signal?: AbortSignal; } export interface GetOneResult { data: RecordType; meta?: any; } export interface GetManyParams { ids: RecordType['id'][]; meta?: any; signal?: AbortSignal; } export interface GetManyResult { data: RecordType[]; meta?: any; } export interface GetManyReferenceParams { target: string; id: Identifier; pagination: PaginationPayload; sort: SortPayload; filter: any; meta?: any; signal?: AbortSignal; } export interface GetManyReferenceResult { data: RecordType[]; total?: number; pageInfo?: { hasNextPage?: boolean; hasPreviousPage?: boolean; }; meta?: any; } export interface UpdateParams { id: RecordType['id']; data: Partial; previousData: RecordType; meta?: any; } export interface UpdateResult { data: RecordType; meta?: any; } export interface UpdateManyParams { ids: Identifier[]; data: Partial; meta?: any; } export interface UpdateManyResult { data?: RecordType['id'][]; meta?: any; } export interface CreateParams { data: Partial; meta?: any; } export interface CreateResult { data: RecordType; meta?: any; } export interface DeleteParams { id: RecordType['id']; previousData?: RecordType; meta?: any; } export interface DeleteResult { data: RecordType; meta?: any; } export interface DeleteManyParams { ids: RecordType['id'][]; meta?: any; } export interface DeleteManyResult { data?: RecordType['id'][]; meta?: any; } export type DataProviderResult = | CreateResult | DeleteResult | DeleteManyResult | GetListResult | GetManyResult | GetManyReferenceResult | GetOneResult | UpdateResult | UpdateManyResult; export type MutationMode = 'pessimistic' | 'optimistic' | 'undoable'; export type OnSuccess = ( response?: any, variables?: any, onMutateResult?: any, context?: any ) => void; export type OnError = ( error?: any, variables?: any, onMutateResult?: any, context?: any ) => void; export type TransformData = ( data: any, options?: { previousData: any } ) => any | Promise; export interface UseDataProviderOptions { action?: string; fetch?: string; meta?: object; mutationMode?: MutationMode; onSuccess?: OnSuccess; onError?: OnError; enabled?: boolean; } export type LegacyDataProvider = ( type: string, resource: string, params: any ) => Promise; export type RecordToStringFunction = (record: any) => string; export interface ResourceDefinition { readonly name: string; readonly options?: OptionsType; readonly hasList?: boolean; readonly hasEdit?: boolean; readonly hasShow?: boolean; readonly hasCreate?: boolean; readonly icon?: any; readonly recordRepresentation?: React.ReactNode | RecordToStringFunction; } /** * Misc types */ export type Dispatch = T extends (...args: infer A) => any ? (...args: A) => void : never; export type ResourceElement = ReactElement; export type RenderResourcesFunction = (permissions: any) => | ReactNode // (permissions) => <> | Promise // (permissions) => fetch().then(() => <>) | ResourceElement[] // // (permissions) => [, , ] | Promise; // (permissions) => fetch().then(() => [, , ]) export type AdminChildren = | RenderResourcesFunction | Iterable | ReactNode; export type TitleComponent = string | ReactElement; export type CatchAllComponent = ComponentType<{ title?: TitleComponent }>; export type LoginComponent = ComponentType<{}> | ReactElement; export type DashboardComponent = ComponentType; export interface CoreLayoutProps { children: ReactNode; } export type LayoutComponent = ComponentType; export type LoadingComponent = ComponentType<{ loadingPrimary?: string; loadingSecondary?: string; }>; export interface ResourceComponentInjectedProps { permissions?: any; resource?: string; options?: any; hasList?: boolean; hasEdit?: boolean; hasShow?: boolean; hasCreate?: boolean; } export interface ResourceOptions { label?: string; [key: string]: any; } export interface ResourceProps { intent?: 'route' | 'registration'; name: string; list?: ComponentType | ReactElement; create?: ComponentType | ReactElement; edit?: ComponentType | ReactElement; show?: ComponentType | ReactElement; hasCreate?: boolean; hasEdit?: boolean; hasShow?: boolean; icon?: ComponentType; recordRepresentation?: React.ReactNode | RecordToStringFunction; options?: ResourceOptions; children?: ReactNode; } export type Exporter = ( data: RecordType[], fetchRelatedRecords: FetchRelatedRecords, dataProvider: DataProvider, resource?: string ) => void | Promise; export type FetchRelatedRecords = ( data: any[], field: string, resource: string ) => Promise<{ [key: Identifier]: RecordType }>; export type SetOnSave = ( onSave?: (values: object, redirect: any) => void ) => void; export type FormFunctions = { setOnSave?: SetOnSave; }; // Type for a string that accept one of the known values but also any other string // Useful for IDE autocompletion without preventing custom values export type HintedString = AnyString | KnownValues; // Re-export react-hook-form implementation of FieldPath that returns all possible paths of an object // This will allow us to either include the FieldPath implementation from react-hook-form or replace it with our own // should we move away from react-hook-form // type Post = { title: string; author: { name: string; }; tags: { id: string; name: string} }; // => Valid paths are "title" | "author" | "author.name" | "tags.id" | "tags.name" export type RecordValues = Record; export type RecordPath = FieldPath; // Returns the union of all possible paths of a type if it is provided, otherwise returns a string // Useful for props such as "source" in react-admin components export type ExtractRecordPaths = // Trick that allows to check whether T was provided [T] extends [never] ? string : RecordPath; export type AnyString = string & {};