Skip to content

Commit 41014f2

Browse files
authored
New Log Details: Create initial component for Log Details (#107466)
* Log Details: fork and refactor as functional * LogDetailsBody: refactor styles * LogDetails: decouple from old panel * LogDetails: extract and centralize styles * LogDetailsRow: refactor as functional * Fix unused * Fix wrong label * LogDetails: create new component * LogLineDetails: process links and add sample sections * LogLineDetails: create and use LogLineDetailsFields * LogLineDetails: group labels by type * LogLineDetails: render all fields * Removed unused components * Fix imports * LogLineDetails: fix label * LogLineDetailsFields: fix stats * LogLinedetailsFields: add base styles * LogLineDetails: store open state * getLabelTypeFromRow: internationalize and add plural support * LogLineDetails: get plural field types * LogLineDetails: sticky header * LogLineDetails: introduce log details header * LogLineDetails: extract into submodules * LogDetails: add more header options and store collapsed state * LogDetails: add scroll for log line * LogLineDetailsHeader: add log line toggle button * LogLineDetailsFieldS: improve sizes * LogLineDetails: add search handler * LogLineDetailsFields: implement search * LogLineDetailsFields: switch to fixed key width * LogLineDetailsFields: refactor fields display * Link: remove tooltip * Fix translations * Revert "Link: remove tooltip" This reverts commit cd927302a7889b9430008ae3b81ace0aed343f5f. * LogLineDetailsFields: switch to css grid * Remap new translations * LogLineDetails: implement disable actions * LogLineDetailsFields: migrate links to css grid * LogLineDetailsFields: migrate stats to css grid * LogLabelStats: make functional * LogLineDetailsHeader: refactor listener * LogLineDetailsFields: decrease column minwidth * Reuse current panel unit tests * Translations * Test search * Update public/app/features/logs/components/panel/LogLineDetails.test.tsx * LogLineDetailsHeader: fix zIndex * Create LogLineDetailsDisplayedFields * Revert "Create LogLineDetailsDisplayedFields" This reverts commit 57d460d966483c3126738994e2705b6578aac120. * LogList: recover unwrapped horizontal scroll * LogLineDetails: apply styles suggestion * LogLineDetailsComponent: fix group option name * LogLineDetailsHeader: tweak styles * LogLineDetailsComponent: remove margin of last collapsable
1 parent de370fb commit 41014f2

File tree

13 files changed

+1510
-149
lines changed

13 files changed

+1510
-149
lines changed

public/app/features/logs/components/LogDetails.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,14 @@ export interface Props extends Themeable2 {
4343

4444
onPinLine?: (row: LogRowModel) => void;
4545
pinLineButtonTooltipTitle?: PopoverContent;
46-
mode?: 'inline' | 'sidebar';
4746
links?: Record<string, LinkModel[]>;
4847
}
4948

5049
interface LinkModelWithIcon extends LinkModel {
5150
icon?: IconName;
5251
}
5352

54-
const useAttributesExtensionLinks = (row: LogRowModel) => {
53+
export const useAttributesExtensionLinks = (row: LogRowModel) => {
5554
// Stable context for useMemo inside usePluginLinks
5655
const context: PluginExtensionResourceAttributesContext = useMemo(() => {
5756
return {
@@ -121,7 +120,6 @@ class UnThemedLogDetails extends PureComponent<Props> {
121120
onPinLine,
122121
styles,
123122
pinLineButtonTooltipTitle,
124-
mode = 'inline',
125123
links,
126124
} = this.props;
127125
const levelStyles = getLogLevelStyles(theme, row.logLevel);
@@ -152,14 +150,9 @@ class UnThemedLogDetails extends PureComponent<Props> {
152150
return (
153151
<tr className={cx(className, styles.logDetails)}>
154152
{showDuplicates && <td />}
155-
{mode === 'inline' && (
156-
<td
157-
className={levelClassName}
158-
aria-label={t('logs.un-themed-log-details.aria-label-log-level', 'Log level')}
159-
/>
160-
)}
153+
<td className={levelClassName} aria-label={t('logs.un-themed-log-details.aria-label-log-level', 'Log level')} />
161154
<td colSpan={4}>
162-
<div className={mode === 'inline' ? styles.logDetailsContainer : styles.logDetailsSidebarContainer}>
155+
<div className={styles.logDetailsContainer}>
163156
<table className={styles.logDetailsTable}>
164157
<tbody>
165158
{displayedFields && displayedFields.length > 0 && (
@@ -168,7 +161,7 @@ class UnThemedLogDetails extends PureComponent<Props> {
168161
<td
169162
colSpan={100}
170163
className={styles.logDetailsHeading}
171-
aria-label={t('logs.un-themed-log-details.aria-label-fields', 'Fields')}
164+
aria-label={t('logs.un-themed-log-details.aria-label-line', 'Log line')}
172165
>
173166
<Trans i18nKey="logs.log-details.log-line">Log line</Trans>
174167
</td>
Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { css } from '@emotion/css';
2-
import { PureComponent } from 'react';
2+
import { useMemo } from 'react';
33

44
import { LogLabelStatsModel, GrafanaTheme2 } from '@grafana/data';
55
import { t } from '@grafana/i18n';
6-
import { stylesFactory, withTheme2, Themeable2 } from '@grafana/ui';
6+
import { useStyles2 } from '@grafana/ui';
77

88
import { LogLabelStatsRow } from './LogLabelStatsRow';
99

1010
const STATS_ROW_LIMIT = 5;
1111

12-
const getStyles = stylesFactory((theme: GrafanaTheme2) => {
12+
const getStyles = (theme: GrafanaTheme2) => {
1313
return {
1414
logsStats: css({
1515
label: 'logs-stats',
@@ -42,20 +42,20 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => {
4242
padding: '5px 0px',
4343
}),
4444
};
45-
});
45+
};
4646

47-
interface Props extends Themeable2 {
47+
interface Props {
48+
className?: string;
4849
stats: LogLabelStatsModel[];
4950
label: string;
5051
value: string;
5152
rowCount: number;
5253
isLabel?: boolean;
5354
}
5455

55-
class UnThemedLogLabelStats extends PureComponent<Props> {
56-
render() {
57-
const { label, rowCount, stats, value, theme, isLabel } = this.props;
58-
const style = getStyles(theme);
56+
export const LogLabelStats = ({ className, label, rowCount, stats, value, isLabel }: Props) => {
57+
const style = useStyles2(getStyles);
58+
const rows = useMemo(() => {
5959
const topRows = stats.slice(0, STATS_ROW_LIMIT);
6060
let activeRow = topRows.find((row) => row.value === value);
6161
let otherRows = stats.slice(STATS_ROW_LIMIT);
@@ -66,45 +66,45 @@ class UnThemedLogLabelStats extends PureComponent<Props> {
6666
activeRow = otherRows.find((row) => row.value === value);
6767
otherRows = otherRows.filter((row) => row.value !== value);
6868
}
69+
return { topRows, otherRows, insertActiveRow, activeRow };
70+
}, [stats, value]);
6971

70-
const otherCount = otherRows.reduce((sum, row) => sum + row.count, 0);
71-
const topCount = topRows.reduce((sum, row) => sum + row.count, 0);
72-
const total = topCount + otherCount;
73-
const otherProportion = otherCount / total;
72+
const otherCount = useMemo(() => rows.otherRows.reduce((sum, row) => sum + row.count, 0), [rows.otherRows]);
73+
const topCount = useMemo(() => rows.topRows.reduce((sum, row) => sum + row.count, 0), [rows.topRows]);
74+
const total = topCount + otherCount;
75+
const otherProportion = otherCount / total;
7476

75-
return (
76-
<div className={style.logsStats} data-testid="logLabelStats">
77-
<div className={style.logsStatsHeader}>
78-
<div className={style.logsStatsTitle}>
79-
{isLabel
80-
? t(
81-
'logs.un-themed-log-label-stats.label-log-stats',
82-
'{{label}}: {{total}} of {{rowCount}} rows have that label',
83-
{
84-
label,
85-
total,
86-
rowCount,
87-
}
88-
)
89-
: t(
90-
'logs.un-themed-log-label-stats.field-log-stats',
91-
'{{label}}: {{total}} of {{rowCount}} rows have that field'
92-
)}
93-
</div>
94-
</div>
95-
<div className={style.logsStatsBody}>
96-
{topRows.map((stat) => (
97-
<LogLabelStatsRow key={stat.value} {...stat} active={stat.value === value} />
98-
))}
99-
{insertActiveRow && activeRow && <LogLabelStatsRow key={activeRow.value} {...activeRow} active />}
100-
{otherCount > 0 && (
101-
<LogLabelStatsRow key="__OTHERS__" count={otherCount} value="Other" proportion={otherProportion} />
102-
)}
77+
return (
78+
<div className={className ?? style.logsStats} data-testid="logLabelStats">
79+
<div className={style.logsStatsHeader}>
80+
<div className={style.logsStatsTitle}>
81+
{isLabel
82+
? t(
83+
'logs.un-themed-log-label-stats.label-log-stats',
84+
'{{label}}: {{total}} of {{rowCount}} rows have that label',
85+
{
86+
label,
87+
total,
88+
rowCount,
89+
}
90+
)
91+
: t(
92+
'logs.un-themed-log-label-stats.field-log-stats',
93+
'{{label}}: {{total}} of {{rowCount}} rows have that field'
94+
)}
10395
</div>
10496
</div>
105-
);
106-
}
107-
}
108-
109-
export const LogLabelStats = withTheme2(UnThemedLogLabelStats);
110-
LogLabelStats.displayName = 'LogLabelStats';
97+
<div className={style.logsStatsBody}>
98+
{rows.topRows.map((stat) => (
99+
<LogLabelStatsRow key={stat.value} {...stat} active={stat.value === value} />
100+
))}
101+
{rows.insertActiveRow && rows.activeRow && (
102+
<LogLabelStatsRow key={rows.activeRow.value} {...rows.activeRow} active />
103+
)}
104+
{otherCount > 0 && (
105+
<LogLabelStatsRow key="__OTHERS__" count={otherCount} value="Other" proportion={otherProportion} />
106+
)}
107+
</div>
108+
</div>
109+
);
110+
};

public/app/features/logs/components/getLogRowStyles.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,6 @@ export const getLogRowStyles = memoizeOne((theme: GrafanaTheme2) => {
187187
margin: theme.spacing(2.5, 1, 2.5, 2),
188188
cursor: 'default',
189189
}),
190-
logDetailsSidebarContainer: css({
191-
label: 'logs-row-details-table',
192-
border: `1px solid ${theme.colors.border.medium}`,
193-
padding: theme.spacing(0, 1, 1),
194-
borderRadius: theme.shape.radius.default,
195-
margin: theme.spacing(0, 1, 0, 1),
196-
cursor: 'default',
197-
}),
198190
logDetailsTable: css({
199191
label: 'logs-row-details-table',
200192
lineHeight: '18px',

public/app/features/logs/components/panel/LogLine.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,6 @@ export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtuali
528528
gridColumnGap: theme.spacing(FIELD_GAP_MULTIPLIER),
529529
whiteSpace: 'pre',
530530
paddingBottom: theme.spacing(0.75),
531-
'& .field': {
532-
overflow: 'hidden',
533-
},
534531
}),
535532
wrappedLogLine: css({
536533
alignSelf: 'flex-start',

0 commit comments

Comments
 (0)