style: new empty states (#1497)
* fix: custom colors opacity * chore: update text colors for dark mode * fix: dropdown text colors, datepicker bg color * chore: update text colors * chore: updated primary bg color * style: new empty states added * refactor: empty state for issues * style: empty state for estimates * chore: update labels, estimates and integrations empty states * fix: custom analytics sidebar
This commit is contained in:
parent
82ff786666
commit
4a2057c0b3
44 changed files with 757 additions and 792 deletions
|
|
@ -61,7 +61,7 @@ export const CustomAnalytics: React.FC<Props> = ({
|
|||
<AnalyticsSelectBar
|
||||
control={control}
|
||||
setValue={setValue}
|
||||
projects={projects}
|
||||
projects={projects ?? []}
|
||||
params={params}
|
||||
fullScreen={fullScreen}
|
||||
isProjectLevel={isProjectLevel}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ import { ContrastIcon, LayerDiagonalIcon } from "components/icons";
|
|||
// helpers
|
||||
import { renderShortDate } from "helpers/date-time.helper";
|
||||
import { renderEmoji } from "helpers/emoji.helper";
|
||||
import { truncateText } from "helpers/string.helper";
|
||||
// types
|
||||
import {
|
||||
IAnalyticsParams,
|
||||
IAnalyticsResponse,
|
||||
ICurrentUserResponse,
|
||||
IExportAnalyticsFormData,
|
||||
IProject,
|
||||
IWorkspace,
|
||||
} from "types";
|
||||
// fetch-keys
|
||||
|
|
@ -179,7 +179,7 @@ export const AnalyticsSidebar: React.FC<Props> = ({
|
|||
};
|
||||
|
||||
const selectedProjects =
|
||||
params.project && params.project.length > 0 ? params.project : projects.map((p) => p.id);
|
||||
params.project && params.project.length > 0 ? params.project : projects?.map((p) => p.id);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -207,7 +207,7 @@ export const AnalyticsSidebar: React.FC<Props> = ({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="h-full overflow-hidden">
|
||||
<div className="h-full w-full overflow-hidden">
|
||||
{fullScreen ? (
|
||||
<>
|
||||
{!isProjectLevel && selectedProjects && selectedProjects.length > 0 && (
|
||||
|
|
@ -215,61 +215,62 @@ export const AnalyticsSidebar: React.FC<Props> = ({
|
|||
<h4 className="font-medium">Selected Projects</h4>
|
||||
<div className="space-y-6 mt-4 h-full overflow-y-auto">
|
||||
{selectedProjects.map((projectId) => {
|
||||
const project: IProject = projects.find((p) => p.id === projectId);
|
||||
const project = projects?.find((p) => p.id === projectId);
|
||||
|
||||
return (
|
||||
<div key={project.id}>
|
||||
<div className="text-sm flex items-center gap-1">
|
||||
{project.emoji ? (
|
||||
<span className="grid h-6 w-6 flex-shrink-0 place-items-center">
|
||||
{renderEmoji(project.emoji)}
|
||||
</span>
|
||||
) : project.icon_prop ? (
|
||||
<div className="h-6 w-6 grid place-items-center flex-shrink-0">
|
||||
<span
|
||||
style={{ color: project.icon_prop.color }}
|
||||
className="material-symbols-rounded text-lg"
|
||||
>
|
||||
{project.icon_prop.name}
|
||||
if (project)
|
||||
return (
|
||||
<div key={project.id} className="w-full">
|
||||
<div className="text-sm flex items-center gap-1">
|
||||
{project.emoji ? (
|
||||
<span className="grid h-6 w-6 flex-shrink-0 place-items-center">
|
||||
{renderEmoji(project.emoji)}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<span className="grid h-6 w-6 mr-1 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
|
||||
{project?.name.charAt(0)}
|
||||
</span>
|
||||
)}
|
||||
<h5 className="flex items-center gap-1">
|
||||
<p className="break-words">{project.name}</p>
|
||||
<span className="text-custom-text-200 text-xs ml-1">
|
||||
({project.identifier})
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div className="mt-4 space-y-3 pl-2">
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<UserGroupIcon className="h-4 w-4 text-custom-text-200" />
|
||||
<h6>Total members</h6>
|
||||
</div>
|
||||
<span className="text-custom-text-200">{project.total_members}</span>
|
||||
) : project.icon_prop ? (
|
||||
<div className="h-6 w-6 grid place-items-center flex-shrink-0">
|
||||
<span
|
||||
style={{ color: project.icon_prop.color }}
|
||||
className="material-symbols-rounded text-lg"
|
||||
>
|
||||
{project.icon_prop.name}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<span className="grid h-6 w-6 mr-1 flex-shrink-0 place-items-center rounded bg-gray-700 uppercase text-white">
|
||||
{project?.name.charAt(0)}
|
||||
</span>
|
||||
)}
|
||||
<h5 className="flex items-center gap-1">
|
||||
<p className="break-words">{truncateText(project.name, 20)}</p>
|
||||
<span className="text-custom-text-200 text-xs ml-1">
|
||||
({project.identifier})
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<ContrastIcon height={16} width={16} />
|
||||
<h6>Total cycles</h6>
|
||||
<div className="mt-4 space-y-3 pl-2 w-full">
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<UserGroupIcon className="h-4 w-4 text-custom-text-200" />
|
||||
<h6>Total members</h6>
|
||||
</div>
|
||||
<span className="text-custom-text-200">{project.total_members}</span>
|
||||
</div>
|
||||
<span className="text-custom-text-200">{project.total_cycles}</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<UserGroupIcon className="h-4 w-4 text-custom-text-200" />
|
||||
<h6>Total modules</h6>
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<ContrastIcon height={16} width={16} />
|
||||
<h6>Total cycles</h6>
|
||||
</div>
|
||||
<span className="text-custom-text-200">{project.total_cycles}</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<UserGroupIcon className="h-4 w-4 text-custom-text-200" />
|
||||
<h6>Total modules</h6>
|
||||
</div>
|
||||
<span className="text-custom-text-200">{project.total_modules}</span>
|
||||
</div>
|
||||
<span className="text-custom-text-200">{project.total_modules}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -29,19 +29,13 @@ import {
|
|||
} from "components/core";
|
||||
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||
import { CreateUpdateViewModal } from "components/views";
|
||||
import { CycleIssuesGanttChartView, TransferIssues, TransferIssuesModal } from "components/cycles";
|
||||
import { IssueGanttChartView } from "components/issues/gantt-chart";
|
||||
import { TransferIssues, TransferIssuesModal } from "components/cycles";
|
||||
// ui
|
||||
import { EmptySpace, EmptySpaceItem, EmptyState, PrimaryButton, Spinner } from "components/ui";
|
||||
import { EmptyState, PrimaryButton, Spinner } from "components/ui";
|
||||
// icons
|
||||
import {
|
||||
ListBulletIcon,
|
||||
PlusIcon,
|
||||
RectangleStackIcon,
|
||||
TrashIcon,
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { PlusIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
// images
|
||||
import emptyIssue from "public/empty-state/empty-issue.svg";
|
||||
import emptyIssue from "public/empty-state/issue.svg";
|
||||
// helpers
|
||||
import { getStatesList } from "helpers/state.helper";
|
||||
import { orderArrayBy } from "helpers/array.helper";
|
||||
|
|
@ -56,7 +50,6 @@ import {
|
|||
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
||||
STATES_LIST,
|
||||
} from "constants/fetch-keys";
|
||||
import { ModuleIssuesGanttChartView } from "components/modules";
|
||||
|
||||
type Props = {
|
||||
type?: "issue" | "cycle" | "module";
|
||||
|
|
@ -107,7 +100,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||
groupByProperty: selectedGroup,
|
||||
orderBy,
|
||||
filters,
|
||||
isNotEmpty,
|
||||
isEmpty,
|
||||
setFilters,
|
||||
params,
|
||||
} = useIssuesView();
|
||||
|
|
@ -517,7 +510,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||
)}
|
||||
</StrictModeDroppable>
|
||||
{groupedByIssues ? (
|
||||
isNotEmpty ? (
|
||||
!isEmpty || issueView === "kanban" || issueView === "calendar" ? (
|
||||
<>
|
||||
{isCompleted && <TransferIssues handleClick={() => setTransferIssuesModal(true)} />}
|
||||
{issueView === "list" ? (
|
||||
|
|
@ -584,46 +577,20 @@ export const IssuesView: React.FC<Props> = ({
|
|||
issueView === "gantt_chart" && <GanttChartView />
|
||||
)}
|
||||
</>
|
||||
) : type === "issue" ? (
|
||||
<EmptyState
|
||||
type="issue"
|
||||
title="Create New Issue"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
imgURL={emptyIssue}
|
||||
/>
|
||||
) : (
|
||||
<div className="grid h-full w-full place-items-center px-4 sm:px-0">
|
||||
<EmptySpace
|
||||
title="You don't have any issue yet."
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
Icon={RectangleStackIcon}
|
||||
>
|
||||
<EmptySpaceItem
|
||||
title="Create a new issue"
|
||||
description={
|
||||
<span>
|
||||
Use <pre className="inline rounded bg-custom-background-80 px-2 py-1">C</pre>{" "}
|
||||
shortcut to create a new issue
|
||||
</span>
|
||||
}
|
||||
Icon={PlusIcon}
|
||||
action={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
/>
|
||||
{openIssuesListModal && (
|
||||
<EmptySpaceItem
|
||||
title="Add an existing issue"
|
||||
description="Open list"
|
||||
Icon={ListBulletIcon}
|
||||
action={openIssuesListModal}
|
||||
/>
|
||||
)}
|
||||
</EmptySpace>
|
||||
</div>
|
||||
<EmptyState
|
||||
title="Project issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
buttonText="New Issue"
|
||||
buttonIcon={<PlusIcon className="h-4 w-4" />}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ import {
|
|||
} from "components/cycles";
|
||||
// ui
|
||||
import { EmptyState, Loader } from "components/ui";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// images
|
||||
import emptyCycle from "public/empty-state/empty-cycle.svg";
|
||||
import emptyCycle from "public/empty-state/cycle.svg";
|
||||
// helpers
|
||||
import { getDateRangeStatus } from "helpers/date-time.helper";
|
||||
// types
|
||||
|
|
@ -205,10 +207,17 @@ export const CyclesView: React.FC<Props> = ({ cycles, viewType }) => {
|
|||
)
|
||||
) : (
|
||||
<EmptyState
|
||||
type="cycle"
|
||||
title="Create New Cycle"
|
||||
description="Sprint more effectively with Cycles by confining your project to a fixed amount of time. Create new cycle now."
|
||||
imgURL={emptyCycle}
|
||||
title="Plan your project with cycles"
|
||||
description="Cycle is a custom time period in which a team works to complete items on their backlog."
|
||||
image={emptyCycle}
|
||||
buttonText="New Cycle"
|
||||
buttonIcon={<PlusIcon className="h-4 w-4" />}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "q",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
) : viewType === "list" ? (
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ export const JiraGetImportDetail: React.FC = () => {
|
|||
label={
|
||||
<span>
|
||||
{value && value !== "" ? (
|
||||
projects.find((p) => p.id === value)?.name
|
||||
projects?.find((p) => p.id === value)?.name
|
||||
) : (
|
||||
<span className="text-custom-text-200">Select a project</span>
|
||||
)}
|
||||
|
|
@ -145,7 +145,7 @@ export const JiraGetImportDetail: React.FC = () => {
|
|||
}
|
||||
verticalPosition="top"
|
||||
>
|
||||
{projects.length > 0 ? (
|
||||
{projects && projects.length > 0 ? (
|
||||
projects.map((project) => (
|
||||
<CustomSelect.Option key={project.id} value={project.id}>
|
||||
{project.name}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import pagesService from "services/pages.service";
|
|||
import { PagesView } from "components/pages";
|
||||
// ui
|
||||
import { EmptyState, Loader } from "components/ui";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// images
|
||||
import emptyPage from "public/empty-state/empty-page.svg";
|
||||
import emptyPage from "public/empty-state/page.svg";
|
||||
// helpers
|
||||
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
||||
// types
|
||||
|
|
@ -51,10 +53,17 @@ export const RecentPagesList: React.FC<TPagesListProps> = ({ viewType }) => {
|
|||
})
|
||||
) : (
|
||||
<EmptyState
|
||||
type="page"
|
||||
title="Create New Page"
|
||||
description="Create and document issues effortlessly in one place with Plane Notes, AI-powered for ease."
|
||||
imgURL={emptyPage}
|
||||
title="Have your thoughts in place"
|
||||
description="You can think of Pages as an AI-powered notepad."
|
||||
image={emptyPage}
|
||||
buttonText="New Page"
|
||||
buttonIcon={<PlusIcon className="h-4 w-4" />}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "d",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ import {
|
|||
} from "components/pages";
|
||||
// ui
|
||||
import { EmptyState, Loader } from "components/ui";
|
||||
// icons
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// images
|
||||
import emptyPage from "public/empty-state/empty-page.svg";
|
||||
import emptyPage from "public/empty-state/page.svg";
|
||||
// types
|
||||
import { IPage, TPageViewProps } from "types";
|
||||
import {
|
||||
|
|
@ -255,10 +257,17 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
|||
)
|
||||
) : (
|
||||
<EmptyState
|
||||
type="page"
|
||||
title="Create New Page"
|
||||
description="Create and document issues effortlessly in one place with Plane Notes, AI-powered for ease."
|
||||
imgURL={emptyPage}
|
||||
title="Have your thoughts in place"
|
||||
description="You can think of Pages as an AI-powered notepad."
|
||||
image={emptyPage}
|
||||
buttonText="New Page"
|
||||
buttonIcon={<PlusIcon className="h-4 w-4" />}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "d",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,11 @@ import {
|
|||
import { ExclamationIcon } from "components/icons";
|
||||
// helpers
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
import { renderShortTime, renderShortDate, renderLongDateFormat } from "helpers/date-time.helper";
|
||||
import {
|
||||
render24HourFormatTime,
|
||||
renderShortDate,
|
||||
renderLongDateFormat,
|
||||
} from "helpers/date-time.helper";
|
||||
// types
|
||||
import { IPage, IProjectMember } from "types";
|
||||
|
||||
|
|
@ -97,11 +101,13 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
|||
<div className="flex items-center gap-2">
|
||||
<Tooltip
|
||||
tooltipContent={`Last updated at ${
|
||||
renderShortTime(page.updated_at) +
|
||||
render24HourFormatTime(page.updated_at) +
|
||||
` ${new Date(page.updated_at).getHours() < 12 ? "am" : "pm"}`
|
||||
} on ${renderShortDate(page.updated_at)}`}
|
||||
>
|
||||
<p className="text-sm text-custom-text-200">{renderShortTime(page.updated_at)}</p>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
{render24HourFormatTime(page.updated_at)}
|
||||
</p>
|
||||
</Tooltip>
|
||||
{page.is_favorite ? (
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -21,7 +21,11 @@ import {
|
|||
import { ExclamationIcon } from "components/icons";
|
||||
// helpers
|
||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||
import { renderLongDateFormat, renderShortDate, renderShortTime } from "helpers/date-time.helper";
|
||||
import {
|
||||
renderLongDateFormat,
|
||||
renderShortDate,
|
||||
render24HourFormatTime,
|
||||
} from "helpers/date-time.helper";
|
||||
// types
|
||||
import { IPage, IProjectMember } from "types";
|
||||
|
||||
|
|
@ -98,12 +102,12 @@ 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 ${renderShortTime(
|
||||
tooltipContent={`Last updated at ${render24HourFormatTime(
|
||||
page.updated_at
|
||||
)} on ${renderShortDate(page.updated_at)}`}
|
||||
>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
{renderShortTime(page.updated_at)}
|
||||
{render24HourFormatTime(page.updated_at)}
|
||||
</p>
|
||||
</Tooltip>
|
||||
{page.is_favorite ? (
|
||||
|
|
|
|||
|
|
@ -1,77 +1,42 @@
|
|||
import React from "react";
|
||||
|
||||
import Image from "next/image";
|
||||
|
||||
// ui
|
||||
import { PrimaryButton } from "components/ui";
|
||||
// icon
|
||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// helper
|
||||
import { capitalizeFirstLetter } from "helpers/string.helper";
|
||||
|
||||
type Props = {
|
||||
type: "cycle" | "module" | "project" | "issue" | "view" | "page" | "estimate";
|
||||
title: string;
|
||||
description: React.ReactNode | string;
|
||||
imgURL: string;
|
||||
action?: () => void;
|
||||
image: any;
|
||||
buttonText: string;
|
||||
buttonIcon?: any;
|
||||
onClick?: () => void;
|
||||
isFullScreen?: boolean;
|
||||
};
|
||||
|
||||
export const EmptyState: React.FC<Props> = ({ type, title, description, imgURL, action }) => {
|
||||
const shortcutKey = (type: string) => {
|
||||
switch (type) {
|
||||
case "cycle":
|
||||
return "Q";
|
||||
case "module":
|
||||
return "M";
|
||||
case "project":
|
||||
return "P";
|
||||
case "issue":
|
||||
return "C";
|
||||
case "view":
|
||||
return "V";
|
||||
case "page":
|
||||
return "D";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center gap-5 text-center">
|
||||
<div className="h-32 w-72">
|
||||
<Image src={imgURL} height="128" width="288" alt={type} />
|
||||
</div>
|
||||
|
||||
<h3 className="text-xl font-semibold">{title}</h3>
|
||||
{shortcutKey(type) && (
|
||||
<span>
|
||||
Use shortcut{" "}
|
||||
<span className="text-custom-text-200 mx-1 rounded-sm border border-custom-border-100 bg-custom-background-90 px-2 py-1 text-sm font-medium">
|
||||
{shortcutKey(type)}
|
||||
</span>{" "}
|
||||
to create {type} from anywhere.
|
||||
</span>
|
||||
)}
|
||||
<p className="max-w-md text-sm text-custom-text-200">{description}</p>
|
||||
|
||||
<PrimaryButton
|
||||
className="flex items-center gap-1"
|
||||
onClick={() => {
|
||||
if (action) {
|
||||
action();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shortcutKey(type)) return;
|
||||
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: shortcutKey(type) as string,
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
>
|
||||
<PlusIcon className="h-4 w-4 font-bold text-white" />
|
||||
Create New {capitalizeFirstLetter(type)}
|
||||
export const EmptyState: React.FC<Props> = ({
|
||||
title,
|
||||
description,
|
||||
image,
|
||||
onClick,
|
||||
buttonText,
|
||||
buttonIcon,
|
||||
isFullScreen = true,
|
||||
}) => (
|
||||
<div
|
||||
className={`h-full w-full mx-auto grid place-items-center p-8 ${
|
||||
isFullScreen ? "md:w-4/5 lg:w-3/5" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="text-center flex flex-col items-center w-full">
|
||||
<Image src={image} className="w-52 sm:w-60" alt={buttonText} />
|
||||
<h6 className="text-xl font-semibold mt-6 sm:mt-8 mb-3">{title}</h6>
|
||||
<p className="text-custom-text-300 mb-7 sm:mb-8">{description}</p>
|
||||
<PrimaryButton className="flex items-center gap-1.5" onClick={onClick}>
|
||||
{buttonIcon}
|
||||
{buttonText}
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { VIEWS_LIST } from "constants/fetch-keys";
|
|||
import useToast from "hooks/use-toast";
|
||||
// helpers
|
||||
import { truncateText } from "helpers/string.helper";
|
||||
import { renderShortDateWithYearFormat, renderShortTime } from "helpers/date-time.helper";
|
||||
import { renderShortDateWithYearFormat, render24HourFormatTime } from "helpers/date-time.helper";
|
||||
|
||||
type Props = {
|
||||
view: IView;
|
||||
|
|
@ -105,12 +105,12 @@ export const SingleViewItem: React.FC<Props> = ({ view, handleEditView, handleDe
|
|||
filters
|
||||
</p>
|
||||
<Tooltip
|
||||
tooltipContent={`Last updated at ${renderShortTime(
|
||||
tooltipContent={`Last updated at ${render24HourFormatTime(
|
||||
view.updated_at
|
||||
)} ${renderShortDateWithYearFormat(view.updated_at)}`}
|
||||
>
|
||||
<p className="text-sm text-custom-text-200">
|
||||
{renderShortTime(view.updated_at)}
|
||||
{render24HourFormatTime(view.updated_at)}
|
||||
</p>
|
||||
</Tooltip>
|
||||
{view.is_favorite ? (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue