Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions packages/i18n/src/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
"description": "Description",
"search": "Search",
"add_member": "Add member",
"adding_members": "Adding members",
"no_matching_members": "No matching members",
"remove_member": "Remove member",
"add_members": "Add members",
"adding_member": "Adding members",
"remove_members": "Remove members",
"add": "Add",
"adding": "Adding",
Expand Down Expand Up @@ -184,6 +187,10 @@
"description_placeholder": "Description...",
"only_alphanumeric_non_latin_characters_allowed": "Only Alphanumeric & Non-latin characters are allowed.",
"project_id_is_required": "Project ID is required",
"project_id_allowed_char": "Only Alphanumeric & Non-latin characters are allowed.",
"project_id_min_char": "Project ID must at least be of 1 character",
"project_id_max_char": "Project ID must at most be of 5 characters",
"project_description_placeholder": "Enter project description",
"select_network": "Select network",
"lead": "Lead",
"date_range": "Date range",
Expand Down Expand Up @@ -515,6 +522,20 @@
"description": "Description",
"title": "Title",
"attachment": "Attachment",
"general": "General",
"features": "Features",
"automation": "Automation",
"project_name": "Project name",
"project_id": "Project ID",
"project_timezone": "Project Timezone",
"created_on": "Created on",
"update_project": "Update project",
"identifier_already_exists": "Identifier already exists",
"add_more": "Add more",
"defaults": "Defaults",
"add_label": "Add label",
"estimates": "estimates",
"customize_time_range": "Customize time range",
"loading": "Loading...",
"attachments": "Attachments",
"properties": "Properties",
Expand Down Expand Up @@ -1229,10 +1250,77 @@
},

"project_settings": {
"general": {
"enter_project_id": "Enter project ID",
"please_select_a_timezone": "Please select a timezone",
"archive_project": {
"title": "Archive project",
"description": "Archiving a project will unlist your project from your side navigation although you will still be able to access it from your projects page. You can restore the project or delete it whenever you want.",
"button": "Archive project"
},
"delete_project": {
"title": "Delete project",
"description": "When deleting a project, all of the data and resources within that project will be permanently removed and cannot be recovered.",
"button": "Delete my project"
},
"toast": {
"success": "Project updated successfully",
"error": "Project could not be updated. Please try again."
}
},
"members": {
"label": "Members",
"project_lead": "Project lead",
"default_assignee": "Default assignee",
"guest_super_permissions": {
"title": "Grant view access to all issues for guest users:",
"sub_heading": "This will allow guests to have view access to all the project issues."
},
"invite_members": {
"title": "Invite members",
"sub_heading": "Invite members to work on your project.",
"select_co_worker": "Select co-worker"
}
},
"states": {
"describe_this_state_for_your_members": "Describe this state for your members."
},
"labels": {
"label_title": "Label title",
"label_title_is_required": "Label title is required",
"label_max_char": "Label name should not exceed 255 characters",
"toast": {
"error": "Error while updating the label"
}
},
"estimates": {
"title": "Enable estimates for my project",
"description": "They help you in communicating complexity and workload of the team."
},
"automations": {
"label": "Automations",
"auto-archive": {
"title": "Auto-archive closed issues",
"description": "Plane will auto archive issues that have been completed or canceled.",
"duration": "Auto-archive issues that are closed for"
},
"auto-close": {
"title": "Auto-close issues",
"description": "Plane will automatically close issues that haven't been completed or canceled.",
"duration": "Auto-close issues that are inactive for",
"auto_close_status": "Auto-close status"
}
},

"empty_state": {
"labels": {
"title": "No labels yet",
"description": "Create labels to help organize and filter issues in you project."
},
"estimates": {
"title": "No estimate systems yet",
"description": "Create a set of estimates to communicate the amount of work per issue.",
"primary_button": "Add estimate system"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { IProject } from "@plane/types";
// ui
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { NotAuthorizedView } from "@/components/auth-screens";
Expand All @@ -21,6 +22,8 @@ const AutomationSettingsPage = observer(() => {
const { workspaceUserInfo, allowPermissions } = useUserPermissions();
const { currentProjectDetails: projectDetails, updateProject } = useProject();

const { t } = useTranslation();

// derived values
const canPerformProjectAdminActions = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.PROJECT);

Expand Down Expand Up @@ -48,7 +51,7 @@ const AutomationSettingsPage = observer(() => {
<PageHead title={pageTitle} />
<section className={`w-full overflow-y-auto ${canPerformProjectAdminActions ? "" : "opacity-60"}`}>
<div className="flex flex-col items-start border-b border-custom-border-100 pb-3.5">
<h3 className="text-xl font-medium leading-normal">Automations</h3>
<h3 className="text-xl font-medium leading-normal">{t("project_settings.automations.label")}</h3>
</div>
<AutoArchiveAutomation handleChange={handleChange} />
<AutoCloseAutomation handleChange={handleChange} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// ui
import { Settings } from "lucide-react";
import { useTranslation } from "@plane/i18n";
import { Breadcrumbs, CustomMenu, Header } from "@plane/ui";
// components
import { BreadcrumbLink } from "@/components/common";
Expand All @@ -24,6 +25,8 @@ export const ProjectSettingHeader: FC = observer(() => {
const { allowPermissions } = useUserPermissions();
const { loader } = useProject();

const { t } = useTranslation();

return (
<Header>
<Header.LeftItem>
Expand Down Expand Up @@ -65,7 +68,7 @@ export const ProjectSettingHeader: FC = observer(() => {
key={item.key}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}${item.href}`)}
>
{item.label}
{t(item.i18n_label)}
</CustomMenu.MenuItem>
)
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import range from "lodash/range";
import { observer } from "mobx-react";
import Link from "next/link";
import { useParams, usePathname } from "next/navigation";
import { useTranslation } from "@plane/i18n";
// ui
import { Loader } from "@plane/ui";
// components
Expand All @@ -21,6 +22,8 @@ export const ProjectSettingsSidebar = observer(() => {
// mobx store
const { allowPermissions, projectUserInfo } = useUserPermissions();

const { t } = useTranslation();

// derived values
const currentProjectRole = projectUserInfo?.[workspaceSlug?.toString()]?.[projectId?.toString()]?.role;

Expand Down Expand Up @@ -58,7 +61,7 @@ export const ProjectSettingsSidebar = observer(() => {
isActive={link.highlight(pathname, `/${workspaceSlug}/projects/${projectId}`)}
className="text-sm font-medium px-4 py-2"
>
{link.label}
{t(link.i18n_label)}
</SidebarNavItem>
</Link>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { useTranslation } from "@plane/i18n";
// components
import { NotAuthorizedView } from "@/components/auth-screens";
import { PageHead } from "@/components/core";
Expand All @@ -16,6 +17,8 @@ const StatesSettingsPage = observer(() => {
const { currentProjectDetails } = useProject();
const { workspaceUserInfo, allowPermissions } = useUserPermissions();

const { t } = useTranslation();

// derived values
const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - States` : undefined;
// derived values
Expand All @@ -32,7 +35,7 @@ const StatesSettingsPage = observer(() => {
<>
<PageHead title={pageTitle} />
<div className="flex items-center border-b border-custom-border-100">
<h3 className="text-xl font-medium">States</h3>
<h3 className="text-xl font-medium">{t("states")}</h3>
</div>
{workspaceSlug && projectId && (
<ProjectStateRoot workspaceSlug={workspaceSlug.toString()} projectId={projectId.toString()} />
Expand Down
18 changes: 9 additions & 9 deletions web/ce/constants/project/settings/tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,55 @@ import { EUserPermissions } from "../../user-permissions";
export const PROJECT_SETTINGS = {
general: {
key: "general",
label: "General",
i18n_label: "common.general",
href: `/settings`,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER, EUserPermissions.GUEST],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/`,
Icon: SettingIcon,
},
members: {
key: "members",
label: "Members",
i18n_label: "members",
href: `/settings/members`,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/members/`,
Icon: SettingIcon,
},
features: {
key: "features",
label: "Features",
i18n_label: "common.features",
href: `/settings/features`,
access: [EUserPermissions.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/features/`,
Icon: SettingIcon,
},
states: {
key: "states",
label: "States",
i18n_label: "common.states",
href: `/settings/states`,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/states/`,
Icon: SettingIcon,
},
labels: {
key: "labels",
label: "Labels",
key: "i18n_labels",
i18n_label: "common.labels",
href: `/settings/labels`,
access: [EUserPermissions.ADMIN, EUserPermissions.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/labels/`,
Icon: SettingIcon,
},
estimates: {
key: "estimates",
label: "Estimates",
i18n_label: "common.estimates",
href: `/settings/estimates`,
access: [EUserPermissions.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/estimates/`,
Icon: SettingIcon,
},
automations: {
key: "automations",
label: "Automations",
i18n_label: "common.automations",
href: `/settings/automations`,
access: [EUserPermissions.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/automations/`,
Expand All @@ -66,7 +66,7 @@ export const PROJECT_SETTINGS = {

export const PROJECT_SETTINGS_LINKS: {
key: string;
label: string;
i18n_label: string;
href: string;
access: EUserPermissions[];
highlight: (pathname: string, baseUrl: string) => boolean;
Expand Down
10 changes: 6 additions & 4 deletions web/core/components/automation/auto-archive-automation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ export const AutoArchiveAutomation: React.FC<Props> = observer((props) => {
<ArchiveRestore className="h-4 w-4 flex-shrink-0 text-custom-text-100" />
</div>
<div className="">
<h4 className="text-sm font-medium">Auto-archive closed issues</h4>
<h4 className="text-sm font-medium">{t("project_settings.automations.auto-archive.title")}</h4>
<p className="text-sm tracking-tight text-custom-text-200">
Plane will auto archive issues that have been completed or canceled.
{t("project_settings.automations.auto-archive.description")}
</p>
</div>
</div>
Expand All @@ -77,7 +77,9 @@ export const AutoArchiveAutomation: React.FC<Props> = observer((props) => {
currentProjectDetails.archive_in !== 0 && (
<div className="mx-6">
<div className="flex w-full items-center justify-between gap-2 rounded border border-custom-border-200 bg-custom-background-90 px-5 py-4">
<div className="w-1/2 text-sm font-medium">Auto-archive issues that are closed for</div>
<div className="w-1/2 text-sm font-medium">
{t("project_settings.automations.auto-archive.duration")}
</div>
<div className="w-1/2">
<CustomSelect
value={currentProjectDetails?.archive_in}
Expand All @@ -102,7 +104,7 @@ export const AutoArchiveAutomation: React.FC<Props> = observer((props) => {
className="flex w-full select-none items-center rounded px-1 py-1.5 text-sm text-custom-text-200 hover:bg-custom-background-80"
onClick={() => setmonthModal(true)}
>
Customize time range
{t("customize_time_range")}
</button>
</>
</CustomSelect>
Expand Down
16 changes: 10 additions & 6 deletions web/core/components/automation/auto-close-automation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ export const AutoCloseAutomation: React.FC<Props> = observer((props) => {
<ArchiveX className="h-4 w-4 flex-shrink-0 text-red-500" />
</div>
<div className="">
<h4 className="text-sm font-medium">Auto-close issues</h4>
<h4 className="text-sm font-medium">{t("project_settings.automations.auto-close.title")}</h4>
<p className="text-sm tracking-tight text-custom-text-200">
Plane will automatically close issues that haven{"'"}t been completed or canceled.
{t("project_settings.automations.auto-close.description")}
</p>
</div>
</div>
Expand All @@ -104,7 +104,9 @@ export const AutoCloseAutomation: React.FC<Props> = observer((props) => {
<div className="mx-6">
<div className="flex flex-col rounded border border-custom-border-200 bg-custom-background-90">
<div className="flex w-full items-center justify-between gap-2 px-5 py-4">
<div className="w-1/2 text-sm font-medium">Auto-close issues that are inactive for</div>
<div className="w-1/2 text-sm font-medium">
{t("project_settings.automations.auto-close.duration")}
</div>
<div className="w-1/2">
<CustomSelect
value={currentProjectDetails?.close_in}
Expand All @@ -128,15 +130,17 @@ export const AutoCloseAutomation: React.FC<Props> = 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")}
</button>
</>
</CustomSelect>
</div>
</div>

<div className="flex w-full items-center justify-between gap-2 px-5 py-4">
<div className="w-1/2 text-sm font-medium">Auto-close status</div>
<div className="w-1/2 text-sm font-medium">
{t("project_settings.automations.auto-close.auto_close_status")}
</div>
<div className="w-1/2 ">
<CustomSearchSelect
value={currentProjectDetails?.default_state ?? defaultState}
Expand All @@ -161,7 +165,7 @@ export const AutoCloseAutomation: React.FC<Props> = observer((props) => {
)}
{selectedOption?.name
? selectedOption.name
: (currentDefaultState?.name ?? <span className="text-custom-text-200">State</span>)}
: (currentDefaultState?.name ?? <span className="text-custom-text-200">{t("state")}</span>)}
</div>
}
onChange={(val: string) => {
Expand Down
Loading
Loading