role table restyle

This commit is contained in:
Tuan Dang
2024-07-18 17:12:02 +07:00
parent 95a4661787
commit ce26a06129
2 changed files with 71 additions and 61 deletions
@@ -68,7 +68,7 @@ export const IdentitySection = withPermission(
}; };
return ( return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4"> <div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-4 flex justify-between"> <div className="mb-4 flex justify-between">
<p className="text-xl font-semibold text-mineshaft-100">Identities</p> <p className="text-xl font-semibold text-mineshaft-100">Identities</p>
<div className="flex w-full justify-end pr-4"> <div className="flex w-full justify-end pr-4">
@@ -1,14 +1,16 @@
import { useState } from "react"; import { faEllipsis,faPlus } from "@fortawesome/free-solid-svg-icons";
import { faEdit, faMagnifyingGlass, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications"; import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions"; import { OrgPermissionCan } from "@app/components/permissions";
import { import {
Button, Button,
DeleteActionModal, DeleteActionModal,
IconButton, DropdownMenu,
Input, DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
Table, Table,
TableContainer, TableContainer,
TableSkeleton, TableSkeleton,
@@ -28,11 +30,12 @@ type Props = {
}; };
export const OrgRoleTable = ({ onSelectRole }: Props) => { export const OrgRoleTable = ({ onSelectRole }: Props) => {
const [searchRoles, setSearchRoles] = useState("");
const { currentOrg } = useOrganization(); const { currentOrg } = useOrganization();
const orgId = currentOrg?.id || ""; const orgId = currentOrg?.id || "";
const { popUp, handlePopUpOpen, handlePopUpClose } = usePopUp(["deleteRole"] as const); const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
"deleteRole"
] as const);
const { data: roles, isLoading: isRolesLoading } = useGetOrgRoles(orgId); const { data: roles, isLoading: isRolesLoading } = useGetOrgRoles(orgId);
@@ -54,50 +57,52 @@ export const OrgRoleTable = ({ onSelectRole }: Props) => {
}; };
return ( return (
<div className="w-full"> <div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="mb-4 flex"> <div className="mb-4 flex justify-between">
<div className="mr-4 flex-1"> <p className="text-xl font-semibold text-mineshaft-100">Organization Roles</p>
<Input
value={searchRoles}
onChange={(e) => setSearchRoles(e.target.value)}
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
placeholder="Search roles..."
/>
</div>
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Role}> <OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Role}>
{(isAllowed) => ( {(isAllowed) => (
<Button <Button
isDisabled={!isAllowed} colorSchema="primary"
type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => onSelectRole()} onClick={() => onSelectRole()}
isDisabled={!isAllowed}
> >
Add Role Add Role
</Button> </Button>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
</div> </div>
<div> <TableContainer>
<TableContainer> <Table>
<Table> <THead>
<THead> <Tr>
<Tr> <Th>Name</Th>
<Th>Name</Th> <Th>Slug</Th>
<Th>Slug</Th> <Th aria-label="actions" className="w-5" />
<Th aria-label="actions" /> </Tr>
</Tr> </THead>
</THead> <TBody>
<TBody> {isRolesLoading && <TableSkeleton columns={3} innerKey="org-roles" />}
{isRolesLoading && <TableSkeleton columns={4} innerKey="org-roles" />} {roles?.map((role) => {
{roles?.map((role) => { const { id, name, slug } = role;
const { id, name, slug } = role; const isNonMutatable = ["owner", "admin", "member", "no-access"].includes(slug);
const isNonMutatable = ["owner", "admin", "member", "no-access"].includes(slug); return (
<Tr
return ( key={`role-list-${id}`}
<Tr key={`role-list-${id}`}> className="h-10 cursor-pointer transition-colors duration-300 hover:bg-mineshaft-700"
<Td>{name}</Td> >
<Td>{slug}</Td> <Td>{name}</Td>
<Td className="flex justify-end"> <Td>{slug}</Td>
<div className="flex space-x-2"> <Td>
<DropdownMenu>
<DropdownMenuTrigger asChild className="rounded-lg">
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
<FontAwesomeIcon size="sm" icon={faEllipsis} />
</div>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="p-1">
<OrgPermissionCan <OrgPermissionCan
I={OrgPermissionActions.Edit} I={OrgPermissionActions.Edit}
a={OrgPermissionSubjects.Role} a={OrgPermissionSubjects.Role}
@@ -105,14 +110,15 @@ export const OrgRoleTable = ({ onSelectRole }: Props) => {
allowedLabel="Edit" allowedLabel="Edit"
> >
{(isAllowed) => ( {(isAllowed) => (
<IconButton <DropdownMenuItem
isDisabled={!isAllowed} className={twMerge(
ariaLabel="edit" !isAllowed && "pointer-events-none cursor-not-allowed opacity-50"
)}
onClick={() => onSelectRole(role)} onClick={() => onSelectRole(role)}
variant="plain" disabled={!isAllowed}
> >
<FontAwesomeIcon icon={faEdit} /> Edit Role
</IconButton> </DropdownMenuItem>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
<OrgPermissionCan <OrgPermissionCan
@@ -124,30 +130,34 @@ export const OrgRoleTable = ({ onSelectRole }: Props) => {
} }
> >
{(isAllowed) => ( {(isAllowed) => (
<IconButton <DropdownMenuItem
ariaLabel="delete" className={twMerge(
isAllowed
? "hover:!bg-red-500 hover:!text-white"
: "pointer-events-none cursor-not-allowed opacity-50"
)}
onClick={() => handlePopUpOpen("deleteRole", role)} onClick={() => handlePopUpOpen("deleteRole", role)}
variant="plain" disabled={!isAllowed}
isDisabled={isNonMutatable || !isAllowed}
> >
<FontAwesomeIcon icon={faTrash} /> Delete Role
</IconButton> </DropdownMenuItem>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
</div> </DropdownMenuContent>
</Td> </DropdownMenu>
</Tr> </Td>
); </Tr>
})} );
</TBody> })}
</Table> </TBody>
</TableContainer> </Table>
</div> </TableContainer>
<DeleteActionModal <DeleteActionModal
isOpen={popUp.deleteRole.isOpen} isOpen={popUp.deleteRole.isOpen}
title={`Are you sure want to delete ${ title={`Are you sure want to delete ${
(popUp?.deleteRole?.data as TOrgRole)?.name || " " (popUp?.deleteRole?.data as TOrgRole)?.name || " "
} role?`} } role?`}
onChange={(isOpen) => handlePopUpToggle("deleteRole", isOpen)}
deleteKey={(popUp?.deleteRole?.data as TOrgRole)?.slug || ""} deleteKey={(popUp?.deleteRole?.data as TOrgRole)?.slug || ""}
onClose={() => handlePopUpClose("deleteRole")} onClose={() => handlePopUpClose("deleteRole")}
onDeleteApproved={handleRoleDelete} onDeleteApproved={handleRoleDelete}