-
Auto-close issues that are inactive for
+
+ {t("project_settings.automations.auto-close.duration")}
+
= observer((props) => {
className="flex w-full select-none items-center rounded px-1 py-1.5 text-custom-text-200 hover:bg-custom-background-80"
onClick={() => setmonthModal(true)}
>
- Customize time range
+ {t("customize_time_range")}
>
@@ -136,7 +138,9 @@ export const AutoCloseAutomation: React.FC
= observer((props) => {
-
Auto-close status
+
+ {t("project_settings.automations.auto-close.auto_close_status")}
+
= observer((props) => {
)}
{selectedOption?.name
? selectedOption.name
- : (currentDefaultState?.name ?? State)}
+ : (currentDefaultState?.name ?? {t("state")})}
}
onChange={(val: string) => {
diff --git a/web/core/components/estimates/empty-screen.tsx b/web/core/components/estimates/empty-screen.tsx
index e3e59a477ea..b05f9f22d16 100644
--- a/web/core/components/estimates/empty-screen.tsx
+++ b/web/core/components/estimates/empty-screen.tsx
@@ -7,6 +7,7 @@ import { Button } from "@plane/ui";
// public images
import EstimateEmptyDarkImage from "@/public/empty-state/estimates/dark.svg";
import EstimateEmptyLightImage from "@/public/empty-state/estimates/light.svg";
+import { useTranslation } from "@plane/i18n";
type TEstimateEmptyScreen = {
onButtonClick: () => void;
@@ -17,6 +18,8 @@ export const EstimateEmptyScreen: FC
= (props) => {
const { onButtonClick } = props;
const { resolvedTheme } = useTheme();
+ const { t } = useTranslation();
+
const emptyScreenImage = resolvedTheme === "light" ? EstimateEmptyLightImage : EstimateEmptyDarkImage;
return (
@@ -31,13 +34,13 @@ export const EstimateEmptyScreen: FC = (props) => {
/>
-
No estimate systems yet
-
- Create a set of estimates to communicate the amount of work per issue.
-
+
+ {t("project_settings.empty_state.estimates.title")}
+
+
{t("project_settings.empty_state.estimates.description")}
-
+
);
diff --git a/web/core/components/estimates/root.tsx b/web/core/components/estimates/root.tsx
index 873ed410088..38abba9b376 100644
--- a/web/core/components/estimates/root.tsx
+++ b/web/core/components/estimates/root.tsx
@@ -14,6 +14,7 @@ import {
import { useProject, useProjectEstimates } from "@/hooks/store";
// plane web components
import { UpdateEstimateModal } from "@/plane-web/components/estimates";
+import { useTranslation } from "@plane/i18n";
type TEstimateRoot = {
workspaceSlug: string;
@@ -31,6 +32,8 @@ export const EstimateRoot: FC
= observer((props) => {
const [estimateToUpdate, setEstimateToUpdate] = useState();
const [estimateToDelete, setEstimateToDelete] = useState();
+ const { t } = useTranslation();
+
const { isLoading: isSWRLoading } = useSWR(
workspaceSlug && projectId ? `PROJECT_ESTIMATES_${workspaceSlug}_${projectId}` : null,
async () => workspaceSlug && projectId && getProjectEstimates(workspaceSlug, projectId)
@@ -44,7 +47,7 @@ export const EstimateRoot: FC = observer((props) => {
{/* header */}
-
Estimates
+ {t("common.estimates")}
{/* current active estimate section */}
@@ -53,10 +56,8 @@ export const EstimateRoot: FC
= observer((props) => {
{/* estimates activated deactivated section */}
-
Enable estimates for my project
-
- They help you in communicating complexity and workload of the team.
-
+
{t("project_settings.estimates.title")}
+
{t("project_settings.estimates.description")}
diff --git a/web/core/components/labels/create-update-label-inline.tsx b/web/core/components/labels/create-update-label-inline.tsx
index f5941ca40c6..ddbe220b933 100644
--- a/web/core/components/labels/create-update-label-inline.tsx
+++ b/web/core/components/labels/create-update-label-inline.tsx
@@ -8,6 +8,7 @@ import { Controller, SubmitHandler, useForm } from "react-hook-form";
import { Popover, Transition } from "@headlessui/react";
// plane imports
import { getRandomLabelColor, LABEL_COLOR_OPTIONS } from "@plane/constants";
+import { useTranslation } from "@plane/i18n";
import { IIssueLabel } from "@plane/types";
import { Button, Input, TOAST_TYPE, setToast } from "@plane/ui";
// hooks
@@ -46,6 +47,8 @@ export const CreateUpdateLabelInline = observer(
defaultValues,
});
+ const { t } = useTranslation();
+
const handleClose = () => {
setLabelForm(false);
reset(defaultValues);
@@ -64,7 +67,7 @@ export const CreateUpdateLabelInline = observer(
setToast({
title: "Error!",
type: TOAST_TYPE.ERROR,
- message: error?.detail ?? error.error ?? "Something went wrong. Please try again later.",
+ message: error?.detail ?? error.error ?? t("common.something_went_wrong"),
});
reset(formData);
});
@@ -83,7 +86,7 @@ export const CreateUpdateLabelInline = observer(
setToast({
title: "Oops!",
type: TOAST_TYPE.ERROR,
- message: error?.error ?? "Error while updating the label",
+ message: error?.error ?? t("project_settings.labels.toast.error"),
});
reset(formData);
});
@@ -171,10 +174,10 @@ export const CreateUpdateLabelInline = observer(
control={control}
name="name"
rules={{
- required: "Label title is required",
+ required: t("project_settings.labels.label_title_is_required"),
maxLength: {
value: 255,
- message: "Label name should not exceed 255 characters",
+ message: t("project_settings.labels.label_max_char"),
},
}}
render={({ field: { value, onChange, ref } }) => (
@@ -187,17 +190,17 @@ export const CreateUpdateLabelInline = observer(
onChange={onChange}
ref={ref}
hasError={Boolean(errors.name)}
- placeholder="Label title"
+ placeholder={t("project_settings.labels.label_title")}
className="w-full"
/>
)}
/>
{errors.name?.message && {errors.name?.message}
}
diff --git a/web/core/components/labels/project-setting-label-list.tsx b/web/core/components/labels/project-setting-label-list.tsx
index e0943da3769..5a25face14a 100644
--- a/web/core/components/labels/project-setting-label-list.tsx
+++ b/web/core/components/labels/project-setting-label-list.tsx
@@ -73,7 +73,7 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
Labels
{isEditable && (
)}
diff --git a/web/core/components/project/form.tsx b/web/core/components/project/form.tsx
index 85328121a6e..0e62b2fe83d 100644
--- a/web/core/components/project/form.tsx
+++ b/web/core/components/project/form.tsx
@@ -107,8 +107,8 @@ export const ProjectDetailsForm: FC
= (props) => {
});
setToast({
type: TOAST_TYPE.SUCCESS,
- title: "Success!",
- message: "Project updated successfully",
+ title: t("toast.success"),
+ message: t("project_settings.general.toast.success"),
});
})
.catch((error) => {
@@ -118,8 +118,8 @@ export const ProjectDetailsForm: FC = (props) => {
});
setToast({
type: TOAST_TYPE.ERROR,
- title: "Error!",
- message: error?.error ?? "Project could not be updated. Please try again.",
+ title: t("toast.error"),
+ message: error?.error ?? t("project_settings.general.toast.error"),
});
});
};
@@ -146,7 +146,7 @@ export const ProjectDetailsForm: FC = (props) => {
await projectService
.checkProjectIdentifierAvailability(workspaceSlug as string, payload.identifier ?? "")
.then(async (res) => {
- if (res.exists) setError("identifier", { message: "Identifier already exists" });
+ if (res.exists) setError("identifier", { message: t("common.identifier_already_exists") });
else await handleUpdateChange(payload);
});
else await handleUpdateChange(payload);
@@ -219,7 +219,7 @@ export const ProjectDetailsForm: FC = (props) => {
name="cover_image_url"
render={({ field: { value, onChange } }) => (
= (props) => {
-
Project name
+ {t("common.project_name")}
= (props) => {
onChange={onChange}
hasError={Boolean(errors.name)}
className="rounded-md !p-3 font-medium"
- placeholder="Project name"
+ placeholder={t("common.project_name")}
disabled={!isAdmin}
/>
)}
@@ -263,7 +263,7 @@ export const ProjectDetailsForm: FC = (props) => {
{errors?.name?.message}
-
Description
+ {t("description")}
= (props) => {
id="description"
name="description"
value={value}
- placeholder="Enter project description"
+ placeholder={t("project_description_placeholder")}
onChange={onChange}
className="min-h-[102px] text-sm font-medium"
hasError={Boolean(errors?.description)}
@@ -289,17 +289,15 @@ export const ProjectDetailsForm: FC = (props) => {
control={control}
name="identifier"
rules={{
- required: "Project ID is required",
- validate: (value) =>
- /^[ÇŞĞIİÖÜA-Z0-9]+$/.test(value.toUpperCase()) ||
- "Only Alphanumeric & Non-latin characters are allowed.",
+ required: t("project_id_is_required"),
+ validate: (value) => /^[ÇŞĞIİÖÜA-Z0-9]+$/.test(value.toUpperCase()) || t("project_id_allowed_char"),
minLength: {
value: 1,
- message: "Project ID must at least be of 1 character",
+ message: t("project_id_min_char"),
},
maxLength: {
value: 5,
- message: "Project ID must at most be of 5 characters",
+ message: t("project_id_max_char"),
},
}}
render={({ field: { value, ref } }) => (
@@ -311,7 +309,7 @@ export const ProjectDetailsForm: FC = (props) => {
onChange={handleIdentifierChange}
ref={ref}
hasError={Boolean(errors.identifier)}
- placeholder="Enter project ID"
+ placeholder={t("project_settings.general.enter_project_id")}
className="w-full font-medium"
disabled={!isAdmin}
/>
@@ -331,7 +329,7 @@ export const ProjectDetailsForm: FC = (props) => {
-
Network
+ {t("network")}
= (props) => {
{t(selectedNetwork.i18n_label)}
>
) : (
- Select network
+ {t("select_network")}
)}
}
@@ -375,11 +373,11 @@ export const ProjectDetailsForm: FC
= (props) => {
/>