[WEB-4245] improvement: minor enhancements to project members settings page (#7153)

This commit is contained in:
Prateek Shourya 2025-06-03 15:09:54 +05:30 committed by GitHub
parent 7766e8b5cf
commit e70105235b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 77 deletions

View file

@ -10,7 +10,7 @@ import { NotAuthorizedView } from "@/components/auth-screens";
import { PageHead } from "@/components/core";
import { ProjectMemberList, ProjectSettingsMemberDefaults } from "@/components/project";
// hooks
import { SettingsContentWrapper } from "@/components/settings";
import { SettingsContentWrapper, SettingsHeading } from "@/components/settings";
import { useProject, useUserPermissions } from "@/hooks/store";
// plane web imports
import { ProjectTeamspaceList } from "@/plane-web/components/projects/teamspaces";
@ -42,16 +42,10 @@ const MembersSettingsPage = observer(() => {
return (
<SettingsContentWrapper size="lg">
<PageHead title={pageTitle} />
<section className={`w-full`}>
<div className="flex items-center border-b border-custom-border-100 pb-3.5">
<div className="text-lg font-semibold">
{t(getProjectSettingsPageLabelI18nKey("members", "common.members"))}
</div>
</div>
<ProjectSettingsMemberDefaults projectId={projectId} workspaceSlug={workspaceSlug} />
<ProjectTeamspaceList projectId={projectId} workspaceSlug={workspaceSlug} />
<ProjectMemberList projectId={projectId} workspaceSlug={workspaceSlug} />
</section>
<SettingsHeading title={t(getProjectSettingsPageLabelI18nKey("members", "common.members"))} />
<ProjectSettingsMemberDefaults projectId={projectId} workspaceSlug={workspaceSlug} />
<ProjectTeamspaceList projectId={projectId} workspaceSlug={workspaceSlug} />
<ProjectMemberList projectId={projectId} workspaceSlug={workspaceSlug} />
</SettingsContentWrapper>
);
});

View file

@ -12,8 +12,6 @@ import { ProjectMemberListItem, SendProjectInvitationModal } from "@/components/
import { MembersSettingsLoader } from "@/components/ui";
// hooks
import { useEventTracker, useMember, useUserPermissions } from "@/hooks/store";
import { getProjectSettingsPageLabelI18nKey } from "@/plane-web/helpers/project-settings";
import { SettingsHeading } from "../settings";
type TProjectMemberListProps = {
projectId: string;
@ -58,35 +56,31 @@ export const ProjectMemberList: React.FC<TProjectMemberListProps> = observer((pr
projectId={projectId}
workspaceSlug={workspaceSlug}
/>
<SettingsHeading
title={t(getProjectSettingsPageLabelI18nKey("members", "common.members"))}
appendToRight={
<div className="flex gap-2">
<div className="ml-auto flex items-center justify-start gap-1 rounded-md border border-custom-border-200 bg-custom-background-100 px-2.5 py-1.5">
<Search className="h-3.5 w-3.5" />
<input
className="w-full max-w-[234px] border-none bg-transparent text-sm focus:outline-none placeholder:text-custom-text-400"
placeholder="Search"
value={searchQuery}
autoFocus
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
{isAdmin && (
<Button
variant="primary"
onClick={() => {
setTrackElement("PROJECT_SETTINGS_MEMBERS_PAGE_HEADER");
setInviteModal(true);
}}
>
{t("add_member")}
</Button>
)}
</div>
}
/>
<div className="flex items-center justify-between gap-4 py-2 overflow-x-hidden border-b border-custom-border-100">
<div className="text-base font-semibold">{t("common.members")}</div>
<div className="ml-auto flex items-center justify-start gap-1.5 rounded-md border border-custom-border-200 bg-custom-background-100 px-2 py-1">
<Search className="h-3.5 w-3.5" />
<input
className="w-full max-w-[234px] border-none bg-transparent text-sm focus:outline-none placeholder:text-custom-text-400"
placeholder="Search"
value={searchQuery}
autoFocus
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
{isAdmin && (
<Button
variant="primary"
size="sm"
onClick={() => {
setTrackElement("PROJECT_SETTINGS_MEMBERS_PAGE_HEADER");
setInviteModal(true);
}}
>
{t("add_member")}
</Button>
)}
</div>
{!projectMemberIds ? (
<MembersSettingsLoader />
) : (

View file

@ -16,7 +16,7 @@ export const SettingsContentWrapper = observer((props: TProps) => {
"md:px-16": size === "lg",
})}
>
<div className="pb-20 w-full">{children}</div>
<div className="pb-10 w-full">{children}</div>
</div>
);
});

View file

@ -1,43 +1,10 @@
import { useEffect, useRef } from "react";
import throttle from "lodash/throttle";
import { useRef } from "react";
import { observer } from "mobx-react";
import { useUserSettings } from "@/hooks/store";
export const SettingsContentLayout = observer(({ children }: { children: React.ReactNode }) => {
// refs
const ref = useRef<HTMLDivElement>(null);
const scrolledRef = useRef(false);
// store hooks
const { toggleIsScrolled, isScrolled } = useUserSettings();
useEffect(() => {
toggleIsScrolled(false);
const container = ref.current;
if (!container) return;
const handleScroll = () => {
const scrollTop = container.scrollTop;
if (container.scrollHeight > container.clientHeight || scrolledRef.current) {
const _isScrolled = scrollTop > 0;
toggleIsScrolled(_isScrolled);
}
};
// Throttle the scroll handler to improve performance
// Set trailing to true to ensure the last call runs after the delay
const throttledHandleScroll = throttle(handleScroll, 150);
container.addEventListener("scroll", throttledHandleScroll);
return () => {
container.removeEventListener("scroll", throttledHandleScroll);
// Cancel any pending throttled invocations when unmounting
throttledHandleScroll.cancel();
};
}, []);
useEffect(() => {
scrolledRef.current = isScrolled;
}, [isScrolled]);
return (
<div className="w-full h-full min-h-full overflow-y-scroll " ref={ref}>
{children}