mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 02:26:40 +00:00
Merge pull request #4888 from Infisical/ENG-4154
improvement: add invite members link to nav bar to improve discovery
This commit is contained in:
@@ -16,15 +16,19 @@ import {
|
|||||||
faSignOut,
|
faSignOut,
|
||||||
faToolbox,
|
faToolbox,
|
||||||
faUser,
|
faUser,
|
||||||
|
faUserCog,
|
||||||
|
faUserPlus,
|
||||||
faUsers
|
faUsers
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { Link, useLocation, useNavigate, useRouter, useRouterState } from "@tanstack/react-router";
|
import { Link, useLocation, useNavigate, useRouter, useRouterState } from "@tanstack/react-router";
|
||||||
|
import { UserPlusIcon } from "lucide-react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { Mfa } from "@app/components/auth/Mfa";
|
import { Mfa } from "@app/components/auth/Mfa";
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
import SecurityClient from "@app/components/utilities/SecurityClient";
|
import SecurityClient from "@app/components/utilities/SecurityClient";
|
||||||
import {
|
import {
|
||||||
BreadcrumbContainer,
|
BreadcrumbContainer,
|
||||||
@@ -44,7 +48,13 @@ import {
|
|||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { Badge, InstanceIcon, OrgIcon, SubOrgIcon } from "@app/components/v3";
|
import { Badge, InstanceIcon, OrgIcon, SubOrgIcon } from "@app/components/v3";
|
||||||
import { envConfig } from "@app/config/env";
|
import { envConfig } from "@app/config/env";
|
||||||
import { useOrganization, useSubscription, useUser } from "@app/context";
|
import {
|
||||||
|
OrgPermissionActions,
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
useOrganization,
|
||||||
|
useSubscription,
|
||||||
|
useUser
|
||||||
|
} from "@app/context";
|
||||||
import { isInfisicalCloud } from "@app/helpers/platform";
|
import { isInfisicalCloud } from "@app/helpers/platform";
|
||||||
import { useToggle } from "@app/hooks";
|
import { useToggle } from "@app/hooks";
|
||||||
import {
|
import {
|
||||||
@@ -567,15 +577,36 @@ export const Navbar = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{user.superAdmin && !location.pathname.startsWith("/admin") && (
|
{/* eslint-disable-next-line no-nested-ternary */}
|
||||||
<Link
|
{!location.pathname.startsWith("/admin") ? (
|
||||||
className="mr-2 flex h-[34px] items-center rounded-md border border-mineshaft-500 px-2.5 py-1.5 text-sm whitespace-nowrap text-mineshaft-200 hover:bg-mineshaft-600"
|
user.superAdmin ? (
|
||||||
to="/admin"
|
<Link
|
||||||
>
|
className="mr-2 flex h-[34px] items-center rounded-md border border-mineshaft-500 px-2.5 py-1.5 text-sm whitespace-nowrap text-mineshaft-200 hover:bg-mineshaft-600"
|
||||||
<InstanceIcon className="inline-block size-3.5" />
|
to="/admin"
|
||||||
<span className="ml-2 hidden md:inline-block">Server Console</span>
|
>
|
||||||
</Link>
|
<InstanceIcon className="inline-block size-3.5" />
|
||||||
)}
|
<span className="ml-2 hidden md:inline-block">Server Console</span>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Member}>
|
||||||
|
{(isAllowed) =>
|
||||||
|
isAllowed ? (
|
||||||
|
<Link
|
||||||
|
className="mr-2 flex h-[34px] items-center rounded-md border border-mineshaft-500 px-2.5 py-1.5 text-sm whitespace-nowrap text-mineshaft-200 hover:bg-mineshaft-600"
|
||||||
|
to="/organization/access-management"
|
||||||
|
search={{
|
||||||
|
selectedTab: "members",
|
||||||
|
action: "invite-members"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<UserPlusIcon className="inline-block size-3.5" />
|
||||||
|
<span className="ml-2 hidden md:inline-block">Invite Members</span>
|
||||||
|
</Link>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</OrgPermissionCan>
|
||||||
|
)
|
||||||
|
) : null}
|
||||||
<DropdownMenu modal={false}>
|
<DropdownMenu modal={false}>
|
||||||
<DropdownMenuTrigger>
|
<DropdownMenuTrigger>
|
||||||
<div className="rounded-l-md border border-r-0 border-mineshaft-500 px-2.5 py-1 hover:bg-mineshaft-600">
|
<div className="rounded-l-md border border-r-0 border-mineshaft-500 px-2.5 py-1 hover:bg-mineshaft-600">
|
||||||
@@ -657,8 +688,27 @@ export const Navbar = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Link to="/personal-settings">
|
<Link to="/personal-settings">
|
||||||
<DropdownMenuItem>Personal Settings</DropdownMenuItem>
|
<DropdownMenuItem icon={<FontAwesomeIcon icon={faUserCog} />}>
|
||||||
|
Personal Settings
|
||||||
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
|
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.Member}>
|
||||||
|
{(isAllowed) =>
|
||||||
|
isAllowed ? (
|
||||||
|
<Link
|
||||||
|
to="/organization/access-management"
|
||||||
|
search={{
|
||||||
|
selectedTab: "members",
|
||||||
|
action: "invite-members"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DropdownMenuItem icon={<FontAwesomeIcon icon={faUserPlus} />}>
|
||||||
|
Invite Members
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</Link>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</OrgPermissionCan>
|
||||||
<a
|
<a
|
||||||
href="https://infisical.com/docs/documentation/getting-started/introduction"
|
href="https://infisical.com/docs/documentation/getting-started/introduction"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|||||||
+24
-5
@@ -1,7 +1,8 @@
|
|||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
import { faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { BanIcon } from "lucide-react";
|
import { useNavigate, useSearch } from "@tanstack/react-router";
|
||||||
|
import { BanIcon, UserPlusIcon } from "lucide-react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||||
@@ -16,6 +17,7 @@ import {
|
|||||||
Tooltip
|
Tooltip
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
import { Badge, DocumentationLinkBadge } from "@app/components/v3";
|
||||||
|
import { ROUTE_PATHS } from "@app/const/routes";
|
||||||
import {
|
import {
|
||||||
OrgPermissionActions,
|
OrgPermissionActions,
|
||||||
OrgPermissionSubjects,
|
OrgPermissionSubjects,
|
||||||
@@ -35,6 +37,7 @@ import { OrgMembersTable } from "./OrgMembersTable";
|
|||||||
export const OrgMembersSection = () => {
|
export const OrgMembersSection = () => {
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
const { currentOrg, isSubOrganization } = useOrganization();
|
const { currentOrg, isSubOrganization } = useOrganization();
|
||||||
|
const navigate = useNavigate();
|
||||||
const orgId = currentOrg?.id ?? "";
|
const orgId = currentOrg?.id ?? "";
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
const userId = user?.id || "";
|
const userId = user?.id || "";
|
||||||
@@ -55,6 +58,22 @@ export const OrgMembersSection = () => {
|
|||||||
|
|
||||||
const [selectedMemberIds, setSelectedMemberIds] = useState<string[]>([]);
|
const [selectedMemberIds, setSelectedMemberIds] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const urlAction = useSearch({
|
||||||
|
from: ROUTE_PATHS.Organization.AccessControlPage.id,
|
||||||
|
select: (el) => el.action,
|
||||||
|
structuralSharing: true
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (urlAction === "invite-members") {
|
||||||
|
handlePopUpOpen("addMember");
|
||||||
|
navigate({
|
||||||
|
to: ".",
|
||||||
|
search: ({ action, ...search }) => search
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [urlAction]);
|
||||||
|
|
||||||
const { mutateAsync: deleteMutateAsync } = useDeleteOrgMembership();
|
const { mutateAsync: deleteMutateAsync } = useDeleteOrgMembership();
|
||||||
const { mutateAsync: deleteBatchMutateAsync } = useDeleteOrgMembershipBatch();
|
const { mutateAsync: deleteBatchMutateAsync } = useDeleteOrgMembershipBatch();
|
||||||
const { mutateAsync: updateOrgMembership } = useUpdateOrgMembership();
|
const { mutateAsync: updateOrgMembership } = useUpdateOrgMembership();
|
||||||
@@ -194,13 +213,13 @@ export const OrgMembersSection = () => {
|
|||||||
<Button
|
<Button
|
||||||
colorSchema="secondary"
|
colorSchema="secondary"
|
||||||
type="submit"
|
type="submit"
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
leftIcon={<UserPlusIcon size={16} />}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
isSubOrganization ? handlePopUpOpen("addMemberToSubOrg") : handleAddMemberModal()
|
isSubOrganization ? handlePopUpOpen("addMemberToSubOrg") : handleAddMemberModal()
|
||||||
}
|
}
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
>
|
>
|
||||||
Add Member
|
{isSubOrganization ? "Add Members" : "Invite Members"}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</OrgPermissionCan>
|
||||||
|
|||||||
Reference in New Issue
Block a user