2021-05-11 15:10:45 -05:00
|
|
|
import React from 'react';
|
|
|
|
import { css, cx } from 'emotion';
|
2021-08-05 06:31:21 -05:00
|
|
|
import { dateTimeFormat, systemDateFormats, TimeZone, AbsoluteTimeRange, GrafanaTheme2 } from '@grafana/data';
|
|
|
|
import { CustomScrollbar, Spinner, useTheme2 } from '@grafana/ui';
|
2021-05-11 15:10:45 -05:00
|
|
|
import { LogsPage } from './LogsNavigation';
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
pages: LogsPage[];
|
|
|
|
currentPageIndex: number;
|
|
|
|
oldestLogsFirst: boolean;
|
|
|
|
timeZone: TimeZone;
|
|
|
|
loading: boolean;
|
|
|
|
changeTime: (range: AbsoluteTimeRange) => void;
|
|
|
|
};
|
|
|
|
|
|
|
|
export function LogsNavigationPages({
|
|
|
|
pages,
|
|
|
|
currentPageIndex,
|
|
|
|
oldestLogsFirst,
|
|
|
|
timeZone,
|
|
|
|
loading,
|
|
|
|
changeTime,
|
|
|
|
}: 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}`;
|
|
|
|
};
|
|
|
|
|
2021-08-05 06:31:21 -05:00
|
|
|
const theme = useTheme2();
|
2021-05-11 15:10:45 -05:00
|
|
|
const styles = getStyles(theme, loading);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<CustomScrollbar autoHide>
|
|
|
|
<div className={styles.pagesWrapper} data-testid="logsNavigationPages">
|
|
|
|
<div className={styles.pagesContainer}>
|
|
|
|
{pages.map((page: LogsPage, index: number) => (
|
|
|
|
<div
|
|
|
|
data-testid={`page${index + 1}`}
|
|
|
|
className={styles.page}
|
|
|
|
key={page.queryRange.to}
|
|
|
|
onClick={() => !loading && changeTime({ from: page.queryRange.from, to: page.queryRange.to })}
|
|
|
|
>
|
|
|
|
<div className={cx(styles.line, { selectedBg: currentPageIndex === index })} />
|
|
|
|
<div className={cx(styles.time, { selectedText: currentPageIndex === index })}>
|
|
|
|
{createPageContent(page, index)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</CustomScrollbar>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-08-05 06:31:21 -05:00
|
|
|
const getStyles = (theme: GrafanaTheme2, loading: boolean) => {
|
2021-05-11 15:10:45 -05:00
|
|
|
return {
|
|
|
|
pagesWrapper: css`
|
|
|
|
height: 100%;
|
2021-08-05 06:31:21 -05:00
|
|
|
padding-left: ${theme.spacing(0.5)};
|
2021-05-11 15:10:45 -05:00
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
overflow-y: scroll;
|
|
|
|
&::after {
|
|
|
|
content: '';
|
|
|
|
display: block;
|
|
|
|
background: repeating-linear-gradient(
|
|
|
|
135deg,
|
2021-08-05 06:31:21 -05:00
|
|
|
${theme.colors.background.primary},
|
|
|
|
${theme.colors.background.primary} 5px,
|
|
|
|
${theme.colors.background.secondary} 5px,
|
|
|
|
${theme.colors.background.secondary} 15px
|
2021-05-11 15:10:45 -05:00
|
|
|
);
|
|
|
|
width: 3px;
|
|
|
|
height: inherit;
|
|
|
|
margin-bottom: 8px;
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
pagesContainer: css`
|
|
|
|
display: flex;
|
|
|
|
padding: 0;
|
|
|
|
flex-direction: column;
|
|
|
|
`,
|
|
|
|
page: css`
|
|
|
|
display: flex;
|
2021-08-05 06:31:21 -05:00
|
|
|
margin: ${theme.spacing(2)} 0;
|
2021-05-11 15:10:45 -05:00
|
|
|
cursor: ${loading ? 'auto' : 'pointer'};
|
|
|
|
white-space: normal;
|
|
|
|
.selectedBg {
|
2021-08-05 06:31:21 -05:00
|
|
|
background: ${theme.colors.primary.main};
|
2021-05-11 15:10:45 -05:00
|
|
|
}
|
|
|
|
.selectedText {
|
2021-08-05 06:31:21 -05:00
|
|
|
color: ${theme.colors.primary.main};
|
2021-05-11 15:10:45 -05:00
|
|
|
}
|
|
|
|
`,
|
|
|
|
line: css`
|
|
|
|
width: 3px;
|
|
|
|
height: 100%;
|
|
|
|
align-items: center;
|
2021-08-05 06:31:21 -05:00
|
|
|
background: ${theme.colors.text.secondary};
|
2021-05-11 15:10:45 -05:00
|
|
|
`,
|
|
|
|
time: css`
|
|
|
|
width: 60px;
|
|
|
|
min-height: 80px;
|
2021-08-05 06:31:21 -05:00
|
|
|
font-size: ${theme.v1.typography.size.sm};
|
|
|
|
padding-left: ${theme.spacing(0.5)};
|
2021-05-11 15:10:45 -05:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
`,
|
|
|
|
};
|
2021-08-05 06:31:21 -05:00
|
|
|
};
|