Skip to content

Commit 24cefe7

Browse files
author
Lasim
committed
feat(frontend): implement ContentWrapper component for consistent layout
1 parent fc1ea93 commit 24cefe7

File tree

3 files changed

+112
-66
lines changed

3 files changed

+112
-66
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<script setup lang="ts">
2+
import { computed } from 'vue'
3+
import { Card, CardContent } from '@/components/ui/card'
4+
5+
interface Props {
6+
/** Maximum width of the content container */
7+
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
8+
/** Enable/disable the gray background wrapper */
9+
background?: boolean
10+
/** Vertical padding size */
11+
padding?: 'sm' | 'md' | 'lg'
12+
/** Disable the white card wrapper (useful for custom content styling) */
13+
noCard?: boolean
14+
}
15+
16+
const props = withDefaults(defineProps<Props>(), {
17+
maxWidth: 'lg',
18+
background: true,
19+
padding: 'lg',
20+
noCard: false
21+
})
22+
23+
// Compute responsive max-width classes
24+
const maxWidthClasses = computed(() => {
25+
const maxWidthMap = {
26+
'sm': 'max-w-xl lg:max-w-2xl',
27+
'md': 'max-w-2xl lg:max-w-3xl',
28+
'lg': 'max-w-2xl lg:max-w-4xl',
29+
'xl': 'max-w-4xl lg:max-w-6xl',
30+
'2xl': 'max-w-6xl lg:max-w-7xl'
31+
}
32+
return maxWidthMap[props.maxWidth]
33+
})
34+
35+
// Compute padding classes
36+
const paddingClasses = computed(() => {
37+
const paddingMap = {
38+
'sm': 'py-8',
39+
'md': 'py-12',
40+
'lg': 'py-16'
41+
}
42+
return paddingMap[props.padding]
43+
})
44+
45+
// Compute container classes
46+
const containerClasses = computed(() => {
47+
const baseClasses = props.background
48+
? 'bg-muted/50 rounded-lg sm:rounded-lg'
49+
: ''
50+
return baseClasses
51+
})
52+
</script>
53+
54+
<template>
55+
<div :class="containerClasses">
56+
<div :class="paddingClasses">
57+
<div class="mx-auto max-w-7xl sm:px-2 lg:px-8">
58+
<div :class="['mx-auto px-4 lg:px-0', maxWidthClasses]">
59+
<!-- White Card wrapper (default) -->
60+
<Card v-if="!noCard" class="bg-white shadow-sm">
61+
<CardContent class="p-6">
62+
<slot />
63+
</CardContent>
64+
</Card>
65+
66+
<!-- Direct content (when noCard is true) -->
67+
<slot v-else />
68+
</div>
69+
</div>
70+
</div>
71+
</div>
72+
</template>

services/frontend/src/views/mcp-server/installation/[id].vue

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Card, CardContent } from '@/components/ui/card'
77
import { ArrowLeft, Info, Settings, Shield } from 'lucide-vue-next'
88
import { DsTabs, DsTabsItem } from '@/components/ui/ds-tabs'
99
import DashboardLayout from '@/components/DashboardLayout.vue'
10+
import ContentWrapper from '@/components/ContentWrapper.vue'
1011
import { InstallationInfo, EnvironmentVariables, DangerZone } from '@/components/mcp-server/installation'
1112
import { McpInstallationService } from '@/services/mcpInstallationService'
1213
import { TeamService, type Team } from '@/services/teamService'
@@ -167,39 +168,25 @@ const handleInstallationUpdated = (updatedInstallation: McpInstallation) => {
167168
</DsTabs>
168169

169170
<!-- Tab Content -->
170-
<div>
171-
<!-- Content Wrapper with same styling as EnvironmentVariablesStep -->
172-
<div class="bg-muted/50 rounded-lg sm:rounded-lg">
173-
<div class="py-16">
174-
<div class="mx-auto max-w-7xl sm:px-2 lg:px-8">
175-
<div class="mx-auto max-w-2xl px-4 lg:max-w-4xl lg:px-0">
176-
<!-- White Card inside the gray wrapper -->
177-
<Card class="bg-white shadow-sm">
178-
<CardContent class="p-6">
179-
<InstallationInfo
180-
v-if="activeTab === 'information'"
181-
:installation="installation"
182-
/>
183-
<EnvironmentVariables
184-
v-if="activeTab === 'environment'"
185-
:installation="installation"
186-
:can-edit="canEditInstallation"
187-
:user-role="userTeamRole"
188-
@installation-updated="handleInstallationUpdated"
189-
/>
190-
<DangerZone
191-
v-if="activeTab === 'danger-zone'"
192-
:installation="installation"
193-
:can-edit="canEditInstallation"
194-
:user-role="userTeamRole"
195-
/>
196-
</CardContent>
197-
</Card>
198-
</div>
199-
</div>
200-
</div>
201-
</div>
202-
</div>
171+
<ContentWrapper>
172+
<InstallationInfo
173+
v-if="activeTab === 'information'"
174+
:installation="installation"
175+
/>
176+
<EnvironmentVariables
177+
v-if="activeTab === 'environment'"
178+
:installation="installation"
179+
:can-edit="canEditInstallation"
180+
:user-role="userTeamRole"
181+
@installation-updated="handleInstallationUpdated"
182+
/>
183+
<DangerZone
184+
v-if="activeTab === 'danger-zone'"
185+
:installation="installation"
186+
:can-edit="canEditInstallation"
187+
:user-role="userTeamRole"
188+
/>
189+
</ContentWrapper>
203190
</div>
204191
</div>
205192
</DashboardLayout>

services/frontend/src/views/teams/manage/[id].vue

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Alert, AlertDescription } from '@/components/ui/alert'
88
import { ArrowLeft, Info, Users, Shield, Loader2, AlertTriangle } from 'lucide-vue-next'
99
import { DsTabs, DsTabsItem } from '@/components/ui/ds-tabs'
1010
import DashboardLayout from '@/components/DashboardLayout.vue'
11+
import ContentWrapper from '@/components/ContentWrapper.vue'
1112
import { TeamInfo, TeamMembers, TeamDangerZone } from '@/components/teams/manage'
1213
import { TeamService, type Team } from '@/services/teamService'
1314
import { useEventBus } from '@/composables/useEventBus'
@@ -197,39 +198,25 @@ onUnmounted(() => {
197198
</DsTabs>
198199

199200
<!-- Tab Content -->
200-
<div>
201-
<!-- Content Wrapper with same styling as MCP installation page -->
202-
<div class="bg-muted/50 rounded-lg sm:rounded-lg">
203-
<div class="py-16">
204-
<div class="mx-auto max-w-7xl sm:px-2 lg:px-8">
205-
<div class="mx-auto max-w-2xl px-4 lg:max-w-4xl lg:px-0">
206-
<!-- White Card inside the gray wrapper -->
207-
<Card class="bg-white shadow-sm">
208-
<CardContent class="p-6">
209-
<TeamInfo
210-
v-if="activeTab === 'team-info'"
211-
:team="team"
212-
:can-edit-name="canEditName"
213-
:can-edit-description="canEditDescription"
214-
@team-updated="handleTeamUpdated"
215-
/>
216-
<TeamMembers
217-
v-if="activeTab === 'members'"
218-
:team="team"
219-
:can-manage-members="canManageMembers"
220-
/>
221-
<TeamDangerZone
222-
v-if="activeTab === 'danger-zone'"
223-
:team="team"
224-
:can-delete-team="canDeleteTeam"
225-
/>
226-
</CardContent>
227-
</Card>
228-
</div>
229-
</div>
230-
</div>
231-
</div>
232-
</div>
201+
<ContentWrapper>
202+
<TeamInfo
203+
v-if="activeTab === 'team-info'"
204+
:team="team"
205+
:can-edit-name="canEditName"
206+
:can-edit-description="canEditDescription"
207+
@team-updated="handleTeamUpdated"
208+
/>
209+
<TeamMembers
210+
v-if="activeTab === 'members'"
211+
:team="team"
212+
:can-manage-members="canManageMembers"
213+
/>
214+
<TeamDangerZone
215+
v-if="activeTab === 'danger-zone'"
216+
:team="team"
217+
:can-delete-team="canDeleteTeam"
218+
/>
219+
</ContentWrapper>
233220
</div>
234221
</div>
235222
</DashboardLayout>

0 commit comments

Comments
 (0)