Support I18n (#243)

* feat: support i18n

* feat: wip support i18n

* feat: complete space translation

* feat: complete page translation

* feat: update space translation

* feat: update workspace translation

* feat: update group translation

* feat: update workspace translation

* feat: update page translation

* feat: update user translation

* chore: update pnpm-lock

* feat: add query translation

* refactor: merge to single file

* chore: remove necessary code

* feat: save language to BE

* fix: only load current language

* feat: save language to locale column

* fix: cleanups

* add language menu to preferences page

* new translations

* translate editor

* Translate editor placeholders

* translate space selection component

---------

Co-authored-by: Philip Okugbe <phil@docmost.com>
Co-authored-by: Philip Okugbe <16838612+Philipinho@users.noreply.github.com>
This commit is contained in:
lleohao
2025-01-04 21:17:17 +08:00
committed by GitHub
parent 290b7d9d94
commit 670ee64179
119 changed files with 1672 additions and 649 deletions

View File

@ -16,12 +16,14 @@ import {
} from "@/features/editor/atoms/editor-atoms";
import { modals } from "@mantine/modals";
import { notifications } from "@mantine/notifications";
import { useTranslation } from "react-i18next";
interface Props {
pageId: string;
}
function HistoryList({ pageId }: Props) {
const { t } = useTranslation();
const [activeHistoryId, setActiveHistoryId] = useAtom(activeHistoryIdAtom);
const {
data: pageHistoryList,
@ -36,14 +38,15 @@ function HistoryList({ pageId }: Props) {
const confirmModal = () =>
modals.openConfirmModal({
title: "Please confirm your action",
title: t("Please confirm your action"),
children: (
<Text size="sm">
Are you sure you want to restore this version? Any changes not
versioned will be lost.
{t(
"Are you sure you want to restore this version? Any changes not versioned will be lost.",
)}
</Text>
),
labels: { confirm: "Confirm", cancel: "Cancel" },
labels: { confirm: t("Confirm"), cancel: t("Cancel") },
onConfirm: handleRestore,
});
@ -60,7 +63,7 @@ function HistoryList({ pageId }: Props) {
.setContent(activeHistoryData.content)
.run();
setHistoryModalOpen(false);
notifications.show({ message: "Successfully restored" });
notifications.show({ message: t("Successfully restored") });
}
}, [activeHistoryData]);
@ -79,11 +82,11 @@ function HistoryList({ pageId }: Props) {
}
if (isError) {
return <div>Error loading page history.</div>;
return <div>{t("Error loading page history.")}</div>;
}
if (!pageHistoryList || pageHistoryList.items.length === 0) {
return <>No page history saved yet.</>;
return <>{t("No page history saved yet.")}</>;
}
return (
@ -104,14 +107,14 @@ function HistoryList({ pageId }: Props) {
<Group p="xs" wrap="nowrap">
<Button size="compact-md" onClick={confirmModal}>
Restore
{t("Restore")}
</Button>
<Button
variant="default"
size="compact-md"
onClick={() => setHistoryModalOpen(false)}
>
Cancel
{t("Cancel")}
</Button>
</Group>
</div>

View File

@ -2,11 +2,13 @@ import { Modal, Text } from "@mantine/core";
import { useAtom } from "jotai";
import { historyAtoms } from "@/features/page-history/atoms/history-atoms";
import HistoryModalBody from "@/features/page-history/components/history-modal-body";
import { useTranslation } from "react-i18next";
interface Props {
pageId: string;
}
export default function HistoryModal({ pageId }: Props) {
const { t } = useTranslation();
const [isModalOpen, setModalOpen] = useAtom(historyAtoms);
return (
@ -21,7 +23,7 @@ export default function HistoryModal({ pageId }: Props) {
<Modal.Header>
<Modal.Title>
<Text size="md" fw={500}>
Page history
{t("Page history")}
</Text>
</Modal.Title>
<Modal.CloseButton />

View File

@ -1,11 +1,13 @@
import { usePageHistoryQuery } from '@/features/page-history/queries/page-history-query';
import { HistoryEditor } from '@/features/page-history/components/history-editor';
import { usePageHistoryQuery } from "@/features/page-history/queries/page-history-query";
import { HistoryEditor } from "@/features/page-history/components/history-editor";
import { useTranslation } from "react-i18next";
interface HistoryProps {
historyId: string;
}
function HistoryView({ historyId }: HistoryProps) {
const { t } = useTranslation();
const { data, isLoading, isError } = usePageHistoryQuery(historyId);
if (isLoading) {
@ -13,13 +15,15 @@ function HistoryView({ historyId }: HistoryProps) {
}
if (isError || !data) {
return <div>Error fetching page data.</div>;
return <div>{t("Error fetching page data.")}</div>;
}
return (data &&
<div>
<HistoryEditor content={data.content} title={data.title} />
</div>
return (
data && (
<div>
<HistoryEditor content={data.content} title={data.title} />
</div>
)
);
}