feat: add i18n (translation/localization) (#16877)

* Translation module init

* Add more i18n keys

* fix: fix string wrong

* refactor: use namespace translation file

* chore: add more translation key

* fix: fix some page name error

* refactor: change Trans tag for t function

* chore: fix some key not work

* chore: fix SearchFilterDialog i18n key error

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* chore: fix en i18n file filter missing some keys

* chore: add some i18n keys

* chore: add more i18n keys again

* feat: add search page i18n

* feat: add explore model i18n keys

* Update web/src/components/menu/GeneralSettings.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/components/menu/GeneralSettings.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/components/menu/GeneralSettings.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* feat: add more live i18n keys

* feat: add more search setting i18n keys

* fix: remove some comment

* fix: fix some setting page url error

* Update web/src/views/settings/SearchSettingsView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* fix: add system missing keys

* fix: update password update i18n keys

* chore: remove outdate translation.json file

* fix: fix exploreSettings error

* chore: add object setting i18n keys

* Update web/src/views/recording/RecordingView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/public/locales/en/components/filter.json

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/components/overlay/ExportDialog.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* feat: add more i18n keys

* fix: fix motionDetectionTuner html node

* feat: add more page i18n keys

* fix: cameraStream i18n keys error

* feat: add Player i18n keys

* feat: add more toast i18n keys

* feat: change explore setting name

* feat: add more document title i18n keys

* feat: add more search i18n keys

* fix: fix accessDenied i18n keys error

* chore: add objectType i18n

* chore: add  inputWithTags i18n

* chore: add SearchFilterDialog i18n

* Update web/src/views/settings/ObjectSettingsView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/views/settings/ObjectSettingsView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/views/settings/ObjectSettingsView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/views/settings/ObjectSettingsView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* Update web/src/views/settings/ObjectSettingsView.tsx

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>

* chore: add some missing i18n keys

* chore: remove most import { t } from "i18next";

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
This commit is contained in:
GuoQing Liu
2025-03-16 10:36:20 -05:00
committed by GitHub
co-authored by Josh Hawkins
parent db541abed4
commit d34533981f
150 changed files with 6809 additions and 1926 deletions
+24 -17
View File
@@ -17,8 +17,9 @@ import FilterSwitch from "../filter/FilterSwitch";
import { SearchFilter, SearchSource } from "@/types/search";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
import { useTranslation } from "react-i18next";
type SearchSettingsProps = {
type ExploreSettingsProps = {
className?: string;
columns: number;
defaultView: string;
@@ -27,7 +28,7 @@ type SearchSettingsProps = {
setDefaultView: (view: string) => void;
onUpdateFilter: (filter: SearchFilter) => void;
};
export default function SearchSettings({
export default function ExploreSettings({
className,
columns,
setColumns,
@@ -35,7 +36,8 @@ export default function SearchSettings({
filter,
setDefaultView,
onUpdateFilter,
}: SearchSettingsProps) {
}: ExploreSettingsProps) {
const { t } = useTranslation(["components/filter"]);
const { data: config } = useSWR<FrigateConfig>("config");
const [open, setOpen] = useState(false);
@@ -46,21 +48,20 @@ export default function SearchSettings({
const trigger = (
<Button
className="flex items-center gap-2"
aria-label="Explore Settings"
aria-label={t("explore.settings.title")}
size="sm"
>
<FaCog className="text-secondary-foreground" />
Settings
{t("explore.settings.title")}
</Button>
);
const content = (
<div className={cn(className, "my-3 space-y-5 py-3 md:mt-0 md:py-0")}>
<div className="space-y-4">
<div className="space-y-0.5">
<div className="text-md">Default View</div>
<div className="text-md">{t("explore.settings.defaultView")}</div>
<div className="space-y-1 text-xs text-muted-foreground">
When no filters are selected, display a summary of the most recent
tracked objects per label, or display an unfiltered grid.
{t("explore.settings.defaultView.desc")}
</div>
</div>
<Select
@@ -68,7 +69,9 @@ export default function SearchSettings({
onValueChange={(value) => setDefaultView(value)}
>
<SelectTrigger className="w-full">
{defaultView == "summary" ? "Summary" : "Unfiltered Grid"}
{defaultView == "summary"
? t("explore.settings.defaultView.summary")
: t("explore.settings.defaultView.unfilteredGrid")}
</SelectTrigger>
<SelectContent>
<SelectGroup>
@@ -78,7 +81,9 @@ export default function SearchSettings({
className="cursor-pointer"
value={value}
>
{value == "summary" ? "Summary" : "Unfiltered Grid"}
{value == "summary"
? t("explore.settings.defaultView.summary")
: t("explore.settings.defaultView.unfilteredGrid")}
</SelectItem>
))}
</SelectGroup>
@@ -90,9 +95,9 @@ export default function SearchSettings({
<DropdownMenuSeparator />
<div className="flex w-full flex-col space-y-4">
<div className="space-y-0.5">
<div className="text-md">Grid Columns</div>
<div className="text-md">{t("explore.settings.gridColumns")}</div>
<div className="space-y-1 text-xs text-muted-foreground">
Select the number of columns in the grid view.
{t("explore.settings.gridColumns.desc")}
</div>
</div>
<div className="flex items-center space-x-4">
@@ -148,20 +153,22 @@ export function SearchTypeContent({
searchSources,
setSearchSources,
}: SearchTypeContentProps) {
const { t } = useTranslation(["components/filter"]);
return (
<>
<div className="overflow-x-hidden">
<DropdownMenuSeparator className="mb-3" />
<div className="space-y-0.5">
<div className="text-md">Search Source</div>
<div className="text-md">
{t("explore.settings.searchSource.label")}
</div>
<div className="space-y-1 text-xs text-muted-foreground">
Choose whether to search the thumbnails or descriptions of your
tracked objects.
{t("explore.settings.searchSource.desc")}
</div>
</div>
<div className="mt-2.5 flex flex-col gap-2.5">
<FilterSwitch
label="Thumbnail Image"
label={t("explore.settings.searchSource.options.thumbnailImage")}
isChecked={searchSources?.includes("thumbnail") ?? false}
onCheckedChange={(isChecked) => {
const updatedSources = searchSources ? [...searchSources] : [];
@@ -179,7 +186,7 @@ export function SearchTypeContent({
}}
/>
<FilterSwitch
label="Description"
label={t("explore.settings.searchSource.options.description")}
isChecked={searchSources?.includes("description") ?? false}
onCheckedChange={(isChecked) => {
const updatedSources = searchSources ? [...searchSources] : [];