Skip to content

Commit

Permalink
Merge pull request #38 from opcodesio/feature/time-based-index
Browse files Browse the repository at this point in the history
Refactor / timestamp-based log index which allows for additional functionality later
  • Loading branch information
arukompas authored Sep 9, 2022
2 parents 28e47b6 + 5057eb0 commit 683befb
Show file tree
Hide file tree
Showing 23 changed files with 678 additions and 231 deletions.
6 changes: 3 additions & 3 deletions config/log-viewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@

'patterns' => [
'laravel' => [
'log_matching_regex' => '/\[\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(\.\d{6}([\+-]\d\d:\d\d)?)?\].*/',
'log_matching_regex' => '/^\[(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}\.?(\d{6}([\+-]\d\d:\d\d)?)?)\].*/',

/**
* This pattern, used for processing Laravel logs, returns these results:
Expand All @@ -102,8 +102,8 @@
* $matches[7] - the log text, the rest of the text.
*/
'log_parsing_regex' => '/^\[(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}\.?(\d{6}([\+-]\d\d:\d\d)?)?)\](.*?(\w+)\.|.*?)('
. implode('|', array_filter(Level::caseValues()))
. ')?: (.*?)( in [\/].*?:[0-9]+)?$/is',
.implode('|', array_filter(Level::caseValues()))
.')?: (.*?)( in [\/].*?:[0-9]+)?$/is',
],
],
];
2 changes: 1 addition & 1 deletion public/app.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/app.js

Large diffs are not rendered by default.

50 changes: 38 additions & 12 deletions resources/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ html.dark {
@apply block flex items-center w-full px-4 py-2 text-left text-sm outline-emerald-500 dark:outline-emerald-800;
& > svg {
@apply w-4 h-4 mr-3 text-gray-400;
&.spin {
// Spinner is slightly dimmer by default, especially because it's constantly spinning
// and it's also a little smaller in size
@apply text-gray-600;
}
}
}
button:hover, a:hover {
Expand All @@ -393,29 +398,37 @@ html.dark {
.file-list {
@apply relative h-full overflow-y-auto pt-6 pb-6 pr-4;

.file-item-container {
@apply relative mb-2 text-gray-800 dark:text-gray-200 rounded-md transition duration-100 border cursor-pointer border-transparent bg-white dark:bg-gray-800;

&.active {
@apply border-emerald-500 bg-emerald-50 dark:border-emerald-900 dark:bg-emerald-900 dark:bg-opacity-50;
}

&:hover {
@apply border-emerald-600 dark:border-emerald-800;
}
.file-item-container,
.folder-item-container {
@apply relative mt-2 text-gray-800 dark:text-gray-200 rounded-md bg-white dark:bg-gray-800;

.file-item {
@apply relative flex justify-between items-center pl-4 pr-10 py-2;
@apply relative flex justify-between items-center pl-4 pr-10 py-2 rounded-md border cursor-pointer border-transparent transition duration-100;

.file-icon {
@apply mr-2 text-gray-400 dark:text-gray-500;
&>svg {
@apply w-4 h-4;
}
}

.file-name {
@apply text-sm mr-3;
@apply text-sm mr-3 w-full;
}

.file-size {
@apply text-xs text-gray-500 dark:text-gray-300 dark:opacity-90 whitespace-nowrap;
}
}

&.active .file-item {
@apply border-emerald-500 dark:border-emerald-900 bg-emerald-50 dark:bg-emerald-900 dark:bg-opacity-40;
}

&:hover .file-item {
@apply border-emerald-600 dark:border-emerald-800;
}

.file-dropdown-toggle {
@apply absolute top-0 right-0 bottom-0 w-8 flex rounded-r-md items-center justify-center border-l border-transparent text-gray-500 dark:text-gray-400 outline-emerald-500 dark:outline-emerald-700 transition duration-200;
&:hover {
Expand All @@ -426,6 +439,19 @@ html.dark {
}
}
}

.folder-container {
.folder-item-container {
&.sticky {
position: -webkit-sticky;
position: sticky;
}

& > .file-item {
@apply pr-4;
}
}
}
}

.menu-button {
Expand Down
112 changes: 53 additions & 59 deletions resources/css/loader.scss
Original file line number Diff line number Diff line change
@@ -1,60 +1,54 @@
.loader,
.loader:before,
.loader:after {
border-radius: 50%;
width: 2.5em;
height: 2.5em;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation: load7 1.8s infinite ease-in-out;
animation: load7 1.8s infinite ease-in-out;
}
.loader {
color: #000000;
font-size: 10px;
margin: 80px auto;
position: relative;
text-indent: -9999em;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
html.dark .loader {
color: #e4e4e7;
}
.loader:before,
.loader:after {
content: '';
position: absolute;
top: 0;
}
.loader:before {
left: -3.5em;
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.loader:after {
left: 3.5em;
}
@-webkit-keyframes load7 {
0%,
80%,
100% {
box-shadow: 0 2.5em 0 -1.3em;
}
40% {
box-shadow: 0 2.5em 0 0;
}
}
@keyframes load7 {
0%,
80%,
100% {
box-shadow: 0 2.5em 0 -1.3em;
}
40% {
box-shadow: 0 2.5em 0 0;
}
.spin {
-webkit-animation-name: spin;
-webkit-animation-duration: 1500ms;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-name: spin;
-moz-animation-duration: 1500ms;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
-ms-animation-name: spin;
-ms-animation-duration: 1500ms;
-ms-animation-iteration-count: infinite;
-ms-animation-timing-function: linear;
animation-name: spin;
animation-duration: 1500ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
}

@-ms-keyframes spin {
from {
-ms-transform: rotate(0deg);
}
to {
-ms-transform: rotate(360deg);
}
}

@-moz-keyframes spin {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(360deg);
}
}

@-webkit-keyframes spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}

@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
84 changes: 84 additions & 0 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,90 @@ Alpine.plugin(Persist)

window.Alpine = Alpine

Alpine.data('dropdown', () => ({
open: false,
direction: 'down',
toggle() {
if (this.open) { return this.close() }
this.$refs.button.focus()
this.open = true
const p = this.$refs.list.getBoundingClientRect()
this.direction = this.$refs.button.getBoundingClientRect().bottom - p.top + 140 > p.height ? 'up' : 'down';
},
close(focusAfter) {
if (! this.open) { return }
this.open = false
focusAfter?.focus()
},
transitions: {
'x-transition:enter': "transition ease-out duration-100",
'x-transition:enter-start': "opacity-0 scale-90",
'x-transition:enter-end': "opacity-100 scale-100",
'x-transition:leave': "transition ease-in duration-100",
'x-transition:leave-start': "opacity-100 scale-100",
'x-transition:leave-end': "opacity-0 scale-90",
}
}));

Alpine.store('fileViewer', {
foldersOpen: [],
foldersInView: [],
folderTops: {},
containerTop: 0,
isOpen(folder) {
return this.foldersOpen.includes(folder);
},
toggle(folder) {
if (this.isOpen(folder)) {
this.foldersOpen = this.foldersOpen.filter(f => f !== folder);
} else {
this.foldersOpen.push(folder);
}
this.onScroll();
},
shouldBeSticky(folder) {
return this.isOpen(folder) && this.foldersInView.includes(folder);
},
stickTopPosition(folder) {
let aboveFold = this.pixelsAboveFold(folder);

if (aboveFold < 0) {
return Math.max(0, -24 + aboveFold) + 'px';
}

return '-24px';
},
pixelsAboveFold(folder) {
let folderContainer = document.getElementById('folder-'+folder);
if (!folderContainer) return false;
let row = folderContainer.getClientRects()[0];
return (row.top + row.height) - this.containerTop;
},
isInViewport(index) {
return this.pixelsAboveFold(index) > -36;
},
onScroll() {
let vm = this;
this.foldersOpen.forEach(function (folder) {
if (vm.isInViewport(folder)) {
if (!vm.foldersInView.includes(folder)) { vm.foldersInView.push(folder); }
vm.folderTops[folder] = vm.stickTopPosition(folder);
} else {
vm.foldersInView = vm.foldersInView.filter(f => f !== folder);
delete vm.folderTops[folder];
}
})
},
reset() {
this.foldersOpen = [];
this.foldersInView = [];
this.folderTops = {};
const container = document.getElementById('file-list-container');
this.containerTop = container.getBoundingClientRect().top;
container.scrollTo(0, 0);
}
});

Alpine.store('logViewer', {
theme: Alpine.$persist(Theme.System).as('logViewer_theme'),
stacksOpen: [],
Expand Down
19 changes: 19 additions & 0 deletions resources/views/icons.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<svg style="display: none">
<defs>
<symbol id="icon-spinner" viewBox="0 0 24 24">
<path d="M12 4.75V6.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M17.1266 6.87347L16.0659 7.93413" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M19.25 12L17.75 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M17.1266 17.1265L16.0659 16.0659" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M12 17.75V19.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M7.9342 16.0659L6.87354 17.1265" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M6.25 12L4.75 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M7.9342 7.93413L6.87354 6.87347" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</symbol>

<symbol id="icon-download" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
Expand Down Expand Up @@ -93,5 +104,13 @@
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
clip-rule="evenodd" />
</symbol>
<symbol id="icon-folder" viewBox="0 0 20 20">
<path d="M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" />
</symbol>
<symbol id="icon-folder-open" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z"
clip-rule="evenodd" />
<path d="M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z" />
</symbol>
</defs>
</svg>
9 changes: 5 additions & 4 deletions resources/views/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</head>
<body class="h-full px-5 bg-gray-100 dark:bg-gray-900"
x-data="{
selectedFileIdentifier: @isset($selectedFileIdentifier) '{{ $selectedFileIdentifier }}' @else null @endisset,
selectedFileIdentifier: @isset($selectedFile) '{{ $selectedFile->identifier }}' @else null @endisset,
selectFile(name) {
if (name && name === this.selectedFileIdentifier) {
this.selectedFileIdentifier = null;
Expand All @@ -25,9 +25,10 @@
this.$dispatch('file-selected', this.selectedFileIdentifier);
}
}"
x-init="$nextTick(() => { $store.fileViewer.reset(); @if(isset($selectedFile)) $store.fileViewer.foldersOpen.push('{{ $selectedFile->subFolderIdentifier() }}') @endif })"
>
<div class="flex h-full max-h-screen max-w-full">
<div class="hidden md:flex md:w-80 md:flex-col md:fixed md:inset-y-0">
<div class="hidden md:flex md:w-88 md:flex-col md:fixed md:inset-y-0">
<nav class="flex flex-col h-full py-5">
<div class="mx-3 mb-4">
<h1 class="font-semibold text-emerald-800 dark:text-emerald-600 text-2xl flex items-center">
Expand All @@ -44,11 +45,11 @@
@endif
</div>

@livewire('log-viewer::file-list', ['selectedFileIdentifier' => $selectedFileIdentifier])
@livewire('log-viewer::file-list', ['selectedFileIdentifier' => $selectedFile?->identifier])
</nav>
</div>

<div class="md:pl-80 flex flex-col flex-1 min-h-screen max-h-screen max-w-full">
<div class="md:pl-88 flex flex-col flex-1 min-h-screen max-h-screen max-w-full">
@livewire('log-viewer::log-list')
</div>
</div>
Expand Down
Loading

0 comments on commit 683befb

Please sign in to comment.