From c4fb54337230e43784a7660908cf698f84431eb8 Mon Sep 17 00:00:00 2001 From: Prateek Shourya Date: Tue, 28 Nov 2023 11:29:01 +0530 Subject: [PATCH] Fix: bug fixes and UI / UX improvements (#2906) * Fix: issue with project publish modal data not updating immediately. * fix: issue with workspace list not scrollable in profile settings. * fix: update redirect workspace slug logic to redirect to prev workspace instead of `/`. * style: update API tokens and webhooks empty state designs. --- web/components/api-token/empty-state.tsx | 2 +- .../project/publish-project/modal.tsx | 2 +- web/components/web-hooks/empty-state.tsx | 2 +- .../settings-layout/profile/sidebar.tsx | 47 ++++++++++++++++--- .../[workspaceSlug]/settings/api-tokens.tsx | 38 ++++++++------- web/pages/invitations/index.tsx | 25 ++++++++-- 6 files changed, 83 insertions(+), 33 deletions(-) diff --git a/web/components/api-token/empty-state.tsx b/web/components/api-token/empty-state.tsx index 474407703..8a6403561 100644 --- a/web/components/api-token/empty-state.tsx +++ b/web/components/api-token/empty-state.tsx @@ -14,7 +14,7 @@ export const ApiTokenEmptyState: React.FC = (props) => { return (
empty diff --git a/web/components/project/publish-project/modal.tsx b/web/components/project/publish-project/modal.tsx index f03e0abcc..91a4bec55 100644 --- a/web/components/project/publish-project/modal.tsx +++ b/web/components/project/publish-project/modal.tsx @@ -119,7 +119,7 @@ export const PublishProjectModal: React.FC = observer((props) => { reset({ ...updatedData }); } - }, [reset, projectPublishStore.projectPublishSettings]); + }, [reset, projectPublishStore.projectPublishSettings, isOpen]); // fetch publish settings useEffect(() => { diff --git a/web/components/web-hooks/empty-state.tsx b/web/components/web-hooks/empty-state.tsx index ef726d7b0..923fb78e4 100644 --- a/web/components/web-hooks/empty-state.tsx +++ b/web/components/web-hooks/empty-state.tsx @@ -11,7 +11,7 @@ export const WebhooksEmptyState = () => { return (
empty diff --git a/web/layouts/settings-layout/profile/sidebar.tsx b/web/layouts/settings-layout/profile/sidebar.tsx index 712ee06b8..0a322e43f 100644 --- a/web/layouts/settings-layout/profile/sidebar.tsx +++ b/web/layouts/settings-layout/profile/sidebar.tsx @@ -1,16 +1,18 @@ +import { Fragment, useEffect, useRef, useState } from "react"; +import { mutate } from "swr"; import Link from "next/link"; +import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; +import { useTheme } from "next-themes"; import { Menu, Transition } from "@headlessui/react"; +// icons import { LogIn, LogOut, MoveLeft, Plus, User, UserPlus } from "lucide-react"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; // ui import { Avatar, Tooltip } from "@plane/ui"; -import { Fragment } from "react"; -import { mutate } from "swr"; -import { useRouter } from "next/router"; +// hooks import useToast from "hooks/use-toast"; -import { useTheme } from "next-themes"; const SIDEBAR_LINKS = [ { @@ -28,6 +30,11 @@ const SIDEBAR_LINKS = [ ]; export const ProfileLayoutSidebar = observer(() => { + // states + const [isScrolled, setIsScrolled] = useState(false); // scroll animation state + // refs + const containerRef = useRef(null); + const router = useRouter(); const { setTheme } = useTheme(); @@ -62,6 +69,27 @@ export const ProfileLayoutSidebar = observer(() => { ); }; + /** + * Implementing scroll animation styles based on the scroll length of the container + */ + useEffect(() => { + const handleScroll = () => { + if (containerRef.current) { + const scrollTop = containerRef.current.scrollTop; + setIsScrolled(scrollTop > 0); + } + }; + const currentContainerRef = containerRef.current; + if (currentContainerRef) { + currentContainerRef.addEventListener("scroll", handleScroll); + } + return () => { + if (currentContainerRef) { + currentContainerRef.removeEventListener("scroll", handleScroll); + } + }; + }, []); + return (
{ ))}
{workspaces && workspaces.length > 0 && ( -
+
{!sidebarCollapsed && (
Your workspaces
)} -
+
{workspaces.map((workspace) => ( {
)} -
+
+
+ {tokens.length > 0 ? ( + <> +
+

API tokens

+ +
+
+ {tokens.map((token) => ( + + ))} +
+ + ) : ( +
+ setIsCreateTokenModalOpen(true)} />
-
- {tokens.map((token) => ( - - ))} -
-
- ) : ( -
- setIsCreateTokenModalOpen(true)} /> -
- ) + )} + ) : (
diff --git a/web/pages/invitations/index.tsx b/web/pages/invitations/index.tsx index d950b13db..731921a10 100644 --- a/web/pages/invitations/index.tsx +++ b/web/pages/invitations/index.tsx @@ -4,6 +4,7 @@ import Image from "next/image"; import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; import { useTheme } from "next-themes"; +import { observer } from "mobx-react-lite"; // services import { WorkspaceService } from "services/workspace.service"; import { UserService } from "services/user.service"; @@ -30,15 +31,23 @@ import type { IWorkspaceMemberInvitation } from "types"; import { ROLE } from "constants/workspace"; // components import { EmptyState } from "components/common"; +// mobx-store +import { useMobxStore } from "lib/mobx/store-provider"; // services const workspaceService = new WorkspaceService(); const userService = new UserService(); -const UserInvitationsPage: NextPageWithLayout = () => { +const UserInvitationsPage: NextPageWithLayout = observer(() => { const [invitationsRespond, setInvitationsRespond] = useState([]); const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false); + // store + const { + workspace: { workspaceSlug }, + user: { currentUserSettings }, + } = useMobxStore(); + const router = useRouter(); const { theme } = useTheme(); @@ -51,6 +60,12 @@ const UserInvitationsPage: NextPageWithLayout = () => { workspaceService.userWorkspaceInvitations() ); + const redirectWorkspaceSlug = + workspaceSlug || + currentUserSettings?.workspace?.last_workspace_slug || + currentUserSettings?.workspace?.fallback_workspace_slug || + ""; + const handleInvitation = (workspace_invitation: IWorkspaceMemberInvitation, action: "accepted" | "withdraw") => { if (action === "accepted") { setInvitationsRespond((prevData) => [...prevData, workspace_invitation.id]); @@ -180,7 +195,7 @@ const UserInvitationsPage: NextPageWithLayout = () => { > Accept & Join - +
@@ -206,7 +221,7 @@ const UserInvitationsPage: NextPageWithLayout = () => { ) : null}
); -}; +}); UserInvitationsPage.getLayout = function getLayout(page: ReactElement) { return (