Skip to content

Commit

Permalink
feat: open left nav items in new tab on cmd ctrl click
Browse files Browse the repository at this point in the history
  • Loading branch information
YounixM committed Feb 17, 2024
1 parent b10f17d commit bb3e39d
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 51 deletions.
4 changes: 2 additions & 2 deletions frontend/src/AppRoutes/Private.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { UPDATE_USER_IS_FETCH } from 'types/actions/app';
import AppReducer from 'types/reducer/app';
import { routePermission } from 'utils/permission';

import routes from './routes';
import routes, { LIST_LICENSES } from './routes';
import afterLogin from './utils';

function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
Expand All @@ -29,7 +29,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
const mapRoutes = useMemo(
() =>
new Map(
routes.map((e) => {
[...routes, LIST_LICENSES].map((e) => {
const currentPath = matchPath(pathname, {
path: e.path,
});
Expand Down
25 changes: 18 additions & 7 deletions frontend/src/container/LogDetailedView/TableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ function TableView({
value: JSON.stringify(flattenLogData[key]),
}));

const onTraceHandler = (record: DataType) => (): void => {
const onTraceHandler = (
record: DataType,
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
) => (): void => {
if (flattenLogData === null) return;

const traceId = flattenLogData[record.field];
Expand All @@ -119,7 +122,12 @@ function TableView({

const route = spanId ? `${basePath}?spanId=${spanId}` : basePath;

history.push(route);
if (event.ctrlKey || event.metaKey) {
// open the trace in new tab
window.open(route, '_blank');
} else {
history.push(route);
}
}
};

Expand Down Expand Up @@ -148,17 +156,20 @@ function TableView({

{traceId && (
<Tooltip title="Inspect in Trace">
<div
style={{ cursor: 'pointer' }}
role="presentation"
onClick={onTraceHandler(record)}
<Button
className="periscope-btn"
onClick={(
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
): void => {
onTraceHandler(record, event);
}}
>
<LinkOutlined
style={{
width: '15px',
}}
/>
</div>
</Button>
</Tooltip>
)}
</Space>
Expand Down
17 changes: 15 additions & 2 deletions frontend/src/container/LogsError/LogsError.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import './LogsError.styles.scss';

import { Typography } from 'antd';
import history from 'lib/history';
import { ArrowRight } from 'lucide-react';
import { isCloudUser } from 'utils/app';

export default function LogsError(): JSX.Element {
const handleContactSupport = (): void => {
if (isCloudUser()) {
history.push('/support');
} else {
window.open('https://signoz.io/slack', '_blank');
}
};
return (
<div className="logs-error-container">
<div className="logs-error-content">
Expand All @@ -16,10 +27,12 @@ export default function LogsError(): JSX.Element {
<span className="aww-snap">Aw snap :/ </span> Something went wrong. Please
try again or contact support.
</Typography.Text>
<section className="contact-support">

<div className="contact-support" onClick={handleContactSupport}>
<Typography.Link className="text">Contact Support </Typography.Link>

<ArrowRight size={14} />
</section>
</div>
</div>
</div>
);
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/container/NoLogs/NoLogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ export default function NoLogs(): JSX.Element {
<div className="no-logs-container-content">
<img className="eyes-emoji" src="/Images/eyesEmoji.svg" alt="eyes emoji" />
<Typography className="no-logs-text">
No logs yet.{' '}
No logs yet.
<span className="sub-text">
When we receive logs, they would show up here
</span>
</Typography>

<Typography.Link className="send-logs-link">
<Typography.Link
className="send-logs-link"
href="https://signoz.io/docs/userguide/logs/"
target="_blank"
>
Sending Logs to SigNoz <ArrowUpRight size={16} />
</Typography.Link>
</div>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/container/SideNav/NavItem/NavItem.styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

height: 36px;
margin-bottom: 4px;
cursor: pointer;

&.active {
.nav-item-active-marker {
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/container/SideNav/NavItem/NavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ export default function NavItem({
isCollapsed: boolean;
item: SidebarItem;
isActive: boolean;
onClick: () => void;
onClick: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
}): JSX.Element {
const { label, icon } = item;

return (
<Tooltip title={isCollapsed ? label : ''} placement="right">
<div className={cx('nav-item', isActive ? 'active' : '')} onClick={onClick}>
<div
className={cx('nav-item', isActive ? 'active' : '')}
onClick={(event): void => onClick(event)}
>
<div className="nav-item-active-marker" />
<div className="nav-item-data">
<div className="nav-item-icon">{icon}</div>
Expand Down
117 changes: 81 additions & 36 deletions frontend/src/container/SideNav/SideNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
RocketIcon,
UserCircle,
} from 'lucide-react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { MouseEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
Expand All @@ -40,7 +40,7 @@ import defaultMenuItems, {
trySignozCloudMenuItem,
} from './menuItems';
import NavItem from './NavItem/NavItem';
import { SecondaryMenuItemKey } from './sideNav.types';
import { SecondaryMenuItemKey, SidebarItem } from './sideNav.types';
import { getActiveMenuKeyFromPath } from './sideNav.utils';

interface UserManagementMenuItems {
Expand Down Expand Up @@ -88,10 +88,6 @@ function SideNav({
window.open('https://signoz.io/slack', '_blank');
};

const onClickVersionHandler = (): void => {
history.push(ROUTES.VERSION);
};

const isLatestVersion = checkVersionState(currentVersion, latestVersion);

const [inviteMembers] = useComponentPermission(['invite_members'], role);
Expand Down Expand Up @@ -164,23 +160,49 @@ function SideNav({
);
};

const onClickShortcuts = (): void => {
history.push(`/shortcuts`);
const isCtrlMetaKey = (e: MouseEvent): boolean => e.ctrlKey || e.metaKey;

const openInNewTab = (path: string): void => {
window.open(path, '_blank');
};

const onClickShortcuts = (e: MouseEvent): void => {
if (isCtrlMetaKey(e)) {
openInNewTab('/shortcuts');
} else {
history.push(`/shortcuts`);
}
};

const onClickGetStarted = (event: MouseEvent): void => {
if (isCtrlMetaKey(event)) {
openInNewTab('/get-started');
} else {
history.push(`/get-started`);
}
};

const onClickGetStarted = (): void => {
history.push(`/get-started`);
const onClickVersionHandler = (event: MouseEvent): void => {
if (isCtrlMetaKey(event)) {
openInNewTab(ROUTES.VERSION);
} else {
history.push(ROUTES.VERSION);
}
};

const onClickHandler = useCallback(
(key: string) => {
(key: string, event: MouseEvent | null) => {
const params = new URLSearchParams(search);
const availableParams = routeConfig[key];

const queryString = getQueryString(availableParams || [], params);

if (pathname !== key) {
history.push(`${key}?${queryString.join('&')}`);
if (event && isCtrlMetaKey(event)) {
openInNewTab(`${key}?${queryString.join('&')}`);
} else {
history.push(`${key}?${queryString.join('&')}`);
}
}
},
[pathname, search],
Expand Down Expand Up @@ -220,16 +242,19 @@ function SideNav({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentVersion, latestVersion]);

const handleUserManagentMenuItemClick = (key: string): void => {
const handleUserManagentMenuItemClick = (
key: string,
event: MouseEvent,
): void => {
switch (key) {
case SecondaryMenuItemKey.Slack:
onClickSlackHandler();
break;
case SecondaryMenuItemKey.Version:
onClickVersionHandler();
onClickVersionHandler(event);
break;
default:
onClickHandler(key);
onClickHandler(key, event);
break;
}
};
Expand All @@ -255,29 +280,41 @@ function SideNav({
? ROUTES.ORG_SETTINGS
: ROUTES.SETTINGS;

const handleMenuItemClick = (event: MouseEvent, item: SidebarItem): void => {
if (item.key === ROUTES.SETTINGS) {
if (isCtrlMetaKey(event)) {
openInNewTab(settingsRoute);
} else {
history.push(settingsRoute);
}
} else if (item) {
onClickHandler(item?.key as string, event);
}
};

useEffect(() => {
registerShortcut(GlobalShortcuts.SidebarCollapse, onCollapse);

registerShortcut(GlobalShortcuts.NavigateToServices, () =>
onClickHandler(ROUTES.APPLICATION),
onClickHandler(ROUTES.APPLICATION, null),
);
registerShortcut(GlobalShortcuts.NavigateToTraces, () =>
onClickHandler(ROUTES.TRACE),
onClickHandler(ROUTES.TRACE, null),
);

registerShortcut(GlobalShortcuts.NavigateToLogs, () =>
onClickHandler(ROUTES.LOGS),
onClickHandler(ROUTES.LOGS, null),
);

registerShortcut(GlobalShortcuts.NavigateToDashboards, () =>
onClickHandler(ROUTES.ALL_DASHBOARD),
onClickHandler(ROUTES.ALL_DASHBOARD, null),
);

registerShortcut(GlobalShortcuts.NavigateToAlerts, () =>
onClickHandler(ROUTES.LIST_ALL_ALERT),
onClickHandler(ROUTES.LIST_ALL_ALERT, null),
);
registerShortcut(GlobalShortcuts.NavigateToExceptions, () =>
onClickHandler(ROUTES.ALL_ERROR),
onClickHandler(ROUTES.ALL_ERROR, null),
);

return (): void => {
Expand All @@ -297,9 +334,9 @@ function SideNav({
<div
className="brand-logo"
// eslint-disable-next-line react/no-unknown-property
onClick={(): void => {
onClick={(event: MouseEvent): void => {
// Current home page
onClickHandler(ROUTES.APPLICATION);
onClickHandler(ROUTES.APPLICATION, event);
}}
>
<img src="/Logos/signoz-brand-logo.svg" alt="SigNoz" />
Expand All @@ -314,7 +351,12 @@ function SideNav({

{isCloudUserVal && (
<div className="get-started-nav-items">
<Button className="get-started-btn" onClick={onClickGetStarted}>
<Button
className="get-started-btn"
onClick={(event: MouseEvent): void => {
onClickGetStarted(event);
}}
>
<RocketIcon size={16} />

{!collapsed && <> Get Started </>}
Expand All @@ -329,12 +371,8 @@ function SideNav({
key={item.key || index}
item={item}
isActive={activeMenuKey === item.key}
onClick={(): void => {
if (item.key === ROUTES.SETTINGS) {
history.push(settingsRoute);
} else if (item) {
onClickHandler(item?.key as string);
}
onClick={(event): void => {
handleMenuItemClick(event, item);
}}
/>
))}
Expand Down Expand Up @@ -366,8 +404,8 @@ function SideNav({
key={item?.key || index}
item={item}
isActive={activeMenuKey === item?.key}
onClick={(): void => {
handleUserManagentMenuItemClick(item?.key as string);
onClick={(event: MouseEvent): void => {
handleUserManagentMenuItemClick(item?.key as string, event);
}}
/>
),
Expand All @@ -379,8 +417,12 @@ function SideNav({
key={inviteMemberMenuItem.key}
item={inviteMemberMenuItem}
isActive={activeMenuKey === inviteMemberMenuItem?.key}
onClick={(): void => {
history.push(`${inviteMemberMenuItem.key}`);
onClick={(event: React.MouseEvent): void => {
if (isCtrlMetaKey(event)) {
openInNewTab(`${inviteMemberMenuItem.key}`);
} else {
history.push(`${inviteMemberMenuItem.key}`);
}
}}
/>
)}
Expand All @@ -391,8 +433,11 @@ function SideNav({
key={ROUTES.MY_SETTINGS}
item={userSettingsMenuItem}
isActive={activeMenuKey === userSettingsMenuItem?.key}
onClick={(): void => {
handleUserManagentMenuItemClick(userSettingsMenuItem?.key as string);
onClick={(event: MouseEvent): void => {
handleUserManagentMenuItemClick(
userSettingsMenuItem?.key as string,
event,
);
}}
/>
)}
Expand Down

0 comments on commit bb3e39d

Please sign in to comment.