Skip to content

Commit

Permalink
feat: Placeholder page for Service Dashboard (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
svc-shorpo authored Jan 5, 2024
1 parent 2910461 commit 8815eff
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/thin-carpets-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hyperdx/app': patch
---

Placeholder page for Service Dashboard
3 changes: 3 additions & 0 deletions packages/app/pages/services.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ServiceDashboardPage from '../src/ServiceDashboardPage';

export default ServiceDashboardPage;
21 changes: 20 additions & 1 deletion packages/app/src/AppNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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(
Expand Down
141 changes: 141 additions & 0 deletions packages/app/src/ServiceDashboardPage.tsx
Original file line number Diff line number Diff line change
@@ -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>
);
}
1 change: 1 addition & 0 deletions packages/app/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 change: 1 addition & 0 deletions packages/app/styles/ServiceDashboardPage.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// TODO

0 comments on commit 8815eff

Please sign in to comment.