Template
first commit
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<div class="menu-tree-item">
|
||||
<v-row
|
||||
no-gutters
|
||||
class="pa-2 border-b"
|
||||
:class="{
|
||||
'bg-grey-lighten-4': level > 0,
|
||||
'bg-red-lighten-5': !item.isActive
|
||||
}"
|
||||
align="center"
|
||||
>
|
||||
<!-- Menu Title with Icon -->
|
||||
<v-col cols="6" sm="4" class="d-flex align-center">
|
||||
<div :style="{ marginLeft: `${level * 20}px` }" class="d-flex align-center">
|
||||
<!-- Expand/Collapse Button -->
|
||||
<v-btn
|
||||
v-if="item.children && item.children.length > 0"
|
||||
icon
|
||||
size="x-small"
|
||||
variant="text"
|
||||
@click="toggleExpanded"
|
||||
class="me-1"
|
||||
>
|
||||
<v-icon>{{ isExpanded ? 'mdi-chevron-down' : 'mdi-chevron-right' }}</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<!-- Menu Icon -->
|
||||
<v-icon
|
||||
:icon="item.icon || 'mdi-circle-outline'"
|
||||
size="small"
|
||||
class="me-2"
|
||||
:color="item.isActive ? 'primary' : 'grey'"
|
||||
/>
|
||||
|
||||
<!-- Menu Title -->
|
||||
<span
|
||||
class="text-body-2 font-weight-medium"
|
||||
:class="{ 'text-grey': !item.isActive }"
|
||||
>
|
||||
{{ item.title }}
|
||||
</span>
|
||||
|
||||
<!-- Active Status Badge -->
|
||||
<v-chip
|
||||
v-if="!item.isActive"
|
||||
size="x-small"
|
||||
color="error"
|
||||
class="ml-2"
|
||||
>
|
||||
Inactive
|
||||
</v-chip>
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
<!-- URL Link (Hidden on mobile) -->
|
||||
<v-col cols="4" sm="5" class="d-none d-sm-block">
|
||||
<span class="text-body-2 text-grey-darken-1">
|
||||
{{ item.url || '-' }}
|
||||
</span>
|
||||
</v-col>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<v-col cols="6" sm="3" class="text-right">
|
||||
<v-btn-group variant="text" density="compact">
|
||||
<!-- Toggle Active/Inactive -->
|
||||
<v-btn
|
||||
:icon="item.isActive ? 'mdi-eye' : 'mdi-eye-off'"
|
||||
size="small"
|
||||
:color="item.isActive ? 'success' : 'warning'"
|
||||
@click="$emit('toggle', item.id)"
|
||||
>
|
||||
<v-icon />
|
||||
<v-tooltip activator="parent" location="top">
|
||||
{{ item.isActive ? 'Active' : 'Inactive' }}
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
|
||||
<!-- Edit Button -->
|
||||
<v-btn
|
||||
icon="mdi-pencil"
|
||||
size="small"
|
||||
color="primary"
|
||||
@click="$emit('edit', item)"
|
||||
>
|
||||
<v-icon />
|
||||
<v-tooltip activator="parent" location="top">Edit</v-tooltip>
|
||||
</v-btn>
|
||||
|
||||
<!-- Delete Button -->
|
||||
<v-btn
|
||||
icon="mdi-delete"
|
||||
size="small"
|
||||
color="error"
|
||||
@click="confirmDelete"
|
||||
>
|
||||
<v-icon />
|
||||
<v-tooltip activator="parent" location="top">Delete</v-tooltip>
|
||||
</v-btn>
|
||||
</v-btn-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- Child Items -->
|
||||
<template v-if="item.children && isExpanded">
|
||||
<MenuTreeItem
|
||||
v-for="child in item.children"
|
||||
:key="child.id"
|
||||
:item="child"
|
||||
:level="level + 1"
|
||||
@edit="$emit('edit', $event)"
|
||||
@delete="$emit('delete', $event)"
|
||||
@toggle="$emit('toggle', $event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- Delete Confirmation Dialog -->
|
||||
<v-dialog v-model="showDeleteDialog" max-width="400">
|
||||
<v-card>
|
||||
<v-card-title class="text-h6">Confirm Delete</v-card-title>
|
||||
<v-card-text>
|
||||
Are you sure you want to delete "{{ item.title }}"?
|
||||
<span v-if="item.children && item.children.length > 0" class="text-error">
|
||||
This will also delete all child items.
|
||||
</span>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="grey" variant="text" @click="showDeleteDialog = false">
|
||||
Cancel
|
||||
</v-btn>
|
||||
<v-btn color="error" variant="elevated" @click="handleDelete">
|
||||
Delete
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { MenuItem } from '../../types/menu'
|
||||
|
||||
interface Props {
|
||||
item: MenuItem
|
||||
level: number
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
edit: [item: MenuItem]
|
||||
delete: [itemId: string]
|
||||
toggle: [itemId: string]
|
||||
}>()
|
||||
|
||||
const isExpanded = ref(props.level === 0) // Top level items expanded by default
|
||||
const showDeleteDialog = ref(false)
|
||||
|
||||
const toggleExpanded = () => {
|
||||
isExpanded.value = !isExpanded.value
|
||||
}
|
||||
|
||||
const confirmDelete = () => {
|
||||
showDeleteDialog.value = true
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
showDeleteDialog.value = false
|
||||
// Emit delete event
|
||||
emit('delete', props.item.id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.menu-tree-item {
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.menu-tree-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.border-b {
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user