mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: removed form in member and identity table, and added ellipsis for noting icons
This commit is contained in:
@@ -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 };
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user