forked from github/plane
chore: ui component revamp (#2415)
* chore: swap tooltip component with plane ui package * chore: swap linear progress component with plane ui package * fix: login button fix
This commit is contained in:
parent
d58d639190
commit
67b28214d0
@ -31,7 +31,10 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blueprintjs/core": "^4.16.3",
|
||||
"@blueprintjs/popover2": "^1.13.3",
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"clsx": "^2.0.0"
|
||||
"clsx": "^2.0.0",
|
||||
"next-themes": "^0.2.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { getIconStyling, getButtonStyling, TButtonVariant } from "./helper";
|
||||
import {
|
||||
getIconStyling,
|
||||
getButtonStyling,
|
||||
TButtonVariant,
|
||||
TButtonSizes,
|
||||
} from "./helper";
|
||||
|
||||
export interface ButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: TButtonVariant;
|
||||
size?: "sm" | "md" | "lg";
|
||||
size?: TButtonSizes;
|
||||
className?: string;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
|
@ -10,7 +10,7 @@ export type TButtonVariant =
|
||||
| "link-danger"
|
||||
| "tertiary-danger";
|
||||
|
||||
export type TButtonSizes = "sm" | "md" | "lg";
|
||||
export type TButtonSizes = "sm" | "md" | "lg" | "xl";
|
||||
|
||||
export interface IButtonStyling {
|
||||
[key: string]: {
|
||||
@ -24,13 +24,15 @@ export interface IButtonStyling {
|
||||
enum buttonSizeStyling {
|
||||
sm = `px-3 py-1.5 font-medium text-xs rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||
md = `px-4 py-1.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||
lg = `px-5 py-2 font-medium text-base rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||
lg = `px-5 py-2 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||
xl = `px-5 py-3.5 font-medium text-sm rounded flex items-center gap-1.5 whitespace-nowrap transition-all justify-center inline`,
|
||||
}
|
||||
|
||||
enum buttonIconStyling {
|
||||
sm = "h-3 w-3 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
|
||||
md = "h-3.5 w-3.5 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
|
||||
lg = "h-4 w-4 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
|
||||
xl = "h-4 w-4 flex justify-center items-center overflow-hidden my-0.5 flex-shrink-0",
|
||||
}
|
||||
|
||||
export const buttonStyling: IButtonStyling = {
|
||||
@ -110,16 +112,12 @@ export const getButtonStyling = (
|
||||
} ${currentVariant.pressed}`;
|
||||
|
||||
let _size: string = ``;
|
||||
if (size === "sm") _size = buttonSizeStyling["sm"];
|
||||
if (size === "md") _size = buttonSizeStyling["md"];
|
||||
if (size === "lg") _size = buttonSizeStyling["lg"];
|
||||
if (size) _size = buttonSizeStyling[size];
|
||||
return `${_variant} ${_size}`;
|
||||
};
|
||||
|
||||
export const getIconStyling = (size: TButtonSizes): string => {
|
||||
let icon: string = ``;
|
||||
if (size === "sm") icon = buttonIconStyling["sm"];
|
||||
if (size === "md") icon = buttonIconStyling["md"];
|
||||
if (size === "lg") icon = buttonIconStyling["lg"];
|
||||
if (size) icon = buttonIconStyling[size];
|
||||
return icon;
|
||||
};
|
||||
|
@ -3,3 +3,4 @@ export * from "./form-fields";
|
||||
export * from "./progress";
|
||||
export * from "./spinners";
|
||||
export * from "./loader";
|
||||
export * from "./tooltip";
|
||||
|
@ -1,2 +1,3 @@
|
||||
export * from "./radial-progress";
|
||||
export * from "./progress-bar";
|
||||
export * from "./linear-progress-indicator";
|
||||
|
44
packages/ui/src/progress/linear-progress-indicator.tsx
Normal file
44
packages/ui/src/progress/linear-progress-indicator.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
import { Tooltip } from "../tooltip";
|
||||
|
||||
type Props = {
|
||||
data: any;
|
||||
noTooltip?: boolean;
|
||||
};
|
||||
|
||||
export const LinearProgressIndicator: React.FC<Props> = ({
|
||||
data,
|
||||
noTooltip = false,
|
||||
}) => {
|
||||
const total = data.reduce((acc: any, cur: any) => acc + cur.value, 0);
|
||||
let progress = 0;
|
||||
|
||||
const bars = data.map((item: any) => {
|
||||
const width = `${(item.value / total) * 100}%`;
|
||||
const style = {
|
||||
width,
|
||||
backgroundColor: item.color,
|
||||
};
|
||||
progress += item.value;
|
||||
if (noTooltip) return <div style={style} />;
|
||||
else
|
||||
return (
|
||||
<Tooltip
|
||||
key={item.id}
|
||||
tooltipContent={`${item.name} ${Math.round(item.value)}%`}
|
||||
>
|
||||
<div style={style} />
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex h-1 w-full items-center justify-between gap-1">
|
||||
{total === 0 ? (
|
||||
<div className="flex h-full w-full gap-1 bg-neutral-500">{bars}</div>
|
||||
) : (
|
||||
<div className="flex h-full w-full gap-1">{bars}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
1
packages/ui/src/tooltip/index.tsx
Normal file
1
packages/ui/src/tooltip/index.tsx
Normal file
@ -0,0 +1 @@
|
||||
export * from "./tooltip";
|
86
packages/ui/src/tooltip/tooltip.tsx
Normal file
86
packages/ui/src/tooltip/tooltip.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import React from "react";
|
||||
|
||||
// next-themes
|
||||
import { useTheme } from "next-themes";
|
||||
import { Tooltip2 } from "@blueprintjs/popover2";
|
||||
|
||||
export type TPosition =
|
||||
| "top"
|
||||
| "right"
|
||||
| "bottom"
|
||||
| "left"
|
||||
| "auto"
|
||||
| "auto-end"
|
||||
| "auto-start"
|
||||
| "bottom-left"
|
||||
| "bottom-right"
|
||||
| "left-bottom"
|
||||
| "left-top"
|
||||
| "right-bottom"
|
||||
| "right-top"
|
||||
| "top-left"
|
||||
| "top-right";
|
||||
|
||||
interface ITooltipProps {
|
||||
tooltipHeading?: string;
|
||||
tooltipContent: string | React.ReactNode;
|
||||
position?: TPosition;
|
||||
children: JSX.Element;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
openDelay?: number;
|
||||
closeDelay?: number;
|
||||
}
|
||||
|
||||
export const Tooltip: React.FC<ITooltipProps> = ({
|
||||
tooltipHeading,
|
||||
tooltipContent,
|
||||
position = "top",
|
||||
children,
|
||||
disabled = false,
|
||||
className = "",
|
||||
openDelay = 200,
|
||||
closeDelay,
|
||||
}) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<Tooltip2
|
||||
disabled={disabled}
|
||||
hoverOpenDelay={openDelay}
|
||||
hoverCloseDelay={closeDelay}
|
||||
content={
|
||||
<div
|
||||
className={`relative z-50 max-w-xs gap-1 rounded-md p-2 text-xs shadow-md ${
|
||||
theme === "custom"
|
||||
? "bg-custom-background-100 text-custom-text-200"
|
||||
: "bg-black text-gray-400"
|
||||
} break-words overflow-hidden ${className}`}
|
||||
>
|
||||
{tooltipHeading && (
|
||||
<h5
|
||||
className={`font-medium ${
|
||||
theme === "custom" ? "text-custom-text-100" : "text-white"
|
||||
}`}
|
||||
>
|
||||
{tooltipHeading}
|
||||
</h5>
|
||||
)}
|
||||
{tooltipContent}
|
||||
</div>
|
||||
}
|
||||
position={position}
|
||||
renderTarget={({
|
||||
isOpen: isTooltipOpen,
|
||||
ref: eleReference,
|
||||
...tooltipProps
|
||||
}) =>
|
||||
React.cloneElement(children, {
|
||||
ref: eleReference,
|
||||
...tooltipProps,
|
||||
...children.props,
|
||||
})
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
@ -212,7 +212,7 @@ export const EmailCodeForm = ({ handleSignIn }: any) => {
|
||||
<Button
|
||||
variant="primary"
|
||||
className="w-full"
|
||||
size="md"
|
||||
size="xl"
|
||||
onClick={() => {
|
||||
handleSubmit(onSubmit)().then(() => {
|
||||
setResendCodeTimer(30);
|
||||
|
@ -26,8 +26,8 @@ import {
|
||||
commandGroups,
|
||||
} from "components/command-palette";
|
||||
// ui
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Loader, ToggleSwitch } from "@plane/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import { Loader, ToggleSwitch, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { DiscordIcon, GithubIcon, SettingIcon } from "components/icons";
|
||||
import { InboxIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
|
@ -7,7 +7,8 @@ import useEstimateOption from "hooks/use-estimate-option";
|
||||
// services
|
||||
import issuesService from "services/issue.service";
|
||||
// icons
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import {
|
||||
TagIcon,
|
||||
CopyPlus,
|
||||
|
@ -11,8 +11,8 @@ import useEstimateOption from "hooks/use-estimate-option";
|
||||
// components
|
||||
import { SelectFilters } from "components/views";
|
||||
// ui
|
||||
import { CustomMenu, Tooltip } from "components/ui";
|
||||
import { ToggleSwitch } from "@plane/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { ToggleSwitch, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||
import {
|
||||
|
@ -13,8 +13,7 @@ import useToast from "hooks/use-toast";
|
||||
import useIssuesView from "hooks/use-issues-view";
|
||||
import useDebounce from "hooks/use-debounce";
|
||||
// ui
|
||||
import { Button, Loader, ToggleSwitch } from "@plane/ui";
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Button, Loader, ToggleSwitch, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { LaunchOutlined } from "@mui/icons-material";
|
||||
import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
|
@ -17,7 +17,8 @@ import { ViewDueDateSelect, ViewEstimateSelect, ViewStartDateSelect } from "comp
|
||||
import { MembersSelect, LabelSelect, PrioritySelect } from "components/project";
|
||||
import { StateSelect } from "components/states";
|
||||
// ui
|
||||
import { ContextMenu, CustomMenu, Tooltip } from "components/ui";
|
||||
import { ContextMenu, CustomMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import {
|
||||
ClipboardDocumentCheckIcon,
|
||||
|
@ -13,10 +13,11 @@ import trackEventServices from "services/track_event.service";
|
||||
import useIssuesProperties from "hooks/use-issue-properties";
|
||||
import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { CustomMenu, Tooltip } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { ViewDueDateSelect, ViewEstimateSelect, ViewStartDateSelect } from "components/issues";
|
||||
import { LabelSelect, MembersSelect, PrioritySelect } from "components/project";
|
||||
import { StateSelect } from "components/states";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { LinkIcon, PaperClipIcon, PencilIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
|
@ -14,7 +14,8 @@ import { ViewDueDateSelect, ViewEstimateSelect, ViewStartDateSelect } from "comp
|
||||
import { LabelSelect, MembersSelect, PrioritySelect } from "components/project";
|
||||
import { StateSelect } from "components/states";
|
||||
// ui
|
||||
import { Tooltip, CustomMenu, ContextMenu } from "components/ui";
|
||||
import { CustomMenu, ContextMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import {
|
||||
ClipboardDocumentCheckIcon,
|
||||
|
@ -10,10 +10,9 @@ import cyclesService from "services/cycles.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { LinearProgressIndicator, Tooltip } from "components/ui";
|
||||
import { AssigneesList } from "components/ui/avatar";
|
||||
import { SingleProgressStats } from "components/core";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Loader, Tooltip, LinearProgressIndicator } from "@plane/ui";
|
||||
// components
|
||||
import ProgressChart from "components/core/sidebar/progress-chart";
|
||||
import { ActiveCycleProgressStats } from "components/cycles";
|
||||
|
@ -7,9 +7,9 @@ import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { SingleProgressStats } from "components/core";
|
||||
// ui
|
||||
import { CustomMenu, LinearProgressIndicator, Tooltip } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { AssigneesList } from "components/ui/avatar";
|
||||
import { RadialProgressBar } from "@plane/ui";
|
||||
import { RadialProgressBar, Tooltip, LinearProgressIndicator } from "@plane/ui";
|
||||
// icons
|
||||
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
|
||||
import {
|
||||
|
@ -4,8 +4,8 @@ import { useRouter } from "next/router";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { RadialProgressBar } from "@plane/ui";
|
||||
import { CustomMenu, LinearProgressIndicator, Tooltip } from "components/ui";
|
||||
import { RadialProgressBar, Tooltip, LinearProgressIndicator } from "@plane/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
// icons
|
||||
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
|
||||
import {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { ContrastIcon } from "components/icons";
|
||||
// helpers
|
||||
@ -44,9 +44,7 @@ export const CycleGanttBlock = ({ data }: { data: ICycle }) => {
|
||||
}
|
||||
position="top-left"
|
||||
>
|
||||
<div className="relative text-custom-text-100 text-sm truncate py-1 px-2.5 w-full">
|
||||
{data?.name}
|
||||
</div>
|
||||
<div className="relative text-custom-text-100 text-sm truncate py-1 px-2.5 w-full">{data?.name}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
|
@ -10,7 +10,8 @@ import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { SingleProgressStats } from "components/core";
|
||||
// ui
|
||||
import { CustomMenu, LinearProgressIndicator, Tooltip } from "components/ui";
|
||||
import { Tooltip, LinearProgressIndicator } from "@plane/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { AssigneesList } from "components/ui/avatar";
|
||||
// icons
|
||||
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
|
||||
@ -22,19 +23,9 @@ import {
|
||||
TriangleExclamationIcon,
|
||||
AlarmClockIcon,
|
||||
} from "components/icons";
|
||||
import {
|
||||
ChevronDownIcon,
|
||||
LinkIcon,
|
||||
PencilIcon,
|
||||
StarIcon,
|
||||
TrashIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { ChevronDownIcon, LinkIcon, PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
// helpers
|
||||
import {
|
||||
getDateRangeStatus,
|
||||
renderShortDateWithYearFormat,
|
||||
findHowManyDaysLeft,
|
||||
} from "helpers/date-time.helper";
|
||||
import { getDateRangeStatus, renderShortDateWithYearFormat, findHowManyDaysLeft } from "helpers/date-time.helper";
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
// types
|
||||
import { ICycle } from "types";
|
||||
@ -93,12 +84,9 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
const startDate = new Date(cycle.start_date ?? "");
|
||||
|
||||
const handleCopyText = () => {
|
||||
const originURL =
|
||||
typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
|
||||
copyTextToClipboard(
|
||||
`${originURL}/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`
|
||||
).then(() => {
|
||||
copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Link Copied!",
|
||||
@ -110,10 +98,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
const progressIndicatorData = stateGroups.map((group, index) => ({
|
||||
id: index,
|
||||
name: group.title,
|
||||
value:
|
||||
cycle.total_issues > 0
|
||||
? ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100
|
||||
: 0,
|
||||
value: cycle.total_issues > 0 ? ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100 : 0,
|
||||
color: group.color,
|
||||
}));
|
||||
|
||||
@ -150,9 +135,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
/>
|
||||
</span>
|
||||
<Tooltip tooltipContent={cycle.name} className="break-words" position="top-left">
|
||||
<h3 className="break-words text-lg font-semibold">
|
||||
{truncateText(cycle.name, 15)}
|
||||
</h3>
|
||||
<h3 className="break-words text-lg font-semibold">{truncateText(cycle.name, 15)}</h3>
|
||||
</Tooltip>
|
||||
</span>
|
||||
<span className="flex items-center gap-1 capitalize">
|
||||
@ -184,9 +167,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
<span className="flex gap-1 whitespace-nowrap">
|
||||
{cycle.total_issues - cycle.completed_issues > 0 && (
|
||||
<Tooltip
|
||||
tooltipContent={`${
|
||||
cycle.total_issues - cycle.completed_issues
|
||||
} more pending ${
|
||||
tooltipContent={`${cycle.total_issues - cycle.completed_issues} more pending ${
|
||||
cycle.total_issues - cycle.completed_issues === 1 ? "issue" : "issues"
|
||||
}`}
|
||||
>
|
||||
@ -357,10 +338,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
</Tooltip>
|
||||
<Disclosure.Button>
|
||||
<span className="p-1">
|
||||
<ChevronDownIcon
|
||||
className={`h-3 w-3 ${open ? "rotate-180 transform" : ""}`}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<ChevronDownIcon className={`h-3 w-3 ${open ? "rotate-180 transform" : ""}`} aria-hidden="true" />
|
||||
</span>
|
||||
</Disclosure.Button>
|
||||
</div>
|
||||
@ -370,10 +348,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
<div className="col-span-2 space-y-3 px-4">
|
||||
<div className="space-y-3 text-xs">
|
||||
{stateGroups.map((group) => (
|
||||
<div
|
||||
key={group.key}
|
||||
className="flex items-center justify-between gap-2"
|
||||
>
|
||||
<div key={group.key} className="flex items-center justify-between gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
className="block h-2 w-2 rounded-full"
|
||||
@ -390,9 +365,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
-{" "}
|
||||
{cycle.total_issues > 0
|
||||
? `${Math.round(
|
||||
((cycle[group.key as keyof ICycle] as number) /
|
||||
cycle.total_issues) *
|
||||
100
|
||||
((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100
|
||||
)}%`
|
||||
: "0%"}
|
||||
</span>
|
||||
|
@ -6,7 +6,8 @@ import { useRouter } from "next/router";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { CustomMenu, LinearProgressIndicator, Tooltip } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { Tooltip, LinearProgressIndicator } from "@plane/ui";
|
||||
// icons
|
||||
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
|
||||
import {
|
||||
@ -19,11 +20,7 @@ import {
|
||||
} from "components/icons";
|
||||
import { LinkIcon, PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
// helpers
|
||||
import {
|
||||
getDateRangeStatus,
|
||||
renderShortDateWithYearFormat,
|
||||
findHowManyDaysLeft,
|
||||
} from "helpers/date-time.helper";
|
||||
import { getDateRangeStatus, renderShortDateWithYearFormat, findHowManyDaysLeft } from "helpers/date-time.helper";
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
// types
|
||||
import { ICycle } from "types";
|
||||
@ -125,12 +122,9 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
const startDate = new Date(cycle.start_date ?? "");
|
||||
|
||||
const handleCopyText = () => {
|
||||
const originURL =
|
||||
typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
|
||||
copyTextToClipboard(
|
||||
`${originURL}/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`
|
||||
).then(() => {
|
||||
copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Link Copied!",
|
||||
@ -142,10 +136,7 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
const progressIndicatorData = stateGroups.map((group, index) => ({
|
||||
id: index,
|
||||
name: group.title,
|
||||
value:
|
||||
cycle.total_issues > 0
|
||||
? ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100
|
||||
: 0,
|
||||
value: cycle.total_issues > 0 ? ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100 : 0,
|
||||
color: group.color,
|
||||
}));
|
||||
|
||||
@ -176,18 +167,10 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
}`}
|
||||
/>
|
||||
<div className="max-w-2xl">
|
||||
<Tooltip
|
||||
tooltipContent={cycle.name}
|
||||
className="break-words"
|
||||
position="top-left"
|
||||
>
|
||||
<h3 className="break-words w-full text-base font-semibold">
|
||||
{truncateText(cycle.name, 60)}
|
||||
</h3>
|
||||
<Tooltip tooltipContent={cycle.name} className="break-words" position="top-left">
|
||||
<h3 className="break-words w-full text-base font-semibold">{truncateText(cycle.name, 60)}</h3>
|
||||
</Tooltip>
|
||||
<p className="mt-2 text-custom-text-200 break-words w-full">
|
||||
{cycle.description}
|
||||
</p>
|
||||
<p className="mt-2 text-custom-text-200 break-words w-full">{cycle.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-shrink-0 flex items-center gap-4">
|
||||
@ -219,9 +202,7 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
<span className="flex items-center gap-1">
|
||||
{cycle.total_issues - cycle.completed_issues > 0 && (
|
||||
<Tooltip
|
||||
tooltipContent={`${
|
||||
cycle.total_issues - cycle.completed_issues
|
||||
} more pending ${
|
||||
tooltipContent={`${cycle.total_issues - cycle.completed_issues} more pending ${
|
||||
cycle.total_issues - cycle.completed_issues === 1 ? "issue" : "issues"
|
||||
}`}
|
||||
>
|
||||
@ -293,12 +274,8 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
<span className="flex gap-1 whitespace-nowrap">
|
||||
{cycle.total_issues > 0 ? (
|
||||
<>
|
||||
<RadialProgressBar
|
||||
progress={(cycle.completed_issues / cycle.total_issues) * 100}
|
||||
/>
|
||||
<span>
|
||||
{Math.floor((cycle.completed_issues / cycle.total_issues) * 100)} %
|
||||
</span>
|
||||
<RadialProgressBar progress={(cycle.completed_issues / cycle.total_issues) * 100} />
|
||||
<span>{Math.floor((cycle.completed_issues / cycle.total_issues) * 100)} %</span>
|
||||
</>
|
||||
) : (
|
||||
<span className="normal-case">No issues present</span>
|
||||
@ -315,9 +292,7 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
</span>
|
||||
) : (
|
||||
<span className="flex gap-1">
|
||||
<RadialProgressBar
|
||||
progress={(cycle.total_issues / cycle.completed_issues) * 100}
|
||||
/>
|
||||
<RadialProgressBar progress={(cycle.total_issues / cycle.completed_issues) * 100} />
|
||||
{cycleStatus}
|
||||
</span>
|
||||
)}
|
||||
|
@ -10,8 +10,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection } from "components/issues";
|
||||
import { CreateUpdateWorkspaceViewModal } from "components/workspace";
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Button } from "@plane/ui";
|
||||
import { Button, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { List, PlusIcon, Sheet } from "lucide-react";
|
||||
// types
|
||||
|
@ -2,7 +2,7 @@ import { useRouter } from "next/router";
|
||||
import Link from "next/link";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { PriorityIcon } from "components/icons";
|
||||
import {
|
||||
@ -34,9 +34,7 @@ export const InboxIssueCard: React.FC<Props> = (props) => {
|
||||
const issueStatus = issue.issue_inbox[0].status;
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={`/${workspaceSlug}/projects/${projectId}/inbox/${inboxId}?inboxIssueId=${issue.bridge_id}`}
|
||||
>
|
||||
<Link href={`/${workspaceSlug}/projects/${projectId}/inbox/${inboxId}?inboxIssueId=${issue.bridge_id}`}>
|
||||
<a>
|
||||
<div
|
||||
id={issue.id}
|
||||
@ -99,9 +97,7 @@ export const InboxIssueCard: React.FC<Props> = (props) => {
|
||||
<>
|
||||
<ClockIcon className="h-3.5 w-3.5" />
|
||||
<span>
|
||||
{new Date(issue.issue_inbox[0].snoozed_till ?? "") < new Date()
|
||||
? "Snoozed date passed"
|
||||
: "Snoozed"}
|
||||
{new Date(issue.issue_inbox[0].snoozed_till ?? "") < new Date() ? "Snoozed date passed" : "Snoozed"}
|
||||
</span>
|
||||
</>
|
||||
) : issueStatus === 1 ? (
|
||||
|
@ -15,7 +15,8 @@ import {
|
||||
PaperClipIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
// components
|
||||
import { Tooltip, CustomMenu, ContextMenu } from "components/ui";
|
||||
import { CustomMenu, ContextMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
import {
|
||||
ViewAssigneeSelect,
|
||||
|
@ -7,8 +7,8 @@ import { useRouter } from "next/router";
|
||||
import { ActivityIcon, ActivityMessage } from "components/core";
|
||||
import { CommentCard } from "components/issues/comment";
|
||||
// ui
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import { Loader, Tooltip } from "@plane/ui";
|
||||
// helpers
|
||||
import { render24HourFormatTime, renderLongDateFormat, timeAgo } from "helpers/date-time.helper";
|
||||
// types
|
||||
|
@ -6,7 +6,7 @@ import { useRouter } from "next/router";
|
||||
import useSWR from "swr";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import { DeleteAttachmentModal } from "./delete-attachment-modal";
|
||||
// icons
|
||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||
|
@ -5,8 +5,8 @@ import { useForm, Controller } from "react-hook-form";
|
||||
// components
|
||||
import { TipTapEditor } from "components/tiptap";
|
||||
// ui
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Button } from "@plane/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import { Button, Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import type { IIssueComment } from "types";
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import { TIssueLayouts } from "types";
|
||||
// constants
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { StateGroupIcon } from "components/icons";
|
||||
// helpers
|
||||
@ -33,16 +33,13 @@ export const IssueGanttBlock = ({ data }: { data: IIssue }) => {
|
||||
<div className="space-y-1">
|
||||
<h5>{data?.name}</h5>
|
||||
<div>
|
||||
{renderShortDate(data?.start_date ?? "")} to{" "}
|
||||
{renderShortDate(data?.target_date ?? "")}
|
||||
{renderShortDate(data?.start_date ?? "")} to {renderShortDate(data?.target_date ?? "")}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
position="top-left"
|
||||
>
|
||||
<div className="relative text-custom-text-100 text-sm truncate py-1 px-2.5 w-full">
|
||||
{data?.name}
|
||||
</div>
|
||||
<div className="relative text-custom-text-100 text-sm truncate py-1 px-2.5 w-full">{data?.name}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
@ -62,10 +59,7 @@ export const IssueGanttSidebarBlock = ({ data }: { data: IIssue }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative w-full flex items-center gap-2 h-full cursor-pointer"
|
||||
onClick={openPeekOverview}
|
||||
>
|
||||
<div className="relative w-full flex items-center gap-2 h-full cursor-pointer" onClick={openPeekOverview}>
|
||||
<StateGroupIcon stateGroup={data?.state_detail?.group} color={data?.state_detail?.color} />
|
||||
<div className="text-xs text-custom-text-300 flex-shrink-0">
|
||||
{data?.project_detail?.identifier} {data?.sequence_id}
|
||||
|
@ -9,7 +9,7 @@ import { IssuePropertyLabels } from "../properties/labels";
|
||||
import { IssuePropertyAssignee } from "../properties/assignee";
|
||||
import { IssuePropertyEstimates } from "../properties/estimates";
|
||||
import { IssuePropertyStartDate } from "../properties/date";
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
|
||||
export interface IKanBanProperties {
|
||||
sub_group_id: string;
|
||||
|
@ -9,7 +9,7 @@ import { IssuePropertyLabels } from "../properties/labels";
|
||||
import { IssuePropertyAssignee } from "../properties/assignee";
|
||||
import { IssuePropertyEstimates } from "../properties/estimates";
|
||||
import { IssuePropertyStartDate } from "../properties/date";
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
|
||||
export interface IKanBanProperties {
|
||||
columnId: string;
|
||||
|
@ -6,7 +6,7 @@ import { ChevronDown, Search, X, Check } from "lucide-react";
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown";
|
||||
// mobx
|
||||
|
@ -8,7 +8,7 @@ import DatePicker from "react-datepicker";
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown";
|
||||
// helpers
|
||||
|
@ -6,7 +6,7 @@ import { ChevronDown, Search, X, Check, Triangle } from "lucide-react";
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown";
|
||||
// mobx
|
||||
|
@ -6,7 +6,7 @@ import { ChevronDown, Search, X, Check } from "lucide-react";
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown";
|
||||
// mobx
|
||||
|
@ -6,7 +6,7 @@ import { ChevronDown, Search, X, Check, AlertCircle, SignalHigh, SignalMedium, S
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown";
|
||||
// constants
|
||||
|
@ -6,7 +6,7 @@ import { ChevronDown, Search, X, Check } from "lucide-react";
|
||||
// mobx
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import { StateGroupIcon } from "components/icons";
|
||||
// hooks
|
||||
import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
|
||||
@ -36,11 +36,7 @@ export const ViewIssueLabel: React.FC<Props> = ({ labelDetails, maxRender = 1 })
|
||||
</>
|
||||
) : (
|
||||
<div className="flex cursor-default items-center flex-shrink-0 rounded-md border border-custom-border-300 px-2.5 py-1 text-xs shadow-sm">
|
||||
<Tooltip
|
||||
position="top"
|
||||
tooltipHeading="Labels"
|
||||
tooltipContent={labelDetails.map((l) => l.name).join(", ")}
|
||||
>
|
||||
<Tooltip position="top" tooltipHeading="Labels" tooltipContent={labelDetails.map((l) => l.name).join(", ")}>
|
||||
<div className="flex items-center gap-1.5 text-custom-text-200">
|
||||
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-custom-primary" />
|
||||
{`${labelDetails.length} Labels`}
|
||||
|
@ -7,7 +7,7 @@ import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter";
|
||||
// components
|
||||
import { MyIssuesSelectFilters } from "components/issues";
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { FormatListBulletedOutlined } from "@mui/icons-material";
|
||||
import { CreditCard } from "lucide-react";
|
||||
|
@ -11,8 +11,7 @@ import useDebounce from "hooks/use-debounce";
|
||||
// components
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Loader, ToggleSwitch } from "@plane/ui";
|
||||
import { Loader, ToggleSwitch, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { LaunchOutlined } from "@mui/icons-material";
|
||||
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
|
@ -8,8 +8,8 @@ import useSWR, { mutate } from "swr";
|
||||
import issuesService from "services/issue.service";
|
||||
import cyclesService from "services/cycles.service";
|
||||
// ui
|
||||
import { CustomSelect, Tooltip } from "components/ui";
|
||||
import { Spinner } from "@plane/ui";
|
||||
import { CustomSelect } from "components/ui";
|
||||
import { Spinner, Tooltip } from "@plane/ui";
|
||||
// helper
|
||||
import { truncateText } from "helpers/string.helper";
|
||||
// types
|
||||
|
@ -7,8 +7,8 @@ import useSWR, { mutate } from "swr";
|
||||
// services
|
||||
import modulesService from "services/modules.service";
|
||||
// ui
|
||||
import { CustomSelect, Tooltip } from "components/ui";
|
||||
import { Spinner } from "@plane/ui";
|
||||
import { CustomSelect } from "components/ui";
|
||||
import { Spinner, Tooltip } from "@plane/ui";
|
||||
// helper
|
||||
import { truncateText } from "helpers/string.helper";
|
||||
// types
|
||||
|
@ -10,7 +10,8 @@ import { IssuePeekOverview } from "components/issues/peek-overview";
|
||||
import { SubIssuesRootList } from "./issues-list";
|
||||
import { IssueProperty } from "./properties";
|
||||
// ui
|
||||
import { Tooltip, CustomMenu } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import { ICurrentUserResponse, IIssue } from "types";
|
||||
import { ISubIssuesRootLoaders, ISubIssuesRootLoadersHandler } from "./root";
|
||||
|
@ -8,7 +8,8 @@ import useSWR from "swr";
|
||||
import projectService from "services/project.service";
|
||||
import trackEventServices from "services/track_event.service";
|
||||
// ui
|
||||
import { AssigneesList, Avatar, CustomSearchSelect, Icon, Tooltip } from "components/ui";
|
||||
import { AssigneesList, Avatar, CustomSearchSelect, Icon } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { UserGroupIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// ui
|
||||
import { CustomDatePicker, Tooltip } from "components/ui";
|
||||
import { CustomDatePicker } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// helpers
|
||||
import { findHowManyDaysLeft, renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||
// services
|
||||
|
@ -7,7 +7,8 @@ import trackEventServices from "services/track_event.service";
|
||||
// hooks
|
||||
import useEstimateOption from "hooks/use-estimate-option";
|
||||
// ui
|
||||
import { CustomSelect, Tooltip } from "components/ui";
|
||||
import { CustomSelect } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { PlayIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
|
@ -9,7 +9,8 @@ import issuesService from "services/issue.service";
|
||||
// component
|
||||
import { CreateLabelModal } from "components/labels";
|
||||
// ui
|
||||
import { CustomSearchSelect, Tooltip } from "components/ui";
|
||||
import { CustomSearchSelect } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { PlusIcon, TagIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
|
@ -5,7 +5,8 @@ import { useRouter } from "next/router";
|
||||
// services
|
||||
import trackEventServices from "services/track_event.service";
|
||||
// ui
|
||||
import { CustomSelect, Tooltip } from "components/ui";
|
||||
import { CustomSelect } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { PriorityIcon } from "components/icons/priority-icon";
|
||||
// helpers
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// ui
|
||||
import { CustomDatePicker, Tooltip } from "components/ui";
|
||||
import { CustomDatePicker } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// helpers
|
||||
import { findHowManyDaysLeft, renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||
// services
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { ModuleStatusIcon } from "components/icons";
|
||||
// helpers
|
||||
@ -27,16 +27,13 @@ export const ModuleGanttBlock = ({ data }: { data: IModule }) => {
|
||||
<div className="space-y-1">
|
||||
<h5>{data?.name}</h5>
|
||||
<div>
|
||||
{renderShortDate(data?.start_date ?? "")} to{" "}
|
||||
{renderShortDate(data?.target_date ?? "")}
|
||||
{renderShortDate(data?.start_date ?? "")} to {renderShortDate(data?.target_date ?? "")}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
position="top-left"
|
||||
>
|
||||
<div className="relative text-custom-text-100 text-sm truncate py-1 px-2.5 w-full">
|
||||
{data?.name}
|
||||
</div>
|
||||
<div className="relative text-custom-text-100 text-sm truncate py-1 px-2.5 w-full">{data?.name}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
|
@ -12,15 +12,10 @@ import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { DeleteModuleModal } from "components/modules";
|
||||
// ui
|
||||
import { AssigneesList, Avatar, CustomMenu, Tooltip } from "components/ui";
|
||||
import { AssigneesList, Avatar, CustomMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import {
|
||||
CalendarDaysIcon,
|
||||
LinkIcon,
|
||||
PencilIcon,
|
||||
StarIcon,
|
||||
TrashIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { CalendarDaysIcon, LinkIcon, PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
import { CalendarMonthIcon, TargetIcon } from "components/icons";
|
||||
|
||||
// helpers
|
||||
@ -45,8 +40,7 @@ export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule, us
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const completionPercentage =
|
||||
((module.completed_issues + module.cancelled_issues) / module.total_issues) * 100;
|
||||
const completionPercentage = ((module.completed_issues + module.cancelled_issues) / module.total_issues) * 100;
|
||||
|
||||
const handleDeleteModule = () => {
|
||||
if (!module) return;
|
||||
@ -93,24 +87,19 @@ export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule, us
|
||||
false
|
||||
);
|
||||
|
||||
modulesService
|
||||
.removeModuleFromFavorites(workspaceSlug as string, projectId as string, module.id)
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Couldn't remove the module from favorites. Please try again.",
|
||||
});
|
||||
modulesService.removeModuleFromFavorites(workspaceSlug as string, projectId as string, module.id).catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Couldn't remove the module from favorites. Please try again.",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleCopyText = () => {
|
||||
const originURL =
|
||||
typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
|
||||
copyTextToClipboard(
|
||||
`${originURL}/${workspaceSlug}/projects/${projectId}/modules/${module.id}`
|
||||
).then(() => {
|
||||
copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${projectId}/modules/${module.id}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Link Copied!",
|
||||
@ -125,12 +114,7 @@ export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule, us
|
||||
|
||||
return (
|
||||
<>
|
||||
<DeleteModuleModal
|
||||
isOpen={moduleDeleteModal}
|
||||
setIsOpen={setModuleDeleteModal}
|
||||
data={module}
|
||||
user={user}
|
||||
/>
|
||||
<DeleteModuleModal isOpen={moduleDeleteModal} setIsOpen={setModuleDeleteModal} data={module} user={user} />
|
||||
<div className="flex flex-col divide-y divide-custom-border-200 overflow-hidden rounded-[10px] border border-custom-border-200 bg-custom-background-100 text-xs">
|
||||
<div className="p-4">
|
||||
<div className="flex w-full flex-col gap-5">
|
||||
|
@ -7,7 +7,8 @@ import { useRouter } from "next/router";
|
||||
import useToast from "hooks/use-toast";
|
||||
|
||||
// icons
|
||||
import { CustomMenu, Icon, Tooltip } from "components/ui";
|
||||
import { CustomMenu, Icon } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
|
||||
// helper
|
||||
import { stripHTML, replaceUnderscoreIfSnakeCase, truncateText } from "helpers/string.helper";
|
||||
@ -66,8 +67,7 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
|
||||
<span className="absolute top-1/2 left-2 -translate-y-1/2 w-1.5 h-1.5 bg-custom-primary-100 rounded-full" />
|
||||
)}
|
||||
<div className="relative w-12 h-12 rounded-full">
|
||||
{notification.triggered_by_details.avatar &&
|
||||
notification.triggered_by_details.avatar !== "" ? (
|
||||
{notification.triggered_by_details.avatar && notification.triggered_by_details.avatar !== "" ? (
|
||||
<div className="h-12 w-12 rounded-full">
|
||||
<Image
|
||||
src={notification.triggered_by_details.avatar}
|
||||
@ -98,15 +98,13 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
|
||||
? notification.triggered_by_details.first_name
|
||||
: notification.triggered_by_details.display_name}{" "}
|
||||
</span>
|
||||
{notification.data.issue_activity.field !== "comment" &&
|
||||
notification.data.issue_activity.verb}{" "}
|
||||
{notification.data.issue_activity.field !== "comment" && notification.data.issue_activity.verb}{" "}
|
||||
{notification.data.issue_activity.field === "comment"
|
||||
? "commented"
|
||||
: notification.data.issue_activity.field === "None"
|
||||
? null
|
||||
: replaceUnderscoreIfSnakeCase(notification.data.issue_activity.field)}{" "}
|
||||
{notification.data.issue_activity.field !== "comment" &&
|
||||
notification.data.issue_activity.field !== "None"
|
||||
{notification.data.issue_activity.field !== "comment" && notification.data.issue_activity.field !== "None"
|
||||
? "to"
|
||||
: ""}
|
||||
<span className="font-semibold">
|
||||
@ -148,14 +146,11 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
|
||||
<p className="text-custom-text-300 flex items-center justify-end gap-x-1 flex-shrink-0">
|
||||
<Icon iconName="schedule" className="!text-base -my-0.5" />
|
||||
<span>
|
||||
Till {renderShortDate(notification.snoozed_till)},{" "}
|
||||
{render12HourFormatTime(notification.snoozed_till)}
|
||||
Till {renderShortDate(notification.snoozed_till)}, {render12HourFormatTime(notification.snoozed_till)}
|
||||
</span>
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-custom-text-300 flex-shrink-0">
|
||||
{formatDateDistance(notification.created_at)}
|
||||
</p>
|
||||
<p className="text-custom-text-300 flex-shrink-0">{formatDateDistance(notification.created_at)}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -168,9 +163,7 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
|
||||
onClick: () => {
|
||||
markNotificationReadStatusToggle(notification.id).then(() => {
|
||||
setToastAlert({
|
||||
title: notification.read_at
|
||||
? "Notification marked as unread"
|
||||
: "Notification marked as read",
|
||||
title: notification.read_at ? "Notification marked as unread" : "Notification marked as read",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
@ -183,9 +176,7 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
|
||||
onClick: () => {
|
||||
markNotificationArchivedStatus(notification.id).then(() => {
|
||||
setToastAlert({
|
||||
title: notification.archived_at
|
||||
? "Notification un-archived"
|
||||
: "Notification archived",
|
||||
title: notification.archived_at ? "Notification un-archived" : "Notification archived",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from "react";
|
||||
|
||||
// components
|
||||
import { CustomMenu, Icon, Tooltip } from "components/ui";
|
||||
import { CustomMenu, Icon } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// helpers
|
||||
import { getNumberCount } from "helpers/string.helper";
|
||||
|
||||
|
@ -9,9 +9,9 @@ import { Popover, Transition } from "@headlessui/react";
|
||||
import useUserNotification from "hooks/use-user-notifications";
|
||||
|
||||
// components
|
||||
import { EmptyState, Tooltip } from "components/ui";
|
||||
import { EmptyState } from "components/ui";
|
||||
import { SnoozeNotificationModal, NotificationCard, NotificationHeader } from "components/notifications";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Loader, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { NotificationsOutlined } from "@mui/icons-material";
|
||||
// images
|
||||
|
@ -7,24 +7,14 @@ import { useRouter } from "next/router";
|
||||
import useUser from "hooks/use-user";
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { CustomMenu, Tooltip } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import {
|
||||
LinkIcon,
|
||||
LockClosedIcon,
|
||||
LockOpenIcon,
|
||||
PencilIcon,
|
||||
StarIcon,
|
||||
TrashIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { LinkIcon, LockClosedIcon, LockOpenIcon, PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
import { ExclamationIcon } from "components/icons";
|
||||
// helpers
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
import {
|
||||
render24HourFormatTime,
|
||||
renderShortDate,
|
||||
renderLongDateFormat,
|
||||
} from "helpers/date-time.helper";
|
||||
import { render24HourFormatTime, renderShortDate, renderLongDateFormat } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { IPage, IProjectMember } from "types";
|
||||
|
||||
@ -55,11 +45,8 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const handleCopyText = () => {
|
||||
const originURL =
|
||||
typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
copyTextToClipboard(
|
||||
`${originURL}/${workspaceSlug}/projects/${projectId}/pages/${page.id}`
|
||||
).then(() => {
|
||||
const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${projectId}/pages/${page.id}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Link Copied!",
|
||||
@ -81,16 +68,13 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
||||
key={label.id}
|
||||
className="group flex items-center gap-1 rounded-2xl border border-custom-border-200 px-2 py-0.5 text-xs"
|
||||
style={{
|
||||
backgroundColor: `${
|
||||
label?.color && label.color !== "" ? label.color : "#000000"
|
||||
}20`,
|
||||
backgroundColor: `${label?.color && label.color !== "" ? label.color : "#000000"}20`,
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="h-1.5 w-1.5 flex-shrink-0 rounded-full"
|
||||
style={{
|
||||
backgroundColor:
|
||||
label?.color && label.color !== "" ? label.color : "#000000",
|
||||
backgroundColor: label?.color && label.color !== "" ? label.color : "#000000",
|
||||
}}
|
||||
/>
|
||||
{label.name}
|
||||
@ -105,9 +89,7 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
||||
` ${new Date(page.updated_at).getHours() < 12 ? "am" : "pm"}`
|
||||
} on ${renderShortDate(page.updated_at)}`}
|
||||
>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
{render24HourFormatTime(page.updated_at)}
|
||||
</p>
|
||||
<p className="text-sm text-custom-text-200">{render24HourFormatTime(page.updated_at)}</p>
|
||||
</Tooltip>
|
||||
{page.is_favorite ? (
|
||||
<button
|
||||
@ -161,8 +143,7 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
||||
<Tooltip
|
||||
position="top-right"
|
||||
tooltipContent={`Created by ${
|
||||
people?.find((person) => person.member.id === page.created_by)?.member
|
||||
.display_name ?? ""
|
||||
people?.find((person) => person.member.id === page.created_by)?.member.display_name ?? ""
|
||||
} on ${renderLongDateFormat(`${page.created_at}`)}`}
|
||||
>
|
||||
<span>
|
||||
@ -210,9 +191,7 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mt-2 space-y-2 text-sm text-custom-text-200">
|
||||
{page.blocks.length > 0
|
||||
? page.blocks.slice(0, 3).map((block) => <h4>{block.name}</h4>)
|
||||
: null}
|
||||
{page.blocks.length > 0 ? page.blocks.slice(0, 3).map((block) => <h4>{block.name}</h4>) : null}
|
||||
</div>
|
||||
</a>
|
||||
</Link>
|
||||
|
@ -7,7 +7,8 @@ import { useRouter } from "next/router";
|
||||
import useUser from "hooks/use-user";
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { CustomMenu, Tooltip } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import {
|
||||
DocumentTextIcon,
|
||||
@ -21,11 +22,7 @@ import {
|
||||
import { ExclamationIcon } from "components/icons";
|
||||
// helpers
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
import {
|
||||
renderLongDateFormat,
|
||||
renderShortDate,
|
||||
render24HourFormatTime,
|
||||
} from "helpers/date-time.helper";
|
||||
import { renderLongDateFormat, renderShortDate, render24HourFormatTime } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { IPage, IProjectMember } from "types";
|
||||
|
||||
@ -56,11 +53,8 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const handleCopyText = () => {
|
||||
const originURL =
|
||||
typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
copyTextToClipboard(
|
||||
`${originURL}/${workspaceSlug}/projects/${projectId}/pages/${page.id}`
|
||||
).then(() => {
|
||||
const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : "";
|
||||
copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${projectId}/pages/${page.id}`).then(() => {
|
||||
setToastAlert({
|
||||
type: "success",
|
||||
title: "Link Copied!",
|
||||
@ -77,9 +71,7 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<DocumentTextIcon className="h-4 w-4" />
|
||||
<p className="mr-2 truncate text-sm text-custom-text-100">
|
||||
{truncateText(page.name, 75)}
|
||||
</p>
|
||||
<p className="mr-2 truncate text-sm text-custom-text-100">{truncateText(page.name, 75)}</p>
|
||||
{page.label_details.length > 0 &&
|
||||
page.label_details.map((label) => (
|
||||
<div
|
||||
@ -102,13 +94,11 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
|
||||
<div className="ml-2 flex flex-shrink-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<Tooltip
|
||||
tooltipContent={`Last updated at ${render24HourFormatTime(
|
||||
tooltipContent={`Last updated at ${render24HourFormatTime(page.updated_at)} on ${renderShortDate(
|
||||
page.updated_at
|
||||
)} on ${renderShortDate(page.updated_at)}`}
|
||||
)}`}
|
||||
>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
{render24HourFormatTime(page.updated_at)}
|
||||
</p>
|
||||
<p className="text-sm text-custom-text-200">{render24HourFormatTime(page.updated_at)}</p>
|
||||
</Tooltip>
|
||||
{page.is_favorite ? (
|
||||
<button
|
||||
@ -160,8 +150,7 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
|
||||
<Tooltip
|
||||
position="top-right"
|
||||
tooltipContent={`Created by ${
|
||||
people?.find((person) => person.member.id === page.created_by)?.member
|
||||
.display_name ?? ""
|
||||
people?.find((person) => person.member.id === page.created_by)?.member.display_name ?? ""
|
||||
} on ${renderLongDateFormat(`${page.created_at}`)}`}
|
||||
>
|
||||
<span>
|
||||
|
@ -10,8 +10,8 @@ import useEstimateOption from "hooks/use-estimate-option";
|
||||
// components
|
||||
import { MyIssuesSelectFilters } from "components/issues";
|
||||
// ui
|
||||
import { CustomMenu, Tooltip } from "components/ui";
|
||||
import { ToggleSwitch } from "@plane/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { ToggleSwitch, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||
import { FormatListBulletedOutlined, GridViewOutlined } from "@mui/icons-material";
|
||||
|
@ -10,8 +10,8 @@ import userService from "services/user.service";
|
||||
// hooks
|
||||
import useUser from "hooks/use-user";
|
||||
// ui
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import { Loader, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { EditOutlined } from "@mui/icons-material";
|
||||
// helpers
|
||||
|
@ -11,7 +11,8 @@ import projectService from "services/project.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { CustomMenu, Tooltip } from "components/ui";
|
||||
import { CustomMenu } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// helpers
|
||||
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
|
@ -17,7 +17,7 @@ import { ChevronDownIcon } from "@heroicons/react/20/solid";
|
||||
import { CheckIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
// types
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import { ICurrentUserResponse, IIssueLabels } from "types";
|
||||
// constants
|
||||
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||
|
@ -9,7 +9,8 @@ import useWorkspaceMembers from "hooks/use-workspace-members";
|
||||
// headless ui
|
||||
import { Combobox } from "@headlessui/react";
|
||||
// components
|
||||
import { AssigneesList, Avatar, Icon, Tooltip } from "components/ui";
|
||||
import { AssigneesList, Avatar, Icon } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { ChevronDownIcon } from "@heroicons/react/20/solid";
|
||||
import { CheckIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
|
@ -9,7 +9,7 @@ import { ChevronDownIcon } from "@heroicons/react/20/solid";
|
||||
import { CheckIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { PriorityIcon } from "components/icons";
|
||||
// components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import { TIssuePriorities } from "types";
|
||||
// constants
|
||||
@ -52,9 +52,7 @@ export const PrioritySelect: React.FC<Props> = ({
|
||||
}));
|
||||
|
||||
const filteredOptions =
|
||||
query === ""
|
||||
? options
|
||||
: options?.filter((option) => option.query.toLowerCase().includes(query.toLowerCase()));
|
||||
query === "" ? options : options?.filter((option) => option.query.toLowerCase().includes(query.toLowerCase()));
|
||||
|
||||
const selectedOption = value ?? "None";
|
||||
|
||||
@ -62,9 +60,7 @@ export const PrioritySelect: React.FC<Props> = ({
|
||||
<Tooltip tooltipHeading="Priority" tooltipContent={selectedOption} position="top">
|
||||
<div
|
||||
className={`grid place-items-center rounded "h-6 w-6 border shadow-sm ${
|
||||
value === "urgent"
|
||||
? "border-red-500/20 bg-red-500"
|
||||
: "border-custom-border-300 bg-custom-background-100"
|
||||
value === "urgent" ? "border-red-500/20 bg-red-500" : "border-custom-border-300 bg-custom-background-100"
|
||||
} items-center`}
|
||||
>
|
||||
<span className="flex gap-1 items-center text-custom-text-200 text-xs">
|
||||
@ -108,15 +104,11 @@ export const PrioritySelect: React.FC<Props> = ({
|
||||
ref={dropdownBtn}
|
||||
type="button"
|
||||
className={`flex items-center justify-between gap-1 w-full text-xs ${
|
||||
disabled
|
||||
? "cursor-not-allowed text-custom-text-200"
|
||||
: "cursor-pointer hover:bg-custom-background-80"
|
||||
disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80"
|
||||
} ${buttonClassName}`}
|
||||
>
|
||||
{label}
|
||||
{!hideDropdownArrow && !disabled && (
|
||||
<ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
|
||||
)}
|
||||
{!hideDropdownArrow && !disabled && <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />}
|
||||
</Combobox.Button>
|
||||
<div className={`${open ? "fixed z-20 top-0 left-0 h-full w-full cursor-auto" : ""}`}>
|
||||
<Combobox.Options
|
||||
|
@ -27,9 +27,10 @@ import { IProject } from "types";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
// components
|
||||
import { CustomMenu, Icon, Tooltip } from "components/ui";
|
||||
import { CustomMenu, Icon } from "components/ui";
|
||||
import { LeaveProjectModal, DeleteProjectModal } from "components/project";
|
||||
import { PublishProjectModal } from "components/project/publish-project";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
|
||||
type Props = {
|
||||
project: IProject;
|
||||
|
@ -15,8 +15,8 @@ import stateService from "services/project_state.service";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
import { CustomSelect, Tooltip } from "components/ui";
|
||||
import { Button, Input } from "@plane/ui";
|
||||
import { CustomSelect } from "components/ui";
|
||||
import { Button, Input, Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import type { ICurrentUserResponse, IState, IStateResponse } from "types";
|
||||
// fetch-keys
|
||||
|
@ -7,7 +7,7 @@ import { mutate } from "swr";
|
||||
// services
|
||||
import stateService from "services/project_state.service";
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { ArrowDownIcon, ArrowUpIcon } from "@heroicons/react/24/outline";
|
||||
import { StateGroupIcon } from "components/icons";
|
||||
|
@ -15,7 +15,7 @@ import { ChevronDownIcon } from "@heroicons/react/20/solid";
|
||||
import { CheckIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||
import { StateGroupIcon } from "components/icons";
|
||||
// types
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// constants
|
||||
import { IState } from "types";
|
||||
import { STATES_LIST } from "constants/fetch-keys";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Rows, Columns, ToggleRight } from "lucide-react";
|
||||
import { cn } from "../utils";
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import InsertLeftTableIcon from "./InsertLeftTableIcon";
|
||||
import InsertRightTableIcon from "./InsertRightTableIcon";
|
||||
import InsertTopTableIcon from "./InsertTopTableIcon";
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// types
|
||||
import { IIssueLabels } from "types";
|
||||
|
||||
@ -10,19 +10,11 @@ type IssueLabelsListProps = {
|
||||
showLength?: boolean;
|
||||
};
|
||||
|
||||
export const IssueLabelsList: React.FC<IssueLabelsListProps> = ({
|
||||
labels,
|
||||
length = 5,
|
||||
showLength = true,
|
||||
}) => (
|
||||
export const IssueLabelsList: React.FC<IssueLabelsListProps> = ({ labels, length = 5, showLength = true }) => (
|
||||
<>
|
||||
{labels && (
|
||||
<>
|
||||
<Tooltip
|
||||
position="top"
|
||||
tooltipHeading="Labels"
|
||||
tooltipContent={labels.map((l) => l?.name).join(", ")}
|
||||
>
|
||||
<Tooltip position="top" tooltipHeading="Labels" tooltipContent={labels.map((l) => l?.name).join(", ")}>
|
||||
<div className="flex items-center gap-1.5 px-2 py-1 text-custom-text-200 rounded shadow-sm border border-custom-border-300">
|
||||
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-custom-primary" />
|
||||
{`${labels.length} Labels`}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { Tooltip } from "./tooltip";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
|
||||
type Props = {
|
||||
data: any;
|
||||
|
@ -2,7 +2,8 @@ import { useRouter } from "next/router";
|
||||
|
||||
// icons
|
||||
import { CopyPlus } from "lucide-react";
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
import { Squares2X2Icon } from "@heroicons/react/24/outline";
|
||||
import { BlockedIcon, BlockerIcon, RelatedIcon } from "components/icons";
|
||||
// helpers
|
||||
@ -12,11 +13,7 @@ import { capitalizeFirstLetter } from "helpers/string.helper";
|
||||
import { IIssueActivity } from "types";
|
||||
|
||||
const IssueLink = ({ activity }: { activity: IIssueActivity }) => (
|
||||
<Tooltip
|
||||
tooltipContent={
|
||||
activity.issue_detail ? activity.issue_detail.name : "This issue has been deleted"
|
||||
}
|
||||
>
|
||||
<Tooltip tooltipContent={activity.issue_detail ? activity.issue_detail.name : "This issue has been deleted"}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
@ -30,9 +27,7 @@ const IssueLink = ({ activity }: { activity: IIssueActivity }) => (
|
||||
}
|
||||
className="font-medium text-custom-text-100 inline-flex items-center gap-1 hover:underline"
|
||||
>
|
||||
{activity.issue_detail
|
||||
? `${activity.project_detail.identifier}-${activity.issue_detail.sequence_id}`
|
||||
: "Issue"}
|
||||
{activity.issue_detail ? `${activity.project_detail.identifier}-${activity.issue_detail.sequence_id}` : "Issue"}
|
||||
<Icon iconName="launch" className="!text-xs" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
@ -52,11 +47,7 @@ const UserLink = ({ activity }: { activity: IIssueActivity }) => (
|
||||
|
||||
const activityDetails: {
|
||||
[key: string]: {
|
||||
message: (
|
||||
activity: IIssueActivity,
|
||||
showIssue: boolean,
|
||||
workspaceSlug: string
|
||||
) => React.ReactNode;
|
||||
message: (activity: IIssueActivity, showIssue: boolean, workspaceSlug: string) => React.ReactNode;
|
||||
icon: React.ReactNode;
|
||||
};
|
||||
} = {
|
||||
@ -106,9 +97,7 @@ const activityDetails: {
|
||||
blocking: {
|
||||
message: (activity) => (
|
||||
<>
|
||||
{activity.old_value === ""
|
||||
? "marked this issue is blocking issue "
|
||||
: "removed the blocking issue "}
|
||||
{activity.old_value === "" ? "marked this issue is blocking issue " : "removed the blocking issue "}
|
||||
<span className="font-medium text-custom-text-100">
|
||||
{activity.old_value === "" ? activity.new_value : activity.old_value}
|
||||
</span>
|
||||
@ -136,9 +125,7 @@ const activityDetails: {
|
||||
duplicate: {
|
||||
message: (activity) => (
|
||||
<>
|
||||
{activity.old_value === ""
|
||||
? "marked this issue as duplicate of "
|
||||
: "removed this issue as a duplicate of "}
|
||||
{activity.old_value === "" ? "marked this issue as duplicate of " : "removed this issue as a duplicate of "}
|
||||
<span className="font-medium text-custom-text-100">
|
||||
{activity.verb === "created" ? activity.new_value : activity.old_value}
|
||||
</span>
|
||||
@ -151,9 +138,7 @@ const activityDetails: {
|
||||
relates_to: {
|
||||
message: (activity) => (
|
||||
<>
|
||||
{activity.old_value === ""
|
||||
? "marked that this issue relates to "
|
||||
: "removed the relation from "}
|
||||
{activity.old_value === "" ? "marked that this issue relates to " : "removed the relation from "}
|
||||
<span className="font-medium text-custom-text-100">
|
||||
{activity.old_value === "" ? activity.new_value : activity.old_value}
|
||||
</span>
|
||||
@ -210,9 +195,7 @@ const activityDetails: {
|
||||
message: (activity, showIssue) => (
|
||||
<>
|
||||
{activity.new_value ? "set the estimate point to " : "removed the estimate point "}
|
||||
{activity.new_value && (
|
||||
<span className="font-medium text-custom-text-100">{activity.new_value}</span>
|
||||
)}
|
||||
{activity.new_value && <span className="font-medium text-custom-text-100">{activity.new_value}</span>}
|
||||
{showIssue && (
|
||||
<>
|
||||
{" "}
|
||||
@ -266,12 +249,7 @@ const activityDetails: {
|
||||
{activity.verb === "updated" && "updated this "}
|
||||
{activity.verb === "deleted" && "removed this "}
|
||||
<button
|
||||
onClick={() =>
|
||||
console.log(
|
||||
"link",
|
||||
activity.verb === "created" ? activity.new_value : activity.old_value
|
||||
)
|
||||
}
|
||||
onClick={() => console.log("link", activity.verb === "created" ? activity.new_value : activity.old_value)}
|
||||
className="font-medium text-custom-text-100 inline-flex items-center gap-1 hover:underline"
|
||||
>
|
||||
link
|
||||
@ -296,12 +274,7 @@ const activityDetails: {
|
||||
{activity.verb === "updated" && "updated this "}
|
||||
{activity.verb === "deleted" && "removed this "}
|
||||
<button
|
||||
onClick={() =>
|
||||
console.log(
|
||||
"module",
|
||||
activity.verb === "created" ? activity.new_value : activity.old_value
|
||||
)
|
||||
}
|
||||
onClick={() => console.log("module", activity.verb === "created" ? activity.new_value : activity.old_value)}
|
||||
className="font-medium text-custom-text-100 inline-flex items-center gap-1 hover:underline"
|
||||
>
|
||||
module
|
||||
@ -388,8 +361,7 @@ const activityDetails: {
|
||||
state: {
|
||||
message: (activity, showIssue) => (
|
||||
<>
|
||||
set the state to{" "}
|
||||
<span className="font-medium text-custom-text-100">{activity.new_value}</span>
|
||||
set the state to <span className="font-medium text-custom-text-100">{activity.new_value}</span>
|
||||
{showIssue && (
|
||||
<>
|
||||
{" "}
|
||||
@ -407,9 +379,7 @@ const activityDetails: {
|
||||
<>
|
||||
{activity.new_value ? "set the target date to " : "removed the target date "}
|
||||
{activity.new_value && (
|
||||
<span className="font-medium text-custom-text-100">
|
||||
{renderShortDateWithYearFormat(activity.new_value)}
|
||||
</span>
|
||||
<span className="font-medium text-custom-text-100">{renderShortDateWithYearFormat(activity.new_value)}</span>
|
||||
)}
|
||||
|
||||
{showIssue && (
|
||||
@ -428,13 +398,7 @@ export const ActivityIcon = ({ activity }: { activity: IIssueActivity }) => (
|
||||
<>{activityDetails[activity.field as keyof typeof activityDetails]?.icon}</>
|
||||
);
|
||||
|
||||
export const ActivityMessage = ({
|
||||
activity,
|
||||
showIssue = false,
|
||||
}: {
|
||||
activity: IIssueActivity;
|
||||
showIssue?: boolean;
|
||||
}) => {
|
||||
export const ActivityMessage = ({ activity, showIssue = false }: { activity: IIssueActivity; showIssue?: boolean }) => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
|
@ -16,11 +16,11 @@ import { TipTapEditor } from "components/tiptap";
|
||||
import { Send } from "lucide-react";
|
||||
|
||||
// ui
|
||||
import { Icon, Tooltip } from "components/ui";
|
||||
import { Icon } from "components/ui";
|
||||
import { Button, Tooltip } from "@plane/ui";
|
||||
|
||||
// types
|
||||
import type { IIssueComment } from "types";
|
||||
import { Button } from "@plane/ui";
|
||||
|
||||
const defaultValues: Partial<IIssueComment> = {
|
||||
access: "INTERNAL",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// helpers
|
||||
import { renderDateFormat, renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||
// types
|
||||
@ -25,14 +25,7 @@ export const ActivityGraph: React.FC<Props> = ({ activities }) => {
|
||||
const fourMonthsAgo = new Date(today.getFullYear(), today.getMonth() - 4, 1);
|
||||
const fiveMonthsAgo = new Date(today.getFullYear(), today.getMonth() - 5, 1);
|
||||
|
||||
const recentMonths = [
|
||||
fiveMonthsAgo,
|
||||
fourMonthsAgo,
|
||||
threeMonthsAgo,
|
||||
twoMonthsAgo,
|
||||
lastMonth,
|
||||
today,
|
||||
];
|
||||
const recentMonths = [fiveMonthsAgo, fourMonthsAgo, threeMonthsAgo, twoMonthsAgo, lastMonth, today];
|
||||
|
||||
const getDatesOfMonth = (dateOfMonth: Date) => {
|
||||
const month = dateOfMonth.getMonth();
|
||||
@ -112,9 +105,7 @@ export const ActivityGraph: React.FC<Props> = ({ activities }) => {
|
||||
} activities on ${renderShortDateWithYearFormat(date)}`}
|
||||
>
|
||||
<div
|
||||
className={`${
|
||||
date === "" ? "pointer-events-none opacity-0" : ""
|
||||
} h-4 w-4 rounded ${
|
||||
className={`${date === "" ? "pointer-events-none opacity-0" : ""} h-4 w-4 rounded ${
|
||||
isActive
|
||||
? `bg-custom-primary ${activitiesIntensity(isActive.activity_count)}`
|
||||
: "bg-custom-background-80"
|
||||
|
@ -1,8 +1,7 @@
|
||||
// components
|
||||
import { ActivityGraph } from "components/workspace";
|
||||
// ui
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Loader } from "@plane/ui";
|
||||
import { Loader, Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { InformationCircleIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
|
@ -5,7 +5,7 @@ import { useRouter } from "next/router";
|
||||
import useTheme from "hooks/use-theme";
|
||||
// components
|
||||
import { NotificationPopover } from "components/notifications";
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// icons
|
||||
import { BarChartRounded, GridViewOutlined, TaskAltOutlined, WorkOutlineOutlined } from "@mui/icons-material";
|
||||
// mobx store
|
||||
|
@ -4,7 +4,7 @@ import Link from "next/link";
|
||||
// icons
|
||||
import { Bars3Icon } from "@heroicons/react/24/outline";
|
||||
// ui components
|
||||
import { Tooltip } from "components/ui";
|
||||
import { Tooltip } from "@plane/ui";
|
||||
// hooks
|
||||
import useProjectDetails from "hooks/use-project-details";
|
||||
|
||||
@ -17,10 +17,10 @@ type Props = {
|
||||
};
|
||||
|
||||
const { NEXT_PUBLIC_DEPLOY_URL } = process.env;
|
||||
let plane_deploy_url = NEXT_PUBLIC_DEPLOY_URL
|
||||
let plane_deploy_url = NEXT_PUBLIC_DEPLOY_URL;
|
||||
|
||||
if (typeof window !== 'undefined' && !plane_deploy_url) {
|
||||
plane_deploy_url= window.location.protocol + "//" + window.location.host + "/spaces";
|
||||
if (typeof window !== "undefined" && !plane_deploy_url) {
|
||||
plane_deploy_url = window.location.protocol + "//" + window.location.host + "/spaces";
|
||||
}
|
||||
|
||||
const Header: React.FC<Props> = ({ breadcrumbs, left, right, setToggleSidebar, noHeader }) => {
|
||||
@ -50,15 +50,10 @@ const Header: React.FC<Props> = ({ breadcrumbs, left, right, setToggleSidebar, n
|
||||
{projectDetails && projectDetails?.is_deployed && (
|
||||
<Link href={`${plane_deploy_url}/${workspaceSlug}/${projectId}`}>
|
||||
<a target="_blank" rel="noreferrer">
|
||||
<Tooltip
|
||||
tooltipContent="This project is public, and live on web."
|
||||
position="bottom-left"
|
||||
>
|
||||
<Tooltip tooltipContent="This project is public, and live on web." position="bottom-left">
|
||||
<div className="transition-all flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 p-1 rounded overflow-hidden relative flex items-center gap-1 cursor-pointer group">
|
||||
<div className="w-[14px] h-[14px] flex justify-center items-center">
|
||||
<span className="material-symbols-rounded text-[14px]">
|
||||
radio_button_checked
|
||||
</span>
|
||||
<span className="material-symbols-rounded text-[14px]">radio_button_checked</span>
|
||||
</div>
|
||||
<div className="text-xs font-medium">Public</div>
|
||||
<div className="w-[14px] h-[14px] hidden group-hover:flex justify-center items-center">
|
||||
|
@ -14,8 +14,8 @@ import modulesService from "services/modules.service";
|
||||
// components
|
||||
import { CreateUpdateModuleModal, ModulesListGanttChartView, SingleModuleCard } from "components/modules";
|
||||
// ui
|
||||
import { Button, Loader } from "@plane/ui";
|
||||
import { EmptyState, Icon, Tooltip } from "components/ui";
|
||||
import { Button, Loader, Tooltip } from "@plane/ui";
|
||||
import { EmptyState, Icon } from "components/ui";
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
|
@ -28,8 +28,8 @@ import { CreateLabelModal } from "components/labels";
|
||||
import { CreateBlock } from "components/pages/create-block";
|
||||
// ui
|
||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||
import { CustomSearchSelect, EmptyState, Tooltip } from "components/ui";
|
||||
import { TextArea, Loader, ToggleSwitch } from "@plane/ui";
|
||||
import { CustomSearchSelect, EmptyState } from "components/ui";
|
||||
import { TextArea, Loader, ToggleSwitch, Tooltip } from "@plane/ui";
|
||||
// images
|
||||
import emptyPage from "public/empty-state/page.svg";
|
||||
// icons
|
||||
|
Loading…
Reference in New Issue
Block a user