feature: migrate to v3 badge, additional badge stories, re-useable documentation link badge and misc styling fixes/improvements

This commit is contained in:
Scott Wilson
2025-10-24 19:27:28 -07:00
parent 6c04dd1937
commit 01d6f5d35e
155 changed files with 1267 additions and 1740 deletions
@@ -7,15 +7,12 @@ import {
faCaretDown,
faCheck,
faChevronRight,
faCubes,
faEnvelope,
faExclamationTriangle,
faGlobe,
faInfinity,
faInfo,
faInfoCircle,
faPlus,
faServer,
faSignOut,
faToolbox,
faUser,
@@ -30,7 +27,6 @@ import { Mfa } from "@app/components/auth/Mfa";
import { createNotification } from "@app/components/notifications";
import SecurityClient from "@app/components/utilities/SecurityClient";
import {
Badge,
BreadcrumbContainer,
Button,
DropdownMenu,
@@ -46,6 +42,7 @@ import {
TBreadcrumbFormat,
Tooltip
} from "@app/components/v2";
import { Badge, InstanceIcon, OrgIcon, SubOrgIcon } from "@app/components/v3";
import { envConfig } from "@app/config/env";
import { useOrganization, useSubscription, useUser } from "@app/context";
import { isInfisicalCloud } from "@app/helpers/platform";
@@ -271,9 +268,7 @@ export const Navbar = () => {
to="/admin"
className="group flex cursor-pointer items-center gap-2 text-sm text-white transition-all duration-100 hover:text-primary"
>
<div>
<FontAwesomeIcon icon={faServer} className="text-xs text-bunker-300" />
</div>
<InstanceIcon className="size-3.5 text-xs text-bunker-300" />
<div className="whitespace-nowrap">Server Console</div>
</Link>
<p className="pr-3 pl-3 text-lg text-mineshaft-400/70">/</p>
@@ -288,24 +283,31 @@ export const Navbar = () => {
<DropdownMenu modal={false} open={isOrgSelectOpen} onOpenChange={setIsOrgSelectOpen}>
<div className="group flex cursor-pointer items-center gap-2 overflow-hidden text-sm text-white transition-all duration-100 hover:text-primary">
<Badge
onClick={async () => {
navigate({
to: "/organization/projects",
search: (search) => ({ ...search, subOrganization: undefined })
});
if (isSubOrganization) {
await router.invalidate({ sync: true }).catch(() => null);
}
}}
asChild
variant="org"
isTruncatable
// TODO(scott): either add badge size/style variant or create designated component for namespace/org nav bar
className={twMerge(
"max-w-full min-w-0 cursor-pointer text-sm",
"gap-x-1.5 text-sm",
(!isOrgScope || isSubOrganization) &&
"bg-transparent text-mineshaft-200 hover:bg-transparent hover:underline"
"bg-transparent text-mineshaft-200 hover:!bg-transparent hover:underline [&>svg]:!text-org"
)}
>
<FontAwesomeIcon icon={faGlobe} />
<p className="truncate">{currentOrg?.name}</p>
<button
type="button"
onClick={async () => {
navigate({
to: "/organization/projects",
search: (search) => ({ ...search, subOrganization: undefined })
});
if (isSubOrganization) {
await router.invalidate({ sync: true }).catch(() => null);
}
}}
>
<OrgIcon className="size-[12px]" />
<span>{currentOrg?.name}</span>
</button>
</Badge>
<div className="mr-1 rounded-sm border border-mineshaft-500 px-1 text-xs text-bunker-300 no-underline!">
{getPlan(subscription)}
@@ -443,19 +445,22 @@ export const Navbar = () => {
<>
<p className="pr-3 pl-1 text-lg text-mineshaft-400/70">/</p>
<DropdownMenu modal={false}>
<Link className="overflow-hidden" to="/organization/projects">
<Badge
variant="namespace"
className={twMerge(
"flex max-w-full min-w-0 cursor-pointer text-sm",
!isOrgScope &&
"bg-transparent text-mineshaft-200 hover:bg-transparent hover:underline"
)}
>
<FontAwesomeIcon icon={faCubes} />
<p className="truncate">{currentOrg.subOrganization.name}</p>
</Badge>
</Link>
<Badge
asChild
isTruncatable
variant="sub-org"
// TODO(scott): either add badge size/style variant or create designated component for namespace/org nav bar
className={twMerge(
"gap-x-1.5 text-sm",
!isOrgScope &&
"bg-transparent text-mineshaft-200 hover:!bg-transparent hover:underline [&>svg]:!text-sub-org"
)}
>
<Link to="/organization/projects">
<SubOrgIcon className="size-[12px]" />
<span>{currentOrg.subOrganization.name}</span>
</Link>
</Badge>
<DropdownMenuTrigger asChild>
<div>
<IconButton
@@ -549,10 +554,10 @@ export const Navbar = () => {
)}
{user.superAdmin && !location.pathname.startsWith("/admin") && (
<Link
className="mr-2 rounded-md border border-mineshaft-500 px-2.5 py-1.5 text-sm whitespace-nowrap text-mineshaft-200 hover:bg-mineshaft-600"
className="mr-2 flex 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="/admin"
>
<FontAwesomeIcon icon={faServer} className="mr-2" />
<InstanceIcon className="mr-2 inline-block size-3.5" />
Server Console
</Link>
)}
@@ -3,7 +3,6 @@ import { faStar } from "@fortawesome/free-regular-svg-icons";
import {
faCaretDown,
faCheck,
faCube,
faMagnifyingGlass,
faPlus,
faStar as faSolidStar
@@ -16,7 +15,6 @@ import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
import { NewProjectModal } from "@app/components/projects";
import {
Badge,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
@@ -25,6 +23,7 @@ import {
Input,
Tooltip
} from "@app/components/v2";
import { Badge, ProjectIcon } from "@app/components/v3";
import {
OrgPermissionActions,
OrgPermissionSubjects,
@@ -120,11 +119,9 @@ export const ProjectSelect = () => {
<p className="inline-block truncate text-mineshaft-200 group-hover:underline">
{currentWorkspace?.name}
</p>
<Badge variant="project" className="cursor-pointer">
<FontAwesomeIcon icon={faCube} />
<span>
{currentWorkspace.type ? PROJECT_TYPE_NAME[currentWorkspace.type] : "Project"}
</span>
<Badge variant="project">
<ProjectIcon />
{currentWorkspace.type ? PROJECT_TYPE_NAME[currentWorkspace.type] : "Project"}
</Badge>
</Link>
<DropdownMenuTrigger asChild>
@@ -4,7 +4,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { Badge, Tab, TabList, Tabs } from "@app/components/v2";
import { Tab, TabList, Tabs } from "@app/components/v2";
import { Badge } from "@app/components/v3";
import { useProject, useProjectPermission } from "@app/context";
import {
useGetAccessRequestsCount,
@@ -88,7 +89,7 @@ export const SecretManagerLayout = () => {
{Boolean(
secretApprovalReqCount?.open || accessApprovalRequestCount?.pendingCount
) && (
<Badge variant="primary" className="ml-1.5">
<Badge variant="warning" isSquare className="ml-1.5">
{pendingRequestsCount}
</Badge>
)}
@@ -1,7 +1,8 @@
import { Link, Outlet, useLocation } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { Badge, Tab, TabList, Tabs } from "@app/components/v2";
import { Tab, TabList, Tabs } from "@app/components/v2";
import { Badge } from "@app/components/v3";
import {
ProjectPermissionSub,
useProject,
@@ -66,7 +67,7 @@ export const SecretScanningLayout = () => {
<Tab value={isActive ? "selected" : ""}>
Findings
{Boolean(unresolvedFindings) && (
<Badge variant="primary" className="ml-2 h-min">
<Badge isSquare variant="warning" className="ml-2">
{unresolvedFindings}
</Badge>
)}