mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-13 23:45:17 +00:00
refactor: extract TagBadge into shared component
Replace duplicated inline badge styling with a reusable TagBadge component to ensure consistent appearance across all tag displays.
This commit is contained in:
@@ -17,6 +17,7 @@ import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar";
|
|||||||
import { DateTooltip } from "@/components/shared/date-tooltip";
|
import { DateTooltip } from "@/components/shared/date-tooltip";
|
||||||
import { FocusShortcutInput } from "@/components/shared/focus-shortcut-input";
|
import { FocusShortcutInput } from "@/components/shared/focus-shortcut-input";
|
||||||
import { StatusTooltip } from "@/components/shared/status-tooltip";
|
import { StatusTooltip } from "@/components/shared/status-tooltip";
|
||||||
|
import { TagBadge } from "@/components/shared/tag-badge";
|
||||||
import { TagFilter } from "@/components/shared/tag-filter";
|
import { TagFilter } from "@/components/shared/tag-filter";
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
@@ -29,7 +30,6 @@ import {
|
|||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -486,23 +486,11 @@ export const ShowProjects = () => {
|
|||||||
project.projectTags.length > 0 && (
|
project.projectTags.length > 0 && (
|
||||||
<div className="flex flex-wrap gap-1.5 mt-2">
|
<div className="flex flex-wrap gap-1.5 mt-2">
|
||||||
{project.projectTags.map((pt) => (
|
{project.projectTags.map((pt) => (
|
||||||
<Badge
|
<TagBadge
|
||||||
key={pt.tag.tagId}
|
key={pt.tag.tagId}
|
||||||
variant="blank"
|
name={pt.tag.name}
|
||||||
style={{
|
color={pt.tag.color}
|
||||||
backgroundColor: pt.tag.color
|
/>
|
||||||
? `${pt.tag.color}33`
|
|
||||||
: undefined,
|
|
||||||
color:
|
|
||||||
pt.tag.color || undefined,
|
|
||||||
borderColor: pt.tag.color
|
|
||||||
? `${pt.tag.color}66`
|
|
||||||
: undefined,
|
|
||||||
}}
|
|
||||||
className="border"
|
|
||||||
>
|
|
||||||
{pt.tag.name}
|
|
||||||
</Badge>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useForm } from "react-hook-form";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { AlertBlock } from "@/components/shared/alert-block";
|
import { AlertBlock } from "@/components/shared/alert-block";
|
||||||
|
import { TagBadge } from "@/components/shared/tag-badge";
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
@@ -15,7 +16,6 @@ import {
|
|||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -232,16 +232,10 @@ export const HandleTag = ({ tagId }: HandleTagProps) => {
|
|||||||
{colorValue && (
|
{colorValue && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-sm text-muted-foreground">Preview:</span>
|
<span className="text-sm text-muted-foreground">Preview:</span>
|
||||||
<Badge
|
<TagBadge
|
||||||
style={{
|
name={form.watch("name") || "Tag Name"}
|
||||||
backgroundColor: `${colorValue}33`,
|
color={colorValue}
|
||||||
color: colorValue,
|
/>
|
||||||
borderColor: `${colorValue}66`,
|
|
||||||
}}
|
|
||||||
className="border"
|
|
||||||
>
|
|
||||||
{form.watch("name") || "Tag Name"}
|
|
||||||
</Badge>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</form>
|
</form>
|
||||||
@@ -355,18 +349,7 @@ export const TagManager = () => {
|
|||||||
className="flex items-center justify-between rounded-lg border p-3 hover:bg-accent/50 transition-colors"
|
className="flex items-center justify-between rounded-lg border p-3 hover:bg-accent/50 transition-colors"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Badge
|
<TagBadge name={tag.name} color={tag.color} />
|
||||||
style={{
|
|
||||||
backgroundColor: tag.color
|
|
||||||
? `${tag.color}33`
|
|
||||||
: undefined,
|
|
||||||
color: tag.color || undefined,
|
|
||||||
borderColor: tag.color ? `${tag.color}66` : undefined,
|
|
||||||
}}
|
|
||||||
className="border"
|
|
||||||
>
|
|
||||||
{tag.name}
|
|
||||||
</Badge>
|
|
||||||
{tag.color && (
|
{tag.color && (
|
||||||
<span className="text-xs text-muted-foreground font-mono">
|
<span className="text-xs text-muted-foreground font-mono">
|
||||||
{tag.color}
|
{tag.color}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
interface TagBadgeProps {
|
||||||
|
name: string;
|
||||||
|
color?: string | null;
|
||||||
|
className?: string;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TagBadge({ name, color, className, children }: TagBadgeProps) {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
style={{
|
||||||
|
backgroundColor: color ? `${color}33` : undefined,
|
||||||
|
color: color || undefined,
|
||||||
|
borderColor: color ? `${color}66` : undefined,
|
||||||
|
}}
|
||||||
|
className={cn("border", className)}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
{children}
|
||||||
|
</Badge>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Filter } from "lucide-react";
|
import { Filter } from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { HandleTag } from "@/components/dashboard/settings/tags/tag-manager";
|
import { HandleTag } from "@/components/dashboard/settings/tags/tag-manager";
|
||||||
|
import { TagBadge } from "@/components/shared/tag-badge";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
@@ -109,18 +110,7 @@ export function TagFilter({
|
|||||||
className="mr-2"
|
className="mr-2"
|
||||||
onCheckedChange={() => handleTagToggle(tag.id)}
|
onCheckedChange={() => handleTagToggle(tag.id)}
|
||||||
/>
|
/>
|
||||||
<Badge
|
<TagBadge name={tag.name} color={tag.color} />
|
||||||
style={{
|
|
||||||
backgroundColor: tag.color
|
|
||||||
? `${tag.color}33`
|
|
||||||
: undefined,
|
|
||||||
color: tag.color || undefined,
|
|
||||||
borderColor: tag.color ? `${tag.color}66` : undefined,
|
|
||||||
}}
|
|
||||||
className="border"
|
|
||||||
>
|
|
||||||
{tag.name}
|
|
||||||
</Badge>
|
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Check, ChevronsUpDown, X } from "lucide-react";
|
import { Check, ChevronsUpDown, X } from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { HandleTag } from "@/components/dashboard/settings/tags/tag-manager";
|
import { HandleTag } from "@/components/dashboard/settings/tags/tag-manager";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { TagBadge } from "@/components/shared/tag-badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
import {
|
||||||
@@ -77,17 +77,12 @@ export function TagSelector({
|
|||||||
<div className="flex flex-wrap gap-1 flex-1">
|
<div className="flex flex-wrap gap-1 flex-1">
|
||||||
{selectedTagObjects.length > 0 ? (
|
{selectedTagObjects.length > 0 ? (
|
||||||
selectedTagObjects.map((tag) => (
|
selectedTagObjects.map((tag) => (
|
||||||
<Badge
|
<TagBadge
|
||||||
key={tag.id}
|
key={tag.id}
|
||||||
variant="blank"
|
name={tag.name}
|
||||||
style={{
|
color={tag.color}
|
||||||
backgroundColor: tag.color ? `${tag.color}33` : undefined,
|
className="flex items-center gap-1 pr-1"
|
||||||
color: tag.color || undefined,
|
|
||||||
borderColor: tag.color ? `${tag.color}66` : undefined,
|
|
||||||
}}
|
|
||||||
className="flex items-center gap-1 pr-1 border"
|
|
||||||
>
|
>
|
||||||
<span>{tag.name}</span>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => handleTagRemove(tag.id, e)}
|
onClick={(e) => handleTagRemove(tag.id, e)}
|
||||||
@@ -97,7 +92,7 @@ export function TagSelector({
|
|||||||
<X className="h-3 w-3 hover:opacity-70" />
|
<X className="h-3 w-3 hover:opacity-70" />
|
||||||
<span className="sr-only">Remove {tag.name}</span>
|
<span className="sr-only">Remove {tag.name}</span>
|
||||||
</button>
|
</button>
|
||||||
</Badge>
|
</TagBadge>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<span className="text-muted-foreground">{placeholder}</span>
|
<span className="text-muted-foreground">{placeholder}</span>
|
||||||
@@ -132,19 +127,11 @@ export function TagSelector({
|
|||||||
className="mr-2"
|
className="mr-2"
|
||||||
onCheckedChange={() => handleTagToggle(tag.id)}
|
onCheckedChange={() => handleTagToggle(tag.id)}
|
||||||
/>
|
/>
|
||||||
<Badge
|
<TagBadge
|
||||||
variant="blank"
|
name={tag.name}
|
||||||
style={{
|
color={tag.color}
|
||||||
backgroundColor: tag.color
|
className="mr-2"
|
||||||
? `${tag.color}33`
|
/>
|
||||||
: undefined,
|
|
||||||
color: tag.color || undefined,
|
|
||||||
borderColor: tag.color ? `${tag.color}66` : undefined,
|
|
||||||
}}
|
|
||||||
className="mr-2 border"
|
|
||||||
>
|
|
||||||
{tag.name}
|
|
||||||
</Badge>
|
|
||||||
<Check
|
<Check
|
||||||
className={cn(
|
className={cn(
|
||||||
"ml-auto h-4 w-4",
|
"ml-auto h-4 w-4",
|
||||||
|
|||||||
Reference in New Issue
Block a user