mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore : project inbox improvement (#3695)
* chore: project inbox layout loader added * chore: project inbox layout loader added * chore: project inbox added in sidebar project items * chore: inbox loader improvement * chore: project inbox improvement
This commit is contained in:
parent
bbbd7047d3
commit
e1bf318317
@ -1,8 +1,7 @@
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import Link from "next/link";
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Briefcase, Circle, ExternalLink, Plus, Inbox } from "lucide-react";
|
import { Briefcase, Circle, ExternalLink, Plus } from "lucide-react";
|
||||||
// hooks
|
// hooks
|
||||||
import {
|
import {
|
||||||
useApplication,
|
useApplication,
|
||||||
@ -11,7 +10,6 @@ import {
|
|||||||
useProject,
|
useProject,
|
||||||
useProjectState,
|
useProjectState,
|
||||||
useUser,
|
useUser,
|
||||||
useInbox,
|
|
||||||
useMember,
|
useMember,
|
||||||
} from "hooks/store";
|
} from "hooks/store";
|
||||||
// components
|
// components
|
||||||
@ -54,7 +52,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
const { currentProjectDetails } = useProject();
|
const { currentProjectDetails } = useProject();
|
||||||
const { projectStates } = useProjectState();
|
const { projectStates } = useProjectState();
|
||||||
const { projectLabels } = useLabel();
|
const { projectLabels } = useLabel();
|
||||||
const { getInboxesByProjectId, getInboxById } = useInbox();
|
|
||||||
|
|
||||||
const activeLayout = issueFilters?.displayFilters?.layout;
|
const activeLayout = issueFilters?.displayFilters?.layout;
|
||||||
|
|
||||||
@ -101,9 +98,6 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
[workspaceSlug, projectId, updateFilters]
|
[workspaceSlug, projectId, updateFilters]
|
||||||
);
|
);
|
||||||
|
|
||||||
const inboxesMap = currentProjectDetails?.inbox_view ? getInboxesByProjectId(currentProjectDetails.id) : undefined;
|
|
||||||
const inboxDetails = inboxesMap && inboxesMap.length > 0 ? getInboxById(inboxesMap[0]) : undefined;
|
|
||||||
|
|
||||||
const deployUrl = process.env.NEXT_PUBLIC_DEPLOY_URL;
|
const deployUrl = process.env.NEXT_PUBLIC_DEPLOY_URL;
|
||||||
const canUserCreateIssue =
|
const canUserCreateIssue =
|
||||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||||
@ -154,7 +148,9 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
|
|
||||||
<Breadcrumbs.BreadcrumbItem
|
<Breadcrumbs.BreadcrumbItem
|
||||||
type="text"
|
type="text"
|
||||||
link={<BreadcrumbLink label="Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />}
|
link={
|
||||||
|
<BreadcrumbLink label="Issues" icon={<LayersIcon className="h-4 w-4 text-custom-text-300" />} />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</div>
|
</div>
|
||||||
@ -201,24 +197,15 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
/>
|
/>
|
||||||
</FiltersDropdown>
|
</FiltersDropdown>
|
||||||
</div>
|
</div>
|
||||||
{currentProjectDetails?.inbox_view && inboxDetails && (
|
|
||||||
<Link href={`/${workspaceSlug}/projects/${projectId}/inbox/${inboxDetails?.id}`}>
|
|
||||||
<span className="hidden md:block" >
|
|
||||||
<Button variant="neutral-primary" size="sm" className="relative">
|
|
||||||
Inbox
|
|
||||||
{inboxDetails?.pending_issue_count > 0 && (
|
|
||||||
<span className="absolute -right-1.5 -top-1.5 h-4 w-4 rounded-full border border-custom-sidebar-border-200 bg-custom-sidebar-background-80 text-custom-text-100">
|
|
||||||
{inboxDetails?.pending_issue_count}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</span>
|
|
||||||
<Inbox className="w-4 h-4 mr-2 text-custom-text-200 block md:hidden" />
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
{canUserCreateIssue && (
|
{canUserCreateIssue && (
|
||||||
<>
|
<>
|
||||||
<Button className="hidden md:block" onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
|
<Button
|
||||||
|
className="hidden md:block"
|
||||||
|
onClick={() => setAnalyticsModal(true)}
|
||||||
|
variant="neutral-primary"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
Analytics
|
Analytics
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
@ -4,7 +4,7 @@ import { observer } from "mobx-react";
|
|||||||
// hooks
|
// hooks
|
||||||
import { useInboxIssues } from "hooks/store";
|
import { useInboxIssues } from "hooks/store";
|
||||||
// ui
|
// ui
|
||||||
import { Loader } from "@plane/ui";
|
import { InboxSidebarLoader } from "components/ui";
|
||||||
// components
|
// components
|
||||||
import { InboxIssueList, InboxIssueFilterSelection, InboxIssueAppliedFilter } from "../";
|
import { InboxIssueList, InboxIssueFilterSelection, InboxIssueAppliedFilter } from "../";
|
||||||
|
|
||||||
@ -21,6 +21,10 @@ export const InboxSidebarRoot: FC<TInboxSidebarRoot> = observer((props) => {
|
|||||||
issues: { loader },
|
issues: { loader },
|
||||||
} = useInboxIssues();
|
} = useInboxIssues();
|
||||||
|
|
||||||
|
if (loader === "init-loader") {
|
||||||
|
return <InboxSidebarLoader />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col w-full h-full">
|
<div className="relative flex flex-col w-full h-full">
|
||||||
<div className="flex-shrink-0 w-full h-[50px] relative flex justify-between items-center gap-2 p-2 px-3 border-b border-custom-border-300">
|
<div className="flex-shrink-0 w-full h-[50px] relative flex justify-between items-center gap-2 p-2 px-3 border-b border-custom-border-300">
|
||||||
@ -28,7 +32,6 @@ export const InboxSidebarRoot: FC<TInboxSidebarRoot> = observer((props) => {
|
|||||||
<div className="relative w-6 h-6 flex justify-center items-center rounded bg-custom-background-80">
|
<div className="relative w-6 h-6 flex justify-center items-center rounded bg-custom-background-80">
|
||||||
<Inbox className="w-4 h-4" />
|
<Inbox className="w-4 h-4" />
|
||||||
</div>
|
</div>
|
||||||
<div className="font-medium">Inbox</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="z-20">
|
<div className="z-20">
|
||||||
<InboxIssueFilterSelection workspaceSlug={workspaceSlug} projectId={projectId} inboxId={inboxId} />
|
<InboxIssueFilterSelection workspaceSlug={workspaceSlug} projectId={projectId} inboxId={inboxId} />
|
||||||
@ -39,18 +42,9 @@ export const InboxSidebarRoot: FC<TInboxSidebarRoot> = observer((props) => {
|
|||||||
<InboxIssueAppliedFilter workspaceSlug={workspaceSlug} projectId={projectId} inboxId={inboxId} />
|
<InboxIssueAppliedFilter workspaceSlug={workspaceSlug} projectId={projectId} inboxId={inboxId} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{loader && ["init-loader", "mutation"].includes(loader) ? (
|
<div className="w-full h-full overflow-hidden">
|
||||||
<Loader className="flex flex-col h-full gap-5 p-5">
|
<InboxIssueList workspaceSlug={workspaceSlug} projectId={projectId} inboxId={inboxId} />
|
||||||
<Loader.Item height="30px" />
|
</div>
|
||||||
<Loader.Item height="30px" />
|
|
||||||
<Loader.Item height="30px" />
|
|
||||||
<Loader.Item height="30px" />
|
|
||||||
</Loader>
|
|
||||||
) : (
|
|
||||||
<div className="w-full h-full overflow-hidden">
|
|
||||||
<InboxIssueList workspaceSlug={workspaceSlug} projectId={projectId} inboxId={inboxId} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -16,12 +16,15 @@ import {
|
|||||||
LogOut,
|
LogOut,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
MoreHorizontal,
|
MoreHorizontal,
|
||||||
|
Inbox,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
// hooks
|
// hooks
|
||||||
import { useApplication, useEventTracker, useProject } from "hooks/store";
|
import { useApplication, useEventTracker, useInbox, useProject } from "hooks/store";
|
||||||
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// helpers
|
// helpers
|
||||||
|
import { cn } from "helpers/common.helper";
|
||||||
|
import { getNumberCount } from "helpers/string.helper";
|
||||||
import { renderEmoji } from "helpers/emoji.helper";
|
import { renderEmoji } from "helpers/emoji.helper";
|
||||||
// components
|
// components
|
||||||
import { CustomMenu, Tooltip, ArchiveIcon, PhotoFilterIcon, DiceIcon, ContrastIcon, LayersIcon } from "@plane/ui";
|
import { CustomMenu, Tooltip, ArchiveIcon, PhotoFilterIcon, DiceIcon, ContrastIcon, LayersIcon } from "@plane/ui";
|
||||||
@ -62,6 +65,11 @@ const navigation = (workspaceSlug: string, projectId: string) => [
|
|||||||
href: `/${workspaceSlug}/projects/${projectId}/pages`,
|
href: `/${workspaceSlug}/projects/${projectId}/pages`,
|
||||||
Icon: FileText,
|
Icon: FileText,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Inbox",
|
||||||
|
href: `/${workspaceSlug}/projects/${projectId}/inbox`,
|
||||||
|
Icon: Inbox,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
href: `/${workspaceSlug}/projects/${projectId}/settings`,
|
href: `/${workspaceSlug}/projects/${projectId}/settings`,
|
||||||
@ -75,7 +83,8 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const { theme: themeStore } = useApplication();
|
const { theme: themeStore } = useApplication();
|
||||||
const { setTrackElement } = useEventTracker();
|
const { setTrackElement } = useEventTracker();
|
||||||
const { addProjectToFavorites, removeProjectFromFavorites, getProjectById } = useProject();
|
const { currentProjectDetails, addProjectToFavorites, removeProjectFromFavorites, getProjectById } = useProject();
|
||||||
|
const { getInboxesByProjectId, getInboxById } = useInbox();
|
||||||
// states
|
// states
|
||||||
const [leaveProjectModalOpen, setLeaveProjectModal] = useState(false);
|
const [leaveProjectModalOpen, setLeaveProjectModal] = useState(false);
|
||||||
const [publishModalOpen, setPublishModal] = useState(false);
|
const [publishModalOpen, setPublishModal] = useState(false);
|
||||||
@ -96,6 +105,9 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
const actionSectionRef = useRef<HTMLDivElement | null>(null);
|
const actionSectionRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
|
const inboxesMap = currentProjectDetails?.inbox_view ? getInboxesByProjectId(currentProjectDetails.id) : undefined;
|
||||||
|
const inboxDetails = inboxesMap && inboxesMap.length > 0 ? getInboxById(inboxesMap[0]) : undefined;
|
||||||
|
|
||||||
const handleAddToFavorites = () => {
|
const handleAddToFavorites = () => {
|
||||||
if (!workspaceSlug || !project) return;
|
if (!workspaceSlug || !project) return;
|
||||||
|
|
||||||
@ -147,8 +159,9 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`group relative flex w-full items-center rounded-md px-2 py-1 text-custom-sidebar-text-10 hover:bg-custom-sidebar-background-80 ${snapshot?.isDragging ? "opacity-60" : ""
|
className={`group relative flex w-full items-center rounded-md px-2 py-1 text-custom-sidebar-text-10 hover:bg-custom-sidebar-background-80 ${
|
||||||
} ${isMenuActive ? "!bg-custom-sidebar-background-80" : ""}`}
|
snapshot?.isDragging ? "opacity-60" : ""
|
||||||
|
} ${isMenuActive ? "!bg-custom-sidebar-background-80" : ""}`}
|
||||||
>
|
>
|
||||||
{provided && (
|
{provided && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -157,9 +170,11 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`absolute -left-2.5 top-1/2 hidden -translate-y-1/2 rounded p-0.5 text-custom-sidebar-text-400 ${isCollapsed ? "" : "group-hover:!flex"
|
className={`absolute -left-2.5 top-1/2 hidden -translate-y-1/2 rounded p-0.5 text-custom-sidebar-text-400 ${
|
||||||
} ${project.sort_order === null ? "cursor-not-allowed opacity-60" : ""} ${isMenuActive ? "!flex" : ""
|
isCollapsed ? "" : "group-hover:!flex"
|
||||||
}`}
|
} ${project.sort_order === null ? "cursor-not-allowed opacity-60" : ""} ${
|
||||||
|
isMenuActive ? "!flex" : ""
|
||||||
|
}`}
|
||||||
{...provided?.dragHandleProps}
|
{...provided?.dragHandleProps}
|
||||||
>
|
>
|
||||||
<MoreVertical className="h-3.5" />
|
<MoreVertical className="h-3.5" />
|
||||||
@ -170,12 +185,14 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
<Tooltip tooltipContent={`${project.name}`} position="right" className="ml-2" disabled={!isCollapsed}>
|
<Tooltip tooltipContent={`${project.name}`} position="right" className="ml-2" disabled={!isCollapsed}>
|
||||||
<Disclosure.Button
|
<Disclosure.Button
|
||||||
as="div"
|
as="div"
|
||||||
className={`flex flex-grow cursor-pointer select-none items-center truncate text-left text-sm font-medium ${isCollapsed ? "justify-center" : `justify-between`
|
className={`flex flex-grow cursor-pointer select-none items-center truncate text-left text-sm font-medium ${
|
||||||
}`}
|
isCollapsed ? "justify-center" : `justify-between`
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`flex w-full flex-grow items-center gap-x-2 truncate ${isCollapsed ? "justify-center" : ""
|
className={`flex w-full flex-grow items-center gap-x-2 truncate ${
|
||||||
}`}
|
isCollapsed ? "justify-center" : ""
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
{project.emoji ? (
|
{project.emoji ? (
|
||||||
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase">
|
<span className="grid h-7 w-7 flex-shrink-0 place-items-center rounded uppercase">
|
||||||
@ -195,8 +212,9 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
</div>
|
</div>
|
||||||
{!isCollapsed && (
|
{!isCollapsed && (
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
className={`hidden h-4 w-4 flex-shrink-0 ${open ? "rotate-180" : ""} ${isMenuActive ? "!block" : ""
|
className={`hidden h-4 w-4 flex-shrink-0 ${open ? "rotate-180" : ""} ${
|
||||||
} mb-0.5 text-custom-sidebar-text-400 duration-300 group-hover:!block`}
|
isMenuActive ? "!block" : ""
|
||||||
|
} mb-0.5 text-custom-sidebar-text-400 duration-300 group-hover:!block`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Disclosure.Button>
|
</Disclosure.Button>
|
||||||
@ -306,7 +324,8 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
(item.name === "Cycles" && !project.cycle_view) ||
|
(item.name === "Cycles" && !project.cycle_view) ||
|
||||||
(item.name === "Modules" && !project.module_view) ||
|
(item.name === "Modules" && !project.module_view) ||
|
||||||
(item.name === "Views" && !project.issue_views_view) ||
|
(item.name === "Views" && !project.issue_views_view) ||
|
||||||
(item.name === "Pages" && !project.page_view)
|
(item.name === "Pages" && !project.page_view) ||
|
||||||
|
(item.name === "Inbox" && !project.inbox_view)
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -320,13 +339,42 @@ export const ProjectSidebarListItem: React.FC<Props> = observer((props) => {
|
|||||||
disabled={!isCollapsed}
|
disabled={!isCollapsed}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`group flex items-center gap-2.5 rounded-md px-2 py-1.5 text-xs font-medium outline-none ${router.asPath.includes(item.href)
|
className={`group flex items-center gap-2.5 rounded-md px-2 py-1.5 text-xs font-medium outline-none ${
|
||||||
? "bg-custom-primary-100/10 text-custom-primary-100"
|
router.asPath.includes(item.href)
|
||||||
: "text-custom-sidebar-text-300 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
|
? "bg-custom-primary-100/10 text-custom-primary-100"
|
||||||
} ${isCollapsed ? "justify-center" : ""}`}
|
: "text-custom-sidebar-text-300 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
|
||||||
|
} ${isCollapsed ? "justify-center" : ""}`}
|
||||||
>
|
>
|
||||||
<item.Icon className="h-4 w-4 stroke-[1.5]" />
|
{item.name === "Inbox" && inboxDetails ? (
|
||||||
{!isCollapsed && item.name}
|
<>
|
||||||
|
<div className="flex items-center justify-center relative">
|
||||||
|
{inboxDetails?.pending_issue_count > 0 && (
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"absolute -right-1.5 -top-1 px-0.5 h-3.5 w-3.5 flex items-center tracking-tight justify-center rounded-full text-[0.5rem] border-[0.5px] border-custom-sidebar-border-200 bg-custom-background-80 text-custom-text-100",
|
||||||
|
{
|
||||||
|
"text-[0.375rem] leading-5": inboxDetails?.pending_issue_count >= 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"border-none bg-custom-primary-300 text-white": router.asPath.includes(
|
||||||
|
item.href
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{getNumberCount(inboxDetails?.pending_issue_count)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<item.Icon className="h-4 w-4 stroke-[1.5]" />
|
||||||
|
</div>
|
||||||
|
{!isCollapsed && item.name}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<item.Icon className="h-4 w-4 stroke-[1.5]" />
|
||||||
|
{!isCollapsed && item.name}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</span>
|
</span>
|
||||||
|
@ -3,3 +3,4 @@ export * from "./kanban-layout-loader";
|
|||||||
export * from "./calendar-layout-loader";
|
export * from "./calendar-layout-loader";
|
||||||
export * from "./spreadsheet-layout-loader";
|
export * from "./spreadsheet-layout-loader";
|
||||||
export * from "./gantt-layout-loader";
|
export * from "./gantt-layout-loader";
|
||||||
|
export * from "./project-inbox";
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
import React from "react";
|
||||||
|
// ui
|
||||||
|
import { InboxSidebarLoader } from "./inbox-sidebar-loader";
|
||||||
|
|
||||||
|
export const InboxLayoutLoader = () => (
|
||||||
|
<div className="relative flex h-full overflow-hidden">
|
||||||
|
<InboxSidebarLoader />
|
||||||
|
<div className="w-full">
|
||||||
|
<div className="grid h-full place-items-center p-4 text-custom-text-200">
|
||||||
|
<div className="grid h-full place-items-center">
|
||||||
|
<div className="my-5 flex flex-col items-center gap-4">
|
||||||
|
<span className="h-[60px] w-[60px] bg-custom-background-80 rounded" />
|
||||||
|
<span className="h-6 w-96 bg-custom-background-80 rounded" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
@ -0,0 +1,24 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const InboxSidebarLoader = () => (
|
||||||
|
<div className="h-full w-[340px] border-r border-custom-border-300">
|
||||||
|
<div className="flex-shrink-0 w-full h-[50px] relative flex justify-between items-center gap-2 p-2 px-3 border-b border-custom-border-300">
|
||||||
|
<span className="h-6 w-16 bg-custom-background-80 rounded" />
|
||||||
|
<span className="h-6 w-16 bg-custom-background-80 rounded" />
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
{[...Array(6)].map(() => (
|
||||||
|
<div className="flex flex-col gap-3 h-[5rem]space-y-3 border-b border-custom-border-200 px-4 py-2">
|
||||||
|
<div className="flex items-center justify-between gap-3">
|
||||||
|
<span className="h-5 w-20 bg-custom-background-80 rounded" />
|
||||||
|
<span className="h-5 w-16 bg-custom-background-80 rounded" />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<span className="h-5 w-5 bg-custom-background-80 rounded" />
|
||||||
|
<span className="h-5 w-16 bg-custom-background-80 rounded" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
2
web/components/ui/loader/layouts/project-inbox/index.ts
Normal file
2
web/components/ui/loader/layouts/project-inbox/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from "./inbox-layout-loader";
|
||||||
|
export * from "./inbox-sidebar-loader";
|
@ -6,6 +6,8 @@ import { observer } from "mobx-react";
|
|||||||
import { useInbox, useProject } from "hooks/store";
|
import { useInbox, useProject } from "hooks/store";
|
||||||
// layouts
|
// layouts
|
||||||
import { AppLayout } from "layouts/app-layout";
|
import { AppLayout } from "layouts/app-layout";
|
||||||
|
// ui
|
||||||
|
import { InboxLayoutLoader } from "components/ui";
|
||||||
// components
|
// components
|
||||||
import { ProjectInboxHeader } from "components/headers";
|
import { ProjectInboxHeader } from "components/headers";
|
||||||
// types
|
// types
|
||||||
@ -33,7 +35,7 @@ const ProjectInboxPage: NextPageWithLayout = observer(() => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col">
|
<div className="flex h-full flex-col">
|
||||||
{currentProjectDetails?.inbox_view ? <div>Loading...</div> : <div>You don{"'"}t have access to inbox</div>}
|
{currentProjectDetails?.inbox_view ? <InboxLayoutLoader /> : <div>You don{"'"}t have access to inbox</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user