feat: add support for changing the font size in logs (#5739)

* feat: add support for changing the font size in logs

* fix: build issues and logs context

* chore: fix build issues

* feat: scale all the spaces

* chore: handle light mode designs

* feat: set small as the default
This commit is contained in:
Vikrant Gupta
2024-08-22 23:56:51 +05:30
committed by GitHub
parent bfeceb0ed2
commit 96b81817e0
34 changed files with 803 additions and 184 deletions

View File

@@ -1,3 +1,16 @@
.addToQueryContainer {
cursor: pointer;
display: flex;
align-items: center;
&.small {
height: 16px;
}
&.medium {
height: 20px;
}
&.large {
height: 24px;
}
}

View File

@@ -1,13 +1,16 @@
import './AddToQueryHOC.styles.scss';
import { Popover } from 'antd';
import cx from 'classnames';
import { OPERATORS } from 'constants/queryBuilder';
import { FontSize } from 'container/OptionsMenu/types';
import { memo, MouseEvent, ReactNode, useMemo } from 'react';
function AddToQueryHOC({
fieldKey,
fieldValue,
onAddToQuery,
fontSize,
children,
}: AddToQueryHOCProps): JSX.Element {
const handleQueryAdd = (event: MouseEvent<HTMLDivElement>): void => {
@@ -21,7 +24,7 @@ function AddToQueryHOC({
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div className="addToQueryContainer" onClick={handleQueryAdd}>
<div className={cx('addToQueryContainer', fontSize)} onClick={handleQueryAdd}>
<Popover placement="top" content={popOverContent}>
{children}
</Popover>
@@ -33,6 +36,7 @@ export interface AddToQueryHOCProps {
fieldKey: string;
fieldValue: string;
onAddToQuery: (fieldKey: string, fieldValue: string, operator: string) => void;
fontSize: FontSize;
children: ReactNode;
}

View File

@@ -6,6 +6,21 @@
font-weight: 400;
line-height: 18px; /* 128.571% */
letter-spacing: -0.07px;
&.small {
font-size: 11px;
line-height: 16px;
}
&.medium {
font-size: 13px;
line-height: 20px;
}
&.large {
font-size: 14px;
line-height: 24px;
}
}
.log-value {
color: var(--text-vanilla-400, #c0c1c3);
@@ -14,6 +29,21 @@
font-weight: 400;
line-height: 18px; /* 128.571% */
letter-spacing: -0.07px;
&.small {
font-size: 11px;
line-height: 16px;
}
&.medium {
font-size: 13px;
line-height: 20px;
}
&.large {
font-size: 14px;
line-height: 24px;
}
}
.log-line {
display: flex;
@@ -40,6 +70,20 @@
font-weight: 400;
line-height: 18px; /* 128.571% */
letter-spacing: -0.07px;
&.small {
font-size: 11px;
line-height: 16px;
}
&.medium {
font-size: 13px;
line-height: 20px;
}
&.large {
font-size: 14px;
line-height: 24px;
}
}
.selected-log-value {
@@ -52,12 +96,37 @@
line-height: 18px;
letter-spacing: -0.07px;
font-size: 14px;
&.small {
font-size: 11px;
line-height: 16px;
}
&.medium {
font-size: 13px;
line-height: 20px;
}
&.large {
font-size: 14px;
line-height: 24px;
}
}
.selected-log-kv {
min-height: 24px;
display: flex;
align-items: center;
&.small {
min-height: 16px;
}
&.medium {
min-height: 20px;
}
&.large {
min-height: 24px;
}
}
}

View File

@@ -3,8 +3,10 @@ import './ListLogView.styles.scss';
import { blue } from '@ant-design/colors';
import Convert from 'ansi-to-html';
import { Typography } from 'antd';
import cx from 'classnames';
import LogDetail from 'components/LogDetail';
import { VIEW_TYPES } from 'components/LogDetail/constants';
import { FontSize } from 'container/OptionsMenu/types';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
import { useActiveLog } from 'hooks/logs/useActiveLog';
@@ -39,6 +41,7 @@ interface LogFieldProps {
fieldKey: string;
fieldValue: string;
linesPerRow?: number;
fontSize: FontSize;
}
type LogSelectedFieldProps = Omit<LogFieldProps, 'linesPerRow'> &
@@ -48,6 +51,7 @@ function LogGeneralField({
fieldKey,
fieldValue,
linesPerRow = 1,
fontSize,
}: LogFieldProps): JSX.Element {
const html = useMemo(
() => ({
@@ -62,12 +66,12 @@ function LogGeneralField({
return (
<TextContainer>
<Text ellipsis type="secondary" className="log-field-key">
<Text ellipsis type="secondary" className={cx('log-field-key', fontSize)}>
{`${fieldKey} : `}
</Text>
<LogText
dangerouslySetInnerHTML={html}
className="log-value"
className={cx('log-value', fontSize)}
linesPerRow={linesPerRow > 1 ? linesPerRow : undefined}
/>
</TextContainer>
@@ -78,6 +82,7 @@ function LogSelectedField({
fieldKey = '',
fieldValue = '',
onAddToQuery,
fontSize,
}: LogSelectedFieldProps): JSX.Element {
return (
<div className="log-selected-fields">
@@ -85,16 +90,22 @@ function LogSelectedField({
fieldKey={fieldKey}
fieldValue={fieldValue}
onAddToQuery={onAddToQuery}
fontSize={fontSize}
>
<Typography.Text>
<span style={{ color: blue[4] }} className="selected-log-field-key">
<span
style={{ color: blue[4] }}
className={cx('selected-log-field-key', fontSize)}
>
{fieldKey}
</span>
</Typography.Text>
</AddToQueryHOC>
<Typography.Text ellipsis className="selected-log-kv">
<span className="selected-log-field-key">{': '}</span>
<span className="selected-log-value">{fieldValue || "''"}</span>
<Typography.Text ellipsis className={cx('selected-log-kv', fontSize)}>
<span className={cx('selected-log-field-key', fontSize)}>{': '}</span>
<span className={cx('selected-log-value', fontSize)}>
{fieldValue || "''"}
</span>
</Typography.Text>
</div>
);
@@ -107,6 +118,7 @@ type ListLogViewProps = {
onAddToQuery: AddToQueryHOCProps['onAddToQuery'];
activeLog?: ILog | null;
linesPerRow: number;
fontSize: FontSize;
};
function ListLogView({
@@ -116,6 +128,7 @@ function ListLogView({
onAddToQuery,
activeLog,
linesPerRow,
fontSize,
}: ListLogViewProps): JSX.Element {
const flattenLogData = useMemo(() => FlatLogData(logData), [logData]);
@@ -185,6 +198,7 @@ function ListLogView({
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleDetailedView}
fontSize={fontSize}
>
<div className="log-line">
<LogStateIndicator
@@ -192,18 +206,28 @@ function ListLogView({
isActive={
activeLog?.id === logData.id || activeContextLog?.id === logData.id
}
fontSize={fontSize}
/>
<div>
<LogContainer>
<LogContainer fontSize={fontSize}>
<LogGeneralField
fieldKey="Log"
fieldValue={flattenLogData.body}
linesPerRow={linesPerRow}
fontSize={fontSize}
/>
{flattenLogData.stream && (
<LogGeneralField fieldKey="Stream" fieldValue={flattenLogData.stream} />
<LogGeneralField
fieldKey="Stream"
fieldValue={flattenLogData.stream}
fontSize={fontSize}
/>
)}
<LogGeneralField fieldKey="Timestamp" fieldValue={timestampValue} />
<LogGeneralField
fieldKey="Timestamp"
fieldValue={timestampValue}
fontSize={fontSize}
/>
{updatedSelecedFields.map((field) =>
isValidLogField(flattenLogData[field.name] as never) ? (
@@ -212,6 +236,7 @@ function ListLogView({
fieldKey={field.name}
fieldValue={flattenLogData[field.name] as never}
onAddToQuery={onAddToQuery}
fontSize={fontSize}
/>
) : null,
)}

View File

@@ -1,21 +1,46 @@
/* eslint-disable no-nested-ternary */
import { Color } from '@signozhq/design-tokens';
import { Card, Typography } from 'antd';
import { FontSize } from 'container/OptionsMenu/types';
import styled from 'styled-components';
interface LogTextProps {
linesPerRow?: number;
}
interface LogContainerProps {
fontSize: FontSize;
}
export const Container = styled(Card)<{
$isActiveLog: boolean;
$isDarkMode: boolean;
fontSize: FontSize;
}>`
width: 100% !important;
margin-bottom: 0.3rem;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `margin-bottom:0.1rem;`
: fontSize === FontSize.MEDIUM
? `margin-bottom: 0.2rem;`
: fontSize === FontSize.LARGE
? `margin-bottom:0.3rem;`
: ``}
cursor: pointer;
.ant-card-body {
padding: 0.3rem 0.6rem;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `padding:0.1rem 0.6rem;`
: fontSize === FontSize.MEDIUM
? `padding: 0.2rem 0.6rem;`
: fontSize === FontSize.LARGE
? `padding:0.3rem 0.6rem;`
: ``}
${({ $isActiveLog, $isDarkMode }): string =>
$isActiveLog
? `background-color: ${
@@ -38,11 +63,17 @@ export const TextContainer = styled.div`
width: 100%;
`;
export const LogContainer = styled.div`
export const LogContainer = styled.div<LogContainerProps>`
margin-left: 0.5rem;
display: flex;
flex-direction: column;
gap: 6px;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `gap: 2px;`
: fontSize === FontSize.MEDIUM
? ` gap:4px;`
: `gap:6px;`}
`;
export const LogText = styled.div<LogTextProps>`

View File

@@ -9,11 +9,24 @@
border-radius: 50px;
background-color: transparent;
&.small {
min-height: 16px;
}
&.medium {
min-height: 20px;
}
&.large {
min-height: 24px;
}
&.INFO {
background-color: var(--bg-slate-400);
}
&.WARNING, &.WARN {
&.WARNING,
&.WARN {
background-color: var(--bg-amber-500);
}

View File

@@ -1,10 +1,13 @@
import { render } from '@testing-library/react';
import { FontSize } from 'container/OptionsMenu/types';
import LogStateIndicator from './LogStateIndicator';
describe('LogStateIndicator', () => {
it('renders correctly with default props', () => {
const { container } = render(<LogStateIndicator type="INFO" />);
const { container } = render(
<LogStateIndicator type="INFO" fontSize={FontSize.MEDIUM} />,
);
const indicator = container.firstChild as HTMLElement;
expect(indicator.classList.contains('log-state-indicator')).toBe(true);
expect(indicator.classList.contains('isActive')).toBe(false);
@@ -15,28 +18,30 @@ describe('LogStateIndicator', () => {
});
it('renders correctly when isActive is true', () => {
const { container } = render(<LogStateIndicator type="INFO" isActive />);
const { container } = render(
<LogStateIndicator type="INFO" isActive fontSize={FontSize.MEDIUM} />,
);
const indicator = container.firstChild as HTMLElement;
expect(indicator.classList.contains('isActive')).toBe(true);
});
it('renders correctly with different types', () => {
const { container: containerInfo } = render(
<LogStateIndicator type="INFO" />,
<LogStateIndicator type="INFO" fontSize={FontSize.MEDIUM} />,
);
expect(containerInfo.querySelector('.line')?.classList.contains('INFO')).toBe(
true,
);
const { container: containerWarning } = render(
<LogStateIndicator type="WARNING" />,
<LogStateIndicator type="WARNING" fontSize={FontSize.MEDIUM} />,
);
expect(
containerWarning.querySelector('.line')?.classList.contains('WARNING'),
).toBe(true);
const { container: containerError } = render(
<LogStateIndicator type="ERROR" />,
<LogStateIndicator type="ERROR" fontSize={FontSize.MEDIUM} />,
);
expect(
containerError.querySelector('.line')?.classList.contains('ERROR'),

View File

@@ -1,6 +1,7 @@
import './LogStateIndicator.styles.scss';
import cx from 'classnames';
import { FontSize } from 'container/OptionsMenu/types';
export const SEVERITY_TEXT_TYPE = {
TRACE: 'TRACE',
@@ -44,13 +45,15 @@ export const LogType = {
function LogStateIndicator({
type,
isActive,
fontSize,
}: {
type: string;
fontSize: FontSize;
isActive?: boolean;
}): JSX.Element {
return (
<div className={cx('log-state-indicator', isActive ? 'isActive' : '')}>
<div className={cx('line', type)}> </div>
<div className={cx('line', type, fontSize)}> </div>
</div>
);
}

View File

@@ -39,6 +39,7 @@ function RawLogView({
linesPerRow,
isTextOverflowEllipsisDisabled,
selectedFields = [],
fontSize,
}: RawLogViewProps): JSX.Element {
const { isHighlighted, isLogsExplorerPage, onLogCopy } = useCopyLogLink(
data.id,
@@ -168,6 +169,7 @@ function RawLogView({
activeContextLog?.id === data.id ||
isActiveLog
}
fontSize={fontSize}
/>
<RawLogContent
@@ -176,6 +178,7 @@ function RawLogView({
$isDarkMode={isDarkMode}
$isTextOverflowEllipsisDisabled={isTextOverflowEllipsisDisabled}
linesPerRow={linesPerRow}
fontSize={fontSize}
dangerouslySetInnerHTML={html}
/>

View File

@@ -1,6 +1,8 @@
/* eslint-disable no-nested-ternary */
import { blue } from '@ant-design/colors';
import { Color } from '@signozhq/design-tokens';
import { Col, Row, Space } from 'antd';
import { FontSize } from 'container/OptionsMenu/types';
import styled from 'styled-components';
import { getActiveLogBackground, getDefaultLogBackground } from 'utils/logs';
@@ -48,10 +50,15 @@ export const ExpandIconWrapper = styled(Col)`
export const RawLogContent = styled.div<RawLogContentProps>`
margin-bottom: 0;
display: flex !important;
align-items: center;
font-family: 'SF Mono', monospace;
font-family: 'Geist Mono';
font-size: 13px;
font-weight: 400;
line-height: 24px;
letter-spacing: -0.07px;
padding: 4px;
text-align: left;
color: ${({ $isDarkMode }): string =>
$isDarkMode ? Color.BG_VANILLA_400 : Color.BG_INK_400};
@@ -66,9 +73,12 @@ export const RawLogContent = styled.div<RawLogContentProps>`
line-clamp: ${linesPerRow};
-webkit-box-orient: vertical;`};
line-height: 24px;
letter-spacing: -0.07px;
padding: 4px;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `font-size:11px; line-height:16px; padding:1px;`
: fontSize === FontSize.MEDIUM
? `font-size:13px; line-height:20px; padding:1px;`
: `font-size:14px; line-height:24px; padding:2px;`}
cursor: ${({ $isActiveLog, $isReadOnly }): string =>
$isActiveLog || $isReadOnly ? 'initial' : 'pointer'};

View File

@@ -1,3 +1,4 @@
import { FontSize } from 'container/OptionsMenu/types';
import { IField } from 'types/api/logs/fields';
import { ILog } from 'types/api/logs/log';
@@ -7,11 +8,13 @@ export interface RawLogViewProps {
isTextOverflowEllipsisDisabled?: boolean;
data: ILog;
linesPerRow: number;
fontSize: FontSize;
selectedFields?: IField[];
}
export interface RawLogContentProps {
linesPerRow: number;
fontSize: FontSize;
$isReadOnly?: boolean;
$isActiveLog?: boolean;
$isDarkMode?: boolean;

View File

@@ -1,7 +1,10 @@
/* eslint-disable no-nested-ternary */
import { FontSize } from 'container/OptionsMenu/types';
import styled from 'styled-components';
interface TableBodyContentProps {
linesPerRow: number;
fontSize: FontSize;
isDarkMode?: boolean;
}
@@ -20,4 +23,10 @@ export const TableBodyContent = styled.div<TableBodyContentProps>`
-webkit-line-clamp: ${(props): number => props.linesPerRow};
line-clamp: ${(props): number => props.linesPerRow};
-webkit-box-orient: vertical;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `font-size:11px; line-height:16px;`
: fontSize === FontSize.MEDIUM
? `font-size:13px; line-height:20px;`
: `font-size:14px; line-height:24px;`}
`;

View File

@@ -1,4 +1,5 @@
import { ColumnsType, ColumnType } from 'antd/es/table';
import { FontSize } from 'container/OptionsMenu/types';
import { IField } from 'types/api/logs/fields';
import { ILog } from 'types/api/logs/log';
@@ -10,6 +11,7 @@ export type LogsTableViewProps = {
logs: ILog[];
fields: IField[];
linesPerRow: number;
fontSize: FontSize;
onClickExpand?: (log: ILog) => void;
};

View File

@@ -5,6 +5,21 @@
font-weight: 400;
line-height: 18px; /* 128.571% */
letter-spacing: -0.07px;
&.small {
font-size: 11px;
line-height: 16px;
}
&.medium {
font-size: 13px;
line-height: 20px;
}
&.large {
font-size: 14px;
line-height: 24px;
}
}
.table-timestamp {
@@ -25,3 +40,21 @@
color: var(--bg-slate-400);
}
}
.paragraph {
padding: 0px !important;
&.small {
font-size: 11px !important;
line-height: 16px !important;
}
&.medium {
font-size: 13px !important;
line-height: 20px !important;
}
&.large {
font-size: 14px !important;
line-height: 24px !important;
}
}

View File

@@ -3,6 +3,7 @@ import './useTableView.styles.scss';
import Convert from 'ansi-to-html';
import { Typography } from 'antd';
import { ColumnsType } from 'antd/es/table';
import cx from 'classnames';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
import { useIsDarkMode } from 'hooks/useDarkMode';
@@ -31,6 +32,7 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
logs,
fields,
linesPerRow,
fontSize,
appendTo = 'center',
activeContextLog,
activeLog,
@@ -57,7 +59,10 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
: getDefaultCellStyle(isDarkMode),
},
children: (
<Typography.Paragraph ellipsis={{ rows: linesPerRow }}>
<Typography.Paragraph
ellipsis={{ rows: linesPerRow }}
className={cx('paragraph', fontSize)}
>
{field}
</Typography.Paragraph>
),
@@ -87,8 +92,9 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
isActive={
activeLog?.id === item.id || activeContextLog?.id === item.id
}
fontSize={fontSize}
/>
<Typography.Paragraph ellipsis className="text">
<Typography.Paragraph ellipsis className={cx('text', fontSize)}>
{date}
</Typography.Paragraph>
</div>
@@ -114,6 +120,7 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
}),
),
}}
fontSize={fontSize}
linesPerRow={linesPerRow}
isDarkMode={isDarkMode}
/>
@@ -130,6 +137,7 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
linesPerRow,
activeLog?.id,
activeContextLog?.id,
fontSize,
]);
return { columns, dataSource: flattenLogData };

View File

@@ -17,17 +17,126 @@
box-shadow: 4px 10px 16px 2px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(20px);
.font-size-dropdown {
display: flex;
flex-direction: column;
.back-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 12px;
border: none !important;
box-shadow: none !important;
.icon {
flex-shrink: 0;
}
.text {
color: var(--bg-vanilla-400);
font-family: Inter;
font-size: 13px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 142.857% */
letter-spacing: 0.14px;
}
}
.back-btn:hover {
background-color: unset !important;
}
.content {
display: flex;
flex-direction: column;
.option-btn {
display: flex;
align-items: center;
padding: 12px;
border: none !important;
box-shadow: none !important;
justify-content: space-between;
.icon {
flex-shrink: 0;
}
.text {
color: var(--bg-vanilla-400);
font-family: Inter;
font-size: 13px;
font-style: normal;
font-weight: 400;
line-height: normal; /* 142.857% */
letter-spacing: 0.14px;
text-transform: capitalize;
}
.text:hover {
color: var(--bg-vanilla-300);
}
}
.option-btn:hover {
background-color: unset !important;
}
}
}
.font-size-container {
padding: 12px;
display: flex;
flex-direction: column;
gap: 12px;
.title {
color: var(--bg-slate-50);
font-family: Inter;
font-size: 11px;
font-style: normal;
font-weight: 500;
line-height: 18px; /* 163.636% */
letter-spacing: 0.88px;
text-transform: uppercase;
}
.value {
display: flex;
height: 20px;
padding: 4px 0px;
justify-content: space-between;
align-items: center;
border: none !important;
.font-value {
color: var(--bg-vanilla-400);
font-family: Inter;
font-size: 13px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.14px;
text-transform: capitalize;
}
.icon {
}
}
.value:hover {
background-color: unset !important;
}
}
.menu-container {
padding: 12px;
.title {
font-family: Inter;
font-size: 11px;
font-weight: 600;
font-weight: 500;
line-height: 18px;
letter-spacing: 0.08em;
text-align: left;
color: #52575c;
color: var(--bg-slate-50);
}
.menu-items {
@@ -65,11 +174,11 @@
padding: 12px;
.title {
color: #52575c;
color: var(--bg-slate-50);
font-family: Inter;
font-size: 11px;
font-style: normal;
font-weight: 600;
font-weight: 500;
line-height: 18px; /* 163.636% */
letter-spacing: 0.88px;
text-transform: uppercase;
@@ -149,11 +258,11 @@
}
.title {
color: #52575c;
color: var(--bg-slate-50);
font-family: Inter;
font-size: 11px;
font-style: normal;
font-weight: 600;
font-weight: 500;
line-height: 18px; /* 163.636% */
letter-spacing: 0.88px;
text-transform: uppercase;
@@ -299,6 +408,38 @@
box-shadow: 4px 10px 16px 2px rgba(255, 255, 255, 0.2);
.font-size-dropdown {
.back-btn {
.text {
color: var(--bg-ink-400);
}
}
.content {
.option-btn {
.text {
color: var(--bg-ink-400);
}
.text:hover {
color: var(--bg-ink-300);
}
}
}
}
.font-size-container {
.title {
color: var(--bg-ink-100);
}
.value {
.font-value {
color: var(--bg-ink-400);
}
}
}
.horizontal-line {
background: var(--bg-vanilla-300);
}

View File

@@ -3,12 +3,12 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
import './LogsFormatOptionsMenu.styles.scss';
import { Divider, Input, InputNumber, Tooltip } from 'antd';
import { Button, Divider, Input, InputNumber, Tooltip, Typography } from 'antd';
import cx from 'classnames';
import { LogViewMode } from 'container/LogsTable';
import { OptionsMenuConfig } from 'container/OptionsMenu/types';
import { FontSize, OptionsMenuConfig } from 'container/OptionsMenu/types';
import useDebouncedFn from 'hooks/useDebouncedFunction';
import { Check, Minus, Plus, X } from 'lucide-react';
import { Check, ChevronLeft, ChevronRight, Minus, Plus, X } from 'lucide-react';
import { useCallback, useEffect, useState } from 'react';
interface LogsFormatOptionsMenuProps {
@@ -24,10 +24,16 @@ export default function LogsFormatOptionsMenu({
selectedOptionFormat,
config,
}: LogsFormatOptionsMenuProps): JSX.Element {
const { maxLines, format, addColumn } = config;
const { maxLines, format, addColumn, fontSize } = config;
const [selectedItem, setSelectedItem] = useState(selectedOptionFormat);
const maxLinesNumber = (maxLines?.value as number) || 1;
const [maxLinesPerRow, setMaxLinesPerRow] = useState<number>(maxLinesNumber);
const [fontSizeValue, setFontSizeValue] = useState<FontSize>(
fontSize?.value || FontSize.SMALL,
);
const [isFontSizeOptionsOpen, setIsFontSizeOptionsOpen] = useState<boolean>(
false,
);
const [addNewColumn, setAddNewColumn] = useState(false);
@@ -88,6 +94,12 @@ export default function LogsFormatOptionsMenu({
}
}, [maxLinesPerRow]);
useEffect(() => {
if (fontSizeValue && config && config.fontSize?.onChange) {
config.fontSize.onChange(fontSizeValue);
}
}, [fontSizeValue]);
return (
<div
className={cx('nested-menu-container', addNewColumn ? 'active' : '')}
@@ -96,145 +108,213 @@ export default function LogsFormatOptionsMenu({
event.stopPropagation();
}}
>
<div className="menu-container">
<div className="title"> {title} </div>
<div className="menu-items">
{items.map(
(item: any): JSX.Element => (
<div
className="item"
key={item.label}
onClick={(): void => handleMenuItemClick(item.key)}
>
<div className={cx('item-label')}>
{item.label}
{selectedItem === item.key && <Check size={12} />}
</div>
</div>
),
)}
{isFontSizeOptionsOpen ? (
<div className="font-size-dropdown">
<Button
onClick={(): void => setIsFontSizeOptionsOpen(false)}
className="back-btn"
type="text"
>
<ChevronLeft size={14} className="icon" />
<Typography.Text className="text">Select font size</Typography.Text>
</Button>
<div className="horizontal-line" />
<div className="content">
<Button
onClick={(): void => {
setFontSizeValue(FontSize.SMALL);
}}
className="option-btn"
type="text"
>
<Typography.Text className="text">{FontSize.SMALL}</Typography.Text>
{fontSizeValue === FontSize.SMALL && (
<Check size={14} className="icon" />
)}
</Button>
<Button
onClick={(): void => {
setFontSizeValue(FontSize.MEDIUM);
}}
className="option-btn"
type="text"
>
<Typography.Text className="text">{FontSize.MEDIUM}</Typography.Text>
{fontSizeValue === FontSize.MEDIUM && (
<Check size={14} className="icon" />
)}
</Button>
<Button
onClick={(): void => {
setFontSizeValue(FontSize.LARGE);
}}
className="option-btn"
type="text"
>
<Typography.Text className="text">{FontSize.LARGE}</Typography.Text>
{fontSizeValue === FontSize.LARGE && (
<Check size={14} className="icon" />
)}
</Button>
</div>
</div>
</div>
{selectedItem && (
) : (
<>
<>
<div className="horizontal-line" />
<div className="max-lines-per-row">
<div className="title"> max lines per row </div>
<div className="raw-format max-lines-per-row-input">
<button
type="button"
className="periscope-btn"
onClick={decrementMaxLinesPerRow}
>
{' '}
<Minus size={12} />{' '}
</button>
<InputNumber
min={1}
max={10}
value={maxLinesPerRow}
onChange={handleLinesPerRowChange}
/>
<button
type="button"
className="periscope-btn"
onClick={incrementMaxLinesPerRow}
>
{' '}
<Plus size={12} />{' '}
</button>
</div>
</div>
</>
<div className="font-size-container">
<div className="title">Font Size</div>
<Button
className="value"
type="text"
onClick={(): void => {
setIsFontSizeOptionsOpen(true);
}}
>
<Typography.Text className="font-value">{fontSizeValue}</Typography.Text>
<ChevronRight size={14} className="icon" />
</Button>
</div>
<div className="horizontal-line" />
<div className="menu-container">
<div className="title"> {title} </div>
<div className="selected-item-content-container active">
{!addNewColumn && <div className="horizontal-line" />}
<div className="menu-items">
{items.map(
(item: any): JSX.Element => (
<div
className="item"
key={item.label}
onClick={(): void => handleMenuItemClick(item.key)}
>
<div className={cx('item-label')}>
{item.label}
{addNewColumn && (
<div className="add-new-column-header">
<div className="title">
{' '}
columns
<X size={14} onClick={handleToggleAddNewColumn} />{' '}
</div>
<Input
tabIndex={0}
type="text"
autoFocus
onFocus={addColumn?.onFocus}
onChange={handleSearchValueChange}
placeholder="Search..."
/>
</div>
)}
<div className="item-content">
{!addNewColumn && (
<div className="title">
columns
<Plus size={14} onClick={handleToggleAddNewColumn} />{' '}
</div>
)}
<div className="column-format">
{addColumn?.value?.map(({ key, id }) => (
<div className="column-name" key={id}>
<div className="name">
<Tooltip placement="left" title={key}>
{key}
</Tooltip>
{selectedItem === item.key && <Check size={12} />}
</div>
<X
className="delete-btn"
size={14}
onClick={(): void => addColumn.onRemove(id as string)}
/>
</div>
))}
</div>
{addColumn?.isFetching && (
<div className="loading-container"> Loading ... </div>
)}
{addNewColumn &&
addColumn &&
addColumn.value.length > 0 &&
addColumn.options &&
addColumn?.options?.length > 0 && (
<Divider className="column-divider" />
)}
{addNewColumn && (
<div className="column-format-new-options">
{addColumn?.options?.map(({ label, value }) => (
<div
className="column-name"
key={value}
onClick={(eve): void => {
eve.stopPropagation();
if (addColumn && addColumn?.onSelect) {
addColumn?.onSelect(value, { label, disabled: false });
}
}}
>
<div className="name">
<Tooltip placement="left" title={label}>
{label}
</Tooltip>
</div>
</div>
))}
</div>
),
)}
</div>
</div>
{selectedItem && (
<>
<>
<div className="horizontal-line" />
<div className="max-lines-per-row">
<div className="title"> max lines per row </div>
<div className="raw-format max-lines-per-row-input">
<button
type="button"
className="periscope-btn"
onClick={decrementMaxLinesPerRow}
>
{' '}
<Minus size={12} />{' '}
</button>
<InputNumber
min={1}
max={10}
value={maxLinesPerRow}
onChange={handleLinesPerRowChange}
/>
<button
type="button"
className="periscope-btn"
onClick={incrementMaxLinesPerRow}
>
{' '}
<Plus size={12} />{' '}
</button>
</div>
</div>
</>
<div className="selected-item-content-container active">
{!addNewColumn && <div className="horizontal-line" />}
{addNewColumn && (
<div className="add-new-column-header">
<div className="title">
{' '}
columns
<X size={14} onClick={handleToggleAddNewColumn} />{' '}
</div>
<Input
tabIndex={0}
type="text"
autoFocus
onFocus={addColumn?.onFocus}
onChange={handleSearchValueChange}
placeholder="Search..."
/>
</div>
)}
<div className="item-content">
{!addNewColumn && (
<div className="title">
columns
<Plus size={14} onClick={handleToggleAddNewColumn} />{' '}
</div>
)}
<div className="column-format">
{addColumn?.value?.map(({ key, id }) => (
<div className="column-name" key={id}>
<div className="name">
<Tooltip placement="left" title={key}>
{key}
</Tooltip>
</div>
<X
className="delete-btn"
size={14}
onClick={(): void => addColumn.onRemove(id as string)}
/>
</div>
))}
</div>
{addColumn?.isFetching && (
<div className="loading-container"> Loading ... </div>
)}
{addNewColumn &&
addColumn &&
addColumn.value.length > 0 &&
addColumn.options &&
addColumn?.options?.length > 0 && (
<Divider className="column-divider" />
)}
{addNewColumn && (
<div className="column-format-new-options">
{addColumn?.options?.map(({ label, value }) => (
<div
className="column-name"
key={value}
onClick={(eve): void => {
eve.stopPropagation();
if (addColumn && addColumn?.onSelect) {
addColumn?.onSelect(value, { label, disabled: false });
}
}}
>
<div className="name">
<Tooltip placement="left" title={label}>
{label}
</Tooltip>
</div>
</div>
))}
</div>
)}
</div>
</div>
</>
)}
</>
)}
</div>

View File

@@ -63,6 +63,7 @@ function LiveLogsList({ logs }: LiveLogsListProps): JSX.Element {
data={log}
linesPerRow={options.maxLines}
selectedFields={selectedFields}
fontSize={options.fontSize}
/>
);
}
@@ -75,12 +76,14 @@ function LiveLogsList({ logs }: LiveLogsListProps): JSX.Element {
linesPerRow={options.maxLines}
onAddToQuery={onAddToQuery}
onSetActiveLog={onSetActiveLog}
fontSize={options.fontSize}
/>
);
},
[
onAddToQuery,
onSetActiveLog,
options.fontSize,
options.format,
options.maxLines,
selectedFields,
@@ -123,6 +126,7 @@ function LiveLogsList({ logs }: LiveLogsListProps): JSX.Element {
logs,
fields: selectedFields,
linesPerRow: options.maxLines,
fontSize: options.fontSize,
appendTo: 'end',
activeLogIndex,
}}

View File

@@ -3,12 +3,17 @@ import './ContextLogRenderer.styles.scss';
import { Skeleton } from 'antd';
import RawLogView from 'components/Logs/RawLogView';
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import { LOCALSTORAGE } from 'constants/localStorage';
import ShowButton from 'container/LogsContextList/ShowButton';
import { useOptionsMenu } from 'container/OptionsMenu';
import { FontSize } from 'container/OptionsMenu/types';
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
import { useCallback, useEffect, useState } from 'react';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { ILog } from 'types/api/logs/log';
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource, StringOperators } from 'types/common/queryBuilder';
import { useContextLogData } from './useContextLogData';
@@ -22,6 +27,20 @@ function ContextLogRenderer({
const [afterLogPage, setAfterLogPage] = useState<number>(1);
const [logs, setLogs] = useState<ILog[]>([log]);
const { initialDataSource, stagedQuery } = useQueryBuilder();
const listQuery = useMemo(() => {
if (!stagedQuery || stagedQuery.builder.queryData.length < 1) return null;
return stagedQuery.builder.queryData.find((item) => !item.disabled) || null;
}, [stagedQuery]);
const { options } = useOptionsMenu({
storageKey: LOCALSTORAGE.LOGS_LIST_OPTIONS,
dataSource: initialDataSource || DataSource.METRICS,
aggregateOperator: listQuery?.aggregateOperator || StringOperators.NOOP,
});
const {
logs: previousLogs,
isFetching: isPreviousLogsFetching,
@@ -34,6 +53,7 @@ function ContextLogRenderer({
order: ORDERBY_FILTERS.ASC,
page: prevLogPage,
setPage: setPrevLogPage,
fontSize: options.fontSize,
});
const {
@@ -48,6 +68,7 @@ function ContextLogRenderer({
order: ORDERBY_FILTERS.DESC,
page: afterLogPage,
setPage: setAfterLogPage,
fontSize: options.fontSize,
});
useEffect(() => {
@@ -65,6 +86,19 @@ function ContextLogRenderer({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filters]);
const lengthMultipier = useMemo(() => {
switch (options.fontSize) {
case FontSize.SMALL:
return 24;
case FontSize.MEDIUM:
return 28;
case FontSize.LARGE:
return 32;
default:
return 32;
}
}, [options.fontSize]);
const getItemContent = useCallback(
(_: number, logTorender: ILog): JSX.Element => (
<RawLogView
@@ -74,9 +108,10 @@ function ContextLogRenderer({
key={logTorender.id}
data={logTorender}
linesPerRow={1}
fontSize={options.fontSize}
/>
),
[log.id],
[log.id, options.fontSize],
);
return (
@@ -101,7 +136,7 @@ function ContextLogRenderer({
initialTopMostItemIndex={0}
data={logs}
itemContent={getItemContent}
style={{ height: `calc(${logs.length} * 32px)` }}
style={{ height: `calc(${logs.length} * ${lengthMultipier}px)` }}
/>
</OverlayScrollbar>
{isAfterLogsFetching && (

View File

@@ -4,9 +4,11 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
import {
getOrderByTimestamp,
INITIAL_PAGE_SIZE,
INITIAL_PAGE_SIZE_SMALL_FONT,
LOGS_MORE_PAGE_SIZE,
} from 'container/LogsContextList/configs';
import { getRequestData } from 'container/LogsContextList/utils';
import { FontSize } from 'container/OptionsMenu/types';
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
import {
@@ -30,6 +32,7 @@ export const useContextLogData = ({
filters,
page,
setPage,
fontSize,
}: {
log: ILog;
query: Query;
@@ -38,6 +41,7 @@ export const useContextLogData = ({
filters: TagFilter | null;
page: number;
setPage: Dispatch<SetStateAction<number>>;
fontSize?: FontSize;
}): {
logs: ILog[];
handleShowNextLines: () => void;
@@ -54,9 +58,14 @@ export const useContextLogData = ({
const logsMorePageSize = useMemo(() => (page - 1) * LOGS_MORE_PAGE_SIZE, [
page,
]);
const initialPageSize =
fontSize && fontSize === FontSize.SMALL
? INITIAL_PAGE_SIZE_SMALL_FONT
: INITIAL_PAGE_SIZE;
const pageSize = useMemo(
() => (page <= 1 ? INITIAL_PAGE_SIZE : logsMorePageSize + INITIAL_PAGE_SIZE),
[page, logsMorePageSize],
() => (page <= 1 ? initialPageSize : logsMorePageSize + initialPageSize),
[page, initialPageSize, logsMorePageSize],
);
const isDisabledFetch = useMemo(() => logs.length < pageSize, [
logs.length,
@@ -77,8 +86,16 @@ export const useContextLogData = ({
log: lastLog,
orderByTimestamp,
page,
pageSize: initialPageSize,
}),
[currentStagedQueryData, query, lastLog, orderByTimestamp, page],
[
currentStagedQueryData,
query,
lastLog,
orderByTimestamp,
page,
initialPageSize,
],
);
const [requestData, setRequestData] = useState<Query | null>(

View File

@@ -2,6 +2,7 @@ import './LogContext.styles.scss';
import RawLogView from 'components/Logs/RawLogView';
import LogsContextList from 'container/LogsContextList';
import { FontSize } from 'container/OptionsMenu/types';
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
import { ILog } from 'types/api/logs/log';
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
@@ -37,6 +38,7 @@ function LogContext({
isTextOverflowEllipsisDisabled={false}
data={log}
linesPerRow={1}
fontSize={FontSize.SMALL}
/>
<LogsContextList
order={ORDERBY_FILTERS.DESC}

View File

@@ -14,7 +14,7 @@ import CopyClipboardHOC from 'components/Logs/CopyClipboardHOC';
import { ResizeTable } from 'components/ResizeTable';
import { OPERATORS } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import { OptionsQuery } from 'container/OptionsMenu/types';
import { FontSize, OptionsQuery } from 'container/OptionsMenu/types';
import { useIsDarkMode } from 'hooks/useDarkMode';
import history from 'lib/history';
import { fieldSearchFilter } from 'lib/logs/fieldSearch';
@@ -256,6 +256,7 @@ function TableView({
fieldKey={fieldFilterKey}
fieldValue={flattenLogData[field]}
onAddToQuery={onAddToQuery}
fontSize={FontSize.SMALL}
>
{renderedField}
</AddToQueryHOC>

View File

@@ -1,6 +1,7 @@
import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData';
export const INITIAL_PAGE_SIZE = 10;
export const INITIAL_PAGE_SIZE_SMALL_FONT = 12;
export const LOGS_MORE_PAGE_SIZE = 10;
export const getOrderByTimestamp = (order: string): OrderByPayload => ({

View File

@@ -5,6 +5,7 @@ import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import Spinner from 'components/Spinner';
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { FontSize } from 'container/OptionsMenu/types';
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
import { useIsDarkMode } from 'hooks/useDarkMode';
@@ -167,6 +168,7 @@ function LogsContextList({
key={log.id}
data={log}
linesPerRow={1}
fontSize={FontSize.SMALL}
/>
),
[],

View File

@@ -2,6 +2,7 @@ import { EditFilled } from '@ant-design/icons';
import { Modal, Typography } from 'antd';
import RawLogView from 'components/Logs/RawLogView';
import LogsContextList from 'container/LogsContextList';
import { FontSize } from 'container/OptionsMenu/types';
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
import { useIsDarkMode } from 'hooks/useDarkMode';
@@ -99,6 +100,7 @@ function LogsExplorerContext({
isTextOverflowEllipsisDisabled
data={log}
linesPerRow={1}
fontSize={FontSize.SMALL}
/>
</LogContainer>
<LogsContextList

View File

@@ -3,6 +3,7 @@ import './TableRow.styles.scss';
import { ColumnsType } from 'antd/es/table';
import LogLinesActionButtons from 'components/Logs/LogLinesActionButtons/LogLinesActionButtons';
import { ColumnTypeRender } from 'components/Logs/TableView/types';
import { FontSize } from 'container/OptionsMenu/types';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
import { useIsDarkMode } from 'hooks/useDarkMode';
import {
@@ -24,6 +25,7 @@ interface TableRowProps {
handleSetActiveContextLog: (log: ILog) => void;
logs: ILog[];
hasActions: boolean;
fontSize: FontSize;
}
export default function TableRow({
@@ -33,6 +35,7 @@ export default function TableRow({
handleSetActiveContextLog,
logs,
hasActions,
fontSize,
}: TableRowProps): JSX.Element {
const isDarkMode = useIsDarkMode();
@@ -78,6 +81,7 @@ export default function TableRow({
$isDragColumn={false}
$isDarkMode={isDarkMode}
key={column.key}
fontSize={fontSize}
>
{cloneElement(children, props)}
</TableCellStyled>

View File

@@ -1,3 +1,5 @@
/* eslint-disable no-nested-ternary */
import { FontSize } from 'container/OptionsMenu/types';
import { CSSProperties } from 'react';
export const infinityDefaultStyles: CSSProperties = {
@@ -5,3 +7,16 @@ export const infinityDefaultStyles: CSSProperties = {
overflowX: 'scroll',
marginTop: '15px',
};
export function getInfinityDefaultStyles(fontSize: FontSize): CSSProperties {
return {
width: '100%',
overflowX: 'scroll',
marginTop:
fontSize === FontSize.SMALL
? '10px'
: fontSize === FontSize.MEDIUM
? '12px'
: '15px',
};
}

View File

@@ -15,7 +15,7 @@ import {
} from 'react-virtuoso';
import { ILog } from 'types/api/logs/log';
import { infinityDefaultStyles } from './config';
import { getInfinityDefaultStyles } from './config';
import { LogsCustomTable } from './LogsCustomTable';
import { TableHeaderCellStyled, TableRowStyled } from './styles';
import TableRow from './TableRow';
@@ -95,9 +95,15 @@ const InfinityTable = forwardRef<TableVirtuosoHandle, InfinityTableProps>(
handleSetActiveContextLog={handleSetActiveContextLog}
logs={tableViewProps.logs}
hasActions
fontSize={tableViewProps.fontSize}
/>
),
[handleSetActiveContextLog, tableColumns, tableViewProps.logs],
[
handleSetActiveContextLog,
tableColumns,
tableViewProps.fontSize,
tableViewProps.logs,
],
);
const tableHeader = useCallback(
@@ -112,6 +118,7 @@ const InfinityTable = forwardRef<TableVirtuosoHandle, InfinityTableProps>(
$isDarkMode={isDarkMode}
$isDragColumn={isDragColumn}
key={column.key}
fontSize={tableViewProps?.fontSize}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(isDragColumn && { className: 'dragHandler' })}
>
@@ -121,7 +128,7 @@ const InfinityTable = forwardRef<TableVirtuosoHandle, InfinityTableProps>(
})}
</tr>
),
[tableColumns, isDarkMode],
[tableColumns, isDarkMode, tableViewProps?.fontSize],
);
const handleClickExpand = (index: number): void => {
@@ -137,7 +144,7 @@ const InfinityTable = forwardRef<TableVirtuosoHandle, InfinityTableProps>(
initialTopMostItemIndex={
tableViewProps.activeLogIndex !== -1 ? tableViewProps.activeLogIndex : 0
}
style={infinityDefaultStyles}
style={getInfinityDefaultStyles(tableViewProps.fontSize)}
data={dataSource}
components={{
// eslint-disable-next-line react/jsx-props-no-spreading

View File

@@ -1,5 +1,7 @@
/* eslint-disable no-nested-ternary */
import { Color } from '@signozhq/design-tokens';
import { themeColors } from 'constants/theme';
import { FontSize } from 'container/OptionsMenu/types';
import styled from 'styled-components';
import { getActiveLogBackground } from 'utils/logs';
@@ -7,6 +9,7 @@ interface TableHeaderCellStyledProps {
$isDragColumn: boolean;
$isDarkMode: boolean;
$isTimestamp?: boolean;
fontSize?: FontSize;
}
export const TableStyled = styled.table`
@@ -15,6 +18,14 @@ export const TableStyled = styled.table`
export const TableCellStyled = styled.td<TableHeaderCellStyledProps>`
padding: 0.5rem;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `padding:0.3rem;`
: fontSize === FontSize.MEDIUM
? `padding:0.4rem;`
: fontSize === FontSize.LARGE
? `padding:0.5rem;`
: ``}
background-color: ${(props): string =>
props.$isDarkMode ? 'inherit' : themeColors.whiteCream};
@@ -33,7 +44,7 @@ export const TableRowStyled = styled.tr<{
? `background-color: ${
$isDarkMode ? Color.BG_SLATE_500 : Color.BG_VANILLA_300
} !important`
: ''}
: ''};
}
cursor: pointer;
@@ -66,9 +77,17 @@ export const TableHeaderCellStyled = styled.th<TableHeaderCellStyledProps>`
line-height: 18px;
letter-spacing: -0.07px;
background: ${(props): string => (props.$isDarkMode ? '#0b0c0d' : '#fdfdfd')};
${({ $isTimestamp }): string => ($isTimestamp ? 'padding-left: 24px;' : '')}
${({ $isDragColumn }): string => ($isDragColumn ? 'cursor: col-resize;' : '')}
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `font-size:11px; line-height:16px; padding: 0.1rem;`
: fontSize === FontSize.MEDIUM
? `font-size:13px; line-height:20px; padding:0.3rem;`
: fontSize === FontSize.LARGE
? `font-size:14px; line-height:24px; padding: 0.5rem;`
: ``};
${({ $isTimestamp }): string => ($isTimestamp ? 'padding-left: 24px;' : '')}
color: ${(props): string =>
props.$isDarkMode ? 'var(--bg-vanilla-100, #fff)' : themeColors.bckgGrey};
`;

View File

@@ -14,6 +14,7 @@ import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch';
import LogsError from 'container/LogsError/LogsError';
import { LogsLoading } from 'container/LogsLoading/LogsLoading';
import { useOptionsMenu } from 'container/OptionsMenu';
import { FontSize } from 'container/OptionsMenu/types';
import { useActiveLog } from 'hooks/logs/useActiveLog';
import { useCopyLogLink } from 'hooks/logs/useCopyLogLink';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
@@ -79,6 +80,7 @@ function LogsExplorerList({
data={log}
linesPerRow={options.maxLines}
selectedFields={selectedFields}
fontSize={options.fontSize}
/>
);
}
@@ -91,6 +93,7 @@ function LogsExplorerList({
onAddToQuery={onAddToQuery}
onSetActiveLog={onSetActiveLog}
activeLog={activeLog}
fontSize={options.fontSize}
linesPerRow={options.maxLines}
/>
);
@@ -99,6 +102,7 @@ function LogsExplorerList({
activeLog,
onAddToQuery,
onSetActiveLog,
options.fontSize,
options.format,
options.maxLines,
selectedFields,
@@ -121,6 +125,7 @@ function LogsExplorerList({
logs,
fields: selectedFields,
linesPerRow: options.maxLines,
fontSize: options.fontSize,
appendTo: 'end',
activeLogIndex,
}}
@@ -129,9 +134,22 @@ function LogsExplorerList({
);
}
function getMarginTop(): string {
switch (options.fontSize) {
case FontSize.SMALL:
return '10px';
case FontSize.MEDIUM:
return '12px';
case FontSize.LARGE:
return '15px';
default:
return '15px';
}
}
return (
<Card
style={{ width: '100%', marginTop: '20px' }}
style={{ width: '100%', marginTop: getMarginTop() }}
bodyStyle={CARD_BODY_STYLE}
>
<OverlayScrollbar isVirtuoso>
@@ -151,6 +169,7 @@ function LogsExplorerList({
isLoading,
options.format,
options.maxLines,
options.fontSize,
activeLogIndex,
logs,
onEndReached,

View File

@@ -10,6 +10,7 @@ import LogsTableView from 'components/Logs/TableView';
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import Spinner from 'components/Spinner';
import { CARD_BODY_STYLE } from 'constants/card';
import { FontSize } from 'container/OptionsMenu/types';
import { useActiveLog } from 'hooks/logs/useActiveLog';
import { memo, useCallback, useMemo } from 'react';
import { useSelector } from 'react-redux';
@@ -66,6 +67,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
data={log}
linesPerRow={linesPerRow}
selectedFields={selected}
fontSize={FontSize.SMALL}
/>
);
}
@@ -78,6 +80,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
linesPerRow={linesPerRow}
onAddToQuery={onAddToQuery}
onSetActiveLog={onSetActiveLog}
fontSize={FontSize.SMALL}
/>
);
},
@@ -92,6 +95,7 @@ function LogsTable(props: LogsTableProps): JSX.Element {
logs={logs}
fields={selected}
linesPerRow={linesPerRow}
fontSize={FontSize.SMALL}
/>
);
}

View File

@@ -1,6 +1,6 @@
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { OptionsQuery } from './types';
import { FontSize, OptionsQuery } from './types';
export const URL_OPTIONS = 'options';
@@ -8,6 +8,7 @@ export const defaultOptionsQuery: OptionsQuery = {
selectColumns: [],
maxLines: 2,
format: 'list',
fontSize: FontSize.SMALL,
};
export const defaultTraceSelectedColumns = [

View File

@@ -2,10 +2,21 @@ import { InputNumberProps, RadioProps, SelectProps } from 'antd';
import { LogViewMode } from 'container/LogsTable';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
export enum FontSize {
SMALL = 'small',
MEDIUM = 'medium',
LARGE = 'large',
}
interface FontSizeProps {
value: FontSize;
onChange: (val: FontSize) => void;
}
export interface OptionsQuery {
selectColumns: BaseAutocompleteData[];
maxLines: number;
format: LogViewMode;
fontSize: FontSize;
}
export interface InitialOptions
@@ -18,6 +29,7 @@ export type OptionsMenuConfig = {
onChange: (value: LogViewMode) => void;
};
maxLines?: Pick<InputNumberProps, 'value' | 'onChange'>;
fontSize?: FontSizeProps;
addColumn?: Pick<
SelectProps,
'options' | 'onSelect' | 'onFocus' | 'onSearch' | 'onBlur'

View File

@@ -21,7 +21,12 @@ import {
defaultTraceSelectedColumns,
URL_OPTIONS,
} from './constants';
import { InitialOptions, OptionsMenuConfig, OptionsQuery } from './types';
import {
FontSize,
InitialOptions,
OptionsMenuConfig,
OptionsQuery,
} from './types';
import { getOptionsFromKeys } from './utils';
interface UseOptionsMenuProps {
@@ -248,6 +253,17 @@ const useOptionsMenu = ({
},
[handleRedirectWithOptionsData, optionsQueryData],
);
const handleFontSizeChange = useCallback(
(value: FontSize) => {
const optionsData: OptionsQuery = {
...optionsQueryData,
fontSize: value,
};
handleRedirectWithOptionsData(optionsData);
},
[handleRedirectWithOptionsData, optionsQueryData],
);
const handleSearchAttribute = useCallback((value: string) => {
setSearchText(value);
@@ -282,18 +298,24 @@ const useOptionsMenu = ({
value: optionsQueryData.maxLines || defaultOptionsQuery.maxLines,
onChange: handleMaxLinesChange,
},
fontSize: {
value: optionsQueryData?.fontSize || defaultOptionsQuery.fontSize,
onChange: handleFontSizeChange,
},
}),
[
optionsFromAttributeKeys,
optionsQueryData?.maxLines,
optionsQueryData?.format,
optionsQueryData?.selectColumns,
isSearchedAttributesFetching,
handleSearchAttribute,
optionsQueryData?.selectColumns,
optionsQueryData.format,
optionsQueryData.maxLines,
optionsQueryData?.fontSize,
optionsFromAttributeKeys,
handleSelectColumns,
handleRemoveSelectedColumn,
handleSearchAttribute,
handleFormatChange,
handleMaxLinesChange,
handleFontSizeChange,
],
);