From ebe4bc8d1bab01e18c8229a4766da7608b97a409 Mon Sep 17 00:00:00 2001 From: Vamsi krishna Date: Tue, 28 Jan 2025 17:48:46 +0530 Subject: [PATCH 1/2] feat: added translation to projects list page --- packages/i18n/src/locales/en/translations.json | 17 ++++++++++++++++- web/ce/components/projects/mobile-header.tsx | 8 ++++++-- .../components/project/applied-filters/root.tsx | 7 +++++-- web/core/components/project/card-list.tsx | 6 +++--- web/core/components/project/filters.tsx | 6 +++++- web/core/components/project/header.tsx | 14 ++++++++++++-- web/core/components/project/root.tsx | 8 ++++++-- web/core/components/project/search-projects.tsx | 6 +++++- 8 files changed, 58 insertions(+), 14 deletions(-) diff --git a/packages/i18n/src/locales/en/translations.json b/packages/i18n/src/locales/en/translations.json index 589a3be796a..13815e0ce84 100644 --- a/packages/i18n/src/locales/en/translations.json +++ b/packages/i18n/src/locales/en/translations.json @@ -593,7 +593,22 @@ }, "project": { - "label": "{count, plural, one {Project} other {Projects}}" + "label": "{count, plural, one {Project} other {Projects}}", + "create": { + "label": "Add Project" + }, + "list": { + "empty_state": { + "title": "No matching projects", + "description": { + "filters": "Remove the filters to see all projects", + "search": "No projects detected with the matching criteria.\nCreate a new project instead" + } + }, + "applied_filters": { + "info": "{filteredProjects} of {totalProjects} projects match the applied filters." + } + } }, "view": { diff --git a/web/ce/components/projects/mobile-header.tsx b/web/ce/components/projects/mobile-header.tsx index 3804721600e..9e51c679991 100644 --- a/web/ce/components/projects/mobile-header.tsx +++ b/web/ce/components/projects/mobile-header.tsx @@ -4,6 +4,8 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons import { ChevronDown, ListFilter } from "lucide-react"; +// i18n +import { useTranslation } from "@plane/i18n"; // types import { TProjectFilters } from "@plane/types"; // hooks @@ -15,6 +17,8 @@ import { calculateTotalFilters } from "@/helpers/filter.helper"; import { useMember, useProjectFilter } from "@/hooks/store"; export const ProjectsListMobileHeader = observer(() => { + // i18n + const { t } = useTranslation(); // router const { workspaceSlug } = useParams(); const { @@ -63,12 +67,12 @@ export const ProjectsListMobileHeader = observer(() => {
} - title="Filters" + title={t("common.filters")} placement="bottom-end" menuButton={
- Filters + {t("common.filters")}
} diff --git a/web/core/components/project/applied-filters/root.tsx b/web/core/components/project/applied-filters/root.tsx index 385ffab7346..2069aa28bf0 100644 --- a/web/core/components/project/applied-filters/root.tsx +++ b/web/core/components/project/applied-filters/root.tsx @@ -1,6 +1,8 @@ "use client"; import { X } from "lucide-react"; +// i18n +import { useTranslation } from "@plane/i18n"; // types import { TProjectAppliedDisplayFilterKeys, TProjectFilters } from "@plane/types"; // ui @@ -30,6 +32,7 @@ const MEMBERS_FILTERS = ["lead", "members"]; const DATE_FILTERS = ["created_at"]; export const ProjectAppliedFiltersList: React.FC = (props) => { + const { t } = useTranslation(); const { appliedFilters, appliedDisplayFilters, @@ -95,7 +98,7 @@ export const ProjectAppliedFiltersList: React.FC = (props) => { {/* Applied display filters */} {appliedDisplayFilters.length > 0 && ( - Projects + {t("projects.label", { count: 2 })} = (props) => { {isEditingAllowed && ( diff --git a/web/core/components/project/card-list.tsx b/web/core/components/project/card-list.tsx index 3d0fa1fae74..65887ef2284 100644 --- a/web/core/components/project/card-list.tsx +++ b/web/core/components/project/card-list.tsx @@ -83,11 +83,11 @@ export const ProjectCardList = observer((props: TProjectCardListProps) => { className="mx-auto h-36 w-36 sm:h-48 sm:w-48" alt="No matching projects" /> -
No matching projects
+
{t("project.list.empty_state.title")}

{searchQuery.trim() === "" - ? "Remove the filters to see all projects" - : "No projects detected with the matching criteria.\nCreate a new project instead"} + ? t("project.list.empty_state.description.filters") + : t("project.list.empty_state.description.search")}

diff --git a/web/core/components/project/filters.tsx b/web/core/components/project/filters.tsx index 2465bbc3693..54ae3a75266 100644 --- a/web/core/components/project/filters.tsx +++ b/web/core/components/project/filters.tsx @@ -2,6 +2,8 @@ import { useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { ListFilter } from "lucide-react"; +// i18n +import { useTranslation } from "@plane/i18n"; // plane types import { TProjectFilters } from "@plane/types"; // plane utils @@ -22,6 +24,8 @@ type Props = { }; const HeaderFilters = observer(({ filterMenuButton, isMobile, classname = "", filterClassname = "" }: Props) => { + // i18n + const { t } = useTranslation(); // router const { workspaceSlug } = useParams(); const { @@ -72,7 +76,7 @@ const HeaderFilters = observer(({ filterMenuButton, isMobile, classname = "", fi
} - title="Filters" + title={t("common.filters")} placement="bottom-end" isFiltersApplied={isFiltersApplied} menuButton={filterMenuButton || null} diff --git a/web/core/components/project/header.tsx b/web/core/components/project/header.tsx index b79f68d68fc..1803b0e7c0f 100644 --- a/web/core/components/project/header.tsx +++ b/web/core/components/project/header.tsx @@ -3,6 +3,8 @@ import { observer } from "mobx-react"; import { usePathname } from "next/navigation"; import { Briefcase } from "lucide-react"; +// i18n +import { useTranslation } from "@plane/i18n"; // ui import { Breadcrumbs, Button, Header } from "@plane/ui"; // components @@ -16,6 +18,8 @@ import HeaderFilters from "./filters"; import { ProjectSearch } from "./search-projects"; export const ProjectsBaseHeader = observer(() => { + // i18n + const { t } = useTranslation(); // store hooks const { toggleCreateProjectModal } = useCommandPalette(); const { setTrackElement } = useEventTracker(); @@ -35,7 +39,12 @@ export const ProjectsBaseHeader = observer(() => { } />} + link={ + } + /> + } /> {isArchived && } />} @@ -54,7 +63,8 @@ export const ProjectsBaseHeader = observer(() => { }} className="items-center gap-1" > - Add Project + {t("project.create.label")} + {t("project.label", { count: 1 })} ) : ( <> diff --git a/web/core/components/project/root.tsx b/web/core/components/project/root.tsx index 0d03155472c..d995cf440f9 100644 --- a/web/core/components/project/root.tsx +++ b/web/core/components/project/root.tsx @@ -2,8 +2,9 @@ import { useCallback, useEffect } from "react"; import { observer } from "mobx-react"; -// types import { useParams, usePathname } from "next/navigation"; +// i18n +import { useTranslation } from "@plane/i18n"; import { TProjectAppliedDisplayFilterKeys, TProjectFilters } from "@plane/types"; // components import { PageHead } from "@/components/core"; @@ -17,6 +18,7 @@ const Root = observer(() => { const { currentWorkspace } = useWorkspace(); const { workspaceSlug } = useParams(); const pathname = usePathname(); + const { t } = useTranslation(); // store const { totalProjectIds, filteredProjectIds } = useProject(); const { @@ -28,7 +30,9 @@ const Root = observer(() => { updateDisplayFilters, } = useProjectFilter(); // derived values - const pageTitle = currentWorkspace?.name ? `${currentWorkspace?.name} - Projects` : undefined; + const pageTitle = currentWorkspace?.name + ? `${currentWorkspace?.name} - ${t("project.label", { count: 2 })}` + : undefined; const isArchived = pathname.includes("/archives"); diff --git a/web/core/components/project/search-projects.tsx b/web/core/components/project/search-projects.tsx index 0434f83470b..8c0dcbc9385 100644 --- a/web/core/components/project/search-projects.tsx +++ b/web/core/components/project/search-projects.tsx @@ -5,12 +5,16 @@ import { observer } from "mobx-react"; import { Search, X } from "lucide-react"; // plane hooks import { useOutsideClickDetector } from "@plane/hooks"; +// i18n +import { useTranslation } from "@plane/i18n"; // helpers import { cn } from "@/helpers/common.helper"; // hooks import { useProjectFilter } from "@/hooks/store"; export const ProjectSearch: FC = observer(() => { + // i18n + const { t } = useTranslation(); // hooks const { searchQuery, updateSearchQuery } = useProjectFilter(); // refs @@ -55,7 +59,7 @@ export const ProjectSearch: FC = observer(() => { updateSearchQuery(e.target.value)} onKeyDown={handleInputKeyDown} From 90cc09a258d038019683a1468bdcdc4c58276d2a Mon Sep 17 00:00:00 2001 From: Vamsi krishna Date: Tue, 28 Jan 2025 18:38:13 +0530 Subject: [PATCH 2/2] chore: restructured translation file --- .../i18n/src/locales/en/translations.json | 26 +++++-------------- web/core/components/project/card-list.tsx | 6 ++--- web/core/components/project/header.tsx | 6 ++--- .../project/project-feature-update.tsx | 5 ++-- web/core/components/project/root.tsx | 2 +- 5 files changed, 17 insertions(+), 28 deletions(-) diff --git a/packages/i18n/src/locales/en/translations.json b/packages/i18n/src/locales/en/translations.json index 13815e0ce84..00eea665972 100644 --- a/packages/i18n/src/locales/en/translations.json +++ b/packages/i18n/src/locales/en/translations.json @@ -592,25 +592,6 @@ } }, - "project": { - "label": "{count, plural, one {Project} other {Projects}}", - "create": { - "label": "Add Project" - }, - "list": { - "empty_state": { - "title": "No matching projects", - "description": { - "filters": "Remove the filters to see all projects", - "search": "No projects detected with the matching criteria.\nCreate a new project instead" - } - }, - "applied_filters": { - "info": "{filteredProjects} of {totalProjects} projects match the applied filters." - } - } - }, - "view": { "label": "{count, plural, one {View} other {Views}}", "create": { @@ -687,6 +668,10 @@ }, "workspace_projects": { + "label": "{count, plural, one {Project} other {Projects}}", + "create": { + "label": "Add Project" + }, "network": { "private": { "title": "Private", @@ -749,6 +734,9 @@ "filter": { "title": "No matching projects", "description": "No projects detected with the matching criteria. \n Create a new project instead." + }, + "search": { + "description": "No projects detected with the matching criteria.\nCreate a new project instead" } } }, diff --git a/web/core/components/project/card-list.tsx b/web/core/components/project/card-list.tsx index 65887ef2284..06509b868fc 100644 --- a/web/core/components/project/card-list.tsx +++ b/web/core/components/project/card-list.tsx @@ -83,11 +83,11 @@ export const ProjectCardList = observer((props: TProjectCardListProps) => { className="mx-auto h-36 w-36 sm:h-48 sm:w-48" alt="No matching projects" /> -
{t("project.list.empty_state.title")}
+
{t("workspace_projects.empty_state.filter.title")}

{searchQuery.trim() === "" - ? t("project.list.empty_state.description.filters") - : t("project.list.empty_state.description.search")} + ? t("workspace_projects.empty_state.filter.description") + : t("workspace_projects.empty_state.search.description")}

diff --git a/web/core/components/project/header.tsx b/web/core/components/project/header.tsx index 1803b0e7c0f..a905576cf7d 100644 --- a/web/core/components/project/header.tsx +++ b/web/core/components/project/header.tsx @@ -41,7 +41,7 @@ export const ProjectsBaseHeader = observer(() => { type="text" link={ } /> } @@ -63,8 +63,8 @@ export const ProjectsBaseHeader = observer(() => { }} className="items-center gap-1" > - {t("project.create.label")} - {t("project.label", { count: 1 })} + {t("workspace_projects.create.label")} + {t("workspace_projects.label", { count: 1 })} ) : ( <> diff --git a/web/core/components/project/project-feature-update.tsx b/web/core/components/project/project-feature-update.tsx index e94b69dd58b..a6e4536446c 100644 --- a/web/core/components/project/project-feature-update.tsx +++ b/web/core/components/project/project-feature-update.tsx @@ -35,8 +35,9 @@ export const ProjectFeatureUpdate: FC = observer((props) => {
- {t("congrats")}! {t("project.label", { count: 1 })} {" "} -

{currentProjectDetails.name}

{t("created").toLowerCase()}. + {t("congrats")}! {t("workspace_projects.label", { count: 1 })}{" "} +

{currentProjectDetails.name}

{" "} + {t("created").toLowerCase()}.