Defining Hotkeys#
This section explains the keyboard shortcut system for the BaSyx AAS Web UI. The system supports global shortcuts (available on all pages) and route-specific shortcuts (only available on certain pages/modules).
Architecture#
Files Overview#
Vuetify
useHotkeycomposable - Central keyboard event handler with scope managementuseShortcutDefinitions.ts- Global shortcut definitions available across all pagesuseRouteShortcuts.ts- Route-specific shortcut definitions that extend global shortcutsuseGlobalShortcuts.ts- Registers all shortcuts (global + route-specific) using Vuetify’suseHotkey
How It Works#
Global keyboard events are listened to via Vuetify’s
useHotkeycomposableWhen a key combination is pressed, it is dispatched to registered handlers based on scope
Route-specific shortcuts are checked first, then global shortcuts
Shortcuts are displayed in the Command Palette (
CommandPalette.vue)
Shortcut Definition Structure#
interface ShortcutDefinition {
id: string; // Unique identifier
title: string; // Display title
description: string; // Description shown in command palette
prependIcon: string; // Vuetify icon (e.g., 'mdi-home')
category: string; // Category for grouping (e.g., 'Global Shortcuts', 'AAS Viewer Shortcuts')
keys: string; // Key combination (e.g., 'cmd+shift+h' - 'cmd' becomes 'Ctrl' on Windows/Linux automatically)
handler: () => void; // Function to execute when shortcut is triggered
}
Adding Global Shortcuts#
Global shortcuts are available on all pages. Define them in useShortcutDefinitions.ts:
// Example: Add a new global shortcut
{
id: 'settings',
title: 'Open Settings',
description: 'Navigate to settings page',
prependIcon: 'mdi-cog',
category: 'Global Shortcuts',
keys: 'cmd+,', // 'cmd' automatically becomes 'Ctrl' on Windows/Linux
handler: () => {
router.push({ name: 'Settings' });
}
}
Warning
All global shortcuts must use the category 'Global Shortcuts' to ensure they appear together in the Command Palette.
Adding Route-Specific Shortcuts#
All pages (both core pages and modules) can define their own shortcuts using the same pattern. Add a second <script> block (without setup) to your page file that exports a shortcuts function.
How to Add Shortcuts to Any Page#
<script setup lang="ts">
// Your regular component setup code
import { ref } from 'vue';
const myData = ref('');
// ... component logic
</script>
<script lang="ts">
import type { PageShortcutDefinitions } from '@/composables/Shortcuts/useRouteShortcuts';
// Page shortcuts - automatically loaded when page is active
export const shortcuts: PageShortcutDefinitions = ({ route, navigationStore }) => [
{
id: 'my-page-action',
title: 'My Action',
description: 'Perform a page-specific action',
prependIcon: 'mdi-cog',
category: 'My Page Shortcuts', // Will appear as a subheader
keys: 'cmd+m', // 'cmd' automatically becomes 'Ctrl' on Windows/Linux
handler: (event: KeyboardEvent) => {
event.preventDefault();
event.stopPropagation();
// Your action logic here
console.log('Page shortcut triggered!');
}
}
];
</script>
Note
The category field should follow the format '<Page Name> Shortcuts' where the page name is human-readable (e.g., 'AAS Viewer Shortcuts', 'SM Editor Shortcuts'). This ensures shortcuts are grouped under their respective page sections in the Command Palette with proper subheaders.
Available Parameters#
The shortcuts function receives an object with:
route- Current Vue Router route objectnavigationStore- Access to navigation store methodsAny other stores can be imported and used within the function
Example: AasImporter Module#
<script lang="ts">
import type { PageShortcutDefinitions } from '@/composables/Shortcuts/useRouteShortcuts';
export const shortcuts: PageShortcutDefinitions = () => [
{
id: 'aas-importer-clear',
title: 'Clear Input',
description: 'Clear the asset ID input field',
prependIcon: 'mdi-eraser',
category: 'AAS Importer Shortcuts',
keys: 'cmd+shift+backspace', // 'cmd' automatically becomes 'Ctrl' on Windows/Linux
handler: (event: KeyboardEvent) => {
event.preventDefault();
event.stopPropagation();
// Clear the input
const input = document.querySelector('input') as HTMLInputElement;
if (input) input.value = '';
}
}
];
</script>
Important Notes:
Page shortcuts are only active when that page/route is active
Shortcuts are cached for performance after first load
Works identically for core pages (
@/pages/*.vue) and modules (@/pages/modules/*.vue)No core application code changes needed
Category should be
'<Page Name> Shortcuts'for consistency
Key Combination Format#
Key combinations are strings with modifiers and keys separated by +. The system uses Vuetify’s useHotkey composable which automatically handles platform differences.
Modifiers:
cmd,ctrl,alt,shift,metaKeys: Any letter, number, or special key name
Platform-aware: Use
cmdfor shortcuts - it automatically becomesCtrlon Windows/Linux
Examples#
// Single key with modifier
'cmd+k' // Command + K (Mac) or Ctrl + K (Windows/Linux)
// Multiple modifiers
'cmd+shift+h' // Command + Shift + H (Mac) or Ctrl + Shift + H (Windows/Linux)
// Letter keys
'cmd+s' // Command + S (save)
// Special keys
'cmd+enter' // Command + Enter
'escape' // Escape key alone
// Explicit Ctrl (same on all platforms)
'ctrl+a' // Ctrl + A on all platforms
Platform Differences#
The cmd modifier is automatically translated:
On macOS:
cmd→ Command (⌘)On Windows/Linux:
cmd→ Control (Ctrl)
Simply use 'cmd+key' format - no need for separate mac/windows definitions!
keys: 'cmd+s' // Automatically works as Cmd+S on Mac, Ctrl+S on Windows/Linux
Complete Example: Adding Shortcuts to a New Page#
Let’s say you’re creating a new “Dashboard” page and want to add shortcuts for it.
1. Create the Page Component#
Create your page file @/pages/Dashboard.vue:
<template>
<v-container>
<h1>Dashboard</h1>
<!-- Your component code -->
</v-container>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const viewMode = ref('grid');
// ... component logic
</script>
<script lang="ts">
import type { PageShortcutDefinitions } from '@/composables/Shortcuts/useRouteShortcuts';
export const shortcuts: PageShortcutDefinitions = () => [
{
id: 'refresh-dashboard',
title: 'Refresh Dashboard',
description: 'Reload dashboard data',
prependIcon: 'mdi-refresh',
category: 'Dashboard Shortcuts',
keys: 'cmd+r', // Automatically Cmd+R on Mac, Ctrl+R on Windows/Linux
handler: (event: KeyboardEvent) => {
event.preventDefault();
event.stopPropagation();
window.location.reload();
}
},
{
id: 'toggle-view',
title: 'Toggle View',
description: 'Switch between grid and list view',
prependIcon: 'mdi-view-dashboard',
category: 'Dashboard Shortcuts',
keys: 'cmd+shift+v', // Automatically adapts to platform
handler: (event: KeyboardEvent) => {
event.preventDefault();
event.stopPropagation();
// Toggle view logic
console.log('Toggling view...');
}
}
];
</script>
2. Define the route in router.ts#
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('@/pages/Dashboard.vue')
}
3. Test your shortcuts#
Navigate to your Dashboard page
Press
Cmd+K(orCtrl+Kon Windows) to open the Command PaletteYou should see your Dashboard-specific shortcuts along with global shortcuts
Best Practices#
1. Avoid Key Conflicts#
Check existing shortcuts before adding new ones
Don’t override browser shortcuts (e.g.,
Cmd+Tfor new tab)Be consistent with platform conventions
2. Use Meaningful Icons#
Choose Vuetify Material Design Icons that match the action:
mdi-refresh- Refresh/reload actionsmdi-content-save- Save actionsmdi-delete- Delete actionsmdi-pencil- Edit actionsBrowse all icons: Material Design Icons
3. Clear Descriptions#
Write concise, action-oriented descriptions:
✅ “Refresh AAS data from server”
❌ “This will refresh the data”
4. Handle Context Properly#
Ensure your shortcut handler has access to necessary context:
// ✅ Good: Access store data within handler
handler: () => {
const selectedAAS = aasStore.getSelectedAAS;
if (selectedAAS) {
copyToClipboard(selectedAAS.id);
}
}
// ❌ Bad: Trying to access undefined context
handler: () => {
copyToClipboard(selectedAAS.id); // selectedAAS not defined
}
5. Prevent Default Behavior#
The shortcut system automatically prevents default browser behavior and stops propagation, but be aware of potential conflicts.
Debugging#
If your shortcuts aren’t working:
Check the console logs - The system logs when shortcuts are registered
Verify route name - Ensure the route name matches exactly (case-sensitive)
Check the Command Palette - Open it to see if your shortcut appears
Test key combination - Make sure the keys aren’t captured by the browser first
Future Enhancements#
Potential future improvements for the shortcut system:
User-customizable key bindings
Shortcut conflict detection
Shortcut cheat sheet overlay
Context-aware shortcut suggestions
Export/import shortcut configurations