books/frontend/src/lib/keyboardShortcuts.ts

328 lines
7 KiB
TypeScript
Raw Normal View History

/**
* Keyboard Shortcuts Registry and Utilities
* Central configuration for all keyboard shortcuts in the application
*/
// Platform detection
export const isMac = typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
/**
* Modifier key display based on platform
*/
export const modifierKey = isMac ? '⌘' : 'Ctrl';
export const altKey = isMac ? '⌥' : 'Alt';
export const shiftKey = '⇧';
/**
* Shortcut definition
*/
export interface ShortcutDefinition {
id: string;
keys: string; // react-hotkeys-hook format: 'mod+k', 'mod+shift+n'
label: string; // Danish display name
description?: string;
category: ShortcutCategory;
scope?: ShortcutScope;
}
export type ShortcutCategory =
| 'global'
| 'navigation'
| 'bogforing'
| 'faktura'
| 'bank'
| 'kunder'
| 'produkter';
export type ShortcutScope =
| 'global' // Works everywhere
| 'page' // Only on specific page
| 'modal' // Only in modals
| 'table'; // Only when table is focused
/**
* All keyboard shortcuts in the application
*/
export const shortcuts: Record<string, ShortcutDefinition> = {
// Global shortcuts
openCommandPalette: {
id: 'openCommandPalette',
keys: 'mod+k',
label: 'Kommandopalette',
description: 'Hurtig navigation og actions',
category: 'global',
scope: 'global',
},
showShortcuts: {
id: 'showShortcuts',
keys: 'mod+/',
label: 'Vis genveje',
description: 'Vis alle tastaturgenveje',
category: 'global',
scope: 'global',
},
closeModal: {
id: 'closeModal',
keys: 'escape',
label: 'Luk',
description: 'Luk aktiv modal eller palette',
category: 'global',
scope: 'global',
},
// Navigation shortcuts (G then X pattern)
goToDashboard: {
id: 'goToDashboard',
keys: 'g d',
label: 'Dashboard',
category: 'navigation',
scope: 'global',
},
goToKassekladde: {
id: 'goToKassekladde',
keys: 'g k',
label: 'Kassekladde',
category: 'navigation',
scope: 'global',
},
goToKontooversigt: {
id: 'goToKontooversigt',
keys: 'g o',
label: 'Kontooversigt',
category: 'navigation',
scope: 'global',
},
goToFakturaer: {
id: 'goToFakturaer',
keys: 'g f',
label: 'Fakturaer',
category: 'navigation',
scope: 'global',
},
goToKreditnotaer: {
id: 'goToKreditnotaer',
keys: 'g c',
label: 'Kreditnotaer',
category: 'navigation',
scope: 'global',
},
goToBankafstemning: {
id: 'goToBankafstemning',
keys: 'g b',
label: 'Bankafstemning',
category: 'navigation',
scope: 'global',
},
goToKunder: {
id: 'goToKunder',
keys: 'g u',
label: 'Kunder',
category: 'navigation',
scope: 'global',
},
goToProdukter: {
id: 'goToProdukter',
keys: 'g p',
label: 'Produkter',
category: 'navigation',
scope: 'global',
},
goToMomsindberetning: {
id: 'goToMomsindberetning',
keys: 'g m',
label: 'Momsindberetning',
category: 'navigation',
scope: 'global',
},
goToIndstillinger: {
id: 'goToIndstillinger',
keys: 'g i',
label: 'Indstillinger',
category: 'navigation',
scope: 'global',
},
// Bogforing shortcuts (Kassekladde)
newDraft: {
id: 'newDraft',
keys: 'mod+n',
label: 'Ny kassekladde',
category: 'bogforing',
scope: 'page',
},
postDraft: {
id: 'postDraft',
keys: 'mod+enter',
Audit v3: VAT alignment, security, encoding, UX, compliance VAT System Alignment (LEGAL - Critical): - Align frontend VAT codes with backend (S25→U25, K25→I25, etc.) - Add missing codes: UEU, IVV, IVY, REP - Fix output VAT account 5710→5611 to match StandardDanishAccounts - Invoice posting now checks fiscal year status before allowing send - Disallow custom invoice number override (always use auto-numbering) Security: - Fix open redirect in AuthController (validate returnUrl is local) - Store seller CVR/name/address on invoice events (Momsloven §52) Backend Compliance: - Add description validation at posting (Bogføringsloven §7) - SAF-T: add DefaultCurrencyCode, TaxAccountingBasis to header - SAF-T: add TaxTable to MasterFiles with all VAT codes - SAF-T: always write balance elements even when zero - Add financial income account 9100 Renteindtægter Danish Encoding (~25 fixes): - Kassekladde: Bogført, Bogføring, Vælg, være, på, Tilføj, Differens - AttachmentUpload: træk, Understøtter, påkrævet, Bogføringsloven - keyboardShortcuts: Bogfør, Bogføring display name - ShortcutsHelpModal: åbne - DataTable: Genindlæs - documentProcessing: være - CloseFiscalYearWizard: årsafslutning Bugs Fixed: - Non-null assertion crashes in Kunder.tsx and Produkter.tsx (company!.id) - StatusBadge typo "Succces"→"Succes" - HTML entity &oslash; in Kassekladde→proper UTF-8 - AmountText showSign prop was dead code (true || showSign) UX Improvements: - Add PageHeader to Bankafstemning and Dashboard loading/empty states - Responsive columns in Bankafstemning (xs/sm/lg breakpoints) - Disable misleading buttons: Settings preferences, Kontooversigt edit, Loenforstaelse export — with tooltips explaining status - Add DemoDataDisclaimer to UserSettings - Fix breadcrumb self-references on 3 pages - Replace Dashboard fake progress bar with honest message - Standardize date format DD-MM-YYYY in Bankafstemning and Ordrer - Replace Input type="number" with InputNumber in Ordrer Quality: - Remove 8 redundant console.error statements - Fix Kreditnotaer breadcrumb "Salg"→"Fakturering" for consistency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:15:45 +01:00
label: 'Bogfør kladde',
category: 'bogforing',
scope: 'page',
},
addLine: {
id: 'addLine',
keys: 'mod+shift+l',
label: 'Tilføj linje',
category: 'bogforing',
scope: 'page',
},
saveDraft: {
id: 'saveDraft',
keys: 'mod+s',
label: 'Gem kladde',
category: 'bogforing',
scope: 'page',
},
discardDraft: {
id: 'discardDraft',
keys: 'mod+backspace',
label: 'Kasser kladde',
category: 'bogforing',
scope: 'page',
},
syncBank: {
id: 'syncBank',
keys: 'mod+r',
label: 'Synkroniser bank',
description: 'Hent nye transaktioner fra bank',
category: 'bank',
scope: 'page',
},
// Faktura shortcuts
newInvoice: {
id: 'newInvoice',
keys: 'mod+i',
label: 'Ny faktura',
category: 'faktura',
scope: 'page',
},
newCreditNote: {
id: 'newCreditNote',
keys: 'mod+shift+i',
label: 'Ny kreditnota',
category: 'faktura',
scope: 'page',
},
newCustomer: {
id: 'newCustomer',
keys: 'mod+shift+k',
label: 'Ny kunde',
category: 'kunder',
scope: 'page',
},
newProduct: {
id: 'newProduct',
keys: 'mod+shift+p',
label: 'Nyt produkt',
category: 'produkter',
scope: 'page',
},
// Bank shortcuts
matchTransaction: {
id: 'matchTransaction',
keys: 'mod+m',
label: 'Match transaktion',
category: 'bank',
scope: 'page',
},
};
/**
* Get shortcuts by category
*/
export function getShortcutsByCategory(category: ShortcutCategory): ShortcutDefinition[] {
return Object.values(shortcuts).filter(s => s.category === category);
}
/**
* Get all shortcuts grouped by category
*/
export function getShortcutsGrouped(): Record<ShortcutCategory, ShortcutDefinition[]> {
const grouped: Record<ShortcutCategory, ShortcutDefinition[]> = {
global: [],
navigation: [],
bogforing: [],
faktura: [],
bank: [],
kunder: [],
produkter: [],
};
Object.values(shortcuts).forEach(shortcut => {
grouped[shortcut.category].push(shortcut);
});
return grouped;
}
/**
* Format shortcut keys for display
* Converts 'mod+k' to '⌘K' on Mac or 'Ctrl+K' on Windows
*/
export function formatShortcut(keys: string): string {
return keys
.split(' ')
.map(part =>
part
.replace(/mod/g, modifierKey)
.replace(/shift/g, shiftKey)
.replace(/alt/g, altKey)
.replace(/\+/g, '')
.toUpperCase()
)
.join(' ');
}
/**
* Format shortcut for tooltip display
* Returns formatted string like "⌘K" or "Ctrl+K"
*/
export function formatShortcutForTooltip(shortcutId: string): string | null {
const shortcut = shortcuts[shortcutId];
if (!shortcut) return null;
return formatShortcut(shortcut.keys);
}
/**
* Category display names in Danish
*/
export const categoryNames: Record<ShortcutCategory, string> = {
global: 'Globale',
navigation: 'Navigation',
Audit v3: VAT alignment, security, encoding, UX, compliance VAT System Alignment (LEGAL - Critical): - Align frontend VAT codes with backend (S25→U25, K25→I25, etc.) - Add missing codes: UEU, IVV, IVY, REP - Fix output VAT account 5710→5611 to match StandardDanishAccounts - Invoice posting now checks fiscal year status before allowing send - Disallow custom invoice number override (always use auto-numbering) Security: - Fix open redirect in AuthController (validate returnUrl is local) - Store seller CVR/name/address on invoice events (Momsloven §52) Backend Compliance: - Add description validation at posting (Bogføringsloven §7) - SAF-T: add DefaultCurrencyCode, TaxAccountingBasis to header - SAF-T: add TaxTable to MasterFiles with all VAT codes - SAF-T: always write balance elements even when zero - Add financial income account 9100 Renteindtægter Danish Encoding (~25 fixes): - Kassekladde: Bogført, Bogføring, Vælg, være, på, Tilføj, Differens - AttachmentUpload: træk, Understøtter, påkrævet, Bogføringsloven - keyboardShortcuts: Bogfør, Bogføring display name - ShortcutsHelpModal: åbne - DataTable: Genindlæs - documentProcessing: være - CloseFiscalYearWizard: årsafslutning Bugs Fixed: - Non-null assertion crashes in Kunder.tsx and Produkter.tsx (company!.id) - StatusBadge typo "Succces"→"Succes" - HTML entity &oslash; in Kassekladde→proper UTF-8 - AmountText showSign prop was dead code (true || showSign) UX Improvements: - Add PageHeader to Bankafstemning and Dashboard loading/empty states - Responsive columns in Bankafstemning (xs/sm/lg breakpoints) - Disable misleading buttons: Settings preferences, Kontooversigt edit, Loenforstaelse export — with tooltips explaining status - Add DemoDataDisclaimer to UserSettings - Fix breadcrumb self-references on 3 pages - Replace Dashboard fake progress bar with honest message - Standardize date format DD-MM-YYYY in Bankafstemning and Ordrer - Replace Input type="number" with InputNumber in Ordrer Quality: - Remove 8 redundant console.error statements - Fix Kreditnotaer breadcrumb "Salg"→"Fakturering" for consistency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:15:45 +01:00
bogforing: 'Bogføring',
faktura: 'Fakturering',
bank: 'Bank',
kunder: 'Kunder',
produkter: 'Produkter',
};
/**
* Navigation routes mapping
*/
export const navigationRoutes: Record<string, string> = {
goToDashboard: '/',
goToKassekladde: '/kassekladde',
goToKontooversigt: '/kontooversigt',
goToFakturaer: '/fakturaer',
goToKreditnotaer: '/kreditnotaer',
goToBankafstemning: '/bankafstemning',
goToKunder: '/kunder',
goToProdukter: '/produkter',
goToMomsindberetning: '/momsindberetning',
goToIndstillinger: '/indstillinger',
};
/**
* Command palette items
*/
export interface CommandItem {
id: string;
label: string;
description?: string;
icon?: string;
shortcut?: string;
category: 'navigation' | 'action' | 'recent';
action: () => void;
}