UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: перевод внешних контуров на shell предложений
This commit is contained in:
@@ -217,7 +217,7 @@ export const InboxIssueActionsHeader = observer(function InboxIssueActionsHeader
|
||||
else {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Permission denied",
|
||||
title: t("permission_denied"),
|
||||
message: errorMessage,
|
||||
});
|
||||
}
|
||||
@@ -407,7 +407,7 @@ export const InboxIssueActionsHeader = observer(function InboxIssueActionsHeader
|
||||
handleActionWithPermission(
|
||||
isProjectAdmin,
|
||||
() => setSelectDuplicateIssue(true),
|
||||
"Only project admins can mark work item as duplicate"
|
||||
t("inbox_issue.errors.duplicate_permission")
|
||||
)
|
||||
}
|
||||
>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { Clock, FileStack, MoreHorizontal, PanelLeft, MoveRight } from "lucide-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { IconButton, getIconButtonStyling } from "@plane/propel/icon-button";
|
||||
import {
|
||||
LinkIcon,
|
||||
@@ -79,6 +80,7 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
isProjectAdmin,
|
||||
handleActionWithPermission,
|
||||
} = props;
|
||||
const { t } = useTranslation();
|
||||
const router = useAppRouter();
|
||||
const { getProjectIdentifierById } = useProject();
|
||||
|
||||
@@ -143,7 +145,7 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
<CustomMenu.MenuItem onClick={handleCopyIssueLink}>
|
||||
<div className="flex items-center gap-2">
|
||||
<LinkIcon width={14} height={14} strokeWidth={2} />
|
||||
Copy work item link
|
||||
{t("inbox_issue.actions.copy")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
@@ -151,7 +153,7 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
<CustomMenu.MenuItem onClick={() => router.push(workItemLink)}>
|
||||
<div className="flex items-center gap-2">
|
||||
<NewTabIcon width={14} height={14} strokeWidth={2} />
|
||||
Open work item
|
||||
{t("inbox_issue.actions.open")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
@@ -161,13 +163,15 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
handleActionWithPermission(
|
||||
isProjectAdmin,
|
||||
handleIssueSnoozeAction,
|
||||
"Only project admins can snooze/Un-snooze work items"
|
||||
t("inbox_issue.errors.snooze_permission")
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock size={14} strokeWidth={2} />
|
||||
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0 ? "Un-snooze" : "Snooze"}
|
||||
{inboxIssue?.snoozed_till && numberOfDaysLeft && numberOfDaysLeft > 0
|
||||
? t("inbox_issue.actions.unsnooze")
|
||||
: t("inbox_issue.actions.snooze")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
@@ -177,13 +181,13 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
handleActionWithPermission(
|
||||
isProjectAdmin,
|
||||
() => setSelectDuplicateIssue(true),
|
||||
"Only project admins can mark work items as duplicate"
|
||||
t("inbox_issue.errors.duplicate_permission")
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<FileStack size={14} strokeWidth={2} />
|
||||
Mark as duplicate
|
||||
{t("inbox_issue.actions.mark_as_duplicate")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
@@ -193,13 +197,13 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
handleActionWithPermission(
|
||||
isProjectAdmin,
|
||||
() => setAcceptIssueModal(true),
|
||||
"Only project admins can accept work items"
|
||||
t("inbox_issue.errors.accept_permission")
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2 text-success-secondary">
|
||||
<CheckCircleFilledIcon width={14} height={14} />
|
||||
Accept
|
||||
{t("inbox_issue.actions.accept")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
@@ -209,13 +213,13 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
handleActionWithPermission(
|
||||
isProjectAdmin,
|
||||
() => setDeclineIssueModal(true),
|
||||
"Only project admins can deny work items"
|
||||
t("inbox_issue.errors.decline_permission")
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2 text-danger-secondary">
|
||||
<CloseCircleFilledIcon width={14} height={14} />
|
||||
Decline
|
||||
{t("inbox_issue.actions.decline")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
@@ -223,7 +227,7 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
|
||||
<CustomMenu.MenuItem onClick={() => setDeleteIssueModal(true)}>
|
||||
<div className="flex items-center gap-2 text-danger-primary">
|
||||
<TrashIcon height={14} width={14} strokeWidth={2} />
|
||||
Delete
|
||||
{t("inbox_issue.actions.delete")}
|
||||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import {
|
||||
StatePropertyIcon,
|
||||
MembersPropertyIcon,
|
||||
@@ -44,6 +45,7 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
props;
|
||||
|
||||
const router = useAppRouter();
|
||||
const { t } = useTranslation();
|
||||
// store hooks
|
||||
const { currentProjectDetails } = useProject();
|
||||
|
||||
@@ -63,14 +65,14 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
return (
|
||||
<div className="flex w-full flex-col divide-y-2 divide-subtle-1">
|
||||
<div className="w-full overflow-y-auto">
|
||||
<h5 className="mb-2 text-body-sm-medium">Properties</h5>
|
||||
<h5 className="mb-2 text-body-sm-medium">{t("properties")}</h5>
|
||||
<div className={`divide-y-2 divide-subtle-1 ${!isEditable ? "opacity-60" : ""}`}>
|
||||
<div className="flex flex-col gap-3">
|
||||
{/* Intake State */}
|
||||
<div className="flex h-8 items-center gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 items-center gap-1 text-13 text-tertiary">
|
||||
<StatePropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>State</span>
|
||||
<span>{t("state")}</span>
|
||||
</div>
|
||||
{issue?.state_id && (
|
||||
<DropdownComponent
|
||||
@@ -91,7 +93,7 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
<div className="flex h-8 items-center gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 items-center gap-1 text-13 text-tertiary">
|
||||
<MembersPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>Assignees</span>
|
||||
<span>{t("assignees")}</span>
|
||||
</div>
|
||||
<MemberDropdown
|
||||
value={issue?.assignee_ids ?? []}
|
||||
@@ -100,7 +102,7 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
}
|
||||
disabled={!isEditable}
|
||||
projectId={projectId?.toString() ?? ""}
|
||||
placeholder="Add assignees"
|
||||
placeholder={t("assignee")}
|
||||
multiple
|
||||
buttonVariant={
|
||||
(issue?.assignee_ids || [])?.length > 0 ? "transparent-without-text" : "transparent-with-text"
|
||||
@@ -119,7 +121,7 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
<div className="flex h-8 items-center gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 items-center gap-1 text-13 text-tertiary">
|
||||
<PriorityPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>Priority</span>
|
||||
<span>{t("priority")}</span>
|
||||
</div>
|
||||
<PriorityDropdown
|
||||
value={issue?.priority}
|
||||
@@ -141,10 +143,10 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
<div className="flex h-8 items-center gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 items-center gap-1 text-13 text-tertiary">
|
||||
<DueDatePropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>Due date</span>
|
||||
<span>{t("due_date")}</span>
|
||||
</div>
|
||||
<DateDropdown
|
||||
placeholder="Add due date"
|
||||
placeholder={t("issues.properties.add_due_date")}
|
||||
value={issue.target_date || null}
|
||||
onChange={(val) =>
|
||||
issue?.id &&
|
||||
@@ -166,7 +168,7 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
<div className="flex min-h-8 items-center gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 items-center gap-1 text-13 text-tertiary">
|
||||
<LabelPropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>Labels</span>
|
||||
<span>{t("labels")}</span>
|
||||
</div>
|
||||
<div className="h-full min-h-8 w-3/5 flex-grow pt-1">
|
||||
{issue?.id && (
|
||||
@@ -187,10 +189,10 @@ export const InboxIssueContentProperties = observer(function InboxIssueContentPr
|
||||
{/* duplicate to*/}
|
||||
{duplicateIssueDetails && (
|
||||
<div className="flex min-h-8 gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 gap-1 pt-2 text-13 text-tertiary">
|
||||
<DuplicatePropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>Duplicate of</span>
|
||||
</div>
|
||||
<div className="flex w-2/5 flex-shrink-0 gap-1 pt-2 text-13 text-tertiary">
|
||||
<DuplicatePropertyIcon className="h-4 w-4 flex-shrink-0" />
|
||||
<span>{t("issues.properties.duplicate_of")}</span>
|
||||
</div>
|
||||
|
||||
<ControlLink
|
||||
href={duplicateWorkItemLink}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import type { Dispatch, SetStateAction } from "react";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// plane imports
|
||||
import type { EditorRefApi } from "@plane/editor";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
@@ -52,6 +53,7 @@ type Props = {
|
||||
|
||||
export const InboxIssueMainContent = observer(function InboxIssueMainContent(props: Props) {
|
||||
const { workspaceSlug, projectId, inboxIssue, isEditable, isSubmitting, setIsSubmitting } = props;
|
||||
const { t } = useTranslation();
|
||||
// refs
|
||||
const editorRef = useRef<EditorRefApi>(null);
|
||||
// store hooks
|
||||
@@ -101,16 +103,16 @@ export const InboxIssueMainContent = observer(function InboxIssueMainContent(pro
|
||||
try {
|
||||
await removeIssue(workspaceSlug, projectId, _issueId);
|
||||
setToast({
|
||||
title: "Success!",
|
||||
title: t("success"),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
message: "Work item deleted successfully",
|
||||
message: t("inbox_issue.modals.delete.success"),
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("Error in deleting work item:", error);
|
||||
setToast({
|
||||
title: "Error!",
|
||||
title: t("error"),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
message: "Work item delete failed",
|
||||
message: t("something_went_wrong_please_try_again"),
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -119,9 +121,9 @@ export const InboxIssueMainContent = observer(function InboxIssueMainContent(pro
|
||||
await inboxIssue.updateIssue(data);
|
||||
} catch (_error) {
|
||||
setToast({
|
||||
title: "Work item update failed",
|
||||
title: t("error"),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
message: "Work item update failed",
|
||||
message: t("issue_could_not_be_updated"),
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -206,7 +208,7 @@ export const InboxIssueMainContent = observer(function InboxIssueMainContent(pro
|
||||
createdAt: issue.created_at ? new Date(issue.created_at) : new Date(),
|
||||
createdByDisplayName:
|
||||
inboxIssue.source === EInboxIssueSource.FORMS
|
||||
? "Intake Form user"
|
||||
? t("inbox_issue.source.form_user")
|
||||
: (getUserDetails(issue.created_by ?? "")?.display_name ?? ""),
|
||||
id: issue.id,
|
||||
isRestoreDisabled: !isEditable,
|
||||
|
||||
@@ -161,11 +161,10 @@ export const InboxSidebar = observer(function InboxSidebar(props: IInboxSidebarP
|
||||
rootClassName="px-page-x"
|
||||
/>
|
||||
) : (
|
||||
// TODO: Add translation
|
||||
<EmptyStateDetailed
|
||||
assetKey="inbox"
|
||||
title="No request closed yet"
|
||||
description="All the work items whether accepted or declined can be found here."
|
||||
title={t("inbox_issue.empty_state.sidebar_closed_tab.title")}
|
||||
description={t("inbox_issue.empty_state.sidebar_closed_tab.description")}
|
||||
assetClassName="size-20"
|
||||
className="px-10"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user