Skip to content

Commit ab76d13

Browse files
author
Lasim
committed
refactor: integrate ProgressBars component for enhanced multi-step navigation and update localization for progress states
1 parent a12903e commit ab76d13

3 files changed

Lines changed: 109 additions & 41 deletions

File tree

services/frontend/src/components/admin/mcp-catalog/McpServerAddFormWizard.vue

Lines changed: 80 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,8 @@
22
import { ref, onMounted, onUnmounted, computed } from 'vue'
33
import { useI18n } from 'vue-i18n'
44
import { Button } from '@/components/ui/button'
5-
import {
6-
Breadcrumb,
7-
BreadcrumbItem,
8-
BreadcrumbLink,
9-
BreadcrumbList,
10-
BreadcrumbPage,
11-
BreadcrumbSeparator,
12-
} from '@/components/ui/breadcrumb'
135
import { Alert, AlertDescription } from '@/components/ui/alert'
6+
import { ProgressBars } from '@/components/ui/progress-bars'
147
import { FileText, Github, Settings, Loader2 } from 'lucide-vue-next'
158
import { McpCatalogService } from '@/services/mcpCatalogService'
169
import { useEventBus } from '@/composables/useEventBus'
@@ -89,6 +82,67 @@ const steps = [
8982
}
9083
]
9184
85+
// Progress steps for ProgressBars component
86+
const progressSteps = computed(() => {
87+
return steps.map((step, index) => {
88+
let status: 'completed' | 'current' | 'pending' | 'error' = 'pending'
89+
90+
if (index < currentStep.value) {
91+
status = 'completed'
92+
} else if (index === currentStep.value) {
93+
status = 'current'
94+
}
95+
96+
// Check for errors
97+
if (index === 0 && githubFetchError.value) {
98+
status = 'error'
99+
}
100+
101+
return {
102+
id: step.key,
103+
label: step.label,
104+
status,
105+
clickable: index < currentStep.value // Only completed steps are clickable
106+
}
107+
})
108+
})
109+
110+
// Calculate progress percentage
111+
const progressPercentage = computed(() => {
112+
// Progress should match visual step positions:
113+
// Step 1 (index 0): 0% progress
114+
// Step 2 (index 1): 50% progress (middle)
115+
// Step 3 (index 2): 100% progress (right)
116+
if (currentStep.value === 0) return 0
117+
if (currentStep.value === 1) return 50
118+
if (currentStep.value === 2) return 100
119+
return 0
120+
})
121+
122+
// Progress title based on current step
123+
const progressTitle = computed(() => {
124+
if (isSubmitting.value) {
125+
return t('mcpCatalog.form.navigation.creating')
126+
}
127+
if (isFetchingGitHub.value) {
128+
return t('mcpCatalog.form.navigation.fetching')
129+
}
130+
if (githubFetchError.value) {
131+
return t('mcpCatalog.form.errors.githubFetch')
132+
}
133+
134+
const currentStepData = steps[currentStep.value]
135+
return `${currentStepData.label} - ${t('mcpCatalog.form.steps.configuring')}`
136+
})
137+
138+
// Progress variant based on state
139+
const progressVariant = computed(() => {
140+
if (githubFetchError.value || submitError.value) return 'destructive'
141+
if (isSubmitting.value) return 'default' // Keep default while submitting
142+
// Only show success after actual completion (would need to be handled by parent component)
143+
return 'default'
144+
})
145+
92146
// State
93147
const currentStep = ref(0)
94148
const isSubmitting = ref(false)
@@ -201,6 +255,13 @@ const goToStep = (stepIndex: number) => {
201255
}
202256
}
203257
258+
// Handle step click from ProgressBars
259+
const handleStepClick = (step: any, index: number) => {
260+
if (step.clickable) {
261+
goToStep(index)
262+
}
263+
}
264+
204265
const nextStep = () => {
205266
if (canGoNext.value) {
206267
const oldStep = currentStep.value
@@ -335,39 +396,17 @@ onUnmounted(() => {
335396

336397
<template>
337398
<div class="space-y-6">
338-
<!-- Breadcrumb Navigation -->
339-
<Breadcrumb>
340-
<BreadcrumbList>
341-
<template v-for="(step, index) in steps" :key="index">
342-
<BreadcrumbItem>
343-
<!-- Current Step -->
344-
<BreadcrumbPage v-if="index === currentStep" class="flex items-center gap-2">
345-
<component :is="step.icon" class="h-4 w-4" />
346-
<span>{{ step.label }}</span>
347-
</BreadcrumbPage>
348-
349-
<!-- Completed Steps (clickable) -->
350-
<BreadcrumbLink
351-
v-else-if="index < currentStep"
352-
@click="goToStep(index)"
353-
class="flex items-center gap-2 cursor-pointer hover:text-foreground"
354-
>
355-
<component :is="step.icon" class="h-4 w-4" />
356-
<span>{{ step.label }}</span>
357-
</BreadcrumbLink>
358-
359-
<!-- Future Steps (disabled) -->
360-
<span v-else class="flex items-center gap-2 text-muted-foreground">
361-
<component :is="step.icon" class="h-4 w-4" />
362-
<span>{{ step.label }}</span>
363-
</span>
364-
</BreadcrumbItem>
365-
366-
<!-- Separator -->
367-
<BreadcrumbSeparator v-if="index < steps.length - 1" />
368-
</template>
369-
</BreadcrumbList>
370-
</Breadcrumb>
399+
<!-- Progress Bar Navigation -->
400+
<ProgressBars
401+
:steps="progressSteps"
402+
:progress="progressPercentage"
403+
:title="progressTitle"
404+
:variant="progressVariant"
405+
size="md"
406+
interactive
407+
styled
408+
@step-click="handleStepClick"
409+
/>
371410

372411
<!-- Error Message -->
373412
<Alert v-if="submitError" variant="destructive">

services/frontend/src/components/ui/progress-bars/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,30 @@ interface ProgressStep {
143143

144144
## Design Variants
145145

146+
### Progress Percentage Calculation
147+
148+
When implementing multi-step processes, the progress percentage should match the visual step positions:
149+
150+
- **Step 1 (index 0)**: 0% progress (leftmost position)
151+
- **Step 2 (index 1)**: 50% progress (middle position)
152+
- **Step 3 (index 2)**: 100% progress (rightmost position)
153+
154+
For more than 3 steps, calculate positions proportionally:
155+
- **4 steps**: 0%, 33%, 67%, 100%
156+
- **5 steps**: 0%, 25%, 50%, 75%, 100%
157+
158+
**Important**: Progress percentage represents visual positioning, not completion state. Use the `variant` prop to indicate actual completion status.
159+
160+
```html
161+
<!-- Example: 3-step wizard on step 2 -->
162+
<ProgressBars
163+
:steps="steps"
164+
:progress="50" <!-- 50% because step 2 is visually in the middle -->
165+
variant="default" <!-- Still default until process actually completes -->
166+
title="Configuration in progress..."
167+
/>
168+
```
169+
146170
### Default Theme
147171
- **Background**: Uses `bg-secondary` for track, `bg-primary` for fill
148172
- **Text**: Uses `text-foreground` for title, `text-primary` for active steps

services/frontend/src/i18n/locales/en/mcp-catalog.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,17 @@ export default {
4848
github: 'GitHub Repository',
4949
claudeConfig: 'Claude Desktop Config',
5050
basic: 'Basic Info',
51+
configuring: 'Step in progress',
5152
repository: 'Repository',
5253
technical: 'Technical',
5354
capabilities: 'Capabilities',
5455
review: 'Review'
5556
},
5657

58+
errors: {
59+
githubFetch: 'Failed to fetch repository information'
60+
},
61+
5762
github: {
5863
title: 'GitHub Repository',
5964
description: 'Connect a GitHub repository to automatically populate server information',

0 commit comments

Comments
 (0)