feat: add support to pin attributes in logs details view (#4692)

* feat: add support to pin attributes in logs details view

* feat: add safety checks

* feat: update styles

* feat: update styles

* feat: move json parsing in try catch block
This commit is contained in:
Yunus M 2024-03-28 16:55:59 +05:30 committed by GitHub
parent 6014bb76b6
commit 9f30bba9a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 158 additions and 8 deletions

View File

@ -17,4 +17,5 @@ export enum LOCALSTORAGE {
IS_IDENTIFIED_USER = 'IS_IDENTIFIED_USER',
DASHBOARD_VARIABLES = 'DASHBOARD_VARIABLES',
SHOW_EXPLORER_TOOLBAR = 'SHOW_EXPLORER_TOOLBAR',
PINNED_ATTRIBUTES = 'PINNED_ATTRIBUTES',
}

View File

@ -53,6 +53,19 @@
background: rgba(171, 189, 255, 0.04);
padding: 8px;
.ant-collapse-extra {
display: flex;
align-items: center;
.action-btn {
display: flex;
.ant-btn {
background: rgba(113, 144, 249, 0.08);
}
}
}
}
.ant-collapse-content {

View File

@ -5,12 +5,13 @@
.ant-table-row:hover {
.ant-table-cell {
.value-field {
display: flex;
justify-content: space-between;
align-items: center;
.action-btn {
display: flex;
gap: 4px;
position: absolute;
top: 50%;
right: 16px;
transform: translateY(-50%);
gap: 8px;
}
}
}
@ -28,6 +29,30 @@
}
}
.attribute-pin {
cursor: pointer;
padding: 0;
vertical-align: middle;
text-align: center;
.log-attribute-pin {
padding: 8px;
display: flex;
justify-content: center;
align-items: center;
.pin-attribute-icon {
border: none;
&.pinned svg {
fill: var(--bg-robin-500);
}
}
}
}
.value-field-container {
background: rgba(22, 25, 34, 0.4);
@ -70,6 +95,10 @@
.value-field-container {
background: var(--bg-vanilla-300);
&.attribute-pin {
background: var(--bg-vanilla-100);
}
.action-btn {
.filter-btn {
background: var(--bg-vanilla-300);

View File

@ -1,22 +1,29 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import './TableView.styles.scss';
import { LinkOutlined } from '@ant-design/icons';
import { Color } from '@signozhq/design-tokens';
import { Button, Space, Spin, Tooltip, Tree, Typography } from 'antd';
import { ColumnsType } from 'antd/es/table';
import getLocalStorageApi from 'api/browser/localstorage/get';
import setLocalStorageApi from 'api/browser/localstorage/set';
import cx from 'classnames';
import AddToQueryHOC, {
AddToQueryHOCProps,
} from 'components/Logs/AddToQueryHOC';
import CopyClipboardHOC from 'components/Logs/CopyClipboardHOC';
import { ResizeTable } from 'components/ResizeTable';
import { LOCALSTORAGE } from 'constants/localStorage';
import { OPERATORS } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import { useIsDarkMode } from 'hooks/useDarkMode';
import history from 'lib/history';
import { fieldSearchFilter } from 'lib/logs/fieldSearch';
import { removeJSONStringifyQuotes } from 'lib/removeJSONStringifyQuotes';
import { isEmpty } from 'lodash-es';
import { ArrowDownToDot, ArrowUpFromDot } from 'lucide-react';
import { useMemo, useState } from 'react';
import { ArrowDownToDot, ArrowUpFromDot, Pin } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';
import { generatePath } from 'react-router-dom';
import { Dispatch } from 'redux';
@ -57,6 +64,28 @@ function TableView({
const dispatch = useDispatch<Dispatch<AppActions>>();
const [isfilterInLoading, setIsFilterInLoading] = useState<boolean>(false);
const [isfilterOutLoading, setIsFilterOutLoading] = useState<boolean>(false);
const isDarkMode = useIsDarkMode();
const [pinnedAttributes, setPinnedAttributes] = useState<
Record<string, boolean>
>({});
useEffect(() => {
const pinnedAttributesFromLocalStorage = getLocalStorageApi(
LOCALSTORAGE.PINNED_ATTRIBUTES,
);
if (pinnedAttributesFromLocalStorage) {
try {
const parsedPinnedAttributes = JSON.parse(pinnedAttributesFromLocalStorage);
setPinnedAttributes(parsedPinnedAttributes);
} catch (e) {
console.error('Error parsing pinned attributes from local storgage');
}
} else {
setPinnedAttributes({});
}
}, []);
const flattenLogData: Record<string, string> | null = useMemo(
() => (logData ? flattenObject(logData) : null),
@ -74,6 +103,19 @@ function TableView({
}
};
const togglePinAttribute = (record: DataType): void => {
if (record) {
const newPinnedAttributes = { ...pinnedAttributes };
newPinnedAttributes[record.key] = !newPinnedAttributes[record.key];
setPinnedAttributes(newPinnedAttributes);
setLocalStorageApi(
LOCALSTORAGE.PINNED_ATTRIBUTES,
JSON.stringify(newPinnedAttributes),
);
}
};
const onClickHandler = (
operator: string,
fieldKey: string,
@ -138,6 +180,37 @@ function TableView({
}
const columns: ColumnsType<DataType> = [
{
title: '',
dataIndex: 'pin',
key: 'pin',
width: 5,
align: 'left',
className: 'attribute-pin value-field-container',
render: (fieldData: Record<string, string>, record): JSX.Element => {
let pinColor = isDarkMode ? Color.BG_VANILLA_100 : Color.BG_INK_500;
if (pinnedAttributes[record?.key]) {
pinColor = Color.BG_ROBIN_500;
}
return (
<div className="log-attribute-pin value-field">
<div
className={cx(
'pin-attribute-icon',
pinnedAttributes[record?.key] ? 'pinned' : '',
)}
onClick={(): void => {
togglePinAttribute(record);
}}
>
<Pin size={14} color={pinColor} />
</div>
</div>
);
},
},
{
title: 'Field',
dataIndex: 'field',
@ -264,12 +337,34 @@ function TableView({
},
},
];
function sortPinnedAttributes(
data: Record<string, string>[],
sortingObj: Record<string, boolean>,
): Record<string, string>[] {
const sortingKeys = Object.keys(sortingObj);
return data.sort((a, b) => {
const aKey = a.key;
const bKey = b.key;
const aSortIndex = sortingKeys.indexOf(aKey);
const bSortIndex = sortingKeys.indexOf(bKey);
if (sortingObj[aKey] && !sortingObj[bKey]) {
return -1;
}
if (!sortingObj[aKey] && sortingObj[bKey]) {
return 1;
}
return aSortIndex - bSortIndex;
});
}
const sortedAttributes = sortPinnedAttributes(dataSource, pinnedAttributes);
return (
<ResizeTable
columns={columns}
tableLayout="fixed"
dataSource={dataSource}
dataSource={sortedAttributes}
pagination={false}
showHeader={false}
className="attribute-table-container"

View File

@ -8,6 +8,10 @@
.resource-attributes-selector {
flex: 1;
border-radius: 3px;
background-color: var(--bg-ink-400);
border: 1px solid #454c58;
}
.environment-selector {
@ -18,3 +22,12 @@
margin-bottom: 0;
}
}
.lightMode {
.resourceAttributesFilter-container {
.resource-attributes-selector {
border: 1px solid #d9d9d9;
background: var(--bg-vanilla-100);
}
}
}

View File

@ -8,7 +8,6 @@ export const SearchContainer = styled.div`
align-items: center;
gap: 0.2rem;
padding: 0 0.2rem;
border: 1px solid #454c58;
box-sizing: border-box;
border-radius: 3px;
`;