chore: guest user profile access-related problem (#3089)

* fix: resolve guest user profile access-related problem

* chore: header and app sidebar permission validation added
This commit is contained in:
Anmol Singh Bhatia 2023-12-13 23:05:50 +05:30 committed by GitHub
parent 2605b938f0
commit 6c61fbd102
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 37 deletions

View File

@ -16,6 +16,7 @@ import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOption
// constants
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue";
import { EFilterType } from "store/issues/types";
import { EUserWorkspaceRoles } from "constants/workspace";
const GLOBAL_VIEW_LAYOUTS = [
{ key: "list", title: "List", link: "/workspace-views", icon: List },
@ -38,7 +39,7 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
workspace: { workspaceLabels },
workspaceMember: { workspaceMembers },
project: { workspaceProjects },
user: { currentWorkspaceRole },
workspaceGlobalIssuesFilter: { issueFilters, updateFilters },
} = useMobxStore();
@ -77,6 +78,8 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
[workspaceSlug, updateFilters]
);
const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
return (
<>
<CreateUpdateWorkspaceViewModal isOpen={createViewModal} onClose={() => setCreateViewModal(false)} />
@ -142,10 +145,11 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
</FiltersDropdown>
</>
)}
<Button variant="primary" size="sm" prependIcon={<PlusIcon />} onClick={() => setCreateViewModal(true)}>
New View
</Button>
{isAuthorizedUser && (
<Button variant="primary" size="sm" prependIcon={<PlusIcon />} onClick={() => setCreateViewModal(true)}>
New View
</Button>
)}
</div>
</div>
</>

View File

@ -5,6 +5,8 @@ import { Breadcrumbs, Button } from "@plane/ui";
// hooks
import { useMobxStore } from "lib/mobx/store-provider";
import { observer } from "mobx-react-lite";
// constants
import { EUserWorkspaceRoles } from "constants/workspace";
export const ProjectsHeader = observer(() => {
const router = useRouter();
@ -15,10 +17,13 @@ export const ProjectsHeader = observer(() => {
project: projectStore,
commandPalette: commandPaletteStore,
trackEvent: { setTrackElement },
user: { currentWorkspaceRole },
} = useMobxStore();
const projectsList = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : [];
const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
@ -44,17 +49,18 @@ export const ProjectsHeader = observer(() => {
/>
</div>
)}
<Button
prependIcon={<Plus />}
size="sm"
onClick={() => {
setTrackElement("PROJECTS_PAGE_HEADER");
commandPaletteStore.toggleCreateProjectModal(true);
}}
>
Add Project
</Button>
{isAuthorizedUser && (
<Button
prependIcon={<Plus />}
size="sm"
onClick={() => {
setTrackElement("PROJECTS_PAGE_HEADER");
commandPaletteStore.toggleCreateProjectModal(true);
}}
>
Add Project
</Button>
)}
</div>
</div>
);

View File

@ -17,6 +17,8 @@ import { orderArrayBy } from "helpers/array.helper";
import { IProject } from "types";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// constants
import { EUserWorkspaceRoles } from "constants/workspace";
export const ProjectSidebarList: FC = observer(() => {
// states
@ -31,6 +33,7 @@ export const ProjectSidebarList: FC = observer(() => {
project: { joinedProjects, favoriteProjects, orderProjectsWithSortOrder, updateProjectView },
commandPalette: { toggleCreateProjectModal },
trackEvent: { setTrackElement },
user: { currentWorkspaceRole },
} = useMobxStore();
// router
const router = useRouter();
@ -39,6 +42,8 @@ export const ProjectSidebarList: FC = observer(() => {
// toast
const { setToastAlert } = useToast();
const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
const orderedJoinedProjects: IProject[] | undefined = joinedProjects
? orderArrayBy(joinedProjects, "sort_order", "ascending")
: undefined;
@ -138,16 +143,18 @@ export const ProjectSidebarList: FC = observer(() => {
<ChevronRight className="h-3 w-3 opacity-0 group-hover:opacity-100" />
)}
</Disclosure.Button>
<button
className="opacity-0 group-hover:opacity-100"
onClick={() => {
setTrackElement("APP_SIDEBAR_FAVORITES_BLOCK");
setIsFavoriteProjectCreate(true);
setIsProjectModalOpen(true);
}}
>
<Plus className="h-3 w-3" />
</button>
{isAuthorizedUser && (
<button
className="opacity-0 group-hover:opacity-100"
onClick={() => {
setTrackElement("APP_SIDEBAR_FAVORITES_BLOCK");
setIsFavoriteProjectCreate(true);
setIsProjectModalOpen(true);
}}
>
<Plus className="h-3 w-3" />
</button>
)}
</div>
)}
<Transition
@ -213,15 +220,17 @@ export const ProjectSidebarList: FC = observer(() => {
<ChevronRight className="h-3 w-3 opacity-0 group-hover:opacity-100" />
)}
</Disclosure.Button>
<button
className="opacity-0 group-hover:opacity-100"
onClick={() => {
setIsFavoriteProjectCreate(false);
setIsProjectModalOpen(true);
}}
>
<Plus className="h-3 w-3" />
</button>
{isAuthorizedUser && (
<button
className="opacity-0 group-hover:opacity-100"
onClick={() => {
setIsFavoriteProjectCreate(false);
setIsProjectModalOpen(true);
}}
>
<Plus className="h-3 w-3" />
</button>
)}
</div>
)}
<Transition
@ -260,7 +269,7 @@ export const ProjectSidebarList: FC = observer(() => {
</Droppable>
</DragDropContext>
{joinedProjects && joinedProjects.length === 0 && (
{isAuthorizedUser && joinedProjects && joinedProjects.length === 0 && (
<button
type="button"
className="flex w-full items-center gap-2 px-3 text-sm text-custom-sidebar-text-200"

View File

@ -1,4 +1,5 @@
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// components
@ -14,6 +15,7 @@ const AUTHORIZED_ROLES = [20, 15, 10];
export const ProfileAuthWrapper: React.FC<Props> = observer((props) => {
const { children, className, showProfileIssuesFilter } = props;
const router = useRouter();
const {
user: { currentWorkspaceRole },
@ -23,12 +25,14 @@ export const ProfileAuthWrapper: React.FC<Props> = observer((props) => {
const isAuthorized = AUTHORIZED_ROLES.includes(currentWorkspaceRole);
const isAuthorizedPath = router.pathname.includes("assigned" || "created" || "subscribed");
return (
<div className="h-full w-full md:flex md:flex-row-reverse md:overflow-hidden">
<ProfileSidebar />
<div className="flex w-full flex-col md:h-full md:overflow-hidden">
<ProfileNavbar isAuthorized={isAuthorized} showProfileIssuesFilter={showProfileIssuesFilter} />
{isAuthorized ? (
{isAuthorized || !isAuthorizedPath ? (
<div className={`w-full overflow-hidden md:h-full ${className}`}>{children}</div>
) : (
<div className="grid h-full w-full place-items-center text-custom-text-200">