diff --git a/frontend/src/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.tsx b/frontend/src/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.tsx
index 2140887de..c386ebc11 100644
--- a/frontend/src/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.tsx
+++ b/frontend/src/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.tsx
@@ -14,7 +14,8 @@ import {
faShield,
faTags,
faUser,
- faUsers} from "@fortawesome/free-solid-svg-icons";
+ faUsers
+} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod";
diff --git a/frontend/src/views/Project/RolePage/RolePage.tsx b/frontend/src/views/Project/RolePage/RolePage.tsx
index 235c28974..19ec657ec 100644
--- a/frontend/src/views/Project/RolePage/RolePage.tsx
+++ b/frontend/src/views/Project/RolePage/RolePage.tsx
@@ -20,9 +20,7 @@ import { withProjectPermission } from "@app/hoc";
import { useGetProjectRoleBySlug } from "@app/hooks/api";
import { usePopUp } from "@app/hooks/usePopUp";
-import { RoleDetailsSection, RolePermissionsSection } from "./components";
-
-// import { RoleDetailsSection, RoleModal, RolePermissionsSection } from "./components";
+import { RoleDetailsSection, RoleModal,RolePermissionsSection } from "./components";
export const RolePage = withProjectPermission(
() => {
@@ -66,7 +64,7 @@ export const RolePage = withProjectPermission(
}
};
- const isCustomRole = !["admin", "member", "no-access"].includes(data?.slug ?? "");
+ const isCustomRole = !["admin", "member", "viewer", "no-access"].includes(data?.slug ?? "");
return (
@@ -148,7 +146,7 @@ export const RolePage = withProjectPermission(
)}
- {/* */}
+
, data?: {}) => void;
+ handlePopUpOpen: (popUpName: keyof UsePopUpState<["role"]>, data?: {}) => void;
};
-export const RoleDetailsSection = ({
- roleSlug
-}: // handlePopUpOpen
-Props) => {
+export const RoleDetailsSection = ({ roleSlug, handlePopUpOpen }: Props) => {
const [copyTextId, isCopyingId, setCopyTextId] = useTimedReset({
initialState: "Copy ID to clipboard"
});
@@ -41,10 +38,9 @@ Props) => {
variant="plain"
className="group relative"
onClick={() => {
- // TODO
- // handlePopUpOpen("role", {
- // roleId
- // })
+ handlePopUpOpen("role", {
+ roleSlug
+ });
}}
>
diff --git a/frontend/src/views/Project/RolePage/components/RoleModal.tsx b/frontend/src/views/Project/RolePage/components/RoleModal.tsx
new file mode 100644
index 000000000..463f36a78
--- /dev/null
+++ b/frontend/src/views/Project/RolePage/components/RoleModal.tsx
@@ -0,0 +1,231 @@
+import { useEffect } from "react";
+import { Controller, useForm } from "react-hook-form";
+// import { useRouter } from "next/router";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { z } from "zod";
+
+import { createNotification } from "@app/components/notifications";
+import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2";
+import {
+ // useOrganization,
+ useWorkspace
+} from "@app/context";
+import {
+ // useCreateProjectRole,
+ // useUpdateProjectRole,
+ useGetProjectRoleBySlug
+ // useCreateOrgRole,
+ // useGetOrgRole,
+ // useUpdateOrgRole
+} from "@app/hooks/api";
+import { UsePopUpState } from "@app/hooks/usePopUp";
+
+const schema = z
+ .object({
+ name: z.string(),
+ description: z.string(),
+ slug: z.string()
+ })
+ .required();
+
+export type FormData = z.infer;
+
+type Props = {
+ popUp: UsePopUpState<["role"]>;
+ handlePopUpToggle: (popUpName: keyof UsePopUpState<["role"]>, state?: boolean) => void;
+};
+
+export const RoleModal = ({ popUp, handlePopUpToggle }: Props) => {
+ // const router = useRouter();
+
+ const popupData = popUp?.role?.data as {
+ roleSlug: string;
+ };
+
+ const { currentWorkspace } = useWorkspace();
+ const projectSlug = currentWorkspace?.slug || "";
+
+ const { data: role } = useGetProjectRoleBySlug(projectSlug, popupData?.roleSlug ?? "");
+
+ console.log("Project RoleModal role: ", role);
+
+ // const { mutateAsync: createProjectRole } = useCreateProjectRole();
+ // const { mutateAsync: updateProjectRole } = useUpdateProjectRole();
+
+ const {
+ control,
+ handleSubmit,
+ reset,
+ formState: { isSubmitting }
+ } = useForm({
+ resolver: zodResolver(schema),
+ defaultValues: {
+ name: "",
+ description: ""
+ }
+ });
+
+ useEffect(() => {
+ if (role) {
+ reset({
+ name: role.name,
+ description: role.description,
+ slug: role.slug
+ });
+ } else {
+ reset({
+ name: "",
+ description: "",
+ slug: ""
+ });
+ }
+ }, [role]);
+
+ const onFormSubmit = async ({ name, description, slug }: FormData) => {
+ try {
+ console.log("onFormSubmit args: ", {
+ name,
+ description,
+ slug
+ });
+
+ if (!projectSlug || !role?.id) return;
+
+ if (role) {
+ // update
+ console.log("update");
+ // const u1 = await updateProjectRole({
+ // id: role.id,
+ // projectSlug,
+ // name,
+ // description,
+ // slug
+ // });
+ // console.log("u1: ", u1);
+ } else {
+ // create
+ console.log("create");
+ }
+
+ // if (!orgId) return;
+
+ // if (role) {
+ // // update
+
+ // await updateOrgRole({
+ // orgId,
+ // id: role.id,
+ // name,
+ // description,
+ // slug
+ // });
+
+ // handlePopUpToggle("role", false);
+ // } else {
+ // // create
+
+ // const newRole = await createOrgRole({
+ // orgId,
+ // name,
+ // description,
+ // slug,
+ // permissions: []
+ // });
+
+ // handlePopUpToggle("role", false);
+ // router.push(`/org/${orgId}/roles/${newRole.id}`);
+ // }
+
+ createNotification({
+ text: `Successfully ${popUp?.role?.data ? "updated" : "created"} role`,
+ type: "success"
+ });
+
+ reset();
+ } catch (err) {
+ console.error(err);
+ const error = err as any;
+ const text =
+ error?.response?.data?.message ??
+ `Failed to ${popUp?.role?.data ? "update" : "create"} role`;
+
+ createNotification({
+ text,
+ type: "error"
+ });
+ }
+ };
+
+ return (
+ {
+ handlePopUpToggle("role", isOpen);
+ reset();
+ }}
+ >
+
+
+
+
+ );
+};
diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionSecretsRow.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionSecretsRow.tsx
index d36be71ae..786f58cf1 100644
--- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionSecretsRow.tsx
+++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionSecretsRow.tsx
@@ -1,16 +1,24 @@
import { useMemo } from "react";
-import {
- Control,
- // Controller,
- UseFormGetValues,
- UseFormSetValue,
- useWatch
-} from "react-hook-form";
-import { faChevronDown, faChevronRight } from "@fortawesome/free-solid-svg-icons";
+import { Control, Controller, UseFormGetValues, UseFormSetValue, useWatch } from "react-hook-form";
+import { faChevronDown } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Select, SelectItem,Td, Tr } from "@app/components/v2";
-import { useToggle } from "@app/hooks";
+import GlobPatternExamples from "@app/components/basic/popups/GlobPatternExamples";
+import {
+ Checkbox,
+ FormControl,
+ Input,
+ Select,
+ SelectItem,
+ Table,
+ TableContainer,
+ TBody,
+ Td,
+ Th,
+ THead,
+ Tr
+} from "@app/components/v2";
+import { useWorkspace } from "@app/context";
import { TFormSchema } from "@app/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.utils";
type Props = {
@@ -37,8 +45,14 @@ export const RowPermissionSecretsRow = ({
getValue,
control
}: Props) => {
- const [isRowExpanded, setIsRowExpanded] = useToggle();
- // const [isCustom, setIsCustom] = useToggle();
+ const { currentWorkspace } = useWorkspace();
+ const environments = currentWorkspace?.environments || [];
+
+ const customRule = useWatch({
+ control,
+ name: `permissions.${formName}.custom`
+ });
+ const isCustom = Boolean(customRule);
const allRule = useWatch({ control, name: `permissions.${formName}.all` });
@@ -83,17 +97,13 @@ export const RowPermissionSecretsRow = ({
};
return (
- setIsRowExpanded.toggle()}
- >
- |
-
- |
+ <>
+
+ | {isCustom && } |
{title} |
|
+ {isCustom && (
+
+
+
+
+
+
+
+ |
+
+
+ Secret Path
+
+
+
+
+ |
+ View |
+ Create |
+ Modify |
+ Delete |
+
+
+
+ {isCustom &&
+ environments.map(({ name, slug }) => (
+
+ | {name} |
+
+ (
+ /* eslint-disable-next-line no-template-curly-in-string */
+
+
+
+ )}
+ />
+ |
+
+ (
+
+
+
+ )}
+ />
+ |
+
+ (
+
+
+
+ )}
+ />
+ |
+
+ (
+
+
+
+ )}
+ />
+ |
+
+ (
+
+
+
+ )}
+ />
+ |
+
+ ))}
+
+
+
+
+ |
+
+ )}
+ >
);
};
diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx
index 3097520bc..6a03503ea 100644
--- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx
+++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx
@@ -2,27 +2,17 @@ import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { createNotification } from "@app/components/notifications";
+import { Button, Table, TableContainer, TBody, Th, THead, Tr } from "@app/components/v2";
+import { ProjectPermissionSub, useWorkspace } from "@app/context";
+import { useGetProjectRoleBySlug, useUpdateProjectRole } from "@app/hooks/api";
import {
- Button,
- Table,
- TableContainer,
- TBody,
- Th,
- THead,
- Tr
- // Td
-} from "@app/components/v2";
-import { ProjectPermissionSub,useWorkspace } from "@app/context";
-import {
- // useUpdateOrgRole,
- useGetProjectRoleBySlug
-} from "@app/hooks/api";
-import {
- formSchema,
+formRolePermission2API, formSchema,
rolePermission2Form,
- TFormSchema} from "@app/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.utils";
+ TFormSchema
+ } from "@app/views/Project/MembersPage/components/ProjectRoleListTab/components/ProjectRoleModifySection/ProjectRoleModifySection.utils";
import { RolePermissionRow } from "./RolePermissionRow";
+import { RowPermissionSecretsRow } from "./RolePermissionSecretsRow";
const SINGLE_PERMISSION_LIST = [
{
@@ -99,16 +89,15 @@ type Props = {
roleSlug: string;
};
-// TODO: fill table
-
+// note: isEditable should also depend on if user has edit role permission
export const RolePermissionsSection = ({ roleSlug }: Props) => {
const { currentWorkspace } = useWorkspace();
+ const projectSlug = currentWorkspace?.slug || "";
const { data: role } = useGetProjectRoleBySlug(currentWorkspace?.slug ?? "", roleSlug as string);
- console.log("RolePermissionsSection role data: ", role);
-
const {
setValue,
+ getValues,
control,
handleSubmit,
formState: { isDirty, isSubmitting },
@@ -118,16 +107,19 @@ export const RolePermissionsSection = ({ roleSlug }: Props) => {
resolver: zodResolver(formSchema)
});
- // const { mutateAsync: updateRole } = useUpdateOrgRole();
+ const { mutateAsync: updateRole } = useUpdateProjectRole();
- const onSubmit = async () => {
+ const onSubmit = async (el: TFormSchema) => {
try {
- // await updateRole({
- // orgId,
- // id: roleId,
- // ...el,
- // permissions: formRolePermission2API(el.permissions)
- // });
+ if (!projectSlug || !role?.id) return;
+
+ await updateRole({
+ id: role?.id as string,
+ projectSlug,
+ ...el,
+ permissions: formRolePermission2API(el.permissions)
+ });
+
createNotification({ type: "success", text: "Successfully updated role" });
} catch (err) {
console.log(err);
@@ -177,8 +169,15 @@ export const RolePermissionsSection = ({ roleSlug }: Props) => {
+
{SINGLE_PERMISSION_LIST.map((permission) => {
- console.log("permission: ", permission);
return (