mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 10:49:03 +08:00
Implement OverlayScrollbars throughout the app for MacOS-like scrolling experience (#5423)
* feat: build overlay scrollbar component for Virtuoso elements * feat: apply overlay scroll to Virtuoso components * feat: build overlay scrollbar component for normal scrollable sections * feat: apply overlay scrollbar to normal scrollable sections * feat: add dark mode UI support to overlay scrollbars * chore: rename OverlayScrollbar to OverlayScrollbarForTypicalChildren * chore: move inline style to scss file * chore: rename VirtuosoOverlayScrollbar to OverlayScrollbarForVirtuosoChildren * chore: move OverlayScrollbarForTypicalChildren to components folder * chore: create a common component for handling Virtuoso and Typical scroll sections * chore: rename Virtuoso and Typical Overlay Scrollbar components * fix: fix the overlay scrollbar initialization flickering * fix: remove calculated height from typical overlay scrollbar + remove the explicit height: 100%
This commit is contained in:
parent
46e6c34e51
commit
cd07c743b6
@ -110,6 +110,8 @@
|
|||||||
"react-syntax-highlighter": "15.5.0",
|
"react-syntax-highlighter": "15.5.0",
|
||||||
"react-use": "^17.3.2",
|
"react-use": "^17.3.2",
|
||||||
"react-virtuoso": "4.0.3",
|
"react-virtuoso": "4.0.3",
|
||||||
|
"overlayscrollbars-react": "^0.5.6",
|
||||||
|
"overlayscrollbars": "^2.8.1",
|
||||||
"redux": "^4.0.5",
|
"redux": "^4.0.5",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"rehype-raw": "7.0.0",
|
"rehype-raw": "7.0.0",
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
import TypicalOverlayScrollbar from 'components/TypicalOverlayScrollbar/TypicalOverlayScrollbar';
|
||||||
|
import VirtuosoOverlayScrollbar from 'components/VirtuosoOverlayScrollbar/VirtuosoOverlayScrollbar';
|
||||||
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { PartialOptions } from 'overlayscrollbars';
|
||||||
|
import { CSSProperties, ReactElement, useMemo } from 'react';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: ReactElement;
|
||||||
|
isVirtuoso?: boolean;
|
||||||
|
style?: CSSProperties;
|
||||||
|
options?: PartialOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
function OverlayScrollbar({
|
||||||
|
children,
|
||||||
|
isVirtuoso,
|
||||||
|
style,
|
||||||
|
options: customOptions,
|
||||||
|
}: Props): any {
|
||||||
|
const isDarkMode = useIsDarkMode();
|
||||||
|
const options = useMemo(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
scrollbars: {
|
||||||
|
autoHide: 'scroll',
|
||||||
|
theme: isDarkMode ? 'os-theme-light' : 'os-theme-dark',
|
||||||
|
},
|
||||||
|
...(customOptions || {}),
|
||||||
|
} as PartialOptions),
|
||||||
|
[customOptions, isDarkMode],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isVirtuoso) {
|
||||||
|
return (
|
||||||
|
<VirtuosoOverlayScrollbar style={style} options={options}>
|
||||||
|
{children}
|
||||||
|
</VirtuosoOverlayScrollbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TypicalOverlayScrollbar style={style} options={options}>
|
||||||
|
{children}
|
||||||
|
</TypicalOverlayScrollbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayScrollbar.defaultProps = {
|
||||||
|
isVirtuoso: false,
|
||||||
|
style: {},
|
||||||
|
options: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OverlayScrollbar;
|
@ -0,0 +1,31 @@
|
|||||||
|
import './typicalOverlayScrollbar.scss';
|
||||||
|
|
||||||
|
import { PartialOptions } from 'overlayscrollbars';
|
||||||
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||||
|
import { CSSProperties, ReactElement } from 'react';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ReactElement;
|
||||||
|
style?: CSSProperties;
|
||||||
|
options?: PartialOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TypicalOverlayScrollbar({
|
||||||
|
children,
|
||||||
|
style,
|
||||||
|
options,
|
||||||
|
}: Props): ReturnType<typeof OverlayScrollbarsComponent> {
|
||||||
|
return (
|
||||||
|
<OverlayScrollbarsComponent
|
||||||
|
defer
|
||||||
|
options={options}
|
||||||
|
style={style}
|
||||||
|
className="overlay-scrollbar"
|
||||||
|
data-overlayscrollbars-initialize
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</OverlayScrollbarsComponent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypicalOverlayScrollbar.defaultProps = { style: {}, options: {} };
|
@ -0,0 +1,3 @@
|
|||||||
|
.overlay-scrollbar {
|
||||||
|
height: 100%;
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import './virtuosoOverlayScrollbar.scss';
|
||||||
|
|
||||||
|
import useInitializeOverlayScrollbar from 'hooks/useInitializeOverlayScrollbar/useInitializeOverlayScrollbar';
|
||||||
|
import { PartialOptions } from 'overlayscrollbars';
|
||||||
|
import React, { CSSProperties, ReactElement } from 'react';
|
||||||
|
|
||||||
|
interface VirtuosoOverlayScrollbarProps {
|
||||||
|
children: ReactElement;
|
||||||
|
style?: CSSProperties;
|
||||||
|
options: PartialOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function VirtuosoOverlayScrollbar({
|
||||||
|
children,
|
||||||
|
style,
|
||||||
|
options,
|
||||||
|
}: VirtuosoOverlayScrollbarProps): JSX.Element {
|
||||||
|
const { rootRef, setScroller } = useInitializeOverlayScrollbar(options);
|
||||||
|
|
||||||
|
const enhancedChild = React.cloneElement(children, {
|
||||||
|
scrollerRef: setScroller,
|
||||||
|
'data-overlayscrollbars-initialize': true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-overlayscrollbars-initialize
|
||||||
|
ref={rootRef}
|
||||||
|
className="overlay-scroll-wrapper"
|
||||||
|
style={style}
|
||||||
|
>
|
||||||
|
{enhancedChild}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtuosoOverlayScrollbar.defaultProps = { style: {} };
|
@ -0,0 +1,5 @@
|
|||||||
|
.overlay-scroll-wrapper {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
.app-content {
|
.app-content {
|
||||||
width: calc(100% - 64px);
|
width: calc(100% - 64px);
|
||||||
overflow: auto;
|
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
|
@ -9,6 +9,7 @@ import getLocalStorageKey from 'api/browser/localstorage/get';
|
|||||||
import getUserLatestVersion from 'api/user/getLatestVersion';
|
import getUserLatestVersion from 'api/user/getLatestVersion';
|
||||||
import getUserVersion from 'api/user/getVersion';
|
import getUserVersion from 'api/user/getVersion';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import SideNav from 'container/SideNav';
|
import SideNav from 'container/SideNav';
|
||||||
@ -303,9 +304,13 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
collapsed={collapsed}
|
collapsed={collapsed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className={cx('app-content', collapsed ? 'collapsed' : '')}>
|
<div
|
||||||
|
className={cx('app-content', collapsed ? 'collapsed' : '')}
|
||||||
|
data-overlayscrollbars-initialize
|
||||||
|
>
|
||||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||||
<LayoutContent>
|
<LayoutContent data-overlayscrollbars-initialize>
|
||||||
|
<OverlayScrollbar>
|
||||||
<ChildrenContainer
|
<ChildrenContainer
|
||||||
style={{
|
style={{
|
||||||
margin:
|
margin:
|
||||||
@ -321,6 +326,7 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
{isToDisplayLayout && !renderFullScreen && <TopNav />}
|
{isToDisplayLayout && !renderFullScreen && <TopNav />}
|
||||||
{children}
|
{children}
|
||||||
</ChildrenContainer>
|
</ChildrenContainer>
|
||||||
|
</OverlayScrollbar>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</Sentry.ErrorBoundary>
|
</Sentry.ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,6 @@ export const Layout = styled(LayoutComponent)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const LayoutContent = styled(LayoutComponent.Content)`
|
export const LayoutContent = styled(LayoutComponent.Content)`
|
||||||
overflow-y: auto;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 0.1rem;
|
width: 0.1rem;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
.fullscreen-grid-container {
|
.fullscreen-grid-container {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
margin: 8px -8px;
|
margin: 8px -8px;
|
||||||
|
margin-right: 0;
|
||||||
|
|
||||||
.react-grid-layout {
|
.react-grid-layout {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
|
@ -428,7 +428,11 @@ function GraphLayout(props: GraphLayoutProps): JSX.Element {
|
|||||||
return isDashboardEmpty ? (
|
return isDashboardEmpty ? (
|
||||||
<DashboardEmptyState />
|
<DashboardEmptyState />
|
||||||
) : (
|
) : (
|
||||||
<FullScreen handle={handle} className="fullscreen-grid-container">
|
<FullScreen
|
||||||
|
handle={handle}
|
||||||
|
className="fullscreen-grid-container"
|
||||||
|
data-overlayscrollbars-initialize
|
||||||
|
>
|
||||||
<ReactGridLayout
|
<ReactGridLayout
|
||||||
cols={12}
|
cols={12}
|
||||||
rowHeight={45}
|
rowHeight={45}
|
||||||
|
@ -3,6 +3,7 @@ import LogDetail from 'components/LogDetail';
|
|||||||
import { VIEW_TYPES } from 'components/LogDetail/constants';
|
import { VIEW_TYPES } from 'components/LogDetail/constants';
|
||||||
import ListLogView from 'components/Logs/ListLogView';
|
import ListLogView from 'components/Logs/ListLogView';
|
||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { CARD_BODY_STYLE } from 'constants/card';
|
import { CARD_BODY_STYLE } from 'constants/card';
|
||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
@ -128,6 +129,7 @@ function LiveLogsList({ logs }: LiveLogsListProps): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Card style={{ width: '100%' }} bodyStyle={CARD_BODY_STYLE}>
|
<Card style={{ width: '100%' }} bodyStyle={CARD_BODY_STYLE}>
|
||||||
|
<OverlayScrollbar isVirtuoso>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
ref={ref}
|
ref={ref}
|
||||||
initialTopMostItemIndex={activeLogIndex !== -1 ? activeLogIndex : 0}
|
initialTopMostItemIndex={activeLogIndex !== -1 ? activeLogIndex : 0}
|
||||||
@ -135,6 +137,7 @@ function LiveLogsList({ logs }: LiveLogsListProps): JSX.Element {
|
|||||||
totalCount={logs.length}
|
totalCount={logs.length}
|
||||||
itemContent={getItemContent}
|
itemContent={getItemContent}
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
</InfinityWrapperStyled>
|
</InfinityWrapperStyled>
|
||||||
|
@ -2,6 +2,7 @@ import './ContextLogRenderer.styles.scss';
|
|||||||
|
|
||||||
import { Skeleton } from 'antd';
|
import { Skeleton } from 'antd';
|
||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import ShowButton from 'container/LogsContextList/ShowButton';
|
import ShowButton from 'container/LogsContextList/ShowButton';
|
||||||
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
import { ORDERBY_FILTERS } from 'container/QueryBuilder/filters/OrderByFilter/config';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
@ -94,6 +95,7 @@ function ContextLogRenderer({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<OverlayScrollbar isVirtuoso>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
className="virtuoso-list"
|
className="virtuoso-list"
|
||||||
initialTopMostItemIndex={0}
|
initialTopMostItemIndex={0}
|
||||||
@ -101,6 +103,7 @@ function ContextLogRenderer({
|
|||||||
itemContent={getItemContent}
|
itemContent={getItemContent}
|
||||||
style={{ height: `calc(${logs.length} * 32px)` }}
|
style={{ height: `calc(${logs.length} * 32px)` }}
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
{isAfterLogsFetching && (
|
{isAfterLogsFetching && (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
style={{
|
style={{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import './LogsContextList.styles.scss';
|
import './LogsContextList.styles.scss';
|
||||||
|
|
||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
|
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
@ -187,7 +188,7 @@ function LogsContextList({
|
|||||||
<EmptyText>No Data</EmptyText>
|
<EmptyText>No Data</EmptyText>
|
||||||
)}
|
)}
|
||||||
{isFetching && <Spinner size="large" height="10rem" />}
|
{isFetching && <Spinner size="large" height="10rem" />}
|
||||||
|
<OverlayScrollbar isVirtuoso>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
className="virtuoso-list"
|
className="virtuoso-list"
|
||||||
initialTopMostItemIndex={0}
|
initialTopMostItemIndex={0}
|
||||||
@ -195,6 +196,7 @@ function LogsContextList({
|
|||||||
itemContent={getItemContent}
|
itemContent={getItemContent}
|
||||||
followOutput={order === ORDERBY_FILTERS.DESC}
|
followOutput={order === ORDERBY_FILTERS.DESC}
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
</ListContainer>
|
</ListContainer>
|
||||||
|
|
||||||
{order === ORDERBY_FILTERS.DESC && (
|
{order === ORDERBY_FILTERS.DESC && (
|
||||||
|
@ -6,6 +6,7 @@ import { VIEW_TYPES } from 'components/LogDetail/constants';
|
|||||||
// components
|
// components
|
||||||
import ListLogView from 'components/Logs/ListLogView';
|
import ListLogView from 'components/Logs/ListLogView';
|
||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { CARD_BODY_STYLE } from 'constants/card';
|
import { CARD_BODY_STYLE } from 'constants/card';
|
||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
@ -133,6 +134,7 @@ function LogsExplorerList({
|
|||||||
style={{ width: '100%', marginTop: '20px' }}
|
style={{ width: '100%', marginTop: '20px' }}
|
||||||
bodyStyle={CARD_BODY_STYLE}
|
bodyStyle={CARD_BODY_STYLE}
|
||||||
>
|
>
|
||||||
|
<OverlayScrollbar isVirtuoso>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
ref={ref}
|
ref={ref}
|
||||||
initialTopMostItemIndex={activeLogIndex !== -1 ? activeLogIndex : 0}
|
initialTopMostItemIndex={activeLogIndex !== -1 ? activeLogIndex : 0}
|
||||||
@ -142,6 +144,7 @@ function LogsExplorerList({
|
|||||||
itemContent={getItemContent}
|
itemContent={getItemContent}
|
||||||
components={components}
|
components={components}
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
|
@ -3,6 +3,7 @@ import './LogsPanelComponent.styles.scss';
|
|||||||
import { Table } from 'antd';
|
import { Table } from 'antd';
|
||||||
import LogDetail from 'components/LogDetail';
|
import LogDetail from 'components/LogDetail';
|
||||||
import { VIEW_TYPES } from 'components/LogDetail/constants';
|
import { VIEW_TYPES } from 'components/LogDetail/constants';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import Controls from 'container/Controls';
|
import Controls from 'container/Controls';
|
||||||
@ -207,6 +208,7 @@ function LogsPanelComponent({
|
|||||||
<>
|
<>
|
||||||
<div className="logs-table">
|
<div className="logs-table">
|
||||||
<div className="resize-table">
|
<div className="resize-table">
|
||||||
|
<OverlayScrollbar>
|
||||||
<Table
|
<Table
|
||||||
pagination={false}
|
pagination={false}
|
||||||
tableLayout="fixed"
|
tableLayout="fixed"
|
||||||
@ -218,6 +220,7 @@ function LogsPanelComponent({
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
onRow={handleRow}
|
onRow={handleRow}
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
</div>
|
</div>
|
||||||
{!widget.query.builder.queryData[0].limit && (
|
{!widget.query.builder.queryData[0].limit && (
|
||||||
<div className="controller">
|
<div className="controller">
|
||||||
|
@ -7,6 +7,7 @@ import { VIEW_TYPES } from 'components/LogDetail/constants';
|
|||||||
import ListLogView from 'components/Logs/ListLogView';
|
import ListLogView from 'components/Logs/ListLogView';
|
||||||
import RawLogView from 'components/Logs/RawLogView';
|
import RawLogView from 'components/Logs/RawLogView';
|
||||||
import LogsTableView from 'components/Logs/TableView';
|
import LogsTableView from 'components/Logs/TableView';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import Spinner from 'components/Spinner';
|
import Spinner from 'components/Spinner';
|
||||||
import { CARD_BODY_STYLE } from 'constants/card';
|
import { CARD_BODY_STYLE } from 'constants/card';
|
||||||
import { useActiveLog } from 'hooks/logs/useActiveLog';
|
import { useActiveLog } from 'hooks/logs/useActiveLog';
|
||||||
@ -97,7 +98,9 @@ function LogsTable(props: LogsTableProps): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="logs-card" bodyStyle={CARD_BODY_STYLE}>
|
<Card className="logs-card" bodyStyle={CARD_BODY_STYLE}>
|
||||||
|
<OverlayScrollbar isVirtuoso>
|
||||||
<Virtuoso totalCount={logs.length} itemContent={getItemContent} />
|
<Virtuoso totalCount={logs.length} itemContent={getItemContent} />
|
||||||
|
</OverlayScrollbar>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}, [getItemContent, linesPerRow, logs, onSetActiveLog, selected, viewMode]);
|
}, [getItemContent, linesPerRow, logs, onSetActiveLog, selected, viewMode]);
|
||||||
|
@ -2,6 +2,7 @@ import './Description.styles.scss';
|
|||||||
|
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import ConfigureIcon from 'assets/Integrations/ConfigureIcon';
|
import ConfigureIcon from 'assets/Integrations/ConfigureIcon';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
import DashboardSettingsContent from '../DashboardSettings';
|
import DashboardSettingsContent from '../DashboardSettings';
|
||||||
@ -41,7 +42,9 @@ function SettingsDrawer({ drawerTitle }: { drawerTitle: string }): JSX.Element {
|
|||||||
open={visible}
|
open={visible}
|
||||||
rootClassName="settings-container-root"
|
rootClassName="settings-container-root"
|
||||||
>
|
>
|
||||||
|
<OverlayScrollbar>
|
||||||
<DashboardSettingsContent variableViewModeRef={variableViewModeRef} />
|
<DashboardSettingsContent variableViewModeRef={variableViewModeRef} />
|
||||||
|
</OverlayScrollbar>
|
||||||
</DrawerContainer>
|
</DrawerContainer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,7 @@ import GridGraphs from './GridGraphs';
|
|||||||
function NewDashboard(): JSX.Element {
|
function NewDashboard(): JSX.Element {
|
||||||
const handle = useFullScreenHandle();
|
const handle = useFullScreenHandle();
|
||||||
return (
|
return (
|
||||||
<div style={{ overflowX: 'hidden' }}>
|
<div>
|
||||||
<Description handle={handle} />
|
<Description handle={handle} />
|
||||||
<GridGraphs handle={handle} />
|
<GridGraphs handle={handle} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,6 +5,7 @@ import { WarningOutlined } from '@ant-design/icons';
|
|||||||
import { Button, Flex, Modal, Space, Tooltip, Typography } from 'antd';
|
import { Button, Flex, Modal, Space, Tooltip, Typography } from 'antd';
|
||||||
import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn';
|
import FacingIssueBtn from 'components/facingIssueBtn/FacingIssueBtn';
|
||||||
import { chartHelpMessage } from 'components/facingIssueBtn/util';
|
import { chartHelpMessage } from 'components/facingIssueBtn/util';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import { FeatureKeys } from 'constants/features';
|
import { FeatureKeys } from 'constants/features';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
@ -586,6 +587,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
|
|
||||||
<PanelContainer>
|
<PanelContainer>
|
||||||
<LeftContainerWrapper isDarkMode={useIsDarkMode()}>
|
<LeftContainerWrapper isDarkMode={useIsDarkMode()}>
|
||||||
|
<OverlayScrollbar>
|
||||||
{selectedWidget && (
|
{selectedWidget && (
|
||||||
<LeftContainer
|
<LeftContainer
|
||||||
selectedGraph={graphType}
|
selectedGraph={graphType}
|
||||||
@ -600,9 +602,11 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
isLoadingPanelData={isLoadingPanelData}
|
isLoadingPanelData={isLoadingPanelData}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</OverlayScrollbar>
|
||||||
</LeftContainerWrapper>
|
</LeftContainerWrapper>
|
||||||
|
|
||||||
<RightContainerWrapper>
|
<RightContainerWrapper>
|
||||||
|
<OverlayScrollbar>
|
||||||
<RightContainer
|
<RightContainer
|
||||||
setGraphHandler={setGraphHandler}
|
setGraphHandler={setGraphHandler}
|
||||||
title={title}
|
title={title}
|
||||||
@ -640,6 +644,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
|
|||||||
softMax={softMax}
|
softMax={softMax}
|
||||||
setSoftMax={setSoftMax}
|
setSoftMax={setSoftMax}
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
</RightContainerWrapper>
|
</RightContainerWrapper>
|
||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import './TracesTableComponent.styles.scss';
|
import './TracesTableComponent.styles.scss';
|
||||||
|
|
||||||
import { Table } from 'antd';
|
import { Table } from 'antd';
|
||||||
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
||||||
import Controls from 'container/Controls';
|
import Controls from 'container/Controls';
|
||||||
import { PER_PAGE_OPTIONS } from 'container/TracesExplorer/ListView/configs';
|
import { PER_PAGE_OPTIONS } from 'container/TracesExplorer/ListView/configs';
|
||||||
@ -86,6 +87,7 @@ function TracesTableComponent({
|
|||||||
return (
|
return (
|
||||||
<div className="traces-table">
|
<div className="traces-table">
|
||||||
<div className="resize-table">
|
<div className="resize-table">
|
||||||
|
<OverlayScrollbar>
|
||||||
<Table
|
<Table
|
||||||
pagination={false}
|
pagination={false}
|
||||||
tableLayout="fixed"
|
tableLayout="fixed"
|
||||||
@ -97,6 +99,7 @@ function TracesTableComponent({
|
|||||||
onRow={handleRow}
|
onRow={handleRow}
|
||||||
sticky
|
sticky
|
||||||
/>
|
/>
|
||||||
|
</OverlayScrollbar>
|
||||||
</div>
|
</div>
|
||||||
<div className="controller">
|
<div className="controller">
|
||||||
<Controls
|
<Controls
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
import { PartialOptions } from 'overlayscrollbars';
|
||||||
|
import { useOverlayScrollbars } from 'overlayscrollbars-react';
|
||||||
|
import {
|
||||||
|
Dispatch,
|
||||||
|
RefObject,
|
||||||
|
SetStateAction,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
|
const useInitializeOverlayScrollbar = (
|
||||||
|
options: PartialOptions,
|
||||||
|
): {
|
||||||
|
setScroller: Dispatch<SetStateAction<null>>;
|
||||||
|
rootRef: RefObject<HTMLDivElement>;
|
||||||
|
} => {
|
||||||
|
const rootRef = useRef(null);
|
||||||
|
const [scroller, setScroller] = useState(null);
|
||||||
|
const [initialize, osInstance] = useOverlayScrollbars({
|
||||||
|
defer: true,
|
||||||
|
options,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const { current: root } = rootRef;
|
||||||
|
|
||||||
|
if (scroller && root) {
|
||||||
|
initialize({
|
||||||
|
target: root,
|
||||||
|
elements: {
|
||||||
|
viewport: scroller,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (): void => osInstance()?.destroy();
|
||||||
|
}, [scroller, initialize, osInstance]);
|
||||||
|
|
||||||
|
return { setScroller, rootRef };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useInitializeOverlayScrollbar;
|
@ -1,4 +1,5 @@
|
|||||||
@import '@signozhq/design-tokens/dist/style.css';
|
@import '@signozhq/design-tokens/dist/style.css';
|
||||||
|
@import 'overlayscrollbars/overlayscrollbars.css';
|
||||||
|
|
||||||
@import './periscope.scss';
|
@import './periscope.scss';
|
||||||
|
|
||||||
|
@ -13028,6 +13028,16 @@ outvariant@^1.2.1, outvariant@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.0.tgz#e742e4bda77692da3eca698ef5bfac62d9fba06e"
|
resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.0.tgz#e742e4bda77692da3eca698ef5bfac62d9fba06e"
|
||||||
integrity sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==
|
integrity sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==
|
||||||
|
|
||||||
|
overlayscrollbars-react@^0.5.6:
|
||||||
|
version "0.5.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/overlayscrollbars-react/-/overlayscrollbars-react-0.5.6.tgz#e9779f9fc2c1a3288570a45c83f8e42518bfb8c1"
|
||||||
|
integrity sha512-E5To04bL5brn9GVCZ36SnfGanxa2I2MDkWoa4Cjo5wol7l+diAgi4DBc983V7l2nOk/OLJ6Feg4kySspQEGDBw==
|
||||||
|
|
||||||
|
overlayscrollbars@^2.8.1:
|
||||||
|
version "2.9.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-2.9.2.tgz#056020a3811742b58b754fab6f775d49bd109be9"
|
||||||
|
integrity sha512-iDT84r39i7oWP72diZN2mbJUsn/taCq568aQaIrc84S87PunBT7qtsVltAF2esk7ORTRjQDnfjVYoqqTzgs8QA==
|
||||||
|
|
||||||
p-limit@^2.2.0:
|
p-limit@^2.2.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
|
resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
|
||||||
@ -14678,7 +14688,7 @@ react-use@17.4.0, react-use@^17.3.2:
|
|||||||
|
|
||||||
react-virtuoso@4.0.3:
|
react-virtuoso@4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.0.3.tgz"
|
resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.0.3.tgz#0dc8b10978095852d985b064157639b9fb9d9b1e"
|
||||||
integrity sha512-tyqt8FBWxO+smve/kUgJbhCI2MEOvH2hHgFYPKWBMA2cJmV+cHIDDh1BL/6w4pg/dcCdlHCNVwi6aiztPxWttw==
|
integrity sha512-tyqt8FBWxO+smve/kUgJbhCI2MEOvH2hHgFYPKWBMA2cJmV+cHIDDh1BL/6w4pg/dcCdlHCNVwi6aiztPxWttw==
|
||||||
|
|
||||||
react@18.2.0:
|
react@18.2.0:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user