[WEB-4245] improvement: minor enhancements to project members settings page (#7153)
This commit is contained in:
parent
7766e8b5cf
commit
e70105235b
4 changed files with 32 additions and 77 deletions
|
|
@ -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>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 />
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue