refactor: migrate badge to design system and remove PrimeVue Badge

- Update StatusBadge severity colors to match Figma design system
- Move Storybook story from Common/ to Components/Badges/
- Replace PrimeVue Badge with StatusBadge in TreeExplorerTreeNode,
  UsageLogsTable, and SearchFilterChip
- Update customerEventsService severity values for StatusBadge compat
This commit is contained in:
dante01yoon
2026-03-24 19:55:23 +09:00
parent 4bfc730a0e
commit 75b47c7970
8 changed files with 80 additions and 54 deletions

View File

@@ -1,17 +1,25 @@
<template>
<Chip removable @remove="emit('remove', $event)">
<Badge size="small" :class="semanticBadgeClass">
<span
:class="
cn(
'inline-flex items-center justify-center rounded-full px-1 text-xxxs font-semibold uppercase',
semanticBadgeClass
)
"
>
{{ badge }}
</Badge>
</span>
{{ text }}
</Chip>
</template>
<script setup lang="ts">
import Badge from 'primevue/badge'
import Chip from 'primevue/chip'
import { computed } from 'vue'
import { cn } from '@/utils/tailwindUtil'
export interface SearchFilter {
text: string
badge: string

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite'
import StatusBadge from './StatusBadge.vue'
const meta = {
title: 'Common/StatusBadge',
title: 'Components/Badges/StatusBadge',
component: StatusBadge,
tags: ['autodocs'],
argTypes: {
@@ -18,7 +18,7 @@ const meta = {
}
},
args: {
label: 'Status',
label: 'NEW',
severity: 'default'
}
} satisfies Meta<typeof StatusBadge>
@@ -28,28 +28,34 @@ type Story = StoryObj<typeof meta>
export const Default: Story = {}
export const Failed: Story = {
export const Secondary: Story = {
args: {
label: 'Failed',
label: 'NEW',
severity: 'secondary'
}
}
export const Warn: Story = {
args: {
label: 'NEW',
severity: 'warn'
}
}
export const Danger: Story = {
args: {
label: 'NEW',
severity: 'danger'
}
}
export const Finished: Story = {
export const Contrast: Story = {
args: {
label: 'Finished',
label: 'NEW',
severity: 'contrast'
}
}
export const Dot: Story = {
args: {
label: undefined,
variant: 'dot',
severity: 'danger'
}
}
export const Circle: Story = {
args: {
label: '3',
@@ -57,16 +63,31 @@ export const Circle: Story = {
}
}
export const AllSeverities: Story = {
export const AllSeveritiesLabel: Story = {
render: () => ({
components: { StatusBadge },
template: `
<div class="flex items-center gap-2">
<StatusBadge label="Default" severity="default" />
<StatusBadge label="Secondary" severity="secondary" />
<StatusBadge label="Warn" severity="warn" />
<StatusBadge label="Danger" severity="danger" />
<StatusBadge label="Contrast" severity="contrast" />
<StatusBadge label="NEW" severity="default" />
<StatusBadge label="NEW" severity="secondary" />
<StatusBadge label="NEW" severity="warn" />
<StatusBadge label="NEW" severity="danger" />
<StatusBadge label="NEW" severity="contrast" />
</div>
`
})
}
export const AllSeveritiesDot: Story = {
render: () => ({
components: { StatusBadge },
template: `
<div class="flex items-center gap-2">
<StatusBadge variant="dot" severity="default" />
<StatusBadge variant="dot" severity="secondary" />
<StatusBadge variant="dot" severity="warn" />
<StatusBadge variant="dot" severity="danger" />
<StatusBadge variant="dot" severity="contrast" />
</div>
`
})
@@ -78,7 +99,7 @@ export const AllVariants: Story = {
template: `
<div class="flex items-center gap-4">
<div class="flex flex-col items-center gap-1">
<StatusBadge label="Label" variant="label" />
<StatusBadge label="NEW" variant="label" />
<span class="text-xs text-muted">label</span>
</div>
<div class="flex flex-col items-center gap-1">

View File

@@ -1,6 +1,6 @@
import { createTestingPinia } from '@pinia/testing'
import { mount } from '@vue/test-utils'
import Badge from 'primevue/badge'
import StatusBadge from '@/components/common/StatusBadge.vue'
import PrimeVue from 'primevue/config'
import InputText from 'primevue/inputtext'
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
@@ -47,7 +47,7 @@ describe('TreeExplorerTreeNode', () => {
const wrapper = mount(TreeExplorerTreeNode, {
props: { node: mockNode },
global: {
components: { EditableText, Badge },
components: { EditableText, StatusBadge },
plugins: [createTestingPinia(), i18n],
provide: {
[InjectKeyHandleEditLabelFunction]: mockHandleEditLabel
@@ -61,8 +61,7 @@ describe('TreeExplorerTreeNode', () => {
expect(wrapper.findComponent(EditableText).props('modelValue')).toBe(
'Test Node'
)
// @ts-expect-error fixme ts strict error
expect(wrapper.findComponent(Badge).props()['value'].toString()).toBe('3')
expect(wrapper.findComponent(StatusBadge).props('label')).toBe('3')
})
it('makes node label editable when renamingEditingNode matches', async () => {
@@ -74,7 +73,7 @@ describe('TreeExplorerTreeNode', () => {
}
},
global: {
components: { EditableText, Badge, InputText },
components: { EditableText, StatusBadge, InputText },
plugins: [createTestingPinia(), i18n, PrimeVue],
provide: {
[InjectKeyHandleEditLabelFunction]: mockHandleEditLabel
@@ -97,7 +96,7 @@ describe('TreeExplorerTreeNode', () => {
}
},
global: {
components: { EditableText, Badge, InputText },
components: { EditableText, StatusBadge, InputText },
provide: { [InjectKeyHandleEditLabelFunction]: handleEditLabelMock },
plugins: [createTestingPinia(), i18n, PrimeVue]
}

View File

@@ -21,11 +21,12 @@
/>
<slot name="after-label" :node="props.node" />
</span>
<Badge
<StatusBadge
v-if="showNodeBadgeText"
:value="nodeBadgeText"
:label="nodeBadgeText"
severity="secondary"
class="leaf-count-badge"
variant="circle"
class="ml-2"
/>
</div>
<div
@@ -38,7 +39,7 @@
<script setup lang="ts" generic="T">
import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview'
import Badge from 'primevue/badge'
import StatusBadge from '@/components/common/StatusBadge.vue'
import { computed, inject, ref } from 'vue'
import EditableText from '@/components/common/EditableText.vue'
@@ -146,9 +147,6 @@ if (props.node.droppable) {
align-items: center;
justify-content: space-between;
}
.leaf-count-badge {
margin-left: 0.5rem;
}
.node-content {
display: flex;
align-items: center;

View File

@@ -5,9 +5,9 @@ export const statusBadgeVariants = cva({
base: 'inline-flex items-center justify-center rounded-full',
variants: {
severity: {
default: 'bg-primary-background text-base-foreground',
secondary: 'bg-secondary-background text-base-foreground',
warn: 'bg-warning-background text-base-background',
default: 'bg-primary-background text-white',
secondary: 'bg-secondary-background-hover text-white',
warn: 'bg-warning-background text-white',
danger: 'bg-destructive-background text-white',
contrast: 'bg-base-foreground text-base-background'
},

View File

@@ -1,6 +1,6 @@
import { createTestingPinia } from '@pinia/testing'
import { mount } from '@vue/test-utils'
import Badge from 'primevue/badge'
import StatusBadge from '@/components/common/StatusBadge.vue'
import Button from '@/components/ui/button/Button.vue'
import Column from 'primevue/column'
import PrimeVue from 'primevue/config'
@@ -125,13 +125,13 @@ describe('UsageLogsTable', () => {
mockCustomerEventsService.getEventSeverity.mockImplementation((type) => {
switch (type) {
case EventType.CREDIT_ADDED:
return 'success'
return 'default'
case EventType.ACCOUNT_CREATED:
return 'info'
return 'secondary'
case EventType.API_USAGE_COMPLETED:
return 'warning'
return 'warn'
default:
return 'info'
return 'secondary'
}
})
mockCustomerEventsService.formatAmount.mockImplementation((amount) => {
@@ -163,7 +163,7 @@ describe('UsageLogsTable', () => {
components: {
DataTable,
Column,
Badge,
StatusBadge,
Button,
Message,
ProgressSpinner
@@ -240,7 +240,7 @@ describe('UsageLogsTable', () => {
vm.events = mockEventsResponse.events
await nextTick()
const badges = wrapper.findAllComponents(Badge)
const badges = wrapper.findAllComponents(StatusBadge)
expect(badges.length).toBeGreaterThan(0)
// Check if formatEventType and getEventSeverity are called

View File

@@ -19,8 +19,8 @@
>
<Column field="event_type" :header="$t('credits.eventType')">
<template #body="{ data }">
<Badge
:value="customerEventService.formatEventType(data.event_type)"
<StatusBadge
:label="customerEventService.formatEventType(data.event_type)"
:severity="customerEventService.getEventSeverity(data.event_type)"
/>
</template>
@@ -91,7 +91,7 @@
</template>
<script setup lang="ts">
import Badge from 'primevue/badge'
import StatusBadge from '@/components/common/StatusBadge.vue'
import Column from 'primevue/column'
import DataTable from 'primevue/datatable'
import Message from 'primevue/message'

View File

@@ -136,13 +136,13 @@ export const useCustomerEventsService = () => {
function getEventSeverity(eventType: string) {
switch (eventType) {
case 'credit_added':
return 'success'
return 'default'
case 'account_created':
return 'info'
return 'secondary'
case 'api_usage_completed':
return 'warning'
return 'warn'
default:
return 'info'
return 'secondary'
}
}