fix: issue stats refactor (#6705)
* fix: issue stats refactor * fix: refactor * fix: ui color * fix: translation key
This commit is contained in:
parent
f01d82ad1e
commit
44af90dc6c
14 changed files with 98 additions and 53 deletions
|
|
@ -814,7 +814,8 @@
|
|||
"sub_issue_count": "Sub-work item count",
|
||||
"attachment_count": "Attachment count",
|
||||
"created_on": "Created on",
|
||||
"sub_issue": "Sub-work item"
|
||||
"sub_issue": "Sub-work item",
|
||||
"work_item_count": "Work item count"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "Show sub-work items",
|
||||
|
|
|
|||
|
|
@ -985,7 +985,8 @@
|
|||
"sub_issue_count": "Cantidad de sub-elementos",
|
||||
"attachment_count": "Cantidad de archivos adjuntos",
|
||||
"created_on": "Creado el",
|
||||
"sub_issue": "Sub-elemento de trabajo"
|
||||
"sub_issue": "Sub-elemento de trabajo",
|
||||
"work_item_count": "Recuento de elementos de trabajo"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "Mostrar sub-elementos",
|
||||
|
|
|
|||
|
|
@ -983,7 +983,8 @@
|
|||
"sub_issue_count": "Nombre de sous-éléments",
|
||||
"attachment_count": "Nombre de pièces jointes",
|
||||
"created_on": "Créé le",
|
||||
"sub_issue": "Sous-élément de travail"
|
||||
"sub_issue": "Sous-élément de travail",
|
||||
"work_item_count": "Nombre d'éléments de travail"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "Afficher les sous-éléments",
|
||||
|
|
|
|||
|
|
@ -980,8 +980,9 @@
|
|||
"sub_issue_count": "Numero di sotto-elementi di lavoro",
|
||||
"attachment_count": "Numero di allegati",
|
||||
"created_on": "Creato il",
|
||||
"sub_issue": "Sotto-elemento di lavoro"
|
||||
},
|
||||
"sub_issue": "Sotto-elemento di lavoro",
|
||||
"work_item_count": "Conteggio degli elementi di lavoro"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "Mostra sotto-elementi di lavoro",
|
||||
"show_empty_groups": "Mostra gruppi vuoti"
|
||||
|
|
|
|||
|
|
@ -983,8 +983,9 @@
|
|||
"sub_issue_count": "サブ作業項目数",
|
||||
"attachment_count": "添付ファイル数",
|
||||
"created_on": "作成日",
|
||||
"sub_issue": "サブ作業項目"
|
||||
},
|
||||
"sub_issue": "サブ作業項目",
|
||||
"work_item_count": "作業項目数"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "サブ作業項目を表示",
|
||||
"show_empty_groups": "空のグループを表示"
|
||||
|
|
|
|||
|
|
@ -982,7 +982,8 @@
|
|||
"sub_issue_count": "Количество подэлементов",
|
||||
"attachment_count": "Количество вложений",
|
||||
"created_on": "Дата создания",
|
||||
"sub_issue": "Подэлемент"
|
||||
"sub_issue": "Подэлемент",
|
||||
"work_item_count": "Количество рабочих элементов"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "Показывать подэлементы",
|
||||
|
|
|
|||
|
|
@ -983,7 +983,8 @@
|
|||
"sub_issue_count": "子工作项数量",
|
||||
"attachment_count": "附件数量",
|
||||
"created_on": "创建于",
|
||||
"sub_issue": "子工作项"
|
||||
"sub_issue": "子工作项",
|
||||
"work_item_count": "工作项数量"
|
||||
},
|
||||
"extra": {
|
||||
"show_sub_issues": "显示子工作项",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import React, { FC } from "react";
|
|||
|
||||
type Props = {
|
||||
issueId: string;
|
||||
className?: string;
|
||||
size?: number;
|
||||
showProgressText?: boolean;
|
||||
showLabel?: boolean;
|
||||
};
|
||||
|
||||
export const IssueStats: FC<Props> = (props) => {
|
||||
const { issueId } = props;
|
||||
return <></>;
|
||||
};
|
||||
export const IssueStats: FC<Props> = (props) => <></>;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export const FilterDisplayProperties: React.FC<Props> = observer((props) => {
|
|||
}
|
||||
}).map((property) => {
|
||||
if (isEpic && property.key === "sub_issue_count") {
|
||||
return { ...property, title: "Work item count" };
|
||||
return { ...property, titleTranslationKey: "issue.display.properties.work_item_count" };
|
||||
}
|
||||
return property;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ import { useParams } from "next/navigation";
|
|||
// ui
|
||||
import { Tooltip, ControlLink } from "@plane/ui";
|
||||
// components
|
||||
import { findTotalDaysInRange } from "@plane/utils";
|
||||
import { SIDEBAR_WIDTH } from "@/components/gantt-chart/constants";
|
||||
// helpers
|
||||
import { renderFormattedDate } from "@/helpers/date-time.helper";
|
||||
import { generateWorkItemLink } from "@/helpers/issue.helper";
|
||||
// hooks
|
||||
import { useIssueDetail, useIssues, useProject, useProjectState } from "@/hooks/store";
|
||||
|
|
@ -17,6 +17,7 @@ import { usePlatformOS } from "@/hooks/use-platform-os";
|
|||
// plane web components
|
||||
import { IssueIdentifier } from "@/plane-web/components/issues";
|
||||
//
|
||||
import { IssueStats } from "@/plane-web/components/issues/issue-layouts/issue-stats";
|
||||
import { getBlockViewDetails } from "../utils";
|
||||
import { GanttStoreType } from "./base-gantt-root";
|
||||
|
||||
|
|
@ -48,6 +49,8 @@ export const IssueGanttBlock: React.FC<Props> = observer((props) => {
|
|||
|
||||
const handleIssuePeekOverview = () => handleRedirection(workspaceSlug, issueDetails, isMobile);
|
||||
|
||||
const duration = findTotalDaysInRange(issueDetails?.start_date, issueDetails?.target_date) || 0;
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
isMobile={isMobile}
|
||||
|
|
@ -62,17 +65,24 @@ export const IssueGanttBlock: React.FC<Props> = observer((props) => {
|
|||
>
|
||||
<div
|
||||
id={`issue-${issueId}`}
|
||||
className="relative flex h-full w-full cursor-pointer items-center rounded"
|
||||
className="relative flex h-full w-full cursor-pointer items-center rounded space-between"
|
||||
style={blockStyle}
|
||||
onClick={handleIssuePeekOverview}
|
||||
>
|
||||
<div className="absolute left-0 top-0 h-full w-full bg-custom-background-100/50" />
|
||||
<div className="absolute left-0 top-0 h-full w-full bg-custom-background-100/50 " />
|
||||
<div
|
||||
className="sticky w-auto overflow-hidden truncate px-2.5 py-1 text-sm text-custom-text-100"
|
||||
className="sticky w-auto overflow-hidden truncate px-2.5 py-1 text-sm text-custom-text-100 flex-1"
|
||||
style={{ left: `${SIDEBAR_WIDTH}px` }}
|
||||
>
|
||||
{issueDetails?.name}
|
||||
</div>
|
||||
{isEpic && (
|
||||
<IssueStats
|
||||
issueId={issueId}
|
||||
className="sticky mx-2 font-medium text-custom-text-100 overflow-hidden truncate w-auto justify-end flex-shrink-0"
|
||||
showProgressText={duration >= 2}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ import { usePlatformOS } from "@/hooks/use-platform-os";
|
|||
// plane web components
|
||||
import { IssueIdentifier } from "@/plane-web/components/issues";
|
||||
// local components
|
||||
import { IssueStats } from "@/plane-web/components/issues/issue-layouts/issue-stats";
|
||||
import { TRenderQuickActions } from "../list/list-view-types";
|
||||
import { IssueProperties } from "../properties/all-properties";
|
||||
import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC";
|
||||
import { getIssueBlockId } from "../utils";
|
||||
|
||||
interface IssueBlockProps {
|
||||
|
|
@ -61,6 +63,9 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
|
|||
// hooks
|
||||
const { isMobile } = usePlatformOS();
|
||||
|
||||
// derived values
|
||||
const subIssueCount = issue?.sub_issues_count ?? 0;
|
||||
|
||||
const handleEventPropagation = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
|
@ -105,6 +110,16 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
|
|||
isReadOnly={isReadOnly}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
|
||||
{isEpic && displayProperties && (
|
||||
<WithDisplayPropertiesHOC
|
||||
displayProperties={displayProperties}
|
||||
displayPropertyKey="sub_issue_count"
|
||||
shouldRenderProperty={(properties) => !!properties.sub_issue_count && !!subIssueCount}
|
||||
>
|
||||
<IssueStats issueId={issue.id} className="mt-2 font-medium text-custom-text-350" />
|
||||
</WithDisplayPropertiesHOC>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import { usePlatformOS } from "@/hooks/use-platform-os";
|
|||
import { IssueIdentifier } from "@/plane-web/components/issues";
|
||||
import { IssueStats } from "@/plane-web/components/issues/issue-layouts/issue-stats";
|
||||
// types
|
||||
import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC";
|
||||
import { TRenderQuickActions } from "./list-view-types";
|
||||
|
||||
interface IssueBlockProps {
|
||||
|
|
@ -269,7 +270,15 @@ export const IssueBlock = observer((props: IssueBlockProps) => {
|
|||
>
|
||||
<p className="truncate cursor-pointer text-sm text-custom-text-100">{issue.name}</p>
|
||||
</Tooltip>
|
||||
{isEpic && <IssueStats issueId={issue.id} />}
|
||||
{isEpic && displayProperties && (
|
||||
<WithDisplayPropertiesHOC
|
||||
displayProperties={displayProperties}
|
||||
displayPropertyKey="sub_issue_count"
|
||||
shouldRenderProperty={(properties) => !!properties.sub_issue_count}
|
||||
>
|
||||
<IssueStats issueId={issue.id} className="ml-2 font-medium text-custom-text-350" />
|
||||
</WithDisplayPropertiesHOC>
|
||||
)}
|
||||
</div>
|
||||
{!issue?.tempId && (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -429,36 +429,38 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
|||
|
||||
{/* extra render properties */}
|
||||
{/* sub-issues */}
|
||||
<WithDisplayPropertiesHOC
|
||||
displayProperties={displayProperties}
|
||||
displayPropertyKey="sub_issue_count"
|
||||
shouldRenderProperty={(properties) => !!properties.sub_issue_count && !!subIssueCount}
|
||||
>
|
||||
<Tooltip
|
||||
tooltipHeading={isEpic ? t("issues.label", { count: 2 }) : t("common.sub_work_items")}
|
||||
tooltipContent={`${subIssueCount}`}
|
||||
isMobile={isMobile}
|
||||
renderByDefault={false}
|
||||
{!isEpic && (
|
||||
<WithDisplayPropertiesHOC
|
||||
displayProperties={displayProperties}
|
||||
displayPropertyKey="sub_issue_count"
|
||||
shouldRenderProperty={(properties) => !!properties.sub_issue_count && !!subIssueCount}
|
||||
>
|
||||
<div
|
||||
onFocus={handleEventPropagation}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (subIssueCount) redirectToIssueDetail();
|
||||
}}
|
||||
className={cn(
|
||||
"flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1",
|
||||
{
|
||||
"hover:bg-custom-background-80 cursor-pointer": subIssueCount,
|
||||
}
|
||||
)}
|
||||
<Tooltip
|
||||
tooltipHeading={t("common.sub_work_items")}
|
||||
tooltipContent={`${subIssueCount}`}
|
||||
isMobile={isMobile}
|
||||
renderByDefault={false}
|
||||
>
|
||||
<Layers className="h-3 w-3 flex-shrink-0" strokeWidth={2} />
|
||||
<div className="text-xs">{subIssueCount}</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</WithDisplayPropertiesHOC>
|
||||
<div
|
||||
onFocus={handleEventPropagation}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (subIssueCount) redirectToIssueDetail();
|
||||
}}
|
||||
className={cn(
|
||||
"flex h-5 flex-shrink-0 items-center justify-center gap-2 overflow-hidden rounded border-[0.5px] border-custom-border-300 px-2.5 py-1",
|
||||
{
|
||||
"hover:bg-custom-background-80 cursor-pointer": subIssueCount,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Layers className="h-3 w-3 flex-shrink-0" strokeWidth={2} />
|
||||
<div className="text-xs">{subIssueCount}</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</WithDisplayPropertiesHOC>
|
||||
)}
|
||||
|
||||
{/* attachments */}
|
||||
<WithDisplayPropertiesHOC
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { Row } from "@plane/ui";
|
|||
import { cn } from "@/helpers/common.helper";
|
||||
// hooks
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
import { IssueStats } from "@/plane-web/components/issues/issue-layouts/issue-stats";
|
||||
|
||||
type Props = {
|
||||
issue: TIssue;
|
||||
|
|
@ -18,30 +19,30 @@ export const SpreadsheetSubIssueColumn: React.FC<Props> = observer((props: Props
|
|||
// router
|
||||
const router = useAppRouter();
|
||||
// hooks
|
||||
const { workspaceSlug, epicId } = useParams();
|
||||
const { workspaceSlug } = useParams();
|
||||
// derived values
|
||||
const isEpic = issue?.is_epic;
|
||||
const subIssueCount = issue?.sub_issues_count ?? 0;
|
||||
|
||||
const redirectToIssueDetail = () => {
|
||||
router.push(
|
||||
`/${workspaceSlug?.toString()}/projects/${issue.project_id}/${issue.archived_at ? "archives/" : ""}${epicId ? "epics" : "issues"}/${issue.id}#sub-issues`
|
||||
`/${workspaceSlug?.toString()}/projects/${issue.project_id}/${issue.archived_at ? "archives/" : ""}${isEpic ? "epics" : "issues"}/${issue.id}#sub-issues`
|
||||
);
|
||||
};
|
||||
|
||||
const issueLabel = epicId ? "work item" : "sub-work item";
|
||||
const label = `${subIssueCount} ${issueLabel}${subIssueCount !== 1 ? "s" : ""}`;
|
||||
const label = `${subIssueCount} sub-work item${subIssueCount !== 1 ? "s" : ""}`;
|
||||
|
||||
return (
|
||||
<Row
|
||||
onClick={subIssueCount ? redirectToIssueDetail : () => {}}
|
||||
className={cn(
|
||||
"flex h-11 w-full items-center border-b-[0.5px] border-custom-border-200 py-1 text-xs hover:bg-custom-background-80 group-[.selected-issue-row]:bg-custom-primary-100/5 group-[.selected-issue-row]:hover:bg-custom-primary-100/10",
|
||||
"flex h-11 w-full items-center border-b-[0.5px] border-custom-border-200 py-1 text-xs hover:bg-custom-background-90 group-[.selected-issue-row]:bg-custom-primary-100/5 group-[.selected-issue-row]:hover:bg-custom-primary-90",
|
||||
{
|
||||
"cursor-pointer": subIssueCount,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
{isEpic ? <IssueStats issueId={issue.id} /> : label}
|
||||
</Row>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue