/usr/share/grafana/public/app/features/explore/Logs
import { css, cx } from '@emotion/css'; import { dateTimeFormat, systemDateFormats, GrafanaTheme2 } from '@grafana/data'; import { TimeZone } from '@grafana/schema'; import { ScrollContainer, Spinner, useTheme2, clearButtonStyles } from '@grafana/ui'; import { LogsPage } from './LogsNavigation'; type Props = { pages: LogsPage[]; currentPageIndex: number; oldestLogsFirst: boolean; timeZone: TimeZone; loading: boolean; onClick: (page: LogsPage, pageNumber: number) => void; }; export function LogsNavigationPages({ pages, currentPageIndex, oldestLogsFirst, timeZone, loading, onClick }: Props) { const formatTime = (time: number) => { return `${dateTimeFormat(time, { format: systemDateFormats.interval.second, timeZone: timeZone, })}`; }; const createPageContent = (page: LogsPage, index: number) => { if (currentPageIndex === index && loading) { return <Spinner />; } const topContent = formatTime(oldestLogsFirst ? page.logsRange.from : page.logsRange.to); const bottomContent = formatTime(oldestLogsFirst ? page.logsRange.to : page.logsRange.from); return `${topContent} — ${bottomContent}`; }; const theme = useTheme2(); const styles = getStyles(theme, loading); return ( <ScrollContainer> <div className={styles.pagesWrapper} data-testid="logsNavigationPages"> <div className={styles.pagesContainer}> {pages.map((page: LogsPage, index: number) => ( <button type="button" data-testid={`page${index + 1}`} className={cx(clearButtonStyles(theme), styles.page)} key={page.queryRange.to} onClick={() => { onClick(page, index + 1); }} disabled={loading} > <div className={cx(styles.line, { selectedBg: currentPageIndex === index })} /> <div className={cx(styles.time, { selectedText: currentPageIndex === index })}> {createPageContent(page, index)} </div> </button> ))} </div> </div> </ScrollContainer> ); } const getStyles = (theme: GrafanaTheme2, loading: boolean) => { return { pagesWrapper: css({ height: '100%', paddingLeft: theme.spacing(0.5), display: 'flex', flexDirection: 'column', '&::after': { content: "''", display: 'block', background: `repeating-linear-gradient(135deg, ${theme.colors.background.primary}, ${theme.colors.background.primary} 5px, ${theme.colors.background.secondary} 5px, ${theme.colors.background.secondary} 15px)`, width: '3px', height: 'inherit', marginBottom: theme.spacing(1), }, }), pagesContainer: css({ display: 'flex', padding: 0, flexDirection: 'column', }), page: css({ display: 'flex', margin: theme.spacing(2, 0), cursor: loading ? 'auto' : 'pointer', whiteSpace: 'normal', '.selectedBg': { background: theme.colors.primary.main, }, '.selectedText': { color: theme.colors.primary.main, }, }), line: css({ width: '3px', height: '100%', alignItems: 'center', background: theme.colors.text.secondary, }), time: css({ width: '60px', minHeight: '80px', fontSize: theme.v1.typography.size.sm, paddingLeft: theme.spacing(0.5), display: 'flex', alignItems: 'center', }), }; };
.
Edit
..
Edit
LiveLogs.test.tsx
Edit
LiveLogs.tsx
Edit
Logs.test.tsx
Edit
Logs.tsx
Edit
LogsColumnSearch.tsx
Edit
LogsContainer.tsx
Edit
LogsFeedback.tsx
Edit
LogsMetaRow.test.tsx
Edit
LogsMetaRow.tsx
Edit
LogsNavigation.test.tsx
Edit
LogsNavigation.tsx
Edit
LogsNavigationPages.test.tsx
Edit
LogsNavigationPages.tsx
Edit
LogsSamplePanel.test.tsx
Edit
LogsSamplePanel.tsx
Edit
LogsTable.test.tsx
Edit
LogsTable.tsx
Edit
LogsTableWrap.test.tsx
Edit
LogsTableWrap.tsx
Edit
LogsVolumePanel.test.tsx
Edit
LogsVolumePanel.tsx
Edit
LogsVolumePanelList.test.tsx
Edit
LogsVolumePanelList.tsx
Edit
PopoverMenu.test.tsx
Edit
PopoverMenu.tsx
Edit
utils
Edit