mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat: Placeholder page for Service Dashboard (#180)

This commit is contained in:
parent
2910461669
commit
8815eff9b8
6 changed files with 171 additions and 1 deletions
5
.changeset/thin-carpets-tease.md
Normal file
5
.changeset/thin-carpets-tease.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hyperdx/app': patch
|
||||
---
|
||||
|
||||
Placeholder page for Service Dashboard
|
||||
3
packages/app/pages/services.tsx
Normal file
3
packages/app/pages/services.tsx
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import ServiceDashboardPage from '../src/ServiceDashboardPage';
|
||||
|
||||
export default ServiceDashboardPage;
|
||||
|
|
@ -17,7 +17,7 @@ import { version } from '../package.json';
|
|||
|
||||
import api from './api';
|
||||
import AuthLoadingBlocker from './AuthLoadingBlocker';
|
||||
import { API_SERVER_URL } from './config';
|
||||
import { API_SERVER_URL, SERVICE_DASHBOARD_ENABLED } from './config';
|
||||
import Icon from './Icon';
|
||||
import Logo from './Logo';
|
||||
import { useWindowSize } from './utils';
|
||||
|
|
@ -694,6 +694,25 @@ export default function AppNav({ fixed = false }: { fixed?: boolean }) {
|
|||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
{SERVICE_DASHBOARD_ENABLED ? (
|
||||
<div className="my-4">
|
||||
<Link href="/services">
|
||||
<a
|
||||
className={cx(
|
||||
'text-decoration-none d-flex justify-content-between align-items-center fs-6 text-muted-hover',
|
||||
{
|
||||
'fw-bold text-success': pathname.includes('/services'),
|
||||
},
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
<i className="bi bi-heart-pulse" />{' '}
|
||||
{!isCollapsed && <span>Service Health</span>}
|
||||
</span>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
) : null}
|
||||
<div>
|
||||
<div
|
||||
className={cx(
|
||||
|
|
|
|||
141
packages/app/src/ServiceDashboardPage.tsx
Normal file
141
packages/app/src/ServiceDashboardPage.tsx
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
import * as React from 'react';
|
||||
import Head from 'next/head';
|
||||
import { StringParam, useQueryParam, withDefault } from 'use-query-params';
|
||||
import { Group, Select, Tabs } from '@mantine/core';
|
||||
|
||||
import AppNav from './AppNav';
|
||||
import SearchInput from './SearchInput';
|
||||
import SearchTimeRangePicker from './SearchTimeRangePicker';
|
||||
import { parseTimeQuery, useTimeQuery } from './timeQuery';
|
||||
|
||||
import styles from '../styles/ServiceDashboardPage.module.scss';
|
||||
|
||||
const defaultTimeRange = parseTimeQuery('Past 1h', false);
|
||||
|
||||
const MOCK_SERVICES = Array.from({ length: 100 }).map((_, i) => ({
|
||||
value: `service-${i}`,
|
||||
label: `service-${i}`,
|
||||
}));
|
||||
|
||||
export default function ServiceDashboardPage() {
|
||||
const searchInputRef = React.useRef<HTMLInputElement>(null);
|
||||
|
||||
const [_searchQuery, _setSearchQuery] = React.useState<string | null>(null);
|
||||
const [searchQuery, setSearchQuery] = useQueryParam(
|
||||
'q',
|
||||
withDefault(StringParam, ''),
|
||||
{ updateType: 'replaceIn' },
|
||||
);
|
||||
const [service, setService] = useQueryParam(
|
||||
'service',
|
||||
withDefault(StringParam, ''),
|
||||
{ updateType: 'replaceIn' },
|
||||
);
|
||||
|
||||
const onSearchSubmit = React.useCallback(
|
||||
(e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setSearchQuery(_searchQuery || null);
|
||||
},
|
||||
[_searchQuery, setSearchQuery],
|
||||
);
|
||||
|
||||
const {
|
||||
searchedTimeRange,
|
||||
displayedTimeInputValue,
|
||||
setDisplayedTimeInputValue,
|
||||
onSearch,
|
||||
} = useTimeQuery({
|
||||
isUTC: false,
|
||||
defaultValue: 'Past 1h',
|
||||
defaultTimeRange: [
|
||||
defaultTimeRange?.[0]?.getTime() ?? -1,
|
||||
defaultTimeRange?.[1]?.getTime() ?? -1,
|
||||
],
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<title>Service Dashboard - HyperDX</title>
|
||||
</Head>
|
||||
<div className="d-flex">
|
||||
<AppNav fixed />
|
||||
<div className="w-100">
|
||||
<div className="d-flex flex-column">
|
||||
<Group
|
||||
px="md"
|
||||
py="xs"
|
||||
className="border-bottom border-dark"
|
||||
spacing="xs"
|
||||
align="center"
|
||||
>
|
||||
{/* Use Autocomplete instead? */}
|
||||
<Select
|
||||
searchable
|
||||
clearable
|
||||
allowDeselect
|
||||
placeholder="All Services"
|
||||
maxDropdownHeight={280}
|
||||
data={MOCK_SERVICES}
|
||||
radius="md"
|
||||
variant="filled"
|
||||
value={service}
|
||||
onChange={v => setService(v)}
|
||||
/>
|
||||
<div style={{ flex: 1 }}>
|
||||
<form onSubmit={onSearchSubmit}>
|
||||
<SearchInput
|
||||
inputRef={searchInputRef}
|
||||
placeholder="Scope dashboard to..."
|
||||
value={_searchQuery ?? searchQuery}
|
||||
onChange={v => _setSearchQuery(v)}
|
||||
onSearch={() => {}}
|
||||
showHotkey={false}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div className="d-flex" style={{ width: 350, height: 36 }}>
|
||||
<SearchTimeRangePicker
|
||||
inputValue={displayedTimeInputValue}
|
||||
setInputValue={setDisplayedTimeInputValue}
|
||||
onSearch={range => {
|
||||
onSearch(range);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Group>
|
||||
</div>
|
||||
<Tabs
|
||||
color="gray"
|
||||
variant="pills"
|
||||
defaultValue="infrastructure"
|
||||
radius="md"
|
||||
>
|
||||
<div className="px-3 py-2 border-bottom border-dark">
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="infrastructure">Infrastructure</Tabs.Tab>
|
||||
<Tabs.Tab value="http">HTTP Service</Tabs.Tab>
|
||||
<Tabs.Tab value="database">Database</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
</div>
|
||||
|
||||
<div className="p-3">
|
||||
<Tabs.Panel value="infrastructure">
|
||||
<pre>
|
||||
{JSON.stringify(
|
||||
{ searchedTimeRange, searchQuery, service },
|
||||
null,
|
||||
4,
|
||||
)}
|
||||
</pre>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="http">HTTP Service</Tabs.Panel>
|
||||
<Tabs.Panel value="database">Database</Tabs.Panel>
|
||||
</div>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -13,3 +13,4 @@ export const IS_OSS = process.env.NEXT_PUBLIC_IS_OSS ?? 'true' === 'true';
|
|||
// Features in development
|
||||
export const METRIC_ALERTS_ENABLED = process.env.NODE_ENV === 'development';
|
||||
export const K8S_METRICS_ENABLED = process.env.NODE_ENV === 'development';
|
||||
export const SERVICE_DASHBOARD_ENABLED = process.env.NODE_ENV === 'development';
|
||||
|
|
|
|||
1
packages/app/styles/ServiceDashboardPage.module.scss
Normal file
1
packages/app/styles/ServiceDashboardPage.module.scss
Normal file
|
|
@ -0,0 +1 @@
|
|||
// TODO
|
||||
Loading…
Reference in a new issue