feat(ui): Add DevTools button for mobile debugging
Add Eruda DevTools integration accessible from hamburger menu on mobile devices. - Add DevTools menu item with mobileOnly flag - Load Eruda dynamically from CDN when clicked - Filter menu items based on device type 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,8 @@ export const menuSections = [
|
||||
{ to: '/reports/telegram', icon: 'pi pi-telegram', label: 'Telegram Bot' },
|
||||
{ to: '/reports/cache-stats', icon: 'pi pi-chart-bar', label: 'Statistici Cache' },
|
||||
{ to: '/data-entry/ocr-metrics', icon: 'pi pi-eye', label: 'Statistici OCR' },
|
||||
{ to: '/reports/server-logs', icon: 'pi pi-server', label: 'Server Logs' }
|
||||
{ to: '/reports/server-logs', icon: 'pi pi-server', label: 'Server Logs' },
|
||||
{ action: 'devtools', icon: 'pi pi-cog', label: 'DevTools', mobileOnly: true }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -18,11 +18,13 @@
|
||||
<h3 class="menu-title">{{ section.title }}</h3>
|
||||
<ul class="menu-list">
|
||||
<li
|
||||
v-for="item in section.items"
|
||||
:key="item.to"
|
||||
v-for="item in getFilteredItems(section.items)"
|
||||
:key="item.to || item.action"
|
||||
class="menu-item"
|
||||
>
|
||||
<!-- Router link for navigation -->
|
||||
<router-link
|
||||
v-if="item.to"
|
||||
:to="item.to"
|
||||
class="menu-link"
|
||||
:class="{ active: isRouteActive(item.to) }"
|
||||
@@ -32,6 +34,16 @@
|
||||
<span>{{ item.label }}</span>
|
||||
<span v-if="item.badge" class="menu-badge">{{ item.badge }}</span>
|
||||
</router-link>
|
||||
<!-- Action link for DevTools etc -->
|
||||
<a
|
||||
v-else-if="item.action"
|
||||
href="#"
|
||||
class="menu-link"
|
||||
@click.prevent="handleAction(item.action)"
|
||||
>
|
||||
<i :class="['menu-icon', item.icon]"></i>
|
||||
<span>{{ item.label }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -58,6 +70,7 @@
|
||||
|
||||
<script>
|
||||
import { useRoute } from "vue-router";
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
export default {
|
||||
name: "SlideMenu",
|
||||
@@ -68,7 +81,7 @@ export default {
|
||||
default: false,
|
||||
},
|
||||
// Menu items configuration
|
||||
// Format: [{ title: 'Section', items: [{ to: '/path', icon: 'pi pi-icon', label: 'Label', badge: null }] }]
|
||||
// Format: [{ title: 'Section', items: [{ to: '/path', icon: 'pi pi-icon', label: 'Label', badge: null, action: null, mobileOnly: false }] }]
|
||||
menuItems: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
@@ -83,6 +96,19 @@ export default {
|
||||
setup(props, { emit }) {
|
||||
const route = useRoute();
|
||||
|
||||
// Mobile detection
|
||||
const isMobile = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
isMobile.value = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
||||
});
|
||||
|
||||
// Filter items based on mobileOnly flag
|
||||
const getFilteredItems = (items) => {
|
||||
if (!items) return [];
|
||||
return items.filter(item => !item.mobileOnly || isMobile.value);
|
||||
};
|
||||
|
||||
const isRouteActive = (path) => {
|
||||
return route.path === path;
|
||||
};
|
||||
@@ -92,9 +118,30 @@ export default {
|
||||
emit("close");
|
||||
};
|
||||
|
||||
const handleAction = (action) => {
|
||||
if (action === 'devtools') {
|
||||
loadEruda();
|
||||
}
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const loadEruda = () => {
|
||||
if (window.eruda) {
|
||||
window.eruda.show();
|
||||
return;
|
||||
}
|
||||
const script = document.createElement('script');
|
||||
script.src = '//cdn.jsdelivr.net/npm/eruda';
|
||||
document.body.appendChild(script);
|
||||
script.onload = () => window.eruda.init();
|
||||
};
|
||||
|
||||
return {
|
||||
isMobile,
|
||||
getFilteredItems,
|
||||
isRouteActive,
|
||||
handleLogout,
|
||||
handleAction,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user