fix: layout fixes

This commit is contained in:
sriramveeraghanta 2023-10-03 00:33:03 +05:30
parent b1448c947e
commit 41fd9ce6e8
58 changed files with 394 additions and 458 deletions

View File

@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
import { observer } from "mobx-react-lite";
// hooks
import useToast from "hooks/use-toast";
import useUser from "hooks/use-user";
@ -18,13 +18,10 @@ import { CreateUpdatePageModal } from "components/pages";
import { copyTextToClipboard } from "helpers/string.helper";
// services
import issuesService from "services/issue.service";
import inboxService from "services/inbox.service";
// fetch keys
import { INBOX_LIST, ISSUE_DETAILS } from "constants/fetch-keys";
import { ISSUE_DETAILS } from "constants/fetch-keys";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { observable } from "mobx";
import { observer } from "mobx-react-lite";
export const CommandPalette: React.FC = observer(() => {
const store: any = useMobxStore();
@ -75,7 +72,7 @@ export const CommandPalette: React.FC = observer(() => {
const handleKeyDown = useCallback(
(e: KeyboardEvent) => {
const { key, ctrlKey, metaKey, altKey, shiftKey } = e;
const { key, ctrlKey, metaKey, altKey } = e;
if (!key) return;
const keyPressed = key.toLowerCase();

View File

@ -34,12 +34,12 @@ export const ProjectSidebarList: FC = observer(() => {
// states
const [isFavoriteProjectCreate, setIsFavoriteProjectCreate] = useState(false);
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false); // scroll animation state
// refs
const containerRef = useRef<HTMLDivElement | null>(null);
// user
const { user } = useUserAuth();
// toast
const { setToastAlert } = useToast();
const joinedProjects = workspaceSlug && projectStore.joinedProjects;

View File

@ -1,11 +1,7 @@
import React, { useRef, useState } from "react";
import Link from "next/link";
// headless ui
import { Transition } from "@headlessui/react";
// hooks
import useTheme from "hooks/use-theme";
import useOutsideClickDetector from "hooks/use-outside-click-detector";
// icons
import { Bolt, HelpOutlineOutlined, WestOutlined } from "@mui/icons-material";
@ -13,6 +9,7 @@ import { ChatBubbleOvalLeftEllipsisIcon } from "@heroicons/react/24/outline";
import { DocumentIcon, DiscordIcon, GithubIcon } from "components/icons";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { observer } from "mobx-react-lite";
const helpOptions = [
{
@ -38,15 +35,14 @@ const helpOptions = [
},
];
export interface WorkspaceHelpSectionProps {
setSidebarActive: React.Dispatch<React.SetStateAction<boolean>>;
}
export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setSidebarActive }) => {
const store: any = useMobxStore();
export interface WorkspaceHelpSectionProps {}
export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = observer(() => {
// store
const { theme: themeStore } = useMobxStore();
// states
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
// refs
const helpOptionsRef = useRef<HTMLDivElement | null>(null);
useOutsideClickDetector(helpOptionsRef, () => setIsNeedHelpOpen(false));
@ -55,23 +51,23 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setS
<>
<div
className={`flex w-full items-center justify-between gap-1 self-baseline border-t border-custom-border-200 bg-custom-sidebar-background-100 py-2 px-4 ${
store?.theme?.sidebarCollapsed ? "flex-col" : ""
themeStore?.sidebarCollapsed ? "flex-col" : ""
}`}
>
{!store?.theme?.sidebarCollapsed && (
{!themeStore?.sidebarCollapsed && (
<div className="w-1/2 text-center cursor-default rounded-md px-2.5 py-1.5 font-medium outline-none text-sm bg-green-500/10 text-green-500">
Free Plan
</div>
)}
<div
className={`flex items-center gap-1 ${
store?.theme?.sidebarCollapsed ? "flex-col justify-center" : "justify-evenly w-1/2"
themeStore?.sidebarCollapsed ? "flex-col justify-center" : "justify-evenly w-1/2"
}`}
>
<button
type="button"
className={`grid place-items-center rounded-md p-1.5 text-custom-text-200 hover:text-custom-text-100 hover:bg-custom-background-90 outline-none ${
store?.theme?.sidebarCollapsed ? "w-full" : ""
themeStore?.sidebarCollapsed ? "w-full" : ""
}`}
onClick={() => {
const e = new KeyboardEvent("keydown", {
@ -85,7 +81,7 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setS
<button
type="button"
className={`grid place-items-center rounded-md p-1.5 text-custom-text-200 hover:text-custom-text-100 hover:bg-custom-background-90 outline-none ${
store?.theme?.sidebarCollapsed ? "w-full" : ""
themeStore?.sidebarCollapsed ? "w-full" : ""
}`}
onClick={() => setIsNeedHelpOpen((prev) => !prev)}
>
@ -94,20 +90,20 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setS
<button
type="button"
className="grid place-items-center rounded-md p-1.5 text-custom-text-200 hover:text-custom-text-100 hover:bg-custom-background-90 outline-none md:hidden"
onClick={() => setSidebarActive(false)}
onClick={() => themeStore.setSidebarCollapsed(!themeStore?.sidebarCollapsed)}
>
<WestOutlined fontSize="small" />
</button>
<button
type="button"
className={`hidden md:grid place-items-center rounded-md p-1.5 text-custom-text-200 hover:text-custom-text-100 hover:bg-custom-background-90 outline-none ${
store?.theme?.sidebarCollapsed ? "w-full" : ""
themeStore?.sidebarCollapsed ? "w-full" : ""
}`}
onClick={() => store.theme.setSidebarCollapsed(!store?.theme?.sidebarCollapsed)}
onClick={() => themeStore.setSidebarCollapsed(!themeStore?.sidebarCollapsed)}
>
<WestOutlined
fontSize="small"
className={`duration-300 ${store?.theme?.sidebarCollapsed ? "rotate-180" : ""}`}
className={`duration-300 ${themeStore?.sidebarCollapsed ? "rotate-180" : ""}`}
/>
</button>
</div>
@ -124,7 +120,7 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setS
>
<div
className={`absolute bottom-2 ${
store?.theme?.sidebarCollapsed ? "left-full" : "left-[-75px]"
themeStore?.sidebarCollapsed ? "left-full" : "left-[-75px]"
} space-y-2 rounded-sm bg-custom-background-80 p-1 shadow-md`}
ref={helpOptionsRef}
>
@ -160,4 +156,4 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = ({ setS
</div>
</>
);
};
});

View File

@ -7,14 +7,10 @@ import useTheme from "hooks/use-theme";
import { NotificationPopover } from "components/notifications";
import { Tooltip } from "components/ui";
// icons
import {
BarChartRounded,
GridViewOutlined,
TaskAltOutlined,
WorkOutlineOutlined,
} from "@mui/icons-material";
import { BarChartRounded, GridViewOutlined, TaskAltOutlined, WorkOutlineOutlined } from "@mui/icons-material";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { observer } from "mobx-react-lite";
const workspaceLinks = (workspaceSlug: string) => [
{
@ -39,21 +35,16 @@ const workspaceLinks = (workspaceSlug: string) => [
},
];
export const WorkspaceSidebarMenu = () => {
const store: any = useMobxStore();
export const WorkspaceSidebarMenu = observer(() => {
const { theme: themeStore } = useMobxStore();
// router
const router = useRouter();
const { workspaceSlug } = router.query;
const { collapsed: sidebarCollapse } = useTheme();
return (
<div className="w-full cursor-pointer space-y-1 p-4">
{workspaceLinks(workspaceSlug as string).map((link, index) => {
const isActive =
link.name === "Settings"
? router.asPath.includes(link.href)
: router.asPath === link.href;
const isActive = link.name === "Settings" ? router.asPath.includes(link.href) : router.asPath === link.href;
return (
<Link key={index} href={link.href}>
@ -62,17 +53,17 @@ export const WorkspaceSidebarMenu = () => {
tooltipContent={link.name}
position="right"
className="ml-2"
disabled={!store?.theme?.sidebarCollapsed}
disabled={!themeStore?.sidebarCollapsed}
>
<div
className={`group flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium outline-none ${
isActive
? "bg-custom-primary-100/10 text-custom-primary-100"
: "text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80"
} ${store?.theme?.sidebarCollapsed ? "justify-center" : ""}`}
} ${themeStore?.sidebarCollapsed ? "justify-center" : ""}`}
>
{<link.Icon fontSize="small" />}
{!store?.theme?.sidebarCollapsed && link.name}
{!themeStore?.sidebarCollapsed && link.name}
</div>
</Tooltip>
</a>
@ -83,4 +74,4 @@ export const WorkspaceSidebarMenu = () => {
<NotificationPopover />
</div>
);
};
});

View File

View File

View File

@ -0,0 +1,3 @@
export * from "./layout";
export * from "./sidebar";
export * from "./header";

View File

@ -0,0 +1,42 @@
import { FC, ReactNode } from "react";
// layouts
import { UserAuthWrapper, WorkspaceAuthWrapper } from "layouts/auth-layout";
// components
import { CommandPalette } from "components/command-palette";
import { AppSidebar } from "./sidebar";
export interface IAppLayout {
bg: string;
children: ReactNode;
}
export const AppLayout: FC<IAppLayout> = (props) => {
const { bg = "primary", children } = props;
return (
<div>
<CommandPalette />
<UserAuthWrapper>
<WorkspaceAuthWrapper>
<div>
<AppSidebar />
<div className="relative flex h-screen w-full overflow-hidden">
<main
className={`relative flex h-full w-full flex-col overflow-hidden ${
bg === "primary"
? "bg-custom-background-100"
: bg === "secondary"
? "bg-custom-background-90"
: "bg-custom-background-80"
}`}
>
<div className="h-full w-full overflow-hidden">
<div className="relative h-full w-full overflow-x-hidden overflow-y-scroll">{children}</div>
</div>
</main>
</div>
</div>
</WorkspaceAuthWrapper>
</UserAuthWrapper>
</div>
);
};

View File

@ -0,0 +1,36 @@
import { FC } from "react";
import { observer } from "mobx-react-lite";
// components
import {
WorkspaceHelpSection,
WorkspaceSidebarDropdown,
WorkspaceSidebarMenu,
WorkspaceSidebarQuickAction,
} from "components/workspace";
import { ProjectSidebarList } from "components/project";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
export interface IAppSidebar {}
export const AppSidebar: FC<IAppSidebar> = observer(() => {
// store
const { theme: themStore } = useMobxStore();
return (
<div
id="app-sidebar"
className={`fixed md:relative inset-y-0 flex flex-col bg-custom-sidebar-background-100 h-full flex-shrink-0 flex-grow-0 border-r border-custom-sidebar-border-200 z-20 duration-300 ${
themStore?.sidebarCollapsed ? "" : "md:w-[280px]"
} ${themStore?.sidebarCollapsed ? "left-0" : "-left-full md:left-0"}`}
>
<div className="flex h-full w-full flex-1 flex-col">
<WorkspaceSidebarDropdown />
<WorkspaceSidebarQuickAction />
<WorkspaceSidebarMenu />
<ProjectSidebarList />
<WorkspaceHelpSection />
</div>
</div>
);
});

View File

@ -0,0 +1,3 @@
export * from "./project-authorization-wrapper";
export * from "./workspace-authorization-wrapper";
export * from "./user-authorization-wrapper";

View File

@ -6,8 +6,8 @@ import { useRouter } from "next/router";
// contexts
import { useProjectMyMembership, ProjectMemberProvider } from "contexts/project-member.context";
// layouts
import AppHeader from "layouts/app-layout/app-header";
import AppSidebar from "layouts/app-layout/app-sidebar";
import AppHeader from "layouts/app-layout-legacy/app-header";
import AppSidebar from "layouts/app-layout-legacy/app-sidebar";
// components
import { NotAuthorizedView, JoinProject } from "components/auth-screens";
import { CommandPalette } from "components/command-palette";

View File

@ -22,7 +22,6 @@ export const UserAuthorizationLayout: React.FC<Props> = ({ children }) => {
return (
<div className="h-screen grid place-items-center p-4">
<div className="flex flex-col items-center gap-3 text-center">
<h3 className="text-xl">Loading your profile...</h3>
<Spinner />
</div>
</div>

View File

@ -10,8 +10,8 @@ import workspaceServices from "services/workspace.service";
// contexts
import { WorkspaceMemberProvider } from "contexts/workspace-member.context";
// layouts
import AppSidebar from "layouts/app-layout/app-sidebar";
import AppHeader from "layouts/app-layout/app-header";
import AppSidebar from "layouts/app-layout-legacy/app-sidebar";
import AppHeader from "layouts/app-layout-legacy/app-header";
import { UserAuthorizationLayout } from "./user-authorization-wrapper";
// components
import { NotAuthorizedView, NotAWorkspaceMember } from "components/auth-screens";

View File

@ -1,2 +1,2 @@
export * from "./project-authorization-wrapper";
export * from "./workspace-authorization-wrapper";
export * from "./user-wrapper";
export * from "./workspace-wrapper";

View File

@ -0,0 +1,39 @@
import { FC, ReactNode } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
// services
import userService from "services/user.service";
// ui
import { Spinner } from "components/ui";
// fetch-keys
import { CURRENT_USER } from "constants/fetch-keys";
export interface IUserAuthWrapper {
children: ReactNode;
}
export const UserAuthWrapper: FC<IUserAuthWrapper> = (props) => {
const { children } = props;
// router
const router = useRouter();
// fetching user information
const { data: currentUser, error } = useSWR(CURRENT_USER, () => userService.currentUser());
if (!currentUser && !error) {
return (
<div className="h-screen grid place-items-center p-4">
<div className="flex flex-col items-center gap-3 text-center">
<Spinner />
</div>
</div>
);
}
if (error) {
const redirectTo = router.asPath;
router.push(`/?next=${redirectTo}`);
return null;
}
return <>{children}</>;
};

View File

@ -0,0 +1,73 @@
import { FC, ReactNode } from "react";
import { useRouter } from "next/router";
import Link from "next/link";
import useSWR from "swr";
// services
import workspaceServices from "services/workspace.service";
// icons
import { Spinner, PrimaryButton, SecondaryButton } from "components/ui";
// fetch-keys
import { WORKSPACE_MEMBERS_ME } from "constants/fetch-keys";
export interface IWorkspaceAuthWrapper {
children: ReactNode;
noHeader?: boolean;
bg?: "primary" | "secondary";
breadcrumbs?: JSX.Element;
left?: JSX.Element;
right?: JSX.Element;
}
export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = (props) => {
const { children } = props;
// router
const router = useRouter();
const { workspaceSlug } = router.query;
// fetching user workspace information
const { data: workspaceMemberMe, error } = useSWR(
workspaceSlug ? WORKSPACE_MEMBERS_ME(workspaceSlug as string) : null,
workspaceSlug ? () => workspaceServices.workspaceMemberMe(workspaceSlug.toString()) : null
);
// while data is being loaded
if (!workspaceMemberMe && !error) {
return (
<div className="grid h-screen place-items-center p-4 bg-custom-background-100">
<div className="flex flex-col items-center gap-3 text-center">
<Spinner />
</div>
</div>
);
}
// while user does not have access to view that workspace
if (error?.status === 401 || error?.status === 403) {
return (
<div className={`h-screen w-full overflow-hidden bg-custom-background-100`}>
<div className="grid h-full place-items-center p-4">
<div className="space-y-8 text-center">
<div className="space-y-2">
<h3 className="text-lg font-semibold">Not Authorized!</h3>
<p className="mx-auto w-1/2 text-sm text-custom-text-200">
You{"'"}re not a member of this workspace. Please contact the workspace admin to get an invitation or
check your pending invitations.
</p>
</div>
<div className="flex items-center justify-center gap-2">
<Link href="/invitations">
<a>
<SecondaryButton>Check pending invites</SecondaryButton>
</a>
</Link>
<Link href="/create-workspace">
<a>
<PrimaryButton>Create new workspace</PrimaryButton>
</a>
</Link>
</div>
</div>
</div>
</div>
);
}
return <>{children}</>;
};

View File

@ -1,7 +1,7 @@
// hooks
import { useWorkspaceMyMembership } from "contexts/workspace-member.context";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { ProfileNavbar, ProfileSidebar } from "components/profile";
// ui

View File

@ -15,7 +15,7 @@ import { Tab } from "@headlessui/react";
import analyticsService from "services/analytics.service";
import trackEventServices from "services/track_event.service";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { CustomAnalytics, ScopeAndDemand } from "components/analytics";
// ui

View File

@ -9,19 +9,14 @@ import useSWR, { mutate } from "swr";
// next-themes
import { useTheme } from "next-themes";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// services
import userService from "services/user.service";
// hooks
import useUser from "hooks/use-user";
import useProjects from "hooks/use-projects";
// components
import {
CompletedIssuesGraph,
IssuesList,
IssuesPieChart,
IssuesStats,
} from "components/workspace";
import { CompletedIssuesGraph, IssuesList, IssuesPieChart, IssuesStats } from "components/workspace";
import { TourRoot } from "components/onboarding";
// ui
import { PrimaryButton, ProductUpdatesModal } from "components/ui";
@ -59,8 +54,7 @@ const WorkspacePage: NextPage = () => {
);
const today = new Date();
const greeting =
today.getHours() < 12 ? "morning" : today.getHours() < 18 ? "afternoon" : "evening";
const greeting = today.getHours() < 12 ? "morning" : today.getHours() < 18 ? "afternoon" : "evening";
useEffect(() => {
if (!workspaceSlug) return;
@ -100,10 +94,7 @@ const WorkspacePage: NextPage = () => {
}
>
{isProductUpdatesModalOpen && (
<ProductUpdatesModal
isOpen={isProductUpdatesModalOpen}
setIsOpen={setIsProductUpdatesModalOpen}
/>
<ProductUpdatesModal isOpen={isProductUpdatesModalOpen} setIsOpen={setIsProductUpdatesModalOpen} />
)}
{user && !user.is_tour_completed && (
<div className="fixed top-0 left-0 h-full w-full bg-custom-backdrop bg-opacity-50 transition-opacity z-20 grid place-items-center">
@ -156,9 +147,7 @@ const WorkspacePage: NextPage = () => {
<div className="mt-7 bg-custom-primary-100/5 flex justify-between gap-5 md:gap-8">
<div className="p-5 md:p-8 pr-0">
<h5 className="text-xl font-semibold">Create a project</h5>
<p className="mt-2 mb-5">
Manage your projects by creating issues, cycles, modules, views and pages.
</p>
<p className="mt-2 mb-5">Manage your projects by creating issues, cycles, modules, views and pages.</p>
<PrimaryButton
onClick={() => {
const e = new KeyboardEvent("keydown", {

View File

@ -5,7 +5,7 @@ import { useRouter } from "next/router";
// icons
import { PlusIcon } from "@heroicons/react/24/outline";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// hooks
import useMyIssuesFilters from "hooks/my-issues/use-my-issues-filter";
// components
@ -107,9 +107,7 @@ const MyIssuesPage: NextPage = () => {
type="button"
onClick={tab.onClick}
className={`border-b-2 p-4 text-sm font-medium outline-none whitespace-nowrap ${
tab.selected
? "border-custom-primary-100 text-custom-primary-100"
: "border-transparent"
tab.selected ? "border-custom-primary-100 text-custom-primary-100" : "border-transparent"
}`}
>
{tab.label}

View File

@ -6,7 +6,7 @@ import Link from "next/link";
// services
import userService from "services/user.service";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { ActivityIcon, ActivityMessage } from "components/core";
import { TipTapEditor } from "components/tiptap";
@ -60,8 +60,7 @@ const ProfileActivity = () => {
activityItem.new_value === "restore" && (
<Icon iconName="history" className="text-sm text-custom-text-200" />
)
) : activityItem.actor_detail.avatar &&
activityItem.actor_detail.avatar !== "" ? (
) : activityItem.actor_detail.avatar && activityItem.actor_detail.avatar !== "" ? (
<img
src={activityItem.actor_detail.avatar}
alt={activityItem.actor_detail.display_name}
@ -98,11 +97,7 @@ const ProfileActivity = () => {
<div className="issue-comments-section p-0">
<TipTapEditor
workspaceSlug={workspaceSlug as string}
value={
activityItem?.new_value !== ""
? activityItem.new_value
: activityItem.old_value
}
value={activityItem?.new_value !== "" ? activityItem.new_value : activityItem.old_value}
customClassName="text-xs border border-custom-border-200 bg-custom-background-100"
noBorder
borderOnFocus={false}
@ -124,9 +119,7 @@ const ProfileActivity = () => {
activityItem.field !== "estimate" ? (
<span className="text-custom-text-200">
created{" "}
<Link
href={`/${workspaceSlug}/projects/${activityItem.project}/issues/${activityItem.issue}`}
>
<Link href={`/${workspaceSlug}/projects/${activityItem.project}/issues/${activityItem.issue}`}>
<a className="inline-flex items-center hover:underline">
this issue. <ArrowTopRightOnSquareIcon className="ml-1 h-3.5 w-3.5" />
</a>
@ -150,10 +143,7 @@ const ProfileActivity = () => {
<div className="flex h-6 w-6 items-center justify-center">
{activityItem.field ? (
activityItem.new_value === "restore" ? (
<Icon
iconName="history"
className="!text-2xl text-custom-text-200"
/>
<Icon iconName="history" className="!text-2xl text-custom-text-200" />
) : (
<ActivityIcon activity={activityItem} />
)
@ -179,26 +169,19 @@ const ProfileActivity = () => {
</div>
<div className="min-w-0 flex-1 py-4 border-b border-custom-border-200">
<div className="text-sm text-custom-text-200 break-words">
{activityItem.field === "archived_at" &&
activityItem.new_value !== "restore" ? (
{activityItem.field === "archived_at" && activityItem.new_value !== "restore" ? (
<span className="text-gray font-medium">Plane</span>
) : activityItem.actor_detail.is_bot ? (
<span className="text-gray font-medium">
{activityItem.actor_detail.first_name} Bot
</span>
) : (
<Link
href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}
>
<a className="text-gray font-medium">
{activityItem.actor_detail.display_name}
</a>
<Link href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}>
<a className="text-gray font-medium">{activityItem.actor_detail.display_name}</a>
</Link>
)}{" "}
{message}{" "}
<span className="whitespace-nowrap">
{timeAgo(activityItem.created_at)}
</span>
<span className="whitespace-nowrap">{timeAgo(activityItem.created_at)}</span>
</div>
</div>
</>

View File

@ -11,7 +11,7 @@ import userService from "services/user.service";
import useUserAuth from "hooks/use-user-auth";
import useToast from "hooks/use-toast";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { ImagePickerPopover, ImageUploadModal } from "components/core";
import { SettingsSidebar } from "components/project";
@ -174,10 +174,7 @@ const Profile: NextPage = () => {
<div className={`flex flex-col gap-8 pr-9 py-9 w-full overflow-y-auto`}>
<div className="relative h-44 w-full mt-6">
<img
src={
watch("cover_image") ??
"https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"
}
src={watch("cover_image") ?? "https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"}
className="h-44 w-full rounded-lg object-cover"
alt={myProfile?.name ?? "Cover image"}
/>
@ -214,10 +211,7 @@ const Profile: NextPage = () => {
onChange={(imageUrl) => {
setValue("cover_image", imageUrl);
}}
value={
watch("cover_image") ??
"https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"
}
value={watch("cover_image") ?? "https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"}
/>
)}
/>
@ -307,9 +301,7 @@ const Profile: NextPage = () => {
</CustomSelect>
)}
/>
{errors.role && (
<span className="text-xs text-red-500">Please select a role</span>
)}
{errors.role && <span className="text-xs text-red-500">Please select a role</span>}
</div>
<div className="flex flex-col gap-1">
@ -328,8 +320,7 @@ const Profile: NextPage = () => {
validate: (value) => {
if (value.trim().length < 1) return "Display name can't be empty.";
if (value.split(" ").length > 1)
return "Display name can't have two consecutive spaces.";
if (value.split(" ").length > 1) return "Display name can't have two consecutive spaces.";
if (value.replace(/\s/g, "").length < 1)
return "Display name must be at least 1 characters long.";
@ -353,11 +344,7 @@ const Profile: NextPage = () => {
render={({ field: { value, onChange } }) => (
<CustomSearchSelect
value={value}
label={
value
? TIME_ZONES.find((t) => t.value === value)?.label ?? value
: "Select a timezone"
}
label={value ? TIME_ZONES.find((t) => t.value === value)?.label ?? value : "Select a timezone"}
options={timeZoneOptions}
onChange={onChange}
verticalPosition="top"
@ -366,9 +353,7 @@ const Profile: NextPage = () => {
/>
)}
/>
{errors.role && (
<span className="text-xs text-red-500">Please select a role</span>
)}
{errors.role && <span className="text-xs text-red-500">Please select a role</span>}
</div>
<div className="flex items-center justify-between py-2">

View File

@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
// hooks
import useUserAuth from "hooks/use-user-auth";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { CustomThemeSelector, ThemeSwitch } from "components/core";
// ui
@ -36,14 +36,10 @@ const ProfilePreferences = observer(() => {
background: currentTheme.background !== "" ? currentTheme.background : "#0d101b",
text: currentTheme.text !== "" ? currentTheme.text : "#c5c5c5",
primary: currentTheme.primary !== "" ? currentTheme.primary : "#3f76ff",
sidebarBackground:
currentTheme.sidebarBackground !== "" ? currentTheme.sidebarBackground : "#0d101b",
sidebarBackground: currentTheme.sidebarBackground !== "" ? currentTheme.sidebarBackground : "#0d101b",
sidebarText: currentTheme.sidebarText !== "" ? currentTheme.sidebarText : "#c5c5c5",
darkPalette: false,
palette:
currentTheme.palette !== ",,,,"
? currentTheme.palette
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
palette: currentTheme.palette !== ",,,," ? currentTheme.palette : "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
theme: "custom",
});
setCustomThemeSelectorOptions((prevData) => true);
@ -71,9 +67,7 @@ const ProfilePreferences = observer(() => {
<div className="grid grid-cols-12 gap-4 sm:gap-16 py-6">
<div className="col-span-12 sm:col-span-6">
<h4 className="text-lg font-semibold text-custom-text-100">Theme</h4>
<p className="text-sm text-custom-text-200">
Select or customize your interface color scheme.
</p>
<p className="text-sm text-custom-text-200">Select or customize your interface color scheme.</p>
</div>
<div className="col-span-12 sm:col-span-6">
<ThemeSwitch

View File

@ -12,7 +12,7 @@ import issuesService from "services/issue.service";
import useUserAuth from "hooks/use-user-auth";
import useToast from "hooks/use-toast";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { IssueDetailsSidebar, IssueMainContent } from "components/issues";
// ui

View File

@ -5,7 +5,7 @@ import useSWR from "swr";
// services
import projectService from "services/project.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// contexts
import { IssueViewContextProvider } from "contexts/issue-view.context";
// helper
@ -28,9 +28,7 @@ const ProjectArchivedIssues: NextPage = () => {
const { data: projectDetails } = useSWR(
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null
);
return (
@ -39,9 +37,7 @@ const ProjectArchivedIssues: NextPage = () => {
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
<BreadcrumbItem
title={`${truncateText(projectDetails?.name ?? "Project", 32)} Archived Issues`}
/>
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Archived Issues`} />
</Breadcrumbs>
}
right={

View File

@ -7,7 +7,7 @@ import useSWR from "swr";
import { ArrowLeftIcon } from "@heroicons/react/24/outline";
import { CyclesIcon } from "components/icons";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// contexts
import { IssueViewContextProvider } from "contexts/issue-view.context";
// components

View File

@ -6,7 +6,7 @@ import useSWR from "swr";
import useLocalStorage from "hooks/use-local-storage";
import useUserAuth from "hooks/use-user-auth";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { CyclesView, ActiveCycleDetails, CreateUpdateCycleModal } from "components/cycles";
// ui

View File

@ -5,7 +5,7 @@ import useSWR from "swr";
// services
import projectService from "services/project.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// contexts
import { IssueViewContextProvider } from "contexts/issue-view.context";
// helper
@ -28,9 +28,7 @@ const ProjectDraftIssues: NextPage = () => {
const { data: projectDetails } = useSWR(
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null
);
return (
@ -39,9 +37,7 @@ const ProjectDraftIssues: NextPage = () => {
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
<BreadcrumbItem
title={`${truncateText(projectDetails?.name ?? "Project", 32)} Draft Issues`}
/>
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Draft Issues`} />
</Breadcrumbs>
}
right={

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
// hooks
import useProjectDetails from "hooks/use-project-details";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// contexts
import { InboxViewContextProvider } from "contexts/inbox-view-context";
// components
@ -30,9 +30,7 @@ const ProjectInbox: NextPage = () => {
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
<BreadcrumbItem
title={`${truncateText(projectDetails?.name ?? "Project", 32)} Inbox`}
/>
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Inbox`} />
</Breadcrumbs>
}
right={

View File

@ -11,7 +11,7 @@ import issuesService from "services/issue.service";
// hooks
import useUserAuth from "hooks/use-user-auth";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { IssueDetailsSidebar, IssueMainContent } from "components/issues";
// ui

View File

@ -10,7 +10,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
import projectService from "services/project.service";
import inboxService from "services/inbox.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// helper
import { truncateText } from "helpers/string.helper";
// components

View File

@ -12,7 +12,7 @@ import modulesService from "services/modules.service";
import useToast from "hooks/use-toast";
import useUserAuth from "hooks/use-user-auth";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// contexts
import { IssueViewContextProvider } from "contexts/issue-view.context";
// components
@ -45,32 +45,20 @@ const SingleModule: React.FC = () => {
const { data: modules } = useSWR(
workspaceSlug && projectId ? MODULE_LIST(projectId as string) : null,
workspaceSlug && projectId
? () => modulesService.getModules(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => modulesService.getModules(workspaceSlug as string, projectId as string) : null
);
const { data: moduleIssues } = useSWR(
workspaceSlug && projectId && moduleId ? MODULE_ISSUES(moduleId as string) : null,
workspaceSlug && projectId && moduleId
? () =>
modulesService.getModuleIssues(
workspaceSlug as string,
projectId as string,
moduleId as string
)
? () => modulesService.getModuleIssues(workspaceSlug as string, projectId as string, moduleId as string)
: null
);
const { data: moduleDetails, error } = useSWR(
moduleId ? MODULE_DETAILS(moduleId as string) : null,
workspaceSlug && projectId
? () =>
modulesService.getModuleDetails(
workspaceSlug as string,
projectId as string,
moduleId as string
)
? () => modulesService.getModuleDetails(workspaceSlug as string, projectId as string, moduleId as string)
: null
);
@ -82,13 +70,7 @@ const SingleModule: React.FC = () => {
};
await modulesService
.addIssuesToModule(
workspaceSlug as string,
projectId as string,
moduleId as string,
payload,
user
)
.addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, payload, user)
.catch(() =>
setToastAlert({
type: "error",
@ -176,10 +158,7 @@ const SingleModule: React.FC = () => {
/>
) : (
<>
<AnalyticsProjectModal
isOpen={analyticsModal}
onClose={() => setAnalyticsModal(false)}
/>
<AnalyticsProjectModal isOpen={analyticsModal} onClose={() => setAnalyticsModal(false)} />
<div
className={`h-full flex flex-col ${moduleSidebar ? "mr-[24rem]" : ""} ${
analyticsModal ? "mr-[50%]" : ""

View File

@ -5,18 +5,14 @@ import { useRouter } from "next/router";
import useSWR from "swr";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// hooks
import useUserAuth from "hooks/use-user-auth";
// services
import projectService from "services/project.service";
import modulesService from "services/modules.service";
// components
import {
CreateUpdateModuleModal,
ModulesListGanttChartView,
SingleModuleCard,
} from "components/modules";
import { CreateUpdateModuleModal, ModulesListGanttChartView, SingleModuleCard } from "components/modules";
// ui
import { EmptyState, Icon, Loader, PrimaryButton, Tooltip } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
@ -56,16 +52,12 @@ const ProjectModules: NextPage = () => {
const { data: activeProject } = useSWR(
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null
);
const { data: modules, mutate: mutateModules } = useSWR(
workspaceSlug && projectId ? MODULE_LIST(projectId as string) : null,
workspaceSlug && projectId
? () => modulesService.getModules(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => modulesService.getModules(workspaceSlug as string, projectId as string) : null
);
const handleEditModule = (module: IModule) => {
@ -95,24 +87,17 @@ const ProjectModules: NextPage = () => {
{moduleViewOptions.map((option) => (
<Tooltip
key={option.type}
tooltipContent={
<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} View</span>
}
tooltipContent={<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} View</span>}
position="bottom"
>
<button
type="button"
className={`grid h-7 w-7 place-items-center rounded p-1 outline-none hover:bg-custom-sidebar-background-80 duration-300 ${
modulesView === option.type
? "bg-custom-sidebar-background-80"
: "text-custom-sidebar-text-200"
modulesView === option.type ? "bg-custom-sidebar-background-80" : "text-custom-sidebar-text-200"
}`}
onClick={() => setModulesView(option.type)}
>
<Icon
iconName={option.icon}
className={`!text-base ${option.type === "grid" ? "rotate-90" : ""}`}
/>
<Icon iconName={option.icon} className={`!text-base ${option.type === "grid" ? "rotate-90" : ""}`} />
</button>
</Tooltip>
))}

View File

@ -21,7 +21,7 @@ import issuesService from "services/issue.service";
import useToast from "hooks/use-toast";
import useUser from "hooks/use-user";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { CreateUpdateBlockInline, SinglePageBlock } from "components/pages";
import { CreateLabelModal } from "components/labels";

View File

@ -15,7 +15,7 @@ import useUserAuth from "hooks/use-user-auth";
// icons
import { PlusIcon } from "components/icons";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { RecentPagesList, CreateUpdatePageModal, TPagesListProps } from "components/pages";
// ui
@ -31,33 +31,21 @@ import { PROJECT_DETAILS } from "constants/fetch-keys";
// helper
import { truncateText } from "helpers/string.helper";
const AllPagesList = dynamic<TPagesListProps>(
() => import("components/pages").then((a) => a.AllPagesList),
{
ssr: false,
}
);
const AllPagesList = dynamic<TPagesListProps>(() => import("components/pages").then((a) => a.AllPagesList), {
ssr: false,
});
const FavoritePagesList = dynamic<TPagesListProps>(
() => import("components/pages").then((a) => a.FavoritePagesList),
{
ssr: false,
}
);
const FavoritePagesList = dynamic<TPagesListProps>(() => import("components/pages").then((a) => a.FavoritePagesList), {
ssr: false,
});
const MyPagesList = dynamic<TPagesListProps>(
() => import("components/pages").then((a) => a.MyPagesList),
{
ssr: false,
}
);
const MyPagesList = dynamic<TPagesListProps>(() => import("components/pages").then((a) => a.MyPagesList), {
ssr: false,
});
const OtherPagesList = dynamic<TPagesListProps>(
() => import("components/pages").then((a) => a.OtherPagesList),
{
ssr: false,
}
);
const OtherPagesList = dynamic<TPagesListProps>(() => import("components/pages").then((a) => a.OtherPagesList), {
ssr: false,
});
const tabsList = ["Recent", "All", "Favorites", "Created by me", "Created by others"];
@ -75,9 +63,7 @@ const ProjectPages: NextPage = () => {
const { data: projectDetails } = useSWR(
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null
);
const currentTabValue = (tab: string | null) => {
@ -109,9 +95,7 @@ const ProjectPages: NextPage = () => {
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem title="Projects" link={`/${workspaceSlug}/projects`} />
<BreadcrumbItem
title={`${truncateText(projectDetails?.name ?? "Project", 32)} Pages`}
/>
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Pages`} />
</Breadcrumbs>
}
right={

View File

@ -7,7 +7,7 @@ import { mutate } from "swr";
// services
import projectService from "services/project.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// hooks
import useUserAuth from "hooks/use-user-auth";
import useProjectDetails from "hooks/use-project-details";
@ -45,8 +45,7 @@ const AutomationsSettings: NextPage = () => {
mutate<IProject[]>(
PROJECTS_LIST(workspaceSlug as string, { is_favorite: "all" }),
(prevData) =>
(prevData ?? []).map((p) => (p.id === projectDetails.id ? { ...p, ...formData } : p)),
(prevData) => (prevData ?? []).map((p) => (p.id === projectDetails.id ? { ...p, ...formData } : p)),
false
);

View File

@ -10,7 +10,7 @@ import projectService from "services/project.service";
// hooks
import useProjectDetails from "hooks/use-project-details";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { CreateUpdateEstimateModal, SingleEstimate } from "components/estimates";
import { SettingsSidebar } from "components/project";

View File

@ -8,7 +8,7 @@ import useSWR, { mutate } from "swr";
import projectService from "services/project.service";
import trackEventServices, { MiscellaneousEventType } from "services/track_event.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// hooks
import useToast from "hooks/use-toast";
import useUserAuth from "hooks/use-user-auth";

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import useSWR from "swr";
import { Disclosure, Transition } from "@headlessui/react";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// services
import projectService from "services/project.service";
// components

View File

@ -5,7 +5,7 @@ import { useRouter } from "next/router";
import useSWR from "swr";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// services
import IntegrationService from "services/integration.service";
import projectService from "services/project.service";

View File

@ -10,7 +10,7 @@ import useUserAuth from "hooks/use-user-auth";
import projectService from "services/project.service";
import issuesService from "services/issue.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import {
CreateUpdateLabelInline,

View File

@ -15,7 +15,7 @@ import useProjectMembers from "hooks/use-project-members";
import useProjectDetails from "hooks/use-project-details";
import { Controller, useForm } from "react-hook-form";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import ConfirmProjectMemberRemove from "components/project/confirm-project-member-remove";
import SendProjectInvitationModal from "components/project/send-project-invitation-modal";
@ -80,9 +80,8 @@ const MembersSettings: NextPage = () => {
formState: { isSubmitting },
} = useForm<IProject>({ defaultValues });
const { data: activeWorkspace } = useSWR(
workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null,
() => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null)
const { data: activeWorkspace } = useSWR(workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () =>
workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null
);
const { data: people } = useSWR(
@ -93,21 +92,16 @@ const MembersSettings: NextPage = () => {
);
const { data: projectMembers, mutate: mutateMembers } = useSWR(
workspaceSlug && projectId
? PROJECT_MEMBERS_WITH_EMAIL(workspaceSlug.toString(), projectId.toString())
: null,
workspaceSlug && projectId ? PROJECT_MEMBERS_WITH_EMAIL(workspaceSlug.toString(), projectId.toString()) : null,
workspaceSlug && projectId
? () => projectService.projectMembersWithEmail(workspaceSlug as string, projectId as string)
: null
);
const { data: projectInvitations, mutate: mutateInvitations } = useSWR(
workspaceSlug && projectId ? PROJECT_INVITATIONS_WITH_EMAIL(workspaceSlug.toString(), projectId.toString()) : null,
workspaceSlug && projectId
? PROJECT_INVITATIONS_WITH_EMAIL(workspaceSlug.toString(), projectId.toString())
: null,
workspaceSlug && projectId
? () =>
projectService.projectInvitationsWithEmail(workspaceSlug as string, projectId as string)
? () => projectService.projectInvitationsWithEmail(workspaceSlug as string, projectId as string)
: null
);
@ -231,21 +225,12 @@ const MembersSettings: NextPage = () => {
setSelectedRemoveMember(null);
setSelectedInviteRemoveMember(null);
}}
data={members.find(
(item) => item.id === selectedRemoveMember || item.id === selectedInviteRemoveMember
)}
data={members.find((item) => item.id === selectedRemoveMember || item.id === selectedInviteRemoveMember)}
handleDelete={async () => {
if (!activeWorkspace || !projectDetails) return;
if (selectedRemoveMember) {
await projectService.deleteProjectMember(
activeWorkspace.slug,
projectDetails.id,
selectedRemoveMember
);
mutateMembers(
(prevData: any) => prevData?.filter((item: any) => item.id !== selectedRemoveMember),
false
);
await projectService.deleteProjectMember(activeWorkspace.slug, projectDetails.id, selectedRemoveMember);
mutateMembers((prevData: any) => prevData?.filter((item: any) => item.id !== selectedRemoveMember), false);
}
if (selectedInviteRemoveMember) {
await projectService.deleteProjectInvitation(
@ -254,8 +239,7 @@ const MembersSettings: NextPage = () => {
selectedInviteRemoveMember
);
mutateInvitations(
(prevData: any) =>
prevData?.filter((item: any) => item.id !== selectedInviteRemoveMember),
(prevData: any) => prevData?.filter((item: any) => item.id !== selectedInviteRemoveMember),
false
);
}
@ -348,10 +332,7 @@ const MembersSettings: NextPage = () => {
<div className="divide-y divide-custom-border-200">
{members.length > 0
? members.map((member) => (
<div
key={member.id}
className="flex items-center justify-between px-3.5 py-[18px]"
>
<div key={member.id} className="flex items-center justify-between px-3.5 py-[18px]">
<div className="flex items-center gap-x-6 gap-y-2">
{member.avatar && member.avatar !== "" ? (
<div className="relative flex h-10 w-10 items-center justify-center rounded-lg p-4 capitalize text-white">
@ -377,19 +358,13 @@ const MembersSettings: NextPage = () => {
<span>
{member.first_name} {member.last_name}
</span>
<span className="text-custom-text-300 text-sm ml-2">
({member.display_name})
</span>
<span className="text-custom-text-300 text-sm ml-2">({member.display_name})</span>
</a>
</Link>
) : (
<h4 className="text-sm">{member.display_name || member.email}</h4>
)}
{isOwner && (
<p className="mt-0.5 text-xs text-custom-sidebar-text-300">
{member.email}
</p>
)}
{isOwner && <p className="mt-0.5 text-xs text-custom-sidebar-text-300">{member.email}</p>}
</div>
</div>
<div className="flex items-center gap-3 text-xs">
@ -419,27 +394,19 @@ const MembersSettings: NextPage = () => {
mutateMembers(
(prevData: any) =>
prevData.map((m: any) =>
m.id === member.id ? { ...m, role: value } : m
),
prevData.map((m: any) => (m.id === member.id ? { ...m, role: value } : m)),
false
);
projectService
.updateProjectMember(
activeWorkspace.slug,
projectDetails.id,
member.id,
{
role: value,
}
)
.updateProjectMember(activeWorkspace.slug, projectDetails.id, member.id, {
role: value,
})
.catch(() => {
setToastAlert({
type: "error",
title: "Error!",
message:
"An error occurred while updating member role. Please try again.",
message: "An error occurred while updating member role. Please try again.",
});
});
}}
@ -447,18 +414,11 @@ const MembersSettings: NextPage = () => {
disabled={
member.memberId === user?.id ||
!member.member ||
(currentUser &&
currentUser.role !== 20 &&
currentUser.role < member.role)
(currentUser && currentUser.role !== 20 && currentUser.role < member.role)
}
>
{Object.keys(ROLE).map((key) => {
if (
currentUser &&
currentUser.role !== 20 &&
currentUser.role < parseInt(key)
)
return null;
if (currentUser && currentUser.role !== 20 && currentUser.role < parseInt(key)) return null;
return (
<CustomSelect.Option key={key} value={key}>
@ -477,10 +437,7 @@ const MembersSettings: NextPage = () => {
<span className="flex items-center justify-start gap-2">
<XMarkIcon className="h-4 w-4" />
<span>
{" "}
{member.memberId !== user?.id ? "Remove member" : "Leave project"}
</span>
<span> {member.memberId !== user?.id ? "Remove member" : "Leave project"}</span>
</span>
</CustomMenu.MenuItem>
</CustomMenu>

View File

@ -10,7 +10,7 @@ import stateService from "services/project_state.service";
import useProjectDetails from "hooks/use-project-details";
import useUserAuth from "hooks/use-user-auth";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// components
import { CreateUpdateStateInline, DeleteStateModal, SingleState, StateGroup } from "components/states";
import { SettingsSidebar } from "components/project";

View File

@ -6,7 +6,7 @@ import useSWR from "swr";
import projectService from "services/project.service";
import viewsService from "services/views.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// contexts
import { IssueViewContextProvider } from "contexts/issue-view.context";
// components
@ -30,27 +30,18 @@ const SingleView: React.FC = () => {
const { data: activeProject } = useSWR(
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null
);
const { data: views } = useSWR(
workspaceSlug && projectId ? VIEWS_LIST(projectId as string) : null,
workspaceSlug && projectId
? () => viewsService.getViews(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => viewsService.getViews(workspaceSlug as string, projectId as string) : null
);
const { data: viewDetails, error } = useSWR(
workspaceSlug && projectId && viewId ? VIEW_DETAILS(viewId as string) : null,
workspaceSlug && projectId && viewId
? () =>
viewsService.getViewDetails(
workspaceSlug as string,
projectId as string,
viewId as string
)
? () => viewsService.getViewDetails(workspaceSlug as string, projectId as string, viewId as string)
: null
);

View File

@ -10,7 +10,7 @@ import useUserAuth from "hooks/use-user-auth";
import viewsService from "services/views.service";
import projectService from "services/project.service";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
import { ProjectAuthorizationWrapper } from "layouts/auth-layout-legacy";
// ui
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
//icons
@ -40,16 +40,12 @@ const ProjectViews: NextPage = () => {
const { data: activeProject } = useSWR(
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
workspaceSlug && projectId
? () => projectService.getProject(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null
);
const { data: views } = useSWR(
workspaceSlug && projectId ? VIEWS_LIST(projectId as string) : null,
workspaceSlug && projectId
? () => viewsService.getViews(workspaceSlug as string, projectId as string)
: null
workspaceSlug && projectId ? () => viewsService.getViews(workspaceSlug as string, projectId as string) : null
);
const handleEditView = (view: IView) => {

View File

@ -9,7 +9,7 @@ import useProjects from "hooks/use-projects";
import useWorkspaces from "hooks/use-workspaces";
import useUserAuth from "hooks/use-user-auth";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// ui
import { Icon, PrimaryButton } from "components/ui";
import { Breadcrumbs, BreadcrumbItem } from "components/breadcrumbs";

View File

@ -7,7 +7,7 @@ import useSWR from "swr";
// services
import workspaceService from "services/workspace.service";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// component
import { SettingsSidebar } from "components/project";
// ui
@ -25,9 +25,8 @@ const BillingSettings: NextPage = () => {
query: { workspaceSlug },
} = useRouter();
const { data: activeWorkspace } = useSWR(
workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null,
() => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null)
const { data: activeWorkspace } = useSWR(workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () =>
workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null
);
return (
@ -56,9 +55,7 @@ const BillingSettings: NextPage = () => {
<div className="px-4 py-6">
<div>
<h4 className="text-md mb-1 leading-6">Current plan</h4>
<p className="mb-3 text-sm text-custom-text-200">
You are currently using the free plan
</p>
<p className="mb-3 text-sm text-custom-text-200">You are currently using the free plan</p>
<a href="https://plane.so/pricing" target="_blank" rel="noreferrer">
<SecondaryButton outline>View Plans</SecondaryButton>
</a>

View File

@ -5,7 +5,7 @@ import useSWR from "swr";
// services
import workspaceService from "services/workspace.service";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import ExportGuide from "components/exporter/guide";
import { SettingsSidebar } from "components/project";
@ -22,9 +22,8 @@ const ImportExport: NextPage = () => {
const router = useRouter();
const { workspaceSlug } = router.query;
const { data: activeWorkspace } = useSWR(
workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null,
() => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null)
const { data: activeWorkspace } = useSWR(workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () =>
workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null
);
return (

View File

@ -5,7 +5,7 @@ import useSWR from "swr";
// services
import workspaceService from "services/workspace.service";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import IntegrationGuide from "components/integration/guide";
import { SettingsSidebar } from "components/project";
@ -22,9 +22,8 @@ const ImportExport: NextPage = () => {
const router = useRouter();
const { workspaceSlug } = router.query;
const { data: activeWorkspace } = useSWR(
workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null,
() => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null)
const { data: activeWorkspace } = useSWR(workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () =>
workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null
);
return (

View File

@ -13,7 +13,7 @@ import fileService from "services/file.service";
import useToast from "hooks/use-toast";
import useUserAuth from "hooks/use-user-auth";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { ImageUploadModal } from "components/core";
import { DeleteWorkspaceModal } from "components/workspace";
@ -59,9 +59,8 @@ const WorkspaceSettings: NextPage = () => {
const { setToastAlert } = useToast();
const { data: activeWorkspace } = useSWR(
workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null,
() => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null)
const { data: activeWorkspace } = useSWR(workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () =>
workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null
);
const {
@ -156,9 +155,7 @@ const WorkspaceSettings: NextPage = () => {
<WorkspaceAuthorizationLayout
breadcrumbs={
<Breadcrumbs>
<BreadcrumbItem
title={`${truncateText(activeWorkspace?.name ?? "Workspace", 32)} Settings`}
/>
<BreadcrumbItem title={`${truncateText(activeWorkspace?.name ?? "Workspace", 32)} Settings`} />
</Breadcrumbs>
}
>
@ -191,11 +188,7 @@ const WorkspaceSettings: NextPage = () => {
<div className={`pr-9 py-8 w-full overflow-y-auto ${isAdmin ? "" : "opacity-60"}`}>
<div className="flex gap-5 items-center pb-7 border-b border-custom-border-200">
<div className="flex flex-col gap-1">
<button
type="button"
onClick={() => setIsImageUploadModalOpen(true)}
disabled={!isAdmin}
>
<button type="button" onClick={() => setIsImageUploadModalOpen(true)} disabled={!isAdmin}>
{watch("logo") && watch("logo") !== null && watch("logo") !== "" ? (
<div className="relative mx-auto flex h-14 w-14">
<img
@ -214,8 +207,7 @@ const WorkspaceSettings: NextPage = () => {
<div className="flex flex-col gap-1">
<h3 className="text-lg font-semibold leading-6">{watch("name")}</h3>
<span className="text-sm tracking-tight">{`${
typeof window !== "undefined" &&
window.location.origin.replace("http://", "").replace("https://", "")
typeof window !== "undefined" && window.location.origin.replace("http://", "").replace("https://", "")
}/${activeWorkspace.slug}`}</span>
<div className="flex item-center gap-2.5">
<button
@ -267,9 +259,7 @@ const WorkspaceSettings: NextPage = () => {
<CustomSelect
value={value}
onChange={onChange}
label={
ORGANIZATION_SIZE.find((c) => c === value) ?? "Select organization size"
}
label={ORGANIZATION_SIZE.find((c) => c === value) ?? "Select organization size"}
width="w-full"
input
disabled={!isAdmin}
@ -303,11 +293,7 @@ const WorkspaceSettings: NextPage = () => {
</div>
<div className="flex items-center justify-between py-2">
<PrimaryButton
onClick={handleSubmit(onSubmit)}
loading={isSubmitting}
disabled={!isAdmin}
>
<PrimaryButton onClick={handleSubmit(onSubmit)} loading={isSubmitting} disabled={!isAdmin}>
{isSubmitting ? "Updating..." : "Update Workspace"}
</PrimaryButton>
</div>
@ -337,17 +323,12 @@ const WorkspaceSettings: NextPage = () => {
<Disclosure.Panel>
<div className="flex flex-col gap-8">
<span className="text-sm tracking-tight">
The danger zone of the project delete page is a critical area that
requires careful consideration and attention. When deleting a project, all
of the data and resources within that project will be permanently removed
and cannot be recovered.
The danger zone of the project delete page is a critical area that requires careful
consideration and attention. When deleting a project, all of the data and resources within
that project will be permanently removed and cannot be recovered.
</span>
<div>
<DangerButton
onClick={() => setIsOpen(true)}
className="!text-sm"
outline
>
<DangerButton onClick={() => setIsOpen(true)} className="!text-sm" outline>
Delete my project
</DangerButton>
</div>

View File

@ -8,7 +8,7 @@ import useSWR from "swr";
import workspaceService from "services/workspace.service";
import IntegrationService from "services/integration.service";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import { SingleIntegrationCard } from "components/integration";
import { SettingsSidebar } from "components/project";

View File

@ -12,7 +12,7 @@ import useToast from "hooks/use-toast";
import useUser from "hooks/use-user";
import useWorkspaceMembers from "hooks/use-workspace-members";
// layouts
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout-legacy";
// components
import ConfirmWorkspaceMemberRemove from "components/workspace/confirm-workspace-member-remove";
import SendWorkspaceInvitationModal from "components/workspace/send-workspace-invitation-modal";
@ -25,11 +25,7 @@ import { XMarkIcon } from "components/icons";
// types
import type { NextPage } from "next";
// fetch-keys
import {
WORKSPACE_DETAILS,
WORKSPACE_INVITATION_WITH_EMAIL,
WORKSPACE_MEMBERS_WITH_EMAIL,
} from "constants/fetch-keys";
import { WORKSPACE_DETAILS, WORKSPACE_INVITATION_WITH_EMAIL, WORKSPACE_MEMBERS_WITH_EMAIL } from "constants/fetch-keys";
// constants
import { ROLE } from "constants/workspace";
// helper
@ -49,23 +45,18 @@ const MembersSettings: NextPage = () => {
const { isOwner } = useWorkspaceMembers(workspaceSlug?.toString(), Boolean(workspaceSlug));
const { data: activeWorkspace } = useSWR(
workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug.toString()) : null,
() => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug.toString()) : null)
const { data: activeWorkspace } = useSWR(workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug.toString()) : null, () =>
workspaceSlug ? workspaceService.getWorkspace(workspaceSlug.toString()) : null
);
const { data: workspaceMembers, mutate: mutateMembers } = useSWR(
workspaceSlug ? WORKSPACE_MEMBERS_WITH_EMAIL(workspaceSlug.toString()) : null,
workspaceSlug
? () => workspaceService.workspaceMembersWithEmail(workspaceSlug.toString())
: null
workspaceSlug ? () => workspaceService.workspaceMembersWithEmail(workspaceSlug.toString()) : null
);
const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR(
workspaceSlug ? WORKSPACE_INVITATION_WITH_EMAIL(workspaceSlug.toString()) : null,
workspaceSlug
? () => workspaceService.workspaceInvitationsWithEmail(workspaceSlug.toString())
: null
workspaceSlug ? () => workspaceService.workspaceInvitationsWithEmail(workspaceSlug.toString()) : null
);
const members = [
@ -143,15 +134,12 @@ const MembersSettings: NextPage = () => {
});
})
.finally(() => {
mutateMembers((prevData: any) =>
prevData?.filter((item: any) => item.id !== selectedRemoveMember)
);
mutateMembers((prevData: any) => prevData?.filter((item: any) => item.id !== selectedRemoveMember));
});
}
if (selectedInviteRemoveMember) {
mutateInvitations(
(prevData: any) =>
prevData?.filter((item: any) => item.id !== selectedInviteRemoveMember),
(prevData: any) => prevData?.filter((item: any) => item.id !== selectedInviteRemoveMember),
false
);
workspaceService
@ -206,10 +194,7 @@ const MembersSettings: NextPage = () => {
<div className="divide-y divide-custom-border-200">
{members.length > 0
? members.map((member) => (
<div
key={member.id}
className="group flex items-center justify-between px-3.5 py-[18px]"
>
<div key={member.id} className="group flex items-center justify-between px-3.5 py-[18px]">
<div className="flex items-center gap-x-8 gap-y-2">
{member.avatar && member.avatar !== "" ? (
<Link href={`/${workspaceSlug}/profile/${member.memberId}`}>
@ -239,21 +224,13 @@ const MembersSettings: NextPage = () => {
<span>
{member.first_name} {member.last_name}
</span>
<span className="text-custom-text-300 text-sm ml-2">
({member.display_name})
</span>
<span className="text-custom-text-300 text-sm ml-2">({member.display_name})</span>
</a>
</Link>
) : (
<h4 className="text-sm cursor-default">
{member.display_name || member.email}
</h4>
)}
{isOwner && (
<p className="mt-0.5 text-xs text-custom-sidebar-text-300">
{member.email}
</p>
<h4 className="text-sm cursor-default">{member.display_name || member.email}</h4>
)}
{isOwner && <p className="mt-0.5 text-xs text-custom-sidebar-text-300">{member.email}</p>}
</div>
</div>
<div className="flex items-center gap-3 text-xs">
@ -288,9 +265,7 @@ const MembersSettings: NextPage = () => {
mutateMembers(
(prevData: any) =>
prevData?.map((m: any) =>
m.id === member.id ? { ...m, role: value } : m
),
prevData?.map((m: any) => (m.id === member.id ? { ...m, role: value } : m)),
false
);
@ -302,8 +277,7 @@ const MembersSettings: NextPage = () => {
setToastAlert({
type: "error",
title: "Error!",
message:
"An error occurred while updating member role. Please try again.",
message: "An error occurred while updating member role. Please try again.",
});
});
}}
@ -311,18 +285,11 @@ const MembersSettings: NextPage = () => {
disabled={
member.memberId === currentUser?.member.id ||
!member.status ||
(currentUser &&
currentUser.role !== 20 &&
currentUser.role < member.role)
(currentUser && currentUser.role !== 20 && currentUser.role < member.role)
}
>
{Object.keys(ROLE).map((key) => {
if (
currentUser &&
currentUser.role !== 20 &&
currentUser.role < parseInt(key)
)
return null;
if (currentUser && currentUser.role !== 20 && currentUser.role < parseInt(key)) return null;
return (
<CustomSelect.Option key={key} value={key}>
@ -344,10 +311,7 @@ const MembersSettings: NextPage = () => {
<span className="flex items-center justify-start gap-2">
<XMarkIcon className="h-4 w-4" />
<span>
{" "}
{user?.id === member.memberId ? "Leave" : "Remove member"}
</span>
<span> {user?.id === member.memberId ? "Leave" : "Remove member"}</span>
</span>
</CustomMenu.MenuItem>
</CustomMenu>

View File

@ -2,7 +2,7 @@ import React from "react";
// layouts
import DefaultLayout from "layouts/default-layout";
import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper";
import { UserAuthorizationLayout } from "layouts/auth-layout-legacy/user-authorization-wrapper";
// components
import { CalendarView } from "components/issues";
// types

View File

@ -13,7 +13,7 @@ import userService from "services/user.service";
import useUser from "hooks/use-user";
// layouts
import DefaultLayout from "layouts/default-layout";
import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper";
import { UserAuthorizationLayout } from "layouts/auth-layout-legacy/user-authorization-wrapper";
// components
import { CreateWorkspaceForm } from "components/workspace";
// images
@ -59,9 +59,7 @@ const CreateWorkspace: NextPage = () => {
false
);
await userService
.updateUser({ last_workspace_id: workspace.id })
.then(() => router.push(`/${workspace.slug}`));
await userService.updateUser({ last_workspace_id: workspace.id }).then(() => router.push(`/${workspace.slug}`));
};
return (

View File

@ -15,7 +15,7 @@ import useUser from "hooks/use-user";
import useToast from "hooks/use-toast";
// layouts
import DefaultLayout from "layouts/default-layout";
import { UserAuthorizationLayout } from "layouts/auth-layout/user-authorization-wrapper";
import { UserAuthorizationLayout } from "layouts/auth-layout-legacy/user-authorization-wrapper";
// ui
import { SecondaryButton, PrimaryButton, EmptyState } from "components/ui";
// icons
@ -51,16 +51,11 @@ const OnBoard: NextPage = () => {
workspaceService.userWorkspaceInvitations()
);
const handleInvitation = (
workspace_invitation: IWorkspaceMemberInvitation,
action: "accepted" | "withdraw"
) => {
const handleInvitation = (workspace_invitation: IWorkspaceMemberInvitation, action: "accepted" | "withdraw") => {
if (action === "accepted") {
setInvitationsRespond((prevData) => [...prevData, workspace_invitation.id]);
} else if (action === "withdraw") {
setInvitationsRespond((prevData) =>
prevData.filter((item: string) => item !== workspace_invitation.id)
);
setInvitationsRespond((prevData) => prevData.filter((item: string) => item !== workspace_invitation.id));
}
};
@ -144,9 +139,7 @@ const OnBoard: NextPage = () => {
? "border-custom-primary-100"
: "border-custom-border-200 hover:bg-custom-background-80"
}`}
onClick={() =>
handleInvitation(invitation, isSelected ? "withdraw" : "accepted")
}
onClick={() => handleInvitation(invitation, isSelected ? "withdraw" : "accepted")}
>
<div className="flex-shrink-0">
<div className="grid place-items-center h-9 w-9 rounded">
@ -166,9 +159,7 @@ const OnBoard: NextPage = () => {
</div>
</div>
<div className="min-w-0 flex-1">
<div className="text-sm font-medium">
{truncateText(invitation.workspace.name, 30)}
</div>
<div className="text-sm font-medium">{truncateText(invitation.workspace.name, 30)}</div>
<p className="text-xs text-custom-text-200">{ROLE[invitation.role]}</p>
</div>
<span

View File

@ -2,8 +2,6 @@
import { action, observable, makeObservable } from "mobx";
// helper
import { applyTheme, unsetCustomCssVariables } from "helpers/theme.helper";
// interfaces
import { ICurrentUserSettings } from "types";
class ThemeStore {
sidebarCollapsed: boolean | null = null;
@ -14,8 +12,8 @@ class ThemeStore {
constructor(_rootStore: any | null = null) {
makeObservable(this, {
// observable
sidebarCollapsed: observable,
theme: observable,
sidebarCollapsed: observable.ref,
theme: observable.ref,
// action
setSidebarCollapsed: action,
setTheme: action,