mirror of
https://github.com/SigNoz/signoz.git
synced 2026-05-18 16:00:32 +01:00
Compare commits
301 Commits
main
...
feat/add-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80a78a5426 | ||
|
|
e7911999d7 | ||
|
|
9efe2aacab | ||
|
|
f85da6d8d4 | ||
|
|
0e9d7bf537 | ||
|
|
9c50930f00 | ||
|
|
3eab3e1556 | ||
|
|
b1a81c09ce | ||
|
|
227b098067 | ||
|
|
3882c06054 | ||
|
|
c8548ea27d | ||
|
|
ede67c877a | ||
|
|
074d3b8c85 | ||
|
|
07b0f8e6cb | ||
|
|
24660642cb | ||
|
|
f379a01095 | ||
|
|
d5a07d10bb | ||
|
|
537d183d34 | ||
|
|
10ad886981 | ||
|
|
6cf8ccbfb8 | ||
|
|
0162d3c7e2 | ||
|
|
7124896d37 | ||
|
|
9edd1e88bd | ||
|
|
c2ba08fd31 | ||
|
|
2d26411705 | ||
|
|
181c81ec71 | ||
|
|
192cbb15f8 | ||
|
|
c0b6ef28cd | ||
|
|
ad6813fbe7 | ||
|
|
8be39cb4c5 | ||
|
|
c1905361d2 | ||
|
|
d27d8443fc | ||
|
|
90d09a7a37 | ||
|
|
6a784088f2 | ||
|
|
08b08b85ca | ||
|
|
d1298b7b91 | ||
|
|
2ae7ff394c | ||
|
|
9b79d86436 | ||
|
|
8d4df49bb4 | ||
|
|
4ba3c32ca4 | ||
|
|
593997caa2 | ||
|
|
0ce20e963c | ||
|
|
5c58e8c2a4 | ||
|
|
7336557e79 | ||
|
|
ec392e6e4a | ||
|
|
b5e3ac7179 | ||
|
|
77a4eaeebb | ||
|
|
8f3ed3b725 | ||
|
|
43ccc88440 | ||
|
|
f9b23dbe29 | ||
|
|
1e07156cd0 | ||
|
|
74e5e4d2ac | ||
|
|
0a35a09f1e | ||
|
|
b88e9e52be | ||
|
|
cf58d49de4 | ||
|
|
8e95128414 | ||
|
|
aaff6d8bdd | ||
|
|
4b22ac05b2 | ||
|
|
8e0ecb2666 | ||
|
|
83ed560236 | ||
|
|
e46510fa02 | ||
|
|
07f0bf3e8b | ||
|
|
3b6fd6a5e8 | ||
|
|
c312a54e63 | ||
|
|
35ecfc5e37 | ||
|
|
7b9caf14b8 | ||
|
|
e3db42b7ce | ||
|
|
401f253090 | ||
|
|
2d930c0e4b | ||
|
|
ce8d1837ef | ||
|
|
c38bfa1027 | ||
|
|
473b91f41f | ||
|
|
4f32c23f63 | ||
|
|
8708fa0627 | ||
|
|
cabd7b6641 | ||
|
|
bc91476bce | ||
|
|
b5789e1e36 | ||
|
|
52f2b40e18 | ||
|
|
9fe4ca02da | ||
|
|
41fd155fd3 | ||
|
|
88575f3ea1 | ||
|
|
48f1a4cbf3 | ||
|
|
bb499973bf | ||
|
|
13c087d34d | ||
|
|
f5e772f8a0 | ||
|
|
feb9031bcd | ||
|
|
bc4a6b7ded | ||
|
|
9d83c9b43d | ||
|
|
0144bb78df | ||
|
|
9216bb5f34 | ||
|
|
18d2806f95 | ||
|
|
8d666471e1 | ||
|
|
9d022772b7 | ||
|
|
648a48cbaa | ||
|
|
6e35cee1e7 | ||
|
|
1298074cb2 | ||
|
|
16c8db5fd9 | ||
|
|
6855be7859 | ||
|
|
2c398396dd | ||
|
|
a58539e25c | ||
|
|
eeb7fa3aa5 | ||
|
|
d11234531d | ||
|
|
eb22c57a67 | ||
|
|
896379b680 | ||
|
|
f041b16e4b | ||
|
|
0bd591458d | ||
|
|
9ca3a7fd3e | ||
|
|
43e122367c | ||
|
|
33520c41c8 | ||
|
|
b994d6dd8e | ||
|
|
5e231e799e | ||
|
|
5f4a79c201 | ||
|
|
8edf375019 | ||
|
|
0d1fd6d0bd | ||
|
|
fefd0effef | ||
|
|
36a137be4d | ||
|
|
68dc7e426a | ||
|
|
603077c575 | ||
|
|
7e5c4476f7 | ||
|
|
da648ed3f3 | ||
|
|
9fa56aacd1 | ||
|
|
5acd79419c | ||
|
|
9b7b0f8862 | ||
|
|
c29e8a0136 | ||
|
|
ebac945ac2 | ||
|
|
e787497695 | ||
|
|
eba6bd5f5b | ||
|
|
1aeab2718d | ||
|
|
d879af4fb3 | ||
|
|
ac10be2eb2 | ||
|
|
113d1544ba | ||
|
|
df02da664c | ||
|
|
d0a491ed8e | ||
|
|
77c39a9f05 | ||
|
|
309a76e5fd | ||
|
|
43e80caf09 | ||
|
|
a2d853daf5 | ||
|
|
3970619afa | ||
|
|
9dc87761c1 | ||
|
|
86a44fad42 | ||
|
|
91f74144cb | ||
|
|
0863c5170b | ||
|
|
837cd2a463 | ||
|
|
c88a2d5d90 | ||
|
|
c9abc2cb30 | ||
|
|
01824b0b62 | ||
|
|
d1b378992d | ||
|
|
52ca921d2a | ||
|
|
42f12dfef3 | ||
|
|
f2a694447e | ||
|
|
2e7dfa739f | ||
|
|
0aa73580a3 | ||
|
|
2ff1a43bf8 | ||
|
|
c1477c78be | ||
|
|
9807dd5295 | ||
|
|
2c59eeff26 | ||
|
|
8ccfb4efef | ||
|
|
87d18160e8 | ||
|
|
bfa7ee96da | ||
|
|
5e3eb66d3a | ||
|
|
3d8cdf18bd | ||
|
|
cb4e501047 | ||
|
|
cb8b2137ba | ||
|
|
998315a255 | ||
|
|
250657e46b | ||
|
|
795ae9ab18 | ||
|
|
6a9ea8d9f8 | ||
|
|
2723e18023 | ||
|
|
6e89d5f6eb | ||
|
|
4c2a815236 | ||
|
|
b1d66b2e5f | ||
|
|
ae88edbb5e | ||
|
|
7c9484d47b | ||
|
|
24128bd394 | ||
|
|
2118916a23 | ||
|
|
52220412a1 | ||
|
|
85abee8476 | ||
|
|
650a29d184 | ||
|
|
d9c7101d22 | ||
|
|
b1e7c25189 | ||
|
|
e9904a0558 | ||
|
|
5cd199f535 | ||
|
|
f6f48ca0bc | ||
|
|
847f91e22e | ||
|
|
29d0abe5a8 | ||
|
|
c08840a827 | ||
|
|
a3e7bb90b0 | ||
|
|
8515d2f37c | ||
|
|
07c05ac3a6 | ||
|
|
6289f59ba3 | ||
|
|
76371c9fa2 | ||
|
|
f082e396eb | ||
|
|
840eb8f228 | ||
|
|
2911baf6bb | ||
|
|
fc5be4eeb5 | ||
|
|
a1b92c79a4 | ||
|
|
7a0acd5c8b | ||
|
|
069cbe2c6f | ||
|
|
4c821f9721 | ||
|
|
4eccea92db | ||
|
|
c8d8966a5d | ||
|
|
1e52a5603e | ||
|
|
780ba1a359 | ||
|
|
3b71abe820 | ||
|
|
70b9d0ff02 | ||
|
|
f4657861e1 | ||
|
|
66fe5b5240 | ||
|
|
c333cecf43 | ||
|
|
276e09853e | ||
|
|
4defd41504 | ||
|
|
ab53b29a14 | ||
|
|
b58e82efbf | ||
|
|
0a1a676877 | ||
|
|
bb2aa9f77c | ||
|
|
04bef4ac06 | ||
|
|
3bcb2c2c41 | ||
|
|
9e77b76122 | ||
|
|
ff4a41d842 | ||
|
|
387deb779d | ||
|
|
1ec2663d51 | ||
|
|
1b17370da0 | ||
|
|
c6484a79e2 | ||
|
|
16a2c7a1af | ||
|
|
3c4ac0e85e | ||
|
|
87ba729a00 | ||
|
|
f1ed7145e4 | ||
|
|
bc15495e17 | ||
|
|
f7d3012daf | ||
|
|
6ec9a2ec41 | ||
|
|
9c056f809a | ||
|
|
c1d4273416 | ||
|
|
618fe891d5 | ||
|
|
549c7e7034 | ||
|
|
dd65f83c3d | ||
|
|
8463a131fc | ||
|
|
2d42518440 | ||
|
|
43d75a3853 | ||
|
|
c5bb34e385 | ||
|
|
6fd129991d | ||
|
|
9c5cca426a | ||
|
|
a467efb97d | ||
|
|
58e2718090 | ||
|
|
65fee725c9 | ||
|
|
ea87174088 | ||
|
|
627c483d86 | ||
|
|
2533137db4 | ||
|
|
a774f8a4fe | ||
|
|
8487f6cf66 | ||
|
|
6ebe51126e | ||
|
|
ed64d5cd9f | ||
|
|
c04076e664 | ||
|
|
3c129e2c7d | ||
|
|
0ba51e2058 | ||
|
|
cdc2ab134c | ||
|
|
fb0c05b553 | ||
|
|
68e9707e3b | ||
|
|
17ffaf9ccf | ||
|
|
efec669b76 | ||
|
|
17b9e14d34 | ||
|
|
2db9f969c3 | ||
|
|
9fa466b124 | ||
|
|
0c7768ebff | ||
|
|
58dd51e92f | ||
|
|
870c9bf6dc | ||
|
|
7604956bf0 | ||
|
|
66510e4919 | ||
|
|
a1bf0e67db | ||
|
|
a06046612a | ||
|
|
31c9d4309b | ||
|
|
7bef8b86c4 | ||
|
|
d26acd36a3 | ||
|
|
1cee595135 | ||
|
|
dd1868fcbc | ||
|
|
a20beb8ba2 | ||
|
|
998d652feb | ||
|
|
3695d3c180 | ||
|
|
da175bafbc | ||
|
|
021b187cbc | ||
|
|
f42b468597 | ||
|
|
7e2cf57819 | ||
|
|
dc9ebc5b26 | ||
|
|
398ab6e9d9 | ||
|
|
fec60671d8 | ||
|
|
99259cc4e8 | ||
|
|
ca311717c2 | ||
|
|
a614da2c65 | ||
|
|
ce18709002 | ||
|
|
2b6977e891 | ||
|
|
3e6eedbcab | ||
|
|
fd9e3f0411 | ||
|
|
e99465e030 | ||
|
|
9ad2db4b99 | ||
|
|
07fd5f70ef | ||
|
|
ba79121795 | ||
|
|
6e4e419b5e | ||
|
|
2f06afaf27 | ||
|
|
f77c3cb23c | ||
|
|
9e3a8efcfc | ||
|
|
8e325ba8b3 | ||
|
|
884f516766 | ||
|
|
4bcbb4ffc3 |
@@ -101,21 +101,45 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.preNextToggle {
|
||||
display: flex;
|
||||
// Fixed-width slot for the result-nav cluster. Always present (even when no
|
||||
// expression is active) so the filter input width stays stable — no lateral
|
||||
// layout shift when the count/arrows/clear pop in.
|
||||
.resultNavSlot {
|
||||
width: 220px;
|
||||
flex-shrink: 0;
|
||||
gap: 12px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.preNextCount {
|
||||
// Result-nav cluster: count + ↑↓ + clear (X), sits between the filter input
|
||||
// and the right-side status/highlight controls. Visible whenever there's an
|
||||
// active expression; count + ↑↓ collapse out when no results, clear stays.
|
||||
.resultNav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: auto;
|
||||
flex-shrink: 0;
|
||||
gap: 2px;
|
||||
color: var(--l2-foreground);
|
||||
font-family: 'Geist Mono';
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.resultNavCount {
|
||||
padding: 0 6px;
|
||||
white-space: nowrap;
|
||||
color: var(--l1-foreground);
|
||||
font-family: 'Geist Mono';
|
||||
font-size: 12px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.resultNavDivider {
|
||||
width: 1px;
|
||||
height: 14px;
|
||||
background: var(--l3-border);
|
||||
margin: 0 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.filterStatus {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { useCopyToClipboard } from 'react-use';
|
||||
import {
|
||||
ChevronDown,
|
||||
ChevronsRight,
|
||||
ChevronUp,
|
||||
Copy,
|
||||
Info,
|
||||
@@ -106,6 +107,12 @@ function Filters({
|
||||
const [currentSearchedIndex, setCurrentSearchedIndex] = useState<number>(0);
|
||||
const expressionRef = useRef<string>('');
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
// Ref to the Clear (×) button so we can suppress the search-container
|
||||
// onBlur → runQuery path when focus moves to it. Otherwise the editor
|
||||
// loses focus before our click handler runs, runQuery commits the (still
|
||||
// bad) expression, and React Query re-fires the failing request on the
|
||||
// way to being cleared.
|
||||
const clearBtnRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const runQuery = useCallback(
|
||||
(value: string): void => {
|
||||
@@ -152,6 +159,18 @@ function Filters({
|
||||
runQuery(expressionRef.current);
|
||||
}, [runQuery]);
|
||||
|
||||
// Clear filter — reset expression + filters + results in one shot.
|
||||
// Wired to the X button in the result-nav cluster.
|
||||
const handleClear = useCallback((): void => {
|
||||
setExpression('');
|
||||
expressionRef.current = '';
|
||||
setFilters({ items: [], op: 'AND' });
|
||||
setFilteredSpanIds([]);
|
||||
onFilteredSpansChange?.([], false);
|
||||
setCurrentSearchedIndex(0);
|
||||
setNoData(false);
|
||||
}, [onFilteredSpansChange]);
|
||||
|
||||
// Expression-based filter hooks
|
||||
const filterProps = {
|
||||
expression,
|
||||
@@ -266,10 +285,71 @@ function Filters({
|
||||
</div>
|
||||
);
|
||||
|
||||
const statusIndicators = (
|
||||
<>
|
||||
{isFetching && <Loader className="animate-spin" />}
|
||||
{error && (
|
||||
const hasExpression = expression.trim().length > 0;
|
||||
const hasResults = filteredSpanIds.length > 0;
|
||||
|
||||
// Result-nav cluster: count + ↑↓ + clear (X), all OUTSIDE the input.
|
||||
// - The cluster appears whenever there's an active expression.
|
||||
// - Count + ↑↓ are hidden when there are no results to navigate (no-data or
|
||||
// API error); clear (X) stays so the user can always reset.
|
||||
const resultNav = hasExpression ? (
|
||||
<div className={styles.resultNav}>
|
||||
{hasResults && (
|
||||
<>
|
||||
<Typography.Text className={styles.resultNavCount}>
|
||||
{currentSearchedIndex + 1} / {filteredSpanIds.length}
|
||||
</Typography.Text>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
disabled={currentSearchedIndex === 0}
|
||||
onClick={(): void => {
|
||||
handlePrevNext(currentSearchedIndex - 1);
|
||||
setCurrentSearchedIndex((prev) => prev - 1);
|
||||
}}
|
||||
>
|
||||
<ChevronUp size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
disabled={currentSearchedIndex === filteredSpanIds.length - 1}
|
||||
onClick={(): void => {
|
||||
handlePrevNext(currentSearchedIndex + 1);
|
||||
setCurrentSearchedIndex((prev) => prev + 1);
|
||||
}}
|
||||
>
|
||||
<ChevronDown size={14} />
|
||||
</Button>
|
||||
<span className={styles.resultNavDivider} />
|
||||
</>
|
||||
)}
|
||||
<TooltipRoot>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
ref={clearBtnRef}
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
onClick={handleClear}
|
||||
>
|
||||
<X size={14} />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Clear filter</TooltipContent>
|
||||
</TooltipRoot>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
// Status indicator (right side): "No results found" (muted) or "API error"
|
||||
// (red ring + tooltip). Shown only when there's an active expression and
|
||||
// either no matches came back or the API itself failed.
|
||||
let statusIndicator: JSX.Element | null = null;
|
||||
if (hasExpression && !isFetching) {
|
||||
if (error) {
|
||||
statusIndicator = (
|
||||
<TooltipRoot>
|
||||
<TooltipTrigger asChild>
|
||||
<span className={cx(styles.filterStatus, styles.hasError)}>
|
||||
@@ -281,14 +361,19 @@ function Filters({
|
||||
{(error as AxiosError)?.message || 'Something went wrong'}
|
||||
</TooltipContent>
|
||||
</TooltipRoot>
|
||||
)}
|
||||
{!error && noData && (
|
||||
);
|
||||
} else if (noData) {
|
||||
statusIndicator = (
|
||||
<Typography.Text className={styles.filterStatus}>
|
||||
No results found
|
||||
</Typography.Text>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const fetchingIndicator = isFetching ? (
|
||||
<Loader className="animate-spin" />
|
||||
) : null;
|
||||
|
||||
// --- COLLAPSED VIEW ---
|
||||
if (!isExpanded) {
|
||||
@@ -334,7 +419,8 @@ function Filters({
|
||||
pill
|
||||
)}
|
||||
{highlightErrorsToggle}
|
||||
{statusIndicators}
|
||||
{statusIndicator}
|
||||
{fetchingIndicator}
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
);
|
||||
@@ -365,7 +451,10 @@ function Filters({
|
||||
className={styles.searchContainer}
|
||||
ref={containerRef}
|
||||
onBlur={(e): void => {
|
||||
if (!containerRef.current?.contains(e.relatedTarget as Node)) {
|
||||
const relatedTarget = e.relatedTarget as Node | null;
|
||||
const blurredIntoSelf = !!containerRef.current?.contains(relatedTarget);
|
||||
const blurredIntoClear = !!clearBtnRef.current?.contains(relatedTarget);
|
||||
if (!blurredIntoSelf && !blurredIntoClear) {
|
||||
handleBlur();
|
||||
}
|
||||
}}
|
||||
@@ -382,48 +471,24 @@ function Filters({
|
||||
placeholder="Enter your filter query (e.g., http.status_code >= 500 AND service.name = 'frontend')"
|
||||
/>
|
||||
</div>
|
||||
{filteredSpanIds.length > 0 && (
|
||||
<div className={styles.preNextToggle}>
|
||||
<Typography.Text className={styles.preNextCount}>
|
||||
{currentSearchedIndex + 1} / {filteredSpanIds.length}
|
||||
</Typography.Text>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
disabled={currentSearchedIndex === 0}
|
||||
onClick={(): void => {
|
||||
handlePrevNext(currentSearchedIndex - 1);
|
||||
setCurrentSearchedIndex((prev) => prev - 1);
|
||||
}}
|
||||
>
|
||||
<ChevronUp size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
disabled={currentSearchedIndex === filteredSpanIds.length - 1}
|
||||
onClick={(): void => {
|
||||
handlePrevNext(currentSearchedIndex + 1);
|
||||
setCurrentSearchedIndex((prev) => prev + 1);
|
||||
}}
|
||||
>
|
||||
<ChevronDown size={14} />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
className={styles.collapseBtn}
|
||||
onClick={onCollapse}
|
||||
>
|
||||
<X size={14} />
|
||||
</Button>
|
||||
<div className={styles.resultNavSlot}>{resultNav}</div>
|
||||
{highlightErrorsToggle}
|
||||
{statusIndicators}
|
||||
{statusIndicator}
|
||||
{fetchingIndicator}
|
||||
<TooltipRoot>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
className={styles.collapseBtn}
|
||||
onClick={onCollapse}
|
||||
>
|
||||
<ChevronsRight size={14} />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Collapse filters</TooltipContent>
|
||||
</TooltipRoot>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user