feat: resolved ui issues related to permission based hiding

This commit is contained in:
=
2024-08-21 23:01:23 +05:30
parent cf3b2ebbca
commit 49a0d3cec6
4 changed files with 83 additions and 50 deletions
@@ -44,6 +44,13 @@ export type ProjectPermissionSet =
ProjectPermissionActions, ProjectPermissionActions,
ProjectPermissionSub.Secrets | (ForcedSubject<ProjectPermissionSub.Secrets> & SubjectFields) ProjectPermissionSub.Secrets | (ForcedSubject<ProjectPermissionSub.Secrets> & SubjectFields)
] ]
| [
ProjectPermissionActions,
(
| ProjectPermissionSub.SecretFolders
| (ForcedSubject<ProjectPermissionSub.SecretFolders> & SubjectFields)
)
]
| [ProjectPermissionActions, ProjectPermissionSub.Role] | [ProjectPermissionActions, ProjectPermissionSub.Role]
| [ProjectPermissionActions, ProjectPermissionSub.Tags] | [ProjectPermissionActions, ProjectPermissionSub.Tags]
| [ProjectPermissionActions, ProjectPermissionSub.Member] | [ProjectPermissionActions, ProjectPermissionSub.Member]
@@ -151,6 +151,7 @@ export const RowPermissionSecretsRow = ({
<Controller <Controller
name={`permissions.${formName}.${slug}.secretPath`} name={`permissions.${formName}.${slug}.secretPath`}
control={control} control={control}
defaultValue="/**"
render={({ field }) => ( render={({ field }) => (
/* eslint-disable-next-line no-template-curly-in-string */ /* eslint-disable-next-line no-template-curly-in-string */
<FormControl helperText="Supports glob path pattern string"> <FormControl helperText="Supports glob path pattern string">
@@ -405,8 +405,21 @@ export const SecretOverviewPage = () => {
const pathSegment = secretPath.split("/").filter(Boolean); const pathSegment = secretPath.split("/").filter(Boolean);
const parentPath = `/${pathSegment.slice(0, -1).join("/")}`; const parentPath = `/${pathSegment.slice(0, -1).join("/")}`;
const folderName = pathSegment.at(-1); const folderName = pathSegment.at(-1);
console.log(folderName, parentPath); const canCreateFolder = permission.rules.some((rule) =>
if (folderName && parentPath) { (rule.subject as ProjectPermissionSub[]).includes(ProjectPermissionSub.SecretFolders)
)
? permission.can(
ProjectPermissionActions.Create,
subject(ProjectPermissionSub.SecretFolders, {
environment: slug,
secretPath: parentPath
})
)
: permission.can(
ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment: slug, secretPath: parentPath })
);
if (folderName && parentPath && canCreateFolder) {
await createFolder({ await createFolder({
projectId: workspaceId, projectId: workspaceId,
environment: slug, environment: slug,
@@ -584,22 +597,14 @@ export const SecretOverviewPage = () => {
</div> </div>
{userAvailableEnvs.length > 0 && ( {userAvailableEnvs.length > 0 && (
<div> <div>
<ProjectPermissionCan
I={ProjectPermissionActions.Create}
a={subject(ProjectPermissionSub.Secrets, { secretPath })}
>
{(isAllowed) => (
<Button <Button
variant="outline_bg" variant="outline_bg"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("addSecretsInAllEnvs")} onClick={() => handlePopUpOpen("addSecretsInAllEnvs")}
className="h-10 rounded-r-none" className="h-10 rounded-r-none"
isDisabled={!isAllowed}
> >
Add Secret Add Secret
</Button> </Button>
)}
</ProjectPermissionCan>
<DropdownMenu <DropdownMenu
open={popUp.misc.isOpen} open={popUp.misc.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("misc", isOpen)} onOpenChange={(isOpen) => handlePopUpToggle("misc", isOpen)}
@@ -1,5 +1,6 @@
import { ClipboardEvent } from "react"; import { ClipboardEvent } from "react";
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import { subject } from "@casl/ability";
import { faWarning } from "@fortawesome/free-solid-svg-icons"; import { faWarning } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
@@ -17,7 +18,12 @@ import {
Tooltip Tooltip
} from "@app/components/v2"; } from "@app/components/v2";
import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput"; import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput";
import { useWorkspace } from "@app/context"; import {
ProjectPermissionActions,
ProjectPermissionSub,
useProjectPermission,
useWorkspace
} from "@app/context";
import { getKeyValue } from "@app/helpers/parseEnvVar"; import { getKeyValue } from "@app/helpers/parseEnvVar";
import { useCreateFolder, useCreateSecretV3, useUpdateSecretV3 } from "@app/hooks/api"; import { useCreateFolder, useCreateSecretV3, useUpdateSecretV3 } from "@app/hooks/api";
import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/types"; import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/types";
@@ -62,6 +68,7 @@ export const CreateSecretForm = ({
const newSecretKey = watch("key"); const newSecretKey = watch("key");
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const { permission } = useProjectPermission();
const workspaceId = currentWorkspace?.id || ""; const workspaceId = currentWorkspace?.id || "";
const environments = currentWorkspace?.environments || []; const environments = currentWorkspace?.environments || [];
@@ -186,7 +193,17 @@ export const CreateSecretForm = ({
/> />
<FormLabel label="Environments" className="mb-2" /> <FormLabel label="Environments" className="mb-2" />
<div className="thin-scrollbar grid max-h-64 grid-cols-3 gap-4 overflow-auto py-2"> <div className="thin-scrollbar grid max-h-64 grid-cols-3 gap-4 overflow-auto py-2">
{environments.map((env) => { {environments
.filter((environmentSlug) =>
permission.can(
ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, {
environment: environmentSlug.slug,
secretPath
})
)
)
.map((env) => {
return ( return (
<Controller <Controller
name={`environments.${env.slug}`} name={`environments.${env.slug}`}
@@ -209,7 +226,10 @@ export const CreateSecretForm = ({
className="max-w-[150px]" className="max-w-[150px]"
content="Secret already exists, and it will be overwritten" content="Secret already exists, and it will be overwritten"
> >
<FontAwesomeIcon icon={faWarning} className="ml-1 text-yellow-400" /> <FontAwesomeIcon
icon={faWarning}
className="ml-1 text-yellow-400"
/>
</Tooltip> </Tooltip>
)} )}
</span> </span>