Compare commits

...

11 Commits

Author SHA1 Message Date
Manika Malhotra
911ee2912d feat(calendar): select the calendar through data-slot 2026-09-23 21:57:22 +05:30
Manika Malhotra
d4a4217865 feat(dropdown): adopt Dropdown in place of DropdownMenu 2026-09-23 21:56:48 +05:30
Manika Malhotra
925cbafde6 feat(tabs): adopt the items API 2026-09-23 21:56:30 +05:30
Manika Malhotra
1f57634472 feat(radio-group): adopt the items API 2026-09-23 21:56:09 +05:30
Manika Malhotra
662c91884a feat(toggle-group): adopt the items API 2026-09-23 21:55:50 +05:30
Manika Malhotra
95bbd1b501 feat(tooltip): adopt the single Tooltip API 2026-09-23 21:55:23 +05:30
Manika Malhotra
f0037ae4bd feat(checkbox): adopt the reworked Checkbox API 2026-09-23 21:55:00 +05:30
Manika Malhotra
8c3688131e feat(switch): adopt the reworked Switch API 2026-09-23 21:54:38 +05:30
Manika Malhotra
db286c4f92 feat(badge): adopt the reworked Badge palette 2026-09-23 21:54:16 +05:30
Manika Malhotra
e14a6add4e feat(button-group): import ButtonGroup from its own entry 2026-09-23 21:53:56 +05:30
Manika Malhotra
3e2caa8110 feat(button): adopt the reworked Button API 2026-09-23 21:53:31 +05:30
404 changed files with 4001 additions and 2685 deletions

View File

@@ -26,6 +26,7 @@ function BreadcrumbItem({
return (
<Button
size="md"
variant="ghost"
color="secondary"
className={styles.item}

View File

@@ -34,21 +34,23 @@ function ErrorEmptyState({
</div>
<div className={styles.actions}>
<Button
size="md"
variant="solid"
color="secondary"
prefix={<LifeBuoy size={14} />}
onClick={onContactSupport}
data-testid="error-contact-support-button"
testId="error-contact-support-button"
>
Contact Support
</Button>
{onRefresh && (
<Button
size="md"
variant="outlined"
color="secondary"
prefix={<RefreshCw size={14} />}
onClick={onRefresh}
data-testid="error-refresh-button"
testId="error-refresh-button"
>
Refresh
</Button>

View File

@@ -1,11 +1,7 @@
import { Copy } from '@signozhq/icons';
import { Badge } from '@signozhq/ui/badge';
import { Badge, type BadgeColorType } from '@signozhq/ui/badge';
import { toast } from '@signozhq/ui/sonner';
import {
TooltipContent,
TooltipRoot,
TooltipTrigger,
} from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCopyToClipboard } from 'react-use';
@@ -16,20 +12,7 @@ import { BADGE_GAP, estimateBadgeWidth, OVERFLOW_BADGE_WIDTH } from './utils';
export interface LabelColumnProps {
labels: string[];
color?:
| 'primary'
| 'secondary'
| 'success'
| 'error'
| 'warning'
| 'robin'
| 'forest'
| 'amber'
| 'sienna'
| 'cherry'
| 'sakura'
| 'aqua'
| 'vanilla';
color?: BadgeColorType;
value?: { [key: string]: string };
}
@@ -104,20 +87,10 @@ function LabelColumn({
<LabelTag key={label} label={label} color={color} value={value?.[label]} />
))}
{remainingLabels.length > 0 && (
<TooltipRoot>
<TooltipTrigger asChild>
<span>
<Badge
color={color}
className={styles.overflowBadge}
variant="outline"
data-testid="label-overflow-badge"
>
+{remainingLabels.length}
</Badge>
</span>
</TooltipTrigger>
<TooltipContent side="bottom" align="end">
<Tooltip
side="bottom"
align="end"
title={
<div className={styles.tooltipContent}>
<span>
{remainingLabels
@@ -140,8 +113,19 @@ function LabelColumn({
<Copy size={12} />
</button>
</div>
</TooltipContent>
</TooltipRoot>
}
>
<span>
<Badge
color={color}
className={styles.overflowBadge}
variant="outlined"
testId="label-overflow-badge"
>
+{remainingLabels.length}
</Badge>
</span>
</Tooltip>
)}
</div>
);

View File

@@ -1,31 +1,14 @@
import { Copy } from '@signozhq/icons';
import { Badge } from '@signozhq/ui/badge';
import { Badge, type BadgeColorType } from '@signozhq/ui/badge';
import { toast } from '@signozhq/ui/sonner';
import {
TooltipContent,
TooltipRoot,
TooltipTrigger,
} from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { useCopyToClipboard } from 'react-use';
import styles from './LabelTag.module.scss';
export interface LabelTagProps {
label: string;
color?:
| 'primary'
| 'secondary'
| 'success'
| 'error'
| 'warning'
| 'robin'
| 'forest'
| 'amber'
| 'sienna'
| 'cherry'
| 'sakura'
| 'aqua'
| 'vanilla';
color?: BadgeColorType;
value?: string;
}
@@ -41,20 +24,8 @@ function LabelTag({ label, value, color }: LabelTagProps): JSX.Element {
};
return (
<TooltipRoot>
<TooltipTrigger asChild>
<span>
<Badge
color={color}
className={styles.labelBadge}
variant="outline"
data-testid={`label-tag-${label}`}
>
<span className={styles.labelValue}>{displayText}</span>
</Badge>
</span>
</TooltipTrigger>
<TooltipContent>
<Tooltip
title={
<div className={styles.tooltipContent}>
<span>{displayText}</span>
<button
@@ -66,8 +37,19 @@ function LabelTag({ label, value, color }: LabelTagProps): JSX.Element {
<Copy size={12} />
</button>
</div>
</TooltipContent>
</TooltipRoot>
}
>
<span>
<Badge
color={color ?? 'secondary'}
className={styles.labelBadge}
variant="outlined"
testId={`label-tag-${label}`}
>
<span className={styles.labelValue}>{displayText}</span>
</Badge>
</span>
</Tooltip>
);
}

View File

@@ -30,21 +30,23 @@ function NoResultsEmptyState({
<div className={styles.actions}>
{onClear && (
<Button
size="md"
variant="outlined"
color="secondary"
onClick={onClear}
data-testid="no-results-clear-button"
testId="no-results-clear-button"
>
{clearButtonText}
</Button>
)}
{onRefresh && (
<Button
size="md"
variant="outlined"
color="secondary"
prefix={<RefreshCw size={14} />}
onClick={onRefresh}
data-testid="no-results-refresh-button"
testId="no-results-refresh-button"
>
Refresh
</Button>

View File

@@ -1,4 +1,4 @@
import type { BadgeColor } from '@signozhq/ui/badge';
import type { BadgeColorType } from '@signozhq/ui/badge';
export const STATE_ORDER = ['firing', 'pending', 'inactive', 'disabled'];
export const SEVERITY_ORDER = ['critical', 'error', 'warning', 'info'];
@@ -24,9 +24,9 @@ export const SEVERITY_COLORS: Record<string, string> = {
info: 'var(--bg-robin-500)',
};
export const SEVERITY_BADGE_COLORS: Record<string, BadgeColor> = {
critical: 'error',
error: 'error',
export const SEVERITY_BADGE_COLORS: Record<string, BadgeColorType> = {
critical: 'danger',
error: 'danger',
warning: 'warning',
info: 'primary',
};

View File

@@ -22,11 +22,12 @@ function AuthHeader(): JSX.Element {
<span className="auth-header-logo-text">SigNoz</span>
</div>
<Button
size="md"
className="auth-header-help-button"
prefix={<LifeBuoy size={12} />}
onClick={handleGetHelp}
variant="solid"
color="none"
color="secondary"
>
Get Help
</Button>

View File

@@ -48,14 +48,22 @@ function Badges({ tags, setTags }: AddTagsProps): JSX.Element {
<div className="tags-container">
{tags.map<React.ReactNode>((tag) => (
<Badge
variant="solid"
key={tag}
color="vanilla"
color="secondary"
style={{ userSelect: 'none' }}
closable
onClose={(e): void => {
e.preventDefault();
handleClose(tag);
}}
suffix={
<button
type="button"
aria-label={`Remove ${tag}`}
onClick={(e): void => {
e.preventDefault();
handleClose(tag);
}}
>
<X size={12} />
</button>
}
>
{tag}
</Badge>

View File

@@ -4,7 +4,7 @@ import {
CloudintegrationtypesCollectedMetricDTO,
} from 'api/generated/services/sigNoz.schemas';
import { BarChart, Info, ScrollText } from '@signozhq/icons';
import { TooltipProvider, TooltipSimple } from '@signozhq/ui/tooltip';
import { TooltipProvider, Tooltip } from '@signozhq/ui/tooltip';
import './CloudServiceDataCollected.styles.scss';
@@ -89,12 +89,10 @@ function CloudServiceDataCollected({
Metrics
{metricsInfoTooltip && (
<TooltipProvider>
<TooltipSimple
<Tooltip
className={'cloud-service-data-collected-table-tooltip'}
title={metricsInfoTooltip}
side="top"
tooltipContentProps={{
className: 'cloud-service-data-collected-table-tooltip',
}}
>
<span
className="cloud-service-data-collected-table-heading-info"
@@ -103,7 +101,7 @@ function CloudServiceDataCollected({
>
<Info size={12} />
</span>
</TooltipSimple>
</Tooltip>
</TooltipProvider>
)}
</div>

View File

@@ -2,6 +2,7 @@ import { useMemo, useState } from 'react';
import { useCopyToClipboard } from 'react-use';
import { Check, Copy } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { Tooltip } from '@signozhq/ui/tooltip';
import SyntaxHighlighter, {
a11yDark,
} from 'components/MarkdownRenderer/syntaxHighlighter';
@@ -52,16 +53,19 @@ function CodeBlock({
data-testid="code-block-container"
>
{showCopyButton ? (
<Button
variant="ghost"
color="secondary"
size="sm"
onClick={handleCopy}
prefix={isCopied ? <Check size={14} /> : <Copy size={14} />}
aria-label="Copy code"
title={isCopied ? 'Copied' : 'Copy'}
style={{ position: 'absolute', right: 8, top: 8, zIndex: 1 }}
/>
<Tooltip title={isCopied ? 'Copied' : 'Copy'}>
<Button
variant="ghost"
color="secondary"
size="sm"
icon
onClick={handleCopy}
aria-label="Copy code"
style={{ position: 'absolute', right: 8, top: 8, zIndex: 1 }}
>
{isCopied ? <Check size={14} /> : <Copy size={14} />}
</Button>
</Tooltip>
) : null}
<SyntaxHighlighter
style={a11yDark}

View File

@@ -134,26 +134,33 @@ function CreateServiceAccountModal(): JSX.Element {
<DialogFooter className="create-sa-modal__footer">
<Button
size="md"
type="button"
variant="solid"
color="secondary"
onClick={handleClose}
data-testid="create-sa-cancel-btn"
testId="create-sa-cancel-btn"
>
<X size={12} />
Cancel
</Button>
<AuthZButton
size="md"
checks={[SACreatePermission]}
withPortal={false}
type="submit"
form="create-sa-form"
type="button"
variant="solid"
color="primary"
loading={isSubmitting}
disabled={!isValid}
data-testid="create-sa-submit-btn"
testId="create-sa-submit-btn"
onClick={(): void => {
const form = document.getElementById('create-sa-form');
if (form instanceof HTMLFormElement) {
form.requestSubmit();
}
}}
>
Create Service Account
</AuthZButton>

View File

@@ -656,14 +656,19 @@ function CustomTimePicker({
}
>
<Button
disabledTooltip={undefined}
size="md"
className="zoom-out-btn"
onClick={handleZoomOut}
disabled={zoomOutDisabled}
data-testid="zoom-out-btn"
prefix={<ZoomOut size={14} />}
testId="zoom-out-btn"
icon
aria-label="Zoom out"
variant="solid"
color="none"
/>
color="secondary"
>
<ZoomOut size={14} />
</Button>
</Tooltip>
)}
</div>

View File

@@ -27,12 +27,14 @@ function DetailsHeader({
const closeButton = (
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={onClose}
aria-label="Close"
prefix={<X size={14} />}
></Button>
>
<X size={14} />
</Button>
);
return (

View File

@@ -1,6 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { Button, Popover, Tooltip } from 'antd';
import { RadioGroup, RadioGroupItem } from '@signozhq/ui/radio-group';
import { RadioGroup } from '@signozhq/ui/radio-group';
import { Typography } from '@signozhq/ui/typography';
import { TelemetryFieldKey } from 'api/v5/v5';
import { PANEL_TYPES } from 'constants/queryBuilder';
@@ -68,10 +68,15 @@ export default function DownloadOptionsMenu({
>
<div className="export-format">
<Typography.Text className="title">FORMAT</Typography.Text>
<RadioGroup value={exportFormat} onChange={setExportFormat}>
<RadioGroupItem value={DownloadFormats.CSV}>csv</RadioGroupItem>
<RadioGroupItem value={DownloadFormats.JSONL}>jsonl</RadioGroupItem>
</RadioGroup>
<RadioGroup
color="primary"
value={exportFormat}
onChange={setExportFormat}
items={[
{ value: DownloadFormats.CSV, label: 'csv' },
{ value: DownloadFormats.JSONL, label: 'jsonl' },
]}
/>
</div>
<div className="horizontal-line" />
@@ -79,19 +84,15 @@ export default function DownloadOptionsMenu({
<div className="row-limit">
<Typography.Text className="title">Number of Rows</Typography.Text>
<RadioGroup
color="primary"
value={String(rowLimit)}
onChange={(value): void => setRowLimit(Number(value))}
>
<RadioGroupItem value={String(DownloadRowCounts.TEN_K)}>
10k
</RadioGroupItem>
<RadioGroupItem value={String(DownloadRowCounts.THIRTY_K)}>
30k
</RadioGroupItem>
<RadioGroupItem value={String(DownloadRowCounts.FIFTY_K)}>
50k
</RadioGroupItem>
</RadioGroup>
items={[
{ value: String(DownloadRowCounts.TEN_K), label: '10k' },
{ value: String(DownloadRowCounts.THIRTY_K), label: '30k' },
{ value: String(DownloadRowCounts.FIFTY_K), label: '50k' },
]}
/>
</div>
{dataSource !== DataSource.TRACES && (
@@ -100,12 +101,15 @@ export default function DownloadOptionsMenu({
<div className="columns-scope">
<Typography.Text className="title">Columns</Typography.Text>
<RadioGroup value={columnsScope} onChange={setColumnsScope}>
<RadioGroupItem value={DownloadColumnsScopes.ALL}>All</RadioGroupItem>
<RadioGroupItem value={DownloadColumnsScopes.SELECTED}>
Selected
</RadioGroupItem>
</RadioGroup>
<RadioGroup
color="primary"
value={columnsScope}
onChange={setColumnsScope}
items={[
{ value: DownloadColumnsScopes.ALL, label: 'All' },
{ value: DownloadColumnsScopes.SELECTED, label: 'Selected' },
]}
/>
</div>
</>
)}

View File

@@ -0,0 +1,221 @@
import { isValidElement, type ReactElement, type ReactNode } from 'react';
import {
Dropdown,
type DropdownItemType,
type DropdownProps,
} from '@signozhq/ui/dropdown';
/**
* The menu-item shape SigNoz built against `@signozhq/ui/dropdown-menu`.
* `Dropdown` only accepts its own `items` array, so this module maps the old
* rows onto that array and renders them.
*/
export type BaseMenuItem = {
key?: string;
label?: ReactNode;
disabled?: boolean;
disabledTooltip?: ReactNode;
icon?: ReactNode;
rightIcon?: ReactNode;
shortcut?: ReactNode;
onClick?: (info: { key: string; keyPath: string[] }) => void;
danger?: boolean;
className?: string;
};
export type MenuGroup = BaseMenuItem & {
type: 'group';
label: string;
children: MenuItem[];
};
export type MenuDivider = {
type: 'divider';
key?: string;
};
export type SubMenuItem = BaseMenuItem & {
children: MenuItem[];
};
export type CheckboxMenuItem = BaseMenuItem & {
type: 'checkbox';
key: string;
label: ReactNode;
checked?: boolean;
onCheckedChange?: (checked: boolean) => void;
};
export type RadioMenuItem = {
type: 'radio';
key: string;
label: ReactNode;
value: string;
disabled?: boolean;
className?: string;
};
export type RadioGroupMenuItem = {
type: 'radio-group';
key?: string;
value?: string;
onChange?: (value: string) => void;
children: RadioMenuItem[];
};
export type MenuItem =
| MenuGroup
| MenuDivider
| CheckboxMenuItem
| RadioGroupMenuItem
| (SubMenuItem & { type?: never })
| (BaseMenuItem & { type?: never; children?: never });
export type MenuProps = {
items: MenuItem[];
search?: {
placeholder?: string;
onSearchChange?: (value: string) => void;
};
loading?: boolean | { text?: string };
};
type Align = DropdownProps['align'];
type Side = DropdownProps['side'];
function elementOf(node: ReactNode): ReactElement | undefined {
return isValidElement(node) ? node : undefined;
}
function disabledFields(item: {
disabled?: boolean;
disabledTooltip?: ReactNode;
}): { disabled: boolean; disabledTooltip: ReactNode } | Record<string, never> {
if (item.disabled === undefined && item.disabledTooltip === undefined) {
return {};
}
return {
disabled: Boolean(item.disabled),
disabledTooltip: item.disabledTooltip,
};
}
function mapItem(item: MenuItem, index: number): DropdownItemType {
if ('type' in item && item.type === 'divider') {
return { type: 'separator', value: item.key ?? `separator-${index}` };
}
if ('type' in item && item.type === 'group') {
return {
type: 'group',
value: item.key ?? `group-${index}`,
label: item.label,
items: item.children.map((child, childIndex) => mapItem(child, childIndex)),
} as DropdownItemType;
}
if ('type' in item && item.type === 'checkbox') {
return {
type: 'checkbox',
name: item.key,
label: item.label,
value: item.checked,
onChange: item.onCheckedChange,
prefix: elementOf(item.icon),
...disabledFields(item),
};
}
if ('type' in item && item.type === 'radio-group') {
return {
type: 'radio-group',
name: item.key ?? `radio-${index}`,
value: item.value,
onChange: item.onChange,
items: item.children.map((child) => ({
value: child.value,
label: child.label,
...disabledFields(child),
})),
};
}
if ('children' in item && item.children) {
const key = item.key ?? `submenu-${index}`;
return {
type: 'submenu',
value: key,
label: item.label ?? '',
prefix: elementOf(item.icon),
items: item.children.map((child, childIndex) => mapItem(child, childIndex)),
...disabledFields(item),
} as DropdownItemType;
}
const key = item.key ?? `item-${index}`;
const shortcut = 'shortcut' in item ? item.shortcut : undefined;
const suffix = elementOf('rightIcon' in item ? item.rightIcon : undefined);
return {
type: 'item',
value: key,
label: item.label ?? '',
danger: 'danger' in item ? item.danger : undefined,
prefix: elementOf('icon' in item ? item.icon : undefined),
...(shortcut != null ? { shortcut } : { suffix }),
onClick:
'onClick' in item && item.onClick
? (): void => {
item.onClick?.({ key, keyPath: [key] });
}
: undefined,
...disabledFields(item),
};
}
interface DropdownMenuSimpleProps {
menu: MenuProps;
children: ReactNode;
className?: string;
align?: Align;
side?: Side;
testId?: string;
nativeButton?: boolean;
}
export function DropdownMenuSimple({
menu,
children,
className,
align = 'end',
side = 'bottom',
testId,
nativeButton = true,
}: DropdownMenuSimpleProps): JSX.Element {
const loading = menu.loading;
const loadingText = typeof loading === 'object' ? loading.text : undefined;
return (
<Dropdown
items={menu.items.map(mapItem) as DropdownItemType[]}
nativeButton={nativeButton}
align={align}
side={side}
className={className}
testId={testId}
loading={Boolean(loading)}
loadingContent={loadingText}
searchInputProps={
menu.search
? {
placeholder: menu.search.placeholder,
onChange: menu.search.onSearchChange,
}
: undefined
}
>
{children}
</Dropdown>
);
}
export default DropdownMenuSimple;

View File

@@ -38,13 +38,15 @@ function DeleteMemberDialog({
const footer = (
<>
<Button variant="solid" color="secondary" onClick={onClose}>
<Button size="md" variant="solid" color="secondary" onClick={onClose}>
<X size={12} />
Cancel
</Button>
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="destructive"
color="danger"
disabled={isDeleting}
onClick={onConfirm}
loading={isDeleting}

View File

@@ -519,7 +519,7 @@ function EditMemberDrawer({
localRoles.map((roleId) => {
const role = availableRoles.find((r) => r.id === roleId);
return (
<Badge key={roleId} color="vanilla">
<Badge variant="solid" key={roleId} color="secondary">
{role?.name ?? roleId}
</Badge>
);
@@ -559,15 +559,15 @@ function EditMemberDrawer({
<div className="edit-member-drawer__meta-item">
<span className="edit-member-drawer__meta-label">Status</span>
{member?.status === MemberStatus.Active ? (
<Badge color="forest" variant="outline">
<Badge color="success" variant="outlined">
ACTIVE
</Badge>
) : member?.status === MemberStatus.Deleted ? (
<Badge color="cherry" variant="outline">
<Badge color="danger" variant="outlined">
DELETED
</Badge>
) : (
<Badge color="amber" variant="outline">
<Badge color="warning" variant="outlined">
INVITED
</Badge>
)}
@@ -575,12 +575,16 @@ function EditMemberDrawer({
<div className="edit-member-drawer__meta-item">
<span className="edit-member-drawer__meta-label">{joinedOnLabel}</span>
<Badge color="vanilla">{formatTimestamp(member?.joinedOn)}</Badge>
<Badge variant="solid" color="secondary">
{formatTimestamp(member?.joinedOn)}
</Badge>
</div>
{!isInvited && (
<div className="edit-member-drawer__meta-item">
<span className="edit-member-drawer__meta-label">Last Modified</span>
<Badge color="vanilla">{formatTimestamp(member?.updatedAt)}</Badge>
<Badge variant="solid" color="secondary">
{formatTimestamp(member?.updatedAt)}
</Badge>
</div>
)}
</div>
@@ -614,10 +618,12 @@ function EditMemberDrawer({
<Tooltip title={getDeleteTooltip(isRootUser, isSelf)}>
<span className="edit-member-drawer__tooltip-wrapper">
<Button
disabledTooltip={undefined}
size="md"
onClick={(): void => setShowDeleteConfirm(true)}
disabled={isRootUser || isSelf}
variant="link"
color="destructive"
color="danger"
>
<Trash2 size={12} />
{isInvited ? 'Revoke Invite' : 'Delete Member'}
@@ -629,6 +635,8 @@ function EditMemberDrawer({
<Tooltip title={isRootUser ? ROOT_USER_TOOLTIP : undefined}>
<span className="edit-member-drawer__tooltip-wrapper">
<Button
disabledTooltip={undefined}
size="md"
onClick={handleGenerateResetLink}
disabled={isGeneratingLink || isRootUser || isLoadingTokenStatus}
variant="link"
@@ -651,12 +659,19 @@ function EditMemberDrawer({
</div>
<div className="edit-member-drawer__footer-right">
<Button variant="outlined" color="secondary" onClick={handleClose}>
<Button
size="md"
variant="outlined"
color="secondary"
onClick={handleClose}
>
<X size={14} />
Cancel
</Button>
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="primary"
disabled={!isDirty || isSaving || isRootUser}

View File

@@ -45,6 +45,7 @@ function ResetLinkDialog({
<span className="reset-link-dialog__link-text">{resetLink}</span>
</div>
<Button
size="md"
variant="link"
color="secondary"
onClick={onCopy}

View File

@@ -53,7 +53,7 @@ function ErrorModal({
onClick={(): void => setVisible(true)}
onKeyDown={undefined}
>
<Badge color="error">
<Badge variant="solid" color="danger">
<CircleAlert size={14} color={Color.BG_CHERRY_500} /> error
</Badge>
</span>

View File

@@ -1,7 +1,10 @@
import { useState } from 'react';
import { useCopyToClipboard } from 'react-use';
import { Button, Col, Popover, Row, Select, Space } from 'antd';
import { DropdownMenuSimple, type MenuProps } from '@signozhq/ui/dropdown-menu';
import {
DropdownMenuSimple,
type MenuProps,
} from 'components/DropdownMenu/DropdownMenuSimple';
import { Typography } from '@signozhq/ui/typography';
import axios from 'axios';
import TextToolTip from 'components/TextToolTip';

View File

@@ -1,8 +1,8 @@
import { Download } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@signozhq/ui/popover';
import { RadioGroup, RadioGroupItem } from '@signozhq/ui/radio-group';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { RadioGroup } from '@signozhq/ui/radio-group';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Typography } from '@signozhq/ui/typography';
import {
ClientExportData,
@@ -51,31 +51,40 @@ export default function ExportMenu({
return (
<Popover open={isPopoverOpen} onOpenChange={setIsPopoverOpen}>
<TooltipSimple title="Download">
<Tooltip title="Download">
<PopoverTrigger asChild>
<Button
disabledTooltip={undefined}
variant="ghost"
color="secondary"
size="icon"
size="sm"
icon
aria-label="Download"
data-testid={`export-menu-${dataSource}`}
testId={`export-menu-${dataSource}`}
disabled={isExporting}
loading={isExporting}
>
<Download size={14} />
</Button>
</PopoverTrigger>
</TooltipSimple>
</Tooltip>
<PopoverContent align="end" className="export-menu-popover">
<div className="export-format">
<Typography.Text className="title">FORMAT</Typography.Text>
<RadioGroup value={exportFormat} onChange={setExportFormat}>
<RadioGroupItem value={ExportFormat.Csv}>csv</RadioGroupItem>
<RadioGroupItem value={ExportFormat.Jsonl}>jsonl</RadioGroupItem>
</RadioGroup>
<RadioGroup
color="primary"
value={exportFormat}
onChange={setExportFormat}
items={[
{ value: ExportFormat.Csv, label: 'csv' },
{ value: ExportFormat.Jsonl, label: 'jsonl' },
]}
/>
</div>
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="primary"
className="export-button"

View File

@@ -58,8 +58,8 @@ function SortableField({
{!isRequired && (
<Button
className={cx(styles.removeBtn, 'periscope-btn')}
variant="outlined"
color="destructive"
variant="solid"
color="danger"
size="sm"
onClick={(): void => onRemove(field)}
>

View File

@@ -173,6 +173,7 @@ function FieldsSelectorContent({
{hasUnsavedChanges && (
<div className={styles.footer}>
<Button
size="md"
variant="outlined"
color="secondary"
onClick={handleDiscard}
@@ -181,6 +182,7 @@ function FieldsSelectorContent({
Discard
</Button>
<Button
size="md"
variant="solid"
color="primary"
onClick={handleSave}

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { toast } from '@signozhq/ui/sonner';
import { Button, Input } from 'antd';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { Typography } from '@signozhq/ui/typography';
import logEvent from 'api/common/logEvent';
import { handleContactSupport } from 'container/Integrations/utils';
@@ -102,7 +102,10 @@ function FeedbackModal({ onClose }: { onClose: () => void }): JSX.Element {
return (
<div className="feedback-modal-container">
<div className="feedback-modal-header">
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
size="sm"
type="single"
value={activeTab}
className="feedback-modal-tabs"

View File

@@ -2,7 +2,7 @@ import { useCallback, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { Dot } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import Noz from 'components/Noz/Noz';
import { NOZ_TOOLTIP_TITLE } from 'components/Noz/Noz.constants';
import { Popover } from 'antd';
@@ -113,8 +113,9 @@ function HeaderRightSection({
</span>
) : null}
<TooltipSimple title={NOZ_TOOLTIP_TITLE}>
<Tooltip title={NOZ_TOOLTIP_TITLE}>
<Button
size="md"
variant="solid"
color="secondary"
className="noz-wave"
@@ -130,7 +131,7 @@ function HeaderRightSection({
>
<Typography.Text>Noz</Typography.Text>
</Button>
</TooltipSimple>
</Tooltip>
</div>
)}
@@ -147,13 +148,16 @@ function HeaderRightSection({
onOpenChange={handleOpenFeedbackModalChange}
>
<Button
color="secondary"
variant="ghost"
size="icon"
size="sm"
icon
className="share-feedback-btn"
aria-label="Feedback"
prefix={<SquarePen size={14} />}
onClick={handleOpenFeedbackModal}
/>
>
<SquarePen size={14} />
</Button>
</Popover>
)}
@@ -170,16 +174,19 @@ function HeaderRightSection({
onOpenChange={handleOpenAnnouncementsModalChange}
>
<Button
color="secondary"
variant="ghost"
size="icon"
size="sm"
icon
aria-label="Announcements"
prefix={<Inbox size={14} />}
onClick={(): void => {
logEvent('Announcements: Clicked', {
page: location.pathname,
});
}}
/>
>
<Inbox size={14} />
</Button>
</Popover>
)}
@@ -196,12 +203,15 @@ function HeaderRightSection({
onOpenChange={handleOpenShareURLModalChange}
>
<Button
color="secondary"
variant="ghost"
size="icon"
size="sm"
icon
aria-label="Share"
prefix={<Globe size={14} />}
onClick={handleOpenShareURLModal}
/>
>
<Globe size={14} />
</Button>
</Popover>
)}
</div>

View File

@@ -149,6 +149,9 @@ function ShareURLModal({ extraOption }: ShareURLModalProps): JSX.Element {
<Info size={14} color={Color.BG_AMBER_600} />
)}
<Switch
color="primary"
textPlacement="right"
disabledTooltip={undefined}
value={enableAbsoluteTime}
disabled={!isValidateRelativeTime}
onChange={(): void => {
@@ -173,6 +176,8 @@ function ShareURLModal({ extraOption }: ShareURLModalProps): JSX.Element {
</Typography.Text>
<div className="absolute-relative-time-toggler">
<Switch
color="primary"
textPlacement="right"
value={enableExtraOption}
onChange={(): void => setEnableExtraOption((prev) => !prev)}
/>

View File

@@ -1,14 +1,23 @@
import { Badge } from '@signozhq/ui/badge';
import { Badge, type BadgeColorType } from '@signozhq/ui/badge';
type BadgeColor =
| 'vanilla'
| 'robin'
| 'forest'
| 'amber'
| 'sienna'
| 'cherry'
| 'sakura'
| 'aqua';
function getStatusCodeColor(statusCode: number): BadgeColorType {
if (statusCode >= 200 && statusCode < 300) {
return 'success';
}
if (statusCode >= 300 && statusCode < 400) {
return 'primary';
}
if (statusCode >= 400 && statusCode < 500) {
return 'warning';
}
if (statusCode >= 500) {
return 'danger';
}
if (statusCode >= 100 && statusCode < 200) {
return 'secondary';
}
return 'primary';
}
interface HttpStatusBadgeProps {
statusCode: string | number;
@@ -16,25 +25,6 @@ interface HttpStatusBadgeProps {
className?: string;
}
function getStatusCodeColor(statusCode: number): BadgeColor {
if (statusCode >= 200 && statusCode < 300) {
return 'forest'; // Success - green
}
if (statusCode >= 300 && statusCode < 400) {
return 'robin'; // Redirect - blue
}
if (statusCode >= 400 && statusCode < 500) {
return 'amber'; // Client error - amber
}
if (statusCode >= 500) {
return 'cherry'; // Server error - red
}
if (statusCode >= 100 && statusCode < 200) {
return 'vanilla'; // Informational - neutral
}
return 'robin'; // Default fallback
}
function HttpStatusBadge({
statusCode,
testId,
@@ -49,12 +39,7 @@ function HttpStatusBadge({
const color = getStatusCodeColor(numericStatusCode);
return (
<Badge
color={color}
variant="outline"
data-testid={testId}
className={className}
>
<Badge color={color} variant="outlined" testId={testId} className={className}>
{statusCode}
</Badge>
);

View File

@@ -119,11 +119,12 @@ function InviteMembers({
<div className={styles.cellAction}>
{canRemoveRow && (
<Button
variant="ghost"
color="destructive"
size="md"
variant="solid"
color="danger"
onClick={(): void => removeRow(row.id)}
aria-label="Remove row"
data-testid={`invite-remove-${row.id}`}
testId={`invite-remove-${row.id}`}
>
<Trash2 size={12} />
</Button>
@@ -136,11 +137,12 @@ function InviteMembers({
{showAddButton && (
<div className={styles.addRow}>
<Button
size="md"
variant="dashed"
color="secondary"
prefix={<Plus size={12} />}
onClick={addRow}
data-testid="invite-add-row"
testId="invite-add-row"
>
Add another
</Button>

View File

@@ -1,8 +1,8 @@
import { Button } from '@signozhq/ui/button';
import { Divider } from '@signozhq/ui/divider';
import { DropdownMenuSimple as Dropdown } from '@signozhq/ui/dropdown-menu';
import { DropdownMenuSimple as Dropdown } from 'components/DropdownMenu/DropdownMenuSimple';
import { Typography } from '@signozhq/ui/typography';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { aggregateAttributesResourcesToString } from 'container/LogDetailedView/utils';
import { toast } from '@signozhq/ui/sonner';
@@ -23,8 +23,6 @@ import { useCopyToClipboard } from 'react-use';
import styles from './LogDetailsHeader.module.scss';
const TOOLTIP_CONTENT_PROPS = { className: styles.tooltipContent };
interface LogDetailsHeaderProps {
log: ILog;
onNavigatePrev: () => void;
@@ -91,6 +89,7 @@ function LogDetailsHeader({
<div className={styles.actions}>
{showOpenInExplorer && (
<Button
size="md"
variant="outlined"
color="secondary"
prefix={<Compass size={16} />}
@@ -104,47 +103,59 @@ function LogDetailsHeader({
menu={{ items: menuItems }}
align="end"
className={styles.dropdownContent}
onClick={(e: MouseEvent): void => e.stopPropagation()}
>
<Button
size="md"
variant="link"
color="secondary"
prefix={<Ellipsis size={16} />}
data-testid="log-details-header-menu"
/>
icon
aria-label="Log actions"
testId="log-details-header-menu"
onClick={(e: MouseEvent): void => e.stopPropagation()}
>
<Ellipsis size={16} />
</Button>
</Dropdown>
<div className={styles.arrows}>
<TooltipSimple
<Tooltip
title="Move to previous log"
side="top"
open={isPrevDisabled ? false : undefined}
tooltipContentProps={TOOLTIP_CONTENT_PROPS}
>
<Button
disabledTooltip={undefined}
size="md"
variant="outlined"
color="secondary"
prefix={<ChevronUp size={14} />}
icon
aria-label="Move to previous log"
disabled={isPrevDisabled}
onClick={onNavigatePrev}
data-testid="log-details-header-prev"
/>
</TooltipSimple>
<TooltipSimple
testId="log-details-header-prev"
>
<ChevronUp size={14} />
</Button>
</Tooltip>
<Tooltip
title="Move to next log"
side="top"
open={isNextDisabled ? false : undefined}
tooltipContentProps={TOOLTIP_CONTENT_PROPS}
>
<Button
disabledTooltip={undefined}
size="md"
variant="outlined"
color="secondary"
prefix={<ChevronDown size={14} />}
icon
aria-label="Move to next log"
disabled={isNextDisabled}
onClick={onNavigateNext}
data-testid="log-details-header-next"
/>
</TooltipSimple>
testId="log-details-header-next"
>
<ChevronDown size={14} />
</Button>
</Tooltip>
</div>
</div>
</div>

View File

@@ -1,5 +1,5 @@
import { ReactNode } from 'react';
import { Badge, BadgeColor } from '@signozhq/ui/badge';
import { Badge, type BadgeColorType } from '@signozhq/ui/badge';
import { LogType } from 'components/Logs/LogStateIndicator/LogStateIndicator';
import { getLogIndicatorType } from 'components/Logs/LogStateIndicator/utils';
import { ILog } from 'types/api/logs/log';
@@ -8,13 +8,13 @@ import styles from './LogHighlights.module.scss';
import TraceIdField from './TraceIdField';
// Severity badge color mirrors the LogStateIndicator bar
const SEVERITY_COLOR: Record<string, BadgeColor> = {
[LogType.TRACE]: 'forest',
[LogType.DEBUG]: 'aqua',
[LogType.INFO]: 'robin',
[LogType.WARN]: 'amber',
[LogType.ERROR]: 'cherry',
[LogType.FATAL]: 'sakura',
const SEVERITY_COLOR: Record<string, BadgeColorType> = {
[LogType.TRACE]: 'success',
[LogType.DEBUG]: 'info',
[LogType.INFO]: 'primary',
[LogType.WARN]: 'warning',
[LogType.ERROR]: 'danger',
[LogType.FATAL]: 'highlight-danger',
};
export interface LogHighlightConfig {
@@ -32,9 +32,13 @@ const getAttr = (log: ILog, key: string): string =>
const valueBadge = (
value: string,
options?: { prefix?: ReactNode; color?: BadgeColor },
options?: { prefix?: ReactNode; color?: BadgeColorType },
): ReactNode => (
<Badge color={options?.color ?? 'vanilla'} className={styles.valueBadge}>
<Badge
variant="solid"
color={options?.color ?? 'secondary'}
className={styles.valueBadge}
>
{options?.prefix}
<span className={styles.badgeText} title={value}>
{value}

View File

@@ -4,7 +4,7 @@ import { useCopyToClipboard } from 'react-use';
import { Color, Spacing } from '@signozhq/design-tokens';
import { Button } from '@signozhq/ui/button';
import { Drawer, Tooltip } from 'antd';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { Divider } from '@signozhq/ui/divider';
import { Typography } from '@signozhq/ui/typography';
import cx from 'classnames';
@@ -328,13 +328,18 @@ function LogDetailInner({
mouseLeaveDelay={0}
>
<Button
disabledTooltip={undefined}
size="md"
variant="outlined"
color="secondary"
prefix={<ChevronUp size={14} />}
icon
aria-label="Move to previous log"
className="log-arrow-btn log-arrow-btn-up"
disabled={isPrevDisabled}
onClick={goToPrev}
/>
>
<ChevronUp size={14} />
</Button>
</Tooltip>
<Tooltip
title={isNextDisabled ? '' : 'Move to next log'}
@@ -342,18 +347,24 @@ function LogDetailInner({
mouseLeaveDelay={0}
>
<Button
disabledTooltip={undefined}
size="md"
variant="outlined"
color="secondary"
prefix={<ChevronDown size={14} />}
icon
aria-label="Move to next log"
className="log-arrow-btn log-arrow-btn-down"
disabled={isNextDisabled}
onClick={goToNext}
/>
>
<ChevronDown size={14} />
</Button>
</Tooltip>
</div>
{handleOpenInExplorer && (
<div>
<Button
size="md"
variant="outlined"
color="secondary"
prefix={<Compass size={16} />}
@@ -410,7 +421,10 @@ function LogDetailInner({
{isLogDetailsV2 && <div className="log-detail-drawer__section-divider" />}
<div className="tabs-and-search">
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
size="sm"
type="single"
className="views-tabs"
onChange={handleModeChange}
@@ -473,9 +487,12 @@ function LogDetailInner({
variant="link"
color="secondary"
size="sm"
prefix={<Filter size="lg" />}
icon
aria-label="Show Filters"
onClick={handleFilterVisible}
/>
>
<Filter size="lg" />
</Button>
</Tooltip>
)}
@@ -493,9 +510,14 @@ function LogDetailInner({
variant="link"
color="secondary"
size="sm"
prefix={<Copy size={12} />}
icon
aria-label={
selectedView === VIEW_TYPES.JSON ? 'Copy JSON' : 'Copy Log Link'
}
onClick={selectedView === VIEW_TYPES.JSON ? handleJSONCopy : onLogCopy}
/>
>
<Copy size={12} />
</Button>
</Tooltip>
)}
</div>

View File

@@ -1,4 +1,4 @@
import type { ReactNode } from 'react';
import type { ReactElement, ReactNode } from 'react';
import {
Bold,
CodeXml,
@@ -11,7 +11,7 @@ import {
Type,
} from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Typography } from '@signozhq/ui/typography';
import InsertVariableMenu from './InsertVariableMenu';
@@ -20,7 +20,7 @@ import type { EditorCommand, EditorVariable } from './types';
import styles from './MarkdownEditor.module.scss';
const COMMAND_ICONS: Record<string, ReactNode> = {
const COMMAND_ICONS: Record<string, ReactElement> = {
heading: <Heading size={14} />,
bold: <Bold size={14} />,
italic: <Italic size={14} />,
@@ -61,20 +61,22 @@ function EditorToolbar({
<span className={styles.toolbarDivider} />
<div className={styles.commands}>
{commands.map((command) => (
<TooltipSimple key={command.id} title={command.label}>
<Tooltip key={command.id} title={command.label}>
<Button
disabledTooltip={undefined}
type="button"
variant="ghost"
color="secondary"
size="icon"
size="sm"
icon
disabled={disabled}
aria-label={command.label}
data-testid={`markdown-command-${command.id}`}
testId={`markdown-command-${command.id}`}
onClick={(): void => onRunCommand(command)}
>
{COMMAND_ICONS[command.id]}
</Button>
</TooltipSimple>
</Tooltip>
))}
</div>
<div className={styles.toolbarEnd}>

View File

@@ -1,7 +1,10 @@
import { useMemo, useState } from 'react';
import { ChevronDown, DollarSign, Search } from '@signozhq/icons';
import { ChevronDown, DollarSign } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import {
DropdownMenuSimple,
type MenuItem,
} from 'components/DropdownMenu/DropdownMenuSimple';
import type { EditorVariable } from './types';
@@ -66,12 +69,12 @@ function InsertVariableMenu({
items,
search: {
placeholder: 'Search variables',
searchIcon: <Search size={14} />,
onSearchChange: setSearch,
},
}}
>
<Button
disabledTooltip={undefined}
type="button"
variant="outlined"
color="secondary"
@@ -80,7 +83,7 @@ function InsertVariableMenu({
prefix={<DollarSign size={14} className={styles.insertVariableIcon} />}
suffix={<ChevronDown size={14} />}
className={styles.insertVariable}
data-testid="markdown-insert-variable"
testId="markdown-insert-variable"
>
Insert variable
</Button>

View File

@@ -15,9 +15,10 @@ function MarkdownHelp(): JSX.Element {
type="button"
variant="ghost"
color="secondary"
size="icon"
size="sm"
icon
aria-label="Markdown syntax help"
data-testid="markdown-help-trigger"
testId="markdown-help-trigger"
>
<CircleHelp size={14} />
</Button>

View File

@@ -55,14 +55,14 @@ function NameEmailCell({
function StatusBadge({ status }: { status: MemberRow['status'] }): JSX.Element {
if (status === MemberStatus.Active) {
return (
<Badge color="forest" variant="outline">
<Badge color="success" variant="outlined">
ACTIVE
</Badge>
);
}
if (status === MemberStatus.Deleted) {
return (
<Badge color="cherry" variant="outline">
<Badge color="danger" variant="outlined">
DELETED
</Badge>
);
@@ -70,13 +70,17 @@ function StatusBadge({ status }: { status: MemberRow['status'] }): JSX.Element {
if (status === MemberStatus.Invited) {
return (
<Badge color="amber" variant="outline">
<Badge color="warning" variant="outlined">
INVITED
</Badge>
);
}
return <Badge color="vanilla"></Badge>;
return (
<Badge variant="solid" color="secondary">
</Badge>
);
}
function MembersEmptyState({

View File

@@ -20,7 +20,7 @@ import {
import { Color } from '@signozhq/design-tokens';
import { Button, Select } from 'antd';
import { Checkbox } from '@signozhq/ui/checkbox';
import { TooltipProvider, TooltipSimple } from '@signozhq/ui/tooltip';
import { TooltipProvider, Tooltip } from '@signozhq/ui/tooltip';
import { Typography } from '@signozhq/ui/typography';
import cx from 'classnames';
import TextToolTip from 'components/TextToolTip/TextToolTip';
@@ -758,9 +758,14 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
tabIndex={isActive ? 0 : -1}
>
<Checkbox
color="primary"
value={isSelected}
className="option-checkbox"
onClick={(e): void => selectFromButton(e, 'checkbox')}
onChange={(): void => {
handleItemSelection('checkbox');
setActiveChipIndex(-1);
setActiveIndex(-1);
}}
>
<div className="option-content">
<Typography.Text truncate={1} className="option-label-text">
@@ -1595,7 +1600,11 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
}}
>
<div style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
<Checkbox value={allOptionsSelected} className="option-checkbox">
<Checkbox
color="primary"
value={allOptionsSelected}
className="option-checkbox"
>
<div className="option-content">
<div className="all-option-text">ALL</div>
</div>
@@ -1973,13 +1982,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
// `label` arrives already cut to maxTagTextLength, so the reveal reads the
// option's own text (falling back to the raw value for freeform tags).
return (
<TooltipSimple
side="top"
delayDuration={300}
title={findOptionLabelText(options, value)}
>
<Tooltip side="top" title={findOptionLabelText(options, value)}>
{tag}
</TooltipSimple>
</Tooltip>
);
}

View File

@@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Button, Tooltip } from 'antd';
import cx from 'classnames';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import InputWithLabel from 'components/InputWithLabel/InputWithLabel';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { GroupByFilter } from 'container/QueryBuilder/filters/GroupByFilter/GroupByFilter';
@@ -562,7 +562,10 @@ function QueryAddOns({
</div>
)}
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
size="sm"
type="multiple"
className="add-ons-tabs"
value={selectedViews.map((view) => view.key)}

View File

@@ -724,26 +724,62 @@ function QuerySearch({
// Helper function to render a badge for the current context mode
const renderContextBadge = (): JSX.Element => {
if (!editingMode) {
return <Badge color="vanilla">Unknown</Badge>;
return (
<Badge variant="solid" color="secondary">
Unknown
</Badge>
);
}
switch (editingMode) {
case 'key':
return <Badge color="robin">Key</Badge>;
return (
<Badge variant="solid" color="primary">
Key
</Badge>
);
case 'operator':
return <Badge color="sakura">Operator</Badge>;
return (
<Badge variant="solid" color="highlight-danger">
Operator
</Badge>
);
case 'value':
return <Badge color="forest">Value</Badge>;
return (
<Badge variant="solid" color="success">
Value
</Badge>
);
case 'conjunction':
return <Badge color="amber">Conjunction</Badge>;
return (
<Badge variant="solid" color="warning">
Conjunction
</Badge>
);
case 'function':
return <Badge color="aqua">Function</Badge>;
return (
<Badge variant="solid" color="info">
Function
</Badge>
);
case 'parenthesis':
return <Badge color="sakura">Parenthesis</Badge>;
return (
<Badge variant="solid" color="highlight-danger">
Parenthesis
</Badge>
);
case 'bracketList':
return <Badge color="cherry">Bracket List</Badge>;
return (
<Badge variant="solid" color="danger">
Bracket List
</Badge>
);
default:
return <Badge color="vanilla">Unknown</Badge>;
return (
<Badge variant="solid" color="secondary">
Unknown
</Badge>
);
}
};
@@ -1465,27 +1501,44 @@ function QuerySearch({
Currently editing: {renderContextBadge()}
{queryContext?.keyToken && (
<span className="triplet-info">
Key: <Badge color="vanilla">{queryContext.keyToken}</Badge>
Key:{' '}
<Badge variant="solid" color="secondary">
{queryContext.keyToken}
</Badge>
</span>
)}
{queryContext?.operatorToken && (
<span className="triplet-info">
Operator: <Badge color="vanilla">{queryContext.operatorToken}</Badge>
Operator:{' '}
<Badge variant="solid" color="secondary">
{queryContext.operatorToken}
</Badge>
</span>
)}
{queryContext?.valueToken && (
<span className="triplet-info">
Value: <Badge color="vanilla">{queryContext.valueToken}</Badge>
Value:{' '}
<Badge variant="solid" color="secondary">
{queryContext.valueToken}
</Badge>
</span>
)}
{queryContext?.currentPair && (
<span className="triplet-info query-pair-info">
Current pair: <Badge color="robin">{queryContext.currentPair.key}</Badge>
<Badge color="sakura">{queryContext.currentPair.operator}</Badge>
Current pair:{' '}
<Badge variant="solid" color="primary">
{queryContext.currentPair.key}
</Badge>
<Badge variant="solid" color="highlight-danger">
{queryContext.currentPair.operator}
</Badge>
{queryContext.currentPair.value && (
<Badge color="forest">{queryContext.currentPair.value}</Badge>
<Badge variant="solid" color="success">
{queryContext.currentPair.value}
</Badge>
)}
<Badge
variant="solid"
color={queryContext.currentPair.isComplete ? 'success' : 'warning'}
>
{queryContext.currentPair.isComplete ? 'Complete' : 'Incomplete'}
@@ -1495,7 +1548,9 @@ function QuerySearch({
{queryContext?.queryPairs && queryContext.queryPairs.length > 0 && (
<span className="triplet-info">
Total pairs:{' '}
<Badge color="robin">{queryContext.queryPairs.length}</Badge>
<Badge variant="solid" color="primary">
{queryContext.queryPairs.length}
</Badge>
</span>
)}
</div>

View File

@@ -6,7 +6,7 @@ import {
useMemo,
useState,
} from 'react';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { DropdownMenuSimple } from 'components/DropdownMenu/DropdownMenuSimple';
import cx from 'classnames';
import { ENTITY_VERSION_V4, ENTITY_VERSION_V5 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder';

View File

@@ -2,7 +2,7 @@ import { Button } from 'antd';
import { Checkbox } from '@signozhq/ui/checkbox';
import { Typography } from '@signozhq/ui/typography';
import cx from 'classnames';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
interface CheckboxValueRowProps {
value: string;
@@ -28,6 +28,8 @@ function CheckboxValueRow({
return (
<div className="value">
<Checkbox
color="primary"
disabledTooltip={undefined}
onChange={(isChecked): void => onCheckboxChange(isChecked === true)}
value={checked}
disabled={disabled}
@@ -47,11 +49,11 @@ function CheckboxValueRow({
{customRendererForValue ? (
customRendererForValue(value)
) : (
<TooltipSimple title={String(value)} side="top" align="start">
<Tooltip title={String(value)} side="top" align="start">
<Typography.Text className="value-string" truncate={1}>
{String(value)}
</Typography.Text>
</TooltipSimple>
</Tooltip>
)}
<div className="value-actions">
<Button type="text" className="only-btn">

View File

@@ -1,5 +1,5 @@
import { useState } from 'react';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Typography } from '@signozhq/ui/typography';
import { ChevronDown, ChevronRight, Search, Undo2 } from '@signozhq/icons';
@@ -63,9 +63,7 @@ export function CheckboxFilterV2Header({
<ChevronRight size={13} cursor="pointer" />
)}
{isTitleTruncated ? (
<TooltipSimple title={title} delayDuration={400}>
{titleText}
</TooltipSimple>
<Tooltip title={title}>{titleText}</Tooltip>
) : (
titleText
)}

View File

@@ -54,6 +54,7 @@ export function CheckboxFilterV2ValueRow({
>
<div className={styles.checkbox}>
<Checkbox
disabledTooltip={undefined}
onChange={(isChecked): void =>
onCheckboxChange(isChecked === true, checkedState)
}
@@ -97,7 +98,7 @@ export function CheckboxFilterV2ValueRow({
<div className={styles.actions}>
{badge && (
<Badge
variant="outline"
variant="outlined"
color={badge.color}
className={styles.badge}
testId={`badge-${badge.key}`}
@@ -105,10 +106,20 @@ export function CheckboxFilterV2ValueRow({
{badge.label}
</Badge>
)}
<Button variant="ghost" color="secondary" className={styles.onlyButton}>
<Button
size="md"
variant="ghost"
color="secondary"
className={styles.onlyButton}
>
{onlyButtonLabel}
</Button>
<Button variant="ghost" color="secondary" className={styles.toggleButton}>
<Button
size="md"
variant="ghost"
color="secondary"
className={styles.toggleButton}
>
Toggle
</Button>
</div>

View File

@@ -64,7 +64,7 @@ describe('CheckboxFilterV2ValueRow', () => {
render(
<CheckboxFilterV2ValueRow
{...defaultProps}
badge={{ key: 'related', label: 'Related', color: 'robin' }}
badge={{ key: 'related', label: 'Related', color: 'primary' }}
/>,
);

View File

@@ -9,7 +9,7 @@ export enum SectionType {
export interface BadgeConfig {
key: string;
label: string;
color: 'robin' | 'warning' | 'secondary';
color: 'primary' | 'warning' | 'secondary';
}
export interface ItemConfig {

View File

@@ -23,21 +23,22 @@ export function SectionActionButton({
}: SectionActionButtonProps): JSX.Element {
return (
<Tooltip title={tooltip}>
<Button
variant="link"
color="secondary"
size="sm"
className={classNames(styles.iconBtn, className)}
onMouseDown={(e): void => e.preventDefault()}
onClick={(e): void => {
e.stopPropagation();
e.preventDefault();
onClick();
}}
data-testid={testId}
>
{icon}
</Button>
<span onMouseDown={(e): void => e.preventDefault()}>
<Button
variant="link"
color="secondary"
size="sm"
className={classNames(styles.iconBtn, className)}
onClick={(e): void => {
e.stopPropagation();
e.preventDefault();
onClick();
}}
testId={testId}
>
{icon}
</Button>
</span>
</Tooltip>
);
}

View File

@@ -232,48 +232,55 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
<section className="right-actions">
<Tooltip title="Reset All">
<Button
size="md"
variant="link"
color="secondary"
icon
aria-label="Reset All"
className="right-action-icon-container"
onClick={handleReset}
prefix={<RefreshCw className="sync-icon" size="md" />}
/>
>
<RefreshCw className="sync-icon" size="md" />
</Button>
</Tooltip>
{showFilterCollapse && (
<Tooltip title="Collapse Filters">
<Button
size="md"
variant="link"
color="secondary"
icon
aria-label="Collapse Filters"
className="right-action-icon-container"
onClick={handleFilterVisibilityChange}
prefix={<ArrowUpToLine style={{ rotate: '270deg' }} size="md" />}
/>
>
<ArrowUpToLine style={{ rotate: '270deg' }} size="md" />
</Button>
</Tooltip>
)}
{isDynamicFilters && (
<AuthZButton
size="md"
checks={QuickFilterManagePermissions}
variant="link"
color="secondary"
icon
aria-label="Settings"
className={classNames('right-action-icon-container', {
active: isSettingsOpen,
})}
onClick={(): void => setIsSettingsOpen(true)}
testId="settings-icon-container"
prefix={
<Tooltip title="Settings" open={isSettingsDisabled ? false : undefined}>
<SettingsIcon
className="settings-icon"
data-testid="settings-icon"
width={14}
height={14}
/>
</Tooltip>
}
/>
>
<Tooltip title="Settings" open={isSettingsDisabled ? false : undefined}>
<SettingsIcon
className="settings-icon"
data-testid="settings-icon"
width={14}
height={14}
/>
</Tooltip>
</AuthZButton>
)}
</section>
);
@@ -284,6 +291,8 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
<div className="api-quick-filters-header">
<Typography.Text>Show IP addresses</Typography.Text>
<Switch
color="primary"
textPlacement="right"
style={{ marginLeft: 'auto' }}
value={showIP ?? true}
onChange={(checked): void => {

View File

@@ -61,6 +61,7 @@ function AnnouncementTooltip({
<p className="announcement-tooltip__message">{message}</p>
<div className="announcement-tooltip__footer">
<Button
size="md"
variant="solid"
color="primary"
onClick={closeTooltip}

View File

@@ -2,7 +2,7 @@ import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { refreshLicense } from 'api/generated/services/licenses';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { RefreshCcw } from '@signozhq/icons';
import AuthZTooltip from 'lib/authz/components/AuthZTooltip/AuthZTooltip';
import { buildLicenseUpdatePermission } from 'lib/authz/hooks/useAuthZ/permissions/license.permissions';
@@ -49,7 +49,7 @@ function RefreshPaymentStatus({
>
<Button
variant="link"
color={type === 'text' ? 'none' : 'secondary'}
color="secondary"
size="md"
className={className}
onClick={handleRefreshPaymentStatus}
@@ -64,7 +64,7 @@ function RefreshPaymentStatus({
return (
<span className="refresh-payment-status-btn-wrapper">
{type === 'tooltip' ? (
<TooltipSimple title={t('refreshPaymentStatus')}>{button}</TooltipSimple>
<Tooltip title={t('refreshPaymentStatus')}>{button}</Tooltip>
) : (
button
)}

View File

@@ -5,7 +5,10 @@ import type {
TableColumnType as ColumnType,
} from 'antd';
import { Button, Flex } from 'antd';
import { DropdownMenuSimple, type MenuItem } from '@signozhq/ui/dropdown-menu';
import {
DropdownMenuSimple,
type MenuItem,
} from 'components/DropdownMenu/DropdownMenuSimple';
import { Switch } from '@signozhq/ui/switch';
import logEvent from 'api/common/logEvent';
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
@@ -95,6 +98,8 @@ function DynamicColumnTable({
>
<div>{column.title?.toString()}</div>
<Switch
color="primary"
textPlacement="right"
value={columnsData?.findIndex((c) => c.key === column.key) !== -1}
onChange={onToggleHandler(index, column)}
/>

View File

@@ -152,7 +152,7 @@ function RolesSelect(props: RolesSelectProps): JSX.Element {
optionFilterProp="label"
optionRender={(option): JSX.Element => (
<div style={{ pointerEvents: 'none' }}>
<Checkbox value={value.includes(option.value as string)}>
<Checkbox color="primary" value={value.includes(option.value as string)}>
{option.label}
</Checkbox>
</div>

View File

@@ -24,6 +24,7 @@ function KeyCreatedPhase({
<div className="add-key-modal__key-display">
<span className="add-key-modal__key-text">{createdKey.key}</span>
<Button
size="md"
variant="link"
color="secondary"
onClick={onCopy}
@@ -36,7 +37,9 @@ function KeyCreatedPhase({
<div className="add-key-modal__expiry-meta">
<span className="add-key-modal__expiry-label">Expiration</span>
<Badge color="vanilla">{expiryLabel}</Badge>
<Badge variant="solid" color="secondary">
{expiryLabel}
</Badge>
</div>
<div className="add-key-modal__callout-wrapper">

View File

@@ -2,7 +2,7 @@ import type { Control, UseFormRegister } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import { Button } from '@signozhq/ui/button';
import { Input } from '@signozhq/ui/input';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { DatePicker } from 'antd';
import AuthZButton from 'lib/authz/components/AuthZButton/AuthZButton';
import { AuthZGuardContent } from 'lib/authz/components/AuthZGuard/AuthZGuardContent';
@@ -68,7 +68,9 @@ function KeyFormPhase({
name="expiryMode"
control={control}
render={({ field }): JSX.Element => (
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
type="single"
value={field.value}
onChange={(val: string): void => {
@@ -117,6 +119,7 @@ function KeyFormPhase({
<div className="add-key-modal__footer">
<div className="add-key-modal__footer-right">
<Button
size="md"
variant="solid"
color="secondary"
onClick={onClose}
@@ -125,16 +128,22 @@ function KeyFormPhase({
Cancel
</Button>
<AuthZButton
size="md"
checks={checks}
authZEnabled={!!accountId}
withPortal={false}
type="submit"
form={FORM_ID}
type="button"
variant="solid"
color="primary"
loading={isSubmitting}
disabled={!isValid}
testId="add-key-submit-btn"
onClick={(): void => {
const form = document.getElementById(FORM_ID);
if (form instanceof HTMLFormElement) {
form.requestSubmit();
}
}}
>
Create Key
</AuthZButton>

View File

@@ -80,15 +80,16 @@ function DeleteAccountModal(): JSX.Element {
const footer = (
<div className="sa-delete-dialog__footer">
<Button variant="solid" color="secondary" onClick={handleCancel}>
<Button size="md" variant="solid" color="secondary" onClick={handleCancel}>
<X size={12} />
Cancel
</Button>
<AuthZButton
size="md"
checks={[buildSADeletePermission(accountId ?? '')]}
authZEnabled={!!accountId}
variant="solid"
color="destructive"
color="danger"
loading={isDeleting}
onClick={handleConfirm}
data-testid="confirm-delete-btn"

View File

@@ -4,7 +4,7 @@ import { LockKeyhole, Trash2, X } from '@signozhq/icons';
import { Badge } from '@signozhq/ui/badge';
import { Button } from '@signozhq/ui/button';
import { Input } from '@signozhq/ui/input';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { DatePicker } from 'antd';
import type { ServiceaccounttypesGettableFactorAPIKeyDTO } from 'api/generated/services/sigNoz.schemas';
import AuthZButton from 'lib/authz/components/AuthZButton/AuthZButton';
@@ -103,7 +103,9 @@ function EditKeyForm({
name="expiryMode"
control={control}
render={({ field }): JSX.Element => (
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
type="single"
value={field.value}
onChange={(val: string): void => {
@@ -113,6 +115,9 @@ function EditKeyForm({
}}
size="sm"
disabled={!canUpdate}
disabledTooltip={
canUpdate ? undefined : 'You do not have permission to update this key'
}
className="edit-key-modal__expiry-toggle"
items={[
{ value: ExpiryMode.NONE, label: 'No Expiration' },
@@ -150,7 +155,7 @@ function EditKeyForm({
<div className="edit-key-modal__meta">
<span className="edit-key-modal__meta-label">Last Observed At</span>
<Badge color="vanilla">
<Badge variant="solid" color="secondary">
{formatLastObservedAt(
keyItem?.lastObservedAt ?? null,
formatTimezoneAdjustedTimestamp,
@@ -161,13 +166,14 @@ function EditKeyForm({
<div className="edit-key-modal__footer">
<AuthZButton
size="md"
checks={[
buildAPIKeyDeletePermission(keyItem?.id ?? ''),
buildSADetachPermission(accountId ?? ''),
]}
authZEnabled={!!accountId && !!keyItem?.id}
variant="link"
color="destructive"
color="danger"
onClick={onRevokeClick}
withPortal={false}
>
@@ -175,20 +181,26 @@ function EditKeyForm({
Revoke Key
</AuthZButton>
<div className="edit-key-modal__footer-right">
<Button variant="solid" color="secondary" onClick={onClose}>
<Button size="md" variant="solid" color="secondary" onClick={onClose}>
<X size={12} />
Cancel
</Button>
<AuthZButton
size="md"
checks={[buildAPIKeyUpdatePermission(keyItem?.id ?? '')]}
authZEnabled={!!accountId && !!keyItem?.id}
type="submit"
form={FORM_ID}
type="button"
variant="solid"
color="primary"
loading={isSaving}
disabled={!isDirty}
withPortal={false}
onClick={(): void => {
const form = document.getElementById(FORM_ID);
if (form instanceof HTMLFormElement) {
form.requestSubmit();
}
}}
>
Save Changes
</AuthZButton>

View File

@@ -122,9 +122,11 @@ function buildColumns({
]}
authZEnabled={!isDisabled && !!accountId}
withPortal={false}
variant="ghost"
variant="solid"
size="sm"
color="destructive"
color="danger"
icon
aria-label="Revoke Key"
disabled={isDisabled}
onClick={(e): void => {
e.stopPropagation();
@@ -213,6 +215,7 @@ function KeysTab({
</a>
</p>
<AuthZButton
size="md"
checks={[APIKeyCreatePermission, buildSAAttachPermission(accountId)]}
authZEnabled={!isDisabled && !!accountId}
withPortal={false}

View File

@@ -122,11 +122,12 @@ function OverviewTab({
<span className="sa-drawer__input-text">{account.id || '—'}</span>
{account.id && (
<Button
size="md"
variant="link"
color="secondary"
onClick={handleCopyId}
className="sa-drawer__copy-btn"
data-testid="copy-id-btn"
testId="copy-id-btn"
>
{hasCopiedId ? <Check size={14} /> : <Copy size={14} />}
</Button>
@@ -156,7 +157,7 @@ function OverviewTab({
localRoles.map((roleId) => {
const role = availableRoles.find((r) => r.id === roleId);
return (
<Badge key={roleId} color="vanilla">
<Badge variant="solid" key={roleId} color="secondary">
{role?.name ?? roleId}
</Badge>
);
@@ -187,15 +188,15 @@ function OverviewTab({
<div className="sa-drawer__meta-item">
<span className="sa-drawer__meta-label">Status</span>
{account.status?.toUpperCase() === 'ACTIVE' ? (
<Badge color="forest" variant="outline">
<Badge color="success" variant="outlined">
ACTIVE
</Badge>
) : account.status?.toUpperCase() === 'DELETED' ? (
<Badge color="cherry" variant="outline">
<Badge color="danger" variant="outlined">
DELETED
</Badge>
) : (
<Badge color="vanilla" variant="outline" className="sa-status-badge">
<Badge color="secondary" variant="outlined" className="sa-status-badge">
{account.status ? account.status.toUpperCase() : 'UNKNOWN'}
</Badge>
)}
@@ -203,12 +204,16 @@ function OverviewTab({
<div className="sa-drawer__meta-item">
<span className="sa-drawer__meta-label">Created At</span>
<Badge color="vanilla">{formatTimestamp(account.createdAt)}</Badge>
<Badge variant="solid" color="secondary">
{formatTimestamp(account.createdAt)}
</Badge>
</div>
<div className="sa-drawer__meta-item">
<span className="sa-drawer__meta-label">Updated At</span>
<Badge color="vanilla">{formatTimestamp(account.updatedAt)}</Badge>
<Badge variant="solid" color="secondary">
{formatTimestamp(account.updatedAt)}
</Badge>
</div>
</div>

View File

@@ -41,18 +41,19 @@ export function RevokeKeyFooter({
}: RevokeKeyFooterProps): JSX.Element {
return (
<>
<Button variant="solid" color="secondary" onClick={onCancel}>
<Button size="md" variant="solid" color="secondary" onClick={onCancel}>
<X size={12} />
Cancel
</Button>
<AuthZButton
size="md"
checks={[
buildAPIKeyDeletePermission(keyId ?? ''),
buildSADetachPermission(accountId ?? ''),
]}
authZEnabled={!!accountId && !!keyId}
variant="solid"
color="destructive"
color="danger"
loading={isRevoking}
onClick={onConfirm}
withPortal={false}

View File

@@ -40,8 +40,9 @@ function SaveErrorItem({
</span>
{onRetry && !isRetrying && (
<Button
size="md"
variant="link"
color="none"
color="secondary"
aria-label="Retry"
onClick={async (e): Promise<void> => {
e.stopPropagation();

View File

@@ -10,7 +10,7 @@ import { Key, LayoutGrid, Plus, Trash2, X } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { DrawerWrapper } from '@signozhq/ui/drawer';
import { toast } from '@signozhq/ui/sonner';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { Skeleton } from 'antd';
import { convertToApiError } from 'api/ErrorResponseHandlerForGeneratedAPIs';
import {
@@ -375,11 +375,12 @@ function ServiceAccountDrawer({
activeTab === ServiceAccountDrawerTab.Overview && !isDeleted && open ? (
<div className="sa-drawer__footer">
<AuthZButton
size="md"
checks={[buildSADeletePermission(selectedAccountId ?? '')]}
authZEnabled={!!selectedAccountId}
withPortal={false}
variant="link"
color="destructive"
color="danger"
onClick={(): void => {
void setIsDeleteOpen(true);
}}
@@ -388,11 +389,17 @@ function ServiceAccountDrawer({
Delete Service Account
</AuthZButton>
<div className="sa-drawer__footer-right">
<Button variant="outlined" color="secondary" onClick={handleClose}>
<Button
size="md"
variant="outlined"
color="secondary"
onClick={handleClose}
>
<X size={14} />
Cancel
</Button>
<AuthZButton
size="md"
checks={[
buildSAReadPermission(selectedAccountId ?? ''),
buildSAUpdatePermission(selectedAccountId ?? ''),
@@ -426,7 +433,9 @@ function ServiceAccountDrawer({
const body = (
<div className="sa-drawer__layout">
<div className="sa-drawer__tabs">
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
type="single"
value={activeTab}
size="sm"

View File

@@ -28,20 +28,20 @@ export function NameEmailCell({
export function StatusBadge({ status }: { status: string }): JSX.Element {
if (status?.toUpperCase() === 'ACTIVE') {
return (
<Badge color="forest" variant="outline">
<Badge color="success" variant="outlined">
ACTIVE
</Badge>
);
}
if (status?.toUpperCase() === 'DELETED') {
return (
<Badge color="cherry" variant="outline">
<Badge color="danger" variant="outlined">
DELETED
</Badge>
);
}
return (
<Badge color="vanilla" variant="outline" className="sa-status-badge">
<Badge color="secondary" variant="outlined" className="sa-status-badge">
{status ? status.toUpperCase() : 'UNKNOWN'}
</Badge>
);

View File

@@ -13,7 +13,13 @@ function ModalFixture(): JSX.Element {
return (
<>
<Button data-testid="open-signoz-modal" onClick={(): void => setOpen(true)}>
<Button
size="md"
variant="solid"
color="primary"
testId="open-signoz-modal"
onClick={(): void => setOpen(true)}
>
Open modal
</Button>
<SignozModal

View File

@@ -1,4 +1,4 @@
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import './SignozRadioGroup.styles.scss';
@@ -24,12 +24,16 @@ function SignozRadioGroup({
disabled = false,
}: SignozRadioGroupProps): JSX.Element {
return (
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
size="sm"
type="single"
value={value}
className={`signoz-radio-group ${className}`}
onChange={onChange}
disabled={disabled}
disabledTooltip={undefined}
items={options.map((option) => ({
value: option.value,
label: (

View File

@@ -12,7 +12,7 @@ function BadgeWithTooltip({
return (
<div key={label}>
<Tooltip title={tooltipTitle}>
<Badge className="label-column--tag" color="vanilla">
<Badge variant="solid" className="label-column--tag" color="secondary">
{getLabelRenderingValue(label, value && value[label])}
</Badge>
</Tooltip>

View File

@@ -27,7 +27,11 @@ function LabelColumn({ labels, value }: LabelColumnProps): JSX.Element {
{labels.map(
(label: string): JSX.Element => (
<div key={label}>
<Badge className="label-column--tag" color="vanilla">
<Badge
variant="solid"
className="label-column--tag"
color="secondary"
>
{getLabelAndValueContent(label, value && value[label])}
</Badge>
</div>
@@ -37,7 +41,7 @@ function LabelColumn({ labels, value }: LabelColumnProps): JSX.Element {
}
trigger="hover"
>
<Badge className="label-column--tag" color="vanilla">
<Badge variant="solid" className="label-column--tag" color="secondary">
+{remainingLabels.length}
</Badge>
</Popover>

View File

@@ -1,4 +1,5 @@
import { type MouseEvent, type ReactNode } from 'react';
import { X } from '@signozhq/icons';
import { Badge } from '@signozhq/ui/badge';
import cx from 'classnames';
@@ -23,11 +24,22 @@ function TagBadge({
}: TagBadgeProps): JSX.Element {
return (
<Badge
color="sienna"
variant="outline"
color="archive"
variant="outlined"
className={cx(styles.static, className)}
closable={closable}
onClose={onClose}
suffix={
closable ? (
<button
type="button"
aria-label="Remove"
onClick={(event): void => {
onClose?.(event);
}}
>
<X size={12} />
</button>
) : undefined
}
>
{children}
</Badge>

View File

@@ -1,5 +1,6 @@
import { type ChangeEvent, type KeyboardEvent, useState } from 'react';
import { Button } from '@signozhq/ui/button';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Input } from '@signozhq/ui/input';
import { Typography } from '@signozhq/ui/typography';
import cx from 'classnames';
@@ -138,16 +139,18 @@ function TagKeyValueInput({
closable
onClose={(): void => removeTag(tag)}
>
<Button
variant="ghost"
color="secondary"
className={styles.tagLabel}
title="Double-click to edit"
testId={`${testId}-chip`}
onDoubleClick={(): void => startEdit(index)}
>
{tag}
</Button>
<Tooltip title="Double-click to edit">
<Button
size="md"
variant="ghost"
color="secondary"
className={styles.tagLabel}
testId={`${testId}-chip`}
onDoubleClick={(): void => startEdit(index)}
>
{tag}
</Button>
</Tooltip>
</TagBadge>
),
)}

View File

@@ -1,14 +1,10 @@
import { type ReactNode, useLayoutEffect, useMemo } from 'react';
import { type ReactNode, useLayoutEffect } from 'react';
import { chromePerformanceTanstackTableEndHover } from './perfDevtools';
import { useIsRowHovered } from './TanStackTableStateContext';
import {
TooltipContentProps,
TooltipSimple,
TooltipSimpleProps,
} from '@signozhq/ui/tooltip';
import { Tooltip, TooltipProps, TooltipProvider } from '@signozhq/ui/tooltip';
export type HoverTooltipProps = Omit<TooltipSimpleProps, 'open'> & {
export type HoverTooltipProps = Omit<TooltipProps, 'open'> & {
rowId: string;
children: ReactNode;
};
@@ -26,28 +22,13 @@ export function TanStackHoverTooltip({
}
}, [isHovered, rowId]);
const tooltipContentProps = useMemo(
() =>
({
onPointerDownOutside: (e): void => {
e.preventDefault();
e.stopPropagation();
},
}) satisfies TooltipContentProps,
[],
);
if (!isHovered) {
return <>{children}</>;
}
return (
<TooltipSimple
delayDuration={700}
tooltipContentProps={tooltipContentProps}
{...tooltipProps}
>
{children}
</TooltipSimple>
<TooltipProvider delay={700}>
<Tooltip {...tooltipProps}>{children}</Tooltip>
</TooltipProvider>
);
}

View File

@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
import { Color } from '@signozhq/design-tokens';
import { Ellipsis } from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { DropdownMenuSimple } from 'components/DropdownMenu/DropdownMenuSimple';
import { GroupedStatusCounts } from 'container/InfraMonitoringK8sV2/components/GroupedStatusCounts';
import type { StatusCountItem } from 'container/InfraMonitoringK8sV2/components/GroupedStatusCounts';
import { ValidateColumnValueWrapper } from 'container/InfraMonitoringK8sV2/components/ValidateColumnValueWrapper';
@@ -104,7 +104,8 @@ const rowActions = (): JSX.Element => (
<Button
aria-label="Service actions"
color="secondary"
size="icon"
size="sm"
icon
variant="outlined"
>
<Ellipsis size={16} />

View File

@@ -1,6 +1,6 @@
import { Dispatch, SetStateAction, useCallback, useMemo } from 'react';
import { ChevronDown, Globe } from '@signozhq/icons';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { DropdownMenuSimple } from 'components/DropdownMenu/DropdownMenuSimple';
import { Button } from 'antd';
import { Typography } from '@signozhq/ui/typography';
import TimeItems, {

View File

@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Drawer } from 'antd';
import ROUTES from 'constants/routes';
import { Maximize2, Plus, X } from '@signozhq/icons';
@@ -53,22 +53,25 @@ export default function AIAssistantDrawer(): JSX.Element {
</div>
<div>
<TooltipSimple title="New conversation">
<Tooltip title="New conversation">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleNewConversation}
aria-label="New conversation"
>
<Plus size={16} />
</Button>
</TooltipSimple>
</Tooltip>
<TooltipSimple title="Open full screen">
<Tooltip title="Open full screen">
<Button
disabledTooltip={undefined}
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleExpand}
disabled={!activeConversationId}
@@ -76,19 +79,20 @@ export default function AIAssistantDrawer(): JSX.Element {
>
<Maximize2 size={16} />
</Button>
</TooltipSimple>
</Tooltip>
<TooltipSimple title="Close">
<Tooltip title="Close">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={closeDrawer}
aria-label="Close drawer"
>
<X size={16} />
</Button>
</TooltipSimple>
</Tooltip>
</div>
</div>
}

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { useHistory, useLocation } from 'react-router-dom';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import ROUTES from 'constants/routes';
import { History, Maximize2, Minus, Plus, X } from '@signozhq/icons';
import Noz from 'components/Noz/Noz';
@@ -159,62 +159,73 @@ export default function AIAssistantModal(): JSX.Element | null {
</div>
<div className={styles.actions}>
<TooltipSimple title={showHistory ? 'Back to chat' : 'Conversations'}>
<Tooltip title={showHistory ? 'Back to chat' : 'Conversations'}>
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={(): void => setShowHistory((v) => !v)}
aria-label="Toggle conversations"
className={showHistory ? styles.toggleBtnActive : ''}
prefix={<History size={14} />}
/>
</TooltipSimple>
>
<History size={14} />
</Button>
</Tooltip>
<TooltipSimple title="New conversation">
<Tooltip title="New conversation">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleNew}
aria-label="New conversation"
prefix={<Plus size={14} />}
/>
</TooltipSimple>
>
<Plus size={14} />
</Button>
</Tooltip>
<TooltipSimple title="Open full screen">
<Tooltip title="Open full screen">
<Button
disabledTooltip={undefined}
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleExpand}
disabled={!activeConversationId}
aria-label="Open full screen"
prefix={<Maximize2 size={14} />}
/>
</TooltipSimple>
>
<Maximize2 size={14} />
</Button>
</Tooltip>
<TooltipSimple title="Minimize to side panel">
<Tooltip title="Minimize to side panel">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleMinimize}
aria-label="Minimize to side panel"
prefix={<Minus size={14} />}
/>
</TooltipSimple>
>
<Minus size={14} />
</Button>
</Tooltip>
<TooltipSimple title="Close">
<Tooltip title="Close">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={closeModal}
aria-label="Close"
prefix={<X size={14} />}
/>
</TooltipSimple>
>
<X size={14} />
</Button>
</Tooltip>
</div>
</div>

View File

@@ -1,7 +1,7 @@
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
import { matchPath, useHistory, useLocation } from 'react-router-dom';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import ROUTES from 'constants/routes';
import { History, Maximize2, Plus, X } from '@signozhq/icons';
import Noz from 'components/Noz/Noz';
@@ -144,50 +144,59 @@ export default function AIAssistantPanel(): JSX.Element | null {
</div>
<div className={styles.actions}>
<TooltipSimple title={showHistory ? 'Back to chat' : 'Conversations'}>
<Tooltip title={showHistory ? 'Back to chat' : 'Conversations'}>
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={(): void => setShowHistory((v) => !v)}
aria-label="Toggle conversations"
prefix={<History size={14} />}
/>
</TooltipSimple>
>
<History size={14} />
</Button>
</Tooltip>
<TooltipSimple title="New conversation">
<Tooltip title="New conversation">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleNew}
aria-label="New conversation"
prefix={<Plus size={14} />}
/>
</TooltipSimple>
>
<Plus size={14} />
</Button>
</Tooltip>
<TooltipSimple title="Open full screen">
<Tooltip title="Open full screen">
<Button
disabledTooltip={undefined}
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={handleExpand}
disabled={!activeConversationId}
aria-label="Open full screen"
prefix={<Maximize2 size={14} />}
/>
</TooltipSimple>
>
<Maximize2 size={14} />
</Button>
</Tooltip>
<TooltipSimple title="Close">
<Tooltip title="Close">
<Button
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
onClick={closeDrawer}
aria-label="Close panel"
prefix={<X size={14} />}
/>
</TooltipSimple>
>
<X size={14} />
</Button>
</Tooltip>
</div>
</div>

View File

@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { matchPath, useLocation } from 'react-router-dom';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import logEvent from 'api/common/logEvent';
import ROUTES from 'constants/routes';
import Noz from 'components/Noz/Noz';
@@ -43,15 +43,18 @@ export default function AIAssistantTrigger(): JSX.Element | null {
}
return (
<TooltipSimple title={NOZ_TOOLTIP_TITLE}>
<Tooltip title={NOZ_TOOLTIP_TITLE}>
<Button
size="md"
variant="solid"
color="primary"
icon
className={`${styles.trigger} noz-wave`}
onClick={handleOpen}
aria-label="Open Noz"
prefix={<Noz size={24} />}
/>
</TooltipSimple>
>
<Noz size={24} />
</Button>
</Tooltip>
);
}

View File

@@ -12,7 +12,7 @@ import {
import cx from 'classnames';
import { v4 as uuidv4 } from 'uuid';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import type { MessageActionDTO } from 'api/ai-assistant/sigNozAIAssistantAPI.schemas';
import {
ApplyFilterSignalDTO,
@@ -631,6 +631,7 @@ export default function ActionsSection({
const chip = (
<Button
disabledTooltip={undefined}
variant="outlined"
color="secondary"
size="sm"
@@ -645,9 +646,9 @@ export default function ActionsSection({
);
return tooltip ? (
<TooltipSimple key={key} title={tooltip}>
<Tooltip key={key} title={tooltip}>
{chip}
</TooltipSimple>
</Tooltip>
) : (
<span key={key}>{chip}</span>
);

View File

@@ -10,8 +10,8 @@ import {
DialogSubtitle,
DialogTitle,
} from '@signozhq/ui/dialog';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { Tooltip } from '@signozhq/ui/tooltip';
import type {
ApprovalEventDTO,
ApprovalEventDTODiff,
@@ -101,16 +101,18 @@ export default function ApprovalCard({
<div className={styles.diffSection}>
<div className={styles.diffHeader}>
<span className={styles.diffHeaderLabel}>Diff</span>
<TooltipSimple title="Expand diff">
<Tooltip title="Expand diff">
<Button
variant="link"
size="sm"
color="secondary"
icon
onClick={(): void => setDiffExpanded(true)}
aria-label="Expand diff"
prefix={<Maximize2 size={12} />}
/>
</TooltipSimple>
>
<Maximize2 size={12} />
</Button>
</Tooltip>
</div>
<DiffView diff={approval.diff} />
</div>
@@ -132,7 +134,9 @@ export default function ApprovalCard({
<div className={styles.diffModalBody}>
<p className={styles.diffModalSummary}>{approval.summary}</p>
<div className={styles.diffToolbarRow}>
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
type="single"
size="sm"
value={viewMode}
@@ -156,7 +160,9 @@ export default function ApprovalCard({
},
]}
/>
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
type="multiple"
size="sm"
value={wrapText ? ['wrap'] : []}
@@ -185,6 +191,8 @@ export default function ApprovalCard({
<div className={styles.actions}>
<Button
disabledTooltip={undefined}
color="primary"
variant="solid"
size="sm"
onClick={handleApprove}
@@ -194,6 +202,7 @@ export default function ApprovalCard({
Approve
</Button>
<Button
disabledTooltip={undefined}
variant="outlined"
size="sm"
color="secondary"
@@ -465,7 +474,7 @@ function CopyButton({ text, label }: CopyButtonProps): JSX.Element {
};
return (
<TooltipSimple title={copied ? `Copied ${label}` : `Copy ${label}`}>
<Tooltip title={copied ? `Copied ${label}` : `Copy ${label}`}>
<Button
variant="ghost"
size="sm"
@@ -475,6 +484,6 @@ function CopyButton({ text, label }: CopyButtonProps): JSX.Element {
>
{copied ? <Check size={12} /> : <Copy size={12} />}
</Button>
</TooltipSimple>
</Tooltip>
);
}

View File

@@ -12,7 +12,7 @@ import { Button } from '@signozhq/ui/button';
import { Input } from '@signozhq/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@signozhq/ui/popover';
import { toast } from '@signozhq/ui/sonner';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import type { UploadFile } from 'antd';
import getSessionStorage from 'api/browser/sessionstorage/get';
import setSessionStorage from 'api/browser/sessionstorage/set';
@@ -900,8 +900,10 @@ export default function ChatInput({
<div key={f.uid} className={styles.attachmentChip}>
<span className={styles.attachmentName}>{f.name}</span>
<Button
color="secondary"
variant="ghost"
size="icon"
size="sm"
icon
className={styles.attachmentRemove}
onClick={(): void => removeFile(f.uid)}
aria-label={`Remove ${f.name}`}
@@ -925,7 +927,7 @@ export default function ChatInput({
<div className={styles.contextTagContent}>
<Badge
color="secondary"
variant="outline"
variant="outlined"
className={styles.contextTagCategory}
>
{category}
@@ -935,13 +937,15 @@ export default function ChatInput({
{onDismissAutoContext && (
<Button
variant="link"
size="icon"
size="sm"
icon
color="secondary"
className={styles.contextTagRemove}
onClick={(): void => onDismissAutoContext(key)}
aria-label={`Remove ${category}: ${label} context`}
prefix={<X size={10} />}
></Button>
>
<X size={10} />
</Button>
)}
</div>
);
@@ -954,7 +958,7 @@ export default function ChatInput({
<div className={styles.contextTagContent}>
<Badge
color="primary"
variant="outline"
variant="outlined"
className={styles.contextTagCategory}
>
{contextItem.category}
@@ -963,15 +967,17 @@ export default function ChatInput({
</div>
<Button
variant="link"
size="icon"
size="sm"
icon
color="secondary"
className={styles.contextTagRemove}
onClick={(): void =>
removeContext(contextItem.category, contextItem.entityId)
}
aria-label={`Remove ${contextItem.category}: ${contextItem.value} context`}
prefix={<X size={10} />}
></Button>
>
<X size={10} />
</Button>
</div>
))}
</div>
@@ -1020,6 +1026,7 @@ export default function ChatInput({
>
<PopoverTrigger asChild>
<Button
disabledTooltip={undefined}
variant="solid"
color="secondary"
size="sm"
@@ -1059,7 +1066,6 @@ export default function ChatInput({
variant="ghost"
color="secondary"
size="sm"
role="tab"
id={`ai-context-tab-${category}`}
// Single stable panel id shared by every tab: only the
// active category's tabpanel is rendered, so per-category
@@ -1178,18 +1184,20 @@ export default function ChatInput({
aria-live="polite"
aria-label="Recording voice input"
>
<TooltipSimple title="Discard recording">
<Tooltip title="Discard recording">
<Button
type="button"
variant="ghost"
size="icon"
size="sm"
icon
color="secondary"
className={cx(styles.micDiscard, styles.secondary)}
onClick={handleDiscard}
aria-label="Discard recording"
prefix={<X size={12} />}
/>
</TooltipSimple>
>
<X size={12} />
</Button>
</Tooltip>
<span className={styles.micWaves} aria-hidden="true">
<span />
<span />
@@ -1200,56 +1208,67 @@ export default function ChatInput({
<span />
<span />
</span>
<TooltipSimple title="Stop and send">
<Tooltip title="Stop and send">
<Button
type="button"
variant="ghost"
size="icon"
color="destructive"
variant="solid"
size="sm"
icon
color="danger"
className={cx(styles.micStop, styles.destructive)}
onClick={handleStopAndSend}
aria-label="Stop and send"
prefix={<Square size={9} fill="currentColor" strokeWidth={0} />}
/>
</TooltipSimple>
>
<Square size={9} fill="currentColor" strokeWidth={0} />
</Button>
</Tooltip>
</div>
) : (
<TooltipSimple title="Voice input">
<Tooltip title="Voice input">
<Button
disabledTooltip={undefined}
color="secondary"
variant="ghost"
size="icon"
size="sm"
icon
onClick={(): void => startVoiceInput(VoiceInputSource.Button)}
disabled={disabled}
aria-label="Start voice input"
className={styles.micBtn}
prefix={<Mic size={14} />}
/>
</TooltipSimple>
>
<Mic size={14} />
</Button>
</Tooltip>
))}
{isStreaming && onCancel ? (
<TooltipSimple title="Stop generating">
<Tooltip title="Stop generating">
<Button
variant="solid"
size="icon"
color="destructive"
size="sm"
icon
color="danger"
onClick={onCancel}
aria-label="Stop generating"
prefix={<Square size={10} fill="currentColor" strokeWidth={0} />}
/>
</TooltipSimple>
>
<Square size={10} fill="currentColor" strokeWidth={0} />
</Button>
</Tooltip>
) : (
<TooltipSimple title="Send message">
<Tooltip title="Send message">
<Button
disabledTooltip={undefined}
variant="solid"
size="icon"
size="sm"
icon
color="primary"
onClick={isListening ? handleStopAndSend : handleSend}
disabled={disabled || (!text.trim() && pendingFiles.length === 0)}
aria-label="Send message"
prefix={<Send size={14} />}
/>
</TooltipSimple>
>
<Send size={14} />
</Button>
</Tooltip>
)}
</div>
</div>

View File

@@ -58,7 +58,7 @@ export default function ContextPickerEmptyState({
color="primary"
className={styles.contextPopoverEmptyCta}
onClick={(): void => onPrefill(prefill)}
data-testid={`ai-context-empty-cta-${category}`}
testId={`ai-context-empty-cta-${category}`}
prefix={<Sparkles size={14} />}
>
<span className={styles.contextPopoverEmptyCtaLabel}>{ctaLabel}</span>

View File

@@ -140,6 +140,8 @@ export default function ClarificationForm({
<div className={styles.actions}>
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="primary"
onClick={handleSubmit}
@@ -149,6 +151,8 @@ export default function ClarificationForm({
Submit
</Button>
<Button
disabledTooltip={undefined}
size="md"
variant="outlined"
color="secondary"
onClick={handleCancel}
@@ -310,6 +314,7 @@ function FieldInput({ field, value, onChange }: FieldInputProps): JSX.Element {
return (
<div className={styles.field}>
<Checkbox
color="primary"
className={styles.checkboxLabel}
value={checked}
onChange={(): void => onChange(!checked)}
@@ -382,6 +387,7 @@ function FieldInput({ field, value, onChange }: FieldInputProps): JSX.Element {
<div className={styles.checkboxGroup}>
{options?.map((opt) => (
<Checkbox
color="primary"
key={opt}
className={styles.checkboxLabel}
value={regularSelected.includes(opt)}
@@ -392,6 +398,7 @@ function FieldInput({ field, value, onChange }: FieldInputProps): JSX.Element {
))}
{allowCustom && (
<Checkbox
color="primary"
className={styles.checkboxLabel}
value={isCustom}
onChange={toggleCustom}

View File

@@ -6,7 +6,7 @@ import { getAbsoluteUrl } from 'utils/basePath';
import { Button } from '@signozhq/ui/button';
import { Input } from '@signozhq/ui/input';
import { toast } from '@signozhq/ui/sonner';
import { DropdownMenuSimple } from '@signozhq/ui/dropdown-menu';
import { DropdownMenuSimple } from 'components/DropdownMenu/DropdownMenuSimple';
import {
Archive,
@@ -207,17 +207,18 @@ export default function ConversationItem({
<DropdownMenuSimple
menu={{ items: menuItems }}
align="end"
sideOffset={4}
className={styles.menu}
>
<Button
variant="link"
size="icon"
color="none"
size="sm"
icon
color="secondary"
className={styles.btn}
aria-label="Conversation actions"
prefix={<EllipsisVertical size={12} />}
/>
>
<EllipsisVertical size={12} />
</Button>
</DropdownMenuSimple>
</div>
)}

View File

@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
import cx from 'classnames';
import { Button } from '@signozhq/ui/button';
import { Input } from '@signozhq/ui/input';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Plus, Search } from '@signozhq/icons';
import logEvent from 'api/common/logEvent';
@@ -171,7 +171,7 @@ export default function ConversationsList({
{isLoadingThreads && <HeaderLoadingDots />}
{!isLoadingThreads && showAddNewConversation && (
<TooltipSimple title="New conversation">
<Tooltip title="New conversation">
<Button
variant="solid"
size="sm"
@@ -181,7 +181,7 @@ export default function ConversationsList({
>
<Plus size={12} />
</Button>
</TooltipSimple>
</Tooltip>
)}
</div>

View File

@@ -3,7 +3,7 @@ import cx from 'classnames';
import { useCopyToClipboard } from 'react-use';
import { Button } from '@signozhq/ui/button';
import { DialogWrapper } from '@signozhq/ui/dialog';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { Check, Copy, RefreshCw, ThumbsDown, ThumbsUp } from '@signozhq/icons';
import { useTimezone } from 'providers/Timezone';
@@ -174,10 +174,11 @@ export default function MessageFeedback({
<>
<div className={cx(styles.feedback, { [styles.visible]: isLastAssistant })}>
<div className={styles.actions}>
<TooltipSimple title={copied ? 'Copied!' : 'Copy'}>
<Tooltip title={copied ? 'Copied!' : 'Copy'}>
<Button
className={styles.btn}
size="icon"
size="sm"
icon
variant="ghost"
onClick={handleCopy}
color="secondary"
@@ -185,14 +186,15 @@ export default function MessageFeedback({
>
{copied ? <Check size={12} /> : <Copy size={12} />}
</Button>
</TooltipSimple>
</Tooltip>
<TooltipSimple title={VOTE_LABEL[FeedbackRatingDTO.positive].tooltip}>
<Tooltip title={VOTE_LABEL[FeedbackRatingDTO.positive].tooltip}>
<Button
className={cx(styles.btn, {
[styles.votedUp]: vote === FeedbackRatingDTO.positive,
})}
size="icon"
size="sm"
icon
variant="ghost"
color="secondary"
onClick={(): void => handleVote(FeedbackRatingDTO.positive)}
@@ -201,14 +203,15 @@ export default function MessageFeedback({
>
<ThumbsUp size={12} />
</Button>
</TooltipSimple>
</Tooltip>
<TooltipSimple title={VOTE_LABEL[FeedbackRatingDTO.negative].tooltip}>
<Tooltip title={VOTE_LABEL[FeedbackRatingDTO.negative].tooltip}>
<Button
className={cx(styles.btn, {
[styles.votedDown]: vote === FeedbackRatingDTO.negative,
})}
size="icon"
size="sm"
icon
variant="ghost"
color="secondary"
onClick={(): void => handleVote(FeedbackRatingDTO.negative)}
@@ -217,13 +220,14 @@ export default function MessageFeedback({
>
<ThumbsDown size={12} />
</Button>
</TooltipSimple>
</Tooltip>
{onRegenerate && (
<TooltipSimple title="Regenerate">
<Tooltip title="Regenerate">
<Button
className={styles.btn}
size="icon"
size="sm"
icon
variant="ghost"
color="secondary"
onClick={onRegenerate}
@@ -231,7 +235,7 @@ export default function MessageFeedback({
>
<RefreshCw size={12} />
</Button>
</TooltipSimple>
</Tooltip>
)}
</div>
@@ -249,13 +253,19 @@ export default function MessageFeedback({
footer={
<div className={styles.feedbackDialogFooter}>
<Button
size="md"
variant="solid"
color="secondary"
onClick={(): void => setIsNegativeDialogOpen(false)}
>
Cancel
</Button>
<Button variant="solid" color="primary" onClick={handleSubmitNegative}>
<Button
size="md"
variant="solid"
color="primary"
onClick={handleSubmitNegative}
>
Send feedback
</Button>
</div>

View File

@@ -1,7 +1,7 @@
import { useCallback, useState } from 'react';
import { useCopyToClipboard } from 'react-use';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Check, Copy } from '@signozhq/icons';
import logEvent from 'api/common/logEvent';
@@ -40,10 +40,11 @@ export default function UserMessageActions({
return (
<div className={styles.actions}>
<TooltipSimple title={copied ? 'Copied!' : 'Copy'}>
<Tooltip title={copied ? 'Copied!' : 'Copy'}>
<Button
className={styles.btn}
size="icon"
size="sm"
icon
variant="ghost"
color="secondary"
onClick={handleCopy}
@@ -51,7 +52,7 @@ export default function UserMessageActions({
>
{copied ? <Check size={12} /> : <Copy size={12} />}
</Button>
</TooltipSimple>
</Tooltip>
</div>
);
}

View File

@@ -189,11 +189,16 @@ export default function ActionBlock({
)}
<div className={styles.actions}>
<Button variant="solid" size="sm" onClick={execute}>
<Button color="primary" variant="solid" size="sm" onClick={execute}>
<Check size={12} />
Apply
</Button>
<Button variant="outlined" size="sm" onClick={handleDismiss}>
<Button
color="secondary"
variant="outlined"
size="sm"
onClick={handleDismiss}
>
<X size={12} />
Dismiss
</Button>

View File

@@ -83,11 +83,17 @@ export default function ConfirmBlock({
<div className={blockStyles.block}>
{message && <p className={styles.message}>{message}</p>}
<div className={styles.actions}>
<Button variant="solid" size="sm" onClick={(): void => handle('accepted')}>
<Button
color="primary"
variant="solid"
size="sm"
onClick={(): void => handle('accepted')}
>
<Check size={12} />
{acceptLabel}
</Button>
<Button
color="secondary"
variant="outlined"
size="sm"
onClick={(): void => handle('rejected')}

View File

@@ -3,7 +3,7 @@ import cx from 'classnames';
import { Button } from '@signozhq/ui/button';
import logEvent from 'api/common/logEvent';
import { Checkbox } from '@signozhq/ui/checkbox';
import { RadioGroup, RadioGroupItem } from '@signozhq/ui/radio-group';
import { RadioGroup } from '@signozhq/ui/radio-group';
import { AIAssistantEvents } from '../../../events';
import { useAIAssistantAnalyticsContext } from '../../../hooks/useAIAssistantAnalyticsContext';
@@ -83,27 +83,24 @@ export default function InteractiveQuestion({
{type === 'radio' ? (
<RadioGroup
color="primary"
textOverflow="wrap"
className={styles.options}
onChange={(value): void => {
setSelected([value]);
handleSubmit([value]);
}}
>
{normalized.map((opt) => (
<RadioGroupItem
key={opt.value}
value={opt.value}
className={styles.option}
>
{opt.label}
</RadioGroupItem>
))}
</RadioGroup>
items={normalized.map((opt) => ({
value: opt.value,
label: <span className={styles.option}>{opt.label}</span>,
}))}
/>
) : (
<>
<div className={cx(styles.options, styles.checkbox)}>
{normalized.map((opt) => (
<Checkbox
color="primary"
key={opt.value}
value={selected.includes(opt.value)}
onChange={(checked): void => {
@@ -120,6 +117,8 @@ export default function InteractiveQuestion({
))}
</div>
<Button
disabledTooltip={undefined}
color="primary"
variant="solid"
size="sm"
className={styles.submit}

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from 'react';
import { useCopyToClipboard } from 'react-use';
import { Button } from '@signozhq/ui/button';
import { TooltipSimple } from '@signozhq/ui/tooltip';
import { Tooltip } from '@signozhq/ui/tooltip';
import { Check, Copy } from '@signozhq/icons';
import SyntaxHighlighter, {
a11yDark,
@@ -127,7 +127,7 @@ function CopyButton({ text }: { text: string }): JSX.Element {
};
return (
<TooltipSimple title={copied ? 'Copied' : 'Copy code'}>
<Tooltip title={copied ? 'Copied' : 'Copy code'}>
<Button
variant="ghost"
size="sm"
@@ -138,6 +138,6 @@ function CopyButton({ text }: { text: string }): JSX.Element {
>
{copied ? <Check size={12} /> : <Copy size={12} />}
</Button>
</TooltipSimple>
</Tooltip>
);
}

View File

@@ -320,6 +320,7 @@ function AnomalyAlertEvaluationView({
<div className="anomaly-alert-evaluation-view-series-list-items">
{filteredSeriesKeys.length > 0 && (
<Checkbox
color="primary"
className="anomaly-alert-evaluation-view-series-list-item"
name="series"
value={selectedSeries === null}
@@ -332,6 +333,7 @@ function AnomalyAlertEvaluationView({
{filteredSeriesKeys.map((seriesKey) => (
<div key={seriesKey}>
<Checkbox
color="primary"
className="anomaly-alert-evaluation-view-series-list-item"
key={seriesKey}
name="series"

View File

@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { Spacing } from '@signozhq/design-tokens';
import { Button, Drawer } from 'antd';
import { ToggleGroupSimple } from '@signozhq/ui/toggle-group';
import { ToggleGroup } from '@signozhq/ui/toggle-group';
import { Divider } from '@signozhq/ui/divider';
import { Typography } from '@signozhq/ui/typography';
import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
@@ -225,11 +225,13 @@ function DomainDetails({
timeRange={modalTimeRange}
/>
<div className="views-tabs-container">
<ToggleGroupSimple
<ToggleGroup
variant="outlined"
color="secondary"
type="single"
onChange={handleTabChange}
value={selectedView}
size="lg"
size="md"
items={[
{ value: VIEW_TYPES.ALL_ENDPOINTS, label: 'All Endpoints' },
{ value: VIEW_TYPES.ENDPOINT_STATS, label: 'Endpoint(s) Stats' },

View File

@@ -171,7 +171,12 @@ function TopErrors({
/>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<Switch value={showStatusCodeErrors} onChange={setShowStatusCodeErrors} />
<Switch
color="primary"
textPlacement="right"
value={showStatusCodeErrors}
onChange={setShowStatusCodeErrors}
/>
<span style={{ color: 'white', fontSize: '14px' }}>
Status Message Exists
</span>

View File

@@ -973,7 +973,12 @@ export const getEndPointsColumnsConfig = (
})()}
{isGroupedByAttribute
? text.split(',').map((value) => (
<Badge key={value} color="vanilla" className="endpoint-group-tag-item">
<Badge
variant="solid"
key={value}
color="secondary"
className="endpoint-group-tag-item"
>
{value === '' ? '<no-value>' : value}
</Badge>
))

View File

@@ -436,7 +436,14 @@ export default function BillingContainer(): JSX.Element {
<Flex vertical gap={8}>
<p className={styles.pageInfoTitle}>
{isCloudUserVal ? t('teams_cloud') : t('teams')}{' '}
{isFreeTrial ? <Badge color="success"> Free Trial </Badge> : ''}
{isFreeTrial ? (
<Badge variant="solid" color="success">
{' '}
Free Trial{' '}
</Badge>
) : (
''
)}
</p>
{billingData && !isFetchingBillingData && !showGracePeriodMessage ? (

View File

@@ -141,6 +141,7 @@ function CancelSubscriptionBanner(): JSX.Element {
const confirmFooter = (
<>
<Button
size="md"
variant="solid"
color="secondary"
prefix={<Undo2 size={14} />}
@@ -149,12 +150,14 @@ function CancelSubscriptionBanner(): JSX.Element {
Go back
</Button>
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="destructive"
color="danger"
prefix={<X size={14} />}
disabled={confirmText !== 'cancel'}
onClick={handleContactSupport}
data-testid="cancel-subscription-confirm-btn"
testId="cancel-subscription-confirm-btn"
>
Cancel subscription
</Button>
@@ -162,7 +165,7 @@ function CancelSubscriptionBanner(): JSX.Element {
);
const fallbackFooter = (
<Button variant="solid" color="secondary" onClick={handleClose}>
<Button size="md" variant="solid" color="secondary" onClick={handleClose}>
Close
</Button>
);
@@ -181,6 +184,7 @@ function CancelSubscriptionBanner(): JSX.Element {
</span>
</div>
<AuthZButton
size="md"
checks={[SubscriptionDeletePermission]}
variant="solid"
color="secondary"
@@ -226,30 +230,32 @@ function CancelSubscriptionBanner(): JSX.Element {
<span className={styles.fallbackEmail}>{SUPPORT_EMAIL}</span>
<div className={styles.fallbackActions}>
<Button
size="md"
variant="outlined"
color="secondary"
prefix={copied ? <CircleCheck size={14} /> : <Copy size={14} />}
onClick={handleCopyTemplate}
data-testid="copy-email-template-btn"
testId="copy-email-template-btn"
>
{copied ? 'Copied!' : 'Copy email template'}
</Button>
<Button
asChild
size="md"
variant="outlined"
color="secondary"
data-testid="retry-mailto-btn"
testId="retry-mailto-btn"
prefix={<MailOpen size={14} />}
onClick={(): void => {
handleRetryMailto();
// oxlint-disable-next-line signoz/no-raw-absolute-path -- mailto is an external mail client URL, not an in-app path
window.open(
buildMailtoUri(orgName, userEmail),
'_blank',
'noopener,noreferrer',
);
}}
>
<a
href={buildMailtoUri(orgName, userEmail)}
onClick={handleRetryMailto}
className={styles.retryLink}
target="_blank"
rel="noopener noreferrer"
>
<MailOpen size={14} />
Reopen email client
</a>
Reopen email client
</Button>
</div>
</div>

View File

@@ -37,6 +37,8 @@ function Controls({
return (
<div className={styles.container}>
<Button
disabledTooltip={undefined}
color="primary"
variant="link"
size="md"
disabled={isPreviousDisabled}
@@ -46,6 +48,8 @@ function Controls({
Previous
</Button>
<Button
disabledTooltip={undefined}
color="primary"
variant="link"
size="md"
disabled={isNextDisabled}

View File

@@ -66,7 +66,13 @@ function SelectAlertType({ onSelect }: SelectAlertTypeProps): JSX.Element {
<AlertTypeCard
key={option.selection}
title={option.title}
extra={option.isBeta ? <Badge color="robin">Beta</Badge> : undefined}
extra={
option.isBeta ? (
<Badge variant="solid" color="primary">
Beta
</Badge>
) : undefined
}
onClick={(e): void => {
onSelect(option.selection, isModifierKeyPressed(e));
}}

View File

@@ -445,6 +445,8 @@ export function RoutingPolicyBanner({
</Typography.Text>
<div className="routing-policies-info-banner-right">
<Switch
color="primary"
textPlacement="right"
value={notificationSettings.routingPolicies}
testId="routing-policies-switch"
onChange={(value): void => {

View File

@@ -50,7 +50,12 @@ function AdvancedOptionItem({
>
{input}
</div>
<Switch onChange={handleOnToggle} value={showInput} />
<Switch
color="primary"
textPlacement="right"
onChange={handleOnToggle}
value={showInput}
/>
</div>
</div>
);

View File

@@ -182,6 +182,8 @@ function Footer(): JSX.Element {
const saveAlertButton = useMemo(() => {
let button = (
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="primary"
onClick={handleSaveAlert}
@@ -215,6 +217,8 @@ function Footer(): JSX.Element {
const testAlertButton = useMemo(() => {
let button = (
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="secondary"
onClick={handleTestNotification}
@@ -247,6 +251,8 @@ function Footer(): JSX.Element {
return (
<div className="create-alert-v2-footer">
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="secondary"
onClick={handleDiscard}

View File

@@ -192,6 +192,7 @@ export default function CustomDomainEditModal({
/>
) : (
<Button
disabledTooltip={undefined}
variant="solid"
size="md"
color="primary"

View File

@@ -11,11 +11,7 @@ import {
} from '@signozhq/icons';
import { Button } from '@signozhq/ui/button';
import { Callout } from '@signozhq/ui/callout';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@signozhq/ui/dropdown-menu';
import { Dropdown, type DropdownItemType } from '@signozhq/ui/dropdown';
import { toast } from '@signozhq/ui/sonner';
import { Skeleton } from 'antd';
import {
@@ -48,6 +44,7 @@ function DomainUpdateToast({
</span>
<div className="custom-domain-toast-actions">
<Button
color="secondary"
variant="ghost"
size="sm"
className="custom-domain-toast-visit-btn"
@@ -60,15 +57,18 @@ function DomainUpdateToast({
Visit new URL
</Button>
<Button
color="secondary"
variant="ghost"
size="icon"
size="sm"
icon
className="custom-domain-toast-dismiss-btn"
onClick={(): void => {
toast.dismiss(toastId);
}}
aria-label="Dismiss"
prefix={<X size={14} />}
/>
>
<X size={14} />
</Button>
</div>
</div>
);
@@ -181,6 +181,33 @@ export default function CustomDomainSettings(): JSX.Element {
const workspaceName =
org?.[0]?.displayName || customDomainSubdomain || activeHost?.name;
const workspaceUrlItems: DropdownItemType[] = [
{
type: 'group',
value: 'all-workspace-urls',
label: 'All Workspace URLs',
items: sortedHosts.map((host) => ({
type: 'link',
value: host.name,
label: stripProtocol(host.url),
suffix:
host.name === activeHost?.name ? (
<Check size={14} />
) : (
<ExternalLink size={12} />
),
render: (
<a
href={host.url}
target="_blank"
rel="noopener noreferrer"
aria-label={stripProtocol(host.url)}
/>
),
})),
},
];
if (isLoadingHosts) {
return (
<div className="custom-domain-card custom-domain-card--loading">
@@ -205,54 +232,25 @@ export default function CustomDomainSettings(): JSX.Element {
!workspaceName ? 'workspace-name-hidden' : ''
}`}
>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="link"
color="none"
data-testid="custom-domain-menu-trigger"
disabled={isFetchingHosts}
>
<Link2 size={12} />
<span>{stripProtocol(activeHost?.url ?? '')}</span>
<ChevronDown size={12} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<div className="workspace-url-dropdown">
<span className="workspace-url-dropdown-header">
All Workspace URLs
</span>
<div className="workspace-url-dropdown-divider" />
{sortedHosts.map((host) => {
const isActive = host.name === activeHost?.name;
return (
<a
key={host.name}
href={host.url}
target="_blank"
rel="noopener noreferrer"
className={`workspace-url-dropdown-item${
isActive ? ' workspace-url-dropdown-item--active' : ''
}`}
>
<span className="workspace-url-dropdown-item-label">
{stripProtocol(host.url ?? '')}
</span>
{isActive ? (
<Check size={14} className="workspace-url-dropdown-item-check" />
) : (
<ExternalLink
size={12}
className="workspace-url-dropdown-item-external"
/>
)}
</a>
);
})}
</div>
</DropdownMenuContent>
</DropdownMenu>
<Dropdown
items={workspaceUrlItems}
nativeButton
align="start"
side="bottom"
>
<Button
disabledTooltip={undefined}
size="md"
variant="link"
color="secondary"
testId="custom-domain-menu-trigger"
disabled={isFetchingHosts}
>
<Link2 size={12} />
<span>{stripProtocol(activeHost?.url ?? '')}</span>
<ChevronDown size={12} />
</Button>
</Dropdown>
<span className="custom-domain-card-meta-timezone">
<Clock size={11} />
{timezone.offset}
@@ -261,6 +259,8 @@ export default function CustomDomainSettings(): JSX.Element {
</div>
<Button
disabledTooltip={undefined}
size="md"
variant="solid"
color="secondary"
prefix={<FilePenLine size={12} />}

View File

@@ -1,6 +1,9 @@
import { useState } from 'react';
import { CloudDownload } from '@signozhq/icons';
import { DropdownMenuSimple, type MenuProps } from '@signozhq/ui/dropdown-menu';
import {
DropdownMenuSimple,
type MenuProps,
} from 'components/DropdownMenu/DropdownMenuSimple';
import { Button, Flex } from 'antd';
import { unparse } from 'papaparse';

Some files were not shown because too many files have changed in this diff Show More