mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat(app): theme-based branding in UI copy (#1768)
## Summary
Replace hardcoded "HyperDX" in user-facing UI with the current theme's display name so deployments using the ClickStack theme show "ClickStack" (e.g. "Welcome to ClickStack", "ClickStack Cloud") instead of "HyperDX".
Closes HDX-3463.
## Changes
### Theme
- **ThemeProvider**: Add `useBrandDisplayName()` hook that returns `theme.displayName` ("HyperDX" or "ClickStack") for use in copy.
### Pages & layout
- **Auth**: Login/register page title and brand label use `useBrandDisplayName()`.
- **AuthLoadingBlocker**: "Loading HyperDX" → "Loading {brandName}".
- **JoinTeamPage**: Document title uses brand name.
- **LandingHeader**: "HyperDX Cloud" → "{brandName} Cloud" (desktop and mobile). Active link color scheme updated for theme consistency.
- **Spotlights**: Cloud action label and description use brand name.
- **Page titles**: All `<Head><title>` now suffix with current brand (Dashboard, Search, Client Sessions, Chart Explorer, My Team, Create a Dashboard, Alerts, DBDashboardImportPage).
### Copy and errors
- **OnboardingModal**: Welcome title and demo server success/error messages use brand name.
- **DBSearchPageAlertModal**, **WebhooksSection**, **TeamMembersSection**, **WebhookForm**: "Please contact HyperDX team" → "Please contact {brandName} team".
- **SessionsPage**: Empty state and setup instructions ("HyperDX integration", "HyperDX Otel Collector", "HyperDX Browser Integration") use brand name.
- **TeamPage**: ClickHouse settings tooltip about windowed queries uses brand name.
- **DBChartPage**: AI Assistant alert text ("on the HyperDX server") and Chart Explorer title use brand name.
- **SourceForm**: All help text that referred to "HyperDX" (materialized view tooltip, correlated source labels, metrics "not yet fully supported") use brand name.
- **HDXMultiSeriesTableChart**: CSV export filename "HyperDX_table_results" → "{brandName}_table_results".
## Testing
- With default/HyperDX theme: all existing strings should still read "HyperDX".
- With ClickStack theme (e.g. `NEXT_PUBLIC_THEME=clickstack` or dev theme override): titles, welcome text, errors, and help text should show "ClickStack" where appropriate.
## Notes
- No changes to SDK imports, type names (e.g. `HyperDXEventType`), or theme definition files.
- Brand is deployment-configured via `NEXT_PUBLIC_THEME`; in dev, theme can be switched for verification.
This commit is contained in:
parent
38286f6766
commit
e984e20e69
21 changed files with 116 additions and 57 deletions
5
.changeset/theme-branding-ui-copy.md
Normal file
5
.changeset/theme-branding-ui-copy.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@hyperdx/app": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: Theme-based branding in UI copy. Replace hardcoded "HyperDX" with the current theme display name so ClickStack deployments show "ClickStack" (e.g. "Welcome to ClickStack", page titles, error messages, help text). Adds `useBrandDisplayName()` hook in ThemeProvider.
|
||||||
|
|
@ -36,6 +36,7 @@ import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { ErrorBoundary } from '@/components/Error/ErrorBoundary';
|
import { ErrorBoundary } from '@/components/Error/ErrorBoundary';
|
||||||
import { PageHeader } from '@/components/PageHeader';
|
import { PageHeader } from '@/components/PageHeader';
|
||||||
|
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import { isAlertSilenceExpired } from './utils/alerts';
|
import { isAlertSilenceExpired } from './utils/alerts';
|
||||||
import { getWebhookChannelIcon } from './utils/webhookIcons';
|
import { getWebhookChannelIcon } from './utils/webhookIcons';
|
||||||
import api from './api';
|
import api from './api';
|
||||||
|
|
@ -470,6 +471,7 @@ function AlertCardList({ alerts }: { alerts: AlertsPageItem[] }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AlertsPage() {
|
export default function AlertsPage() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const { data, isError, isLoading } = api.useAlerts();
|
const { data, isError, isLoading } = api.useAlerts();
|
||||||
|
|
||||||
const alerts = React.useMemo(() => data?.data || [], [data?.data]);
|
const alerts = React.useMemo(() => data?.data || [], [data?.data]);
|
||||||
|
|
@ -477,7 +479,7 @@ export default function AlertsPage() {
|
||||||
return (
|
return (
|
||||||
<div data-testid="alerts-page" className="AlertsPage">
|
<div data-testid="alerts-page" className="AlertsPage">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Alerts - HyperDX</title>
|
<title>Alerts - {brandName}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<PageHeader>Alerts</PageHeader>
|
<PageHeader>Alerts</PageHeader>
|
||||||
<div className="my-4">
|
<div className="my-4">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import api from './api';
|
import api from './api';
|
||||||
|
|
||||||
export default function AuthLoadingBlocker() {
|
export default function AuthLoadingBlocker() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const { data: meData } = api.useMe();
|
const { data: meData } = api.useMe();
|
||||||
|
|
||||||
// increase number of periods rendered as a loading animation, 1 period per second
|
// increase number of periods rendered as a loading animation, 1 period per second
|
||||||
|
|
@ -23,7 +25,7 @@ export default function AuthLoadingBlocker() {
|
||||||
zIndex: 2147483647,
|
zIndex: 2147483647,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Loading HyperDX
|
Loading {brandName}
|
||||||
<span style={{ width: 0 }}>{'.'.repeat(periods)}</span>
|
<span style={{ width: 0 }}>{'.'.repeat(periods)}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import {
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { IconAt, IconLock } from '@tabler/icons-react';
|
import { IconAt, IconLock } from '@tabler/icons-react';
|
||||||
|
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import api from './api';
|
import api from './api';
|
||||||
import * as config from './config';
|
import * as config from './config';
|
||||||
import LandingHeader from './LandingHeader';
|
import LandingHeader from './LandingHeader';
|
||||||
|
|
@ -26,6 +27,7 @@ type FormData = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const { data: team, isLoading: teamIsLoading } = api.useTeam();
|
const { data: team, isLoading: teamIsLoading } = api.useTeam();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|
@ -55,7 +57,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
||||||
|
|
||||||
const verificationSent = msg === 'verify';
|
const verificationSent = msg === 'verify';
|
||||||
|
|
||||||
const title = `HyperDX - ${isRegister ? 'Sign up' : 'Login'}`;
|
const title = `${brandName} - ${isRegister ? 'Sign up' : 'Login'}`;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// If an OSS user accidentally lands on /register after already creating a team
|
// If an OSS user accidentally lands on /register after already creating a team
|
||||||
|
|
@ -138,7 +140,7 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
||||||
: isRegister
|
: isRegister
|
||||||
? 'Register for '
|
? 'Register for '
|
||||||
: 'Login to '}
|
: 'Login to '}
|
||||||
<span className="text-brand fw-bold">HyperDX</span>
|
<span className="text-brand fw-bold">{brandName}</span>
|
||||||
</div>
|
</div>
|
||||||
{action === 'login' && (
|
{action === 'login' && (
|
||||||
<div className="text-center mb-2 ">Welcome back!</div>
|
<div className="text-center mb-2 ">Welcome back!</div>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import { SourceSelectControlled } from '@/components/SourceSelect';
|
||||||
import { useChartAssistant } from '@/hooks/ai';
|
import { useChartAssistant } from '@/hooks/ai';
|
||||||
import { withAppNav } from '@/layout';
|
import { withAppNav } from '@/layout';
|
||||||
import { useSources } from '@/source';
|
import { useSources } from '@/source';
|
||||||
|
import { useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
import { parseTimeQuery, useNewTimeQuery } from '@/timeQuery';
|
import { parseTimeQuery, useNewTimeQuery } from '@/timeQuery';
|
||||||
import { useLocalStorage } from '@/utils';
|
import { useLocalStorage } from '@/utils';
|
||||||
|
|
||||||
|
|
@ -52,6 +53,7 @@ function AIAssistant({
|
||||||
submitRef: React.RefObject<(() => void) | undefined>;
|
submitRef: React.RefObject<(() => void) | undefined>;
|
||||||
aiAssistantEnabled: boolean;
|
aiAssistantEnabled: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
const [alertDismissed, setAlertDismissed] = useLocalStorage(
|
const [alertDismissed, setAlertDismissed] = useLocalStorage(
|
||||||
'ai-assistant-alert-dismissed',
|
'ai-assistant-alert-dismissed',
|
||||||
|
|
@ -131,8 +133,8 @@ function AIAssistant({
|
||||||
>
|
>
|
||||||
<Text size="xs" pt="2px">
|
<Text size="xs" pt="2px">
|
||||||
New AI Assistant available, enable with configuring the{' '}
|
New AI Assistant available, enable with configuring the{' '}
|
||||||
<code>ANTHROPIC_API_KEY</code> environment variable on the HyperDX
|
<code>ANTHROPIC_API_KEY</code> environment variable on the{' '}
|
||||||
server.
|
{brandName} server.
|
||||||
</Text>
|
</Text>
|
||||||
</Alert>
|
</Alert>
|
||||||
<Divider mt="sm" />
|
<Divider mt="sm" />
|
||||||
|
|
@ -202,6 +204,7 @@ function AIAssistant({
|
||||||
}
|
}
|
||||||
|
|
||||||
function DBChartExplorerPage() {
|
function DBChartExplorerPage() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const {
|
const {
|
||||||
searchedTimeRange,
|
searchedTimeRange,
|
||||||
displayedTimeInputValue,
|
displayedTimeInputValue,
|
||||||
|
|
@ -229,7 +232,7 @@ function DBChartExplorerPage() {
|
||||||
return (
|
return (
|
||||||
<Box data-testid="chart-explorer-page" p="sm">
|
<Box data-testid="chart-explorer-page" p="sm">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Chart Explorer - HyperDX</title>
|
<title>Chart Explorer - {brandName}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<AIAssistant
|
<AIAssistant
|
||||||
setConfig={setChartConfig}
|
setConfig={setChartConfig}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import {
|
||||||
|
|
||||||
import { PageHeader } from './components/PageHeader';
|
import { PageHeader } from './components/PageHeader';
|
||||||
import SelectControlled from './components/SelectControlled';
|
import SelectControlled from './components/SelectControlled';
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import { useCreateDashboard, useUpdateDashboard } from './dashboard';
|
import { useCreateDashboard, useUpdateDashboard } from './dashboard';
|
||||||
import { withAppNav } from './layout';
|
import { withAppNav } from './layout';
|
||||||
import { useSources } from './source';
|
import { useSources } from './source';
|
||||||
|
|
@ -406,12 +407,13 @@ function Mapping({ input }: { input: Input }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function DBDashboardImportPage() {
|
function DBDashboardImportPage() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const [input, setInput] = useState<Input | null>(null);
|
const [input, setInput] = useState<Input | null>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Create a Dashboard - HyperDX</title>
|
<title>Create a Dashboard - {brandName}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
<div>Create Dashboard > Import Dashboard</div>
|
<div>Create Dashboard > Import Dashboard</div>
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ import OnboardingModal from './components/OnboardingModal';
|
||||||
import { Tags } from './components/Tags';
|
import { Tags } from './components/Tags';
|
||||||
import useDashboardFilters from './hooks/useDashboardFilters';
|
import useDashboardFilters from './hooks/useDashboardFilters';
|
||||||
import { useDashboardRefresh } from './hooks/useDashboardRefresh';
|
import { useDashboardRefresh } from './hooks/useDashboardRefresh';
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import { parseAsStringWithNewLines } from './utils/queryParsers';
|
import { parseAsStringWithNewLines } from './utils/queryParsers';
|
||||||
import { buildTableRowSearchUrl, DEFAULT_CHART_CONFIG } from './ChartUtils';
|
import { buildTableRowSearchUrl, DEFAULT_CHART_CONFIG } from './ChartUtils';
|
||||||
import { IS_LOCAL_MODE } from './config';
|
import { IS_LOCAL_MODE } from './config';
|
||||||
|
|
@ -675,6 +676,7 @@ function downloadObjectAsJson(object: object, fileName = 'output') {
|
||||||
}
|
}
|
||||||
|
|
||||||
function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -1010,7 +1012,7 @@ function DBDashboardPage({ presetConfig }: { presetConfig?: Dashboard }) {
|
||||||
return (
|
return (
|
||||||
<Box p="sm" data-testid="dashboard-page">
|
<Box p="sm" data-testid="dashboard-page">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Dashboard – HyperDX</title>
|
<title>Dashboard – {brandName}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<OnboardingModal />
|
<OnboardingModal />
|
||||||
<EditTileModal
|
<EditTileModal
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ import {
|
||||||
useSource,
|
useSource,
|
||||||
useSources,
|
useSources,
|
||||||
} from '@/source';
|
} from '@/source';
|
||||||
import { useAppTheme } from '@/theme/ThemeProvider';
|
import { useAppTheme, useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
import {
|
import {
|
||||||
parseRelativeTimeQuery,
|
parseRelativeTimeQuery,
|
||||||
parseTimeQuery,
|
parseTimeQuery,
|
||||||
|
|
@ -806,6 +806,7 @@ const queryStateMap = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function DBSearchPage() {
|
function DBSearchPage() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
// Next router is laggy behind window.location, which causes race
|
// Next router is laggy behind window.location, which causes race
|
||||||
// conditions with useQueryStates, so we'll parse it directly
|
// conditions with useQueryStates, so we'll parse it directly
|
||||||
const paths = window.location.pathname.split('/');
|
const paths = window.location.pathname.split('/');
|
||||||
|
|
@ -1577,7 +1578,7 @@ function DBSearchPage() {
|
||||||
>
|
>
|
||||||
<Head>
|
<Head>
|
||||||
<title>
|
<title>
|
||||||
{savedSearch ? `${savedSearch.name} Search` : 'Search'} - HyperDX
|
{savedSearch ? `${savedSearch.name} Search` : 'Search'} - {brandName}
|
||||||
</title>
|
</title>
|
||||||
</Head>
|
</Head>
|
||||||
{!IS_LOCAL_MODE && isAlertModalOpen && (
|
{!IS_LOCAL_MODE && isAlertModalOpen && (
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { useCreateSavedSearch } from '@/savedSearch';
|
import { useCreateSavedSearch } from '@/savedSearch';
|
||||||
import { useSavedSearch } from '@/savedSearch';
|
import { useSavedSearch } from '@/savedSearch';
|
||||||
import { useSource } from '@/source';
|
import { useSource } from '@/source';
|
||||||
|
import { useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
import {
|
import {
|
||||||
ALERT_CHANNEL_OPTIONS,
|
ALERT_CHANNEL_OPTIONS,
|
||||||
ALERT_INTERVAL_OPTIONS,
|
ALERT_INTERVAL_OPTIONS,
|
||||||
|
|
@ -266,6 +267,7 @@ export const DBSearchPageAlertModal = ({
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const createAlert = api.useCreateAlert();
|
const createAlert = api.useCreateAlert();
|
||||||
const updateAlert = api.useUpdateAlert();
|
const updateAlert = api.useUpdateAlert();
|
||||||
|
|
@ -350,7 +352,7 @@ export const DBSearchPageAlertModal = ({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message: 'Something went wrong. Please contact HyperDX team.',
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -369,7 +371,7 @@ export const DBSearchPageAlertModal = ({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message: 'Something went wrong. Please contact HyperDX team.',
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import { CsvExportButton } from './components/CsvExportButton';
|
import { CsvExportButton } from './components/CsvExportButton';
|
||||||
import TableHeader from './components/DBTable/TableHeader';
|
import TableHeader from './components/DBTable/TableHeader';
|
||||||
import { useCsvExport } from './hooks/useCsvExport';
|
import { useCsvExport } from './hooks/useCsvExport';
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import { UNDEFINED_WIDTH } from './tableUtils';
|
import { UNDEFINED_WIDTH } from './tableUtils';
|
||||||
import type { NumberFormat } from './types';
|
import type { NumberFormat } from './types';
|
||||||
import { formatNumber } from './utils';
|
import { formatNumber } from './utils';
|
||||||
|
|
@ -51,6 +52,7 @@ export const Table = ({
|
||||||
onSortingChange: (sorting: SortingState) => void;
|
onSortingChange: (sorting: SortingState) => void;
|
||||||
variant?: TableVariant;
|
variant?: TableVariant;
|
||||||
}) => {
|
}) => {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const MIN_COLUMN_WIDTH_PX = 100;
|
const MIN_COLUMN_WIDTH_PX = 100;
|
||||||
//we need a reference to the scrolling element for logic down below
|
//we need a reference to the scrolling element for logic down below
|
||||||
const tableContainerRef = useRef<HTMLDivElement>(null);
|
const tableContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
@ -254,7 +256,7 @@ export const Table = ({
|
||||||
</UnstyledButton>
|
</UnstyledButton>
|
||||||
<CsvExportButton
|
<CsvExportButton
|
||||||
data={csvData}
|
data={csvData}
|
||||||
filename="HyperDX_table_results"
|
filename={`${brandName}_table_results`}
|
||||||
className="fs-8 ms-2"
|
className="fs-8 ms-2"
|
||||||
title="Download table as CSV"
|
title="Download table as CSV"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@ import { useRouter } from 'next/router';
|
||||||
import { NextSeo } from 'next-seo';
|
import { NextSeo } from 'next-seo';
|
||||||
import { Button, Paper, Text, TextInput } from '@mantine/core';
|
import { Button, Paper, Text, TextInput } from '@mantine/core';
|
||||||
|
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
|
|
||||||
export default function JoinTeam() {
|
export default function JoinTeam() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const { err, token } = router.query;
|
const { err, token } = router.query;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="AuthPage">
|
<div className="AuthPage">
|
||||||
<NextSeo title="Join Team - HyperDX" />
|
<NextSeo title={`Join Team - ${brandName}`} />
|
||||||
<div className="d-flex align-items-center justify-content-center vh-100 p-2">
|
<div className="d-flex align-items-center justify-content-center vh-100 p-2">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-center mb-4">
|
<div className="text-center mb-4">
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import Link from 'next/link';
|
||||||
import { Anchor, Burger, Button, Container, Group } from '@mantine/core';
|
import { Anchor, Burger, Button, Container, Group } from '@mantine/core';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
|
|
||||||
import { useWordmark } from './theme/ThemeProvider';
|
import { useBrandDisplayName, useWordmark } from './theme/ThemeProvider';
|
||||||
import api from './api';
|
import api from './api';
|
||||||
|
|
||||||
export default function LandingHeader({
|
export default function LandingHeader({
|
||||||
|
|
@ -12,6 +12,7 @@ export default function LandingHeader({
|
||||||
activeKey: string;
|
activeKey: string;
|
||||||
fixed?: boolean;
|
fixed?: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const wordmark = useWordmark();
|
const wordmark = useWordmark();
|
||||||
const { data: me } = api.useMe();
|
const { data: me } = api.useMe();
|
||||||
const isLoggedIn = Boolean(me);
|
const isLoggedIn = Boolean(me);
|
||||||
|
|
@ -49,16 +50,16 @@ export default function LandingHeader({
|
||||||
<Group gap="lg" visibleFrom="lg">
|
<Group gap="lg" visibleFrom="lg">
|
||||||
<Anchor
|
<Anchor
|
||||||
href="https://hyperdx.io"
|
href="https://hyperdx.io"
|
||||||
c={activeKey === 'cloud' ? 'green' : 'gray'}
|
c={activeKey === 'cloud' ? 'var(--color-text-primary)' : 'gray'}
|
||||||
underline="never"
|
underline="never"
|
||||||
style={{ fontWeight: activeKey === 'cloud' ? 600 : 400 }}
|
style={{ fontWeight: activeKey === 'cloud' ? 600 : 400 }}
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
HyperDX Cloud
|
{brandName} Cloud
|
||||||
</Anchor>
|
</Anchor>
|
||||||
<Anchor
|
<Anchor
|
||||||
href="https://clickhouse.com/docs/use-cases/observability/clickstack"
|
href="https://clickhouse.com/docs/use-cases/observability/clickstack"
|
||||||
c={activeKey === 'docs' ? 'green' : 'gray'}
|
c={activeKey === 'docs' ? 'var(--color-text-primary)' : 'gray'}
|
||||||
underline="never"
|
underline="never"
|
||||||
style={{ fontWeight: activeKey === 'docs' ? 600 : 400 }}
|
style={{ fontWeight: activeKey === 'docs' ? 600 : 400 }}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
@ -68,7 +69,11 @@ export default function LandingHeader({
|
||||||
{!isLoggedIn && installation?.isTeamExisting === true && (
|
{!isLoggedIn && installation?.isTeamExisting === true && (
|
||||||
<Anchor
|
<Anchor
|
||||||
href="/login"
|
href="/login"
|
||||||
c={activeKey === '/login' ? 'green' : 'gray'}
|
c={
|
||||||
|
activeKey === '/login'
|
||||||
|
? 'var(--color-text-primary)'
|
||||||
|
: 'gray'
|
||||||
|
}
|
||||||
underline="never"
|
underline="never"
|
||||||
style={{ fontWeight: activeKey === '/login' ? 600 : 400 }}
|
style={{ fontWeight: activeKey === '/login' ? 600 : 400 }}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
@ -103,7 +108,7 @@ export default function LandingHeader({
|
||||||
underline="never"
|
underline="never"
|
||||||
style={{ fontWeight: activeKey === 'cloud' ? 600 : 400 }}
|
style={{ fontWeight: activeKey === 'cloud' ? 600 : 400 }}
|
||||||
>
|
>
|
||||||
HyperDX Cloud
|
{brandName} Cloud
|
||||||
</Anchor>
|
</Anchor>
|
||||||
<Anchor
|
<Anchor
|
||||||
href="https://clickhouse.com/docs/use-cases/observability/clickstack"
|
href="https://clickhouse.com/docs/use-cases/observability/clickstack"
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ import { parseTimeQuery, useNewTimeQuery } from '@/timeQuery';
|
||||||
|
|
||||||
import { SQLInlineEditorControlled } from './components/SQLInlineEditor';
|
import { SQLInlineEditorControlled } from './components/SQLInlineEditor';
|
||||||
import WhereLanguageControlled from './components/WhereLanguageControlled';
|
import WhereLanguageControlled from './components/WhereLanguageControlled';
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import { withAppNav } from './layout';
|
import { withAppNav } from './layout';
|
||||||
import SearchInputV2 from './SearchInputV2';
|
import SearchInputV2 from './SearchInputV2';
|
||||||
import { Session, useSessions } from './sessions';
|
import { Session, useSessions } from './sessions';
|
||||||
|
|
@ -115,6 +116,7 @@ function SessionCardList({
|
||||||
isSessionLoading?: boolean;
|
isSessionLoading?: boolean;
|
||||||
onClick: (session: Session) => void;
|
onClick: (session: Session) => void;
|
||||||
}) {
|
}) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const parentRef = useRef<HTMLDivElement>(null);
|
const parentRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
// The virtualizer
|
// The virtualizer
|
||||||
|
|
@ -141,7 +143,7 @@ function SessionCardList({
|
||||||
search syntax issues.
|
search syntax issues.
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted mt-3">
|
<div className="text-muted mt-3">
|
||||||
Add new data sources by setting up a HyperDX integration.
|
Add new data sources by setting up a {brandName} integration.
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
component="a"
|
component="a"
|
||||||
|
|
@ -150,7 +152,7 @@ function SessionCardList({
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="/docs/install/browser"
|
href="/docs/install/browser"
|
||||||
>
|
>
|
||||||
Install HyperDX Browser Integration
|
Install {brandName} Browser Integration
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -230,6 +232,7 @@ const appliedConfigMap = {
|
||||||
whereLanguage: parseAsStringEnum<'sql' | 'lucene'>(['sql', 'lucene']),
|
whereLanguage: parseAsStringEnum<'sql' | 'lucene'>(['sql', 'lucene']),
|
||||||
};
|
};
|
||||||
export default function SessionsPage() {
|
export default function SessionsPage() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const [appliedConfig, setAppliedConfig] = useQueryStates(appliedConfigMap);
|
const [appliedConfig, setAppliedConfig] = useQueryStates(appliedConfigMap);
|
||||||
|
|
||||||
const { control, setValue, handleSubmit } = useForm({
|
const { control, setValue, handleSubmit } = useForm({
|
||||||
|
|
@ -385,7 +388,7 @@ export default function SessionsPage() {
|
||||||
return (
|
return (
|
||||||
<div className="SessionsPage" data-testid="sessions-page">
|
<div className="SessionsPage" data-testid="sessions-page">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Client Sessions - HyperDX</title>
|
<title>Client Sessions - {brandName}</title>
|
||||||
</Head>
|
</Head>
|
||||||
{selectedSession != null &&
|
{selectedSession != null &&
|
||||||
traceTrace != null &&
|
traceTrace != null &&
|
||||||
|
|
@ -530,6 +533,7 @@ export default function SessionsPage() {
|
||||||
SessionsPage.getLayout = withAppNav;
|
SessionsPage.getLayout = withAppNav;
|
||||||
|
|
||||||
function SessionSetupInstructions() {
|
function SessionSetupInstructions() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card w={500} mx="auto" mt="xl" p="xl" withBorder>
|
<Card w={500} mx="auto" mt="xl" p="xl" withBorder>
|
||||||
|
|
@ -543,7 +547,7 @@ function SessionSetupInstructions() {
|
||||||
</Title>
|
</Title>
|
||||||
<Text size="sm" c="dimmed" ta="center">
|
<Text size="sm" c="dimmed" ta="center">
|
||||||
Follow these steps to start recording and viewing session replays
|
Follow these steps to start recording and viewing session replays
|
||||||
with the HyperDX Otel Collector.
|
with the {brandName} Otel Collector.
|
||||||
</Text>
|
</Text>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
@ -585,7 +589,7 @@ function SessionSetupInstructions() {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
HyperDX Browser Integration
|
{brandName} Browser Integration
|
||||||
</Anchor>{' '}
|
</Anchor>{' '}
|
||||||
to start recording sessions.
|
to start recording sessions.
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import {
|
||||||
IconSettings,
|
IconSettings,
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
|
|
||||||
import { useLogomark } from './theme/ThemeProvider';
|
import { useBrandDisplayName, useLogomark } from './theme/ThemeProvider';
|
||||||
import api from './api';
|
import api from './api';
|
||||||
import { useSavedSearches } from './savedSearch';
|
import { useSavedSearches } from './savedSearch';
|
||||||
|
|
||||||
|
|
@ -22,6 +22,7 @@ import '@mantine/spotlight/styles.css';
|
||||||
|
|
||||||
export const useSpotlightActions = () => {
|
export const useSpotlightActions = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const logomark = useLogomark({ size: 16 });
|
const logomark = useLogomark({ size: 16 });
|
||||||
|
|
||||||
const { data: logViewsData } = useSavedSearches();
|
const { data: logViewsData } = useSavedSearches();
|
||||||
|
|
@ -152,17 +153,19 @@ export const useSpotlightActions = () => {
|
||||||
id: 'cloud',
|
id: 'cloud',
|
||||||
group: 'Menu',
|
group: 'Menu',
|
||||||
leftSection: logomark,
|
leftSection: logomark,
|
||||||
label: 'HyperDX Cloud',
|
label: `${brandName} Cloud`,
|
||||||
description: 'Ready to use HyperDX Cloud? Get started for free.',
|
description: `Ready to use ${brandName} Cloud? Get started for free.`,
|
||||||
keywords: ['account', 'profile'],
|
keywords: ['account', 'profile'],
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
router.push('https://hyperdx.io/register');
|
router.push(
|
||||||
|
'https://clickhouse.com/docs/use-cases/observability/clickstack/getting-started#deploy-with-clickhouse-cloud',
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return logViewActions;
|
return logViewActions;
|
||||||
}, [logomark, logViewsData, dashboardsData, router]);
|
}, [brandName, logomark, logViewsData, dashboardsData, router]);
|
||||||
|
|
||||||
return { actions };
|
return { actions };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import { IS_LOCAL_MODE } from '@/config';
|
||||||
import { PageHeader } from './components/PageHeader';
|
import { PageHeader } from './components/PageHeader';
|
||||||
import TeamMembersSection from './components/TeamSettings/TeamMembersSection';
|
import TeamMembersSection from './components/TeamSettings/TeamMembersSection';
|
||||||
import WebhooksSection from './components/TeamSettings/WebhooksSection';
|
import WebhooksSection from './components/TeamSettings/WebhooksSection';
|
||||||
|
import { useBrandDisplayName } from './theme/ThemeProvider';
|
||||||
import api from './api';
|
import api from './api';
|
||||||
import { useConnections } from './connection';
|
import { useConnections } from './connection';
|
||||||
import { DEFAULT_QUERY_TIMEOUT, DEFAULT_SEARCH_ROW_LIMIT } from './defaults';
|
import { DEFAULT_QUERY_TIMEOUT, DEFAULT_SEARCH_ROW_LIMIT } from './defaults';
|
||||||
|
|
@ -453,6 +454,7 @@ function ClickhouseSettingForm({
|
||||||
}
|
}
|
||||||
|
|
||||||
function TeamQueryConfigSection() {
|
function TeamQueryConfigSection() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const displayValueWithUnit =
|
const displayValueWithUnit =
|
||||||
(unit: string) => (value: any, defaultValue?: any) =>
|
(unit: string) => (value: any, defaultValue?: any) =>
|
||||||
value === undefined || value === defaultValue
|
value === undefined || value === defaultValue
|
||||||
|
|
@ -508,7 +510,7 @@ function TeamQueryConfigSection() {
|
||||||
<ClickhouseSettingForm
|
<ClickhouseSettingForm
|
||||||
settingKey="parallelizeWhenPossible"
|
settingKey="parallelizeWhenPossible"
|
||||||
label="Parallelize Queries When Possible"
|
label="Parallelize Queries When Possible"
|
||||||
tooltip="HyperDX sends windowed queries to ClickHouse in series. This setting parallelizes those queries when it makes sense to. This may cause increased peak load on ClickHouse"
|
tooltip={`${brandName} sends windowed queries to ClickHouse in series. This setting parallelizes those queries when it makes sense to. This may cause increased peak load on ClickHouse`}
|
||||||
type="boolean"
|
type="boolean"
|
||||||
displayValue={value => (value ? 'Enabled' : 'Disabled')}
|
displayValue={value => (value ? 'Enabled' : 'Disabled')}
|
||||||
/>
|
/>
|
||||||
|
|
@ -649,6 +651,7 @@ function ApiKeysSection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TeamPage() {
|
export default function TeamPage() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const { data: team, isLoading } = api.useTeam();
|
const { data: team, isLoading } = api.useTeam();
|
||||||
const hasAllowedAuthMethods =
|
const hasAllowedAuthMethods =
|
||||||
team?.allowedAuthMethods != null && team?.allowedAuthMethods.length > 0;
|
team?.allowedAuthMethods != null && team?.allowedAuthMethods.length > 0;
|
||||||
|
|
@ -656,7 +659,7 @@ export default function TeamPage() {
|
||||||
return (
|
return (
|
||||||
<div className="TeamPage">
|
<div className="TeamPage">
|
||||||
<Head>
|
<Head>
|
||||||
<title>My Team - HyperDX</title>
|
<title>My Team - {brandName}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
<div>{team?.name || 'My team'}</div>
|
<div>{team?.name || 'My team'}</div>
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import {
|
||||||
useSources,
|
useSources,
|
||||||
useUpdateSource,
|
useUpdateSource,
|
||||||
} from '@/source';
|
} from '@/source';
|
||||||
|
import { useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
|
|
||||||
import { TableSourceForm } from './Sources/SourceForm';
|
import { TableSourceForm } from './Sources/SourceForm';
|
||||||
import { SourcesList } from './Sources/SourcesList';
|
import { SourcesList } from './Sources/SourcesList';
|
||||||
|
|
@ -210,6 +211,7 @@ function OnboardingModalComponent({
|
||||||
}: {
|
}: {
|
||||||
requireSource?: boolean;
|
requireSource?: boolean;
|
||||||
}) {
|
}) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const { data: sources } = useSources();
|
const { data: sources } = useSources();
|
||||||
const { data: connections } = useConnections();
|
const { data: connections } = useConnections();
|
||||||
|
|
||||||
|
|
@ -652,7 +654,7 @@ function OnboardingModalComponent({
|
||||||
|
|
||||||
notifications.show({
|
notifications.show({
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
message: 'Connected to HyperDX demo server.',
|
message: `Connected to ${brandName} demo server.`,
|
||||||
});
|
});
|
||||||
setStep('closed');
|
setStep('closed');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -660,11 +662,11 @@ function OnboardingModalComponent({
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
message:
|
message: `Could not connect to the ${brandName} demo server, please try again later.`,
|
||||||
'Could not connect to the HyperDX demo server, please try again later.',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
brandName,
|
||||||
createSourceMutation,
|
createSourceMutation,
|
||||||
createConnectionMutation,
|
createConnectionMutation,
|
||||||
updateSourceMutation,
|
updateSourceMutation,
|
||||||
|
|
@ -677,7 +679,7 @@ function OnboardingModalComponent({
|
||||||
data-testid="onboarding-modal"
|
data-testid="onboarding-modal"
|
||||||
opened={step != null && step !== 'closed'}
|
opened={step != null && step !== 'closed'}
|
||||||
onClose={() => {}}
|
onClose={() => {}}
|
||||||
title="Welcome to HyperDX"
|
title={`Welcome to ${brandName}`}
|
||||||
size="xl"
|
size="xl"
|
||||||
withCloseButton={false}
|
withCloseButton={false}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ import {
|
||||||
useSources,
|
useSources,
|
||||||
useUpdateSource,
|
useUpdateSource,
|
||||||
} from '@/source';
|
} from '@/source';
|
||||||
|
import { useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
import {
|
import {
|
||||||
inferMaterializedViewConfig,
|
inferMaterializedViewConfig,
|
||||||
MV_AGGREGATE_FUNCTIONS,
|
MV_AGGREGATE_FUNCTIONS,
|
||||||
|
|
@ -498,6 +499,7 @@ function MaterializedViewFormSection({
|
||||||
onRemove,
|
onRemove,
|
||||||
setValue,
|
setValue,
|
||||||
}: { mvIndex: number; onRemove: () => void } & TableModelProps) {
|
}: { mvIndex: number; onRemove: () => void } & TableModelProps) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const connection = useWatch({ control, name: `connection` });
|
const connection = useWatch({ control, name: `connection` });
|
||||||
const sourceDatabaseName = useWatch({
|
const sourceDatabaseName = useWatch({
|
||||||
control,
|
control,
|
||||||
|
|
@ -589,7 +591,7 @@ function MaterializedViewFormSection({
|
||||||
<Text size="xs" fw={500} mb={4}>
|
<Text size="xs" fw={500} mb={4}>
|
||||||
Minimum Date
|
Minimum Date
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label="(Optional) The earliest date and time (in the local timezone) for which the materialized view contains data. If not provided, then HyperDX will assume that the materialized view contains data for all dates for which the source table contains data."
|
label={`(Optional) The earliest date and time (in the local timezone) for which the materialized view contains data. If not provided, then ${brandName} will assume that the materialized view contains data for all dates for which the source table contains data.`}
|
||||||
color="dark"
|
color="dark"
|
||||||
c="white"
|
c="white"
|
||||||
multiline
|
multiline
|
||||||
|
|
@ -883,6 +885,7 @@ function AggregatedColumnRow({
|
||||||
|
|
||||||
export function LogTableModelForm(props: TableModelProps) {
|
export function LogTableModelForm(props: TableModelProps) {
|
||||||
const { control } = props;
|
const { control } = props;
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const databaseName = useWatch({
|
const databaseName = useWatch({
|
||||||
control,
|
control,
|
||||||
name: 'from.databaseName',
|
name: 'from.databaseName',
|
||||||
|
|
@ -1035,13 +1038,13 @@ export function LogTableModelForm(props: TableModelProps) {
|
||||||
<Divider />
|
<Divider />
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Metric Source'}
|
label={'Correlated Metric Source'}
|
||||||
helpText="HyperDX Source for metrics associated with logs. Optional"
|
helpText={`${brandName} Source for metrics associated with logs. Optional`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="metricSourceId" />
|
<SourceSelectControlled control={control} name="metricSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Trace Source'}
|
label={'Correlated Trace Source'}
|
||||||
helpText="HyperDX Source for traces associated with logs. Optional"
|
helpText={`${brandName} Source for traces associated with logs. Optional`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="traceSourceId" />
|
<SourceSelectControlled control={control} name="traceSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
@ -1136,6 +1139,7 @@ export function LogTableModelForm(props: TableModelProps) {
|
||||||
|
|
||||||
export function TraceTableModelForm(props: TableModelProps) {
|
export function TraceTableModelForm(props: TableModelProps) {
|
||||||
const { control } = props;
|
const { control } = props;
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const databaseName = useWatch({
|
const databaseName = useWatch({
|
||||||
control,
|
control,
|
||||||
name: 'from.databaseName',
|
name: 'from.databaseName',
|
||||||
|
|
@ -1279,19 +1283,19 @@ export function TraceTableModelForm(props: TableModelProps) {
|
||||||
<Divider />
|
<Divider />
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Log Source'}
|
label={'Correlated Log Source'}
|
||||||
helpText="HyperDX Source for logs associated with traces. Optional"
|
helpText={`${brandName} Source for logs associated with traces. Optional`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="logSourceId" />
|
<SourceSelectControlled control={control} name="logSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Session Source'}
|
label={'Correlated Session Source'}
|
||||||
helpText="HyperDX Source for sessions associated with traces. Optional"
|
helpText={`${brandName} Source for sessions associated with traces. Optional`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="sessionSourceId" />
|
<SourceSelectControlled control={control} name="sessionSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Metric Source'}
|
label={'Correlated Metric Source'}
|
||||||
helpText="HyperDX Source for metrics associated with traces. Optional"
|
helpText={`${brandName} Source for metrics associated with traces. Optional`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="metricSourceId" />
|
<SourceSelectControlled control={control} name="metricSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
@ -1420,6 +1424,7 @@ export function TraceTableModelForm(props: TableModelProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SessionTableModelForm({ control }: TableModelProps) {
|
export function SessionTableModelForm({ control }: TableModelProps) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const databaseName = useWatch({
|
const databaseName = useWatch({
|
||||||
control,
|
control,
|
||||||
name: 'from.databaseName',
|
name: 'from.databaseName',
|
||||||
|
|
@ -1464,7 +1469,7 @@ export function SessionTableModelForm({ control }: TableModelProps) {
|
||||||
<Stack gap="sm">
|
<Stack gap="sm">
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Trace Source'}
|
label={'Correlated Trace Source'}
|
||||||
helpText="HyperDX Source for traces associated with sessions. Required"
|
helpText={`${brandName} Source for traces associated with sessions. Required`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="traceSourceId" />
|
<SourceSelectControlled control={control} name="traceSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
@ -1494,6 +1499,7 @@ interface TableModelProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MetricTableModelForm({ control, setValue }: TableModelProps) {
|
export function MetricTableModelForm({ control, setValue }: TableModelProps) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const databaseName = useWatch({
|
const databaseName = useWatch({
|
||||||
control,
|
control,
|
||||||
name: 'from.databaseName',
|
name: 'from.databaseName',
|
||||||
|
|
@ -1562,7 +1568,7 @@ export function MetricTableModelForm({ control, setValue }: TableModelProps) {
|
||||||
helpText={
|
helpText={
|
||||||
metricType === MetricsDataType.ExponentialHistogram ||
|
metricType === MetricsDataType.ExponentialHistogram ||
|
||||||
metricType === MetricsDataType.Summary
|
metricType === MetricsDataType.Summary
|
||||||
? `Table containing ${metricType.toLowerCase()} metrics data. Note: not yet fully supported by HyperDX`
|
? `Table containing ${metricType.toLowerCase()} metrics data. Note: not yet fully supported by ${brandName}`
|
||||||
: `Table containing ${metricType.toLowerCase()} metrics data`
|
: `Table containing ${metricType.toLowerCase()} metrics data`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -1576,7 +1582,7 @@ export function MetricTableModelForm({ control, setValue }: TableModelProps) {
|
||||||
))}
|
))}
|
||||||
<FormRow
|
<FormRow
|
||||||
label={'Correlated Log Source'}
|
label={'Correlated Log Source'}
|
||||||
helpText="HyperDX Source for logs associated with metrics. Optional"
|
helpText={`${brandName} Source for logs associated with metrics. Optional`}
|
||||||
>
|
>
|
||||||
<SourceSelectControlled control={control} name="logSourceId" />
|
<SourceSelectControlled control={control} name="logSourceId" />
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,10 @@ import { notifications } from '@mantine/notifications';
|
||||||
import { IconLock, IconUserPlus } from '@tabler/icons-react';
|
import { IconLock, IconUserPlus } from '@tabler/icons-react';
|
||||||
|
|
||||||
import api from '@/api';
|
import api from '@/api';
|
||||||
|
import { useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
|
|
||||||
export default function TeamMembersSection() {
|
export default function TeamMembersSection() {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const hasAdminAccess = true;
|
const hasAdminAccess = true;
|
||||||
|
|
||||||
const { data: team } = api.useTeam();
|
const { data: team } = api.useTeam();
|
||||||
|
|
@ -85,8 +87,7 @@ export default function TeamMembersSection() {
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message:
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
'Something went wrong. Please contact HyperDX team.',
|
|
||||||
|
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
|
|
@ -94,7 +95,7 @@ export default function TeamMembersSection() {
|
||||||
} else {
|
} else {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message: 'Something went wrong. Please contact HyperDX team.',
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -143,8 +144,7 @@ export default function TeamMembersSection() {
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message:
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
'Something went wrong. Please contact HyperDX team.',
|
|
||||||
|
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
|
|
@ -152,7 +152,7 @@ export default function TeamMembersSection() {
|
||||||
} else {
|
} else {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message: 'Something went wrong. Please contact HyperDX team.',
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -187,15 +187,14 @@ export default function TeamMembersSection() {
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message:
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
'Something went wrong. Please contact HyperDX team.',
|
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
notifications.show({
|
notifications.show({
|
||||||
color: 'red',
|
color: 'red',
|
||||||
message: 'Something went wrong. Please contact HyperDX team.',
|
message: `Something went wrong. Please contact ${brandName} team.`,
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import ReactCodeMirror, {
|
||||||
} from '@uiw/react-codemirror';
|
} from '@uiw/react-codemirror';
|
||||||
|
|
||||||
import api from '@/api';
|
import api from '@/api';
|
||||||
|
import { useBrandDisplayName } from '@/theme/ThemeProvider';
|
||||||
import { isValidUrl } from '@/utils';
|
import { isValidUrl } from '@/utils';
|
||||||
|
|
||||||
const DEFAULT_GENERIC_WEBHOOK_BODY = [
|
const DEFAULT_GENERIC_WEBHOOK_BODY = [
|
||||||
|
|
@ -65,6 +66,7 @@ export function WebhookForm({
|
||||||
onClose: VoidFunction;
|
onClose: VoidFunction;
|
||||||
onSuccess: (webhookId?: string) => void;
|
onSuccess: (webhookId?: string) => void;
|
||||||
}) {
|
}) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const saveWebhook = api.useSaveWebhook();
|
const saveWebhook = api.useSaveWebhook();
|
||||||
const updateWebhook = api.useUpdateWebhook();
|
const updateWebhook = api.useUpdateWebhook();
|
||||||
const testWebhook = api.useTestWebhook();
|
const testWebhook = api.useTestWebhook();
|
||||||
|
|
@ -233,7 +235,7 @@ export function WebhookForm({
|
||||||
onClose();
|
onClose();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
let message = 'Something went wrong. Please contact HyperDX team.';
|
let message = `Something went wrong. Please contact ${brandName} team.`;
|
||||||
|
|
||||||
if (e instanceof HTTPError) {
|
if (e instanceof HTTPError) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { notifications } from '@mantine/notifications';
|
||||||
import { IconPencil, IconX } from '@tabler/icons-react';
|
import { IconPencil, IconX } from '@tabler/icons-react';
|
||||||
|
|
||||||
import api from '../../api';
|
import api from '../../api';
|
||||||
|
import { useBrandDisplayName } from '../../theme/ThemeProvider';
|
||||||
import { useConfirm } from '../../useConfirm';
|
import { useConfirm } from '../../useConfirm';
|
||||||
import {
|
import {
|
||||||
getWebhookServiceConfig,
|
getWebhookServiceConfig,
|
||||||
|
|
@ -28,6 +29,7 @@ function DeleteWebhookButton({
|
||||||
webhookName: string;
|
webhookName: string;
|
||||||
onSuccess: VoidFunction;
|
onSuccess: VoidFunction;
|
||||||
}) {
|
}) {
|
||||||
|
const brandName = useBrandDisplayName();
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
const deleteWebhook = api.useDeleteWebhook();
|
const deleteWebhook = api.useDeleteWebhook();
|
||||||
|
|
||||||
|
|
@ -51,7 +53,8 @@ function DeleteWebhookButton({
|
||||||
const message =
|
const message =
|
||||||
(e instanceof HTTPError
|
(e instanceof HTTPError
|
||||||
? (await e.response.json())?.message
|
? (await e.response.json())?.message
|
||||||
: null) || 'Something went wrong. Please contact HyperDX team.';
|
: null) ||
|
||||||
|
`Something went wrong. Please contact ${brandName} team.`;
|
||||||
notifications.show({
|
notifications.show({
|
||||||
message,
|
message,
|
||||||
color: 'red',
|
color: 'red',
|
||||||
|
|
|
||||||
|
|
@ -239,3 +239,9 @@ export function useThemeName(): ThemeName {
|
||||||
const { themeName } = useAppTheme();
|
const { themeName } = useAppTheme();
|
||||||
return themeName;
|
return themeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hook to get the current theme's display name for UI copy (e.g. "HyperDX" or "ClickStack"). */
|
||||||
|
export function useBrandDisplayName(): string {
|
||||||
|
const { theme } = useAppTheme();
|
||||||
|
return theme.displayName;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue