Skip to content

Commit

Permalink
Merge pull request #375 from opcodesio/next-log-shortcut
Browse files Browse the repository at this point in the history
Next log shortcut
  • Loading branch information
arukompas authored May 17, 2024
2 parents d3e254a + da746f6 commit fddafd5
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 24 deletions.
2 changes: 1 addition & 1 deletion public/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"/app.js": "/app.js?id=fc139aeb14d759b4a2906fc46d6c8150",
"/app.js": "/app.js?id=10fd202d284550adc56be1499fbd44c1",
"/app.css": "/app.css?id=12c5e78a91987c11d8a0cc04436541e9",
"/img/log-viewer-128.png": "/img/log-viewer-128.png?id=d576c6d2e16074d3f064e60fe4f35166",
"/img/log-viewer-32.png": "/img/log-viewer-32.png?id=f8ec67d10f996aa8baf00df3b61eea6d",
Expand Down
16 changes: 16 additions & 0 deletions resources/js/components/KeyboardShortcutsOverlay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@
<span class="shortcut">{{ KeyShortcuts.Logs }}</span>
<span class="description">Jump to logs</span>
</div>
<div class="keyboard-shortcut">
<span class="shortcut">{{ KeyShortcuts.NextLog }}</span>
<span class="description">Open next log</span>
</div>
<div class="keyboard-shortcut">
<span class="shortcut">{{ KeyShortcuts.PreviousLog }}</span>
<span class="description">Open previous log</span>
</div>
<div class="keyboard-shortcut">
<span class="shortcut">{{ KeyShortcuts.Next }}</span>
<span class="description">Next (file or log)</span>
</div>
<div class="keyboard-shortcut">
<span class="shortcut">{{ KeyShortcuts.Previous }}</span>
<span class="description">Previous (file or log)</span>
</div>
<div class="keyboard-shortcut">
<span class="shortcut">{{ KeyShortcuts.Severity }}</span>
<span class="description">Severity selection</span>
Expand Down
12 changes: 11 additions & 1 deletion resources/js/components/Pagination.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/vue/24/outline';
import { usePaginationStore } from '../stores/pagination.js';
import { useRoute, useRouter } from 'vue-router';
import { computed } from 'vue';
import {computed, onBeforeUnmount, onMounted} from 'vue';
import { replaceQuery } from '../helpers.js';
const props = defineProps({
Expand Down Expand Up @@ -69,4 +69,14 @@ const gotoPage = (page) => {
const nextPage = () => gotoPage(paginationStore.page + 1);
const previousPage = () => gotoPage(paginationStore.page - 1);
onMounted(() => {
document.addEventListener('goToNextPage', nextPage);
document.addEventListener('goToPreviousPage', previousPage);
})
onBeforeUnmount(() => {
document.removeEventListener('goToNextPage', nextPage);
document.removeEventListener('goToPreviousPage', previousPage);
})
</script>
21 changes: 5 additions & 16 deletions resources/js/keyboardNavigation/files.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
import {
getPreviousElementWithClass,
getNextElementWithClass,
logToggleButtonClass,
fileItemClass,
} from './shared.js';
import {focusNextFile, focusPreviousFile, logToggleButtonClass} from './shared.js';

export const handleKeyboardFileNavigation = (event) => {
if (event.key === 'ArrowUp') {
const previousElement = getPreviousElementWithClass(document.activeElement, fileItemClass);
if (previousElement) {
event.preventDefault();
previousElement.focus();
}
event.preventDefault();
focusPreviousFile();
} else if (event.key === 'ArrowDown') {
const nextElement = getNextElementWithClass(document.activeElement, fileItemClass);
if (nextElement) {
event.preventDefault();
nextElement.focus();
}
event.preventDefault();
focusNextFile();
} else if (event.key === 'ArrowRight') {
event.preventDefault();
document.activeElement.nextElementSibling.focus();
Expand Down
48 changes: 44 additions & 4 deletions resources/js/keyboardNavigation/global.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import {
KeyShortcuts,
ensureIsExpanded,
fileItemClass,
focusActiveOrFirstFile,
focusFirstLogEntry,
focusActiveOrFirstFile
focusLastLogEntry, focusNextFile, focusPreviousFile,
KeyShortcuts,
logToggleButtonClass,
openNextLogEntry,
openPreviousLogEntry
} from './shared.js';
import { useLogViewerStore } from '../stores/logViewer.js';
import {useLogViewerStore} from '../stores/logViewer.js';

const globalKeyboardEventHandler = (event) => {
// if event.target is an <input> element, we don't want to handle the keyboard shortcuts
Expand Down Expand Up @@ -40,8 +46,42 @@ const globalKeyboardEventHandler = (event) => {
event.preventDefault();
const refreshButton = document.getElementById('reload-logs-button');
refreshButton?.click();
} else if (event.key === KeyShortcuts.NextLog) {
event.preventDefault();
if (!document.activeElement.classList.contains(logToggleButtonClass)) {
focusFirstLogEntry();
ensureIsExpanded(document.activeElement);
return;
}
openNextLogEntry();
} else if (event.key === KeyShortcuts.PreviousLog) {
event.preventDefault();
if (!document.activeElement.classList.contains(logToggleButtonClass)) {
focusLastLogEntry();
ensureIsExpanded(document.activeElement);
return;
}
openPreviousLogEntry();
} else if (event.key === KeyShortcuts.Next) {
event.preventDefault();
const isLogEntry = document.activeElement.classList.contains(logToggleButtonClass);
const isFile = document.activeElement.classList.contains(fileItemClass);
if (isLogEntry) {
openNextLogEntry();
} else if (isFile) {
focusNextFile();
}
} else if (event.key === KeyShortcuts.Previous) {
event.preventDefault();
const isLogEntry = document.activeElement.classList.contains(logToggleButtonClass);
const isFile = document.activeElement.classList.contains(fileItemClass);
if (isLogEntry) {
openPreviousLogEntry();
} else if (isFile) {
focusPreviousFile();
}
}
};
}

export const registerGlobalShortcuts = () => {
document.addEventListener('keydown', globalKeyboardEventHandler);
Expand Down
2 changes: 1 addition & 1 deletion resources/js/keyboardNavigation/logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const handleLogToggleKeyboardNavigation = (event) => {
nextElement.focus();
}
}
};
}

export const handleLogLinkKeyboardNavigation = (event) => {
if (event.key === 'ArrowLeft') {
Expand Down
79 changes: 79 additions & 0 deletions resources/js/keyboardNavigation/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export const logLinkClass = 'log-link.large-screen';
export const KeyShortcuts = {
Files: 'f',
Logs: 'l',
Next: 'j',
Previous: 'k',
NextLog: 'n',
PreviousLog: 'p',
Hosts: 'h',
Severity: 's',
Settings: 'g',
Expand All @@ -21,6 +25,67 @@ export const focusFirstLogEntry = () => {
}
}

export const focusLastLogEntry = () => {
const logToggleButtons = Array.from(document.querySelectorAll(`.${logToggleButtonClass}`));
if (logToggleButtons.length > 0) {
logToggleButtons[logToggleButtons.length - 1].focus();
}
}

export const ensureIsExpanded = (element) => {
const isExpanded = element.getAttribute('aria-expanded') === 'true';
if (!isExpanded) {
element.click();
}
}

export const ensureIsCollapsed = (element) => {
const isExpanded = element.getAttribute('aria-expanded') === 'true';
if (isExpanded) {
element.click();
}
}

export const openNextLogEntry = () => {
const el = document.activeElement;
const nextElement = getNextElementWithClass(el, logToggleButtonClass);
if (!nextElement) {
const onNextPageLoad = () => {
setTimeout(() => {
focusFirstLogEntry();
ensureIsExpanded(document.activeElement);
}, 50)
document.removeEventListener('logsPageLoaded', onNextPageLoad);
};
document.addEventListener('logsPageLoaded', onNextPageLoad);
document.dispatchEvent(new Event('goToNextPage'));
return;
}
ensureIsCollapsed(el);
nextElement.focus();
ensureIsExpanded(nextElement);
}

export const openPreviousLogEntry = () => {
const el = document.activeElement;
const previousElement = getPreviousElementWithClass(el, logToggleButtonClass);
if (!previousElement) {
const onPreviousPageLoad = () => {
setTimeout(() => {
focusLastLogEntry();
ensureIsExpanded(document.activeElement);
}, 50)
document.removeEventListener('logsPageLoaded', onPreviousPageLoad);
};
document.addEventListener('logsPageLoaded', onPreviousPageLoad);
document.dispatchEvent(new Event('goToPreviousPage'));
return;
}
ensureIsCollapsed(el);
previousElement.focus();
ensureIsExpanded(previousElement);
}

export const focusActiveOrFirstFile = () => {
const activeFile = document.querySelector('.file-item-container.active .file-item-info');
if (activeFile) {
Expand All @@ -41,6 +106,20 @@ export const focusActiveOrFirstFileSettings = () => {
}
};

export const focusNextFile = () => {
const nextElement = getNextElementWithClass(document.activeElement, fileItemClass);
if (nextElement) {
nextElement.focus();
}
}

export const focusPreviousFile = () => {
const previousElement = getPreviousElementWithClass(document.activeElement, fileItemClass);
if (previousElement) {
previousElement.focus();
}
}

export const getPreviousElementWithClass = (element, className) => {
const elements = Array.from(document.querySelectorAll(`.${className}`));
const currentIndex = elements.findIndex(el => el === element);
Expand Down
3 changes: 3 additions & 0 deletions resources/js/stores/logViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,14 @@ export const useLogViewerStore = defineStore({

if (!silently) {
nextTick(() => {
document.dispatchEvent(new Event('logsPageLoaded'));
this.reset();
if (data.expandAutomatically) {
this.stacksOpen.push(0);
}
});
} else {
document.dispatchEvent(new Event('logsPageLoadedSilently'));
}

if (this.hasMoreResults) {
Expand Down

0 comments on commit fddafd5

Please sign in to comment.