Skip to content

Commit d4d45eb

Browse files
committed
chore: wip
1 parent 37ca2b9 commit d4d45eb

File tree

2 files changed

+153
-201
lines changed

2 files changed

+153
-201
lines changed

app/Models/Activity.ts

Lines changed: 0 additions & 101 deletions
This file was deleted.

storage/framework/defaults/views/dashboard/models/users.vue

Lines changed: 153 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,57 @@
9999
<div class="flex items-center justify-between mb-6">
100100
<div>
101101
<h3 class="text-base font-medium text-gray-900 dark:text-gray-100">User Model Relationships</h3>
102-
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Interactive diagram showing User model relationships. Click on any model to navigate to its details.</p>
102+
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Interactive diagram showing User model relationships. Click on any model to view details.</p>
103103
</div>
104104
</div>
105-
<div ref="diagramContainer" class="h-[400px] relative">
106-
<!-- D3 diagram will be rendered here -->
105+
<div class="flex">
106+
<div ref="diagramContainer" class="h-[400px] relative flex-1">
107+
<!-- D3 diagram will be rendered here -->
108+
</div>
109+
110+
<div v-if="selectedModel" class="w-64 ml-6 p-4 bg-gray-50 dark:bg-blue-gray-600 rounded-lg">
111+
<div class="flex items-center mb-4">
112+
<span class="text-2xl mr-2">{{ selectedModel.emoji }}</span>
113+
<h4 class="text-lg font-semibold text-gray-900 dark:text-gray-100">{{ selectedModel.name }}</h4>
114+
</div>
115+
116+
<div class="mb-4">
117+
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Properties</h5>
118+
<ul class="space-y-1">
119+
<li v-for="prop in selectedModel.properties" :key="prop" class="text-sm text-gray-600 dark:text-gray-400 font-mono">
120+
{{ prop }}
121+
</li>
122+
</ul>
123+
</div>
124+
125+
<div class="mb-6">
126+
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Relationships</h5>
127+
<ul class="space-y-1">
128+
<li v-for="rel in selectedModel.relationships" :key="rel" class="text-sm text-gray-600 dark:text-gray-400 font-mono">
129+
{{ rel }}
130+
</li>
131+
</ul>
132+
</div>
133+
134+
<router-link
135+
v-if="selectedModel.id === 'user'"
136+
:to="getModelRoute('team')"
137+
class="flex items-center justify-center w-full px-4 py-2 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-500 rounded-md shadow-sm transition-colors duration-150 group"
138+
>
139+
Next: Team Model
140+
<svg class="w-4 h-4 ml-2 transition-transform group-hover:translate-x-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
141+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
142+
</svg>
143+
</router-link>
144+
145+
<router-link
146+
v-else
147+
:to="getModelRoute(selectedModel.id)"
148+
class="block w-full text-center px-4 py-2 text-sm font-semibold text-white bg-blue-600 hover:bg-blue-500 rounded-md shadow-sm transition-colors duration-150"
149+
>
150+
View Details
151+
</router-link>
152+
</div>
107153
</div>
108154
</div>
109155
</div>
@@ -381,104 +427,11 @@ watch(timeRange, async () => {
381427
// Initial load
382428
onMounted(async () => {
383429
isLoading.value = true
430+
// Set User as the default selected model
431+
selectedModel.value = models.find(model => model.id === 'user') || null
384432
await new Promise(resolve => setTimeout(resolve, 500))
385433
isLoading.value = false
386-
})
387-
388-
// Get router instance
389-
const router = useRouter()
390-
391-
// Model node interface
392-
interface ModelNode extends d3.SimulationNodeDatum {
393-
id: string
394-
name: string
395-
properties: string[]
396-
relationships: string[]
397-
emoji: string
398-
color: string
399-
x?: number
400-
y?: number
401-
fx?: number | null
402-
fy?: number | null
403-
}
404-
405-
// Relationship link interface
406-
interface RelationshipLink {
407-
source: string | ModelNode
408-
target: string | ModelNode
409-
type: 'hasMany' | 'belongsTo' | 'hasOne' | 'belongsToMany'
410-
}
411-
412-
// User model and its relationships
413-
const models: ModelNode[] = [
414-
{
415-
id: 'user',
416-
name: 'User',
417-
properties: ['id', 'name', 'email', 'password'],
418-
relationships: ['teams', 'accessTokens', 'activities', 'posts'],
419-
emoji: '👤',
420-
color: '#2563EB'
421-
},
422-
{
423-
id: 'team',
424-
name: 'Team',
425-
properties: ['id', 'name', 'owner_id'],
426-
relationships: ['users'],
427-
emoji: '👥',
428-
color: '#60A5FA'
429-
},
430-
{
431-
id: 'accessToken',
432-
name: 'AccessToken',
433-
properties: ['id', 'token', 'user_id'],
434-
relationships: ['user'],
435-
emoji: '🔑',
436-
color: '#3B82F6'
437-
},
438-
{
439-
id: 'activity',
440-
name: 'Activity',
441-
properties: ['id', 'type', 'user_id'],
442-
relationships: ['user'],
443-
emoji: '📊',
444-
color: '#93C5FD'
445-
},
446-
{
447-
id: 'post',
448-
name: 'Post',
449-
properties: ['id', 'title', 'content'],
450-
relationships: ['user'],
451-
emoji: '📝',
452-
color: '#BFDBFE'
453-
}
454-
]
455-
456-
// Define relationships
457-
const relationships: RelationshipLink[] = [
458-
{ source: 'user', target: 'team', type: 'belongsToMany' },
459-
{ source: 'team', target: 'user', type: 'belongsToMany' },
460-
{ source: 'user', target: 'accessToken', type: 'hasMany' },
461-
{ source: 'user', target: 'activity', type: 'hasMany' },
462-
{ source: 'post', target: 'user', type: 'belongsTo' }
463-
]
464-
465-
// Visualization state
466-
const diagramContainer = ref<HTMLElement | null>(null)
467-
let simulation: d3.Simulation<ModelNode, undefined>
468-
469-
// Function to get route path for a model
470-
const getModelRoute = (modelId: string) => {
471-
const routes: Record<string, string> = {
472-
user: '/models/users',
473-
team: '/models/teams',
474-
accessToken: '/models/access-tokens',
475-
activity: '/models/activities',
476-
post: '/models/posts'
477-
}
478-
return routes[modelId] || '/models'
479-
}
480434
481-
onMounted(() => {
482435
if (!diagramContainer.value) return
483436
484437
const width = 800
@@ -534,8 +487,12 @@ onMounted(() => {
534487
.on('end', dragended))
535488
.style('cursor', 'pointer') // Add pointer cursor
536489
.on('click', (event, d) => {
537-
// Navigate to the model's page
538-
router.push(getModelRoute(d.id))
490+
// Set the selected model
491+
selectedModel.value = d
492+
// Navigate to the model's page on double click
493+
if (event.detail === 2) {
494+
router.push(getModelRoute(d.id))
495+
}
539496
})
540497
541498
// Add hover effect to nodes
@@ -603,6 +560,102 @@ onMounted(() => {
603560
event.subject.fy = null
604561
}
605562
})
563+
564+
// Get router instance
565+
const router = useRouter()
566+
567+
// Model node interface
568+
interface ModelNode extends d3.SimulationNodeDatum {
569+
id: string
570+
name: string
571+
properties: string[]
572+
relationships: string[]
573+
emoji: string
574+
color: string
575+
x?: number
576+
y?: number
577+
fx?: number | null
578+
fy?: number | null
579+
}
580+
581+
// Relationship link interface
582+
interface RelationshipLink {
583+
source: string | ModelNode
584+
target: string | ModelNode
585+
type: 'hasMany' | 'belongsTo' | 'hasOne' | 'belongsToMany'
586+
}
587+
588+
// Add selectedModel ref before the models definition
589+
const selectedModel = ref<ModelNode | null>(null)
590+
591+
// User model and its relationships
592+
const models: ModelNode[] = [
593+
{
594+
id: 'user',
595+
name: 'User',
596+
properties: ['id', 'name', 'email', 'password'],
597+
relationships: ['teams', 'accessTokens', 'activities', 'posts'],
598+
emoji: '👤',
599+
color: '#2563EB'
600+
},
601+
{
602+
id: 'team',
603+
name: 'Team',
604+
properties: ['id', 'name', 'owner_id'],
605+
relationships: ['users'],
606+
emoji: '👥',
607+
color: '#60A5FA'
608+
},
609+
{
610+
id: 'accessToken',
611+
name: 'AccessToken',
612+
properties: ['id', 'token', 'user_id'],
613+
relationships: ['user'],
614+
emoji: '🔑',
615+
color: '#3B82F6'
616+
},
617+
{
618+
id: 'activity',
619+
name: 'Activity',
620+
properties: ['id', 'type', 'user_id'],
621+
relationships: ['user'],
622+
emoji: '📊',
623+
color: '#93C5FD'
624+
},
625+
{
626+
id: 'post',
627+
name: 'Post',
628+
properties: ['id', 'title', 'content'],
629+
relationships: ['user'],
630+
emoji: '📝',
631+
color: '#BFDBFE'
632+
}
633+
]
634+
635+
// Define relationships
636+
const relationships: RelationshipLink[] = [
637+
{ source: 'user', target: 'team', type: 'belongsToMany' },
638+
{ source: 'team', target: 'user', type: 'belongsToMany' },
639+
{ source: 'user', target: 'accessToken', type: 'hasMany' },
640+
{ source: 'user', target: 'activity', type: 'hasMany' },
641+
{ source: 'post', target: 'user', type: 'belongsTo' }
642+
]
643+
644+
// Visualization state
645+
const diagramContainer = ref<HTMLElement | null>(null)
646+
let simulation: d3.Simulation<ModelNode, undefined>
647+
648+
// Function to get route path for a model
649+
const getModelRoute = (modelId: string) => {
650+
const routes: Record<string, string> = {
651+
user: '/models/users',
652+
team: '/models/teams',
653+
accessToken: '/models/access-tokens',
654+
activity: '/models/activities',
655+
post: '/models/posts'
656+
}
657+
return routes[modelId] || '/models'
658+
}
606659
</script>
607660

608661
<style scoped>

0 commit comments

Comments
 (0)