whoami7 - Manager
:
/
home
/
kckglobal
/
www
/
portal
/
vendor
/
opcodesio
/
log-viewer
/
resources
/
js
/
stores
/
Upload File:
files >> //home/kckglobal/www/portal/vendor/opcodesio/log-viewer/resources/js/stores/logViewer.js
import { defineStore } from 'pinia'; import { useFileStore } from './files.js'; import axios from 'axios'; import { useSearchStore } from './search.js'; import { nextTick, toRaw } from 'vue'; import { usePaginationStore } from './pagination.js'; import { useSeverityStore } from './severity.js'; import { useLocalStorage } from '@vueuse/core'; import { debounce } from 'lodash'; import { useHostStore } from './hosts.js'; export const Theme = { System: 'System', Light: 'Light', Dark: 'Dark', } const defaultColumns = [ { label: 'Datetime', data_key: 'datetime' }, { label: 'Severity', data_key: 'level' }, { label: 'Message', data_key: 'message' }, ] export const useLogViewerStore = defineStore({ id: 'logViewer', state: () => ({ theme: useLocalStorage('logViewerTheme', Theme.System), shorterStackTraces: useLocalStorage('logViewerShorterStackTraces', false), direction: useLocalStorage('logViewerDirection', 'desc'), resultsPerPage: useLocalStorage('logViewerResultsPerPage', 25), helpSlideOverOpen: false, // Log data loading: false, error: null, logs: [], columns: defaultColumns, levelCounts: [], performance: {}, hasMoreResults: false, percentScanned: 100, abortController: null, // Log scrolling behaviour data viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, stacksOpen: [], stacksInView: [], stackTops: {}, containerTop: 0, showLevelsDropdown: true, }), getters: { selectedFile() { const fileStore = useFileStore(); return fileStore.selectedFile; }, isOpen: (state) => (index) => state.stacksOpen.includes(index), isMobile: (state) => state.viewportWidth <= 1023, tableRowHeight() { return this.isMobile ? 29 : 36; }, headerHeight() { return this.isMobile ? 0 : 36; }, shouldBeSticky(state) { return (index) => this.isOpen(index) && state.stacksInView.includes(index); }, stickTopPosition() { return (index) => { let aboveFold = this.pixelsAboveFold(index); if (aboveFold < 0) { return Math.max( this.headerHeight - this.tableRowHeight, this.headerHeight + aboveFold ) + 'px'; } return this.headerHeight + 'px'; } }, pixelsAboveFold(state) { return (index) => { let tbody = document.getElementById('tbody-' + index); if (!tbody) return false; let row = tbody.getClientRects()[0]; return (row.top + row.height - this.tableRowHeight - this.headerHeight) - state.containerTop; } }, isInViewport() { return (index) => this.pixelsAboveFold(index) > -this.tableRowHeight; }, }, actions: { setViewportDimensions(width, height) { this.viewportWidth = width; this.viewportHeight = height; const container = document.querySelector('.log-item-container'); if (container) { this.containerTop = container.getBoundingClientRect().top; } }, toggleTheme() { switch (this.theme) { case Theme.System: this.theme = Theme.Light; break; case Theme.Light: this.theme = Theme.Dark; break; default: this.theme = Theme.System; break; } this.syncTheme(); }, syncTheme() { const theme = this.theme; if (theme === Theme.Dark || (theme === Theme.System && window.matchMedia('(prefers-color-scheme: dark)').matches)) { document.documentElement.classList.add('dark') } else { document.documentElement.classList.remove('dark') } }, toggle(index) { if (this.isOpen(index)) { this.stacksOpen = this.stacksOpen.filter(idx => idx !== index) } else { this.stacksOpen.push(index) } this.onScroll(); }, onScroll() { let vm = this; this.stacksOpen.forEach(function (index) { if (vm.isInViewport(index)) { if (!vm.stacksInView.includes(index)) { vm.stacksInView.push(index); } vm.stackTops[index] = vm.stickTopPosition(index); } else { vm.stacksInView = vm.stacksInView.filter(idx => idx !== index); delete vm.stackTops[index]; } }) }, reset() { this.stacksOpen = []; this.stacksInView = []; this.stackTops = {}; const container = document.querySelector('.log-item-container'); if (!container) return; this.containerTop = container.getBoundingClientRect().top; container.scrollTo(0, 0); }, loadLogs: debounce(function ({ silently = false } = {}) { const hostStore = useHostStore(); const fileStore = useFileStore(); const searchStore = useSearchStore(); const paginationStore = usePaginationStore(); const severityStore = useSeverityStore(); // abort if the files are not ready yet if (fileStore.folders.length === 0) return; // abort the previous request which might now be outdated if (this.abortController) { this.abortController.abort(); } // abort if there's no selected file and no query if (!this.selectedFile && !searchStore.hasQuery) return; this.abortController = new AbortController(); const params = { host: hostStore.hostQueryParam, file: this.selectedFile?.identifier, direction: this.direction, query: searchStore.query, page: paginationStore.currentPage, per_page: this.resultsPerPage, exclude_levels: toRaw(severityStore.excludedLevels), exclude_file_types: toRaw(fileStore.fileTypesExcluded), shorter_stack_traces: this.shorterStackTraces, }; if (!silently) { this.loading = true; } axios.get(`${LogViewer.basePath}/api/logs`, { params, signal: this.abortController.signal }) .then(({ data }) => { if (params.host) { // because the host is different, we need to update the log links to be local instead of remote. this.logs = data.logs.map(log => { const queryParams = { host: params.host, file: log.file_identifier, query: `log-index:${log.index}` }; log.url = `${window.location.host}${LogViewer.basePath}?${new URLSearchParams(queryParams)}`; return log; }) } else { this.logs = data.logs; } this.columns = data.columns || defaultColumns; this.hasMoreResults = data.hasMoreResults; this.percentScanned = data.percentScanned; this.error = data.error || null; this.performance = data.performance || {}; severityStore.setLevelCounts(data.levelCounts); paginationStore.setPagination(data.pagination); this.loading = false; 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) { this.loadLogs({ silently: true }); } }) .catch((error) => { // aborted, thus we don't need to display that as an error. if (error.code === 'ERR_CANCELED') { this.hasMoreResults = false; this.percentScanned = 100; return; } this.loading = false; this.error = error.message; if (error.response?.data?.message) { this.error += ': ' + error.response.data.message; } console.error(error); }); }, 10), }, })
Copyright ©2021 || Defacer Indonesia