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
@@ -1,14 +1,14 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { FormProvider, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button, ModalClose } from "@app/components/v2";
import { PamResourceType, TMySQLAccount } from "@app/hooks/api/pam";
import { UNCHANGED_PASSWORD_SENTINEL } from "@app/hooks/api/pam/constants";
import { GenericAccountFields, genericAccountFieldsSchema } from "./GenericAccountFields";
import { BaseSqlAccountSchema } from "./shared/sql-account-schemas";
import { SqlAccountFields } from "./shared/SqlAccountFields";
import { GenericAccountFields, genericAccountFieldsSchema } from "./GenericAccountFields";
type Props = {
account?: TMySQLAccount;
@@ -1,6 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button, ModalClose } from "@app/components/v2";
@@ -12,10 +12,10 @@ import {
} from "@app/hooks/api/pam";
import { UNCHANGED_PASSWORD_SENTINEL } from "@app/hooks/api/pam/constants";
import { GenericAccountFields, genericAccountFieldsSchema } from "./GenericAccountFields";
import { RotateAccountFields, rotateAccountFieldsSchema } from "./RotateAccountFields";
import { BaseSqlAccountSchema } from "./shared/sql-account-schemas";
import { SqlAccountFields } from "./shared/SqlAccountFields";
import { GenericAccountFields, genericAccountFieldsSchema } from "./GenericAccountFields";
import { RotateAccountFields, rotateAccountFieldsSchema } from "./RotateAccountFields";
type Props = {
account?: TPostgresAccount;
@@ -1,23 +1,20 @@
import { useCallback } from "react";
import {
faBoxOpen,
faCheck,
faCopy,
faEdit,
faEllipsisV,
faFolder,
faRightToBracket,
faRotate,
faTrash
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { formatDistance } from "date-fns";
import { FolderIcon, PackageOpenIcon, RefreshCwIcon } from "lucide-react";
import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions";
import {
Badge,
Button,
DropdownMenu,
DropdownMenuContent,
@@ -29,6 +26,7 @@ import {
Tr
} from "@app/components/v2";
import { HighlightText } from "@app/components/v2/HighlightText";
import { Badge } from "@app/components/v3";
import { ProjectPermissionSub } from "@app/context";
import { ProjectPermissionPamAccountActions } from "@app/context/ProjectPermissionContext/types";
import { useToggle } from "@app/hooks";
@@ -88,23 +86,23 @@ export const PamAccountRow = ({
<span>
<HighlightText text={name} highlight={search} />
</span>
<Badge className="flex h-5 w-min items-center gap-1.5 bg-bunker-300/20 whitespace-nowrap text-bunker-300">
<FontAwesomeIcon icon={faBoxOpen} />
<Badge variant="neutral">
<PackageOpenIcon />
<span>
<HighlightText text={account.resource.name} highlight={search} />
</span>
</Badge>
{isFlatView && accountPath && (
<Badge className="flex h-5 w-min items-center gap-1.5 bg-bunker-300/20 whitespace-nowrap text-bunker-300">
<FontAwesomeIcon icon={faFolder} />
<Badge variant="neutral">
<FolderIcon />
<span>
<HighlightText text={accountPath} highlight={search} />
</span>
</Badge>
)}
{account.lastRotatedAt && (
<Badge className="flex h-5 w-min items-center gap-1.5 bg-orange/20 whitespace-nowrap text-orange">
<FontAwesomeIcon icon={faRotate} />
<Badge variant="info">
<RefreshCwIcon />
<span>Rotated {formatDistance(new Date(), account.lastRotatedAt)} ago</span>
</Badge>
)}
@@ -3,7 +3,7 @@ import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Badge } from "@app/components/v2";
import { Badge } from "@app/components/v3";
import { PAM_RESOURCE_TYPE_MAP, PamResourceType } from "@app/hooks/api/pam";
export const PamResourceOption = ({
@@ -27,7 +27,7 @@ export const PamResourceOption = ({
<>
<p className="truncate">{children}</p>
<div className="mr-auto ml-2">
<Badge className="flex h-5 items-center gap-1 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
<Badge variant="neutral">
<img
alt={`${name} logo`}
src={`/images/integrations/${image}`}
@@ -4,7 +4,6 @@ import { twMerge } from "tailwind-merge";
import { ProjectPermissionCan } from "@app/components/permissions";
import {
Badge,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
@@ -15,6 +14,7 @@ import {
Tr
} from "@app/components/v2";
import { HighlightText } from "@app/components/v2/HighlightText";
import { Badge } from "@app/components/v3";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { PAM_RESOURCE_TYPE_MAP, TPamResource } from "@app/hooks/api/pam";
@@ -40,7 +40,7 @@ export const PamResourceRow = ({ resource, onUpdate, onDelete, search }: Props)
<span>
<HighlightText text={name} highlight={search} />
</span>
<Badge className="flex h-5 w-min items-center gap-1.5 bg-mineshaft-400/50 whitespace-nowrap text-bunker-300">
<Badge variant="neutral">
<span>
<HighlightText text={resourceTypeName} highlight={search} />
</span>
@@ -1,7 +1,9 @@
import { faBoxOpen, faCheck, faCopy, faUser } from "@fortawesome/free-solid-svg-icons";
import { faCheck, faCopy, faUser } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PackageOpenIcon } from "lucide-react";
import { Badge, IconButton, Tooltip } from "@app/components/v2";
import { IconButton, Tooltip } from "@app/components/v2";
import { Badge } from "@app/components/v3";
import { useTimedReset } from "@app/hooks";
import { PAM_RESOURCE_TYPE_MAP, TPamSession } from "@app/hooks/api/pam";
@@ -76,8 +78,8 @@ export const PamSessionDetailsSection = ({
className="size-4"
/>
<p>{accountName}</p>
<Badge className="flex h-5 w-min items-center gap-1.5 bg-yellow/20 whitespace-nowrap text-yellow">
<FontAwesomeIcon icon={faBoxOpen} />
<Badge variant="neutral">
<PackageOpenIcon />
{resourceName}
</Badge>
</div>
@@ -1,45 +1,38 @@
import {
faBan,
faCircle,
faGavel,
faHourglass,
IconDefinition
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { twMerge } from "tailwind-merge";
ActivityIcon,
BanIcon,
ChevronsLeftRightEllipsisIcon,
GavelIcon,
LucideIcon
} from "lucide-react";
import { Badge } from "@app/components/v2";
import { Badge, TBadgeProps } from "@app/components/v3";
import { PamSessionStatus } from "@app/hooks/api/pam";
interface StatusConfig {
bgColor: string;
textColor: string;
icon: IconDefinition;
iconClassName?: string;
variant: TBadgeProps["variant"];
icon: LucideIcon;
className?: string;
}
const PAM_SESSION_STATUS_CONFIG: Record<PamSessionStatus, StatusConfig> = {
[PamSessionStatus.Active]: {
bgColor: "bg-green/20",
textColor: "text-green",
icon: faCircle,
iconClassName: "size-2 animate-pulse"
variant: "success",
icon: ActivityIcon,
className: "animate-pulse"
},
[PamSessionStatus.Terminated]: {
bgColor: "bg-red/20",
textColor: "text-red",
icon: faGavel
variant: "danger",
icon: GavelIcon
},
[PamSessionStatus.Starting]: {
bgColor: "bg-yellow/20",
textColor: "text-yellow",
icon: faHourglass,
iconClassName: "animate-spin"
variant: "info",
icon: ChevronsLeftRightEllipsisIcon,
className: "animate-pulse"
},
[PamSessionStatus.Ended]: {
bgColor: "bg-bunker-300/20",
textColor: "text-bunker-300",
icon: faBan
variant: "neutral",
icon: BanIcon
}
};
@@ -48,15 +41,11 @@ export const PamSessionStatusBadge = ({ status }: { status: PamSessionStatus })
const displayName = status[0].toUpperCase() + status.slice(1);
const Icon = config.icon;
return (
<Badge
className={twMerge(
"flex h-5 w-min items-center gap-1.5 whitespace-nowrap",
config.bgColor,
config.textColor
)}
>
<FontAwesomeIcon icon={config.icon} className={config.iconClassName} />
<Badge variant={config.variant} className={config.className}>
<Icon />
{displayName}
</Badge>
);