[WEB-2126] chore: guest and viewer role permission (#5347)
* chore: user store code refactor * chore: general unauthorized screen asset added * chore: workspace setting sidebar options updated for guest and viewer * chore: NotAuthorizedView component code updated * chore: project setting layout code refactor * chore: workspace setting members and exports page permission validation added * chore: workspace members and exports settings page improvement * chore: project invite modal updated * chore: workspace setting unauthorized access empty state * chore: workspace setting unauthorized access empty state * chore: project settings sidebar permission updated * fix: project settings user role permission updated * chore: app sidebar role permission validation updated * chore: app sidebar role permission validation * chore: disabled page empty state validation * chore: app sidebar add project improvement * chore: guest role changes * fix: user favorite * chore: changed pages permission * chore: guest role changes * fix: app sidebar project item permission * fix: project setting empty state flicker * fix: workspace setting empty state flicker * chore: granted notification permission to viewer * chore: project invite and edit validation updated * chore: favorite validation added for guest and viewer role * chore: create view validation updated * chore: views permission changes * chore: create view empty state validation updated * chore: created ENUM for permissions --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com>
This commit is contained in:
parent
d60e988ca1
commit
0a1c656865
62 changed files with 957 additions and 590 deletions
|
|
@ -45,7 +45,7 @@ import { EUserProjectRoles } from "@/constants/project";
|
|||
// helpers
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
// hooks
|
||||
import { useAppTheme, useEventTracker, useProject } from "@/hooks/store";
|
||||
import { useAppTheme, useEventTracker, useProject, useUser } from "@/hooks/store";
|
||||
import useOutsideClickDetector from "@/hooks/use-outside-click-detector";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// constants
|
||||
|
|
@ -70,31 +70,37 @@ const navigation = (workspaceSlug: string, projectId: string) => [
|
|||
name: "Issues",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/issues`,
|
||||
Icon: LayersIcon,
|
||||
access: EUserProjectRoles.GUEST,
|
||||
},
|
||||
{
|
||||
name: "Cycles",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/cycles`,
|
||||
Icon: ContrastIcon,
|
||||
access: EUserProjectRoles.VIEWER,
|
||||
},
|
||||
{
|
||||
name: "Modules",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/modules`,
|
||||
Icon: DiceIcon,
|
||||
access: EUserProjectRoles.VIEWER,
|
||||
},
|
||||
{
|
||||
name: "Views",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/views`,
|
||||
Icon: Layers,
|
||||
access: EUserProjectRoles.GUEST,
|
||||
},
|
||||
{
|
||||
name: "Pages",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/pages`,
|
||||
Icon: FileText,
|
||||
access: EUserProjectRoles.VIEWER,
|
||||
},
|
||||
{
|
||||
name: "Intake",
|
||||
href: `/${workspaceSlug}/projects/${projectId}/inbox`,
|
||||
Icon: Intake,
|
||||
access: EUserProjectRoles.GUEST,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -106,6 +112,9 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
|
|||
const { setTrackElement } = useEventTracker();
|
||||
const { addProjectToFavorites, removeProjectFromFavorites, getProjectById } = useProject();
|
||||
const { isMobile } = usePlatformOS();
|
||||
const {
|
||||
membership: { currentWorkspaceAllProjectsRole },
|
||||
} = useUser();
|
||||
// states
|
||||
const [leaveProjectModalOpen, setLeaveProjectModal] = useState(false);
|
||||
const [publishModalOpen, setPublishModal] = useState(false);
|
||||
|
|
@ -378,16 +387,20 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
|
|||
customButtonClassName="grid place-items-center"
|
||||
placement="bottom-start"
|
||||
>
|
||||
<CustomMenu.MenuItem onClick={project.is_favorite ? handleRemoveFromFavorites : handleAddToFavorites}>
|
||||
<span className="flex items-center justify-start gap-2">
|
||||
<Star
|
||||
className={cn("h-3.5 w-3.5 ", {
|
||||
"fill-yellow-500 stroke-yellow-500": project.is_favorite,
|
||||
})}
|
||||
/>
|
||||
<span>{project.is_favorite ? "Remove from favorites" : "Add to favorites"}</span>
|
||||
</span>
|
||||
</CustomMenu.MenuItem>
|
||||
{!isViewerOrGuest && (
|
||||
<CustomMenu.MenuItem
|
||||
onClick={project.is_favorite ? handleRemoveFromFavorites : handleAddToFavorites}
|
||||
>
|
||||
<span className="flex items-center justify-start gap-2">
|
||||
<Star
|
||||
className={cn("h-3.5 w-3.5 ", {
|
||||
"fill-yellow-500 stroke-yellow-500": project.is_favorite,
|
||||
})}
|
||||
/>
|
||||
<span>{project.is_favorite ? "Remove from favorites" : "Add to favorites"}</span>
|
||||
</span>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
|
||||
{/* publish project settings */}
|
||||
{isAdmin && (
|
||||
|
|
@ -400,14 +413,16 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
|
|||
</div>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
<CustomMenu.MenuItem>
|
||||
<Link href={`/${workspaceSlug}/projects/${project?.id}/draft-issues/`}>
|
||||
<div className="flex items-center justify-start gap-2">
|
||||
<PenSquare className="h-3.5 w-3.5 stroke-[1.5] text-custom-text-300" />
|
||||
<span>Draft issues</span>
|
||||
</div>
|
||||
</Link>
|
||||
</CustomMenu.MenuItem>
|
||||
{!isViewerOrGuest && (
|
||||
<CustomMenu.MenuItem>
|
||||
<Link href={`/${workspaceSlug}/projects/${project?.id}/draft-issues/`}>
|
||||
<div className="flex items-center justify-start gap-2">
|
||||
<PenSquare className="h-3.5 w-3.5 stroke-[1.5] text-custom-text-300" />
|
||||
<span>Draft issues</span>
|
||||
</div>
|
||||
</Link>
|
||||
</CustomMenu.MenuItem>
|
||||
)}
|
||||
<CustomMenu.MenuItem onClick={handleCopyText}>
|
||||
<span className="flex items-center justify-start gap-2">
|
||||
<LinkIcon className="h-3.5 w-3.5 stroke-[1.5]" />
|
||||
|
|
@ -482,31 +497,37 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
|
|||
(item.name === "Intake" && !project.inbox_view)
|
||||
)
|
||||
return;
|
||||
|
||||
const currentRole = currentWorkspaceAllProjectsRole
|
||||
? currentWorkspaceAllProjectsRole[projectId]
|
||||
: undefined;
|
||||
return (
|
||||
<Tooltip
|
||||
key={item.name}
|
||||
isMobile={isMobile}
|
||||
tooltipContent={`${project?.name}: ${item.name}`}
|
||||
position="right"
|
||||
className="ml-2"
|
||||
disabled={!isSidebarCollapsed}
|
||||
>
|
||||
<Link key={item.name} href={item.href} onClick={handleProjectClick}>
|
||||
<SidebarNavItem
|
||||
<>
|
||||
{currentRole >= item.access && (
|
||||
<Tooltip
|
||||
key={item.name}
|
||||
className={`pl-[18px] ${isSidebarCollapsed ? "p-0 size-7 justify-center mx-auto" : ""}`}
|
||||
isActive={pathname.includes(item.href)}
|
||||
isMobile={isMobile}
|
||||
tooltipContent={`${project?.name}: ${item.name}`}
|
||||
position="right"
|
||||
className="ml-2"
|
||||
disabled={!isSidebarCollapsed}
|
||||
>
|
||||
<div className="flex items-center gap-1.5 py-[1px]">
|
||||
<item.Icon
|
||||
className={`flex-shrink-0 size-4 ${item.name === "Intake" ? "stroke-1" : "stroke-[1.5]"}`}
|
||||
/>
|
||||
{!isSidebarCollapsed && <span className="text-xs font-medium">{item.name}</span>}
|
||||
</div>
|
||||
</SidebarNavItem>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
<Link key={item.name} href={item.href} onClick={handleProjectClick}>
|
||||
<SidebarNavItem
|
||||
key={item.name}
|
||||
className={`pl-[18px] ${isSidebarCollapsed ? "p-0 size-7 justify-center mx-auto" : ""}`}
|
||||
isActive={pathname.includes(item.href)}
|
||||
>
|
||||
<div className="flex items-center gap-1.5 py-[1px]">
|
||||
<item.Icon
|
||||
className={`flex-shrink-0 size-4 ${item.name === "Intake" ? "stroke-1" : "stroke-[1.5]"}`}
|
||||
/>
|
||||
{!isSidebarCollapsed && <span className="text-xs font-medium">{item.name}</span>}
|
||||
</div>
|
||||
</SidebarNavItem>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</Disclosure.Panel>
|
||||
|
|
|
|||
|
|
@ -263,7 +263,6 @@ export const SidebarProjectsList: FC = observer(() => {
|
|||
toggleCreateProjectModal(true);
|
||||
}}
|
||||
>
|
||||
<Plus className="flex-shrink-0 size-4" />
|
||||
{!isCollapsed && "Add project"}
|
||||
</button>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue