Files
plane/apps/web/ce/components/issues/issue-details/issue-identifier.tsx
chuan bba4bb40c8
Some checks failed
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
feat: init
2025-11-11 01:56:44 +08:00

106 lines
3.3 KiB
TypeScript

import type { FC } from "react";
import { observer } from "mobx-react";
// types
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import type { IIssueDisplayProperties } from "@plane/types";
// ui
// helpers
import { cn } from "@plane/utils";
// hooks
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import { useProject } from "@/hooks/store/use-project";
type TIssueIdentifierBaseProps = {
projectId: string;
size?: "xs" | "sm" | "md" | "lg";
textContainerClassName?: string;
displayProperties?: IIssueDisplayProperties | undefined;
enableClickToCopyIdentifier?: boolean;
};
type TIssueIdentifierFromStore = TIssueIdentifierBaseProps & {
issueId: string;
};
type TIssueIdentifierWithDetails = TIssueIdentifierBaseProps & {
issueTypeId?: string | null;
projectIdentifier: string;
issueSequenceId: string | number;
};
export type TIssueIdentifierProps = TIssueIdentifierFromStore | TIssueIdentifierWithDetails;
type TIssueTypeIdentifier = {
issueTypeId: string;
size?: "xs" | "sm" | "md" | "lg";
};
export const IssueTypeIdentifier: FC<TIssueTypeIdentifier> = observer((props) => <></>);
type TIdentifierTextProps = {
identifier: string;
enableClickToCopyIdentifier?: boolean;
textContainerClassName?: string;
};
export const IdentifierText: React.FC<TIdentifierTextProps> = (props) => {
const { identifier, enableClickToCopyIdentifier = false, textContainerClassName } = props;
// handlers
const handleCopyIssueIdentifier = () => {
if (enableClickToCopyIdentifier) {
navigator.clipboard.writeText(identifier).then(() => {
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Work item ID copied to clipboard",
});
});
}
};
return (
<Tooltip tooltipContent="Click to copy" disabled={!enableClickToCopyIdentifier} position="top">
<span
className={cn(
"text-base font-medium text-custom-text-300",
{
"cursor-pointer": enableClickToCopyIdentifier,
},
textContainerClassName
)}
onClick={handleCopyIssueIdentifier}
>
{identifier}
</span>
</Tooltip>
);
};
export const IssueIdentifier: React.FC<TIssueIdentifierProps> = observer((props) => {
const { projectId, textContainerClassName, displayProperties, enableClickToCopyIdentifier = false } = props;
// store hooks
const { getProjectIdentifierById } = useProject();
const {
issue: { getIssueById },
} = useIssueDetail();
// Determine if the component is using store data or not
const isUsingStoreData = "issueId" in props;
// derived values
const issue = isUsingStoreData ? getIssueById(props.issueId) : null;
const projectIdentifier = isUsingStoreData ? getProjectIdentifierById(projectId) : props.projectIdentifier;
const issueSequenceId = isUsingStoreData ? issue?.sequence_id : props.issueSequenceId;
const shouldRenderIssueID = displayProperties ? displayProperties.key : true;
if (!shouldRenderIssueID) return null;
return (
<div className="flex items-center space-x-2">
<IdentifierText
identifier={`${projectIdentifier}-${issueSequenceId}`}
enableClickToCopyIdentifier={enableClickToCopyIdentifier}
textContainerClassName={textContainerClassName}
/>
</div>
);
});