Add status badge to USB policy chip in device details
- Replace parentheses text with styled badge - Use color-coded badges: success (green), warning (amber), error (red) - Add APPLYING status support - Match badge style with custom fields counter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
71757a1d59
commit
0c8d53c0b6
1 changed files with 36 additions and 7 deletions
|
|
@ -3137,7 +3137,7 @@ export function DeviceDetails({ device }: DeviceDetailsProps) {
|
|||
const hasRemoteAccess = remoteAccessEntries.length > 0
|
||||
|
||||
const summaryChips = useMemo(() => {
|
||||
const chips: Array<{ key: string; label: string; value: string; icon: ReactNode; tone?: "warning" | "muted"; onClick?: () => void }> = []
|
||||
const chips: Array<{ key: string; label: string; value: string; icon: ReactNode; tone?: "warning" | "muted"; onClick?: () => void; statusBadge?: { text: string; variant: "default" | "success" | "warning" | "error" } }> = []
|
||||
const osName = osNameDisplay || "Sistema desconhecido"
|
||||
const osVersionRaw = device?.osVersion ?? windowsVersionLabel ?? ""
|
||||
const osVersion = formatOsVersionDisplay(osNameDisplay, osVersionRaw)
|
||||
|
|
@ -3193,20 +3193,34 @@ export function DeviceDetails({ device }: DeviceDetailsProps) {
|
|||
}
|
||||
const statusLabels: Record<string, string> = {
|
||||
PENDING: "Pendente",
|
||||
APPLYING: "Aplicando",
|
||||
APPLIED: "Aplicado",
|
||||
FAILED: "Falhou",
|
||||
}
|
||||
const statusBadgeVariants: Record<string, "default" | "success" | "warning" | "error"> = {
|
||||
PENDING: "warning",
|
||||
APPLYING: "warning",
|
||||
APPLIED: "success",
|
||||
FAILED: "error",
|
||||
}
|
||||
const currentPolicy = device?.usbPolicy ?? "ALLOW"
|
||||
const policyLabel = policyLabels[currentPolicy] ?? currentPolicy
|
||||
const statusLabel = device?.usbPolicyStatus ? ` (${statusLabels[device.usbPolicyStatus] ?? device.usbPolicyStatus})` : ""
|
||||
const isPending = device?.usbPolicyStatus === "PENDING"
|
||||
const isApplying = device?.usbPolicyStatus === "APPLYING"
|
||||
const isFailed = device?.usbPolicyStatus === "FAILED"
|
||||
const statusBadge = device?.usbPolicyStatus
|
||||
? {
|
||||
text: statusLabels[device.usbPolicyStatus] ?? device.usbPolicyStatus,
|
||||
variant: statusBadgeVariants[device.usbPolicyStatus] ?? "default" as const,
|
||||
}
|
||||
: undefined
|
||||
chips.push({
|
||||
key: "usb-policy",
|
||||
label: "USB",
|
||||
value: `${policyLabel}${statusLabel}`,
|
||||
icon: <Usb className={`size-4 ${isFailed ? "text-red-500" : isPending ? "text-amber-500" : "text-neutral-500"}`} />,
|
||||
tone: isFailed ? "warning" : isPending ? "warning" : undefined,
|
||||
value: policyLabel,
|
||||
icon: <Usb className={`size-4 ${isFailed ? "text-red-500" : isPending || isApplying ? "text-amber-500" : "text-neutral-500"}`} />,
|
||||
tone: isFailed ? "warning" : isPending || isApplying ? "warning" : undefined,
|
||||
statusBadge,
|
||||
})
|
||||
}
|
||||
return chips
|
||||
|
|
@ -3917,6 +3931,7 @@ export function DeviceDetails({ device }: DeviceDetailsProps) {
|
|||
value={chip.value}
|
||||
icon={chip.icon}
|
||||
tone={chip.tone}
|
||||
statusBadge={chip.statusBadge}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -6176,7 +6191,7 @@ function DetailLine({ label, value, classNameValue, layout = "spread" }: DetailL
|
|||
)
|
||||
}
|
||||
|
||||
function InfoChip({ label, value, icon, tone = "default", onClick }: { label: string; value: string; icon?: ReactNode; tone?: "default" | "warning" | "muted"; onClick?: () => void }) {
|
||||
function InfoChip({ label, value, icon, tone = "default", onClick, statusBadge }: { label: string; value: string; icon?: ReactNode; tone?: "default" | "warning" | "muted"; onClick?: () => void; statusBadge?: { text: string; variant: "default" | "success" | "warning" | "error" } }) {
|
||||
const toneClasses =
|
||||
tone === "warning"
|
||||
? "border-amber-200 bg-amber-50 text-amber-700"
|
||||
|
|
@ -6186,6 +6201,13 @@ function InfoChip({ label, value, icon, tone = "default", onClick }: { label: st
|
|||
|
||||
const clickableClasses = onClick ? "cursor-pointer hover:ring-2 hover:ring-blue-200 transition-all" : ""
|
||||
|
||||
const badgeVariantClasses = {
|
||||
default: "border-slate-200 bg-slate-100 text-slate-600",
|
||||
success: "border-emerald-200 bg-emerald-50 text-emerald-700",
|
||||
warning: "border-amber-200 bg-amber-50 text-amber-700",
|
||||
error: "border-red-200 bg-red-50 text-red-700",
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn("flex items-center gap-3 rounded-xl border px-3 py-2 shadow-sm", toneClasses, clickableClasses)}
|
||||
|
|
@ -6197,7 +6219,14 @@ function InfoChip({ label, value, icon, tone = "default", onClick }: { label: st
|
|||
{icon ? <span className="text-neutral-500">{icon}</span> : null}
|
||||
<div className="min-w-0 leading-tight">
|
||||
<p className="text-xs uppercase text-neutral-500">{label}</p>
|
||||
<p className="truncate text-sm font-semibold">{value}</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="truncate text-sm font-semibold">{value}</p>
|
||||
{statusBadge && (
|
||||
<span className={cn("inline-flex rounded-full border px-2 py-0.5 text-[11px] font-semibold", badgeVariantClasses[statusBadge.variant])}>
|
||||
{statusBadge.text}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue