feat(ledger): use i18next (#5248)

This commit is contained in:
Bartłomiej Głownia 2023-11-17 20:55:10 +01:00 committed by GitHub
parent 66f55855ae
commit 6e8894936e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 113 additions and 64 deletions

View File

@ -0,0 +1,18 @@
{
"Date from": "Date from",
"Date to": "Date to",
"Download": "Download",
"Download all to .csv file": "Download all to .csv file",
"Download has been started": "Download has been started",
"Downloading for {{asset}} from {{startDate}} till {{endDate}}": "Downloading for {{asset}} from {{startDate}} till {{endDate}}",
"Export ledger entries": "Export ledger entries",
"Get file here": "Get file here",
"Please note this can take several minutes.": "Please note this can take several minutes.",
"Select asset": "Select asset",
"Something went wrong": "Something went wrong",
"Still in progress": "Still in progress",
"The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC{{offset}}.": "The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC{{offset}}.",
"Try again later": "Try again later",
"You will be notified here when your file is ready.": "You will be notified here when your file is ready.",
"Your file is ready": "Your file is ready"
}

View File

@ -0,0 +1,14 @@
export const useTranslation = () => ({
t: (label: string, replacements?: Record<string, string>) => {
let translatedLabel = label;
if (typeof replacements === 'object' && replacements !== null) {
Object.keys(replacements).forEach((key) => {
translatedLabel = translatedLabel.replace(
`{{${key}}}`,
replacements[key]
);
});
}
return translatedLabel;
},
});

View File

@ -3,8 +3,8 @@ import type { ReactNode } from 'react';
import { useCallback, useEffect } from 'react'; import { useCallback, useEffect } from 'react';
import type { Toast } from '@vegaprotocol/ui-toolkit'; import type { Toast } from '@vegaprotocol/ui-toolkit';
import { useToasts, Intent } from '@vegaprotocol/ui-toolkit'; import { useToasts, Intent } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { subscribeWithSelector } from 'zustand/middleware'; import { subscribeWithSelector } from 'zustand/middleware';
import { useT } from './use-t';
type DownloadSettings = { type DownloadSettings = {
title: string; title: string;
@ -52,24 +52,31 @@ export const useLedgerDownloadFile = create<LedgerDownloadFileStore>()(
})) }))
); );
const ErrorContent = ({ message }: { message?: string }) => ( const ErrorContent = ({ message }: { message?: string }) => {
<> const t = useT();
<h4 className="mb-1 text-sm">{t('Something went wrong')}</h4> return (
<p>{message || t('Try again later')}</p> <>
</> <h4 className="mb-1 text-sm">{t('Something went wrong')}</h4>
); <p>{message || t('Try again later')}</p>
</>
);
};
const InfoContent = ({ progress = false }) => ( const InfoContent = ({ progress = false }) => {
<> const t = useT();
<p>{t('Please note this can take several minutes.')}</p> return (
<p>{t('You will be notified here when your file is ready.')}</p> <>
<h4 className="my-2"> <p>{t('Please note this can take several minutes.')}</p>
{progress ? t('Still in progress') : t('Download has been started')} <p>{t('You will be notified here when your file is ready.')}</p>
</h4> <h4 className="my-2">
</> {progress ? t('Still in progress') : t('Download has been started')}
); </h4>
</>
);
};
export const useLedgerDownloadManager = () => { export const useLedgerDownloadManager = () => {
const t = useT();
const queue = useLedgerDownloadFile((store) => store.queue); const queue = useLedgerDownloadFile((store) => store.queue);
const updateQueue = useLedgerDownloadFile((store) => store.updateQueue); const updateQueue = useLedgerDownloadFile((store) => store.updateQueue);
const removeItem = useLedgerDownloadFile((store) => store.removeItem); const removeItem = useLedgerDownloadFile((store) => store.removeItem);
@ -88,48 +95,51 @@ export const useLedgerDownloadManager = () => {
[removeToast, removeItem] [removeToast, removeItem]
); );
const createToast = (item: DownloadSettings) => { const createToast = useCallback(
let content: ReactNode; (item: DownloadSettings) => {
switch (true) { let content: ReactNode;
case item.isError: switch (true) {
content = <ErrorContent message={item.errorMessage} />; case item.isError:
break; content = <ErrorContent message={item.errorMessage} />;
case Boolean(item.blob): break;
content = ( case Boolean(item.blob):
content = (
<>
<h4 className="mb-1 text-sm">{t('Your file is ready')}</h4>
<a
onClick={() => onDownloadClose(item.link)}
href={URL.createObjectURL(item.blob as Blob)}
download={item.filename}
className="underline"
>
{t('Get file here')}
</a>
</>
);
break;
default:
content = <InfoContent progress={item.isDelayed} />;
}
const toast: Toast = {
id: item.link,
intent: item.intent || Intent.Primary,
content: (
<> <>
<h4 className="mb-1 text-sm">{t('Your file is ready')}</h4> <h3 className="mb-1 text-md uppercase">{item.title}</h3>
<a {content}
onClick={() => onDownloadClose(item.link)}
href={URL.createObjectURL(item.blob as Blob)}
download={item.filename}
className="underline"
>
{t('Get file here')}
</a>
</> </>
); ),
break; onClose: () => onDownloadClose(item.link),
default: loader: !item.isDownloaded && !item.isError,
content = <InfoContent progress={item.isDelayed} />; };
} if (hasToast(toast.id)) {
const toast: Toast = { updateToast(toast.id, toast);
id: item.link, } else {
intent: item.intent || Intent.Primary, setToast(toast);
content: ( }
<> },
<h3 className="mb-1 text-md uppercase">{item.title}</h3> [hasToast, setToast, onDownloadClose, updateToast, t]
{content} );
</>
),
onClose: () => onDownloadClose(item.link),
loader: !item.isDownloaded && !item.isError,
};
if (hasToast(toast.id)) {
updateToast(toast.id, toast);
} else {
setToast(toast);
}
};
useEffect(() => { useEffect(() => {
queue.forEach((item) => { queue.forEach((item) => {

View File

@ -14,9 +14,9 @@ import {
toNanoSeconds, toNanoSeconds,
VEGA_ID_REGEX, VEGA_ID_REGEX,
} from '@vegaprotocol/utils'; } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { localLoggerFactory } from '@vegaprotocol/logger'; import { localLoggerFactory } from '@vegaprotocol/logger';
import { useLedgerDownloadFile } from './ledger-download-store'; import { useLedgerDownloadFile } from './ledger-download-store';
import { useT } from './use-t';
const DEFAULT_EXPORT_FILE_NAME = 'ledger_entries.csv'; const DEFAULT_EXPORT_FILE_NAME = 'ledger_entries.csv';
@ -70,6 +70,7 @@ interface Props {
} }
export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => { export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => {
const t = useT();
const now = useRef(new Date()); const now = useRef(new Date());
const [dateFrom, setDateFrom] = useState(() => { const [dateFrom, setDateFrom] = useState(() => {
return formatForInput(subDays(now.current, 7)); return formatForInput(subDays(now.current, 7));
@ -116,11 +117,14 @@ export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => {
const startDownload = async (event: React.FormEvent<HTMLFormElement>) => { const startDownload = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault(); event.preventDefault();
const title = t('Downloading for %s from %s till %s', [ const title = t(
assets[assetId], 'Downloading for {{asset}} from {{startDate}} till {{endDate}}',
format(new Date(dateFrom), 'dd MMMM yyyy HH:mm'), {
format(new Date(dateTo || Date.now()), 'dd MMMM yyyy HH:mm'), asset: assets[assetId],
]); startDate: format(new Date(dateFrom), 'dd MMMM yyyy HH:mm'),
endDate: format(new Date(dateTo || Date.now()), 'dd MMMM yyyy HH:mm'),
}
);
const downloadStoreItem = { const downloadStoreItem = {
title, title,
@ -225,8 +229,8 @@ export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => {
{offset && ( {offset && (
<p className="text-xs text-neutral-400 mt-1"> <p className="text-xs text-neutral-400 mt-1">
{t( {t(
'The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC%s.', 'The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC{{offset}}.',
[toHoursAndMinutes(offset)] { offset: toHoursAndMinutes(offset) }
)} )}
</p> </p>
)} )}

View File

@ -0,0 +1,3 @@
import { useTranslation } from 'react-i18next';
export const useT = () => useTranslation('ledger').t;