mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-12 10:53:51 +00:00
133 lines
4.2 KiB
TypeScript
133 lines
4.2 KiB
TypeScript
import { TranslationObject, langEn } from 'ontime-types';
|
|
import { useEffect, useMemo } from 'react';
|
|
import { useForm } from 'react-hook-form';
|
|
|
|
import { maybeAxiosError } from '../../../../../common/api/utils';
|
|
import Button from '../../../../../common/components/buttons/Button';
|
|
import Info from '../../../../../common/components/info/Info';
|
|
import Input from '../../../../../common/components/input/input/Input';
|
|
import Modal from '../../../../../common/components/modal/Modal';
|
|
import { useTranslation } from '../../../../../translation/TranslationProvider';
|
|
import * as Panel from '../../../panel-utils/PanelUtils';
|
|
|
|
import style from './CustomTranslationModal.module.scss';
|
|
|
|
interface CustomTranslationModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export default function CustomTranslationModal({ isOpen, onClose }: CustomTranslationModalProps) {
|
|
const { userTranslation, postUserTranslation } = useTranslation();
|
|
const customTranslationFormValues = useMemo(() => toFormValues(userTranslation), [userTranslation]);
|
|
|
|
const {
|
|
handleSubmit,
|
|
register,
|
|
reset,
|
|
formState: { isSubmitting, isDirty, errors, isValid },
|
|
setError,
|
|
} = useForm({
|
|
defaultValues: customTranslationFormValues,
|
|
mode: 'onChange',
|
|
});
|
|
|
|
// keep data up to date
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
reset(customTranslationFormValues);
|
|
}
|
|
}, [customTranslationFormValues, isOpen, reset]);
|
|
|
|
const onSubmit = async (formData: Record<string, string>) => {
|
|
try {
|
|
const translationData: Record<string, string> = {};
|
|
Object.keys(formData).forEach((key) => {
|
|
translationData[toApiKey(key)] = formData[key];
|
|
});
|
|
|
|
await postUserTranslation(translationData as TranslationObject);
|
|
reset(formData);
|
|
} catch (error) {
|
|
setError('root', { message: maybeAxiosError(error) });
|
|
}
|
|
};
|
|
|
|
const resetToEnglish = () => {
|
|
reset(toFormValues(langEn), { keepDefaultValues: true });
|
|
};
|
|
|
|
return (
|
|
<Modal
|
|
title='Edit custom translations'
|
|
isOpen={isOpen}
|
|
onClose={onClose}
|
|
showCloseButton
|
|
showBackdrop
|
|
bodyElements={
|
|
<Panel.Section as='form' onSubmit={handleSubmit(onSubmit)} id='custom-translations-form'>
|
|
<Info>
|
|
Provide custom translations for the public views of Ontime. <br />
|
|
You will need to activate this in the settings by selecting "Custom" as the views language.
|
|
</Info>
|
|
<Panel.ListGroup>
|
|
{Object.entries(langEn).map(([key, value]) => (
|
|
<Panel.ListItem key={key}>
|
|
<Panel.Field title={value} description='' error={errors[toFormKey(key)]?.message} />
|
|
<Input
|
|
maxLength={150}
|
|
{...register(toFormKey(key), {
|
|
required: 'This field is required',
|
|
})}
|
|
placeholder={value}
|
|
/>
|
|
</Panel.ListItem>
|
|
))}
|
|
</Panel.ListGroup>
|
|
</Panel.Section>
|
|
}
|
|
footerElements={
|
|
<div className={style.footer}>
|
|
{errors?.root && <Panel.Error>{errors.root.message}</Panel.Error>}
|
|
<Panel.InlineElements align='apart'>
|
|
<Button variant='ghosted' size='large' onClick={resetToEnglish} disabled={isSubmitting}>
|
|
Reset to English
|
|
</Button>
|
|
<Panel.InlineElements>
|
|
<Button size='large' onClick={onClose}>
|
|
Cancel
|
|
</Button>
|
|
<Button
|
|
variant='primary'
|
|
size='large'
|
|
type='submit'
|
|
form='custom-translations-form'
|
|
disabled={isSubmitting || !isDirty || !isValid}
|
|
loading={isSubmitting}
|
|
>
|
|
Save changes
|
|
</Button>
|
|
</Panel.InlineElements>
|
|
</Panel.InlineElements>
|
|
</div>
|
|
}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function toFormValues(translation: Partial<TranslationObject>) {
|
|
const values: Record<string, string> = {};
|
|
Object.keys(langEn).forEach((key) => {
|
|
values[toFormKey(key)] = translation[key as keyof TranslationObject] || '';
|
|
});
|
|
return values;
|
|
}
|
|
|
|
function toFormKey(key: string) {
|
|
return key.replace('.', '_');
|
|
}
|
|
|
|
function toApiKey(key: string) {
|
|
return key.replace('_', '.');
|
|
}
|