Skip to content

Commit ce05c33

Browse files
author
Lasim
committed
feat(event-bus): implement event bus for team updates and manage event emissions
1 parent 9c4bb9c commit ce05c33

File tree

8 files changed

+49
-5
lines changed

8 files changed

+49
-5
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"class-variance-authority": "^0.7.1",
2222
"clsx": "^2.1.1",
2323
"lucide-vue-next": "^0.511.0",
24+
"mitt": "^3.0.1",
2425
"pinia": "^3.0.3",
2526
"reka-ui": "^2.3.1",
2627
"tailwind-merge": "^3.3.0",

services/frontend/src/components/AppSidebar.vue

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { ref, onMounted, computed } from 'vue'
2+
import { ref, onMounted, onUnmounted, computed } from 'vue'
33
import { useRouter } from 'vue-router'
44
import { useI18n } from 'vue-i18n'
55
// import { cn } from '@/lib/utils' // cn might not be needed for root if $attrs.class is used directly
@@ -30,6 +30,7 @@ import {
3030
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
3131
import { TeamService, type Team } from '@/services/teamService'
3232
import { UserService, type User } from '@/services/userService'
33+
import { useEventBus } from '@/composables/useEventBus'
3334
import {
3435
Server,
3536
LayoutDashboard,
@@ -52,6 +53,7 @@ const props = defineProps<Props>()
5253
5354
const router = useRouter()
5455
const { t } = useI18n()
56+
const eventBus = useEventBus()
5557
5658
// User data
5759
const currentUser = ref<User | null>(null)
@@ -154,6 +156,17 @@ const getUserInitials = (name: string) => { return name.split(' ').map(word => w
154156
onMounted(() => {
155157
fetchUserData()
156158
fetchTeams()
159+
160+
// Listen for team updates from other components
161+
eventBus.on('teams-updated', () => {
162+
console.log('Teams updated event received, refreshing teams...')
163+
fetchTeams(true) // Force refresh to get latest data
164+
})
165+
})
166+
167+
onUnmounted(() => {
168+
// Clean up event listeners
169+
eventBus.off('teams-updated')
157170
})
158171
</script>
159172

services/frontend/src/components/teams/AddTeamModal.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Button } from '@/components/ui/button'
1414
import { Input } from '@/components/ui/input'
1515
import { Label } from '@/components/ui/label'
1616
import { TeamService, CreateTeamSchema, type CreateTeamInput } from '@/services/teamService'
17+
import { useEventBus } from '@/composables/useEventBus'
1718
1819
interface Props {
1920
open: boolean
@@ -27,6 +28,7 @@ interface Emits {
2728
const props = defineProps<Props>()
2829
const emit = defineEmits<Emits>()
2930
const { t } = useI18n()
31+
const eventBus = useEventBus()
3032
3133
// Form state
3234
const formData = ref<CreateTeamInput>({
@@ -77,6 +79,9 @@ const handleSubmit = async () => {
7779
try {
7880
await TeamService.createTeam(formData.value)
7981
82+
// Emit global event for immediate UI updates across components
83+
eventBus.emit('teams-updated')
84+
8085
// Reset form
8186
formData.value = { name: '', description: '' }
8287
errors.value = {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { inject } from 'vue'
2+
import type { Emitter } from 'mitt'
3+
4+
export type EventBusEvents = {
5+
'teams-updated': void
6+
'team-created': void
7+
'team-deleted': void
8+
}
9+
10+
export function useEventBus() {
11+
const emitter = inject<Emitter<EventBusEvents>>('emitter')
12+
if (!emitter) {
13+
throw new Error('Event bus not provided. Make sure to provide the emitter in main.ts')
14+
}
15+
return emitter
16+
}

services/frontend/src/main.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import './assets/index.css'
22

33
import { createApp } from 'vue'
44
import { createPinia } from 'pinia'
5+
import mitt from 'mitt'
56

67
import App from './App.vue'
78
import router from './router'
@@ -10,10 +11,14 @@ import i18n from './i18n'
1011
import { PluginManager } from './plugin-system/plugin-manager'
1112
import { loadPlugins } from './plugins'
1213
import ExtensionPoint from './components/ExtensionPoint.vue'
14+
import type { EventBusEvents } from './composables/useEventBus'
1315

1416
const app = createApp(App)
1517
const pinia = createPinia()
1618

19+
// Create event bus
20+
const emitter = mitt<EventBusEvents>()
21+
1722
// Register global components
1823
app.component('ExtensionPoint', ExtensionPoint)
1924

@@ -30,8 +35,9 @@ app.use(pinia)
3035
app.use(router)
3136
app.use(i18n)
3237

33-
// Make plugin manager available globally in the app
38+
// Provide global services
3439
app.provide('pluginManager', pluginManager)
40+
app.provide('emitter', emitter)
3541

3642
// Initialize application with plugins
3743
async function initializeApplication() {

services/frontend/src/views/Teams.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import DashboardLayout from '@/components/DashboardLayout.vue'
2727
import AddTeamModal from '@/components/teams/AddTeamModal.vue'
2828
import { TeamService, type TeamWithRole } from '@/services/teamService'
2929
import { UserService } from '@/services/userService'
30+
import { useEventBus } from '@/composables/useEventBus'
3031
import { createColumns } from './teams/columns'
3132
import { useRouter, useRoute } from 'vue-router'
3233
import { Alert, AlertDescription } from '@/components/ui/alert'
@@ -35,6 +36,7 @@ import { CheckCircle } from 'lucide-vue-next'
3536
const { t } = useI18n()
3637
const router = useRouter()
3738
const route = useRoute()
39+
const eventBus = useEventBus()
3840
3941
// State
4042
const teams = ref<TeamWithRole[]>([])
@@ -89,8 +91,8 @@ const fetchTeams = async (): Promise<void> => {
8991
// Handle team creation success
9092
const handleTeamCreated = async () => {
9193
await fetchTeams()
92-
// Also refresh the sidebar teams
93-
await TeamService.getUserTeams(true)
94+
// Emit global event to update sidebar and other components
95+
eventBus.emit('teams-updated')
9496
}
9597
9698
// Check for delete success message from query params

services/frontend/src/views/teams/TeamManage.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { Label } from '@/components/ui/label'
88
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
99
import { Alert, AlertDescription } from '@/components/ui/alert'
1010
import { Badge } from '@/components/ui/badge'
11-
import { Separator } from '@/components/ui/separator'
1211
import { ArrowLeft, Save, Trash2, AlertTriangle, Lock } from 'lucide-vue-next'
1312
import DashboardLayout from '@/components/DashboardLayout.vue'
1413
import { TeamService, type Team } from '@/services/teamService'
@@ -39,6 +38,7 @@ const saveError = ref<string | null>(null)
3938
const saveSuccess = ref(false)
4039
const showDeleteDialog = ref(false)
4140
const userPermissions = ref<string[]>([])
41+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
4242
const currentUser = ref<any>(null)
4343
4444
// Form data

0 commit comments

Comments
 (0)