import * as React from 'react';
import englishMessages from 'ra-language-english';
import frenchMessages from 'ra-language-french';
import polyglotI18nProvider from 'ra-i18n-polyglot';
import fakeRestDataProvider from 'ra-data-fakerest';
import {
AuthProvider,
CoreAdminContext,
EditBase,
EditBaseProps,
DataProvider,
SaveHandlerCallbacks,
useSaveContext,
I18nProvider,
mergeTranslations,
useEditContext,
useLocaleState,
MutationMode,
WithRecord,
IsOffline,
GetOneResult,
TestMemoryRouter,
CoreAdmin,
Resource,
} from '../..';
import { onlineManager, useMutationState } from '@tanstack/react-query';
export default {
title: 'ra-core/controller/EditBase',
};
const defaultI18nProvider = polyglotI18nProvider(
locale =>
locale === 'fr'
? mergeTranslations(frenchMessages, {
resources: {
posts: {
name: 'Article |||| Articles',
},
},
})
: englishMessages,
'en'
);
const customI18nProvider = polyglotI18nProvider(
locale =>
locale === 'fr'
? mergeTranslations(frenchMessages, {
resources: {
posts: {
page: {
edit: "Modifier l'article %{recordRepresentation}",
},
},
},
})
: mergeTranslations(englishMessages, {
resources: {
posts: {
page: {
edit: 'Update article %{recordRepresentation}',
},
},
},
}),
'en'
);
export const DefaultTitle = ({
translations = 'default',
i18nProvider = translations === 'default'
? defaultI18nProvider
: customI18nProvider,
}: {
i18nProvider?: I18nProvider;
translations?: 'default' | 'resource specific';
}) => (
);
DefaultTitle.args = {
translations: 'default',
};
DefaultTitle.argTypes = {
translations: {
options: ['default', 'resource specific'],
control: { type: 'radio' },
},
};
export const NoAuthProvider = ({
dataProvider = defaultDataProvider,
callTimeOptions,
...props
}: {
dataProvider?: DataProvider;
callTimeOptions?: SaveHandlerCallbacks;
} & Partial) => (
);
export const WithAuthProviderNoAccessControl = ({
authProvider = {
login: () => Promise.resolve(),
logout: () => Promise.resolve(),
checkError: () => Promise.resolve(),
checkAuth: () => new Promise(resolve => setTimeout(resolve, 300)),
},
dataProvider = defaultDataProvider,
EditProps,
}: {
authProvider?: AuthProvider;
dataProvider?: DataProvider;
EditProps?: Partial;
}) => (
Authentication loading...}
>
);
export const AccessControl = ({
authProvider = {
login: () => Promise.resolve(),
logout: () => Promise.resolve(),
checkError: () => Promise.resolve(),
checkAuth: () => new Promise(resolve => setTimeout(resolve, 300)),
canAccess: () => new Promise(resolve => setTimeout(resolve, 300, true)),
},
dataProvider = defaultDataProvider,
}: {
authProvider?: AuthProvider;
dataProvider?: DataProvider;
}) => (
Authentication loading...}
>
);
export const WithRenderProps = ({
dataProvider = defaultDataProvider,
mutationMode = 'optimistic',
}: {
dataProvider?: DataProvider;
mutationMode?: MutationMode;
}) => (
{
const handleClick = () => {
if (!save) return;
save({ test: 'test' });
};
return (
<>
{record?.id}
{record?.test}
>
);
}}
/>
);
export const Loading = () => {
let resolveGetOne: (() => void) | null = null;
const dataProvider = {
...defaultDataProvider,
getOne: (resource, params) => {
return new Promise(resolve => {
resolveGetOne = () =>
resolve(defaultDataProvider.getOne(resource, params));
});
},
};
return (
Loading data...}>
);
};
export const FetchError = () => {
let rejectGetOne: (() => void) | null = null;
const dataProvider = {
...defaultDataProvider,
getOne: () => {
return new Promise((_, reject) => {
rejectGetOne = () => reject(new Error('Expected error.'));
});
},
};
return (
Something went wrong.
}>
);
};
export const RedirectOnError = () => {
let rejectGetOne: (() => void) | null = null;
const dataProvider = {
...defaultDataProvider,
getOne: () => {
return new Promise((_, reject) => {
rejectGetOne = () => reject(new Error('Expected error.'));
});
},
};
return (
List view}
show={
<>
>
}
/>
);
};
export const Offline = ({
dataProvider = defaultDataProvider,
isOnline = true,
...props
}: {
dataProvider?: DataProvider;
isOnline?: boolean;
} & Partial) => {
React.useEffect(() => {
onlineManager.setOnline(isOnline);
}, [isOnline]);
return (
You are offline, cannot load data
}
>
);
};
Offline.args = {
isOnline: true,
};
Offline.argTypes = {
isOnline: {
control: { type: 'boolean' },
},
};
const defaultDataProvider = fakeRestDataProvider(
{
posts: [
{ id: 12, test: 'Hello', title: 'Hello' },
{ id: 13, test: 'World', title: 'World' },
],
},
process.env.NODE_ENV !== 'test',
process.env.NODE_ENV !== 'test' ? 300 : 0
);
const defaultProps = {
id: 12,
resource: 'posts',
};
const Child = ({
callTimeOptions,
}: {
callTimeOptions?: SaveHandlerCallbacks;
}) => {
const saveContext = useSaveContext();
const handleClick = () => {
if (!saveContext || !saveContext.save) return;
saveContext.save({ test: 'test' }, callTimeOptions);
};
return (
<>
{record?.test}
} />
>
);
};
const OfflineChild = ({
callTimeOptions,
}: {
callTimeOptions?: SaveHandlerCallbacks;
}) => {
const saveContext = useSaveContext();
const { saving } = useEditContext();
const handleClick = () => {
if (!saveContext || !saveContext.save) return;
saveContext.save({ test: 'test' }, callTimeOptions);
};
return (
<>
Use the story controls to simulate offline mode:
You are offline, the data may be outdated
{record?.test}
} />
>
);
};
const MutationsState = () => {
const pendingMutations = useMutationState({
filters: {
status: 'pending',
},
});
return (
{pendingMutations.length > 0 ? (
You have pending mutations
) : (
No pending mutations
)}
);
};
const Title = () => {
const { defaultTitle } = useEditContext();
const [locale, setLocale] = useLocaleState();
return (
{defaultTitle} ({locale})
);
};