feat: removed form in member and identity table, and added ellipsis for noting icons

This commit is contained in:
=
2024-10-23 01:33:23 +05:30
parent a1c2bc695c
commit f2b852a09e
9 changed files with 44 additions and 119 deletions

View File

@@ -69,7 +69,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
actorAuthMethod: req.permission.authMethod,
projectMembershipId: req.body.projectMembershipId,
...req.body.type,
slug: req.body.slug || slugify(alphaNumericNanoId(8).toLowerCase()),
slug: req.body.slug || slugify(alphaNumericNanoId(8)),
permissions: JSON.stringify(packRules(req.body.permissions))
});
return { privilege };

View File

@@ -77,7 +77,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
projectId: req.body.projectId,
identityId: req.body.identityId,
...req.body.type,
slug: req.body.slug || slugify(alphaNumericNanoId(8).toLowerCase()),
slug: req.body.slug || slugify(alphaNumericNanoId(8)),
permissions: JSON.stringify(packRules(req.body.permissions))
});
return { privilege };

View File

@@ -18,6 +18,7 @@ import { createNotification } from "@app/components/notifications";
import {
Button,
FormControl,
FormLabel,
IconButton,
Input,
Modal,
@@ -133,9 +134,8 @@ export const IdentityProjectAdditionalPrivilegeModifySection = ({
const onSubmit = async (el: TFormSchema) => {
const accessType = !el.temporaryAccess.isTemporary
? { role: el.slug, isTemporary: false as const }
? { isTemporary: false as const }
: {
role: el.slug,
isTemporary: true as const,
temporaryMode: IdentityProjectAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: el.temporaryAccess.temporaryRange,
@@ -270,6 +270,7 @@ export const IdentityProjectAdditionalPrivilegeModifySection = ({
<Popover>
<PopoverTrigger disabled={isIdentityEditDisabled} asChild>
<div className="w-full max-w-md flex-grow">
<FormLabel label="Access Type" />
<Tooltip content={toolTipText}>
<Button
variant="outline_bg"

View File

@@ -1,4 +1,4 @@
import { faFolder, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { faEllipsisV, faFolder, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { format, formatDistance } from "date-fns";
import { AnimatePresence, motion } from "framer-motion";
@@ -189,7 +189,7 @@ export const IdentityProjectAdditionalPrivilegeSection = ({ identityMembershipDe
</Tooltip>
</Td>
<Td>
<div className="opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<div className="flex space-x-2 opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<ProjectPermissionCan
I={ProjectPermissionActions.Edit}
a={ProjectPermissionSub.Identity}
@@ -216,6 +216,9 @@ export const IdentityProjectAdditionalPrivilegeSection = ({ identityMembershipDe
</IconButton>
)}
</ProjectPermissionCan>
<IconButton ariaLabel="more-icon" variant="plain">
<FontAwesomeIcon icon={faEllipsisV} />
</IconButton>
</div>
</Td>
</Tr>

View File

@@ -1,4 +1,4 @@
import { faFolder, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { faEllipsisV, faFolder, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { format, formatDistance } from "date-fns";
import { AnimatePresence, motion } from "framer-motion";
@@ -196,7 +196,7 @@ export const MemberProjectAdditionalPrivilegeSection = ({ membershipDetails }: P
</Tooltip>
</Td>
<Td>
<div className="opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<div className="flex space-x-2 opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<ProjectPermissionCan
I={ProjectPermissionActions.Edit}
a={ProjectPermissionSub.Member}
@@ -206,7 +206,7 @@ export const MemberProjectAdditionalPrivilegeSection = ({ membershipDetails }: P
{(isAllowed) => (
<IconButton
colorSchema="danger"
ariaLabel="copy icon"
ariaLabel="delete-icon"
variant="plain"
className="group relative"
isDisabled={!isAllowed || isOwnProjectMembershipDetails}
@@ -223,6 +223,13 @@ export const MemberProjectAdditionalPrivilegeSection = ({ membershipDetails }: P
</IconButton>
)}
</ProjectPermissionCan>
<IconButton
ariaLabel="more-icon"
variant="plain"
className="group relative"
>
<FontAwesomeIcon icon={faEllipsisV} />
</IconButton>
</div>
</Td>
</Tr>

View File

@@ -18,6 +18,7 @@ import { createNotification } from "@app/components/notifications";
import {
Button,
FormControl,
FormLabel,
IconButton,
Input,
Modal,
@@ -93,6 +94,8 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({
const { data: privilegeDetails, isLoading } = useGetProjectUserPrivilegeDetails(
privilegeId || ""
);
console.log(privilegeDetails);
const { permission } = useProjectPermission();
const isMemberEditDisabled = permission.cannot(
ProjectPermissionActions.Edit,
@@ -131,9 +134,8 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({
const onSubmit = async (el: TFormSchema) => {
const accessType = !el.temporaryAccess.isTemporary
? { role: el.slug, isTemporary: false as const }
? { isTemporary: false as const }
: {
role: el.slug,
isTemporary: true as const,
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: el.temporaryAccess.temporaryRange,
@@ -202,9 +204,7 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({
<IconButton ariaLabel="go-back" variant="plain" onClick={onGoBack}>
<FontAwesomeIcon icon={faChevronLeft} />
</IconButton>
<h3 className="text-lg font-semibold text-mineshaft-100">
Modify Additional Privilege
</h3>
<h3 className="text-lg font-semibold text-mineshaft-100">Back</h3>
</div>
<div className="flex items-center space-x-4">
{isDirty && (
@@ -268,6 +268,7 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({
<Popover>
<PopoverTrigger disabled={isMemberEditDisabled} asChild>
<div className="w-full max-w-md flex-grow">
<FormLabel label="Access Type" />
<Tooltip content={toolTipText}>
<Button
variant="outline_bg"

View File

@@ -5,7 +5,7 @@ import {
faArrowUp,
faArrowUpRightFromSquare,
faClock,
faEdit,
faEllipsisV,
faMagnifyingGlass,
faPlus,
faServer,
@@ -27,8 +27,6 @@ import {
HoverCardTrigger,
IconButton,
Input,
Modal,
ModalContent,
Pagination,
Spinner,
Table,
@@ -47,13 +45,11 @@ import { withProjectPermission } from "@app/hoc";
import { usePagination, useResetPageHelper } from "@app/hooks";
import { useDeleteIdentityFromWorkspace, useGetWorkspaceIdentityMemberships } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { IdentityMembership } from "@app/hooks/api/identities/types";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { ProjectIdentityOrderBy } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { IdentityModal } from "./components/IdentityModal";
import { IdentityRoleForm } from "./components/IdentityRoleForm";
const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2;
@@ -111,8 +107,7 @@ export const IdentityTab = withProjectPermission(
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
"identity",
"deleteIdentity",
"upgradePlan",
"updateRole"
"upgradePlan"
] as const);
const onRemoveIdentitySubmit = async (identityId: string) => {
@@ -234,7 +229,7 @@ export const IdentityTab = withProjectPermission(
{!isLoading &&
data &&
data.identityMemberships.length > 0 &&
data.identityMemberships.map((identityMember, index) => {
data.identityMemberships.map((identityMember) => {
const {
identity: { id, name },
roles,
@@ -242,7 +237,7 @@ export const IdentityTab = withProjectPermission(
} = identityMember;
return (
<Tr
className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
className="group h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
key={`st-v3-${id}`}
role="button"
tabIndex={0}
@@ -348,24 +343,10 @@ export const IdentityTab = withProjectPermission(
</HoverCardContent>
</HoverCard>
)}
<Tooltip content="Edit permission">
<IconButton
size="sm"
variant="plain"
ariaLabel="update-role"
onClick={(evt) => {
evt.stopPropagation();
evt.preventDefault();
handlePopUpOpen("updateRole", { ...identityMember, index });
}}
>
<FontAwesomeIcon icon={faEdit} />
</IconButton>
</Tooltip>
</div>
</Td>
<Td>{format(new Date(createdAt), "yyyy-MM-dd")}</Td>
<Td className="flex justify-end">
<Td className="flex justify-end space-x-2 opacity-0 duration-300 group-hover:opacity-100">
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={ProjectPermissionSub.Identity}
@@ -391,6 +372,9 @@ export const IdentityTab = withProjectPermission(
</IconButton>
)}
</ProjectPermissionCan>
<IconButton ariaLabel="more-icon" variant="plain">
<FontAwesomeIcon icon={faEllipsisV} />
</IconButton>
</Td>
</Tr>
);
@@ -417,31 +401,6 @@ export const IdentityTab = withProjectPermission(
/>
)}
</TableContainer>
<Modal
isOpen={popUp.updateRole.isOpen}
onOpenChange={(state) => handlePopUpToggle("updateRole", state)}
>
<ModalContent
className="max-w-3xl"
title={`Manage Access for ${
(popUp.updateRole.data as IdentityMembership)?.identity?.name
}`}
subTitle={`
Configure role-based access control by assigning machine identities a mix of roles and specific privileges. An identity will gain access to all actions within the roles assigned to it, not just the actions those roles share in common. You must choose at least one permanent role.
`}
>
<IdentityRoleForm
onOpenUpgradeModal={(description) =>
handlePopUpOpen("upgradePlan", { description })
}
identityProjectMember={
data?.identityMemberships[
(popUp.updateRole?.data as IdentityMembership & { index: number })?.index
] as IdentityMembership
}
/>
</ModalContent>
</Modal>
<IdentityModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
<DeleteActionModal
isOpen={popUp.deleteIdentity.isOpen}

View File

@@ -25,8 +25,7 @@ export const MembersSection = () => {
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
"addMember",
"removeMember",
"upgradePlan",
"updateRole"
"upgradePlan"
] as const);
const handleRemoveUser = async () => {
@@ -72,11 +71,7 @@ export const MembersSection = () => {
)}
</ProjectPermissionCan>
</div>
<MembersTable
popUp={popUp}
handlePopUpOpen={handlePopUpOpen}
handlePopUpToggle={handlePopUpToggle}
/>
<MembersTable handlePopUpOpen={handlePopUpOpen} />
<AddMemberModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
<DeleteActionModal
isOpen={popUp.removeMember.isOpen}

View File

@@ -2,7 +2,7 @@ import { useMemo, useState } from "react";
import { useRouter } from "next/router";
import {
faClock,
faEdit,
faEllipsisV,
faMagnifyingGlass,
faTrash,
faUsers
@@ -18,8 +18,6 @@ import {
HoverCardTrigger,
IconButton,
Input,
Modal,
ModalContent,
Table,
TableContainer,
TableSkeleton,
@@ -39,11 +37,8 @@ import {
} from "@app/context";
import { useGetWorkspaceUsers } from "@app/hooks/api";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { TWorkspaceUser } from "@app/hooks/api/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { MemberRoleForm } from "./MemberRoleForm";
const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2;
const formatRoleName = (role: string, customRoleName?: string) => {
if (role === ProjectMembershipRole.Custom) return customRoleName;
@@ -53,15 +48,13 @@ const formatRoleName = (role: string, customRoleName?: string) => {
};
type Props = {
popUp: UsePopUpState<["updateRole"]>;
handlePopUpOpen: (
popUpName: keyof UsePopUpState<["removeMember", "updateRole", "upgradePlan"]>,
popUpName: keyof UsePopUpState<["removeMember", "upgradePlan"]>,
data?: {}
) => void;
handlePopUpToggle: (popUpName: keyof UsePopUpState<["updateRole"]>, state?: boolean) => void;
};
export const MembersTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Props) => {
export const MembersTable = ({ handlePopUpOpen }: Props) => {
const [searchMemberFilter, setSearchMemberFilter] = useState("");
const { currentWorkspace } = useWorkspace();
@@ -107,7 +100,7 @@ export const MembersTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Prop
<TBody>
{isMembersLoading && <TableSkeleton columns={4} innerKey="project-members" />}
{!isMembersLoading &&
filterdUsers?.map((projectMember, index) => {
filterdUsers?.map((projectMember) => {
const { user: u, inviteEmail, id: membershipId, roles } = projectMember;
const name = u.firstName || u.lastName ? `${u.firstName} ${u.lastName || ""}` : "-";
const email = u?.email || inviteEmail;
@@ -209,27 +202,11 @@ export const MembersTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Prop
</HoverCardContent>
</HoverCard>
)}
{userId !== u?.id && (
<Tooltip content="Edit permission">
<IconButton
size="sm"
variant="plain"
ariaLabel="update-role"
onClick={(evt) => {
evt.preventDefault();
evt.stopPropagation();
handlePopUpOpen("updateRole", { ...projectMember, index });
}}
>
<FontAwesomeIcon icon={faEdit} />
</IconButton>
</Tooltip>
)}
</div>
</Td>
<Td>
{userId !== u?.id && (
<div className="opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<div className="flex items-center space-x-2 opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={ProjectPermissionSub.Member}
@@ -251,6 +228,9 @@ export const MembersTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Prop
</IconButton>
)}
</ProjectPermissionCan>
<IconButton ariaLabel="more-icon" variant="plain">
<FontAwesomeIcon icon={faEllipsisV} />
</IconButton>
</div>
)}
</Td>
@@ -263,27 +243,6 @@ export const MembersTable = ({ popUp, handlePopUpOpen, handlePopUpToggle }: Prop
<EmptyState title="No project members found" icon={faUsers} />
)}
</TableContainer>
<Modal
isOpen={popUp.updateRole.isOpen}
onOpenChange={(state) => handlePopUpToggle("updateRole", state)}
>
<ModalContent
className="max-w-4xl"
title={`Manage Access for ${(popUp.updateRole.data as TWorkspaceUser)?.user?.email}`}
subTitle={`
Configure role-based access control by assigning Infisical users a mix of roles and specific privileges. A user will gain access to all actions within the roles assigned to them, not just the actions those roles share in common. You must choose at least one permanent role.
`}
>
<MemberRoleForm
onOpenUpgradeModal={(description) => handlePopUpOpen("upgradePlan", { description })}
projectMember={
filterdUsers?.[
(popUp.updateRole?.data as TWorkspaceUser & { index: number })?.index
] as TWorkspaceUser
}
/>
</ModalContent>
</Modal>
</div>
);
};