mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
Remove Bootstrap Icons (#1480)
This PR removes bootstrap-icons entirely from the app. It also adds an eslint plugin to detect uses and throw an error, this will help in the immediate short term with PRs in flight and merging downstream. Fixes HDX-3050
This commit is contained in:
parent
58e78ab16f
commit
4ba37e557c
69 changed files with 685 additions and 2470 deletions
5
.changeset/hungry-cups-applaud.md
Normal file
5
.changeset/hungry-cups-applaud.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
Swap out bootstrap icons for tabler icons across app
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
- **Charts/Visualization**: Recharts, uPlot
|
||||
- **Code Editor**: CodeMirror (for SQL/JSON editing)
|
||||
- **Styling**: Mantine's built-in system, SCSS modules when needed
|
||||
- **Icons**: Use `@tabler/icons-react`
|
||||
|
||||
**UI Component Priority**: Mantine components first → Custom components on Mantine primitives → Custom SCSS modules as last resort
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css"
|
||||
/>
|
||||
<link
|
||||
rel="preconnect"
|
||||
href="https://fonts.gstatic.com"
|
||||
|
|
|
|||
|
|
@ -68,6 +68,15 @@ export default [
|
|||
],
|
||||
},
|
||||
],
|
||||
// Temporary rule to enforce use of @tabler/icons-react instead of bi bi-icons
|
||||
// Will remove after we've updated all icons and let some PRs merge.
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
selector: 'Literal[value=/\\bbi-\\b/i]',
|
||||
message: 'Please update to use @tabler/icons-react instead',
|
||||
},
|
||||
],
|
||||
'react-hooks/exhaustive-deps': 'error',
|
||||
'no-console': ['error', { allow: ['warn', 'error'] }],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@ export default function Document() {
|
|||
<script src="/__ENV.js" />
|
||||
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
|
||||
<script src="https://cdn.jsdelivr.net/pyodide/v0.27.2/full/pyodide.js"></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css"
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
|
|
|
|||
|
|
@ -20,7 +20,17 @@ import {
|
|||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconBell } from '@tabler/icons-react';
|
||||
import {
|
||||
IconAlertTriangle,
|
||||
IconBell,
|
||||
IconBrandSlack,
|
||||
IconChartLine,
|
||||
IconCheck,
|
||||
IconChevronRight,
|
||||
IconHelpCircle,
|
||||
IconInfoCircleFilled,
|
||||
IconTableRow,
|
||||
} from '@tabler/icons-react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { ErrorBoundary } from '@/components/ErrorBoundary';
|
||||
|
|
@ -312,7 +322,7 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) {
|
|||
{alert.dashboard?.name}
|
||||
{tileName ? (
|
||||
<>
|
||||
<i className="bi bi-chevron-right fs-8 mx-1 " />
|
||||
<IconChevronRight size={14} className="mx-1" />
|
||||
{tileName}
|
||||
</>
|
||||
) : null}
|
||||
|
|
@ -338,11 +348,11 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) {
|
|||
const alertIcon = (() => {
|
||||
switch (alert.source) {
|
||||
case AlertSource.TILE:
|
||||
return 'bi-graph-up';
|
||||
return <IconChartLine size={14} />;
|
||||
case AlertSource.SAVED_SEARCH:
|
||||
return 'bi-layout-text-sidebar-reverse';
|
||||
return <IconTableRow size={14} />;
|
||||
default:
|
||||
return 'bi-question';
|
||||
return <IconHelpCircle size={14} />;
|
||||
}
|
||||
})();
|
||||
|
||||
|
|
@ -359,9 +369,9 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) {
|
|||
const notificationMethod = React.useMemo(() => {
|
||||
if (alert.channel.type === 'webhook') {
|
||||
return (
|
||||
<span>
|
||||
Notify via <i className="bi bi-slack"></i> Webhook
|
||||
</span>
|
||||
<Group gap={2}>
|
||||
Notify via <IconBrandSlack size={16} /> Webhook
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
}, [alert]);
|
||||
|
|
@ -400,8 +410,10 @@ function AlertDetails({ alert }: { alert: AlertsPageItem }) {
|
|||
className={styles.alertLink}
|
||||
title={linkTitle}
|
||||
>
|
||||
<i className={`bi ${alertIcon} me-2 fs-8`} />
|
||||
{alertName}
|
||||
<Group gap={2}>
|
||||
{alertIcon}
|
||||
{alertName}
|
||||
</Group>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="fs-8 d-flex gap-2">
|
||||
|
|
@ -435,18 +447,18 @@ function AlertCardList({ alerts }: { alerts: AlertsPageItem[] }) {
|
|||
<div className="d-flex flex-column gap-4">
|
||||
{alarmAlerts.length > 0 && (
|
||||
<div>
|
||||
<div className={styles.sectionHeader}>
|
||||
<i className="bi bi-exclamation-triangle"></i> Triggered
|
||||
</div>
|
||||
<Group className={styles.sectionHeader}>
|
||||
<IconAlertTriangle size={14} /> Triggered
|
||||
</Group>
|
||||
{alarmAlerts.map((alert, index) => (
|
||||
<AlertDetails key={index} alert={alert} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<div className={styles.sectionHeader}>
|
||||
<i className="bi bi-check-lg"></i> OK
|
||||
</div>
|
||||
<Group className={styles.sectionHeader}>
|
||||
<IconCheck size={14} /> OK
|
||||
</Group>
|
||||
{okData.length === 0 && (
|
||||
<div className="text-center my-4 fs-8">No alerts</div>
|
||||
)}
|
||||
|
|
@ -472,7 +484,7 @@ export default function AlertsPage() {
|
|||
<div className="my-4">
|
||||
<Container maw={1500}>
|
||||
<Alert
|
||||
icon={<i className="bi bi-info-circle-fill " />}
|
||||
icon={<IconInfoCircleFilled size={16} />}
|
||||
color="gray"
|
||||
py="xs"
|
||||
mt="md"
|
||||
|
|
|
|||
|
|
@ -14,8 +14,19 @@ import {
|
|||
UnstyledButton,
|
||||
} from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import {
|
||||
IconBook,
|
||||
IconBrandDiscord,
|
||||
IconBulb,
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconChevronUp,
|
||||
IconHelp,
|
||||
IconLogout,
|
||||
IconSettings,
|
||||
IconUserCog,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { Icon } from '@/components/Icon';
|
||||
import InstallInstructionModal from '@/InstallInstructionsModal';
|
||||
import { useSources } from '@/source';
|
||||
|
||||
|
|
@ -132,7 +143,7 @@ export const AppNavUserMenu = ({
|
|||
</Text>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Icon name="chevron-right" className="fs-8 " />
|
||||
<IconChevronRight size={14} />
|
||||
</>
|
||||
)}
|
||||
</Group>
|
||||
|
|
@ -146,14 +157,14 @@ export const AppNavUserMenu = ({
|
|||
data-testid="team-settings-menu-item"
|
||||
href="/team"
|
||||
component={Link}
|
||||
leftSection={<Icon name="gear" />}
|
||||
leftSection={<IconSettings size={16} />}
|
||||
>
|
||||
Team Settings
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item
|
||||
data-testid="user-preferences-menu-item"
|
||||
leftSection={<Icon name="person-gear" />}
|
||||
leftSection={<IconUserCog size={16} />}
|
||||
onClick={onClickUserPreferences}
|
||||
>
|
||||
User Preferences
|
||||
|
|
@ -164,7 +175,7 @@ export const AppNavUserMenu = ({
|
|||
<Menu.Item
|
||||
data-testid="logout-menu-item"
|
||||
color="red"
|
||||
leftSection={<Icon name="box-arrow-left" />}
|
||||
leftSection={<IconLogout size={16} />}
|
||||
component={Link}
|
||||
href={logoutUrl}
|
||||
>
|
||||
|
|
@ -221,7 +232,7 @@ export const AppNavHelpMenu = ({
|
|||
<Menu.Target>
|
||||
<UnstyledButton data-testid="help-menu-trigger" w="100%">
|
||||
<Group align="center" justify="center" h={28}>
|
||||
<Icon name="question-lg" />
|
||||
<IconHelp size={16} />
|
||||
</Group>
|
||||
</UnstyledButton>
|
||||
</Menu.Target>
|
||||
|
|
@ -239,13 +250,13 @@ export const AppNavHelpMenu = ({
|
|||
data-testid="documentation-menu-item"
|
||||
href="https://clickhouse.com/docs/use-cases/observability/clickstack"
|
||||
component="a"
|
||||
leftSection={<Icon name="book" />}
|
||||
leftSection={<IconBook size={16} />}
|
||||
>
|
||||
Documentation
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
data-testid="discord-menu-item"
|
||||
leftSection={<Icon name="discord" />}
|
||||
leftSection={<IconBrandDiscord size={16} />}
|
||||
component="a"
|
||||
href="https://hyperdx.io/discord"
|
||||
target="_blank"
|
||||
|
|
@ -254,7 +265,7 @@ export const AppNavHelpMenu = ({
|
|||
</Menu.Item>
|
||||
<Menu.Item
|
||||
data-testid="setup-instructions-menu-item"
|
||||
leftSection={<Icon name="lightbulb" />}
|
||||
leftSection={<IconBulb size={16} />}
|
||||
onClick={onAddDataClick}
|
||||
>
|
||||
Setup Instructions
|
||||
|
|
@ -321,11 +332,11 @@ export const AppNavLink = ({
|
|||
size="sm"
|
||||
onClick={onToggle}
|
||||
>
|
||||
<i
|
||||
className={`fs-8 bi bi-chevron-${
|
||||
isExpanded ? 'up' : 'down'
|
||||
} text-muted-hover`}
|
||||
/>
|
||||
{isExpanded ? (
|
||||
<IconChevronUp size={14} className="text-muted-hover" />
|
||||
) : (
|
||||
<IconChevronDown size={14} className="text-muted-hover" />
|
||||
)}
|
||||
</ActionIcon>
|
||||
)}
|
||||
</Group>
|
||||
|
|
|
|||
|
|
@ -27,10 +27,15 @@ import {
|
|||
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
|
||||
import {
|
||||
IconBell,
|
||||
IconBellFilled,
|
||||
IconChartDots,
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconCommand,
|
||||
IconDeviceLaptop,
|
||||
IconLayoutGrid,
|
||||
IconLayoutSidebarLeftCollapse,
|
||||
IconSearch,
|
||||
IconSettings,
|
||||
IconSitemap,
|
||||
IconTable,
|
||||
|
|
@ -135,7 +140,7 @@ function SearchInput({
|
|||
return (
|
||||
<div className={styles.kbd}>
|
||||
{window.navigator.platform?.toUpperCase().includes('MAC') ? (
|
||||
<i className="bi bi-command" />
|
||||
<IconCommand size={8} />
|
||||
) : (
|
||||
<span style={{ letterSpacing: -2 }}>Ctrl</span>
|
||||
)}
|
||||
|
|
@ -161,7 +166,7 @@ function SearchInput({
|
|||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
onChange(e.currentTarget.value)
|
||||
}
|
||||
leftSection={<i className="bi bi-search fs-8 ps-1 " />}
|
||||
leftSection={<IconSearch size={16} className="ps-1" />}
|
||||
onKeyDown={handleKeyDown}
|
||||
rightSection={
|
||||
value ? (
|
||||
|
|
@ -208,7 +213,11 @@ const AppNavGroupLabel = ({
|
|||
}) => {
|
||||
return (
|
||||
<div className={styles.listGroupName} onClick={onClick}>
|
||||
<i className={`bi bi-chevron-${collapsed ? 'right' : 'down'}`} />
|
||||
{collapsed ? (
|
||||
<IconChevronRight size={14} />
|
||||
) : (
|
||||
<IconChevronDown size={14} />
|
||||
)}
|
||||
<div>{name}</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -486,20 +495,25 @@ export default function AppNav({ fixed = false }: { fixed?: boolean }) {
|
|||
draggable
|
||||
data-savedsearchid={savedSearch.id}
|
||||
>
|
||||
<div className="d-inline-block text-truncate">{savedSearch.name}</div>
|
||||
{Array.isArray(savedSearch.alerts) && savedSearch.alerts.length > 0 ? (
|
||||
savedSearch.alerts.some(a => a.state === AlertState.ALERT) ? (
|
||||
<i
|
||||
className="bi bi-bell float-end text-danger ms-1"
|
||||
title="Has Alerts and is in ALERT state"
|
||||
></i>
|
||||
) : (
|
||||
<i
|
||||
className="bi bi-bell float-end ms-1"
|
||||
title="Has Alerts and is in OK state"
|
||||
></i>
|
||||
)
|
||||
) : null}
|
||||
<Group gap={2}>
|
||||
<div className="d-inline-block text-truncate">{savedSearch.name}</div>
|
||||
{Array.isArray(savedSearch.alerts) &&
|
||||
savedSearch.alerts.length > 0 ? (
|
||||
savedSearch.alerts.some(a => a.state === AlertState.ALERT) ? (
|
||||
<IconBellFilled
|
||||
size={14}
|
||||
className="float-end text-danger ms-1"
|
||||
aria-label="Has Alerts and is in ALERT state"
|
||||
/>
|
||||
) : (
|
||||
<IconBell
|
||||
size={14}
|
||||
className="float-end ms-1"
|
||||
aria-label="Has Alerts and is in OK state"
|
||||
/>
|
||||
)
|
||||
) : null}
|
||||
</Group>
|
||||
</Link>
|
||||
),
|
||||
[
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
Stack,
|
||||
TextInput,
|
||||
} from '@mantine/core';
|
||||
import { IconAt, IconLock } from '@tabler/icons-react';
|
||||
|
||||
import api from './api';
|
||||
import * as config from './config';
|
||||
|
|
@ -150,7 +151,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
|||
withAsterisk={false}
|
||||
placeholder="you@company.com"
|
||||
type="email"
|
||||
leftSection={<i className="bi bi-at fs-5" />}
|
||||
leftSection={<IconAt size={18} />}
|
||||
error={errors.email?.message}
|
||||
required
|
||||
{...form.email}
|
||||
|
|
@ -159,7 +160,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
|||
size="md"
|
||||
label="Password"
|
||||
withAsterisk={false}
|
||||
leftSection={<i className="bi bi-lock-fill" />}
|
||||
leftSection={<IconLock size={16} />}
|
||||
error={errors.password?.message}
|
||||
required
|
||||
placeholder="Password"
|
||||
|
|
@ -179,7 +180,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
|||
size="md"
|
||||
required
|
||||
withAsterisk={false}
|
||||
leftSection={<i className="bi bi-lock-fill" />}
|
||||
leftSection={<IconLock size={16} />}
|
||||
error={errors.confirmPassword?.message}
|
||||
placeholder="Confirm Password"
|
||||
{...form.confirmPassword}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import {
|
|||
Text,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { IconRefresh } from '@tabler/icons-react';
|
||||
import ReactCodeMirror from '@uiw/react-codemirror';
|
||||
|
||||
import { ConnectionSelectControlled } from '@/components/ConnectionSelect';
|
||||
|
|
@ -529,7 +530,7 @@ function ClickhousePage() {
|
|||
aria-label="Refresh dashboard"
|
||||
px="xs"
|
||||
>
|
||||
<i className="bi bi-arrow-clockwise fs-5"></i>
|
||||
<IconRefresh size={18} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ import {
|
|||
Text,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconInfoCircle,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import api from '@/api';
|
||||
import { DEFAULT_CHART_CONFIG, Granularity } from '@/ChartUtils';
|
||||
|
|
@ -120,7 +125,7 @@ function AIAssistant({
|
|||
<Box mb="sm">
|
||||
<Alert
|
||||
color="dark"
|
||||
icon={<i className="bi bi-info-circle" />}
|
||||
icon={<IconInfoCircle size={16} />}
|
||||
variant="outline"
|
||||
withCloseButton
|
||||
onClose={() => setAlertDismissed(true)}
|
||||
|
|
@ -150,9 +155,9 @@ function AIAssistant({
|
|||
>
|
||||
<Group gap="xs">
|
||||
{opened ? (
|
||||
<i className="bi bi-chevron-up" />
|
||||
<IconChevronUp size={14} />
|
||||
) : (
|
||||
<i className="bi bi-chevron-down" />
|
||||
<IconChevronDown size={14} />
|
||||
)}
|
||||
<Text size="xxs">AI Assistant [A]</Text>
|
||||
</Group>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,19 @@ import {
|
|||
} from '@mantine/core';
|
||||
import { useHover } from '@mantine/hooks';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconBell, IconFilterEdit, IconPlayerPlay } from '@tabler/icons-react';
|
||||
import {
|
||||
IconBell,
|
||||
IconCopy,
|
||||
IconDotsVertical,
|
||||
IconDownload,
|
||||
IconFilterEdit,
|
||||
IconPencil,
|
||||
IconPlayerPlay,
|
||||
IconRefresh,
|
||||
IconTags,
|
||||
IconTrash,
|
||||
IconUpload,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { ContactSupportText } from '@/components/ContactSupportText';
|
||||
import EditTimeChartForm from '@/components/DBEditTimeChartForm';
|
||||
|
|
@ -277,7 +289,7 @@ const Tile = forwardRef(
|
|||
onClick={onDuplicateClick}
|
||||
title="Duplicate"
|
||||
>
|
||||
<i className="bi bi-copy fs-8"></i>
|
||||
<IconCopy size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
data-testid={`tile-edit-button-${chart.id}`}
|
||||
|
|
@ -287,7 +299,7 @@ const Tile = forwardRef(
|
|||
onClick={onEditClick}
|
||||
title="Edit"
|
||||
>
|
||||
<i className="bi bi-pencil"></i>
|
||||
<IconPencil size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
data-testid={`tile-delete-button-${chart.id}`}
|
||||
|
|
@ -297,7 +309,7 @@ const Tile = forwardRef(
|
|||
onClick={onDeleteClick}
|
||||
title="Delete"
|
||||
>
|
||||
<i className="bi bi-trash"></i>
|
||||
<IconTrash size={14} />
|
||||
</Button>
|
||||
</Flex>
|
||||
) : (
|
||||
|
|
@ -505,7 +517,7 @@ function DashboardName({
|
|||
size="xs"
|
||||
onClick={() => setEditing(true)}
|
||||
>
|
||||
<i className="bi bi-pencil"></i>
|
||||
<IconPencil size={14} />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -944,7 +956,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
|||
size="xs"
|
||||
style={{ flexShrink: 0 }}
|
||||
>
|
||||
<i className="bi bi-tags-fill me-2"></i>
|
||||
<IconTags size={14} className="me-2" />
|
||||
{dashboard?.tags?.length || 0}{' '}
|
||||
{dashboard?.tags?.length === 1 ? 'Tag' : 'Tags'}
|
||||
</Button>
|
||||
|
|
@ -954,14 +966,14 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
|||
<Menu width={250}>
|
||||
<Menu.Target>
|
||||
<Button variant="default" px="xs" size="xs">
|
||||
<i className="bi bi-three-dots-vertical" />
|
||||
<IconDotsVertical size={14} />
|
||||
</Button>
|
||||
</Menu.Target>
|
||||
|
||||
<Menu.Dropdown>
|
||||
{hasTiles && (
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-download" />}
|
||||
leftSection={<IconDownload size={16} />}
|
||||
onClick={() => {
|
||||
if (!sources || !dashboard) {
|
||||
notifications.show({
|
||||
|
|
@ -984,7 +996,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
|||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-upload" />}
|
||||
leftSection={<IconUpload size={16} />}
|
||||
onClick={() => {
|
||||
if (dashboard && !dashboard.tiles.length) {
|
||||
router.push(
|
||||
|
|
@ -998,7 +1010,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
|||
{hasTiles ? 'Import New Dashboard' : 'Import Dashboard'}
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-trash-fill" />}
|
||||
leftSection={<IconTrash size={16} />}
|
||||
color="red"
|
||||
onClick={() =>
|
||||
deleteDashboard.mutate(dashboard?.id ?? '', {
|
||||
|
|
@ -1097,7 +1109,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
|||
title="Refresh dashboard"
|
||||
px="xs"
|
||||
>
|
||||
<i className="bi bi-arrow-clockwise fs-5"></i>
|
||||
<IconRefresh size={18} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip withArrow label="Edit Filters" fz="xs" color="gray">
|
||||
|
|
|
|||
|
|
@ -60,7 +60,15 @@ import {
|
|||
useDocumentVisibility,
|
||||
} from '@mantine/hooks';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconPlayerPlay } from '@tabler/icons-react';
|
||||
import {
|
||||
IconBolt,
|
||||
IconCirclePlus,
|
||||
IconPlayerPlay,
|
||||
IconPlus,
|
||||
IconSettings,
|
||||
IconTags,
|
||||
IconX,
|
||||
} from '@tabler/icons-react';
|
||||
import { useIsFetching } from '@tanstack/react-query';
|
||||
import { SortingState } from '@tanstack/react-table';
|
||||
import CodeMirror from '@uiw/react-codemirror';
|
||||
|
|
@ -381,7 +389,7 @@ function SaveSearchModal({
|
|||
}}
|
||||
size="xs"
|
||||
>
|
||||
<i className="bi bi-x" />
|
||||
<IconX size={14} />
|
||||
</ActionIcon>
|
||||
}
|
||||
>
|
||||
|
|
@ -395,7 +403,7 @@ function SaveSearchModal({
|
|||
color="gray"
|
||||
size="xs"
|
||||
>
|
||||
<i className="bi bi-plus me-1"></i>
|
||||
<IconPlus size={14} className="me-1" />
|
||||
Add Tag
|
||||
</Button>
|
||||
</Tags>
|
||||
|
|
@ -1376,7 +1384,7 @@ function DBSearchPage() {
|
|||
title="Edit Source"
|
||||
>
|
||||
<Text size="xs">
|
||||
<i className="bi bi-gear" />
|
||||
<IconSettings size={14} />
|
||||
</Text>
|
||||
</ActionIcon>
|
||||
</Menu.Target>
|
||||
|
|
@ -1384,7 +1392,7 @@ function DBSearchPage() {
|
|||
<Menu.Label>Sources</Menu.Label>
|
||||
<Menu.Item
|
||||
data-testid="create-new-source-menu-item"
|
||||
leftSection={<i className="bi bi-plus-circle" />}
|
||||
leftSection={<IconCirclePlus size={14} />}
|
||||
onClick={() => setNewSourceModalOpened(true)}
|
||||
>
|
||||
Create New Source
|
||||
|
|
@ -1392,7 +1400,7 @@ function DBSearchPage() {
|
|||
{IS_LOCAL_MODE ? (
|
||||
<Menu.Item
|
||||
data-testid="edit-source-menu-item"
|
||||
leftSection={<i className="bi bi-gear" />}
|
||||
leftSection={<IconSettings size={14} />}
|
||||
onClick={() => setModelFormExpanded(v => !v)}
|
||||
>
|
||||
Edit Source
|
||||
|
|
@ -1400,7 +1408,7 @@ function DBSearchPage() {
|
|||
) : (
|
||||
<Menu.Item
|
||||
data-testid="edit-sources-menu-item"
|
||||
leftSection={<i className="bi bi-gear" />}
|
||||
leftSection={<IconSettings size={14} />}
|
||||
component={Link}
|
||||
href="/team"
|
||||
>
|
||||
|
|
@ -1485,7 +1493,7 @@ function DBSearchPage() {
|
|||
size="xs"
|
||||
style={{ flexShrink: 0 }}
|
||||
>
|
||||
<i className="bi bi-tags-fill me-1"></i>
|
||||
<IconTags size={14} className="me-1" />
|
||||
{savedSearch.tags?.length || 0}
|
||||
</Button>
|
||||
</Tags>
|
||||
|
|
@ -1755,7 +1763,10 @@ function DBSearchPage() {
|
|||
variant="outline"
|
||||
onClick={handleResumeLiveTail}
|
||||
>
|
||||
<i className="bi text-success bi-lightning-charge-fill me-2" />
|
||||
<IconBolt
|
||||
size={14}
|
||||
className="text-success me-2"
|
||||
/>
|
||||
Resume Live Tail
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ import {
|
|||
Text,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import {
|
||||
IconBrandSlack,
|
||||
IconChartLine,
|
||||
IconInfoCircleFilled,
|
||||
IconPlus,
|
||||
} from '@tabler/icons-react';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { useCreateSavedSearch } from '@/savedSearch';
|
||||
|
|
@ -56,7 +62,7 @@ const SavedSearchAlertFormSchema = z
|
|||
.passthrough();
|
||||
|
||||
const CHANNEL_ICONS = {
|
||||
webhook: <i className="bi bi-slack fs-7 " />,
|
||||
webhook: <IconBrandSlack size={14} />,
|
||||
};
|
||||
|
||||
const AlertForm = ({
|
||||
|
|
@ -166,7 +172,7 @@ const AlertForm = ({
|
|||
</Paper>
|
||||
{groupBy && thresholdType === AlertThresholdType.BELOW && (
|
||||
<MantineAlert
|
||||
icon={<i className="bi bi-info-circle-fill " />}
|
||||
icon={<IconInfoCircleFilled size={16} />}
|
||||
bg="dark"
|
||||
py="xs"
|
||||
>
|
||||
|
|
@ -181,7 +187,7 @@ const AlertForm = ({
|
|||
|
||||
<Accordion defaultValue={'chart'} mt="sm" mx={-16}>
|
||||
<Accordion.Item value="chart">
|
||||
<Accordion.Control icon={<i className="bi bi-chart"></i>}>
|
||||
<Accordion.Control icon={<IconChartLine size={16} />}>
|
||||
<Text size="sm">Threshold chart</Text>
|
||||
</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
|
|
@ -417,7 +423,7 @@ export const DBSearchPageAlertModal = ({
|
|||
))}
|
||||
<Tabs.Tab value="stage">
|
||||
<Group gap={4}>
|
||||
<i className="bi bi-plus fs-5 " style={{ marginLeft: -8 }} />
|
||||
<IconPlus size={18} style={{ marginLeft: -8 }} />
|
||||
New Alert
|
||||
</Group>
|
||||
</Tabs.Tab>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@ import throttle from 'lodash/throttle';
|
|||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { Replayer } from 'rrweb';
|
||||
import { ActionIcon, CopyButton, HoverCard } from '@mantine/core';
|
||||
import {
|
||||
IconArrowsMaximize,
|
||||
IconCheck,
|
||||
IconCopy,
|
||||
IconGlobe,
|
||||
IconLink,
|
||||
IconList,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { useRRWebEventStream } from '@/sessions';
|
||||
import { useDebugMode } from '@/utils';
|
||||
|
|
@ -43,13 +51,13 @@ const URLHoverCard = memo(({ url }: { url: string }) => {
|
|||
<table className="table fs-8 mb-0">
|
||||
<tr>
|
||||
<td>
|
||||
<i className="bi bi-globe fs-8 "></i>
|
||||
<IconGlobe size={14} />
|
||||
</td>
|
||||
<td>{parsedUrl?.host}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<i className="bi bi-link-45deg fs-7"></i>
|
||||
<IconLink size={14} />
|
||||
</td>
|
||||
<td>{parsedUrl?.pathname}</td>
|
||||
</tr>
|
||||
|
|
@ -474,9 +482,9 @@ export default function DOMPlayer({
|
|||
color="gray"
|
||||
>
|
||||
{playerFullWidth ? (
|
||||
<i className="bi bi-list"></i>
|
||||
<IconList size={14} />
|
||||
) : (
|
||||
<i className="bi bi-arrows-fullscreen fs-8"></i>
|
||||
<IconArrowsMaximize size={14} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
<CopyButton value={lastHref}>
|
||||
|
|
@ -490,11 +498,7 @@ export default function DOMPlayer({
|
|||
size="sm"
|
||||
color="gray"
|
||||
>
|
||||
{copied ? (
|
||||
<i className="bi bi-check2 fs-8" />
|
||||
) : (
|
||||
<i className="bi bi-copy fs-8" />
|
||||
)}
|
||||
{copied ? <IconCheck size={14} /> : <IconCopy size={14} />}
|
||||
</ActionIcon>
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,13 @@ import {
|
|||
Tooltip,
|
||||
UnstyledButton,
|
||||
} from '@mantine/core';
|
||||
import { IconFilter, IconPencil, IconTrash } from '@tabler/icons-react';
|
||||
import {
|
||||
IconFilter,
|
||||
IconInfoCircle,
|
||||
IconPencil,
|
||||
IconStack,
|
||||
IconTrash,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import SourceSchemaPreview from './components/SourceSchemaPreview';
|
||||
import { SourceSelectControlled } from './components/SourceSelect';
|
||||
|
|
@ -55,7 +61,7 @@ const CustomInputWrapper = ({
|
|||
<Input.Label>{label}</Input.Label>
|
||||
{tooltipText && (
|
||||
<Tooltip label={tooltipText}>
|
||||
<i className="bi bi-info-circle ms-2" />
|
||||
<IconInfoCircle size={14} className="ms-2" />
|
||||
</Tooltip>
|
||||
)}
|
||||
{errorMessage && (
|
||||
|
|
@ -280,7 +286,7 @@ const DashboardFiltersList = ({
|
|||
</Group>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<i className="bi bi-collection"></i>
|
||||
<IconStack size={14} />
|
||||
<Text size="xs">
|
||||
{sources?.find(s => s.id === filter.source)?.name}
|
||||
</Text>
|
||||
|
|
@ -329,7 +335,6 @@ const DashboardFiltersModal = ({
|
|||
if (opened) {
|
||||
setSelectedFilter(undefined);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [opened]);
|
||||
|
||||
const handleRemoveFilter = (id: string) => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import cx from 'classnames';
|
||||
import { Flex, Text, UnstyledButton } from '@mantine/core';
|
||||
import { IconGripVertical } from '@tabler/icons-react';
|
||||
import { UnstyledButton } from '@mantine/core';
|
||||
import { IconDownload, IconTextWrap } from '@tabler/icons-react';
|
||||
import {
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
|
|
@ -228,7 +228,7 @@ export const Table = ({
|
|||
<UnstyledButton
|
||||
onClick={() => setWrapLinesEnabled(prev => !prev)}
|
||||
>
|
||||
<i className="bi bi-text-wrap" />
|
||||
<IconTextWrap size={14} />
|
||||
</UnstyledButton>
|
||||
<CsvExportButton
|
||||
data={csvData}
|
||||
|
|
@ -236,7 +236,7 @@ export const Table = ({
|
|||
className="fs-8 ms-2"
|
||||
title="Download table as CSV"
|
||||
>
|
||||
<i className="bi bi-download" />
|
||||
<IconDownload size={14} />
|
||||
</CsvExportButton>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import cx from 'classnames';
|
||||
import { Button, Modal } from '@mantine/core';
|
||||
import { Button, Group, Modal } from '@mantine/core';
|
||||
import { IconClipboard, IconClipboardCheck } from '@tabler/icons-react';
|
||||
|
||||
import api from './api';
|
||||
import Clipboard from './Clipboard';
|
||||
|
|
@ -29,15 +30,14 @@ function CopyableValue({
|
|||
{value}
|
||||
</pre>
|
||||
</div>
|
||||
<div className={cx('fs-7 text-end text-nowrap')}>
|
||||
<i
|
||||
className={cx('bi me-2', {
|
||||
'bi-clipboard': !isCopied,
|
||||
'bi-clipboard-check': isCopied,
|
||||
})}
|
||||
></i>
|
||||
<Group gap={2} wrap="nowrap" className={cx('fs-7 text-end')}>
|
||||
{isCopied ? (
|
||||
<IconClipboardCheck size={14} />
|
||||
) : (
|
||||
<IconClipboard size={14} />
|
||||
)}
|
||||
{isCopied ? 'Copied!' : 'Copy'}
|
||||
</div>
|
||||
</Group>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ import {
|
|||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import {
|
||||
IconCaretDownFilled,
|
||||
IconCaretUpFilled,
|
||||
IconRefresh,
|
||||
} from '@tabler/icons-react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
|
||||
import { TimePicker } from '@/components/TimePicker';
|
||||
|
|
@ -81,13 +86,12 @@ const Th = React.memo<{
|
|||
onClick={() => onSort?.(sort === 'asc' ? 'desc' : 'asc')}
|
||||
>
|
||||
{children}
|
||||
{!!sort && (
|
||||
<i
|
||||
className={`ps-1 fs-8.5 bi bi-caret-${
|
||||
sort === 'asc' ? 'up-fill' : 'down-fill'
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
{!!sort &&
|
||||
(sort === 'asc' ? (
|
||||
<IconCaretUpFilled size={12} className="ps-1" />
|
||||
) : (
|
||||
<IconCaretDownFilled size={12} className="ps-1" />
|
||||
))}
|
||||
</Table.Th>
|
||||
);
|
||||
});
|
||||
|
|
@ -1213,7 +1217,7 @@ function KubernetesDashboardPage() {
|
|||
aria-label="Refresh dashboard"
|
||||
px="xs"
|
||||
>
|
||||
<i className="bi bi-arrow-clockwise fs-5"></i>
|
||||
<IconRefresh size={18} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
|
@ -1350,7 +1354,7 @@ function KubernetesDashboardPage() {
|
|||
legacyBehavior
|
||||
>
|
||||
<Anchor size="xs" color="dimmed">
|
||||
Search <i className="bi bi-box-arrow-up-right"></i>
|
||||
Search <IconExternalLink size={12} style={{ display: 'inline' }} />
|
||||
</Anchor>
|
||||
</Link>
|
||||
*/}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,15 @@ import cx from 'classnames';
|
|||
import { format } from 'date-fns';
|
||||
import { JSONTree } from 'react-json-tree';
|
||||
import { Alert, Button, CloseButton, Kbd, Text, Tooltip } from '@mantine/core';
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconCode,
|
||||
IconPackage,
|
||||
} from '@tabler/icons-react';
|
||||
import { ColumnDef, Row, Table } from '@tanstack/react-table';
|
||||
|
||||
import HyperJson from './components/HyperJson';
|
||||
import { Icon } from './components/Icon';
|
||||
import { StacktraceFrame as StacktraceFrameCmp } from './components/StacktraceFrame';
|
||||
import { TableCellButton } from './components/Table';
|
||||
import { UNDEFINED_WIDTH } from './tableUtils';
|
||||
|
|
@ -37,7 +42,11 @@ export const CollapsibleSection = ({
|
|||
role="button"
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
>
|
||||
<i className={`bi bi-chevron-${collapsed ? 'right' : 'down'} me-2`}></i>
|
||||
{collapsed ? (
|
||||
<IconChevronRight size={14} className="me-2" />
|
||||
) : (
|
||||
<IconChevronDown size={14} className="me-2" />
|
||||
)}
|
||||
<div className="fs-7">{title}</div>
|
||||
</div>
|
||||
{collapsed ? null : <div className="mb-4">{children}</div>}
|
||||
|
|
@ -137,7 +146,11 @@ export const StacktraceRow = ({
|
|||
withArrow
|
||||
color="gray"
|
||||
>
|
||||
<i className="bi bi-box-seam me-2" title="in_app: false" />
|
||||
<IconPackage
|
||||
size={14}
|
||||
className="me-2"
|
||||
aria-label="in_app: false"
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
{augmentedFrame && (
|
||||
|
|
@ -526,9 +539,9 @@ export const SourceMapsFtux = () => {
|
|||
onClose={() => setIsDismissed(true)}
|
||||
>
|
||||
<Text size="xs">
|
||||
<Icon name="code-square" /> Some of the stack frames are pointing to
|
||||
minified files. Use hyperdx-cli to upload your source maps and see the
|
||||
original code.
|
||||
<IconCode size={16} /> Some of the stack frames are pointing to minified
|
||||
files. Use hyperdx-cli to upload your source maps and see the original
|
||||
code.
|
||||
</Text>
|
||||
<Link href="https://www.npmjs.com/package/@hyperdx/cli" target="_blank">
|
||||
<Button size="compact-xs" variant="light" mt="xs">
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ function NamespaceLogs({
|
|||
legacyBehavior
|
||||
>
|
||||
<Anchor size="xs" color="dimmed">
|
||||
Search <i className="bi bi-box-arrow-up-right"></i>
|
||||
Search <IconExternalLink size={12} style={{ display: 'inline' }} />
|
||||
</Anchor>
|
||||
</Link>
|
||||
*/}
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ function NodeLogs({
|
|||
legacyBehavior
|
||||
>
|
||||
<Anchor size="xs" color="dimmed">
|
||||
Search <i className="bi bi-box-arrow-up-right"></i>
|
||||
Search <IconExternalLink size={12} style={{ display: 'inline' }} />
|
||||
</Anchor>
|
||||
</Link>
|
||||
*/}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@ import {
|
|||
Text,
|
||||
UnstyledButton,
|
||||
} from '@mantine/core';
|
||||
import {
|
||||
IconArrowRight,
|
||||
IconCheck,
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { useQueriedChartConfig } from './hooks/useChartConfig';
|
||||
import api from './api';
|
||||
|
|
@ -165,10 +171,11 @@ const OnboardingChecklist = ({
|
|||
size="sm"
|
||||
onClick={() => setIsCollapsed(!isCollapsed)}
|
||||
>
|
||||
<i
|
||||
className={`bi bi-chevron-${isCollapsed ? 'down' : 'up'} `}
|
||||
style={{ fontSize: 12 }}
|
||||
/>
|
||||
{isCollapsed ? (
|
||||
<IconChevronDown size={12} />
|
||||
) : (
|
||||
<IconChevronUp size={12} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
|
||||
|
|
@ -200,8 +207,8 @@ const OnboardingChecklist = ({
|
|||
{step.isLoading ? (
|
||||
<Loader size="xs" color="gray" />
|
||||
) : step.isComplete ? (
|
||||
<i
|
||||
className="bi bi-check"
|
||||
<IconCheck
|
||||
size={16}
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
|
|
@ -232,10 +239,9 @@ const OnboardingChecklist = ({
|
|||
</div>
|
||||
|
||||
{!step.isComplete && (step.href || step.onClick) && (
|
||||
<i
|
||||
className="bi bi-arrow-right"
|
||||
<IconArrowRight
|
||||
size={12}
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: 'var(--color-text-muted)',
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { useMemo } from 'react';
|
||||
import { IconCheck, IconX } from '@tabler/icons-react';
|
||||
|
||||
const checkLength = (password: string) => password.length >= 12;
|
||||
const checkOneUpper = (password: string) => /[A-Z]+/.test(password);
|
||||
|
|
@ -71,6 +72,6 @@ export const CheckOrX = ({
|
|||
);
|
||||
};
|
||||
|
||||
const Check = () => <i className={'bi bi-check2'}></i>;
|
||||
const Check = () => <IconCheck size={14} />;
|
||||
|
||||
const XShape = () => <i className={'bi bi-x'}></i>;
|
||||
const XShape = () => <IconX size={14} />;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Only use this file if you can't find any icon in bootstrap icons
|
||||
// Only use this file if you can't find any icon in tabler icons
|
||||
|
||||
type IconProps = {
|
||||
style?: React.CSSProperties;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import {
|
|||
TableConnectionChoice,
|
||||
} from '@hyperdx/common-utils/dist/core/metadata';
|
||||
import { genEnglishExplanation } from '@hyperdx/common-utils/dist/queryParser';
|
||||
import { Group } from '@mantine/core';
|
||||
import { IconBook } from '@tabler/icons-react';
|
||||
|
||||
import AutocompleteInput from '@/AutocompleteInput';
|
||||
|
||||
|
|
@ -205,17 +207,17 @@ export default function SearchInputV2({
|
|||
</code>
|
||||
</div>
|
||||
|
||||
<div className="mb-2 me-2">
|
||||
<a
|
||||
className="text-muted"
|
||||
target="_blank"
|
||||
href="https://clickhouse.com/docs/use-cases/observability/clickstack/search"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<i className="bi bi-book me-1" />
|
||||
<span className="me-1">Docs</span>
|
||||
</a>
|
||||
</div>
|
||||
<a
|
||||
className="text-muted mb-2"
|
||||
target="_blank"
|
||||
href="https://clickhouse.com/docs/use-cases/observability/clickstack/search"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Group gap={5}>
|
||||
<IconBook size={14} />
|
||||
<span>Docs</span>
|
||||
</Group>
|
||||
</a>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,13 @@ import {
|
|||
Text,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { IconPlayerPlay } from '@tabler/icons-react';
|
||||
import {
|
||||
IconChartLine,
|
||||
IconFilter,
|
||||
IconPlayerPlay,
|
||||
IconRefresh,
|
||||
IconTable,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import {
|
||||
convertDateRangeToGranularityString,
|
||||
|
|
@ -207,7 +213,7 @@ export function EndpointLatencyChart({
|
|||
title="Line Chart"
|
||||
onClick={() => setLatencyChartType('line')}
|
||||
>
|
||||
<i className="bi bi-graph-up" />
|
||||
<IconChartLine size={14} />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
|
@ -1086,7 +1092,7 @@ function DatabaseTab({
|
|||
title="List"
|
||||
onClick={() => setChartType('list')}
|
||||
>
|
||||
<i className="bi bi-filter-left" />
|
||||
<IconFilter size={14} />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
|
@ -1096,7 +1102,7 @@ function DatabaseTab({
|
|||
title="Table"
|
||||
onClick={() => setChartType('table')}
|
||||
>
|
||||
<i className="bi bi-table" />
|
||||
<IconTable size={14} />
|
||||
</Button>
|
||||
</Button.Group>
|
||||
</Box>
|
||||
|
|
@ -1491,7 +1497,7 @@ function ServicesDashboardPage() {
|
|||
aria-label="Refresh dashboard"
|
||||
px="xs"
|
||||
>
|
||||
<i className="bi bi-arrow-clockwise fs-5"></i>
|
||||
<IconRefresh size={18} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Button variant="outline" type="submit" px="sm">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,14 @@ import cx from 'classnames';
|
|||
import { ChartConfigWithOptDateRange } from '@hyperdx/common-utils/dist/types';
|
||||
import { ScrollArea, Skeleton, Stack } from '@mantine/core';
|
||||
import { useThrottledCallback, useThrottledValue } from '@mantine/hooks';
|
||||
import { IconPlayerPlay } from '@tabler/icons-react';
|
||||
import {
|
||||
IconArrowsLeftRight,
|
||||
IconMapPin,
|
||||
IconMessage,
|
||||
IconPlayerPlay,
|
||||
IconPointer,
|
||||
IconTerminal,
|
||||
} from '@tabler/icons-react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
|
||||
import useRowWhere from '@/hooks/useRowWhere';
|
||||
|
|
@ -28,11 +35,11 @@ type SessionEvent = {
|
|||
duration: number;
|
||||
};
|
||||
|
||||
const EVENT_ROW_SOURCE_ICONS = {
|
||||
navigation: 'bi bi-geo-alt',
|
||||
chat: 'bi bi-chat-dots',
|
||||
network: 'bi bi-arrow-left-right',
|
||||
custom: 'bi bi-cursor',
|
||||
const EVENT_ROW_SOURCE_ICONS: Record<string, React.ReactNode> = {
|
||||
navigation: <IconMapPin size={14} />,
|
||||
chat: <IconMessage size={14} />,
|
||||
network: <IconArrowsLeftRight size={14} />,
|
||||
custom: <IconPointer size={14} />,
|
||||
};
|
||||
|
||||
const EventRow = React.forwardRef(
|
||||
|
|
@ -63,11 +70,9 @@ const EventRow = React.forwardRef(
|
|||
})}
|
||||
>
|
||||
<div className={styles.eventRowIcon}>
|
||||
<i
|
||||
className={
|
||||
EVENT_ROW_SOURCE_ICONS[event.eventSource] || 'bi bi-terminal'
|
||||
}
|
||||
/>
|
||||
{EVENT_ROW_SOURCE_ICONS[event.eventSource] || (
|
||||
<IconTerminal size={14} />
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.eventRowContent} onClick={onClick}>
|
||||
<div className={styles.eventRowTitle}>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
import { Button } from '@mantine/core';
|
||||
import { Drawer } from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconLink, IconX } from '@tabler/icons-react';
|
||||
|
||||
import { Session } from './sessions';
|
||||
import SessionSubpanel from './SessionSubpanel';
|
||||
|
|
@ -123,7 +124,7 @@ export default function SessionSidePanel({
|
|||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
leftSection={<i className="bi bi-link-45deg fs-7.5" />}
|
||||
leftSection={<IconLink size={14} />}
|
||||
style={{ fontSize: '12px' }}
|
||||
>
|
||||
Share Session
|
||||
|
|
@ -135,7 +136,7 @@ export default function SessionSidePanel({
|
|||
onClick={onClose}
|
||||
style={{ padding: '4px 8px' }}
|
||||
>
|
||||
<i className="bi bi-x-lg" />
|
||||
<IconX size={14} />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,15 @@ import {
|
|||
SegmentedControl,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import {
|
||||
IconArrowBackUp,
|
||||
IconArrowForwardUp,
|
||||
IconArrowsMinimize,
|
||||
IconPlayerPause,
|
||||
IconPlayerPlay,
|
||||
IconToggleLeft,
|
||||
IconToggleRight,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import DBRowSidePanel from '@/components/DBRowSidePanel';
|
||||
|
||||
|
|
@ -531,7 +540,7 @@ export default function SessionSubpanel({
|
|||
setEventsFollowPlayerPosition(!eventsFollowPlayerPosition)
|
||||
}
|
||||
>
|
||||
<i className="bi bi-chevron-bar-contract fs-6" />
|
||||
<IconArrowsMinimize size={18} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
|
@ -631,7 +640,7 @@ export default function SessionSubpanel({
|
|||
onClick={skipBackward}
|
||||
disabled={(focus?.ts || 0) <= minTs}
|
||||
>
|
||||
<i className="bi bi-arrow-counterclockwise fs-6" />
|
||||
<IconArrowBackUp size={18} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
|
|
@ -645,11 +654,11 @@ export default function SessionSubpanel({
|
|||
radius="xl"
|
||||
onClick={togglePlayerState}
|
||||
>
|
||||
<i
|
||||
className={`bi fs-4 ${
|
||||
playerState === 'paused' ? 'bi-play-fill' : 'bi-pause-fill'
|
||||
}`}
|
||||
/>
|
||||
{playerState === 'paused' ? (
|
||||
<IconPlayerPlay size={20} />
|
||||
) : (
|
||||
<IconPlayerPause size={20} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
<Tooltip label="Skip 15 seconds" color="gray">
|
||||
|
|
@ -661,7 +670,7 @@ export default function SessionSubpanel({
|
|||
onClick={skipForward}
|
||||
disabled={(focus?.ts || 0) >= maxTs}
|
||||
>
|
||||
<i className="bi bi-arrow-clockwise fs-6" />
|
||||
<IconArrowForwardUp size={18} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
|
@ -672,11 +681,11 @@ export default function SessionSubpanel({
|
|||
variant="light"
|
||||
fw="normal"
|
||||
rightSection={
|
||||
<i
|
||||
className={`bi ${
|
||||
skipInactive ? 'bi-toggle-off' : 'bi-toggle-on'
|
||||
} fs-6 pe-1`}
|
||||
/>
|
||||
skipInactive ? (
|
||||
<IconToggleLeft size={18} className="pe-1" />
|
||||
) : (
|
||||
<IconToggleRight size={18} className="pe-1" />
|
||||
)
|
||||
}
|
||||
onClick={() => setSkipInactive(!skipInactive)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,11 @@ import {
|
|||
Text,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconPlayerPlay } from '@tabler/icons-react';
|
||||
import {
|
||||
IconDeviceLaptop,
|
||||
IconInfoCircleFilled,
|
||||
IconPlayerPlay,
|
||||
} from '@tabler/icons-react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
|
||||
import { SourceSelectControlled } from '@/components/SourceSelect';
|
||||
|
|
@ -511,7 +515,7 @@ export default function SessionsPage() {
|
|||
<>
|
||||
{sessionSource && sessionSource.kind !== SourceKind.Session && (
|
||||
<Alert
|
||||
icon={<i className="bi bi-info-circle-fill " />}
|
||||
icon={<IconInfoCircleFilled size={16} />}
|
||||
color="gray"
|
||||
py="xs"
|
||||
mt="md"
|
||||
|
|
@ -545,7 +549,7 @@ function SessionSetupInstructions() {
|
|||
return (
|
||||
<>
|
||||
<Stack w={500} mx="auto" mt="xl" gap="xxs">
|
||||
<i className="bi bi-laptop text-muted fs-1"></i>
|
||||
<IconDeviceLaptop size={32} className="text-muted" />
|
||||
<Text c="gray" fw={500} size="xs">
|
||||
Instructions
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,19 @@
|
|||
import * as React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Spotlight, SpotlightActionData } from '@mantine/spotlight';
|
||||
import {
|
||||
IconActivityHeartbeat,
|
||||
IconBell,
|
||||
IconChartLine,
|
||||
IconDeviceLaptop,
|
||||
IconGridDots,
|
||||
IconHelpCircle,
|
||||
IconLayout,
|
||||
IconLayoutSidebar,
|
||||
IconLogs,
|
||||
IconSearch,
|
||||
IconSettings,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import api from './api';
|
||||
import Logo from './Icon';
|
||||
|
|
@ -27,7 +40,7 @@ export const useSpotlightActions = () => {
|
|||
logViewActions.push({
|
||||
id: logView._id,
|
||||
group: 'Saved searches',
|
||||
leftSection: <i className="bi bi-layout-text-sidebar-reverse" />,
|
||||
leftSection: <IconLogs size={16} />,
|
||||
description: logView.query,
|
||||
label: logView.name,
|
||||
keywords: ['search', 'log', 'saved'],
|
||||
|
|
@ -42,7 +55,7 @@ export const useSpotlightActions = () => {
|
|||
logViewActions.push({
|
||||
id: dashboard._id,
|
||||
group: 'Dashboards',
|
||||
leftSection: <i className="bi bi-grid-1x2" />,
|
||||
leftSection: <IconLayout size={16} />,
|
||||
label: dashboard.name,
|
||||
keywords: ['dashboard'],
|
||||
onClick: () => {
|
||||
|
|
@ -55,7 +68,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'search',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-layout-text-sidebar-reverse" />,
|
||||
leftSection: <IconLogs size={16} />,
|
||||
label: 'Search',
|
||||
description: 'Start a new search',
|
||||
keywords: ['log', 'events', 'logs'],
|
||||
|
|
@ -66,7 +79,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'chart-explorer',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-graph-up" />,
|
||||
leftSection: <IconChartLine size={16} />,
|
||||
label: 'Chart Explorer',
|
||||
description: 'Explore your data',
|
||||
keywords: ['graph', 'metrics'],
|
||||
|
|
@ -77,7 +90,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'new-dashboard',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-grid-1x2" />,
|
||||
leftSection: <IconGridDots size={16} />,
|
||||
label: 'New Dashboard',
|
||||
description: 'Create a new dashboard',
|
||||
keywords: ['graph'],
|
||||
|
|
@ -88,7 +101,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'sessions',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-laptop" />,
|
||||
leftSection: <IconDeviceLaptop size={16} />,
|
||||
label: 'Client Sessions',
|
||||
description: 'View client sessions',
|
||||
keywords: ['browser', 'web'],
|
||||
|
|
@ -99,7 +112,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'alerts',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-bell" />,
|
||||
leftSection: <IconBell size={16} />,
|
||||
label: 'Alerts',
|
||||
description: 'View and manage alerts',
|
||||
onClick: () => {
|
||||
|
|
@ -110,7 +123,7 @@ export const useSpotlightActions = () => {
|
|||
id: 'service-health',
|
||||
group: 'Menu',
|
||||
label: 'Service Health',
|
||||
leftSection: <i className="bi bi-heart-pulse" />,
|
||||
leftSection: <IconActivityHeartbeat size={16} />,
|
||||
description: 'HTTP, Database and Infrastructure metrics',
|
||||
onClick: () => {
|
||||
router.push('/services');
|
||||
|
|
@ -119,7 +132,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'team-settings',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-gear" />,
|
||||
leftSection: <IconSettings size={16} />,
|
||||
label: 'Team Settings',
|
||||
|
||||
onClick: () => {
|
||||
|
|
@ -129,7 +142,7 @@ export const useSpotlightActions = () => {
|
|||
{
|
||||
id: 'documentation',
|
||||
group: 'Menu',
|
||||
leftSection: <i className="bi bi-question-circle" />,
|
||||
leftSection: <IconHelpCircle size={16} />,
|
||||
label: 'Documentation',
|
||||
keywords: ['help', 'docs'],
|
||||
onClick: () => {
|
||||
|
|
@ -170,7 +183,7 @@ export const HDXSpotlightProvider = ({
|
|||
<Spotlight
|
||||
shortcut="mod + K"
|
||||
searchProps={{
|
||||
leftSection: <i className="bi bi-search" />,
|
||||
leftSection: <IconSearch size={16} />,
|
||||
placeholder: 'Search',
|
||||
}}
|
||||
nothingFound="Nothing found"
|
||||
|
|
|
|||
|
|
@ -28,7 +28,17 @@ import {
|
|||
} from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconPencil } from '@tabler/icons-react';
|
||||
import {
|
||||
IconCheck,
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconClipboard,
|
||||
IconDatabase,
|
||||
IconHelpCircle,
|
||||
IconPencil,
|
||||
IconServer,
|
||||
IconX,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { ConnectionForm } from '@/components/ConnectionForm';
|
||||
import SelectControlled from '@/components/SelectControlled';
|
||||
|
|
@ -84,7 +94,7 @@ function ConnectionsSection() {
|
|||
onClick={() => setEditedConnectionId(c.id)}
|
||||
size="sm"
|
||||
>
|
||||
<i className="bi bi-pencil-fill me-2" /> Edit
|
||||
<IconPencil size={14} className="me-2" /> Edit
|
||||
</Button>
|
||||
)}
|
||||
{editedConnectionId === c.id && (
|
||||
|
|
@ -93,7 +103,7 @@ function ConnectionsSection() {
|
|||
onClick={() => setEditedConnectionId(null)}
|
||||
size="sm"
|
||||
>
|
||||
<i className="bi bi-x-lg me-2" /> Cancel
|
||||
<IconX size={14} className="me-2" /> Cancel
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
|
|
@ -162,23 +172,27 @@ function SourcesSection() {
|
|||
<div>
|
||||
<Text>{s.name}</Text>
|
||||
<Text size="xxs" c="dimmed" mt="xs">
|
||||
{capitalizeFirstLetter(s.kind)}
|
||||
<Text px="md" span>
|
||||
<span className="bi-hdd-stack me-1" />
|
||||
{connections?.find(c => c.id === s.connection)?.name}
|
||||
</Text>
|
||||
{s.from && (
|
||||
<>
|
||||
<span className="bi-database me-1" />
|
||||
{s.from.databaseName}
|
||||
{
|
||||
s.kind === SourceKind.Metric
|
||||
? ''
|
||||
: '.' /** Metrics dont have table names */
|
||||
}
|
||||
{s.from.tableName}
|
||||
</>
|
||||
)}
|
||||
<Group gap="xs">
|
||||
{capitalizeFirstLetter(s.kind)}
|
||||
<Group gap={2}>
|
||||
<IconServer size={14} />
|
||||
{connections?.find(c => c.id === s.connection)?.name}
|
||||
</Group>
|
||||
<Group gap={2}>
|
||||
{s.from && (
|
||||
<>
|
||||
<IconDatabase size={14} />
|
||||
{s.from.databaseName}
|
||||
{
|
||||
s.kind === SourceKind.Metric
|
||||
? ''
|
||||
: '.' /** Metrics dont have table names */
|
||||
}
|
||||
{s.from.tableName}
|
||||
</>
|
||||
)}
|
||||
</Group>
|
||||
</Group>
|
||||
</Text>
|
||||
</div>
|
||||
{editedSourceId !== s.id && (
|
||||
|
|
@ -187,7 +201,7 @@ function SourcesSection() {
|
|||
onClick={() => setEditedSourceId(s.id)}
|
||||
size="sm"
|
||||
>
|
||||
<i className="bi bi-chevron-down" />
|
||||
<IconChevronDown size={14} />
|
||||
</Button>
|
||||
)}
|
||||
{editedSourceId === s.id && (
|
||||
|
|
@ -196,7 +210,7 @@ function SourcesSection() {
|
|||
onClick={() => setEditedSourceId(null)}
|
||||
size="sm"
|
||||
>
|
||||
<i className="bi bi-chevron-up" />
|
||||
<IconChevronUp size={14} />
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
|
|
@ -348,7 +362,7 @@ function IntegrationsSection() {
|
|||
onClick={() => setEditedWebhookId(null)}
|
||||
size="compact-xs"
|
||||
>
|
||||
<i className="bi bi-x-lg me-2" /> Cancel
|
||||
<IconX size={14} className="me-2" /> Cancel
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
|
|
@ -472,7 +486,7 @@ function TeamNameSection() {
|
|||
<Button
|
||||
size="xs"
|
||||
variant="default"
|
||||
leftSection={<i className="bi bi-pencil " />}
|
||||
leftSection={<IconPencil size={16} />}
|
||||
onClick={() => {
|
||||
setIsEditingTeamName(true);
|
||||
}}
|
||||
|
|
@ -578,7 +592,7 @@ function ClickhouseSettingForm({
|
|||
{tooltip && (
|
||||
<Tooltip label={tooltip}>
|
||||
<Text size="sm" style={{ cursor: 'help' }}>
|
||||
<i className="bi bi-question-circle" />
|
||||
<IconHelpCircle size={14} />
|
||||
</Text>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
|
@ -663,7 +677,7 @@ function ClickhouseSettingForm({
|
|||
<Button
|
||||
size="xs"
|
||||
variant="default"
|
||||
leftSection={<i className="bi bi-pencil " />}
|
||||
leftSection={<IconPencil size={16} />}
|
||||
onClick={() => setIsEditing(true)}
|
||||
>
|
||||
Change
|
||||
|
|
@ -756,14 +770,10 @@ const APIKeyCopyButton = ({
|
|||
variant={copied ? 'light' : 'default'}
|
||||
color="gray"
|
||||
rightSection={
|
||||
<div className="ms-2 text-nowrap">
|
||||
{copied ? (
|
||||
<i className="bi bi-check-lg me-2" />
|
||||
) : (
|
||||
<i className="bi bi-clipboard-fill me-2" />
|
||||
)}
|
||||
<Group wrap="nowrap" gap={4} ms="xs">
|
||||
{copied ? <IconCheck size={14} /> : <IconClipboard size={14} />}
|
||||
{copied ? 'Copied!' : 'Copy'}
|
||||
</div>
|
||||
</Group>
|
||||
}
|
||||
>
|
||||
<div data-test-id={dataTestId} className="text-wrap text-break">
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
Switch,
|
||||
Text,
|
||||
} from '@mantine/core';
|
||||
import { IconWorld } from '@tabler/icons-react';
|
||||
|
||||
import { OPTIONS_FONTS } from './config/fonts';
|
||||
import { UserPreferences, useUserPreferences } from './useUserPreferences';
|
||||
|
|
@ -215,7 +216,7 @@ export const UserPreferencesModal = ({
|
|||
<Input
|
||||
placeholder="https:// or data:"
|
||||
value={userPreferences.backgroundUrl}
|
||||
leftSection={<i className="bi bi-globe" />}
|
||||
leftSection={<IconWorld size={16} />}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setUserPreference({
|
||||
backgroundUrl: e.currentTarget.value,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Button, Menu } from '@mantine/core';
|
||||
import { IconTrash } from '@tabler/icons-react';
|
||||
|
||||
export default function ConfirmDeleteMenu({
|
||||
onDelete,
|
||||
|
|
@ -13,10 +14,7 @@ export default function ConfirmDeleteMenu({
|
|||
</Button>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-trash-fill" />}
|
||||
onClick={onDelete}
|
||||
>
|
||||
<Menu.Item leftSection={<IconTrash size={16} />} onClick={onDelete}>
|
||||
Confirm Delete
|
||||
</Menu.Item>
|
||||
</Menu.Dropdown>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useMemo } from 'react';
|
||||
import { UseControllerProps } from 'react-hook-form';
|
||||
import { IconServer } from '@tabler/icons-react';
|
||||
|
||||
import SelectControlled from '@/components/SelectControlled';
|
||||
import { useConnections } from '@/connection';
|
||||
|
|
@ -28,7 +29,7 @@ export function ConnectionSelectControlled({
|
|||
comboboxProps={{ withinPortal: false }}
|
||||
searchable
|
||||
placeholder="Connection"
|
||||
leftSection={<i className="bi bi-hdd-stack"></i>}
|
||||
leftSection={<IconServer size={16} />}
|
||||
maxDropdownHeight={280}
|
||||
size={size}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,22 @@ import {
|
|||
Text,
|
||||
Textarea,
|
||||
} from '@mantine/core';
|
||||
import { IconPlayerPlay } from '@tabler/icons-react';
|
||||
import {
|
||||
IconArrowDown,
|
||||
IconArrowUp,
|
||||
IconBell,
|
||||
IconChartLine,
|
||||
IconCirclePlus,
|
||||
IconCode,
|
||||
IconDotsVertical,
|
||||
IconLayoutGrid,
|
||||
IconList,
|
||||
IconMarkdown,
|
||||
IconNumbers,
|
||||
IconPlayerPlay,
|
||||
IconTable,
|
||||
IconTrash,
|
||||
} from '@tabler/icons-react';
|
||||
import { SortingState } from '@tanstack/react-table';
|
||||
|
||||
import {
|
||||
|
|
@ -216,7 +231,7 @@ function ChartSeriesEditorComponent({
|
|||
onClick={() => onSwapSeries(index, index - 1)}
|
||||
title="Move up"
|
||||
>
|
||||
<i className="bi bi-arrow-up" />
|
||||
<IconArrowUp size={14} />
|
||||
</Button>
|
||||
)}
|
||||
{(index ?? -1) < length - 1 && (
|
||||
|
|
@ -227,7 +242,7 @@ function ChartSeriesEditorComponent({
|
|||
onClick={() => onSwapSeries(index, index + 1)}
|
||||
title="Move down"
|
||||
>
|
||||
<i className="bi bi-arrow-down" />
|
||||
<IconArrowDown size={14} />
|
||||
</Button>
|
||||
)}
|
||||
{((index ?? -1) > 0 || length > 1) && (
|
||||
|
|
@ -237,7 +252,7 @@ function ChartSeriesEditorComponent({
|
|||
size="xs"
|
||||
onClick={() => onRemoveSeries(index)}
|
||||
>
|
||||
<i className="bi bi-trash me-2" />
|
||||
<IconTrash size={14} className="me-2" />
|
||||
Remove Series
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -700,31 +715,31 @@ export default function EditTimeChartForm({
|
|||
<Tabs.List>
|
||||
<Tabs.Tab
|
||||
value={DisplayType.Line}
|
||||
leftSection={<i className="bi bi-graph-up" />}
|
||||
leftSection={<IconChartLine size={16} />}
|
||||
>
|
||||
Line/Bar
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value={DisplayType.Table}
|
||||
leftSection={<i className="bi bi-table" />}
|
||||
leftSection={<IconTable size={16} />}
|
||||
>
|
||||
Table
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value={DisplayType.Number}
|
||||
leftSection={<i className="bi bi-123" />}
|
||||
leftSection={<IconNumbers size={16} />}
|
||||
>
|
||||
Number
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value={DisplayType.Search}
|
||||
leftSection={<i className="bi bi-card-list" />}
|
||||
leftSection={<IconList size={16} />}
|
||||
>
|
||||
Search
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
value={DisplayType.Markdown}
|
||||
leftSection={<i className="bi bi-markdown" />}
|
||||
leftSection={<IconMarkdown size={16} />}
|
||||
>
|
||||
Markdown
|
||||
</Tabs.Tab>
|
||||
|
|
@ -851,7 +866,7 @@ export default function EditTimeChartForm({
|
|||
});
|
||||
}}
|
||||
>
|
||||
<i className="bi bi-plus-circle me-2" />
|
||||
<IconCirclePlus size={14} className="me-2" />
|
||||
Add Series
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -885,7 +900,7 @@ export default function EditTimeChartForm({
|
|||
)
|
||||
}
|
||||
>
|
||||
<i className="bi bi-bell-fill me-2" />
|
||||
<IconBell size={14} className="me-2" />
|
||||
{!alert ? 'Add Alert' : 'Remove Alert'}
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -1070,12 +1085,12 @@ export default function EditTimeChartForm({
|
|||
<Menu width={250}>
|
||||
<Menu.Target>
|
||||
<Button variant="outline" color="gray" px="xs" size="xs">
|
||||
<i className="bi bi-three-dots-vertical" />
|
||||
<IconDotsVertical size={14} />
|
||||
</Button>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-layout-three-columns" />}
|
||||
leftSection={<IconLayoutGrid size={16} />}
|
||||
onClick={() => setSaveToDashboardModalOpen(true)}
|
||||
>
|
||||
Save to Dashboard
|
||||
|
|
@ -1221,7 +1236,7 @@ export default function EditTimeChartForm({
|
|||
{showSampleEvents && (
|
||||
<Accordion defaultValue="sample">
|
||||
<Accordion.Item value="sample">
|
||||
<Accordion.Control icon={<i className="bi bi-card-list"></i>}>
|
||||
<Accordion.Control icon={<IconList size={16} />}>
|
||||
<Text size="sm" style={{ alignSelf: 'center' }}>
|
||||
Sample Matched Events
|
||||
</Text>
|
||||
|
|
@ -1247,7 +1262,7 @@ export default function EditTimeChartForm({
|
|||
)}
|
||||
<Accordion defaultValue="">
|
||||
<Accordion.Item value={'SQL'}>
|
||||
<Accordion.Control icon={<i className="bi bi-code-square"></i>}>
|
||||
<Accordion.Control icon={<IconCode size={16} />}>
|
||||
<Text size="sm" style={{ alignSelf: 'center' }}>
|
||||
Generated SQL
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,17 @@ import {
|
|||
} from '@mantine/core';
|
||||
import { useDebouncedValue } from '@mantine/hooks';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import {
|
||||
IconChartLine,
|
||||
IconCheck,
|
||||
IconCopy,
|
||||
IconFilter,
|
||||
IconMinus,
|
||||
IconPlus,
|
||||
IconSearch,
|
||||
IconSettings,
|
||||
IconTextWrap,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import HyperJson, { GetLineActions, LineAction } from '@/components/HyperJson';
|
||||
import { mergePath } from '@/utils';
|
||||
|
|
@ -81,12 +92,12 @@ function HyperJsonMenu() {
|
|||
setJsonOptions({ ...jsonOptions, lineWrap: !jsonOptions.lineWrap })
|
||||
}
|
||||
>
|
||||
<i className="bi bi-text-wrap" />
|
||||
<IconTextWrap size={14} />
|
||||
</UnstyledButton>
|
||||
<Menu width={240} withinPortal={false}>
|
||||
<Menu.Target>
|
||||
<UnstyledButton>
|
||||
<i className="bi bi-gear" />
|
||||
<IconSettings size={14} />
|
||||
</UnstyledButton>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
|
|
@ -104,7 +115,7 @@ function HyperJsonMenu() {
|
|||
py={8}
|
||||
rightSection={
|
||||
jsonOptions.normallyExpanded ? (
|
||||
<i className="ps-2 bi bi-check2" />
|
||||
<IconCheck size={14} className="ps-2" />
|
||||
) : null
|
||||
}
|
||||
>
|
||||
|
|
@ -114,7 +125,9 @@ function HyperJsonMenu() {
|
|||
lh="1"
|
||||
py={8}
|
||||
rightSection={
|
||||
jsonOptions.tabulate ? <i className="ps-2 bi bi-check2" /> : null
|
||||
jsonOptions.tabulate ? (
|
||||
<IconCheck size={14} className="ps-2" />
|
||||
) : null
|
||||
}
|
||||
onClick={() =>
|
||||
setJsonOptions({
|
||||
|
|
@ -183,10 +196,10 @@ export function DBRowJsonViewer({
|
|||
actions.push({
|
||||
key: 'add-to-search',
|
||||
label: (
|
||||
<>
|
||||
<i className="bi bi-funnel-fill me-1" />
|
||||
<Group gap={2}>
|
||||
<IconFilter size={14} />
|
||||
Add to Filters
|
||||
</>
|
||||
</Group>
|
||||
),
|
||||
title: 'Add to Filters',
|
||||
onClick: () => {
|
||||
|
|
@ -226,10 +239,10 @@ export function DBRowJsonViewer({
|
|||
actions.push({
|
||||
key: 'search',
|
||||
label: (
|
||||
<>
|
||||
<i className="bi bi-search me-1" />
|
||||
<Group gap={2}>
|
||||
<IconSearch size={14} />
|
||||
Search
|
||||
</>
|
||||
</Group>
|
||||
),
|
||||
title: 'Search for this value only',
|
||||
onClick: () => {
|
||||
|
|
@ -271,7 +284,7 @@ export function DBRowJsonViewer({
|
|||
if (generateChartUrl && typeof value === 'number') {
|
||||
actions.push({
|
||||
key: 'chart',
|
||||
label: <i className="bi bi-graph-up" />,
|
||||
label: <IconChartLine size={14} />,
|
||||
title: 'Chart',
|
||||
onClick: () => {
|
||||
let chartFieldPath = fieldPath;
|
||||
|
|
@ -317,15 +330,15 @@ export function DBRowJsonViewer({
|
|||
actions.push({
|
||||
key: 'toggle-column',
|
||||
label: isIncluded ? (
|
||||
<>
|
||||
<i className="bi bi-dash fs-7 me-1" />
|
||||
<Group gap={2}>
|
||||
<IconMinus size={14} />
|
||||
Column
|
||||
</>
|
||||
</Group>
|
||||
) : (
|
||||
<>
|
||||
<i className="bi bi-plus fs-7 me-1" />
|
||||
<Group gap={2}>
|
||||
<IconPlus size={14} />
|
||||
Column
|
||||
</>
|
||||
</Group>
|
||||
),
|
||||
title: isIncluded
|
||||
? `Remove ${fieldPath} column from results table`
|
||||
|
|
@ -372,7 +385,12 @@ export function DBRowJsonViewer({
|
|||
} else {
|
||||
actions.push({
|
||||
key: 'copy-value',
|
||||
label: 'Copy Value',
|
||||
label: (
|
||||
<Group gap={2}>
|
||||
<IconCopy size={14} />
|
||||
Copy Value
|
||||
</Group>
|
||||
),
|
||||
onClick: () => {
|
||||
window.navigator.clipboard.writeText(
|
||||
typeof value === 'string'
|
||||
|
|
@ -415,7 +433,7 @@ export function DBRowJsonViewer({
|
|||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setFilter(e.currentTarget.value)
|
||||
}
|
||||
leftSection={<i className="bi bi-search" />}
|
||||
leftSection={<IconSearch size={16} />}
|
||||
/>
|
||||
{filter && (
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ import {
|
|||
Tooltip,
|
||||
UnstyledButton,
|
||||
} from '@mantine/core';
|
||||
import {
|
||||
IconArrowsDiagonal,
|
||||
IconArrowsDiagonalMinimize2,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { FormatTime } from '@/useFormatTime';
|
||||
import { useUserPreferences } from '@/useUserPreferences';
|
||||
|
|
@ -240,9 +244,9 @@ export default function DBRowSidePanelHeader({
|
|||
>
|
||||
{/* TODO: Only show expand button when maxHeight = 120? */}
|
||||
{expandSidebarHeader ? (
|
||||
<i className="bi bi-arrows-angle-contract" />
|
||||
<IconArrowsDiagonalMinimize2 size={14} />
|
||||
) : (
|
||||
<i className="bi bi-arrows-angle-expand" />
|
||||
<IconArrowsDiagonal size={14} />
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import {
|
|||
import {
|
||||
IconCode,
|
||||
IconDownload,
|
||||
IconRefresh,
|
||||
IconRotateClockwise,
|
||||
IconSettings,
|
||||
IconTextWrap,
|
||||
|
|
@ -272,8 +273,8 @@ const SqlModal = ({
|
|||
<SQLPreview data={sql} enableCopy={true} />
|
||||
) : isLoadingSql ? (
|
||||
<div className="text-center my-2">
|
||||
<div className="spin-animate d-inline-block me-2">
|
||||
<i className="bi bi-arrow-repeat" />
|
||||
<div className="d-inline-block me-2">
|
||||
<IconRefresh size={14} className="spin-animate" />
|
||||
</div>
|
||||
Loading SQL...
|
||||
</div>
|
||||
|
|
@ -956,8 +957,8 @@ export const RawLogTable = memo(
|
|||
<div className="rounded fs-7 bg-muted text-center d-flex align-items-center justify-content-center mt-3">
|
||||
{isLoading ? (
|
||||
<div className="my-3">
|
||||
<div className="spin-animate d-inline-block">
|
||||
<i className="bi bi-arrow-repeat" />
|
||||
<div className="d-inline-block">
|
||||
<IconRefresh size={14} className="spin-animate" />
|
||||
</div>{' '}
|
||||
{loadingDate != null && (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,19 @@ import {
|
|||
UnstyledButton,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import {
|
||||
IconChartBar,
|
||||
IconChartBarOff,
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconChevronUp,
|
||||
IconPin,
|
||||
IconPinFilled,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
IconShadow,
|
||||
IconSitemap,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import {
|
||||
useAllFields,
|
||||
|
|
@ -229,13 +241,13 @@ export const FilterCheckbox = ({
|
|||
)}
|
||||
<TextButton
|
||||
onClick={onClickPin}
|
||||
label={<i className={`bi bi-pin-angle${pinned ? '-fill' : ''}`}></i>}
|
||||
label={pinned ? <IconPinFilled size={14} /> : <IconPin size={14} />}
|
||||
data-testid={`filter-pin-${label}`}
|
||||
/>
|
||||
</div>
|
||||
{pinned && (
|
||||
<Text size="xxs">
|
||||
<i className="bi bi-pin-angle-fill"></i>
|
||||
<IconPinFilled size={12} />
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -602,9 +614,13 @@ export const FilterGroup = ({
|
|||
aria-checked={showDistributions}
|
||||
role="checkbox"
|
||||
>
|
||||
<i
|
||||
className={`bi ${isFetchingDistribution ? 'spinner-border spinner-border-sm' : showDistributions ? 'bi-bar-chart-line-fill' : 'bi-bar-chart-line'}`}
|
||||
/>
|
||||
{isFetchingDistribution ? (
|
||||
<span className="spinner-border spinner-border-sm" />
|
||||
) : showDistributions ? (
|
||||
<IconChartBar size={14} />
|
||||
) : (
|
||||
<IconChartBarOff size={14} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
{onFieldPinClick && (
|
||||
<ActionIcon
|
||||
|
|
@ -615,9 +631,11 @@ export const FilterGroup = ({
|
|||
title={isFieldPinned ? 'Unpin field' : 'Pin field'}
|
||||
me={'4px'}
|
||||
>
|
||||
<i
|
||||
className={`bi bi-pin-angle${isFieldPinned ? '-fill' : ''}`}
|
||||
/>
|
||||
{isFieldPinned ? (
|
||||
<IconPinFilled size={14} />
|
||||
) : (
|
||||
<IconPin size={14} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
)}
|
||||
</>
|
||||
|
|
@ -729,11 +747,11 @@ export const FilterGroup = ({
|
|||
label={
|
||||
shouldShowMore ? (
|
||||
<>
|
||||
<span className="bi-chevron-up" /> Less
|
||||
<IconChevronUp size={12} /> Less
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="bi-chevron-right" /> Show more
|
||||
<IconChevronRight size={12} /> Show more
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -757,7 +775,7 @@ export const FilterGroup = ({
|
|||
display={hasLoadedMore ? 'none' : undefined}
|
||||
label={
|
||||
<>
|
||||
<span className="bi-chevron-right" /> Load more
|
||||
<IconChevronRight size={12} /> Load more
|
||||
</>
|
||||
}
|
||||
onClick={() => onLoadMore(name)}
|
||||
|
|
@ -1143,8 +1161,9 @@ const DBSearchPageFiltersComponent = ({
|
|||
{showRefreshButton && (
|
||||
<TextButton
|
||||
label={
|
||||
<i
|
||||
className="bi-arrow-clockwise ms-1 fs-7"
|
||||
<IconRefresh
|
||||
size={14}
|
||||
className="ms-1"
|
||||
onClick={() => setDateRange(chartConfig.dateRange)}
|
||||
/>
|
||||
}
|
||||
|
|
@ -1174,8 +1193,14 @@ const DBSearchPageFiltersComponent = ({
|
|||
withArrow
|
||||
label="Denoise results will visually remove events matching common event patterns from the results table."
|
||||
>
|
||||
<Text size="xs" mt="-1px">
|
||||
<i className="bi bi-noise-reduction"></i> Denoise Results
|
||||
<Text size="xs" mt="-2px">
|
||||
<Group gap={2}>
|
||||
<IconShadow
|
||||
size={14}
|
||||
style={{ display: 'inline', verticalAlign: 'middle' }}
|
||||
/>
|
||||
Denoise Results
|
||||
</Group>
|
||||
</Text>
|
||||
</Tooltip>
|
||||
}
|
||||
|
|
@ -1197,8 +1222,14 @@ const DBSearchPageFiltersComponent = ({
|
|||
withArrow
|
||||
label="Only show root spans (spans with no parent span)."
|
||||
>
|
||||
<Text size="xs" mt="-1px">
|
||||
<i className="bi bi-diagram-3"></i> Root Spans Only
|
||||
<Text size="xs" mt="-2px">
|
||||
<Group gap={2}>
|
||||
<IconSitemap
|
||||
size={14}
|
||||
style={{ display: 'inline', verticalAlign: 'middle' }}
|
||||
/>
|
||||
Root Spans Only
|
||||
</Group>
|
||||
</Text>
|
||||
</Tooltip>
|
||||
}
|
||||
|
|
@ -1344,7 +1375,11 @@ const DBSearchPageFiltersComponent = ({
|
|||
size="compact-xs"
|
||||
loading={isFacetsFetching}
|
||||
rightSection={
|
||||
<i className={`bi-chevron-${showMoreFields ? 'up' : 'down'}`} />
|
||||
showMoreFields ? (
|
||||
<IconChevronUp size={14} />
|
||||
) : (
|
||||
<IconChevronDown size={14} />
|
||||
)
|
||||
}
|
||||
onClick={() => setShowMoreFields(!showMoreFields)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useController, UseControllerProps } from 'react-hook-form';
|
||||
import { Flex, Select } from '@mantine/core';
|
||||
import { IconTable } from '@tabler/icons-react';
|
||||
|
||||
import { useTablesDirect } from '@/clickhouse';
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ export default function DBTableSelect({
|
|||
<Select
|
||||
searchable
|
||||
placeholder="Table"
|
||||
leftSection={<i className="bi bi-table"></i>}
|
||||
leftSection={<IconTable size={16} />}
|
||||
maxDropdownHeight={280}
|
||||
data={data}
|
||||
disabled={isTablesLoading}
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ function DBTimeChartComponent({
|
|||
} groups are hidden. Try grouping by a different field.`}
|
||||
>
|
||||
<span className="text-muted-hover text-decoration-none fs-8">
|
||||
<i className="bi bi-exclamation-triangle"></i> Only top{' '}
|
||||
<IconAlertTriangle size={14} style={{ display: 'inline' }} /> Only top{' '}
|
||||
{groupKeys.length} groups shown
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
Stack,
|
||||
Text,
|
||||
} from '@mantine/core';
|
||||
import { IconPencil } from '@tabler/icons-react';
|
||||
|
||||
import { DBTraceWaterfallChartContainer } from '@/components/DBTraceWaterfallChart';
|
||||
import { useSource, useUpdateSource } from '@/source';
|
||||
|
|
@ -135,7 +136,7 @@ export default function DBTracePanel({
|
|||
size="xs"
|
||||
onClick={() => setShowTraceIdInput(v => !v)}
|
||||
>
|
||||
<i className="bi bi-pencil"></i>
|
||||
<IconPencil size={14} />
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,12 @@ import {
|
|||
SourceKind,
|
||||
TSource,
|
||||
} from '@hyperdx/common-utils/dist/types';
|
||||
import { Anchor, Box, Code, Divider, Group, Text } from '@mantine/core';
|
||||
import { Anchor, Box, Center, Code, Divider, Group, Text } from '@mantine/core';
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconLogs,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { ContactSupportText } from '@/components/ContactSupportText';
|
||||
import useOffsetPaginatedQuery from '@/hooks/useOffsetPaginatedQuery';
|
||||
|
|
@ -667,9 +672,7 @@ export function DBTraceWaterfallChartContainer({
|
|||
}}
|
||||
></div>
|
||||
))}
|
||||
<Text
|
||||
span
|
||||
me="xxs"
|
||||
<Center
|
||||
style={{
|
||||
opacity: result.children.length > 0 ? 1 : 0,
|
||||
}}
|
||||
|
|
@ -677,12 +680,12 @@ export function DBTraceWaterfallChartContainer({
|
|||
toggleCollapse(id);
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className={`bi bi-chevron-${
|
||||
collapsedIds.has(id) ? 'right' : 'down'
|
||||
}`}
|
||||
/>{' '}
|
||||
</Text>
|
||||
{collapsedIds.has(id) ? (
|
||||
<IconChevronRight size={16} className="me-1 text-muted-hover" />
|
||||
) : (
|
||||
<IconChevronDown size={16} className="me-1 text-muted-hover" />
|
||||
)}{' '}
|
||||
</Center>
|
||||
{!isFilterActive && (
|
||||
<Text span size="xxs" me="xs" pt="2px">
|
||||
{result.children.length > 0
|
||||
|
|
@ -690,26 +693,30 @@ export function DBTraceWaterfallChartContainer({
|
|||
: ''}
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
size="xxs"
|
||||
truncate="end"
|
||||
// style={{ width: 200 }}
|
||||
span
|
||||
// onClick={() => {
|
||||
// toggleCollapse(id);
|
||||
// }}
|
||||
title={`${serviceName}${hasHttpAttributes && httpUrl ? ` | ${displayText}` : ''}`}
|
||||
role="button"
|
||||
>
|
||||
|
||||
<Group gap={0} wrap="nowrap">
|
||||
{type === SourceKind.Log ? (
|
||||
<i
|
||||
className="bi bi-card-text fs-8 me-2 align-middle"
|
||||
title="Correlated Log Line"
|
||||
<IconLogs
|
||||
size={14}
|
||||
className="align-middle me-2"
|
||||
aria-label="Correlated Log Line"
|
||||
/>
|
||||
) : null}
|
||||
{serviceName ? `${serviceName} | ` : ''}
|
||||
{displayText}
|
||||
</Text>
|
||||
<Text
|
||||
size="xxs"
|
||||
truncate="end"
|
||||
// style={{ width: 200 }}
|
||||
span
|
||||
// onClick={() => {
|
||||
// toggleCollapse(id);
|
||||
// }}
|
||||
title={`${serviceName}${hasHttpAttributes && httpUrl ? ` | ${displayText}` : ''}`}
|
||||
role="button"
|
||||
>
|
||||
{serviceName ? `${serviceName} | ` : ''}
|
||||
{displayText}
|
||||
</Text>
|
||||
</Group>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useController, UseControllerProps } from 'react-hook-form';
|
||||
import { Select } from '@mantine/core';
|
||||
import { IconDatabase } from '@tabler/icons-react';
|
||||
|
||||
import { useDatabasesDirect } from '@/clickhouse';
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ export default function DatabaseSelect({
|
|||
<Select
|
||||
searchable
|
||||
placeholder="Database"
|
||||
leftSection={<i className="bi bi-database"></i>}
|
||||
leftSection={<IconDatabase size={16} />}
|
||||
maxDropdownHeight={280}
|
||||
data={data}
|
||||
disabled={isDatabasesLoading}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import React from 'react';
|
||||
import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary';
|
||||
import { Alert, Button, Stack, Text } from '@mantine/core';
|
||||
|
||||
import { Icon } from './Icon';
|
||||
import { IconInfoCircleFilled } from '@tabler/icons-react';
|
||||
|
||||
type ErrorBoundaryProps = {
|
||||
children: React.ReactNode;
|
||||
|
|
@ -33,7 +32,7 @@ export const ErrorBoundary = ({
|
|||
<Alert
|
||||
p="xs"
|
||||
color="orange"
|
||||
icon={<Icon name="info-circle-fill" />}
|
||||
icon={<IconInfoCircleFilled size={16} />}
|
||||
title={message || 'Something went wrong'}
|
||||
>
|
||||
{(showErrorMessage || showRetry) && (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Link from 'next/link';
|
|||
import SqlString from 'sqlstring';
|
||||
import { SearchConditionLanguage } from '@hyperdx/common-utils/dist/types';
|
||||
import { Button, Group, Popover, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { IconLink } from '@tabler/icons-react';
|
||||
import { IconCirclePlus, IconLink, IconSearch } from '@tabler/icons-react';
|
||||
|
||||
import { isLinkableUrl } from '@/utils/highlightedAttributes';
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ export default function EventTag({
|
|||
color="gray"
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
rightSection={<i className="bi bi-plus-circle" />}
|
||||
rightSection={<IconCirclePlus size={14} />}
|
||||
onClick={() => {
|
||||
onPropertyAddClick(sqlExpression, value);
|
||||
setOpened(false);
|
||||
|
|
@ -123,7 +123,7 @@ export default function EventTag({
|
|||
color="gray"
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
rightSection={<i className="bi bi-search" />}
|
||||
rightSection={<IconSearch size={14} />}
|
||||
>
|
||||
Search This Value
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ import cx from 'classnames';
|
|||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { Button, Text, Tooltip } from '@mantine/core';
|
||||
import { Group, Loader } from '@mantine/core';
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconChevronUp,
|
||||
IconLogs,
|
||||
} from '@tabler/icons-react';
|
||||
import { ColumnDef, Row, Table as TanstackTable } from '@tanstack/react-table';
|
||||
|
||||
import { StacktraceFrame as TStacktraceFrame } from '@/types';
|
||||
|
|
@ -126,7 +132,11 @@ export const CollapsibleSection = ({
|
|||
role="button"
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
>
|
||||
<i className={`bi bi-chevron-${collapsed ? 'right' : 'down'} me-2`}></i>
|
||||
{collapsed ? (
|
||||
<IconChevronRight size={14} className="me-2" />
|
||||
) : (
|
||||
<IconChevronDown size={14} className="me-2" />
|
||||
)}
|
||||
<div className="fs-7">{title}</div>
|
||||
</div>
|
||||
{collapsed ? null : <div className="mb-4">{children}</div>}
|
||||
|
|
@ -226,7 +236,7 @@ export const StacktraceRow = ({
|
|||
withArrow
|
||||
color="gray"
|
||||
>
|
||||
<i className="bi bi-box-seam me-2" title="in_app: false" />
|
||||
<IconLogs size={14} className="me-2" aria-label="in_app: false" />
|
||||
</Tooltip>
|
||||
)}
|
||||
{augmentedFrame && (
|
||||
|
|
@ -618,11 +628,11 @@ export const ExceptionSubpanel = ({
|
|||
>
|
||||
{stacktraceExpanded ? (
|
||||
<>
|
||||
<i className="bi bi-chevron-up me-2" /> Hide stack trace
|
||||
<IconChevronUp size={14} className="me-2" /> Hide stack trace
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<i className="bi bi-chevron-down me-2" />
|
||||
<IconChevronDown size={14} className="me-2" />
|
||||
Show {stacktraceHiddenRowsCount} more frames
|
||||
</>
|
||||
)}
|
||||
|
|
@ -647,11 +657,12 @@ export const ExceptionSubpanel = ({
|
|||
>
|
||||
{breadcrumbExpanded ? (
|
||||
<>
|
||||
<i className="bi bi-chevron-up me-2" /> Hide breadcrumbs
|
||||
<IconChevronUp size={14} className="me-2" /> Hide
|
||||
breadcrumbs
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<i className="bi bi-chevron-down me-2" />
|
||||
<IconChevronDown size={14} className="me-2" />
|
||||
Show {breadcrumbHiddenRowsCount} more breadcrumbs
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React, { memo, useCallback, useState } from 'react';
|
|||
import cx from 'classnames';
|
||||
import { useQueryState } from 'nuqs';
|
||||
import { TSource } from '@hyperdx/common-utils/dist/types';
|
||||
import { IconChevronRight } from '@tabler/icons-react';
|
||||
import { IconArrowsMaximize, IconChevronRight } from '@tabler/icons-react';
|
||||
|
||||
import styles from '../../styles/LogTable.module.scss';
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ export const ExpandedLogRow = memo(
|
|||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
<i className="bi bi-arrows-angle-expand" />
|
||||
<IconArrowsMaximize size={14} />
|
||||
</button>
|
||||
)}
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ import {
|
|||
isString,
|
||||
} from 'lodash';
|
||||
import { useHover } from '@mantine/hooks';
|
||||
import {
|
||||
IconCaretDownFilled,
|
||||
IconCaretRightFilled,
|
||||
IconClipboard,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import styles from './HyperJson.module.scss';
|
||||
|
||||
|
|
@ -264,13 +269,13 @@ const Line = React.memo(
|
|||
<div className={styles.key}>
|
||||
{isExpandable &&
|
||||
(isExpanded ? (
|
||||
<i className="bi bi-caret-down-fill fs-9"></i>
|
||||
<IconCaretDownFilled size={10} />
|
||||
) : (
|
||||
<i className="bi bi-caret-right-fill fs-9"></i>
|
||||
<IconCaretRightFilled size={10} />
|
||||
))}
|
||||
{keyName}
|
||||
<div className={styles.hoverContent}>
|
||||
<i className="bi bi-clipboard" />
|
||||
<IconClipboard size={14} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3,15 +3,9 @@ import Link from 'next/link';
|
|||
import { pickBy } from 'lodash';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import { JSONTree } from 'react-json-tree';
|
||||
import {
|
||||
Accordion,
|
||||
Box,
|
||||
Button,
|
||||
CopyButton,
|
||||
TableData,
|
||||
Text,
|
||||
} from '@mantine/core';
|
||||
import { Accordion, Box, Button, CopyButton, TableData } from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconTerminal } from '@tabler/icons-react';
|
||||
|
||||
import HyperJson from '@/components/HyperJson';
|
||||
import { Table } from '@/components/Table';
|
||||
|
|
@ -229,7 +223,7 @@ export function NetworkPropertySubpanel({
|
|||
}}
|
||||
>
|
||||
<Button size="xs" variant="light">
|
||||
<i className="bi bi-terminal-plus me-2" />
|
||||
<IconTerminal size={14} className="me-2" />
|
||||
Copy Request as Curl
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
|
|
@ -240,7 +234,7 @@ export function NetworkPropertySubpanel({
|
|||
size="sm"
|
||||
as="a"
|
||||
>
|
||||
<i className="bi bi-graph-up me-2" />
|
||||
<IconChartLine size={14} className="me-2" />
|
||||
Endpoint Trends
|
||||
</Button>
|
||||
</Link> */}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@ import {
|
|||
TextInput,
|
||||
} from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import {
|
||||
IconClock,
|
||||
IconCurrencyDollar,
|
||||
IconDatabase,
|
||||
IconNumbers,
|
||||
IconPercentage,
|
||||
IconX,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { NumberFormat } from '../types';
|
||||
import { formatNumber } from '../utils';
|
||||
|
|
@ -23,12 +31,12 @@ const FORMAT_NAMES: Record<string, string> = {
|
|||
time: 'Time',
|
||||
};
|
||||
|
||||
const FORMAT_ICONS: Record<string, string> = {
|
||||
number: '123',
|
||||
currency: 'currency-dollar',
|
||||
percent: 'percent',
|
||||
byte: 'database',
|
||||
time: 'clock',
|
||||
const FORMAT_ICONS: Record<string, React.ReactNode> = {
|
||||
number: <IconNumbers size={14} />,
|
||||
currency: <IconCurrencyDollar size={14} />,
|
||||
percent: <IconPercentage size={14} />,
|
||||
byte: <IconDatabase size={14} />,
|
||||
time: <IconClock size={14} />,
|
||||
};
|
||||
|
||||
export const NumberFormatForm: React.FC<{
|
||||
|
|
@ -83,11 +91,7 @@ export const NumberFormatForm: React.FC<{
|
|||
>
|
||||
<NativeSelect
|
||||
label="Output format"
|
||||
leftSection={
|
||||
values.output && (
|
||||
<i className={`bi bi-${FORMAT_ICONS[values.output]}`} />
|
||||
)
|
||||
}
|
||||
leftSection={values.output && FORMAT_ICONS[values.output]}
|
||||
style={{ flex: 1 }}
|
||||
data={[
|
||||
{ value: 'number', label: 'Number' },
|
||||
|
|
@ -234,11 +238,7 @@ export const NumberFormatInput: React.FC<{
|
|||
size="compact-sm"
|
||||
color="dark"
|
||||
variant="default"
|
||||
leftSection={
|
||||
value?.output && (
|
||||
<i className={`bi bi-${FORMAT_ICONS[value.output]}`} />
|
||||
)
|
||||
}
|
||||
leftSection={value?.output && FORMAT_ICONS[value.output]}
|
||||
>
|
||||
{value?.output ? FORMAT_NAMES[value.output] : 'Set number format'}
|
||||
</Button>
|
||||
|
|
@ -250,7 +250,7 @@ export const NumberFormatInput: React.FC<{
|
|||
px="xs"
|
||||
onClick={() => handleApply(undefined)}
|
||||
>
|
||||
<i className="bi bi-x-lg" />
|
||||
<IconX size={14} />
|
||||
</Button>
|
||||
)}
|
||||
</Button.Group>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {
|
|||
} from '@hyperdx/common-utils/dist/types';
|
||||
import { Button, Divider, Modal, Text } from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconArrowLeft } from '@tabler/icons-react';
|
||||
|
||||
import { ConnectionForm } from '@/components/ConnectionForm';
|
||||
import { IS_LOCAL_MODE } from '@/config';
|
||||
|
|
@ -400,7 +401,7 @@ export default function OnboardingModal({
|
|||
p="xs"
|
||||
mb="md"
|
||||
>
|
||||
<i className="bi bi-arrow-left me-2" /> Back
|
||||
<IconArrowLeft size={14} className="me-2" /> Back
|
||||
</Button>
|
||||
<Text size="sm" mb="md">
|
||||
Lets set up a source table to query telemetry from.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Button, Menu, Text } from '@mantine/core';
|
||||
import { IconDotsVertical, IconForms, IconTrash } from '@tabler/icons-react';
|
||||
|
||||
export default function SearchPageActionBar({
|
||||
onClickDeleteSavedSearch,
|
||||
|
|
@ -17,19 +18,19 @@ export default function SearchPageActionBar({
|
|||
size="xs"
|
||||
style={{ flexShrink: 0 }}
|
||||
>
|
||||
<i className="bi bi-three-dots-vertical" />
|
||||
<IconDotsVertical size={14} />
|
||||
</Button>
|
||||
</Menu.Target>
|
||||
|
||||
<Menu.Dropdown>
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-trash-fill" />}
|
||||
leftSection={<IconTrash size={16} />}
|
||||
onClick={onClickDeleteSavedSearch}
|
||||
>
|
||||
Delete Saved Search
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
leftSection={<i className="bi bi-input-cursor-text" />}
|
||||
leftSection={<IconForms size={16} />}
|
||||
onClick={onClickRenameSavedSearch}
|
||||
>
|
||||
Rename Saved Search
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useCallback, useMemo } from 'react';
|
|||
import { parseAsString, useQueryState } from 'nuqs';
|
||||
import type { Filter } from '@hyperdx/common-utils/dist/types';
|
||||
import { Drawer, Grid, Group, Text } from '@mantine/core';
|
||||
import { IconServer } from '@tabler/icons-react';
|
||||
|
||||
import { INTEGER_NUMBER_FORMAT, MS_NUMBER_FORMAT } from '@/ChartUtils';
|
||||
import { ChartBox } from '@/components/ChartBox';
|
||||
|
|
@ -76,7 +77,7 @@ export default function ServiceDashboardDbQuerySidePanel({
|
|||
Details for {dbQuery}
|
||||
{service && (
|
||||
<Text component="span" c="gray" fz="xs">
|
||||
<i className="bi bi-hdd ms-3 me-1" />
|
||||
<IconServer size={14} className="ms-3 me-1" />
|
||||
{service}
|
||||
</Text>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useCallback, useMemo } from 'react';
|
|||
import { parseAsString, useQueryState } from 'nuqs';
|
||||
import type { Filter } from '@hyperdx/common-utils/dist/types';
|
||||
import { Drawer, Grid, Group, Text } from '@mantine/core';
|
||||
import { IconServer } from '@tabler/icons-react';
|
||||
|
||||
import {
|
||||
ERROR_RATE_PERCENTAGE_NUMBER_FORMAT,
|
||||
|
|
@ -83,7 +84,7 @@ export default function ServiceDashboardEndpointSidePanel({
|
|||
Details for {endpoint}
|
||||
{service && (
|
||||
<Text component="span" c="gray" fz="xs">
|
||||
<i className="bi bi-hdd ms-3 me-1" />
|
||||
<IconServer size={14} className="ms-3 me-1" />
|
||||
{service}
|
||||
</Text>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import {
|
|||
Anchor,
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Divider,
|
||||
Flex,
|
||||
Grid,
|
||||
|
|
@ -31,7 +32,12 @@ import {
|
|||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconTrash } from '@tabler/icons-react';
|
||||
import {
|
||||
IconCirclePlus,
|
||||
IconHelpCircle,
|
||||
IconSettings,
|
||||
IconTrash,
|
||||
} from '@tabler/icons-react';
|
||||
|
||||
import { SourceSelectControlled } from '@/components/SourceSelect';
|
||||
import { IS_METRICS_ENABLED, IS_SESSIONS_ENABLED } from '@/config';
|
||||
|
|
@ -125,16 +131,17 @@ function FormRow({
|
|||
label
|
||||
)}
|
||||
</Stack>
|
||||
<Text
|
||||
<Center
|
||||
me="sm"
|
||||
ms="sm"
|
||||
style={{
|
||||
...(!helpText ? { opacity: 0, pointerEvents: 'none' } : {}),
|
||||
}}
|
||||
>
|
||||
<Tooltip label={helpText} color="dark" c="white" multiline maw={600}>
|
||||
<i className="bi bi-question-circle cursor-pointer" />
|
||||
<IconHelpCircle size={20} className="cursor-pointer" />
|
||||
</Tooltip>
|
||||
</Text>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Box
|
||||
w="100%"
|
||||
|
|
@ -229,7 +236,7 @@ function HighlightedAttributeExpressionsFormRow({
|
|||
multiline
|
||||
maw={600}
|
||||
>
|
||||
<i className="bi bi-question-circle cursor-pointer" />
|
||||
<IconHelpCircle size={14} className="cursor-pointer" />
|
||||
</Tooltip>
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
|
|
@ -250,7 +257,7 @@ function HighlightedAttributeExpressionsFormRow({
|
|||
});
|
||||
}}
|
||||
>
|
||||
<i className="bi bi-plus-circle me-2" />
|
||||
<IconCirclePlus size={14} className="me-2" />
|
||||
Add expression
|
||||
</Button>
|
||||
</FormRow>
|
||||
|
|
@ -313,10 +320,10 @@ export function LogTableModelForm(props: TableModelProps) {
|
|||
onClick={() => setShowOptionalFields(true)}
|
||||
size="xs"
|
||||
>
|
||||
<Text me="sm" span>
|
||||
<i className="bi bi-gear" />
|
||||
</Text>
|
||||
Configure Optional Fields
|
||||
<Group gap="xs">
|
||||
<IconSettings size={14} />
|
||||
Configure Optional Fields
|
||||
</Group>
|
||||
</Anchor>
|
||||
)}
|
||||
{showOptionalFields && (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useState } from 'react';
|
||||
import { MetricsDataType, TSource } from '@hyperdx/common-utils/dist/types';
|
||||
import { Modal, Paper, Tabs, Text, TextProps, Tooltip } from '@mantine/core';
|
||||
import { IconCode } from '@tabler/icons-react';
|
||||
import { IconCode, IconRefresh } from '@tabler/icons-react';
|
||||
|
||||
import { useTableMetadata } from '@/hooks/useMetadata';
|
||||
|
||||
|
|
@ -77,8 +77,8 @@ const TableSchemaPreview = ({
|
|||
style={{ overflow: 'hidden' }}
|
||||
>
|
||||
{isLoading ? (
|
||||
<div className="spin-animate d-inline-block">
|
||||
<i className="bi bi-arrow-repeat" />
|
||||
<div className="d-inline-block">
|
||||
<IconRefresh className="spin-animate" />
|
||||
</div>
|
||||
) : (
|
||||
<SQLPreview
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { UseControllerProps } from 'react-hook-form';
|
|||
import { SourceKind } from '@hyperdx/common-utils/dist/types';
|
||||
import { SelectProps, UnstyledButton } from '@mantine/core';
|
||||
import { ComboboxChevron } from '@mantine/core';
|
||||
import { IconStack } from '@tabler/icons-react';
|
||||
|
||||
import SelectControlled from '@/components/SelectControlled';
|
||||
import { HDX_LOCAL_DEFAULT_SOURCES } from '@/config';
|
||||
|
|
@ -94,7 +95,7 @@ function SourceSelectControlledComponent({
|
|||
comboboxProps={{ withinPortal: false, ...comboboxProps }}
|
||||
searchable
|
||||
placeholder="Data Source"
|
||||
leftSection={<i className="bi bi-collection"></i>}
|
||||
leftSection={<IconStack size={16} />}
|
||||
maxDropdownHeight={280}
|
||||
size={size}
|
||||
onCreate={onCreate}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useMemo } from 'react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { Box, Button, Text } from '@mantine/core';
|
||||
import { IconChevronDown, IconChevronUp } from '@tabler/icons-react';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
import { FormatTime } from '@/useFormatTime';
|
||||
|
|
@ -128,11 +129,11 @@ export const SpanEventsSubpanel = ({
|
|||
>
|
||||
{isExpanded ? (
|
||||
<>
|
||||
<i className="bi bi-chevron-up me-2" /> Hide events
|
||||
<IconChevronUp size={14} className="me-2" /> Hide events
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<i className="bi bi-chevron-down me-2" />
|
||||
<IconChevronDown size={14} className="me-2" />
|
||||
Show {hiddenRowsCount} more events
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import cx from 'classnames';
|
||||
import { IconChevronDown, IconChevronUp } from '@tabler/icons-react';
|
||||
import {
|
||||
ColumnDef,
|
||||
flexRender,
|
||||
|
|
@ -108,13 +109,14 @@ export const Table = <T extends Record<string, unknown> | string[]>({
|
|||
export const TableCellButton: React.FC<{
|
||||
title?: string;
|
||||
label: React.ReactNode;
|
||||
biIcon?: string;
|
||||
biIcon?: 'chevron-up' | 'chevron-down';
|
||||
onClick: VoidFunction;
|
||||
}> = ({ onClick, title, label, biIcon }) => {
|
||||
return (
|
||||
<button className={styles.tableCellButton} title={title} onClick={onClick}>
|
||||
{label && <span>{label}</span>}
|
||||
{biIcon ? <i className={`bi bi-${biIcon}`} /> : null}
|
||||
{biIcon === 'chevron-up' && <IconChevronUp size={14} />}
|
||||
{biIcon === 'chevron-down' && <IconChevronDown size={14} />}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
ScrollArea,
|
||||
Stack,
|
||||
} from '@mantine/core';
|
||||
import { IconSearch, IconTags } from '@tabler/icons-react';
|
||||
|
||||
import api from '@/api';
|
||||
|
||||
|
|
@ -101,7 +102,7 @@ export const Tags = React.memo(
|
|||
color="gray"
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<i className="bi bi-tags fs-7" />
|
||||
<IconTags size={14} />
|
||||
</ActionIcon>
|
||||
)}
|
||||
</Popover.Target>
|
||||
|
|
@ -112,7 +113,7 @@ export const Tags = React.memo(
|
|||
size="xs"
|
||||
placeholder={allowCreate ? 'Search or create tag' : 'Search tag'}
|
||||
variant="filled"
|
||||
leftSection={<i className="bi bi-search" />}
|
||||
leftSection={<IconSearch size={16} />}
|
||||
autoFocus
|
||||
m={8}
|
||||
mb={0}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
TextInput,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconLock, IconUserPlus } from '@tabler/icons-react';
|
||||
|
||||
import api from '@/api';
|
||||
|
||||
|
|
@ -215,7 +216,7 @@ export default function TeamMembersSection() {
|
|||
<div className="fs-7">Team Members</div>
|
||||
<Button
|
||||
variant="light"
|
||||
leftSection={<i className="bi bi-person-plus-fill" />}
|
||||
leftSection={<IconUserPlus size={16} />}
|
||||
onClick={() => setTeamInviteModalShow(true)}
|
||||
>
|
||||
Invite Team Member
|
||||
|
|
@ -244,7 +245,7 @@ export default function TeamMembersSection() {
|
|||
<div>{member.email}</div>
|
||||
{member.hasPasswordAuth && (
|
||||
<div>
|
||||
<i className="bi bi-lock-fill" /> Password Auth
|
||||
<IconLock size={14} /> Password Auth
|
||||
</div>
|
||||
)}
|
||||
</Group>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import {
|
|||
TextInput,
|
||||
} from '@mantine/core';
|
||||
import { notifications } from '@mantine/notifications';
|
||||
import { IconInfoCircleFilled } from '@tabler/icons-react';
|
||||
import ReactCodeMirror, {
|
||||
EditorView,
|
||||
placeholder,
|
||||
|
|
@ -373,7 +374,7 @@ export function WebhookForm({
|
|||
/>
|
||||
</div>,
|
||||
<Alert
|
||||
icon={<i className="bi bi-info-circle-fill " />}
|
||||
icon={<IconInfoCircleFilled size={16} />}
|
||||
key="5"
|
||||
className="mb-4"
|
||||
color="gray"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Button } from '@mantine/core';
|
||||
import type { Meta } from '@storybook/nextjs';
|
||||
import { IconStarFilled } from '@tabler/icons-react';
|
||||
|
||||
// Just a test story, can be deleted
|
||||
|
||||
|
|
@ -14,7 +15,7 @@ const meta: Meta = {
|
|||
export const Default = () => (
|
||||
<Button
|
||||
variant="light"
|
||||
leftSection={<i className="bi bi-star-fill" />}
|
||||
leftSection={<IconStarFilled size={14} />}
|
||||
size="compact-sm"
|
||||
>
|
||||
Assign exception to Warren
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
// Custom utilities (bg-surface, border-dark, etc.)
|
||||
@use './_utilities';
|
||||
@import url('https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css');
|
||||
|
||||
.inter {
|
||||
font-family: var(--font-inter), 'Helvetica Neue', sans-serif;
|
||||
|
|
|
|||
|
|
@ -176,7 +176,9 @@ test.describe('Kubernetes Dashboard', { tag: ['@kubernetes'] }, () => {
|
|||
});
|
||||
|
||||
test.describe('Pods Table Sorting', () => {
|
||||
const SORT_ICON_SELECTOR = 'i.bi-caret-down-fill, i.bi-caret-up-fill';
|
||||
// Tabler icons render as SVG elements with class 'tabler-icon'
|
||||
const SORT_ICON_SELECTOR =
|
||||
'svg.tabler-icon-caret-down-filled, svg.tabler-icon-caret-up-filled';
|
||||
|
||||
async function waitForTableLoad(page: Page): Promise<Locator> {
|
||||
const podsTable = page.getByTestId('k8s-pods-table');
|
||||
|
|
@ -196,7 +198,9 @@ test.describe('Kubernetes Dashboard', { tag: ['@kubernetes'] }, () => {
|
|||
const podsTable = await waitForTableLoad(page);
|
||||
const restartsHeader = getColumnHeader(podsTable, 'Restarts');
|
||||
|
||||
await expect(restartsHeader.locator('i.bi-caret-down-fill')).toBeVisible({
|
||||
await expect(
|
||||
restartsHeader.locator('svg.tabler-icon-caret-down-filled'),
|
||||
).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
|
|
@ -210,7 +214,9 @@ test.describe('Kubernetes Dashboard', { tag: ['@kubernetes'] }, () => {
|
|||
await restartsHeader.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await expect(restartsHeader.locator('i.bi-caret-up-fill')).toBeVisible();
|
||||
await expect(
|
||||
restartsHeader.locator('svg.tabler-icon-caret-up-filled'),
|
||||
).toBeVisible();
|
||||
|
||||
const firstRestartsAfter = await podsTable
|
||||
.locator('tbody tr')
|
||||
|
|
|
|||
Loading…
Reference in a new issue