diff --git a/packages/i18n/src/locales/en/translations.json b/packages/i18n/src/locales/en/translations.json index bf1da0356b9..708ec429b46 100644 --- a/packages/i18n/src/locales/en/translations.json +++ b/packages/i18n/src/locales/en/translations.json @@ -333,6 +333,14 @@ "show_all": "Show all", "show_less": "Show less", "no_data_yet": "No Data yet", + "Syncing": "Syncing", + "add_work_item": "Add work item", + "advanced_description_placeholder": "Press '/' for commands...", + "create_work_item": "Create work item", + "attachments": "Attachments", + "declining": "Declining", + "declined": "Declined", + "decline": "Decline", "project_view": { "sort_by": { @@ -516,9 +524,12 @@ }, "comments": "Comments", "updates": "Updates", - "clear_all": "Clear all" + "clear_all": "Clear all", + "link_copied": "Link copied", + "copied_to_clipboard": "Work item link copied to clipboard", + "is_copied_to_clipboard": "Work item is copied to clipboard" }, - + "form": { "title": { "required": "Title is required", @@ -638,6 +649,33 @@ "description": "Duplicate" } }, + "modals": { + "decline": { + "title": "Decline work item", + "content": "Are you sure you want to decline work item {value}?" + }, + "delete": { + "title": "Delete work item", + "content": "Are you sure you want to delete work item {value}?", + "success": "Work item deleted successfully" + } + }, + "errors": { + "snooze_permission": "Only project admins can snooze/Un-snooze work items", + "accept_permission": "Only project admins can accept work items", + "decline_permission": "Only project admins can deny work items" + }, + "actions": { + "accept": "Accept", + "decline": "Decline", + "snooze": "Snooze", + "unsnooze": "Un snooze", + "copy": "Copy work item link", + "delete": "Delete", + "open": "Open work item", + "mark_as_duplicate": "Mark as duplicate", + "move": "Move {value} to project work items" + }, "source": { "in-app": "in-app" }, @@ -645,6 +683,32 @@ "created_at": "Created at", "updated_at": "Updated at", "id": "ID" + }, + "label": "Intake", + "page_label": "{workspace} - Intake", + "modal": { + "title": "Create intake work item" + }, + "tabs": { + "open": "Open", + "closed": "Closed" + }, + "empty_state": { + "sidebar_open_tab": { + "title": "No open issues", + "description": "Find open issues here. Create new issue." + }, + "sidebar_closed_tab": { + "title": "No closed issues", + "description": "All the issues whether accepted or declined can be found here." + }, + "sidebar_filter": { + "title": "No matching issues", + "description": "No issue matches filter applied in intake. Create a new issue." + }, + "detail": { + "title": "Select an issue to view its details." + } } }, @@ -1191,30 +1255,7 @@ } } }, - - "inbox": { - "label": "Inbox", - "empty_state": { - "sidebar_open_tab": { - "title": "No open issues", - "description": "Find open issues here. Create new issue." - }, - "sidebar_closed_tab": { - "title": "No closed issues", - "description": "All the issues whether accepted or declined can be found here." - }, - "sidebar_filter": { - "title": "No matching issues", - "description": "No issue matches filter applied in intake. Create a new issue." - }, - "detail": { - "title": "Select an issue to view its details." - } - } - }, - "workspace_draft_issues": { - "draft_an_issue": "Draft an issue", "draft_an_issue": "Draft an issue", "empty_state": { "title": "Half-written issues, and soon, comments will show up here.", diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/inbox/page.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/inbox/page.tsx index 92d01aa25a9..4b1d5657344 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/inbox/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/inbox/page.tsx @@ -51,7 +51,13 @@ const ProjectInboxPage = observer(() => { ); // derived values - const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Intake` : "Plane - Intake"; + const pageTitle = currentProjectDetails?.name + ? t("inbox_issue.page_label", { + workspace: currentProjectDetails?.name, + }) + : t("inbox_issue.page_label", { + workspace: "Plane", + }); const currentNavigationTab = navigationTab ? navigationTab === "open" diff --git a/web/ce/components/projects/settings/intake/header.tsx b/web/ce/components/projects/settings/intake/header.tsx index 9ed39733bb5..8704ebb68b6 100644 --- a/web/ce/components/projects/settings/intake/header.tsx +++ b/web/ce/components/projects/settings/intake/header.tsx @@ -5,6 +5,7 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { RefreshCcw } from "lucide-react"; // ui +import { useTranslation } from "@plane/i18n"; import { Breadcrumbs, Button, Intake, Header } from "@plane/ui"; // components import { BreadcrumbLink } from "@/components/common"; @@ -22,6 +23,7 @@ export const ProjectInboxHeader: FC = observer(() => { const { workspaceSlug, projectId } = useParams(); // store hooks const { allowPermissions } = useUserPermissions(); + const { t } = useTranslation(); const { currentProjectDetails, loader: currentProjectDetailsLoader } = useProject(); const { loader } = useProjectInbox(); @@ -41,14 +43,14 @@ export const ProjectInboxHeader: FC = observer(() => { } />} + link={} />} /> {loader === "pagination-loading" && (
-

Syncing...

+

{t("syncing")}...

)} @@ -64,7 +66,7 @@ export const ProjectInboxHeader: FC = observer(() => { /> ) : ( diff --git a/web/core/components/inbox/content/inbox-issue-header.tsx b/web/core/components/inbox/content/inbox-issue-header.tsx index cb0dbcfc5f1..67b1f7f4d64 100644 --- a/web/core/components/inbox/content/inbox-issue-header.tsx +++ b/web/core/components/inbox/content/inbox-issue-header.tsx @@ -15,6 +15,7 @@ import { MoveRight, Copy, } from "lucide-react"; +import { useTranslation } from "@plane/i18n"; import { TNameDescriptionLoader } from "@plane/types"; import { Button, ControlLink, CustomMenu, Row, TOAST_TYPE, setToast } from "@plane/ui"; // components @@ -71,6 +72,7 @@ export const InboxIssueActionsHeader: FC = observer((p const { data: currentUser } = useUser(); const { allowPermissions } = useUserPermissions(); const { currentProjectDetails } = useProject(); + const { t } = useTranslation(); const router = useAppRouter(); const { getProjectById } = useProject(); @@ -172,8 +174,8 @@ export const InboxIssueActionsHeader: FC = observer((p copyUrlToClipboard(path).then(() => setToast({ type: TOAST_TYPE.SUCCESS, - title: "Link copied", - message: "Issue link copied to clipboard", + title: t("common.link_copied"), + message: t("common.copied_to_clipboard"), }) ); @@ -243,10 +245,12 @@ export const InboxIssueActionsHeader: FC = observer((p beforeFormSubmit={handleInboxIssueAccept} withDraftIssueWrapper={false} fetchIssueDetails={false} - modalTitle={`Move ${currentProjectDetails?.identifier}-${issue?.sequence_id} to project issues`} + modalTitle={t("inbox_issue.actions.move", { + value: `${currentProjectDetails?.identifier}-${issue?.sequence_id}`, + })} primaryButtonText={{ - default: "Add to project", - loading: "Adding", + default: t("add_to_project"), + loading: t("adding"), }} /> = observer((p handleActionWithPermission( isProjectAdmin, () => setAcceptIssueModal(true), - "Only project admins can accept issues" + t("inbox_issue.errors.accept_permission") ) } > - Accept + {t("inbox_issue.actions.accept")} )} @@ -339,11 +343,11 @@ export const InboxIssueActionsHeader: FC = observer((p handleActionWithPermission( isProjectAdmin, () => setDeclineIssueModal(true), - "Only project admins can deny issues" + t("inbox_issue.errors.decline_permission") ) } > - Decline + {t("inbox_issue.actions.decline")} )} @@ -356,7 +360,7 @@ export const InboxIssueActionsHeader: FC = observer((p size="sm" onClick={() => handleCopyIssueLink(issueLink)} > - Copy issue link + {t("inbox_issue.actions.copy")} = observer((p target="_self" > @@ -380,15 +384,15 @@ export const InboxIssueActionsHeader: FC = observer((p handleActionWithPermission( isProjectAdmin, handleIssueSnoozeAction, - "Only project admins can snooze/Un-snooze issues" + t("inbox_issue.errors.snooze_permission") ) } >
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0 - ? "Un-snooze" - : "Snooze"} + ? t("inbox_issue.actions.unsnooze") + : t("inbox_issue.actions.snooze")}
)} @@ -404,21 +408,21 @@ export const InboxIssueActionsHeader: FC = observer((p >
- Mark as duplicate + {t("inbox_issue.actions.mark_as_duplicate")}
)} handleCopyIssueLink(intakeIssueLink)}>
- Copy issue link + {t("inbox_issue.actions.copy")}
{canDelete && ( setDeleteIssueModal(true)}>
- Delete + {t("inbox_issue.actions.delete")}
)} diff --git a/web/core/components/inbox/modals/create-modal/create-root.tsx b/web/core/components/inbox/modals/create-modal/create-root.tsx index d966a93fbb2..0d404d4b20b 100644 --- a/web/core/components/inbox/modals/create-modal/create-root.tsx +++ b/web/core/components/inbox/modals/create-modal/create-root.tsx @@ -7,6 +7,7 @@ import { usePathname } from "next/navigation"; import { ETabIndices, ISSUE_CREATED } from "@plane/constants"; import { EditorRefApi } from "@plane/editor"; // types +import { useTranslation } from "@plane/i18n"; import { TIssue } from "@plane/types"; import { Button, ToggleSwitch, TOAST_TYPE, setToast } from "@plane/ui"; // components @@ -66,6 +67,7 @@ export const InboxIssueCreateRoot: FC = observer((props) const workspaceId = getWorkspaceBySlug(workspaceSlug)?.id; const { isMobile } = usePlatformOS(); const { getProjectById } = useProject(); + const { t } = useTranslation(); // states const [createMore, setCreateMore] = useState(false); const [formSubmitting, setFormSubmitting] = useState(false); @@ -212,7 +214,7 @@ export const InboxIssueCreateRoot: FC = observer((props)
-

Create intake issue

+

{t("inbox_issue.modal.title")}

{duplicateIssues?.length > 0 && ( = observer((props) tabIndex={getIndex("create_more")} > {}} size="sm" /> - Create more + {t("create_more")}
diff --git a/web/core/components/inbox/modals/create-modal/issue-title.tsx b/web/core/components/inbox/modals/create-modal/issue-title.tsx index 8ab8620fd32..cd645fb704a 100644 --- a/web/core/components/inbox/modals/create-modal/issue-title.tsx +++ b/web/core/components/inbox/modals/create-modal/issue-title.tsx @@ -4,6 +4,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; // plane imports import { ETabIndices } from "@plane/constants"; +import { useTranslation } from "@plane/i18n"; import { TIssue } from "@plane/types"; import { Input } from "@plane/ui"; // helpers @@ -23,6 +24,7 @@ export const InboxIssueTitle: FC = observer((props) => { const { isMobile } = usePlatformOS(); const { getIndex } = getTabIndex(ETabIndices.INTAKE_ISSUE_FORM, isMobile); + const { t } = useTranslation(); return (
= observer((props) => { type="text" value={data?.name} onChange={(e) => handleData("name", e.target.value)} - placeholder="Title" + placeholder={t("title")} className="w-full text-base" tabIndex={getIndex("name")} required /> {isTitleLengthMoreThan255Character && ( - Title should be less than 255 characters + {t("title_should_be_less_than_255_characters")} )}
); diff --git a/web/core/components/inbox/modals/decline-issue-modal.tsx b/web/core/components/inbox/modals/decline-issue-modal.tsx index dd6b009e267..fb5ea5c0405 100644 --- a/web/core/components/inbox/modals/decline-issue-modal.tsx +++ b/web/core/components/inbox/modals/decline-issue-modal.tsx @@ -1,5 +1,6 @@ import React, { useState } from "react"; // types +import { useTranslation } from "@plane/i18n"; import type { TIssue } from "@plane/types"; // ui import { AlertModalCore } from "@plane/ui"; @@ -19,6 +20,7 @@ export const DeclineIssueModal: React.FC = (props) => { const [isDeclining, setIsDeclining] = useState(false); // store hooks const { getProjectById } = useProject(); + const { t } = useTranslation(); // derived values const projectDetails = data.project_id ? getProjectById(data?.project_id) : undefined; @@ -38,10 +40,10 @@ export const DeclineIssueModal: React.FC = (props) => { handleSubmit={handleDecline} isSubmitting={isDeclining} isOpen={isOpen} - title="Decline issue" + title={t("inbox_issue.modals.decline.title")} + // TODO: Need to translate the confirmation message content={ <> - {" "} Are you sure you want to decline issue{" "} {projectDetails?.identifier}-{data?.sequence_id} @@ -50,8 +52,8 @@ export const DeclineIssueModal: React.FC = (props) => { } primaryButtonText={{ - loading: "Declining", - default: "Decline", + loading: t("declining"), + default: t("decline"), }} /> ); diff --git a/web/core/components/inbox/modals/delete-issue-modal.tsx b/web/core/components/inbox/modals/delete-issue-modal.tsx index d2e96d8273b..058e6c67b91 100644 --- a/web/core/components/inbox/modals/delete-issue-modal.tsx +++ b/web/core/components/inbox/modals/delete-issue-modal.tsx @@ -37,8 +37,8 @@ export const DeleteInboxIssueModal: React.FC = observer(({ isOpen, onClos .then(() => { setToast({ type: TOAST_TYPE.SUCCESS, - title: "Success!", - message: `Issue deleted successfully`, + title: `${t("success")!}`, + message: `${t("inbox_issue.modal.delete.success")!}`, }); }) .catch((errors) => { @@ -61,7 +61,8 @@ export const DeleteInboxIssueModal: React.FC = observer(({ isOpen, onClos handleSubmit={handleDelete} isSubmitting={isDeleting} isOpen={isOpen} - title="Delete issue" + title={t("inbox_issue.modals.delete.title")} + // TODO: Need to translate the confirmation message content={ <> Are you sure you want to delete issue{" "} diff --git a/web/core/components/inbox/modals/snooze-issue-modal.tsx b/web/core/components/inbox/modals/snooze-issue-modal.tsx index 02134d56635..a25b0236570 100644 --- a/web/core/components/inbox/modals/snooze-issue-modal.tsx +++ b/web/core/components/inbox/modals/snooze-issue-modal.tsx @@ -4,6 +4,7 @@ import { FC, Fragment, useState } from "react"; import { DayPicker } from "react-day-picker"; import { Dialog, Transition } from "@headlessui/react"; // ui +import { useTranslation } from "@plane/i18n"; import { Button } from "@plane/ui"; export type InboxIssueSnoozeModalProps = { @@ -17,6 +18,8 @@ export const InboxIssueSnoozeModal: FC = (props) => const { isOpen, handleClose, value, onConfirm } = props; // states const [date, setDate] = useState(value || new Date()); + //hooks + const { t } = useTranslation(); return ( @@ -67,7 +70,7 @@ export const InboxIssueSnoozeModal: FC = (props) => onConfirm(date); }} > - Snooze + {t("inbox_issue.actions.snooze")} diff --git a/web/core/components/inbox/sidebar/root.tsx b/web/core/components/inbox/sidebar/root.tsx index a7821ec9e45..e40359087ed 100644 --- a/web/core/components/inbox/sidebar/root.tsx +++ b/web/core/components/inbox/sidebar/root.tsx @@ -26,14 +26,14 @@ type IInboxSidebarProps = { setIsMobileSidebar: (value: boolean) => void; }; -const tabNavigationOptions: { key: TInboxIssueCurrentTab; label: string }[] = [ +const tabNavigationOptions: { key: TInboxIssueCurrentTab; i18n_label: string }[] = [ { key: EInboxIssueCurrentTab.OPEN, - label: "Open", + i18n_label: "inbox_issue.tabs.open", }, { key: EInboxIssueCurrentTab.CLOSED, - label: "Closed", + i18n_label: "inbox_issue.tabs.closed", }, ]; @@ -99,7 +99,7 @@ export const InboxSidebar: FC = observer((props) => { } }} > -
{option?.label}
+
{t(option?.i18n_label)}
{option?.key === "open" && currentTab === option?.key && (
{inboxIssuePaginationInfo?.total_results || 0} @@ -138,20 +138,20 @@ export const InboxSidebar: FC = observer((props) => {
{getAppliedFiltersCount > 0 ? ( ) : currentTab === EInboxIssueCurrentTab.OPEN ? ( ) : ( )} diff --git a/web/core/components/workspace/sidebar/user-menu.tsx b/web/core/components/workspace/sidebar/user-menu.tsx index 4e44dc20c82..67dfd319c70 100644 --- a/web/core/components/workspace/sidebar/user-menu.tsx +++ b/web/core/components/workspace/sidebar/user-menu.tsx @@ -37,7 +37,7 @@ export const SidebarUserMenu = observer(() => { }, { key: "notifications", - labelTranslationKey: "inbox.label", + labelTranslationKey: "notification.label", href: `/${workspaceSlug.toString()}/notifications/`, access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER, EUserWorkspaceRoles.GUEST], Icon: Inbox,