Compare commits

..

35 Commits

Author SHA1 Message Date
Srikanth Chekuri
585caa84fe Merge branch 'main' into issue-10008 2026-01-23 20:11:48 +05:30
Tushar Vats
605d6ba17d feat: extract context and data type from telemetry field name (#9986)
This pull request introduces significant improvements to the handling and normalization of telemetry field keys, adds comprehensive tests for these changes, and refactors JSON unmarshaling for query builder types to ensure consistent normalization and error handling
2026-01-23 13:19:03 +00:00
srikanthccv
814fd40a1d chore: update tests 2026-01-23 05:43:26 +05:30
srikanthccv
0978bdfa7f chore: fix warn 2026-01-23 04:33:07 +05:30
srikanthccv
4f99261743 chore: resolve conflicts 2026-01-23 04:25:39 +05:30
Amlan Kumar Nandy
f017b07525 chore: make new alerting experience as default with the ability to switch to classic (#10040)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-01-22 22:15:21 +00:00
Tushar Vats
b5901ac174 feat: handle attribute collision (#10086)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
This pull request improves the handling of field key resolution in query building. The main focus is to make the field key matching logic in the VisitKey function more robust, especially when dealing with context and data type prefixes.
2026-01-23 01:04:46 +05:30
Amlan Kumar Nandy
caacbc086c chore: update metrics explorer v2 generated APIs (#10093) 2026-01-22 14:42:26 +00:00
Abhishek Kumar Singh
9d06ccab48 chore: return notification channel info in Create notification channel API (#10090) 2026-01-22 14:23:47 +00:00
Pandey
de45292782 chore: add query params to metrics explorer (#10091) 2026-01-22 14:07:27 +00:00
Yunus M
9f38305e5a fix: update query to use dot notation is dotMetrics is enabled (#10078) 2026-01-22 18:27:24 +05:30
Ashwin Bhatkal
e1c8b68cd2 chore: add eslint rules for no-else-return and curly (#10070)
* chore: add eslint rules for no-else-return and curly

* chore: use isNumber from lodash-es

* fix: no-else-return
2026-01-22 12:12:51 +00:00
Ashwin Bhatkal
76ec089a43 chore: updated eslint base config with comments (#10067) 2026-01-22 17:28:18 +05:30
Ashwin Bhatkal
4117c7442b feature: init open api ts code gen (#10011)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feature: init open api ts code gen

* chore: update custom instance to a separate axios instance

* chore: update code owners

* chore: set up node version in CI

* fix: node version

* chore: update jsci.yaml

* chore: update goci.yaml

* chore: rename instance

* chore: resolve comments
2026-01-22 15:22:56 +05:30
Ishan
4153515767 feat: Improve Power-User Experience with Query-Aware Filter Management (#9978)
* feat: dropdown to select query filters

* feat: updated test cases

* feat: updated for cursor fixes

* feat: updated value to have default as lastUsedQuery

* chore: updated package json and lock file

* chore: test case updated

* chore: updated auto-import

* feat: dropdown to select query filters

* feat: updated test cases

* feat: updated for cursor fixes

* feat: updated value to have default as lastUsedQuery

* chore: updated package json and lock file

* chore: test case updated

* chore: updated auto-import

* feat: updated conditions for traces page - duration and logs table actions

* feat: updated conditions for checkbox

* feat: renoved unwanted test caes

* feat: updated value to have lastUsedquery or minIndex

* feat: removed state for value , used lastUsedQuery

* feat: used displayQueryName for leftActions
2026-01-22 10:54:19 +05:30
Pandey
6a0ee32616 test: add mocks for tokenizer (#10081)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
## Description

- add mocks for tokenizer
- rename mocks in alertmanager to alertmanagertest
- add makefile command for generating mocks
2026-01-22 02:04:26 +05:30
Pandey
1f13b60703 feat: remove old login endpoint (#10079)
- remove old login endpoint
2026-01-22 01:22:42 +05:30
Jatinderjit Singh
0865d2edaf fix: add support for minimum data points in PromQL alerts (#9975)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-01-21 16:00:30 +05:30
Yunus M
8629c959f0 chore: move types, constants to separate files, delete unused code (#10026)
* chore: move types, constants to separate files, delete unused code

* chore: fix import error
2026-01-21 08:42:11 +00:00
Yunus M
10760e6e1b Update pull_request_template.md (#10064)
Update PR template to include 

Before / After Screenshots
Issues closed by PR
2026-01-21 13:52:15 +05:30
primus-bot[bot]
4f45645b32 chore(release): bump to v0.108.0 (#10065)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-01-21 12:13:18 +05:30
Karan Balani
1417e22ae4 fix: use reliable selenium methods for actions in integration tests (#10061) 2026-01-21 06:09:42 +00:00
Pandey
3051d442c0 fix: move ee references out of cmd/community (#10063)
- move ee references out of cmd/community
- add check in commitci
2026-01-21 09:22:40 +05:30
Karan Balani
ea15ce4e04 feat: sso stats reporting (#10062)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-01-20 18:57:35 +00:00
Ashwin Bhatkal
865a7a5a31 fix: promql and clickhouse query based panels refresh on dynamic variable change (#10060)
* fix: promql and clickhouse query based panels refresh on dynamic variable change

* chore: add test
2026-01-20 17:19:58 +00:00
swapnil-signoz
de4ca50a40 refactor: using global config's ingestion URL (#10019)
* refactor: using global config's ingestion URL

* refactor: add global ingestion URL to configuration

---------

Co-authored-by: Vikrant Gupta <vikrant@signoz.io>
2026-01-20 17:05:56 +00:00
Amlan Kumar Nandy
8cabaafc58 fix: handle threshold unit scaling issues (#10020) 2026-01-20 16:22:49 +00:00
Ashwin Bhatkal
e9d66b8094 chore: update yarn.lock (#10051) 2026-01-20 16:07:05 +00:00
Karan Balani
26d3d6b1e4 feat: gateway apis (#10010) 2026-01-20 15:46:46 +00:00
Ashwin Bhatkal
36d6debeab chore: update .gitignore with only settings.json of .vscode folder (#10058) 2026-01-20 13:54:58 +00:00
Srikanth Chekuri
836988273f Merge branch 'main' into issue-10008 2026-01-20 16:48:54 +05:30
srikanthccv
a622d65226 chore: lint 2026-01-20 06:30:00 +05:30
srikanthccv
2410e3d411 chore: add integration tests 2026-01-20 06:14:13 +05:30
Srikanth Chekuri
654e2e4b7e Merge branch 'main' into issue-10008 2026-01-20 05:02:15 +05:30
srikanthccv
03ad7a85fa feat(querybuilder): support using variables inside value
prior to this, variables work only as standalone RHS values (e.g. field = $var / field IN $var). this change adds support to use variables inside a value for pattern matching or substitution ex "$env-suffix" or LIKE "%$pattern-var-name%"
2026-01-19 01:41:42 +05:30
492 changed files with 21822 additions and 3581 deletions

8
.github/CODEOWNERS vendored
View File

@@ -103,10 +103,18 @@
/tests/integration/ @vikrantgupta25
# OpenAPI types generator
/frontend/src/api @SigNoz/frontend-maintainers
# Dashboard Owners
/frontend/src/hooks/dashboard/ @SigNoz/pulse-frontend
## Dashboard Types
/frontend/src/api/types/dashboard/ @SigNoz/pulse-frontend
## Dashboard List
/frontend/src/pages/DashboardsListPage/ @SigNoz/pulse-frontend

View File

@@ -6,6 +6,15 @@
> Why does this change exist?
> What problem does it solve, and why is this the right approach?
#### Screenshots / Screen Recordings (if applicable)
> Include screenshots or screen recordings that clearly show the behavior before the change and the result after the change. This helps reviewers quickly understand the impact and verify the update.
#### Issues closed by this PR
> Reference issues using `Closes #issue-number` to enable automatic closure on merge.
---
### ✅ Change Type

View File

@@ -25,3 +25,10 @@ jobs:
else
echo "No references to 'ee' packages found in 'pkg' directory"
fi
if grep -R --include="*.go" '.*/ee/.*' cmd/community/; then
echo "Error: Found references to 'ee' packages in 'cmd/community' directory"
exit 1
else
echo "No references to 'ee' packages found in 'cmd/community' directory"
fi

View File

@@ -65,6 +65,10 @@ jobs:
set -ex
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: node-install
uses: actions/setup-node@v5
with:
node-version: "22"
- name: docker-community
shell: bash
run: |

View File

@@ -84,8 +84,11 @@ jobs:
sudo rm /etc/apt/sources.list.d/google-chrome.list
export CHROMEDRIVER_VERSION=`curl -s https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_${CHROME_MAJOR_VERSION%%.*}`
curl -L -O "https://storage.googleapis.com/chrome-for-testing-public/${CHROMEDRIVER_VERSION}/linux64/chromedriver-linux64.zip"
unzip chromedriver-linux64.zip && chmod +x chromedriver && sudo mv chromedriver /usr/local/bin
unzip chromedriver-linux64.zip
chmod +x chromedriver-linux64/chromedriver
sudo mv chromedriver-linux64/chromedriver /usr/local/bin/chromedriver
chromedriver -version
google-chrome-stable --version
- name: run
run: |
cd tests/integration && \

View File

@@ -17,10 +17,23 @@ jobs:
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup node
uses: actions/setup-node@v5
with:
node-version: "22"
- name: install
run: cd frontend && yarn install
- name: tsc
run: cd frontend && yarn tsc
tsc2:
if: |
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/js-tsc.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
test:
if: |
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||

4
.gitignore vendored
View File

@@ -1,6 +1,9 @@
node_modules
.vscode
!.vscode/settings.json
deploy/docker/environment_tiny/common_test
frontend/node_modules
frontend/.pnp
@@ -104,7 +107,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/

View File

@@ -4,7 +4,14 @@ packages:
github.com/SigNoz/signoz/pkg/alertmanager:
config:
all: true
dir: '{{.InterfaceDir}}/mocks'
filename: "mocks.go"
dir: '{{.InterfaceDir}}/alertmanagertest'
filename: "alertmanager.go"
structname: 'Mock{{.InterfaceName}}'
pkgname: '{{.SrcPackageName}}mock'
pkgname: '{{.SrcPackageName}}test'
github.com/SigNoz/signoz/pkg/tokenizer:
config:
all: true
dir: '{{.InterfaceDir}}/tokenizertest'
filename: "tokenizer.go"
structname: 'Mock{{.InterfaceName}}'
pkgname: '{{.SrcPackageName}}test'

View File

@@ -5,5 +5,9 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"prettier.requireConfig": true
"prettier.requireConfig": true,
"[go]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "golang.go"
}
}

View File

@@ -230,3 +230,12 @@ py-clean: ## Clear all pycache and pytest cache from tests directory recursively
@find tests -type f -name "*.pyc" -delete 2>/dev/null || true
@find tests -type f -name "*.pyo" -delete 2>/dev/null || true
@echo ">> python cache cleaned"
##############################################################
# generate commands
##############################################################
.PHONY: gen-mocks
gen-mocks:
@echo ">> Generating mocks"
@mockery --config .mockery.yml

View File

@@ -5,13 +5,14 @@ import (
"log/slog"
"github.com/SigNoz/signoz/cmd"
"github.com/SigNoz/signoz/ee/authz/openfgaauthz"
"github.com/SigNoz/signoz/ee/authz/openfgaschema"
"github.com/SigNoz/signoz/ee/sqlstore/postgressqlstore"
"github.com/SigNoz/signoz/pkg/analytics"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/authz/openfgaauthz"
"github.com/SigNoz/signoz/pkg/authz/openfgaschema"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/gateway/noopgateway"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/licensing/nooplicensing"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
@@ -24,7 +25,6 @@ import (
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/sqlstore/sqlstorehook"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/version"
"github.com/SigNoz/signoz/pkg/zeus"
@@ -57,13 +57,6 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
// print the version
version.Info.PrettyPrint(config.Version)
// add enterprise sqlstore factories to the community sqlstore factories
sqlstoreFactories := signoz.NewSQLStoreProviderFactories()
if err := sqlstoreFactories.Add(postgressqlstore.NewFactory(sqlstorehook.NewLoggingFactory())); err != nil {
logger.ErrorContext(ctx, "failed to add postgressqlstore factory", "error", err)
return err
}
signoz, err := signoz.New(
ctx,
config,
@@ -90,6 +83,9 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, _ role.Module, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing) dashboard.Module {
return impldashboard.NewModule(impldashboard.NewStore(store), settings, analytics, orgGetter, queryParser)
},
func(_ licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return noopgateway.NewProviderFactory()
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create signoz", "error", err)

View File

@@ -10,6 +10,7 @@ import (
"github.com/SigNoz/signoz/ee/authn/callbackauthn/samlcallbackauthn"
"github.com/SigNoz/signoz/ee/authz/openfgaauthz"
"github.com/SigNoz/signoz/ee/authz/openfgaschema"
"github.com/SigNoz/signoz/ee/gateway/httpgateway"
enterpriselicensing "github.com/SigNoz/signoz/ee/licensing"
"github.com/SigNoz/signoz/ee/licensing/httplicensing"
"github.com/SigNoz/signoz/ee/modules/dashboard/impldashboard"
@@ -22,6 +23,7 @@ import (
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
pkgimpldashboard "github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
@@ -120,6 +122,9 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, role role.Module, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, role, queryParser, querier, licensing)
},
func(licensing licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return httpgateway.NewProviderFactory(licensing)
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create signoz", "error", err)

View File

@@ -176,7 +176,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:v0.107.0
image: signoz/signoz:v0.108.0
command:
- --config=/root/config/prometheus.yml
ports:

View File

@@ -117,7 +117,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:v0.107.0
image: signoz/signoz:v0.108.0
command:
- --config=/root/config/prometheus.yml
ports:

View File

@@ -179,7 +179,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.107.0}
image: signoz/signoz:${VERSION:-v0.108.0}
container_name: signoz
command:
- --config=/root/config/prometheus.yml

View File

@@ -111,7 +111,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.107.0}
image: signoz/signoz:${VERSION:-v0.108.0}
container_name: signoz
command:
- --config=/root/config/prometheus.yml

View File

@@ -607,186 +607,6 @@ paths:
summary: Update auth domain
tags:
- authdomains
/api/v1/fields/keys:
get:
deprecated: false
description: This endpoint returns field keys
operationId: GetFieldsKeys
parameters:
- in: query
name: signal
schema:
type: string
- in: query
name: source
schema:
type: string
- in: query
name: limit
schema:
type: integer
- in: query
name: startUnixMilli
schema:
format: int64
type: integer
- in: query
name: endUnixMilli
schema:
format: int64
type: integer
- in: query
name: fieldContext
schema:
type: string
- in: query
name: fieldDataType
schema:
type: string
- content:
application/json:
schema:
$ref: '#/components/schemas/TelemetrytypesMetricContext'
in: query
name: metricContext
- in: query
name: name
schema:
type: string
- in: query
name: searchText
schema:
type: string
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/TelemetrytypesGettableFieldKeys'
status:
type: string
type: object
description: OK
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get field keys
tags:
- fields
/api/v1/fields/values:
get:
deprecated: false
description: This endpoint returns field values
operationId: GetFieldsValues
parameters:
- in: query
name: signal
schema:
type: string
- in: query
name: source
schema:
type: string
- in: query
name: limit
schema:
type: integer
- in: query
name: startUnixMilli
schema:
format: int64
type: integer
- in: query
name: endUnixMilli
schema:
format: int64
type: integer
- in: query
name: fieldContext
schema:
type: string
- in: query
name: fieldDataType
schema:
type: string
- content:
application/json:
schema:
$ref: '#/components/schemas/TelemetrytypesMetricContext'
in: query
name: metricContext
- in: query
name: name
schema:
type: string
- in: query
name: searchText
schema:
type: string
- in: query
name: existingQuery
schema:
type: string
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/TelemetrytypesGettableFieldValues'
status:
type: string
type: object
description: OK
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- VIEWER
- tokenizer:
- VIEWER
summary: Get field values
tags:
- fields
/api/v1/getResetPasswordToken/{id}:
get:
deprecated: false
@@ -1187,43 +1007,6 @@ paths:
summary: Create bulk invite
tags:
- users
/api/v1/login:
post:
deprecated: true
description: This endpoint is deprecated and will be removed in the future
operationId: DeprecatedCreateSessionByEmailPassword
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AuthtypesDeprecatedPostableLogin'
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/AuthtypesDeprecatedGettableLogin'
status:
type: string
type: object
description: OK
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
summary: Deprecated create session by email password
tags:
- sessions
/api/v1/logs/promote_paths:
get:
deprecated: false
@@ -2247,11 +2030,371 @@ paths:
summary: Get features
tags:
- features
/api/v2/gateway/ingestion_keys:
get:
deprecated: false
description: This endpoint returns the ingestion keys for a workspace
operationId: GetIngestionKeys
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/GatewaytypesGettableIngestionKeys'
status:
type: string
type: object
description: OK
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Get ingestion keys for workspace
tags:
- gateway
post:
deprecated: false
description: This endpoint creates an ingestion key for the workspace
operationId: CreateIngestionKey
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GatewaytypesPostableIngestionKey'
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/GatewaytypesGettableCreatedIngestionKey'
status:
type: string
type: object
description: OK
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Create ingestion key for workspace
tags:
- gateway
/api/v2/gateway/ingestion_keys/{keyId}:
delete:
deprecated: false
description: This endpoint deletes an ingestion key for the workspace
operationId: DeleteIngestionKey
parameters:
- in: path
name: keyId
required: true
schema:
type: string
responses:
"204":
description: No Content
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Delete ingestion key for workspace
tags:
- gateway
patch:
deprecated: false
description: This endpoint updates an ingestion key for the workspace
operationId: UpdateIngestionKey
parameters:
- in: path
name: keyId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GatewaytypesPostableIngestionKey'
responses:
"204":
description: No Content
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Update ingestion key for workspace
tags:
- gateway
/api/v2/gateway/ingestion_keys/{keyId}/limits:
post:
deprecated: false
description: This endpoint creates an ingestion key limit
operationId: CreateIngestionKeyLimit
parameters:
- in: path
name: keyId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GatewaytypesPostableIngestionKeyLimit'
responses:
"201":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/GatewaytypesGettableCreatedIngestionKeyLimit'
status:
type: string
type: object
description: Created
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Create limit for the ingestion key
tags:
- gateway
/api/v2/gateway/ingestion_keys/limits/{limitId}:
delete:
deprecated: false
description: This endpoint deletes an ingestion key limit
operationId: DeleteIngestionKeyLimit
parameters:
- in: path
name: limitId
required: true
schema:
type: string
responses:
"204":
description: No Content
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Delete limit for the ingestion key
tags:
- gateway
patch:
deprecated: false
description: This endpoint updates an ingestion key limit
operationId: UpdateIngestionKeyLimit
parameters:
- in: path
name: limitId
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GatewaytypesUpdatableIngestionKeyLimit'
responses:
"204":
description: No Content
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Update limit for the ingestion key
tags:
- gateway
/api/v2/gateway/ingestion_keys/search:
get:
deprecated: false
description: This endpoint returns the ingestion keys for a workspace
operationId: SearchIngestionKeys
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/GatewaytypesGettableIngestionKeys'
status:
type: string
type: object
description: OK
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- ADMIN
- tokenizer:
- ADMIN
summary: Search ingestion keys for workspace
tags:
- gateway
/api/v2/metric/alerts:
get:
deprecated: false
description: This endpoint returns associated alerts for a specified metric
operationId: GetMetricAlerts
parameters:
- in: query
name: metricName
schema:
type: string
responses:
"200":
content:
@@ -2301,6 +2444,11 @@ paths:
deprecated: false
description: This endpoint returns associated dashboards for a specified metric
operationId: GetMetricDashboards
parameters:
- in: query
name: metricName
schema:
type: string
responses:
"200":
content:
@@ -2351,6 +2499,11 @@ paths:
description: This endpoint returns highlights like number of datapoints, totaltimeseries,
active time series, last received time for a specified metric
operationId: GetMetricHighlights
parameters:
- in: query
name: metricName
schema:
type: string
responses:
"200":
content:
@@ -2512,6 +2665,11 @@ paths:
description: This endpoint returns metadata information like metric description,
unit, type, temporality, monotonicity for a specified metric
operationId: GetMetricMetadata
parameters:
- in: query
name: metricName
schema:
type: string
responses:
"200":
content:
@@ -2968,20 +3126,6 @@ components:
url:
type: string
type: object
AuthtypesDeprecatedGettableLogin:
properties:
accessJwt:
type: string
userId:
type: string
type: object
AuthtypesDeprecatedPostableLogin:
properties:
email:
type: string
password:
type: string
type: object
AuthtypesGettableAuthDomain:
properties:
authNProviderInfo:
@@ -3231,6 +3375,160 @@ components:
nullable: true
type: object
type: object
GatewaytypesGettableCreatedIngestionKey:
properties:
id:
type: string
value:
type: string
type: object
GatewaytypesGettableCreatedIngestionKeyLimit:
properties:
id:
type: string
type: object
GatewaytypesGettableIngestionKeys:
properties:
_pagination:
$ref: '#/components/schemas/GatewaytypesPagination'
keys:
items:
$ref: '#/components/schemas/GatewaytypesIngestionKey'
nullable: true
type: array
type: object
GatewaytypesIngestionKey:
properties:
created_at:
format: date-time
type: string
expires_at:
format: date-time
type: string
id:
type: string
limits:
items:
$ref: '#/components/schemas/GatewaytypesLimit'
nullable: true
type: array
name:
type: string
tags:
items:
type: string
nullable: true
type: array
updated_at:
format: date-time
type: string
value:
type: string
workspace_id:
type: string
type: object
GatewaytypesLimit:
properties:
config:
$ref: '#/components/schemas/GatewaytypesLimitConfig'
created_at:
format: date-time
type: string
id:
type: string
key_id:
type: string
metric:
$ref: '#/components/schemas/GatewaytypesLimitMetric'
signal:
type: string
tags:
items:
type: string
nullable: true
type: array
updated_at:
format: date-time
type: string
type: object
GatewaytypesLimitConfig:
properties:
day:
$ref: '#/components/schemas/GatewaytypesLimitValue'
second:
$ref: '#/components/schemas/GatewaytypesLimitValue'
type: object
GatewaytypesLimitMetric:
properties:
day:
$ref: '#/components/schemas/GatewaytypesLimitMetricValue'
second:
$ref: '#/components/schemas/GatewaytypesLimitMetricValue'
type: object
GatewaytypesLimitMetricValue:
properties:
count:
format: int64
type: integer
size:
format: int64
type: integer
type: object
GatewaytypesLimitValue:
properties:
count:
format: int64
type: integer
size:
format: int64
type: integer
type: object
GatewaytypesPagination:
properties:
page:
type: integer
pages:
type: integer
per_page:
type: integer
total:
type: integer
type: object
GatewaytypesPostableIngestionKey:
properties:
expires_at:
format: date-time
type: string
name:
type: string
tags:
items:
type: string
nullable: true
type: array
type: object
GatewaytypesPostableIngestionKeyLimit:
properties:
config:
$ref: '#/components/schemas/GatewaytypesLimitConfig'
signal:
type: string
tags:
items:
type: string
nullable: true
type: array
type: object
GatewaytypesUpdatableIngestionKeyLimit:
properties:
config:
$ref: '#/components/schemas/GatewaytypesLimitConfig'
tags:
items:
type: string
nullable: true
type: array
type: object
MetricsexplorertypesMetricAlert:
properties:
alertId:
@@ -3561,65 +3859,6 @@ components:
status:
type: string
type: object
TelemetrytypesGettableFieldKeys:
properties:
complete:
type: boolean
keys:
additionalProperties:
items:
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldKey'
type: array
nullable: true
type: object
type: object
TelemetrytypesGettableFieldValues:
properties:
complete:
type: boolean
values:
$ref: '#/components/schemas/TelemetrytypesTelemetryFieldValues'
type: object
TelemetrytypesMetricContext:
properties:
metricName:
type: string
type: object
TelemetrytypesTelemetryFieldKey:
properties:
description:
type: string
fieldContext:
type: string
fieldDataType:
type: string
name:
type: string
signal:
type: string
unit:
type: string
type: object
TelemetrytypesTelemetryFieldValues:
properties:
boolValues:
items:
type: boolean
type: array
numberValues:
items:
format: double
type: number
type: array
relatedValues:
items:
type: string
type: array
stringValues:
items:
type: string
type: array
type: object
TypesChangePasswordRequest:
properties:
newPassword:

View File

@@ -0,0 +1,282 @@
package httpgateway
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/url"
"strconv"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/http/client"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/types/gatewaytypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/tidwall/gjson"
)
type Provider struct {
settings factory.ScopedProviderSettings
config gateway.Config
httpClient *client.Client
licensing licensing.Licensing
}
func NewProviderFactory(licensing licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return factory.NewProviderFactory(factory.MustNewName("http"), func(ctx context.Context, ps factory.ProviderSettings, c gateway.Config) (gateway.Gateway, error) {
return New(ctx, ps, c, licensing)
})
}
func New(ctx context.Context, providerSettings factory.ProviderSettings, config gateway.Config, licensing licensing.Licensing) (gateway.Gateway, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/ee/gateway/httpgateway")
httpClient, err := client.New(
settings.Logger(),
providerSettings.TracerProvider,
providerSettings.MeterProvider,
client.WithRequestResponseLog(true),
client.WithRetryCount(3),
)
if err != nil {
return nil, err
}
return &Provider{
settings: settings,
config: config,
httpClient: httpClient,
licensing: licensing,
}, nil
}
func (provider *Provider) GetIngestionKeys(ctx context.Context, orgID valuer.UUID, page, perPage int) (*gatewaytypes.GettableIngestionKeys, error) {
qParams := url.Values{}
qParams.Add("page", strconv.Itoa(page))
qParams.Add("per_page", strconv.Itoa(perPage))
responseBody, err := provider.do(ctx, orgID, http.MethodGet, "/v1/workspaces/me/keys", qParams, nil)
if err != nil {
return nil, err
}
var ingestionKeys []gatewaytypes.IngestionKey
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &ingestionKeys); err != nil {
return nil, err
}
var pagination gatewaytypes.Pagination
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "_pagination").String()), &pagination); err != nil {
return nil, err
}
return &gatewaytypes.GettableIngestionKeys{
Keys: ingestionKeys,
Pagination: pagination,
}, nil
}
func (provider *Provider) SearchIngestionKeysByName(ctx context.Context, orgID valuer.UUID, name string, page, perPage int) (*gatewaytypes.GettableIngestionKeys, error) {
qParams := url.Values{}
qParams.Add("name", name)
qParams.Add("page", strconv.Itoa(page))
qParams.Add("per_page", strconv.Itoa(perPage))
responseBody, err := provider.do(ctx, orgID, http.MethodGet, "/v1/workspaces/me/keys/search", qParams, nil)
if err != nil {
return nil, err
}
var ingestionKeys []gatewaytypes.IngestionKey
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &ingestionKeys); err != nil {
return nil, err
}
var pagination gatewaytypes.Pagination
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "_pagination").String()), &pagination); err != nil {
return nil, err
}
return &gatewaytypes.GettableIngestionKeys{
Keys: ingestionKeys,
Pagination: pagination,
}, nil
}
func (provider *Provider) CreateIngestionKey(ctx context.Context, orgID valuer.UUID, name string, tags []string, expiresAt time.Time) (*gatewaytypes.GettableCreatedIngestionKey, error) {
requestBody := gatewaytypes.PostableIngestionKey{
Name: name,
Tags: tags,
ExpiresAt: expiresAt,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
return nil, err
}
responseBody, err := provider.do(ctx, orgID, http.MethodPost, "/v1/workspaces/me/keys", nil, requestBodyBytes)
if err != nil {
return nil, err
}
var createdKeyResponse gatewaytypes.GettableCreatedIngestionKey
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &createdKeyResponse); err != nil {
return nil, err
}
return &createdKeyResponse, nil
}
func (provider *Provider) UpdateIngestionKey(ctx context.Context, orgID valuer.UUID, keyID string, name string, tags []string, expiresAt time.Time) error {
requestBody := gatewaytypes.PostableIngestionKey{
Name: name,
Tags: tags,
ExpiresAt: expiresAt,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
return err
}
_, err = provider.do(ctx, orgID, http.MethodPatch, "/v1/workspaces/me/keys/"+keyID, nil, requestBodyBytes)
if err != nil {
return err
}
return nil
}
func (provider *Provider) DeleteIngestionKey(ctx context.Context, orgID valuer.UUID, keyID string) error {
_, err := provider.do(ctx, orgID, http.MethodDelete, "/v1/workspaces/me/keys/"+keyID, nil, nil)
if err != nil {
return err
}
return nil
}
func (provider *Provider) CreateIngestionKeyLimit(ctx context.Context, orgID valuer.UUID, keyID string, signal string, limitConfig gatewaytypes.LimitConfig, tags []string) (*gatewaytypes.GettableCreatedIngestionKeyLimit, error) {
requestBody := gatewaytypes.PostableIngestionKeyLimit{
Signal: signal,
Config: limitConfig,
Tags: tags,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
return nil, err
}
responseBody, err := provider.do(ctx, orgID, http.MethodPost, "/v1/workspaces/me/keys/"+keyID+"/limits", nil, requestBodyBytes)
if err != nil {
return nil, err
}
var createdIngestionKeyLimitResponse gatewaytypes.GettableCreatedIngestionKeyLimit
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &createdIngestionKeyLimitResponse); err != nil {
return nil, err
}
return &createdIngestionKeyLimitResponse, nil
}
func (provider *Provider) UpdateIngestionKeyLimit(ctx context.Context, orgID valuer.UUID, limitID string, limitConfig gatewaytypes.LimitConfig, tags []string) error {
requestBody := gatewaytypes.UpdatableIngestionKeyLimit{
Config: limitConfig,
Tags: tags,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
return err
}
_, err = provider.do(ctx, orgID, http.MethodPatch, "/v1/workspaces/me/limits/"+limitID, nil, requestBodyBytes)
if err != nil {
return err
}
return nil
}
func (provider *Provider) DeleteIngestionKeyLimit(ctx context.Context, orgID valuer.UUID, limitID string) error {
_, err := provider.do(ctx, orgID, http.MethodDelete, "/v1/workspaces/me/limits/"+limitID, nil, nil)
if err != nil {
return err
}
return nil
}
func (provider *Provider) do(ctx context.Context, orgID valuer.UUID, method string, path string, queryParams url.Values, body []byte) ([]byte, error) {
license, err := provider.licensing.GetActive(ctx, orgID)
if err != nil {
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "no valid license found").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
// build url
requestURL := provider.config.URL.JoinPath(path)
// add query params to the url
if queryParams != nil {
requestURL.RawQuery = queryParams.Encode()
}
// build request
request, err := http.NewRequestWithContext(ctx, method, requestURL.String(), bytes.NewBuffer(body))
if err != nil {
return nil, err
}
// add headers needed to call gateway
request.Header.Set("Content-Type", "application/json")
request.Header.Set("X-Signoz-Cloud-Api-Key", license.Key)
request.Header.Set("X-Consumer-Username", "lid:00000000-0000-0000-0000-000000000000")
request.Header.Set("X-Consumer-Groups", "ns:default")
// execute request
response, err := provider.httpClient.Do(request)
if err != nil {
return nil, err
}
// read response
defer response.Body.Close()
responseBody, err := io.ReadAll(response.Body)
if err != nil {
return nil, err
}
// only 2XX
if response.StatusCode/100 == 2 {
return responseBody, nil
}
errorMessage := gjson.GetBytes(responseBody, "error").String()
if errorMessage == "" {
errorMessage = "an unknown error occurred"
}
// return error for non 2XX
return nil, provider.errFromStatusCode(response.StatusCode, errorMessage)
}
func (provider *Provider) errFromStatusCode(code int, errorMessage string) error {
switch code {
case http.StatusBadRequest:
return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, errorMessage)
case http.StatusUnauthorized:
return errors.New(errors.TypeUnauthenticated, errors.CodeUnauthenticated, errorMessage)
case http.StatusForbidden:
return errors.New(errors.TypeForbidden, errors.CodeForbidden, errorMessage)
case http.StatusNotFound:
return errors.New(errors.TypeNotFound, errors.CodeNotFound, errorMessage)
case http.StatusConflict:
return errors.New(errors.TypeAlreadyExists, errors.CodeAlreadyExists, errorMessage)
}
return errors.New(errors.TypeInternal, errors.CodeInternal, errorMessage)
}

View File

@@ -9,6 +9,8 @@ import (
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
"github.com/SigNoz/signoz/ee/query-service/usage"
"github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/apis/fields"
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/http/middleware"
querierAPI "github.com/SigNoz/signoz/pkg/querier"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
@@ -35,6 +37,7 @@ type APIHandlerOptions struct {
GatewayUrl string
// Querier Influx Interval
FluxInterval time.Duration
GlobalConfig global.Config
}
type APIHandler struct {
@@ -53,6 +56,7 @@ func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz) (*APIHandler,
FluxInterval: opts.FluxInterval,
AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager),
LicensingAPI: httplicensing.NewLicensingAPI(signoz.Licensing),
FieldsAPI: fields.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.TelemetryStore),
Signoz: signoz,
QuerierAPI: querierAPI.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.Querier, signoz.Analytics),
QueryParserAPI: queryparser.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.QueryParser),

View File

@@ -76,7 +76,7 @@ func (ah *APIHandler) CloudIntegrationsGenerateConnectionParams(w http.ResponseW
return
}
ingestionUrl, signozApiUrl, apiErr := ah.getIngestionUrlAndSigNozAPIUrl(r.Context(), license.Key)
signozApiUrl, apiErr := ah.getIngestionUrlAndSigNozAPIUrl(r.Context(), license.Key)
if apiErr != nil {
RespondError(w, basemodel.WrapApiError(
apiErr, "couldn't deduce ingestion url and signoz api url",
@@ -84,7 +84,7 @@ func (ah *APIHandler) CloudIntegrationsGenerateConnectionParams(w http.ResponseW
return
}
result.IngestionUrl = ingestionUrl
result.IngestionUrl = ah.opts.GlobalConfig.IngestionURL.String()
result.SigNozAPIUrl = signozApiUrl
gatewayUrl := ah.opts.GatewayUrl
@@ -186,7 +186,7 @@ func (ah *APIHandler) getOrCreateCloudIntegrationUser(
}
func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licenseKey string) (
string, string, *basemodel.ApiError,
string, *basemodel.ApiError,
) {
// TODO: remove this struct from here
type deploymentResponse struct {
@@ -200,7 +200,7 @@ func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licens
respBytes, err := ah.Signoz.Zeus.GetDeployment(ctx, licenseKey)
if err != nil {
return "", "", basemodel.InternalError(fmt.Errorf(
return "", basemodel.InternalError(fmt.Errorf(
"couldn't query for deployment info: error: %w", err,
))
}
@@ -209,7 +209,7 @@ func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licens
err = json.Unmarshal(respBytes, resp)
if err != nil {
return "", "", basemodel.InternalError(fmt.Errorf(
return "", basemodel.InternalError(fmt.Errorf(
"couldn't unmarshal deployment info response: error: %w", err,
))
}
@@ -219,16 +219,14 @@ func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licens
if len(regionDns) < 1 || len(deploymentName) < 1 {
// Fail early if actual response structure and expectation here ever diverge
return "", "", basemodel.InternalError(fmt.Errorf(
return "", basemodel.InternalError(fmt.Errorf(
"deployment info response not in expected shape. couldn't determine region dns and deployment name",
))
}
ingestionUrl := fmt.Sprintf("https://ingest.%s", regionDns)
signozApiUrl := fmt.Sprintf("https://%s.%s", deploymentName, regionDns)
return ingestionUrl, signozApiUrl, nil
return signozApiUrl, nil
}
type ingestionKey struct {

View File

@@ -172,6 +172,7 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
FluxInterval: config.Querier.FluxInterval,
Gateway: gatewayProxy,
GatewayUrl: config.Gateway.URL.String(),
GlobalConfig: config.Global,
}
apiHandler, err := api.NewAPIHandler(apiOpts, signoz)
@@ -236,6 +237,7 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*h
apiHandler.RegisterLogsRoutes(r, am)
apiHandler.RegisterIntegrationRoutes(r, am)
apiHandler.RegisterCloudIntegrationsRoutes(r, am)
apiHandler.RegisterFieldsRoutes(r, am)
apiHandler.RegisterQueryRangeV3Routes(r, am)
apiHandler.RegisterInfraMetricsRoutes(r, am)
apiHandler.RegisterQueryRangeV4Routes(r, am)

View File

@@ -240,11 +240,9 @@ func (r *AnomalyRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID, t
r.logger.InfoContext(ctx, "anomaly scores", "scores", string(scoresJSON))
for _, series := range queryResult.AnomalyScores {
if r.Condition() != nil && r.Condition().RequireMinPoints {
if len(series.Points) < r.Condition().RequiredNumPoints {
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
continue
}
if !r.Condition().ShouldEval(series) {
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
continue
}
results, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
ActiveAlerts: r.ActiveAlertsLabelFP(),
@@ -305,11 +303,9 @@ func (r *AnomalyRule) buildAndRunQueryV5(ctx context.Context, orgID valuer.UUID,
}
for _, series := range seriesToProcess {
if r.Condition().RequireMinPoints {
if len(series.Points) < r.Condition().RequiredNumPoints {
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
continue
}
if !r.Condition().ShouldEval(series) {
r.logger.InfoContext(ctx, "not enough data points to evaluate series, skipping", "ruleid", r.ID(), "numPoints", len(series.Points), "requiredPoints", r.Condition().RequiredNumPoints)
continue
}
results, err := r.Threshold.Eval(*series, r.Unit(), ruletypes.EvalData{
ActiveAlerts: r.ActiveAlertsLabelFP(),
@@ -323,7 +319,7 @@ func (r *AnomalyRule) buildAndRunQueryV5(ctx context.Context, orgID valuer.UUID,
return resultVector, nil
}
func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (interface{}, error) {
func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (int, error) {
prevState := r.State()
@@ -340,7 +336,7 @@ func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (interface{}, erro
res, err = r.buildAndRunQuery(ctx, r.OrgID(), ts)
}
if err != nil {
return nil, err
return 0, err
}
r.mtx.Lock()
@@ -415,7 +411,7 @@ func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (interface{}, erro
if _, ok := alerts[h]; ok {
r.logger.ErrorContext(ctx, "the alert query returns duplicate records", "rule_id", r.ID(), "alert", alerts[h])
err = fmt.Errorf("duplicate alert found, vector contains metrics with the same labelset after applying alert labels")
return nil, err
return 0, err
}
alerts[h] = &ruletypes.Alert{

View File

@@ -10,7 +10,7 @@ import (
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
baserules "github.com/SigNoz/signoz/pkg/query-service/rules"
"github.com/SigNoz/signoz/pkg/query-service/utils/labels"
ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes"
"github.com/SigNoz/signoz/pkg/types/ruletypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/google/uuid"
"go.uber.org/zap"
@@ -47,7 +47,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
rules = append(rules, tr)
// create ch rule task for evalution
// create ch rule task for evaluation
task = newTask(baserules.TaskTypeCh, opts.TaskName, time.Duration(evaluation.GetFrequency()), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
} else if opts.Rule.RuleType == ruletypes.RuleTypeProm {
@@ -71,7 +71,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
rules = append(rules, pr)
// create promql rule task for evalution
// create promql rule task for evaluation
task = newTask(baserules.TaskTypeProm, opts.TaskName, time.Duration(evaluation.GetFrequency()), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
} else if opts.Rule.RuleType == ruletypes.RuleTypeAnomaly {
@@ -95,7 +95,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
rules = append(rules, ar)
// create anomaly rule task for evalution
// create anomaly rule task for evaluation
task = newTask(baserules.TaskTypeCh, opts.TaskName, time.Duration(evaluation.GetFrequency()), rules, opts.ManagerOpts, opts.NotifyFunc, opts.MaintenanceStore, opts.OrgID)
} else {
@@ -203,16 +203,12 @@ func TestNotification(opts baserules.PrepareTestRuleOptions) (int, *basemodel.Ap
// set timestamp to current utc time
ts := time.Now().UTC()
count, err := rule.Eval(ctx, ts)
alertsFound, err := rule.Eval(ctx, ts)
if err != nil {
zap.L().Error("evaluating rule failed", zap.String("rule", rule.Name()), zap.Error(err))
return 0, basemodel.InternalError(fmt.Errorf("rule evaluation failed"))
}
alertsFound, ok := count.(int)
if !ok {
return 0, basemodel.InternalError(fmt.Errorf("something went wrong"))
}
rule.SendAlerts(ctx, ts, 0, time.Duration(1*time.Minute), opts.NotifyFunc)
rule.SendAlerts(ctx, ts, 0, time.Minute, opts.NotifyFunc)
return alertsFound, nil
}

View File

@@ -9,7 +9,7 @@ import (
"time"
"github.com/SigNoz/signoz/pkg/alertmanager"
alertmanagermock "github.com/SigNoz/signoz/pkg/alertmanager/mocks"
alertmanagermock "github.com/SigNoz/signoz/pkg/alertmanager/alertmanagertest"
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/prometheus"
"github.com/SigNoz/signoz/pkg/prometheus/prometheustest"

View File

@@ -2,4 +2,6 @@ node_modules
build
*.typegen.ts
i18-generate-hash.js
src/parser/TraceOperatorParser/**
src/parser/TraceOperatorParser/**
orval.config.ts

View File

@@ -1,3 +1,6 @@
/**
* ESLint Configuration for SigNoz Frontend
*/
module.exports = {
ignorePatterns: ['src/parser/*.ts', 'scripts/update-registry.js'],
env: {
@@ -10,11 +13,9 @@ module.exports = {
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:react-hooks/recommended',
'plugin:prettier/recommended',
'plugin:sonarjs/recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:react/jsx-runtime',
],
parser: '@typescript-eslint/parser',
@@ -23,17 +24,21 @@ module.exports = {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
ecmaVersion: 2021,
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
'simple-import-sort',
'react-hooks',
'prettier',
'jest',
'jsx-a11y',
'react', // React-specific rules
'@typescript-eslint', // TypeScript linting
'simple-import-sort', // Auto-sort imports
'react-hooks', // React Hooks rules
'prettier', // Code formatting
'jest', // Jest test rules
'jsx-a11y', // Accessibility rules
'import', // Import/export linting
'sonarjs', // Code quality/complexity
// TODO: Uncomment after running: yarn add -D eslint-plugin-spellcheck
// 'spellcheck',
],
settings: {
react: {
@@ -47,81 +52,104 @@ module.exports = {
},
},
rules: {
// Code quality rules
'prefer-const': 'error', // Enforces const for variables never reassigned
'no-var': 'error', // Disallows var, enforces let/const
'no-else-return': ['error', { allowElseIf: false }], // Reduces nesting by disallowing else after return
'no-cond-assign': 'error', // Prevents accidental assignment in conditions (if (x = 1) instead of if (x === 1))
'no-debugger': 'error', // Disallows debugger statements in production code
curly: 'error', // Requires curly braces for all control statements
eqeqeq: ['error', 'always', { null: 'ignore' }], // Enforces === and !== (allows == null for null/undefined check)
// TODO: Enable after fixing ~15 console.log statements
// 'no-console': ['error', { allow: ['warn', 'error'] }], // Warns on console.log, allows console.warn/error
// TypeScript rules
'@typescript-eslint/explicit-function-return-type': 'error', // Requires explicit return types on functions
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'warn', // Warns when using 'any' type (consider upgrading to error)
// TODO: Change to 'error' after fixing ~80 empty function placeholders in providers/contexts
'@typescript-eslint/no-empty-function': 'off', // Disallows empty function bodies
'@typescript-eslint/no-var-requires': 'error', // Disallows require() in TypeScript (use import instead)
'@typescript-eslint/ban-ts-comment': 'off', // Allows @ts-ignore comments (sometimes needed for third-party libs)
'no-empty-function': 'off', // Disabled in favor of TypeScript version above
// React rules
'react/jsx-filename-extension': [
'error',
{
extensions: ['.tsx', '.js', '.jsx'],
extensions: ['.tsx', '.jsx'], // Warns if JSX is used in non-.jsx/.tsx files
},
],
'react/prop-types': 'off',
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/no-var-requires': 'error',
'react/no-array-index-key': 'error',
'linebreak-style': [
'error',
process.env.platform === 'win32' ? 'windows' : 'unix',
],
'@typescript-eslint/default-param-last': 'off',
'react/prop-types': 'off', // Disabled - using TypeScript instead
'react/jsx-props-no-spreading': 'off', // Allows {...props} spreading (common in HOCs, forms, wrappers)
'react/no-array-index-key': 'error', // Prevents using array index as key (causes bugs when list changes)
// simple sort error
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
// hooks
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
'import/prefer-default-export': 'off',
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
// Disabled because TypeScript already handles this check more accurately,
// and the rule has false positives with type-only imports (e.g., TooltipProps from antd)
'import/named': 'off',
'no-plusplus': 'off',
// Accessibility rules
'jsx-a11y/label-has-associated-control': [
'error',
{
required: {
some: ['nesting', 'id'],
some: ['nesting', 'id'], // Labels must either wrap inputs or use htmlFor/id
},
},
],
'jsx-a11y/label-has-for': [
'error',
{
required: {
some: ['nesting', 'id'],
},
},
],
// Allow empty functions for mocks, default context values, and noop callbacks
'@typescript-eslint/no-empty-function': 'off',
// Allow underscore prefix for intentionally unused variables (e.g., const { id: _id, ...rest } = props)
'@typescript-eslint/no-unused-vars': 'warn',
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'arrow-body-style': ['error', 'as-needed'],
// eslint rules need to remove
'@typescript-eslint/no-shadow': 'off',
'import/no-cycle': 'off',
// https://typescript-eslint.io/rules/consistent-return/ check the warning for details
'consistent-return': 'off',
// React Hooks rules
'react-hooks/rules-of-hooks': 'error', // Enforces Rules of Hooks (only call at top level)
'react-hooks/exhaustive-deps': 'warn', // Warns about missing dependencies in useEffect/useMemo/useCallback
// Import/export rules
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never', // Disallows .js extension in imports
jsx: 'never', // Disallows .jsx extension in imports
ts: 'never', // Disallows .ts extension in imports
tsx: 'never', // Disallows .tsx extension in imports
},
],
'import/no-extraneous-dependencies': ['error', { devDependencies: true }], // Prevents importing packages not in package.json
// 'import/no-cycle': 'warn', // TODO: Enable later to detect circular dependencies
// TODO: Enable in separate PR with auto fixes
// // Import sorting rules
// 'simple-import-sort/imports': [
// 'error',
// {
// groups: [
// ['^react', '^@?\\w'], // React first, then external packages
// ['^@/'], // Absolute imports with @ alias
// ['^\\u0000'], // Side effect imports (import './file')
// ['^\\.'], // Relative imports
// ['^.+\\.s?css$'], // Style imports
// ],
// },
// ],
// 'simple-import-sort/exports': 'error', // Auto-sorts exports
// Prettier - code formatting
'prettier/prettier': [
'error',
{},
{
usePrettierrc: true,
usePrettierrc: true, // Uses .prettierrc.json for formatting rules
},
],
'react/jsx-props-no-spreading': 'off',
// SonarJS - code quality and complexity
'sonarjs/no-duplicate-string': 'off', // Disabled - can be noisy (enable periodically to check)
},
overrides: [
{
files: ['src/api/generated/**/*.ts'],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'no-nested-ternary': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
'sonarjs/no-duplicate-string': 'off',
},
},
],
};

View File

@@ -7,7 +7,7 @@
"semi": true,
"printWidth": 80,
"bracketSpacing": true,
"bracketSameLine": false,
"jsxBracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf",
"quoteProps": "as-needed",

97
frontend/orval.config.ts Normal file
View File

@@ -0,0 +1,97 @@
/**
* When making changes to this file, remove this the file name from .eslintignore and tsconfig.json
* The reason this is required because of the moduleResolution being "node". Changing this is a more detailed effort.
* So, until then, we will keep this file ignored for eslint and typescript.
*/
import { defineConfig } from 'orval';
export default defineConfig({
signoz: {
input: {
target: '../docs/api/openapi.yml',
},
output: {
target: './src/api/generated/services',
client: 'react-query',
httpClient: 'axios',
mode: 'tags-split',
prettier: true,
headers: true,
clean: true,
override: {
query: {
useQuery: true,
useMutation: true,
useInvalidate: true,
signal: true,
useOperationIdAsQueryKey: true,
},
useDates: true,
useNamedParameters: true,
enumGenerationType: 'enum',
mutator: {
path: './src/api/index.ts',
name: 'GeneratedAPIInstance',
},
jsDoc: {
filter: (schema) => {
const allowlist = [
'type',
'format',
'maxLength',
'minLength',
'description',
'minimum',
'maximum',
'exclusiveMinimum',
'exclusiveMaximum',
'pattern',
'nullable',
'enum',
];
return Object.entries(schema || {})
.filter(([key]) => allowlist.includes(key))
.map(([key, value]: [string, any]) => ({
key,
value,
}))
.sort((a, b) => a.key.length - b.key.length);
},
},
components: {
schemas: {
suffix: 'DTO',
},
responses: {
suffix: 'Response',
},
parameters: {
suffix: 'Params',
},
requestBodies: {
suffix: 'Body',
},
},
// info is of type InfoObject from openapi spec
header: (info: { title: string; version: string }): string[] => [
`! Do not edit manually`,
`* The file has been auto-generated using Orval for SigNoz`,
`* regenerate with 'yarn generate:api'`,
...(info.title ? [info.title] : []),
...(info.version ? [`OpenAPI spec version: ${info.version}`] : []),
],
// @ts-expect-error
// propertySortOrder, urlEncodeParameters, aliasCombinedTypes
// are valid options in the document without types
propertySortOrder: 'Alphabetical',
urlEncodeParameters: true,
aliasCombinedTypes: true,
},
},
},
});

View File

@@ -18,7 +18,8 @@
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
"commitlint": "commitlint --edit $1",
"test": "jest",
"test:changedsince": "jest --changedSince=main --coverage --silent"
"test:changedsince": "jest --changedSince=main --coverage --silent",
"generate:api": "orval --config ./orval.config.ts && sh scripts/post-types-generation.sh && prettier --write src/api/generated && (eslint --fix src/api/generated || true)"
},
"engines": {
"node": ">=16.15.0"
@@ -48,6 +49,7 @@
"@signozhq/calendar": "0.0.0",
"@signozhq/callout": "0.0.2",
"@signozhq/checkbox": "0.0.2",
"@signozhq/combobox": "0.0.2",
"@signozhq/command": "0.0.0",
"@signozhq/design-tokens": "1.1.4",
"@signozhq/input": "0.0.2",
@@ -237,6 +239,7 @@
"lint-staged": "^12.5.0",
"msw": "1.3.2",
"npm-run-all": "latest",
"orval": "7.18.0",
"portfinder-sync": "^0.0.2",
"postcss": "8.4.38",
"prettier": "2.2.1",

View File

@@ -0,0 +1,14 @@
#!/bin/bash
# Rename tag files to index.ts in services directories
# tags-split creates: services/tagName/tagName.ts -> rename to services/tagName/index.ts
find src/api/generated/services -mindepth 1 -maxdepth 1 -type d | while read -r dir; do
dirname=$(basename "$dir")
tagfile="$dir/$dirname.ts"
if [ -f "$tagfile" ]; then
mv "$tagfile" "$dir/index.ts"
echo "Renamed $tagfile -> $dir/index.ts"
fi
done
echo "Tag files renamed to index.ts"

View File

@@ -0,0 +1,378 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
AuthtypesPostableAuthDomainDTO,
AuthtypesUpdateableAuthDomainDTO,
CreateAuthDomain200,
DeleteAuthDomainPathParameters,
ListAuthDomains200,
RenderErrorResponseDTO,
UpdateAuthDomainPathParameters,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint lists all auth domains
* @summary List all auth domains
*/
export const listAuthDomains = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListAuthDomains200>({
url: `/api/v1/domains`,
method: 'GET',
signal,
});
};
export const getListAuthDomainsQueryKey = () => {
return ['listAuthDomains'] as const;
};
export const getListAuthDomainsQueryOptions = <
TData = Awaited<ReturnType<typeof listAuthDomains>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listAuthDomains>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListAuthDomainsQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof listAuthDomains>>> = ({
signal,
}) => listAuthDomains(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listAuthDomains>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListAuthDomainsQueryResult = NonNullable<
Awaited<ReturnType<typeof listAuthDomains>>
>;
export type ListAuthDomainsQueryError = RenderErrorResponseDTO;
/**
* @summary List all auth domains
*/
export function useListAuthDomains<
TData = Awaited<ReturnType<typeof listAuthDomains>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listAuthDomains>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListAuthDomainsQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary List all auth domains
*/
export const invalidateListAuthDomains = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListAuthDomainsQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint creates an auth domain
* @summary Create auth domain
*/
export const createAuthDomain = (
authtypesPostableAuthDomainDTO: AuthtypesPostableAuthDomainDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateAuthDomain200>({
url: `/api/v1/domains`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesPostableAuthDomainDTO,
signal,
});
};
export const getCreateAuthDomainMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: AuthtypesPostableAuthDomainDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: AuthtypesPostableAuthDomainDTO },
TContext
> => {
const mutationKey = ['createAuthDomain'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createAuthDomain>>,
{ data: AuthtypesPostableAuthDomainDTO }
> = (props) => {
const { data } = props ?? {};
return createAuthDomain(data);
};
return { mutationFn, ...mutationOptions };
};
export type CreateAuthDomainMutationResult = NonNullable<
Awaited<ReturnType<typeof createAuthDomain>>
>;
export type CreateAuthDomainMutationBody = AuthtypesPostableAuthDomainDTO;
export type CreateAuthDomainMutationError = RenderErrorResponseDTO;
/**
* @summary Create auth domain
*/
export const useCreateAuthDomain = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: AuthtypesPostableAuthDomainDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: AuthtypesPostableAuthDomainDTO },
TContext
> => {
const mutationOptions = getCreateAuthDomainMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint deletes an auth domain
* @summary Delete auth domain
*/
export const deleteAuthDomain = ({ id }: DeleteAuthDomainPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/domains/${id}`,
method: 'DELETE',
});
};
export const getDeleteAuthDomainMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteAuthDomain>>,
TError,
{ pathParams: DeleteAuthDomainPathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteAuthDomain>>,
TError,
{ pathParams: DeleteAuthDomainPathParameters },
TContext
> => {
const mutationKey = ['deleteAuthDomain'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteAuthDomain>>,
{ pathParams: DeleteAuthDomainPathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deleteAuthDomain(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteAuthDomainMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteAuthDomain>>
>;
export type DeleteAuthDomainMutationError = RenderErrorResponseDTO;
/**
* @summary Delete auth domain
*/
export const useDeleteAuthDomain = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteAuthDomain>>,
TError,
{ pathParams: DeleteAuthDomainPathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteAuthDomain>>,
TError,
{ pathParams: DeleteAuthDomainPathParameters },
TContext
> => {
const mutationOptions = getDeleteAuthDomainMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint updates an auth domain
* @summary Update auth domain
*/
export const updateAuthDomain = (
{ id }: UpdateAuthDomainPathParameters,
authtypesUpdateableAuthDomainDTO: AuthtypesUpdateableAuthDomainDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/domains/${id}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: authtypesUpdateableAuthDomainDTO,
});
};
export const getUpdateAuthDomainMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateAuthDomain>>,
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateAuthDomain>>,
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
> => {
const mutationKey = ['updateAuthDomain'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateAuthDomain>>,
{
pathParams: UpdateAuthDomainPathParameters;
data: AuthtypesUpdateableAuthDomainDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateAuthDomain(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateAuthDomainMutationResult = NonNullable<
Awaited<ReturnType<typeof updateAuthDomain>>
>;
export type UpdateAuthDomainMutationBody = AuthtypesUpdateableAuthDomainDTO;
export type UpdateAuthDomainMutationError = RenderErrorResponseDTO;
/**
* @summary Update auth domain
*/
export const useUpdateAuthDomain = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateAuthDomain>>,
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateAuthDomain>>,
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
> => {
const mutationOptions = getUpdateAuthDomainMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -0,0 +1,632 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
CreatePublicDashboard201,
CreatePublicDashboardPathParameters,
DashboardtypesPostablePublicDashboardDTO,
DashboardtypesUpdatablePublicDashboardDTO,
DeletePublicDashboardPathParameters,
GetPublicDashboard200,
GetPublicDashboardData200,
GetPublicDashboardDataPathParameters,
GetPublicDashboardPathParameters,
GetPublicDashboardWidgetQueryRange200,
GetPublicDashboardWidgetQueryRangePathParameters,
RenderErrorResponseDTO,
UpdatePublicDashboardPathParameters,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoints deletes the public sharing config and disables the public sharing of a dashboard
* @summary Delete public dashboard
*/
export const deletePublicDashboard = ({
id,
}: DeletePublicDashboardPathParameters) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
method: 'DELETE',
});
};
export const getDeletePublicDashboardMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deletePublicDashboard>>,
TError,
{ pathParams: DeletePublicDashboardPathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deletePublicDashboard>>,
TError,
{ pathParams: DeletePublicDashboardPathParameters },
TContext
> => {
const mutationKey = ['deletePublicDashboard'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deletePublicDashboard>>,
{ pathParams: DeletePublicDashboardPathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deletePublicDashboard(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeletePublicDashboardMutationResult = NonNullable<
Awaited<ReturnType<typeof deletePublicDashboard>>
>;
export type DeletePublicDashboardMutationError = RenderErrorResponseDTO;
/**
* @summary Delete public dashboard
*/
export const useDeletePublicDashboard = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deletePublicDashboard>>,
TError,
{ pathParams: DeletePublicDashboardPathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deletePublicDashboard>>,
TError,
{ pathParams: DeletePublicDashboardPathParameters },
TContext
> => {
const mutationOptions = getDeletePublicDashboardMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoints returns public sharing config for a dashboard
* @summary Get public dashboard
*/
export const getPublicDashboard = (
{ id }: GetPublicDashboardPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetPublicDashboard200>({
url: `/api/v1/dashboards/${id}/public`,
method: 'GET',
signal,
});
};
export const getGetPublicDashboardQueryKey = ({
id,
}: GetPublicDashboardPathParameters) => {
return ['getPublicDashboard'] as const;
};
export const getGetPublicDashboardQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboard>>,
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardPathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboard>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetPublicDashboardQueryKey({ id });
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getPublicDashboard>>
> = ({ signal }) => getPublicDashboard({ id }, signal);
return {
queryKey,
queryFn,
enabled: !!id,
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboard>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetPublicDashboardQueryResult = NonNullable<
Awaited<ReturnType<typeof getPublicDashboard>>
>;
export type GetPublicDashboardQueryError = RenderErrorResponseDTO;
/**
* @summary Get public dashboard
*/
export function useGetPublicDashboard<
TData = Awaited<ReturnType<typeof getPublicDashboard>>,
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardPathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboard>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetPublicDashboardQueryOptions({ id }, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get public dashboard
*/
export const invalidateGetPublicDashboard = async (
queryClient: QueryClient,
{ id }: GetPublicDashboardPathParameters,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetPublicDashboardQueryKey({ id }) },
options,
);
return queryClient;
};
/**
* This endpoints creates public sharing config and enables public sharing of the dashboard
* @summary Create public dashboard
*/
export const createPublicDashboard = (
{ id }: CreatePublicDashboardPathParameters,
dashboardtypesPostablePublicDashboardDTO: DashboardtypesPostablePublicDashboardDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreatePublicDashboard201>({
url: `/api/v1/dashboards/${id}/public`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: dashboardtypesPostablePublicDashboardDTO,
signal,
});
};
export const getCreatePublicDashboardMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createPublicDashboard>>,
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createPublicDashboard>>,
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
> => {
const mutationKey = ['createPublicDashboard'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createPublicDashboard>>,
{
pathParams: CreatePublicDashboardPathParameters;
data: DashboardtypesPostablePublicDashboardDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return createPublicDashboard(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type CreatePublicDashboardMutationResult = NonNullable<
Awaited<ReturnType<typeof createPublicDashboard>>
>;
export type CreatePublicDashboardMutationBody = DashboardtypesPostablePublicDashboardDTO;
export type CreatePublicDashboardMutationError = RenderErrorResponseDTO;
/**
* @summary Create public dashboard
*/
export const useCreatePublicDashboard = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createPublicDashboard>>,
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createPublicDashboard>>,
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
> => {
const mutationOptions = getCreatePublicDashboardMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoints updates the public sharing config for a dashboard
* @summary Update public dashboard
*/
export const updatePublicDashboard = (
{ id }: UpdatePublicDashboardPathParameters,
dashboardtypesUpdatablePublicDashboardDTO: DashboardtypesUpdatablePublicDashboardDTO,
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: dashboardtypesUpdatablePublicDashboardDTO,
});
};
export const getUpdatePublicDashboardMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updatePublicDashboard>>,
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updatePublicDashboard>>,
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
> => {
const mutationKey = ['updatePublicDashboard'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updatePublicDashboard>>,
{
pathParams: UpdatePublicDashboardPathParameters;
data: DashboardtypesUpdatablePublicDashboardDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updatePublicDashboard(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdatePublicDashboardMutationResult = NonNullable<
Awaited<ReturnType<typeof updatePublicDashboard>>
>;
export type UpdatePublicDashboardMutationBody = DashboardtypesUpdatablePublicDashboardDTO;
export type UpdatePublicDashboardMutationError = RenderErrorResponseDTO;
/**
* @summary Update public dashboard
*/
export const useUpdatePublicDashboard = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updatePublicDashboard>>,
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updatePublicDashboard>>,
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
> => {
const mutationOptions = getUpdatePublicDashboardMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoints returns the sanitized dashboard data for public access
* @summary Get public dashboard data
*/
export const getPublicDashboardData = (
{ id }: GetPublicDashboardDataPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetPublicDashboardData200>({
url: `/api/v1/public/dashboards/${id}`,
method: 'GET',
signal,
});
};
export const getGetPublicDashboardDataQueryKey = ({
id,
}: GetPublicDashboardDataPathParameters) => {
return ['getPublicDashboardData'] as const;
};
export const getGetPublicDashboardDataQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboardData>>,
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardDataPathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboardData>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetPublicDashboardDataQueryKey({ id });
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getPublicDashboardData>>
> = ({ signal }) => getPublicDashboardData({ id }, signal);
return {
queryKey,
queryFn,
enabled: !!id,
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboardData>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetPublicDashboardDataQueryResult = NonNullable<
Awaited<ReturnType<typeof getPublicDashboardData>>
>;
export type GetPublicDashboardDataQueryError = RenderErrorResponseDTO;
/**
* @summary Get public dashboard data
*/
export function useGetPublicDashboardData<
TData = Awaited<ReturnType<typeof getPublicDashboardData>>,
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardDataPathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboardData>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetPublicDashboardDataQueryOptions({ id }, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get public dashboard data
*/
export const invalidateGetPublicDashboardData = async (
queryClient: QueryClient,
{ id }: GetPublicDashboardDataPathParameters,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetPublicDashboardDataQueryKey({ id }) },
options,
);
return queryClient;
};
/**
* This endpoint return query range results for a widget of public dashboard
* @summary Get query range result
*/
export const getPublicDashboardWidgetQueryRange = (
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetPublicDashboardWidgetQueryRange200>({
url: `/api/v1/public/dashboards/${id}/widgets/${idx}/query_range`,
method: 'GET',
signal,
});
};
export const getGetPublicDashboardWidgetQueryRangeQueryKey = ({
id,
idx,
}: GetPublicDashboardWidgetQueryRangePathParameters) => {
return ['getPublicDashboardWidgetQueryRange'] as const;
};
export const getGetPublicDashboardWidgetQueryRangeQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError = RenderErrorResponseDTO
>(
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ??
getGetPublicDashboardWidgetQueryRangeQueryKey({ id, idx });
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>
> = ({ signal }) => getPublicDashboardWidgetQueryRange({ id, idx }, signal);
return {
queryKey,
queryFn,
enabled: !!(id && idx),
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetPublicDashboardWidgetQueryRangeQueryResult = NonNullable<
Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>
>;
export type GetPublicDashboardWidgetQueryRangeQueryError = RenderErrorResponseDTO;
/**
* @summary Get query range result
*/
export function useGetPublicDashboardWidgetQueryRange<
TData = Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError = RenderErrorResponseDTO
>(
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetPublicDashboardWidgetQueryRangeQueryOptions(
{ id, idx },
options,
);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get query range result
*/
export const invalidateGetPublicDashboardWidgetQueryRange = async (
queryClient: QueryClient,
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetPublicDashboardWidgetQueryRangeQueryKey({ id, idx }) },
options,
);
return queryClient;
};

View File

@@ -0,0 +1,109 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useQuery } from 'react-query';
import type {
InvalidateOptions,
QueryClient,
QueryFunction,
QueryKey,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type { GetFeatures200, RenderErrorResponseDTO } from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint returns the supported features and their details
* @summary Get features
*/
export const getFeatures = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetFeatures200>({
url: `/api/v2/features`,
method: 'GET',
signal,
});
};
export const getGetFeaturesQueryKey = () => {
return ['getFeatures'] as const;
};
export const getGetFeaturesQueryOptions = <
TData = Awaited<ReturnType<typeof getFeatures>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getFeatures>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetFeaturesQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof getFeatures>>> = ({
signal,
}) => getFeatures(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getFeatures>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetFeaturesQueryResult = NonNullable<
Awaited<ReturnType<typeof getFeatures>>
>;
export type GetFeaturesQueryError = RenderErrorResponseDTO;
/**
* @summary Get features
*/
export function useGetFeatures<
TData = Awaited<ReturnType<typeof getFeatures>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getFeatures>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetFeaturesQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get features
*/
export const invalidateGetFeatures = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetFeaturesQueryKey() },
options,
);
return queryClient;
};

View File

@@ -0,0 +1,746 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
CreateIngestionKey200,
CreateIngestionKeyLimit201,
CreateIngestionKeyLimitPathParameters,
DeleteIngestionKeyLimitPathParameters,
DeleteIngestionKeyPathParameters,
GatewaytypesPostableIngestionKeyDTO,
GatewaytypesPostableIngestionKeyLimitDTO,
GatewaytypesUpdatableIngestionKeyLimitDTO,
GetIngestionKeys200,
RenderErrorResponseDTO,
SearchIngestionKeys200,
UpdateIngestionKeyLimitPathParameters,
UpdateIngestionKeyPathParameters,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint returns the ingestion keys for a workspace
* @summary Get ingestion keys for workspace
*/
export const getIngestionKeys = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetIngestionKeys200>({
url: `/api/v2/gateway/ingestion_keys`,
method: 'GET',
signal,
});
};
export const getGetIngestionKeysQueryKey = () => {
return ['getIngestionKeys'] as const;
};
export const getGetIngestionKeysQueryOptions = <
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetIngestionKeysQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof getIngestionKeys>>> = ({
signal,
}) => getIngestionKeys(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetIngestionKeysQueryResult = NonNullable<
Awaited<ReturnType<typeof getIngestionKeys>>
>;
export type GetIngestionKeysQueryError = RenderErrorResponseDTO;
/**
* @summary Get ingestion keys for workspace
*/
export function useGetIngestionKeys<
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetIngestionKeysQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get ingestion keys for workspace
*/
export const invalidateGetIngestionKeys = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetIngestionKeysQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint creates an ingestion key for the workspace
* @summary Create ingestion key for workspace
*/
export const createIngestionKey = (
gatewaytypesPostableIngestionKeyDTO: GatewaytypesPostableIngestionKeyDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateIngestionKey200>({
url: `/api/v2/gateway/ingestion_keys`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: gatewaytypesPostableIngestionKeyDTO,
signal,
});
};
export const getCreateIngestionKeyMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
> => {
const mutationKey = ['createIngestionKey'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createIngestionKey>>,
{ data: GatewaytypesPostableIngestionKeyDTO }
> = (props) => {
const { data } = props ?? {};
return createIngestionKey(data);
};
return { mutationFn, ...mutationOptions };
};
export type CreateIngestionKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof createIngestionKey>>
>;
export type CreateIngestionKeyMutationBody = GatewaytypesPostableIngestionKeyDTO;
export type CreateIngestionKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Create ingestion key for workspace
*/
export const useCreateIngestionKey = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
> => {
const mutationOptions = getCreateIngestionKeyMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint deletes an ingestion key for the workspace
* @summary Delete ingestion key for workspace
*/
export const deleteIngestionKey = ({
keyId,
}: DeleteIngestionKeyPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/${keyId}`,
method: 'DELETE',
});
};
export const getDeleteIngestionKeyMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteIngestionKey>>,
TError,
{ pathParams: DeleteIngestionKeyPathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteIngestionKey>>,
TError,
{ pathParams: DeleteIngestionKeyPathParameters },
TContext
> => {
const mutationKey = ['deleteIngestionKey'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteIngestionKey>>,
{ pathParams: DeleteIngestionKeyPathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deleteIngestionKey(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteIngestionKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteIngestionKey>>
>;
export type DeleteIngestionKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Delete ingestion key for workspace
*/
export const useDeleteIngestionKey = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteIngestionKey>>,
TError,
{ pathParams: DeleteIngestionKeyPathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteIngestionKey>>,
TError,
{ pathParams: DeleteIngestionKeyPathParameters },
TContext
> => {
const mutationOptions = getDeleteIngestionKeyMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint updates an ingestion key for the workspace
* @summary Update ingestion key for workspace
*/
export const updateIngestionKey = (
{ keyId }: UpdateIngestionKeyPathParameters,
gatewaytypesPostableIngestionKeyDTO: GatewaytypesPostableIngestionKeyDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/${keyId}`,
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
data: gatewaytypesPostableIngestionKeyDTO,
});
};
export const getUpdateIngestionKeyMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateIngestionKey>>,
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateIngestionKey>>,
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
> => {
const mutationKey = ['updateIngestionKey'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateIngestionKey>>,
{
pathParams: UpdateIngestionKeyPathParameters;
data: GatewaytypesPostableIngestionKeyDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateIngestionKey(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateIngestionKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof updateIngestionKey>>
>;
export type UpdateIngestionKeyMutationBody = GatewaytypesPostableIngestionKeyDTO;
export type UpdateIngestionKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Update ingestion key for workspace
*/
export const useUpdateIngestionKey = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateIngestionKey>>,
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateIngestionKey>>,
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
> => {
const mutationOptions = getUpdateIngestionKeyMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint creates an ingestion key limit
* @summary Create limit for the ingestion key
*/
export const createIngestionKeyLimit = (
{ keyId }: CreateIngestionKeyLimitPathParameters,
gatewaytypesPostableIngestionKeyLimitDTO: GatewaytypesPostableIngestionKeyLimitDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateIngestionKeyLimit201>({
url: `/api/v2/gateway/ingestion_keys/${keyId}/limits`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: gatewaytypesPostableIngestionKeyLimitDTO,
signal,
});
};
export const getCreateIngestionKeyLimitMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
> => {
const mutationKey = ['createIngestionKeyLimit'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: GatewaytypesPostableIngestionKeyLimitDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return createIngestionKeyLimit(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type CreateIngestionKeyLimitMutationResult = NonNullable<
Awaited<ReturnType<typeof createIngestionKeyLimit>>
>;
export type CreateIngestionKeyLimitMutationBody = GatewaytypesPostableIngestionKeyLimitDTO;
export type CreateIngestionKeyLimitMutationError = RenderErrorResponseDTO;
/**
* @summary Create limit for the ingestion key
*/
export const useCreateIngestionKeyLimit = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
> => {
const mutationOptions = getCreateIngestionKeyLimitMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint deletes an ingestion key limit
* @summary Delete limit for the ingestion key
*/
export const deleteIngestionKeyLimit = ({
limitId,
}: DeleteIngestionKeyLimitPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/limits/${limitId}`,
method: 'DELETE',
});
};
export const getDeleteIngestionKeyLimitMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>,
TError,
{ pathParams: DeleteIngestionKeyLimitPathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>,
TError,
{ pathParams: DeleteIngestionKeyLimitPathParameters },
TContext
> => {
const mutationKey = ['deleteIngestionKeyLimit'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>,
{ pathParams: DeleteIngestionKeyLimitPathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deleteIngestionKeyLimit(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteIngestionKeyLimitMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>
>;
export type DeleteIngestionKeyLimitMutationError = RenderErrorResponseDTO;
/**
* @summary Delete limit for the ingestion key
*/
export const useDeleteIngestionKeyLimit = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>,
TError,
{ pathParams: DeleteIngestionKeyLimitPathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>,
TError,
{ pathParams: DeleteIngestionKeyLimitPathParameters },
TContext
> => {
const mutationOptions = getDeleteIngestionKeyLimitMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint updates an ingestion key limit
* @summary Update limit for the ingestion key
*/
export const updateIngestionKeyLimit = (
{ limitId }: UpdateIngestionKeyLimitPathParameters,
gatewaytypesUpdatableIngestionKeyLimitDTO: GatewaytypesUpdatableIngestionKeyLimitDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/limits/${limitId}`,
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
data: gatewaytypesUpdatableIngestionKeyLimitDTO,
});
};
export const getUpdateIngestionKeyLimitMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>,
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>,
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
> => {
const mutationKey = ['updateIngestionKeyLimit'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateIngestionKeyLimit(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateIngestionKeyLimitMutationResult = NonNullable<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>
>;
export type UpdateIngestionKeyLimitMutationBody = GatewaytypesUpdatableIngestionKeyLimitDTO;
export type UpdateIngestionKeyLimitMutationError = RenderErrorResponseDTO;
/**
* @summary Update limit for the ingestion key
*/
export const useUpdateIngestionKeyLimit = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>,
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>,
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
> => {
const mutationOptions = getUpdateIngestionKeyLimitMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint returns the ingestion keys for a workspace
* @summary Search ingestion keys for workspace
*/
export const searchIngestionKeys = (signal?: AbortSignal) => {
return GeneratedAPIInstance<SearchIngestionKeys200>({
url: `/api/v2/gateway/ingestion_keys/search`,
method: 'GET',
signal,
});
};
export const getSearchIngestionKeysQueryKey = () => {
return ['searchIngestionKeys'] as const;
};
export const getSearchIngestionKeysQueryOptions = <
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getSearchIngestionKeysQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof searchIngestionKeys>>
> = ({ signal }) => searchIngestionKeys(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type SearchIngestionKeysQueryResult = NonNullable<
Awaited<ReturnType<typeof searchIngestionKeys>>
>;
export type SearchIngestionKeysQueryError = RenderErrorResponseDTO;
/**
* @summary Search ingestion keys for workspace
*/
export function useSearchIngestionKeys<
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getSearchIngestionKeysQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Search ingestion keys for workspace
*/
export const invalidateSearchIngestionKeys = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getSearchIngestionKeysQueryKey() },
options,
);
return queryClient;
};

View File

@@ -0,0 +1,112 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useQuery } from 'react-query';
import type {
InvalidateOptions,
QueryClient,
QueryFunction,
QueryKey,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
GetGlobalConfig200,
RenderErrorResponseDTO,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoints returns global config
* @summary Get global config
*/
export const getGlobalConfig = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetGlobalConfig200>({
url: `/api/v1/global/config`,
method: 'GET',
signal,
});
};
export const getGetGlobalConfigQueryKey = () => {
return ['getGlobalConfig'] as const;
};
export const getGetGlobalConfigQueryOptions = <
TData = Awaited<ReturnType<typeof getGlobalConfig>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getGlobalConfig>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetGlobalConfigQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof getGlobalConfig>>> = ({
signal,
}) => getGlobalConfig(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getGlobalConfig>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetGlobalConfigQueryResult = NonNullable<
Awaited<ReturnType<typeof getGlobalConfig>>
>;
export type GetGlobalConfigQueryError = RenderErrorResponseDTO;
/**
* @summary Get global config
*/
export function useGetGlobalConfig<
TData = Awaited<ReturnType<typeof getGlobalConfig>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getGlobalConfig>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetGlobalConfigQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get global config
*/
export const invalidateGetGlobalConfig = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetGlobalConfigQueryKey() },
options,
);
return queryClient;
};

View File

@@ -0,0 +1,203 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
ListPromotedAndIndexedPaths200,
PromotetypesPromotePathDTO,
RenderErrorResponseDTO,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoints promotes and indexes paths
* @summary Promote and index paths
*/
export const listPromotedAndIndexedPaths = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListPromotedAndIndexedPaths200>({
url: `/api/v1/logs/promote_paths`,
method: 'GET',
signal,
});
};
export const getListPromotedAndIndexedPathsQueryKey = () => {
return ['listPromotedAndIndexedPaths'] as const;
};
export const getListPromotedAndIndexedPathsQueryOptions = <
TData = Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getListPromotedAndIndexedPathsQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>
> = ({ signal }) => listPromotedAndIndexedPaths(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListPromotedAndIndexedPathsQueryResult = NonNullable<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>
>;
export type ListPromotedAndIndexedPathsQueryError = RenderErrorResponseDTO;
/**
* @summary Promote and index paths
*/
export function useListPromotedAndIndexedPaths<
TData = Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListPromotedAndIndexedPathsQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Promote and index paths
*/
export const invalidateListPromotedAndIndexedPaths = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListPromotedAndIndexedPathsQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoints promotes and indexes paths
* @summary Promote and index paths
*/
export const handlePromoteAndIndexPaths = (
promotetypesPromotePathDTONull: PromotetypesPromotePathDTO[] | null,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/logs/promote_paths`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: promotetypesPromotePathDTONull,
signal,
});
};
export const getHandlePromoteAndIndexPathsMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: PromotetypesPromotePathDTO[] | null },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: PromotetypesPromotePathDTO[] | null },
TContext
> => {
const mutationKey = ['handlePromoteAndIndexPaths'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
{ data: PromotetypesPromotePathDTO[] | null }
> = (props) => {
const { data } = props ?? {};
return handlePromoteAndIndexPaths(data);
};
return { mutationFn, ...mutationOptions };
};
export type HandlePromoteAndIndexPathsMutationResult = NonNullable<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>
>;
export type HandlePromoteAndIndexPathsMutationBody =
| PromotetypesPromotePathDTO[]
| null;
export type HandlePromoteAndIndexPathsMutationError = RenderErrorResponseDTO;
/**
* @summary Promote and index paths
*/
export const useHandlePromoteAndIndexPaths = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: PromotetypesPromotePathDTO[] | null },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: PromotetypesPromotePathDTO[] | null },
TContext
> => {
const mutationOptions = getHandlePromoteAndIndexPathsMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -0,0 +1,790 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
GetMetricAlerts200,
GetMetricAlertsParams,
GetMetricAttributes200,
GetMetricDashboards200,
GetMetricDashboardsParams,
GetMetricHighlights200,
GetMetricHighlightsParams,
GetMetricMetadata200,
GetMetricMetadataParams,
GetMetricsStats200,
GetMetricsTreemap200,
MetricsexplorertypesMetricAttributesRequestDTO,
MetricsexplorertypesStatsRequestDTO,
MetricsexplorertypesTreemapRequestDTO,
MetricsexplorertypesUpdateMetricMetadataRequestDTO,
RenderErrorResponseDTO,
UpdateMetricMetadataPathParameters,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint returns associated alerts for a specified metric
* @summary Get metric alerts
*/
export const getMetricAlerts = (
params?: GetMetricAlertsParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricAlerts200>({
url: `/api/v2/metric/alerts`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricAlertsQueryKey = (params?: GetMetricAlertsParams) => {
return ['getMetricAlerts', ...(params ? [params] : [])] as const;
};
export const getGetMetricAlertsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricAlertsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetMetricAlertsQueryKey(params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof getMetricAlerts>>> = ({
signal,
}) => getMetricAlerts(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetMetricAlertsQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricAlerts>>
>;
export type GetMetricAlertsQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric alerts
*/
export function useGetMetricAlerts<
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricAlertsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricAlertsQueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get metric alerts
*/
export const invalidateGetMetricAlerts = async (
queryClient: QueryClient,
params?: GetMetricAlertsParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricAlertsQueryKey(params) },
options,
);
return queryClient;
};
/**
* This endpoint returns associated dashboards for a specified metric
* @summary Get metric dashboards
*/
export const getMetricDashboards = (
params?: GetMetricDashboardsParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricDashboards200>({
url: `/api/v2/metric/dashboards`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricDashboardsQueryKey = (
params?: GetMetricDashboardsParams,
) => {
return ['getMetricDashboards', ...(params ? [params] : [])] as const;
};
export const getGetMetricDashboardsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricDashboardsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetMetricDashboardsQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMetricDashboards>>
> = ({ signal }) => getMetricDashboards(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetMetricDashboardsQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricDashboards>>
>;
export type GetMetricDashboardsQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric dashboards
*/
export function useGetMetricDashboards<
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricDashboardsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricDashboardsQueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get metric dashboards
*/
export const invalidateGetMetricDashboards = async (
queryClient: QueryClient,
params?: GetMetricDashboardsParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricDashboardsQueryKey(params) },
options,
);
return queryClient;
};
/**
* This endpoint returns highlights like number of datapoints, totaltimeseries, active time series, last received time for a specified metric
* @summary Get metric highlights
*/
export const getMetricHighlights = (
params?: GetMetricHighlightsParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricHighlights200>({
url: `/api/v2/metric/highlights`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricHighlightsQueryKey = (
params?: GetMetricHighlightsParams,
) => {
return ['getMetricHighlights', ...(params ? [params] : [])] as const;
};
export const getGetMetricHighlightsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricHighlightsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetMetricHighlightsQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMetricHighlights>>
> = ({ signal }) => getMetricHighlights(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetMetricHighlightsQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricHighlights>>
>;
export type GetMetricHighlightsQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric highlights
*/
export function useGetMetricHighlights<
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricHighlightsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricHighlightsQueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get metric highlights
*/
export const invalidateGetMetricHighlights = async (
queryClient: QueryClient,
params?: GetMetricHighlightsParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricHighlightsQueryKey(params) },
options,
);
return queryClient;
};
/**
* This endpoint helps to update metadata information like metric description, unit, type, temporality, monotonicity for a specified metric
* @summary Update metric metadata
*/
export const updateMetricMetadata = (
{ metricName }: UpdateMetricMetadataPathParameters,
metricsexplorertypesUpdateMetricMetadataRequestDTO: MetricsexplorertypesUpdateMetricMetadataRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<string>({
url: `/api/v2/metrics/${metricName}/metadata`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesUpdateMetricMetadataRequestDTO,
signal,
});
};
export const getUpdateMetricMetadataMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMetricMetadata>>,
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateMetricMetadata>>,
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
> => {
const mutationKey = ['updateMetricMetadata'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateMetricMetadata>>,
{
pathParams: UpdateMetricMetadataPathParameters;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateMetricMetadata(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateMetricMetadataMutationResult = NonNullable<
Awaited<ReturnType<typeof updateMetricMetadata>>
>;
export type UpdateMetricMetadataMutationBody = MetricsexplorertypesUpdateMetricMetadataRequestDTO;
export type UpdateMetricMetadataMutationError = RenderErrorResponseDTO;
/**
* @summary Update metric metadata
*/
export const useUpdateMetricMetadata = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMetricMetadata>>,
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateMetricMetadata>>,
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
> => {
const mutationOptions = getUpdateMetricMetadataMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint returns attribute keys and their unique values for a specified metric
* @summary Get metric attributes
*/
export const getMetricAttributes = (
metricsexplorertypesMetricAttributesRequestDTO: MetricsexplorertypesMetricAttributesRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricAttributes200>({
url: `/api/v2/metrics/attributes`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesMetricAttributesRequestDTO,
signal,
});
};
export const getGetMetricAttributesMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricAttributes>>,
TError,
{ data: MetricsexplorertypesMetricAttributesRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof getMetricAttributes>>,
TError,
{ data: MetricsexplorertypesMetricAttributesRequestDTO },
TContext
> => {
const mutationKey = ['getMetricAttributes'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof getMetricAttributes>>,
{ data: MetricsexplorertypesMetricAttributesRequestDTO }
> = (props) => {
const { data } = props ?? {};
return getMetricAttributes(data);
};
return { mutationFn, ...mutationOptions };
};
export type GetMetricAttributesMutationResult = NonNullable<
Awaited<ReturnType<typeof getMetricAttributes>>
>;
export type GetMetricAttributesMutationBody = MetricsexplorertypesMetricAttributesRequestDTO;
export type GetMetricAttributesMutationError = RenderErrorResponseDTO;
/**
* @summary Get metric attributes
*/
export const useGetMetricAttributes = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricAttributes>>,
TError,
{ data: MetricsexplorertypesMetricAttributesRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof getMetricAttributes>>,
TError,
{ data: MetricsexplorertypesMetricAttributesRequestDTO },
TContext
> => {
const mutationOptions = getGetMetricAttributesMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint returns metadata information like metric description, unit, type, temporality, monotonicity for a specified metric
* @summary Get metric metadata
*/
export const getMetricMetadata = (
params?: GetMetricMetadataParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricMetadata200>({
url: `/api/v2/metrics/metadata`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricMetadataQueryKey = (
params?: GetMetricMetadataParams,
) => {
return ['getMetricMetadata', ...(params ? [params] : [])] as const;
};
export const getGetMetricMetadataQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricMetadataParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetMetricMetadataQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMetricMetadata>>
> = ({ signal }) => getMetricMetadata(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetMetricMetadataQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricMetadata>>
>;
export type GetMetricMetadataQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric metadata
*/
export function useGetMetricMetadata<
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
TError = RenderErrorResponseDTO
>(
params?: GetMetricMetadataParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricMetadataQueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get metric metadata
*/
export const invalidateGetMetricMetadata = async (
queryClient: QueryClient,
params?: GetMetricMetadataParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricMetadataQueryKey(params) },
options,
);
return queryClient;
};
/**
* This endpoint provides list of metrics with their number of samples and timeseries for the given time range
* @summary Get metrics statistics
*/
export const getMetricsStats = (
metricsexplorertypesStatsRequestDTO: MetricsexplorertypesStatsRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricsStats200>({
url: `/api/v2/metrics/stats`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesStatsRequestDTO,
signal,
});
};
export const getGetMetricsStatsMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
> => {
const mutationKey = ['getMetricsStats'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof getMetricsStats>>,
{ data: MetricsexplorertypesStatsRequestDTO }
> = (props) => {
const { data } = props ?? {};
return getMetricsStats(data);
};
return { mutationFn, ...mutationOptions };
};
export type GetMetricsStatsMutationResult = NonNullable<
Awaited<ReturnType<typeof getMetricsStats>>
>;
export type GetMetricsStatsMutationBody = MetricsexplorertypesStatsRequestDTO;
export type GetMetricsStatsMutationError = RenderErrorResponseDTO;
/**
* @summary Get metrics statistics
*/
export const useGetMetricsStats = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
> => {
const mutationOptions = getGetMetricsStatsMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint returns a treemap visualization showing the proportional distribution of metrics by sample count or time series count
* @summary Get metrics treemap
*/
export const getMetricsTreemap = (
metricsexplorertypesTreemapRequestDTO: MetricsexplorertypesTreemapRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricsTreemap200>({
url: `/api/v2/metrics/treemap`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesTreemapRequestDTO,
signal,
});
};
export const getGetMetricsTreemapMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
> => {
const mutationKey = ['getMetricsTreemap'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof getMetricsTreemap>>,
{ data: MetricsexplorertypesTreemapRequestDTO }
> = (props) => {
const { data } = props ?? {};
return getMetricsTreemap(data);
};
return { mutationFn, ...mutationOptions };
};
export type GetMetricsTreemapMutationResult = NonNullable<
Awaited<ReturnType<typeof getMetricsTreemap>>
>;
export type GetMetricsTreemapMutationBody = MetricsexplorertypesTreemapRequestDTO;
export type GetMetricsTreemapMutationError = RenderErrorResponseDTO;
/**
* @summary Get metrics treemap
*/
export const useGetMetricsTreemap = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
> => {
const mutationOptions = getGetMetricsTreemapMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -0,0 +1,198 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
GetMyOrganization200,
RenderErrorResponseDTO,
TypesOrganizationDTO,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint returns the organization I belong to
* @summary Get my organization
*/
export const getMyOrganization = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetMyOrganization200>({
url: `/api/v2/orgs/me`,
method: 'GET',
signal,
});
};
export const getGetMyOrganizationQueryKey = () => {
return ['getMyOrganization'] as const;
};
export const getGetMyOrganizationQueryOptions = <
TData = Awaited<ReturnType<typeof getMyOrganization>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMyOrganization>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetMyOrganizationQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMyOrganization>>
> = ({ signal }) => getMyOrganization(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMyOrganization>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetMyOrganizationQueryResult = NonNullable<
Awaited<ReturnType<typeof getMyOrganization>>
>;
export type GetMyOrganizationQueryError = RenderErrorResponseDTO;
/**
* @summary Get my organization
*/
export function useGetMyOrganization<
TData = Awaited<ReturnType<typeof getMyOrganization>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMyOrganization>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMyOrganizationQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get my organization
*/
export const invalidateGetMyOrganization = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMyOrganizationQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint updates the organization I belong to
* @summary Update my organization
*/
export const updateMyOrganization = (
typesOrganizationDTO: TypesOrganizationDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/orgs/me`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: typesOrganizationDTO,
});
};
export const getUpdateMyOrganizationMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: TypesOrganizationDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: TypesOrganizationDTO },
TContext
> => {
const mutationKey = ['updateMyOrganization'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateMyOrganization>>,
{ data: TypesOrganizationDTO }
> = (props) => {
const { data } = props ?? {};
return updateMyOrganization(data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateMyOrganizationMutationResult = NonNullable<
Awaited<ReturnType<typeof updateMyOrganization>>
>;
export type UpdateMyOrganizationMutationBody = TypesOrganizationDTO;
export type UpdateMyOrganizationMutationError = RenderErrorResponseDTO;
/**
* @summary Update my organization
*/
export const useUpdateMyOrganization = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: TypesOrganizationDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: TypesOrganizationDTO },
TContext
> => {
const mutationOptions = getUpdateMyOrganizationMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -0,0 +1,612 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
GetOrgPreference200,
GetOrgPreferencePathParameters,
GetUserPreference200,
GetUserPreferencePathParameters,
ListOrgPreferences200,
ListUserPreferences200,
PreferencetypesUpdatablePreferenceDTO,
RenderErrorResponseDTO,
UpdateOrgPreferencePathParameters,
UpdateUserPreferencePathParameters,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint lists all org preferences
* @summary List org preferences
*/
export const listOrgPreferences = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListOrgPreferences200>({
url: `/api/v1/org/preferences`,
method: 'GET',
signal,
});
};
export const getListOrgPreferencesQueryKey = () => {
return ['listOrgPreferences'] as const;
};
export const getListOrgPreferencesQueryOptions = <
TData = Awaited<ReturnType<typeof listOrgPreferences>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listOrgPreferences>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListOrgPreferencesQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof listOrgPreferences>>
> = ({ signal }) => listOrgPreferences(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listOrgPreferences>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListOrgPreferencesQueryResult = NonNullable<
Awaited<ReturnType<typeof listOrgPreferences>>
>;
export type ListOrgPreferencesQueryError = RenderErrorResponseDTO;
/**
* @summary List org preferences
*/
export function useListOrgPreferences<
TData = Awaited<ReturnType<typeof listOrgPreferences>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listOrgPreferences>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListOrgPreferencesQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary List org preferences
*/
export const invalidateListOrgPreferences = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListOrgPreferencesQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint returns the org preference by name
* @summary Get org preference
*/
export const getOrgPreference = (
{ name }: GetOrgPreferencePathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetOrgPreference200>({
url: `/api/v1/org/preferences/${name}`,
method: 'GET',
signal,
});
};
export const getGetOrgPreferenceQueryKey = ({
name,
}: GetOrgPreferencePathParameters) => {
return ['getOrgPreference'] as const;
};
export const getGetOrgPreferenceQueryOptions = <
TData = Awaited<ReturnType<typeof getOrgPreference>>,
TError = RenderErrorResponseDTO
>(
{ name }: GetOrgPreferencePathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getOrgPreference>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetOrgPreferenceQueryKey({ name });
const queryFn: QueryFunction<Awaited<ReturnType<typeof getOrgPreference>>> = ({
signal,
}) => getOrgPreference({ name }, signal);
return {
queryKey,
queryFn,
enabled: !!name,
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getOrgPreference>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetOrgPreferenceQueryResult = NonNullable<
Awaited<ReturnType<typeof getOrgPreference>>
>;
export type GetOrgPreferenceQueryError = RenderErrorResponseDTO;
/**
* @summary Get org preference
*/
export function useGetOrgPreference<
TData = Awaited<ReturnType<typeof getOrgPreference>>,
TError = RenderErrorResponseDTO
>(
{ name }: GetOrgPreferencePathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getOrgPreference>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetOrgPreferenceQueryOptions({ name }, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get org preference
*/
export const invalidateGetOrgPreference = async (
queryClient: QueryClient,
{ name }: GetOrgPreferencePathParameters,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetOrgPreferenceQueryKey({ name }) },
options,
);
return queryClient;
};
/**
* This endpoint updates the org preference by name
* @summary Update org preference
*/
export const updateOrgPreference = (
{ name }: UpdateOrgPreferencePathParameters,
preferencetypesUpdatablePreferenceDTO: PreferencetypesUpdatablePreferenceDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/org/preferences/${name}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: preferencetypesUpdatablePreferenceDTO,
});
};
export const getUpdateOrgPreferenceMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateOrgPreference>>,
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateOrgPreference>>,
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
const mutationKey = ['updateOrgPreference'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateOrgPreference>>,
{
pathParams: UpdateOrgPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateOrgPreference(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateOrgPreferenceMutationResult = NonNullable<
Awaited<ReturnType<typeof updateOrgPreference>>
>;
export type UpdateOrgPreferenceMutationBody = PreferencetypesUpdatablePreferenceDTO;
export type UpdateOrgPreferenceMutationError = RenderErrorResponseDTO;
/**
* @summary Update org preference
*/
export const useUpdateOrgPreference = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateOrgPreference>>,
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateOrgPreference>>,
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
const mutationOptions = getUpdateOrgPreferenceMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint lists all user preferences
* @summary List user preferences
*/
export const listUserPreferences = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListUserPreferences200>({
url: `/api/v1/user/preferences`,
method: 'GET',
signal,
});
};
export const getListUserPreferencesQueryKey = () => {
return ['listUserPreferences'] as const;
};
export const getListUserPreferencesQueryOptions = <
TData = Awaited<ReturnType<typeof listUserPreferences>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listUserPreferences>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListUserPreferencesQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof listUserPreferences>>
> = ({ signal }) => listUserPreferences(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listUserPreferences>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListUserPreferencesQueryResult = NonNullable<
Awaited<ReturnType<typeof listUserPreferences>>
>;
export type ListUserPreferencesQueryError = RenderErrorResponseDTO;
/**
* @summary List user preferences
*/
export function useListUserPreferences<
TData = Awaited<ReturnType<typeof listUserPreferences>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listUserPreferences>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListUserPreferencesQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary List user preferences
*/
export const invalidateListUserPreferences = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListUserPreferencesQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint returns the user preference by name
* @summary Get user preference
*/
export const getUserPreference = (
{ name }: GetUserPreferencePathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetUserPreference200>({
url: `/api/v1/user/preferences/${name}`,
method: 'GET',
signal,
});
};
export const getGetUserPreferenceQueryKey = ({
name,
}: GetUserPreferencePathParameters) => {
return ['getUserPreference'] as const;
};
export const getGetUserPreferenceQueryOptions = <
TData = Awaited<ReturnType<typeof getUserPreference>>,
TError = RenderErrorResponseDTO
>(
{ name }: GetUserPreferencePathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getUserPreference>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetUserPreferenceQueryKey({ name });
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getUserPreference>>
> = ({ signal }) => getUserPreference({ name }, signal);
return {
queryKey,
queryFn,
enabled: !!name,
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getUserPreference>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetUserPreferenceQueryResult = NonNullable<
Awaited<ReturnType<typeof getUserPreference>>
>;
export type GetUserPreferenceQueryError = RenderErrorResponseDTO;
/**
* @summary Get user preference
*/
export function useGetUserPreference<
TData = Awaited<ReturnType<typeof getUserPreference>>,
TError = RenderErrorResponseDTO
>(
{ name }: GetUserPreferencePathParameters,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getUserPreference>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetUserPreferenceQueryOptions({ name }, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get user preference
*/
export const invalidateGetUserPreference = async (
queryClient: QueryClient,
{ name }: GetUserPreferencePathParameters,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetUserPreferenceQueryKey({ name }) },
options,
);
return queryClient;
};
/**
* This endpoint updates the user preference by name
* @summary Update user preference
*/
export const updateUserPreference = (
{ name }: UpdateUserPreferencePathParameters,
preferencetypesUpdatablePreferenceDTO: PreferencetypesUpdatablePreferenceDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/user/preferences/${name}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: preferencetypesUpdatablePreferenceDTO,
});
};
export const getUpdateUserPreferenceMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateUserPreference>>,
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateUserPreference>>,
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
const mutationKey = ['updateUserPreference'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateUserPreference>>,
{
pathParams: UpdateUserPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateUserPreference(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateUserPreferenceMutationResult = NonNullable<
Awaited<ReturnType<typeof updateUserPreference>>
>;
export type UpdateUserPreferenceMutationBody = PreferencetypesUpdatablePreferenceDTO;
export type UpdateUserPreferenceMutationError = RenderErrorResponseDTO;
/**
* @summary Update user preference
*/
export const useUpdateUserPreference = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateUserPreference>>,
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateUserPreference>>,
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
const mutationOptions = getUpdateUserPreferenceMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -0,0 +1,662 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import { useMutation, useQuery } from 'react-query';
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type {
AuthtypesPostableEmailPasswordSessionDTO,
AuthtypesPostableRotateTokenDTO,
CreateSessionByEmailPassword200,
CreateSessionByGoogleCallback303,
CreateSessionByOIDCCallback303,
CreateSessionBySAMLCallback303,
CreateSessionBySAMLCallbackBody,
CreateSessionBySAMLCallbackParams,
GetSessionContext200,
RenderErrorResponseDTO,
RotateSession200,
} from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../index';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint creates a session for a user using google callback
* @summary Create session by google callback
*/
export const createSessionByGoogleCallback = (signal?: AbortSignal) => {
return GeneratedAPIInstance<unknown>({
url: `/api/v1/complete/google`,
method: 'GET',
signal,
});
};
export const getCreateSessionByGoogleCallbackQueryKey = () => {
return ['createSessionByGoogleCallback'] as const;
};
export const getCreateSessionByGoogleCallbackQueryOptions = <
TData = Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError = CreateSessionByGoogleCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getCreateSessionByGoogleCallbackQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>
> = ({ signal }) => createSessionByGoogleCallback(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type CreateSessionByGoogleCallbackQueryResult = NonNullable<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>
>;
export type CreateSessionByGoogleCallbackQueryError =
| CreateSessionByGoogleCallback303
| RenderErrorResponseDTO;
/**
* @summary Create session by google callback
*/
export function useCreateSessionByGoogleCallback<
TData = Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError = CreateSessionByGoogleCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getCreateSessionByGoogleCallbackQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Create session by google callback
*/
export const invalidateCreateSessionByGoogleCallback = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getCreateSessionByGoogleCallbackQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint creates a session for a user using oidc callback
* @summary Create session by oidc callback
*/
export const createSessionByOIDCCallback = (signal?: AbortSignal) => {
return GeneratedAPIInstance<unknown>({
url: `/api/v1/complete/oidc`,
method: 'GET',
signal,
});
};
export const getCreateSessionByOIDCCallbackQueryKey = () => {
return ['createSessionByOIDCCallback'] as const;
};
export const getCreateSessionByOIDCCallbackQueryOptions = <
TData = Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError = CreateSessionByOIDCCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getCreateSessionByOIDCCallbackQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>
> = ({ signal }) => createSessionByOIDCCallback(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type CreateSessionByOIDCCallbackQueryResult = NonNullable<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>
>;
export type CreateSessionByOIDCCallbackQueryError =
| CreateSessionByOIDCCallback303
| RenderErrorResponseDTO;
/**
* @summary Create session by oidc callback
*/
export function useCreateSessionByOIDCCallback<
TData = Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError = CreateSessionByOIDCCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getCreateSessionByOIDCCallbackQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Create session by oidc callback
*/
export const invalidateCreateSessionByOIDCCallback = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getCreateSessionByOIDCCallbackQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint creates a session for a user using saml callback
* @summary Create session by saml callback
*/
export const createSessionBySAMLCallback = (
createSessionBySAMLCallbackBody: CreateSessionBySAMLCallbackBody,
params?: CreateSessionBySAMLCallbackParams,
signal?: AbortSignal,
) => {
const formUrlEncoded = new URLSearchParams();
if (createSessionBySAMLCallbackBody.RelayState !== undefined) {
formUrlEncoded.append(
`RelayState`,
createSessionBySAMLCallbackBody.RelayState,
);
}
if (createSessionBySAMLCallbackBody.SAMLResponse !== undefined) {
formUrlEncoded.append(
`SAMLResponse`,
createSessionBySAMLCallbackBody.SAMLResponse,
);
}
return GeneratedAPIInstance<unknown>({
url: `/api/v1/complete/saml`,
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formUrlEncoded,
params,
signal,
});
};
export const getCreateSessionBySAMLCallbackMutationOptions = <
TError = CreateSessionBySAMLCallback303 | RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
> => {
const mutationKey = ['createSessionBySAMLCallback'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
{
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
}
> = (props) => {
const { data, params } = props ?? {};
return createSessionBySAMLCallback(data, params);
};
return { mutationFn, ...mutationOptions };
};
export type CreateSessionBySAMLCallbackMutationResult = NonNullable<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>
>;
export type CreateSessionBySAMLCallbackMutationBody = CreateSessionBySAMLCallbackBody;
export type CreateSessionBySAMLCallbackMutationError =
| CreateSessionBySAMLCallback303
| RenderErrorResponseDTO;
/**
* @summary Create session by saml callback
*/
export const useCreateSessionBySAMLCallback = <
TError = CreateSessionBySAMLCallback303 | RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
> => {
const mutationOptions = getCreateSessionBySAMLCallbackMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint deletes the session
* @summary Delete session
*/
export const deleteSession = () => {
return GeneratedAPIInstance<void>({
url: `/api/v2/sessions`,
method: 'DELETE',
});
};
export const getDeleteSessionMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteSession>>,
TError,
void,
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteSession>>,
TError,
void,
TContext
> => {
const mutationKey = ['deleteSession'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteSession>>,
void
> = () => {
return deleteSession();
};
return { mutationFn, ...mutationOptions };
};
export type DeleteSessionMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteSession>>
>;
export type DeleteSessionMutationError = RenderErrorResponseDTO;
/**
* @summary Delete session
*/
export const useDeleteSession = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteSession>>,
TError,
void,
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteSession>>,
TError,
void,
TContext
> => {
const mutationOptions = getDeleteSessionMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint returns the context for the session
* @summary Get session context
*/
export const getSessionContext = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetSessionContext200>({
url: `/api/v2/sessions/context`,
method: 'GET',
signal,
});
};
export const getGetSessionContextQueryKey = () => {
return ['getSessionContext'] as const;
};
export const getGetSessionContextQueryOptions = <
TData = Awaited<ReturnType<typeof getSessionContext>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getSessionContext>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetSessionContextQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getSessionContext>>
> = ({ signal }) => getSessionContext(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getSessionContext>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetSessionContextQueryResult = NonNullable<
Awaited<ReturnType<typeof getSessionContext>>
>;
export type GetSessionContextQueryError = RenderErrorResponseDTO;
/**
* @summary Get session context
*/
export function useGetSessionContext<
TData = Awaited<ReturnType<typeof getSessionContext>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getSessionContext>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetSessionContextQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get session context
*/
export const invalidateGetSessionContext = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetSessionContextQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint creates a session for a user using email and password.
* @summary Create session by email and password
*/
export const createSessionByEmailPassword = (
authtypesPostableEmailPasswordSessionDTO: AuthtypesPostableEmailPasswordSessionDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateSessionByEmailPassword200>({
url: `/api/v2/sessions/email_password`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesPostableEmailPasswordSessionDTO,
signal,
});
};
export const getCreateSessionByEmailPasswordMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
> => {
const mutationKey = ['createSessionByEmailPassword'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
{ data: AuthtypesPostableEmailPasswordSessionDTO }
> = (props) => {
const { data } = props ?? {};
return createSessionByEmailPassword(data);
};
return { mutationFn, ...mutationOptions };
};
export type CreateSessionByEmailPasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof createSessionByEmailPassword>>
>;
export type CreateSessionByEmailPasswordMutationBody = AuthtypesPostableEmailPasswordSessionDTO;
export type CreateSessionByEmailPasswordMutationError = RenderErrorResponseDTO;
/**
* @summary Create session by email and password
*/
export const useCreateSessionByEmailPassword = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
> => {
const mutationOptions = getCreateSessionByEmailPasswordMutationOptions(
options,
);
return useMutation(mutationOptions);
};
/**
* This endpoint rotates the session
* @summary Rotate session
*/
export const rotateSession = (
authtypesPostableRotateTokenDTO: AuthtypesPostableRotateTokenDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<RotateSession200>({
url: `/api/v2/sessions/rotate`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesPostableRotateTokenDTO,
signal,
});
};
export const getRotateSessionMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: AuthtypesPostableRotateTokenDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: AuthtypesPostableRotateTokenDTO },
TContext
> => {
const mutationKey = ['rotateSession'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof rotateSession>>,
{ data: AuthtypesPostableRotateTokenDTO }
> = (props) => {
const { data } = props ?? {};
return rotateSession(data);
};
return { mutationFn, ...mutationOptions };
};
export type RotateSessionMutationResult = NonNullable<
Awaited<ReturnType<typeof rotateSession>>
>;
export type RotateSessionMutationBody = AuthtypesPostableRotateTokenDTO;
export type RotateSessionMutationError = RenderErrorResponseDTO;
/**
* @summary Rotate session
*/
export const useRotateSession = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: AuthtypesPostableRotateTokenDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: AuthtypesPostableRotateTokenDTO },
TContext
> => {
const mutationOptions = getRotateSessionMutationOptions(options);
return useMutation(mutationOptions);
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -229,6 +229,17 @@ export const GatewayApiV2Instance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${gatewayApiV2}`,
});
// generated API Instance
export const GeneratedAPIInstance = axios.create({
baseURL: ENVIRONMENT.baseURL,
});
GeneratedAPIInstance.interceptors.request.use(interceptorsRequestResponse);
GeneratedAPIInstance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
);
GatewayApiV2Instance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,

View File

@@ -75,7 +75,9 @@ export const getK8sClustersList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -83,7 +83,9 @@ export const getK8sDaemonSetsList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -82,7 +82,9 @@ export const getK8sDeploymentsList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -82,7 +82,9 @@ export const getK8sJobsList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -73,7 +73,9 @@ export const getK8sNamespacesList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -77,7 +77,9 @@ export const getK8sNodesList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -113,7 +113,9 @@ export const getK8sPodsList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -98,7 +98,9 @@ export const getK8sVolumesList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -81,7 +81,9 @@ export const getK8sStatefulSetsList = async (
...props.filters,
items: props.filters.items.reduce<typeof props.filters.items>(
(acc, item) => {
if (item.value === undefined) return acc;
if (item.value === undefined) {
return acc;
}
if (
item.key &&
typeof item.key === 'object' &&

View File

@@ -68,8 +68,12 @@ export function mapPanelTypeToRequestType(panelType: PANEL_TYPES): RequestType {
* Gets signal type from data source
*/
function getSignalType(dataSource: string): 'traces' | 'logs' | 'metrics' {
if (dataSource === 'traces') return 'traces';
if (dataSource === 'logs') return 'logs';
if (dataSource === 'traces') {
return 'traces';
}
if (dataSource === 'logs') {
return 'logs';
}
return 'metrics';
}
@@ -509,7 +513,9 @@ function reduceQueriesToObject(
// eslint-disable-line @typescript-eslint/no-explicit-any
const legends: Record<string, string> = {};
const queries = queryArray.reduce((acc, queryItem) => {
if (!queryItem.query) return acc;
if (!queryItem.query) {
return acc;
}
acc[queryItem.name] = queryItem;
legends[queryItem.name] = queryItem.legend;
return acc;

View File

@@ -15,6 +15,7 @@ import '@signozhq/button';
import '@signozhq/calendar';
import '@signozhq/callout';
import '@signozhq/checkbox';
import '@signozhq/combobox';
import '@signozhq/command';
import '@signozhq/design-tokens';
import '@signozhq/input';

View File

@@ -20,7 +20,6 @@ import {
getQueueOverview,
QueueOverviewResponse,
} from 'api/messagingQueues/celery/getQueueOverview';
import { isNumber } from 'chart.js/helpers';
import { ResizeTable } from 'components/ResizeTable';
import { LOCALSTORAGE } from 'constants/localStorage';
import { QueryParams } from 'constants/query';
@@ -33,6 +32,7 @@ import { useMutation } from 'react-query';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
import { formatNumericValue } from 'utils/numericUtils';
const INITIAL_PAGE_SIZE = 20;
@@ -60,8 +60,12 @@ function ProgressRender(item: string | number): JSX.Element {
size="small"
strokeColor={((): string => {
const cpuPercent = percent;
if (cpuPercent >= 90) return Color.BG_SAKURA_500;
if (cpuPercent >= 60) return Color.BG_AMBER_500;
if (cpuPercent >= 90) {
return Color.BG_SAKURA_500;
}
if (cpuPercent >= 60) {
return Color.BG_AMBER_500;
}
return Color.BG_FOREST_500;
})()}
className="progress-bar"
@@ -239,10 +243,7 @@ function getColumns(data: RowData[]): TableColumnsType<RowData> {
const bValue = Number(b.p95_latency);
return aValue - bValue;
},
render: (value: number | string): string => {
if (!isNumber(value)) return value.toString();
return (typeof value === 'string' ? parseFloat(value) : value).toFixed(3);
},
render: formatNumericValue,
},
{
title: 'THROUGHPUT (ops/s)',
@@ -257,10 +258,7 @@ function getColumns(data: RowData[]): TableColumnsType<RowData> {
const bValue = Number(b.throughput);
return aValue - bValue;
},
render: (value: number | string): string => {
if (!isNumber(value)) return value.toString();
return (typeof value === 'string' ? parseFloat(value) : value).toFixed(3);
},
render: formatNumericValue,
},
];
}
@@ -337,7 +335,9 @@ function makeFilters(urlQuery: URLSearchParams): Filter[] {
return filterConfigs
.map(({ paramName, operator, key }) => {
const value = urlQuery.get(paramName);
if (!value) return null;
if (!value) {
return null;
}
return {
key: {
@@ -464,7 +464,9 @@ export default function CeleryOverviewTable({
const getFilteredData = useCallback(
(data: RowData[]): RowData[] => {
if (!searchText) return data;
if (!searchText) {
return data;
}
const searchLower = searchText.toLowerCase();
return data.filter((record) =>

View File

@@ -69,7 +69,9 @@ export function useGetAllFilters(props: Filters): GetAllFiltersResponse {
const uniqueValues = [
...new Set(
responses.flatMap(({ payload }) => {
if (!payload) return [];
if (!payload) {
return [];
}
const dataType = filterAttributeKeyDataType || DataTypes.String;
const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType];

View File

@@ -11,12 +11,24 @@ import { v4 as uuidv4 } from 'uuid';
export const getStepInterval = (startTime: number, endTime: number): number => {
const diffInMinutes = (endTime - startTime) / 1000000 / (60 * 1000); // Convert to minutes
if (diffInMinutes <= 15) return 60; // 15 min or less
if (diffInMinutes <= 30) return 60; // 30 min or less
if (diffInMinutes <= 60) return 120; // 1 hour or less
if (diffInMinutes <= 360) return 520; // 6 hours or less
if (diffInMinutes <= 1440) return 2440; // 1 day or less
if (diffInMinutes <= 10080) return 10080; // 1 week or less
if (diffInMinutes <= 15) {
return 60;
} // 15 min or less
if (diffInMinutes <= 30) {
return 60;
} // 30 min or less
if (diffInMinutes <= 60) {
return 120;
} // 1 hour or less
if (diffInMinutes <= 360) {
return 520;
} // 6 hours or less
if (diffInMinutes <= 1440) {
return 2440;
} // 1 day or less
if (diffInMinutes <= 10080) {
return 10080;
} // 1 week or less
return 54000; // More than a week (use monthly interval)
};

View File

@@ -49,8 +49,12 @@ export const useGetValueFromWidget = (
const isError = queries.some((query) => query.isError);
const values = queries.map((query) => {
if (query.isLoading) return 'Loading...';
if (query.isError) return 'Error';
if (query.isLoading) {
return 'Loading...';
}
if (query.isError) {
return 'Error';
}
const value = parseFloat(
query.data?.payload?.data?.newResult?.data?.result?.[0]?.series?.[0]

View File

@@ -49,7 +49,9 @@ export function useNavigateToExplorer(): (
...(item.filters?.items || []),
...selectedFilters,
].filter((item) => {
if (seen.has(item.id)) return false;
if (seen.has(item.id)) {
return false;
}
seen.add(item.id);
return true;
});

View File

@@ -440,9 +440,12 @@ function ClientSideQBSearch(
const values: Array<string | number | boolean> = [];
const { tagValue } = getTagToken(searchValue);
if (isArray(tagValue)) {
if (!isEmpty(tagValue[tagValue.length - 1]))
if (!isEmpty(tagValue[tagValue.length - 1])) {
values.push(tagValue[tagValue.length - 1]);
} else if (!isEmpty(tagValue)) values.push(tagValue);
}
} else if (!isEmpty(tagValue)) {
values.push(tagValue);
}
const currentAttributeValues =
attributeValues?.stringAttributeValues ||
@@ -556,7 +559,9 @@ function ClientSideQBSearch(
disabled={isDisabled}
$isEnabled={!!searchValue}
onClick={(): void => {
if (!isDisabled) tagEditHandler(value);
if (!isDisabled) {
tagEditHandler(value);
}
}}
>
{chipValue}

View File

@@ -12,7 +12,7 @@ import {
FixedDurationSuggestionOptions,
Options,
RelativeDurationSuggestionOptions,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/constants';
import dayjs from 'dayjs';
import { isValidShortHandDateTimeFormat } from 'lib/getMinMax';
import { defaultTo, isFunction, noop } from 'lodash-es';

View File

@@ -8,11 +8,11 @@ import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { RelativeDurationSuggestionOptions } from 'container/TopNav/DateTimeSelectionV2/constants';
import {
LexicalContext,
Option,
RelativeDurationSuggestionOptions,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/types';
import dayjs from 'dayjs';
import { Clock, PenLine, TriangleAlertIcon } from 'lucide-react';
import { useTimezone } from 'providers/Timezone';

View File

@@ -8,7 +8,7 @@ import {
CustomTimeType,
LexicalContext,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/types';
import dayjs, { Dayjs } from 'dayjs';
import { useTimezone } from 'providers/Timezone';
import { Dispatch, SetStateAction, useMemo } from 'react';

View File

@@ -38,7 +38,9 @@ const normalizeTimezoneName = (timezone: string): string => {
};
const formatOffset = (offsetMinutes: number): string => {
if (offsetMinutes === 0) return 'UTC';
if (offsetMinutes === 0) {
return 'UTC';
}
const hours = Math.floor(Math.abs(offsetMinutes) / 60);
const minutes = Math.abs(offsetMinutes) % 60;

View File

@@ -16,7 +16,9 @@ function DraggableTableRow({
const handleDrop = useCallback(
(item: { index: number }) => {
if (moveRow) moveRow(item.index, index);
if (moveRow) {
moveRow(item.index, index);
}
},
[moveRow, index],
);

View File

@@ -13,9 +13,13 @@ function Editor({
const isDarkMode = useIsDarkMode();
const onChangeHandler = (newValue?: string): void => {
if (readOnly) return;
if (readOnly) {
return;
}
if (typeof newValue === 'string' && onChange) onChange(newValue);
if (typeof newValue === 'string' && onChange) {
onChange(newValue);
}
};
const editorOptions = useMemo(

View File

@@ -52,7 +52,9 @@ function MenuItemGenerator({
const onMenuItemSelectHandler = useCallback(
({ key }: { key: string }): void => {
const currentViewDetails = getViewDetailsUsingViewKey(key, viewData);
if (!currentViewDetails) return;
if (!currentViewDetails) {
return;
}
const { query, name, id, panelType: currentPanelType } = currentViewDetails;
handleExplorerTabChange(currentPanelType, {

View File

@@ -28,9 +28,15 @@ export const getYAxisFormattedValue = (
const numValue = parseFloat(value);
// Handle non-numeric or special values first.
if (isNaN(numValue)) return 'NaN';
if (numValue === Infinity) return '';
if (numValue === -Infinity) return '-∞';
if (isNaN(numValue)) {
return 'NaN';
}
if (numValue === Infinity) {
return '∞';
}
if (numValue === -Infinity) {
return '-∞';
}
// For all other standard formats, delegate to grafana/data's built-in formatter.
const computeDecimals = (): number | undefined => {
@@ -41,8 +47,12 @@ export const getYAxisFormattedValue = (
};
const fallbackFormat = (): string => {
if (precision === PrecisionOptionsEnum.FULL) return numValue.toString();
if (precision === 0) return Math.round(numValue).toString();
if (precision === PrecisionOptionsEnum.FULL) {
return numValue.toString();
}
if (precision === 0) {
return Math.round(numValue).toString();
}
return precision !== undefined
? numValue
.toFixed(precision)

View File

@@ -13,7 +13,7 @@ import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
import {
CustomTimeType,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/types';
import TraceExplorerControls from 'container/TracesExplorer/Controls';
import { PER_PAGE_OPTIONS } from 'container/TracesExplorer/ListView/configs';
import { TracesLoading } from 'container/TracesExplorer/TraceLoading/TraceLoading';

View File

@@ -24,7 +24,7 @@ import { INFRA_MONITORING_K8S_PARAMS_KEYS } from 'container/InfraMonitoringK8s/c
import {
CustomTimeType,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/types';
import { useIsDarkMode } from 'hooks/useDarkMode';
import useUrlQuery from 'hooks/useUrlQuery';
import GetMinMax from 'lib/getMinMax';
@@ -450,8 +450,12 @@ function HostMetricsDetails({
size="small"
strokeColor={((): string => {
const cpuPercent = Number((host.cpu * 100).toFixed(1));
if (cpuPercent >= 90) return Color.BG_SAKURA_500;
if (cpuPercent >= 60) return Color.BG_AMBER_500;
if (cpuPercent >= 90) {
return Color.BG_SAKURA_500;
}
if (cpuPercent >= 60) {
return Color.BG_AMBER_500;
}
return Color.BG_FOREST_500;
})()}
className="progress-bar"
@@ -463,8 +467,12 @@ function HostMetricsDetails({
size="small"
strokeColor={((): string => {
const memoryPercent = Number((host.memory * 100).toFixed(1));
if (memoryPercent >= 90) return Color.BG_CHERRY_500;
if (memoryPercent >= 60) return Color.BG_AMBER_500;
if (memoryPercent >= 90) {
return Color.BG_CHERRY_500;
}
if (memoryPercent >= 60) {
return Color.BG_AMBER_500;
}
return Color.BG_FOREST_500;
})()}
className="progress-bar"

View File

@@ -5,7 +5,7 @@ import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
import {
CustomTimeType,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/types';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useMemo } from 'react';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';

View File

@@ -12,7 +12,7 @@ import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
import {
CustomTimeType,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config';
} from 'container/TopNav/DateTimeSelectionV2/types';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useResizeObserver } from 'hooks/useDimensions';

View File

@@ -22,7 +22,9 @@ export default function WaitlistFragment({
const [isSuccess, setIsSuccess] = useState(false);
const handleJoinWaitlist = (): void => {
if (!user || !user.email) return;
if (!user || !user.email) {
return;
}
setIsSubmitting(true);

View File

@@ -29,8 +29,9 @@ function QueryBuilderSearchWrapper({
(!tagFiltersLength && (!filters || !filters.items.length)) ||
tagFiltersLength === filters?.items.length ||
!contextQuery
)
) {
return;
}
const nextQuery: Query = {
...contextQuery,
@@ -48,7 +49,9 @@ function QueryBuilderSearchWrapper({
};
// eslint-disable-next-line react/jsx-no-useless-fragment
if (!contextQuery || !isEdit) return <></>;
if (!contextQuery || !isEdit) {
return <></>;
}
return (
<QueryBuilderSearch

View File

@@ -75,7 +75,9 @@ function LogDetailInner({
const { stagedQuery, updateAllQueriesOperators } = useQueryBuilder();
const listQuery = useMemo(() => {
if (!stagedQuery || stagedQuery.builder.queryData.length < 1) return null;
if (!stagedQuery || stagedQuery.builder.queryData.length < 1) {
return null;
}
return stagedQuery.builder.queryData.find((item) => !item.disabled) || null;
}, [stagedQuery]);
@@ -153,7 +155,9 @@ function LogDetailInner({
(value: string, queryIndex: number) => {
// update the query at the given index
setContextQuery((prev) => {
if (!prev) return prev;
if (!prev) {
return prev;
}
return {
...prev,

View File

@@ -127,7 +127,9 @@ function RawLogView({
const handleClickExpand = useCallback(
(event: MouseEvent) => {
if (isReadOnly) return;
if (isReadOnly) {
return;
}
// Use custom click handler if provided, otherwise use default behavior
if (onLogClick) {

View File

@@ -52,7 +52,9 @@ function OptionsMenu({
const onChange = useCallback(
(key: LogViewMode) => {
if (!format) return;
if (!format) {
return;
}
format.onChange(key);
},
@@ -148,7 +150,9 @@ function OptionsMenu({
}
const handleKeyDown = (e: KeyboardEvent): void => {
if (!selectedValue) return;
if (!selectedValue) {
return;
}
const optionsData = addColumn?.options || [];

View File

@@ -13,7 +13,9 @@ function MessageTip({
message,
action,
}: MessageTipProps): JSX.Element | null {
if (!show) return null;
if (!show) {
return null;
}
return (
<StyledAlert showIcon description={message} type="info" action={action} />

View File

@@ -165,7 +165,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
return;
}
if (!onChange) return;
if (!onChange) {
return;
}
// Case 1: Cleared (empty array or undefined)
if (!newValue || currentNewValue.length === 0) {
@@ -327,7 +329,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
* Selects all chips
*/
const selectAllChips = useCallback((): void => {
if (selectedValues.length === 0) return;
if (selectedValues.length === 0) {
return;
}
// When maxTagCount is set, only select visible chips
const visibleCount =
@@ -394,7 +398,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
* Handle copy event
*/
const handleCopy = useCallback((): void => {
if (selectedChips.length === 0) return;
if (selectedChips.length === 0) {
return;
}
const selectedTexts = selectedChips
.sort((a, b) => a - b)
@@ -409,7 +415,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
* Handle cut event
*/
const handleCut = useCallback((): void => {
if (selectedChips.length === 0) return;
if (selectedChips.length === 0) {
return;
}
// First copy the content
handleCopy();
@@ -577,7 +585,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
}
}
if (onSearch) onSearch(trimmedValue);
if (onSearch) {
onSearch(trimmedValue);
}
},
[
onSearch,
@@ -596,7 +606,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
*/
const highlightMatchedText = useCallback(
(text: string, searchQuery: string): React.ReactNode => {
if (!searchQuery || !highlightSearch) return text;
if (!searchQuery || !highlightSearch) {
return text;
}
try {
const parts = text.split(
@@ -632,7 +644,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
// Adjusted handleSelectAll for internal change handler
const handleSelectAll = useCallback((): void => {
if (!options) return;
if (!options) {
return;
}
if (isAllSelected) {
// If all are selected, deselect all
@@ -658,7 +672,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
const handleItemSelection = (source?: string): void => {
// Special handling for ALL option is done by the caller
if (!option.value) return;
if (!option.value) {
return;
}
if (source === 'option') {
if (
@@ -792,7 +808,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
// Helper function to get visible chip indices
const getVisibleChipIndices = useCallback((): number[] => {
// If no values, return empty array
if (selectedValues.length === 0) return [];
if (selectedValues.length === 0) {
return [];
}
// If maxTagCount is set and greater than 0, only return the first maxTagCount indices
const visibleCount =
@@ -836,7 +854,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
// Get flattened list of all selectable options
const getFlatOptions = (): OptionData[] => {
if (!visibleOptions) return [];
if (!visibleOptions) {
return [];
}
const flatList: OptionData[] = [];
const hasAll = enableAllSelection && !searchText;
@@ -1845,7 +1865,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
// but base indices/visibility on the original `selectedValues`
if (!isAllSelected) {
const index = selectedValues.indexOf(value);
if (index === -1) return <div style={{ display: 'none' }} />; // Should not happen if value comes from displayValue
if (index === -1) {
return <div style={{ display: 'none' }} />;
} // Should not happen if value comes from displayValue
const isActive = index === activeChipIndex;
const isSelected = selectedChips.includes(index);
@@ -1931,7 +1953,9 @@ const CustomMultiSelect: React.FC<CustomMultiSelectProps> = ({
// Normal clear behavior
handleInternalChange([], true);
if (onClear) onClear();
if (onClear) {
onClear();
}
}, [onClear, handleInternalChange, allOptionShown, isAllSelected]);
// ===== Component Rendering =====

View File

@@ -147,7 +147,9 @@ const CustomSelect: React.FC<CustomSelectProps> = ({
*/
const highlightMatchedText = useCallback(
(text: string, searchQuery: string): React.ReactNode => {
if (!searchQuery || !highlightSearch) return text;
if (!searchQuery || !highlightSearch) {
return text;
}
try {
const parts = text.split(
@@ -257,8 +259,12 @@ const CustomSelect: React.FC<CustomSelectProps> = ({
<CloseOutlined
onClick={(e): void => {
e.stopPropagation();
if (onChange) onChange(undefined, []);
if (onClear) onClear();
if (onChange) {
onChange(undefined, []);
}
if (onClear) {
onClear();
}
}}
/>
),
@@ -280,7 +286,9 @@ const CustomSelect: React.FC<CustomSelectProps> = ({
setActiveOptionIndex(0);
}
if (onSearch) onSearch(trimmedValue);
if (onSearch) {
onSearch(trimmedValue);
}
},
[onSearch, isOpen],
);
@@ -301,7 +309,9 @@ const CustomSelect: React.FC<CustomSelectProps> = ({
if (isOpen) {
// Get flattened list of all selectable options
const getFlatOptions = (): OptionData[] => {
if (!filteredOptions) return [];
if (!filteredOptions) {
return [];
}
const flatList: OptionData[] = [];

View File

@@ -204,7 +204,9 @@ describe('CustomMultiSelect Component', () => {
options.forEach((option) => {
const text = option.textContent || '';
if (text.includes('Option 2')) foundOption2 = true;
if (text.includes('Option 2')) {
foundOption2 = true;
}
});
expect(foundOption2).toBe(true);

View File

@@ -26,7 +26,9 @@ export const prioritizeOrAddOptionForSingleSelect = (
(subOption) => subOption.value === value,
);
if (extractedOption) foundOption = extractedOption;
if (extractedOption) {
foundOption = extractedOption;
}
// Keep the group if it still has remaining options
return remainingSubOptions.length > 0
@@ -115,7 +117,9 @@ export const filterOptionsBySearch = (
options: OptionData[],
searchText: string,
): OptionData[] => {
if (!searchText.trim()) return options;
if (!searchText.trim()) {
return options;
}
const lowerSearchText = searchText.toLowerCase();

View File

@@ -25,10 +25,14 @@ function mockOverflow(clientWidth: number, scrollWidth: number): void {
function queryTooltipInner(): HTMLElement | null {
// find element that has role="tooltip" (could be the inner itself)
const tooltip = document.querySelector<HTMLElement>('[role="tooltip"]');
if (!tooltip) return document.querySelector(TOOLTIP_INNER_SELECTOR);
if (!tooltip) {
return document.querySelector(TOOLTIP_INNER_SELECTOR);
}
// if the role element is already the inner, return it; otherwise return its descendant
if (tooltip.classList.contains('ant-tooltip-inner')) return tooltip;
if (tooltip.classList.contains('ant-tooltip-inner')) {
return tooltip;
}
return (
(tooltip.querySelector(TOOLTIP_INNER_SELECTOR) as HTMLElement) ??
document.querySelector(TOOLTIP_INNER_SELECTOR)
@@ -52,7 +56,9 @@ describe('OverflowInputToolTip', () => {
});
const tooltipInner = queryTooltipInner();
if (!tooltipInner) throw new Error('Tooltip inner not found');
if (!tooltipInner) {
throw new Error('Tooltip inner not found');
}
expect(
within(tooltipInner).getByText('Very long overflowing text'),
).toBeInTheDocument();

View File

@@ -157,7 +157,9 @@ function HavingFilter({
// Helper to check if we're after an operator
const isAfterOperator = (tokens: string[]): boolean => {
if (tokens.length === 0) return false;
if (tokens.length === 0) {
return false;
}
const lastToken = tokens[tokens.length - 1];
// Check if the last token is exactly an operator or ends with an operator and space
return havingOperators.some((op) => {

View File

@@ -84,25 +84,33 @@ function getFunctionContextAtCursor(
let funcName: string | null = null;
let parenStack = 0;
for (let i = cursorPos - 1; i >= 0; i--) {
if (text[i] === ')') parenStack++;
else if (text[i] === '(') {
if (text[i] === ')') {
parenStack++;
} else if (text[i] === '(') {
if (parenStack === 0) {
openParenIndex = i;
const before = text.slice(0, i);
const match = before.match(/(\w+)\s*$/);
if (match) funcName = match[1].toLowerCase();
if (match) {
funcName = match[1].toLowerCase();
}
break;
}
parenStack--;
}
}
if (openParenIndex === -1 || !funcName) return null;
if (openParenIndex === -1 || !funcName) {
return null;
}
// Scan forwards to find the matching closing parenthesis
let closeParenIndex = -1;
let depth = 1;
for (let j = openParenIndex + 1; j < text.length; j++) {
if (text[j] === '(') depth++;
else if (text[j] === ')') depth--;
if (text[j] === '(') {
depth++;
} else if (text[j] === ')') {
depth--;
}
if (depth === 0) {
closeParenIndex = j;
break;
@@ -277,10 +285,14 @@ function QueryAggregationSelect({
// Transaction filter to limit aggregations
const transactionFilterExtension = useMemo(() => {
if (maxAggregations === undefined) return [];
if (maxAggregations === undefined) {
return [];
}
return EditorState.transactionFilter.of((tr: Transaction) => {
if (!tr.docChanged) return tr;
if (!tr.docChanged) {
return tr;
}
const regex = /([a-zA-Z_][\w]*)\s*\(([^)]*)\)/g;
const oldMatches = [
@@ -425,7 +437,9 @@ function QueryAggregationSelect({
() =>
Object.keys(aggregateAttributeData?.data.data.keys || {}).flatMap((key) => {
const attributeKeys = aggregateAttributeData?.data.data.keys[key];
if (!attributeKeys) return [];
if (!attributeKeys) {
return [];
}
return attributeKeys.map((attributeKey) => ({
label: attributeKey.name,
@@ -482,7 +496,9 @@ function QueryAggregationSelect({
const start = match.index ?? 0;
return cursorPos >= start && cursorPos <= start + match[0].length;
});
if (!isEditing) return null;
if (!isEditing) {
return null;
}
}
}
@@ -523,7 +539,9 @@ function QueryAggregationSelect({
const argsString = doc.slice(lastOpenParen + 1, cursorPos);
argsString.split(',').forEach((arg) => {
const trimmed = arg.trim();
if (trimmed) usedArgs.add(trimmed);
if (trimmed) {
usedArgs.add(trimmed);
}
});
}

View File

@@ -31,7 +31,9 @@ function TraceOperatorSection({
]);
const traceOperatorWarning = useMemo(() => {
if (currentQuery.builder.queryData.length === 0) return '';
if (currentQuery.builder.queryData.length === 0) {
return '';
}
const firstQuery = currentQuery.builder.queryData[0];
return `Currently, you are only seeing results from query ${firstQuery.queryName}. Add a trace operator to combine results of multiple queries.`;
}, [currentQuery]);

View File

@@ -135,10 +135,14 @@ function QuerySearch({
const updateEditorValue = useCallback(
(value: string, options: { skipOnChange?: boolean } = {}): void => {
const view = editorRef.current;
if (!view) return;
if (!view) {
return;
}
const currentValue = view.state.doc.toString();
if (currentValue === value) return;
if (currentValue === value) {
return;
}
if (options.skipOnChange) {
isProgrammaticChangeRef.current = true;
@@ -165,7 +169,9 @@ function QuerySearch({
useEffect(
() => {
if (!isEditorReady) return;
if (!isEditorReady) {
return;
}
const newExpression = queryData.filter?.expression || '';
const currentExpression = getCurrentExpression();
@@ -236,7 +242,9 @@ function QuerySearch({
const toggleSuggestions = useCallback(
(timeout?: number) => {
const timeoutId = setTimeout(() => {
if (!editorRef.current) return;
if (!editorRef.current) {
return;
}
if (isFocused) {
startCompletion(editorRef.current);
} else {
@@ -281,7 +289,9 @@ function QuerySearch({
options.forEach((opt) => merged.set(opt.label, opt));
if (searchText && lastKeyRef.current !== searchText) {
(keySuggestions || []).forEach((opt) => {
if (!merged.has(opt.label)) merged.set(opt.label, opt);
if (!merged.has(opt.label)) {
merged.set(opt.label, opt);
}
});
}
setKeySuggestions(Array.from(merged.values()));
@@ -346,7 +356,9 @@ function QuerySearch({
// Helper function to check if operator is for list operations (IN, NOT IN, etc.)
const isListOperator = (op: string | undefined): boolean => {
if (!op) return false;
if (!op) {
return false;
}
return op.toUpperCase() === 'IN' || op.toUpperCase() === 'NOT IN';
};
@@ -400,8 +412,9 @@ function QuerySearch({
!key ||
(key === activeKey && !isLoadingSuggestions && !fetchingComplete) ||
!isMountedRef.current
)
) {
return;
}
// Set loading state and store the key we're fetching for
setIsLoadingSuggestions(true);
@@ -538,7 +551,9 @@ function QuerySearch({
);
const handleUpdate = useCallback((viewUpdate: { view: EditorView }): void => {
if (!isMountedRef.current) return;
if (!isMountedRef.current) {
return;
}
if (!editorRef.current) {
editorRef.current = viewUpdate.view;
@@ -582,13 +597,21 @@ function QuerySearch({
| 'bracketList'
| null = null;
if (context.isInKey) newContextType = 'key';
else if (context.isInOperator) newContextType = 'operator';
else if (context.isInValue) newContextType = 'value';
else if (context.isInConjunction) newContextType = 'conjunction';
else if (context.isInFunction) newContextType = 'function';
else if (context.isInParenthesis) newContextType = 'parenthesis';
else if (context.isInBracketList) newContextType = 'bracketList';
if (context.isInKey) {
newContextType = 'key';
} else if (context.isInOperator) {
newContextType = 'operator';
} else if (context.isInValue) {
newContextType = 'value';
} else if (context.isInConjunction) {
newContextType = 'conjunction';
} else if (context.isInFunction) {
newContextType = 'function';
} else if (context.isInParenthesis) {
newContextType = 'parenthesis';
} else if (context.isInBracketList) {
newContextType = 'bracketList';
}
setQueryContext(context);
@@ -637,7 +660,9 @@ function QuerySearch({
// Helper function to render a badge for the current context mode
const renderContextBadge = (): JSX.Element => {
if (!editingMode) return <Tag>Unknown</Tag>;
if (!editingMode) {
return <Tag>Unknown</Tag>;
}
switch (editingMode) {
case 'key':
@@ -665,7 +690,9 @@ function QuerySearch({
// This matches words before the cursor position
// eslint-disable-next-line no-useless-escape
const word = context.matchBefore(/[a-zA-Z0-9_.:/?&=#%\-\[\]]*/);
if (word?.from === word?.to && !context.explicit) return null;
if (word?.from === word?.to && !context.explicit) {
return null;
}
// Get current query from editor
const currentExpression = getCurrentExpression();
@@ -1228,7 +1255,9 @@ function QuerySearch({
}, [isFocused, toggleSuggestions]);
useEffect(() => {
if (!queryContext) return;
if (!queryContext) {
return;
}
// Trigger suggestions based on context
if (editorRef.current) {
toggleSuggestions(10);

View File

@@ -104,7 +104,9 @@ function TraceOperatorEditor({
const toggleSuggestions = useCallback(
(timeout?: number) => {
const timeoutId = setTimeout(() => {
if (!editorRef.current) return;
if (!editorRef.current) {
return;
}
if (isFocused) {
startCompletion(editorRef.current);
} else {
@@ -152,7 +154,9 @@ function TraceOperatorEditor({
// This matches words before the cursor position
// eslint-disable-next-line no-useless-escape
const word = context.matchBefore(/[a-zA-Z0-9_.:/?&=#%\-\[\]]*/);
if (word?.from === word?.to && !context.explicit) return null;
if (word?.from === word?.to && !context.explicit) {
return null;
}
// Get the trace operator context at the cursor position
const queryContext = getTraceOperatorContextAtCursor(value, cursorPos.ch);

View File

@@ -375,7 +375,9 @@ export function getTraceOperatorContextAtCursor(
let lastTokenBeforeCursor: IToken | null = null;
for (let i = 0; i < allTokens.length; i++) {
const token = allTokens[i];
if (token.type === TraceOperatorGrammarLexer.EOF) continue;
if (token.type === TraceOperatorGrammarLexer.EOF) {
continue;
}
if (token.stop < cursorIndex || token.stop + 1 === cursorIndex) {
lastTokenBeforeCursor = token;
@@ -390,7 +392,9 @@ export function getTraceOperatorContextAtCursor(
let exactToken: IToken | null = null;
for (let i = 0; i < allTokens.length; i++) {
const token = allTokens[i];
if (token.type === TraceOperatorGrammarLexer.EOF) continue;
if (token.type === TraceOperatorGrammarLexer.EOF) {
continue;
}
if (token.start <= cursorIndex && cursorIndex <= token.stop + 1) {
exactToken = token;

View File

@@ -7,8 +7,9 @@ export const getInvolvedQueriesInTraceOperator = (
!traceOperators ||
traceOperators.length === 0 ||
traceOperators.length > 1
)
) {
return [];
}
const currentTraceOperator = traceOperators[0];

View File

@@ -190,7 +190,9 @@ const formatValuesForFilter = (
export const convertExpressionToFilters = (
expression: string,
): TagFilterItem[] => {
if (!expression) return [];
if (!expression) {
return [];
}
const queryPairs = extractQueryPairs(expression);
const filters: TagFilterItem[] = [];
@@ -271,7 +273,9 @@ export const convertFiltersToExpressionWithExistingQuery = (
const { key, op, value } = filter;
// Skip invalid filters with no key
if (!key) return;
if (!key) {
return;
}
let shouldAddToNonExisting = true; // Flag to decide if the filter should be added to non-existing filters
const sanitizedOperator = op.trim().toUpperCase();
@@ -545,7 +549,9 @@ export const removeKeysFromExpression = (
? existingQueryPairs.filter((pair) => {
const pairKey = pair.key?.trim().toLowerCase();
const matchesKey = pairKey === `${key}`.trim().toLowerCase();
if (!matchesKey) return false;
if (!matchesKey) {
return false;
}
const value = pair.value?.toString().trim();
return value && value.includes('$');
})

View File

@@ -43,6 +43,12 @@ interface MockFilterConfig {
}
const SERVICE_NAME_KEY = 'service.name';
const OTEL_DEMO = 'otel-demo';
const SAMPLE_FLASK = 'sample-flask';
const OTLP_PYTHON = 'otlp-python';
const MQ_KAFKA = 'mq-kafka';
const MOCK_SERVICE_NAMES = [MQ_KAFKA, OTEL_DEMO, OTLP_PYTHON, SAMPLE_FLASK];
const createMockFilter = (
overrides: Partial<MockFilterConfig> = {},
@@ -76,7 +82,7 @@ const createMockQueryBuilderData = (hasActiveFilters = false): any => ({
type: 'resource',
},
op: 'in',
value: ['otel-demo', 'sample-flask'],
value: [OTEL_DEMO, SAMPLE_FLASK],
},
]
: [],
@@ -93,24 +99,32 @@ describe('CheckboxFilter - User Flows', () => {
// Reset all mocks
jest.clearAllMocks();
// Default mock implementations using the same structure as existing tests
mockUseGetAggregateValues.mockReturnValue({
// Default mock implementations for useGetAggregateValues
mockUseGetAggregateValues.mockReturnValue(({
data: {
payload: {
stringAttributeValues: [
'mq-kafka',
'otel-demo',
'otlp-python',
'sample-flask',
],
stringAttributeValues: MOCK_SERVICE_NAMES,
},
},
isLoading: false,
} as UseQueryResult<SuccessResponse<IAttributeValuesResponse>>);
refetch: jest.fn(),
} as unknown) as UseQueryResult<SuccessResponse<IAttributeValuesResponse>>);
// Default mock implementations for useGetQueryKeyValueSuggestions
// Returns data in the format expected by the hook
mockUseGetQueryKeyValueSuggestions.mockReturnValue({
data: null,
data: {
data: {
data: {
values: {
stringValues: MOCK_SERVICE_NAMES,
numberValues: [],
},
},
},
},
isLoading: false,
refetch: jest.fn(),
} as any);
// Setup MSW server for API calls

View File

@@ -12,7 +12,10 @@ import {
QuickFiltersSource,
} from 'components/QuickFilters/types';
import { OPERATORS } from 'constants/antlrQueryConstants';
import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder';
import {
DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY,
PANEL_TYPES,
} from 'constants/queryBuilder';
import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig';
import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
import { useGetAggregateValues } from 'hooks/queryBuilder/useGetAggregateValues';
@@ -62,26 +65,44 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
lastUsedQuery,
currentQuery,
redirectWithQueryBuilderData,
panelType,
} = useQueryBuilder();
// Determine if we're in ListView mode
const isListView = panelType === PANEL_TYPES.LIST;
// In ListView mode, use index 0 for most sources; for TRACES_EXPLORER, use lastUsedQuery
// Otherwise use lastUsedQuery for non-ListView modes
const activeQueryIndex = useMemo(() => {
if (isListView) {
return source === QuickFiltersSource.TRACES_EXPLORER
? lastUsedQuery || 0
: 0;
}
return lastUsedQuery || 0;
}, [isListView, source, lastUsedQuery]);
// Check if this filter has active filters in the query
const isSomeFilterPresentForCurrentAttribute = useMemo(
() =>
currentQuery.builder.queryData?.[
lastUsedQuery || 0
activeQueryIndex
]?.filters?.items?.some((item) =>
isEqual(item.key?.key, filter.attributeKey.key),
),
[currentQuery.builder.queryData, lastUsedQuery, filter.attributeKey.key],
[currentQuery.builder.queryData, activeQueryIndex, filter.attributeKey.key],
);
// Derive isOpen from filter state + user action
const isOpen = useMemo(() => {
// If user explicitly toggled, respect that
if (userToggleState !== null) return userToggleState;
if (userToggleState !== null) {
return userToggleState;
}
// Auto-open if this filter has active filters in the query
if (isSomeFilterPresentForCurrentAttribute) return true;
if (isSomeFilterPresentForCurrentAttribute) {
return true;
}
// Otherwise use default behavior (first 2 filters open)
return filter.defaultOpen;
@@ -169,7 +190,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
false,
);
const filterSync = currentQuery?.builder.queryData?.[
lastUsedQuery || 0
activeQueryIndex
]?.filters?.items.find((item) =>
isEqual(item.key?.key, filter.attributeKey.key),
);
@@ -209,19 +230,19 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
attributeValues,
currentQuery?.builder.queryData,
filter.attributeKey,
lastUsedQuery,
activeQueryIndex,
]);
// disable the filter when there are multiple entries of the same attribute key present in the filter bar
const isFilterDisabled = useMemo(
() =>
(currentQuery?.builder?.queryData?.[
lastUsedQuery || 0
activeQueryIndex
]?.filters?.items?.filter((item) =>
isEqual(item.key?.key, filter.attributeKey.key),
)?.length || 0) > 1,
[currentQuery?.builder?.queryData, lastUsedQuery, filter.attributeKey],
[currentQuery?.builder?.queryData, activeQueryIndex, filter.attributeKey],
);
// variable to check if the current filter has multiple values to its name in the key op value section
@@ -260,7 +281,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
filters: {
...item.filters,
items:
idx === lastUsedQuery
idx === activeQueryIndex
? item.filters?.items?.filter(
(fil) => !isEqual(fil.key?.key, filter.attributeKey.key),
) || []
@@ -284,7 +305,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
isOnlyOrAllClicked: boolean,
// eslint-disable-next-line sonarjs/cognitive-complexity
): void => {
const query = cloneDeep(currentQuery.builder.queryData?.[lastUsedQuery || 0]);
const query = cloneDeep(currentQuery.builder.queryData?.[activeQueryIndex]);
// if only or all are clicked we do not need to worry about anything just override whatever we have
// by either adding a new IN operator value clause in case of ONLY or remove everything we have for ALL.
@@ -515,7 +536,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
...currentQuery.builder,
queryData: [
...currentQuery.builder.queryData.map((q, idx) => {
if (idx === lastUsedQuery) {
if (idx === activeQueryIndex) {
return query;
}
return q;

View File

@@ -2,7 +2,11 @@
import './Duration.styles.scss';
import { Button, Collapse } from 'antd';
import { IQuickFiltersConfig } from 'components/QuickFilters/types';
import {
IQuickFiltersConfig,
QuickFiltersSource,
} from 'components/QuickFilters/types';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { getMs } from 'container/Trace/Filters/Panel/PanelBody/Duration/util';
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
@@ -27,9 +31,11 @@ export type FilterType = Record<
function Duration({
filter,
onFilterChange,
source,
}: {
filter: IQuickFiltersConfig;
onFilterChange?: (query: Query) => void;
source?: QuickFiltersSource;
}): JSX.Element {
const [selectedFilters, setSelectedFilters] = useState<
Record<
@@ -41,13 +47,31 @@ function Duration({
filter.defaultOpen ? 'durationNano' : '',
]);
const { currentQuery, redirectWithQueryBuilderData } = useQueryBuilder();
const {
currentQuery,
redirectWithQueryBuilderData,
lastUsedQuery,
panelType,
} = useQueryBuilder();
const compositeQuery = useGetCompositeQueryParam();
const isListView = panelType === PANEL_TYPES.LIST;
// In ListView mode, use index 0 for most sources; for TRACES_EXPLORER, use lastUsedQuery
// Otherwise use lastUsedQuery for non-ListView modes
const activeQueryIndex = useMemo(() => {
if (isListView) {
return source === QuickFiltersSource.TRACES_EXPLORER
? lastUsedQuery || 0
: 0;
}
return lastUsedQuery || 0;
}, [isListView, source, lastUsedQuery]);
// eslint-disable-next-line sonarjs/cognitive-complexity
const syncSelectedFilters = useMemo((): FilterType => {
const filters = compositeQuery?.builder.queryData?.[0].filters;
const filters =
compositeQuery?.builder.queryData?.[activeQueryIndex]?.filters;
if (!filters) {
return {} as FilterType;
}
@@ -95,7 +119,7 @@ function Duration({
return acc;
}, {} as FilterType);
}, [compositeQuery]);
}, [compositeQuery, activeQueryIndex]);
useEffect(() => {
if (!isEqual(syncSelectedFilters, selectedFilters)) {
@@ -195,20 +219,25 @@ function Duration({
...currentQuery,
builder: {
...currentQuery.builder,
queryData: currentQuery.builder.queryData.map((item) => ({
...item,
filters: {
...item.filters,
items: props?.resetAll
? []
: (unionTagFilterItems(item.filters?.items || [], preparePostData())
.map((item) =>
item.key?.key === props?.clearByType ? undefined : item,
)
.filter((i) => i) as TagFilterItem[]),
op: item.filters?.op || 'AND',
},
})),
queryData: currentQuery.builder.queryData.map((item, idx) => {
if (idx !== activeQueryIndex) {
return item;
}
return {
...item,
filters: {
...item.filters,
items: props?.resetAll
? []
: (unionTagFilterItems(item.filters?.items || [], preparePostData())
.map((item) =>
item.key?.key === props?.clearByType ? undefined : item,
)
.filter((i) => i) as TagFilterItem[]),
op: item.filters?.op || 'AND',
},
};
}),
},
};
@@ -221,14 +250,18 @@ function Duration({
) {
return;
}
if (onFilterChange && isFunction(onFilterChange)) {
onFilterChange(preparedQuery);
} else {
redirectWithQueryBuilderData(preparedQuery);
}
},
[currentQuery, redirectWithQueryBuilderData, selectedFilters],
[
currentQuery,
redirectWithQueryBuilderData,
selectedFilters,
activeQueryIndex,
],
);
useEffect(() => {

View File

@@ -38,9 +38,11 @@
font-weight: 400;
line-height: 18px;
letter-spacing: -0.07px;
min-width: 70px;
}
.sync-tag {
.sync-tag,
.select-box {
display: flex;
padding: 5px 9px;
flex-direction: column;
@@ -58,6 +60,19 @@
line-height: 18px;
text-transform: uppercase;
}
.select-box {
display: flex;
padding: 2px 5px;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 3px;
height: 30px;
}
.select-box-item {
min-width: 60px;
}
}
.right-actions {

View File

@@ -5,6 +5,14 @@ import {
SyncOutlined,
VerticalAlignTopOutlined,
} from '@ant-design/icons';
import {
Combobox,
ComboboxCommand,
ComboboxContent,
ComboboxItem,
ComboboxList,
ComboboxTrigger,
} from '@signozhq/combobox';
import { Skeleton, Switch, Tooltip, Typography } from 'antd';
import getLocalStorageKey from 'api/browser/localstorage/get';
import setLocalStorageKey from 'api/browser/localstorage/set';
@@ -12,9 +20,10 @@ import logEvent from 'api/common/logEvent';
import classNames from 'classnames';
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import { LOCALSTORAGE } from 'constants/localStorage';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { useApiMonitoringParams } from 'container/ApiMonitoring/queryParams';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { cloneDeep, isFunction, isNull } from 'lodash-es';
import { isFunction, isNull } from 'lodash-es';
import { Frown, Settings2 as SettingsIcon } from 'lucide-react';
import { useAppContext } from 'providers/App/App';
import { useMemo, useState } from 'react';
@@ -57,8 +66,40 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
const {
currentQuery,
lastUsedQuery,
setLastUsedQuery,
redirectWithQueryBuilderData,
panelType,
} = useQueryBuilder();
const [open, setOpen] = useState(false);
// Sync lastUsedQuery when queries change (e.g., after deletion)
const validQueryIndex = useMemo(
() =>
Math.min(
lastUsedQuery || 0,
(currentQuery?.builder?.queryData?.length || 1) - 1,
),
[lastUsedQuery, currentQuery?.builder?.queryData?.length],
);
// Determine if we're in ListView mode
const isListView = panelType === PANEL_TYPES.LIST;
// Generate query options based on available queries
const queryOptions = useMemo(() => {
if (!currentQuery?.builder?.queryData) {
return [];
}
return currentQuery.builder.queryData.map((query, index) => ({
label: query.queryName || String.fromCharCode(65 + index),
value: index,
}));
}, [currentQuery?.builder?.queryData]);
// Show dropdown in ListView only for TRACES_EXPLORER source
const shouldShowDropdownInListView =
isListView && source === QuickFiltersSource.TRACES_EXPLORER;
const showAnnouncementTooltip = useMemo(() => {
const localStorageValue = getLocalStorageKey(
@@ -70,36 +111,45 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
return true;
}, []);
const activeQueryIndex = useMemo(() => {
if (isListView) {
return source === QuickFiltersSource.TRACES_EXPLORER
? lastUsedQuery || 0
: 0;
}
return lastUsedQuery || 0;
}, [isListView, source, lastUsedQuery]);
// clear all the filters for the query which is in sync with filters
const handleReset = (): void => {
const updatedQuery = cloneDeep(
currentQuery?.builder.queryData?.[lastUsedQuery || 0],
);
const activeQuery = currentQuery?.builder.queryData?.[activeQueryIndex];
if (!updatedQuery) {
if (!activeQuery) {
return;
}
if (updatedQuery?.filters?.items) {
updatedQuery.filters.items = [];
}
const preparedQuery: Query = {
...currentQuery,
builder: {
...currentQuery.builder,
queryData: currentQuery.builder.queryData.map((item, idx) => ({
...item,
filter: {
...item.filter,
expression: '',
},
filters: {
...item.filters,
items: idx === lastUsedQuery ? [] : [...(item.filters?.items || [])],
op: item.filters?.op || 'AND',
},
})),
queryData: currentQuery.builder.queryData.map((item, idx) => {
if (idx !== activeQueryIndex) {
return item;
}
return {
...item,
filter: {
...item.filter,
expression: '',
},
filters: {
...item.filters,
items: [],
op: item.filters?.op || 'AND',
},
};
}),
},
};
@@ -114,138 +164,195 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
showQueryName &&
currentQuery.builder.queryData?.[lastUsedQuery || 0]?.queryName;
// In ListView, always show the 0th query's name; otherwise use the active query's name
const displayedQueryName = isListView
? showQueryName && currentQuery.builder.queryData?.[0]?.queryName
: lastQueryName;
const handleQueryChange = (value: number): void => {
setLastUsedQuery(value);
};
// Helpers to reduce cognitive complexity in main render
const renderLeftActions = (): JSX.Element => (
<section className="left-actions">
<FilterOutlined />
<Typography.Text className="text">
{displayedQueryName ? 'Filters for' : 'Filters'}
</Typography.Text>
{queryOptions.length > 1 && (!isListView || shouldShowDropdownInListView) ? (
<Combobox open={open} onOpenChange={setOpen}>
<ComboboxTrigger
placeholder="Select a query"
value={queryOptions.find((f) => f.value === validQueryIndex)?.label || ''}
className="select-box"
/>
{open && (
<ComboboxContent>
<ComboboxCommand>
<ComboboxList>
{queryOptions.map((option) => (
<ComboboxItem
key={option.value}
value={String(option.value)}
onSelect={(): void => {
handleQueryChange(option.value);
setOpen(false);
}}
isSelected={validQueryIndex === option.value}
showCheck={false}
>
{option.label}
</ComboboxItem>
))}
</ComboboxList>
</ComboboxCommand>
</ComboboxContent>
)}
</Combobox>
) : (
displayedQueryName && (
<Tooltip
title={`Filter currently in sync with query ${displayedQueryName}`}
>
<Typography.Text className="sync-tag">
{displayedQueryName}
</Typography.Text>
</Tooltip>
)
)}
</section>
);
const renderRightActions = (): JSX.Element => (
<section className="right-actions">
<Tooltip title="Reset All">
<div className="right-action-icon-container">
<SyncOutlined className="sync-icon" onClick={handleReset} />
</div>
</Tooltip>
{showFilterCollapse && (
<Tooltip title="Collapse Filters">
<div className="right-action-icon-container">
<VerticalAlignTopOutlined
rotate={270}
onClick={handleFilterVisibilityChange}
/>
</div>
</Tooltip>
)}
{isDynamicFilters && isAdmin && (
<Tooltip title="Settings">
<div
className={classNames('right-action-icon-container', {
active: isSettingsOpen,
})}
>
<SettingsIcon
className="settings-icon"
data-testid="settings-icon"
width={14}
height={14}
onClick={(): void => setIsSettingsOpen(true)}
/>
<AnnouncementTooltip
show={showAnnouncementTooltip}
position={{ top: -5, left: 15 }}
title="Edit your quick filters"
message="You can now customize and re-arrange your quick filters panel. Select the quick filters youd need and hide away the rest for faster exploration."
onClose={(): void => {
setLocalStorageKey(
LOCALSTORAGE.QUICK_FILTERS_SETTINGS_ANNOUNCEMENT,
'false',
);
}}
/>
</div>
</Tooltip>
)}
</section>
);
const renderContent = (): JSX.Element => (
<>
{source === QuickFiltersSource.API_MONITORING && (
<div className="api-quick-filters-header">
<Typography.Text>Show IP addresses</Typography.Text>
<Switch
size="small"
style={{ marginLeft: 'auto' }}
checked={showIP ?? true}
onClick={(): void => {
logEvent('API Monitoring: Show IP addresses clicked', {
showIP: !(showIP ?? true),
});
setParams({ showIP });
}}
/>
</div>
)}
<section className="filters">
{filterConfig.map((filter) => {
switch (filter.type) {
case FiltersType.CHECKBOX:
return (
<Checkbox
source={source}
filter={filter}
onFilterChange={onFilterChange}
/>
);
case FiltersType.DURATION:
return (
<Duration
filter={filter}
onFilterChange={onFilterChange}
source={source}
/>
);
case FiltersType.SLIDER:
return <Slider filter={filter} />;
// eslint-disable-next-line sonarjs/no-duplicated-branches
default:
return (
<Checkbox
source={source}
filter={filter}
onFilterChange={onFilterChange}
/>
);
}
})}
{filterConfig.length === 0 && (
<div className="no-filters-container">
<Frown size={16} />
<Typography.Text>No filters found</Typography.Text>
</div>
)}
</section>
</>
);
return (
<div className="quick-filters-container">
<div className="quick-filters">
{source !== QuickFiltersSource.INFRA_MONITORING && (
<section className="header">
<section className="left-actions">
<FilterOutlined />
<Typography.Text className="text">
{lastQueryName ? 'Filters for' : 'Filters'}
</Typography.Text>
{lastQueryName && (
<Tooltip title={`Filter currently in sync with query ${lastQueryName}`}>
<Typography.Text className="sync-tag">{lastQueryName}</Typography.Text>
</Tooltip>
)}
</section>
<section className="right-actions">
<Tooltip title="Reset All">
<div className="right-action-icon-container">
<SyncOutlined className="sync-icon" onClick={handleReset} />
</div>
</Tooltip>
{showFilterCollapse && (
<Tooltip title="Collapse Filters">
<div className="right-action-icon-container">
<VerticalAlignTopOutlined
rotate={270}
onClick={handleFilterVisibilityChange}
/>
</div>
</Tooltip>
)}
{isDynamicFilters && isAdmin && (
<Tooltip title="Settings">
<div
className={classNames('right-action-icon-container', {
active: isSettingsOpen,
})}
>
<SettingsIcon
className="settings-icon"
data-testid="settings-icon"
width={14}
height={14}
onClick={(): void => setIsSettingsOpen(true)}
/>
<AnnouncementTooltip
show={showAnnouncementTooltip}
position={{ top: -5, left: 15 }}
title="Edit your quick filters"
message="You can now customize and re-arrange your quick filters panel. Select the quick filters youd need and hide away the rest for faster exploration."
onClose={(): void => {
setLocalStorageKey(
LOCALSTORAGE.QUICK_FILTERS_SETTINGS_ANNOUNCEMENT,
'false',
);
}}
/>
</div>
</Tooltip>
)}
</section>
{renderLeftActions()}
{renderRightActions()}
</section>
)}
{isCustomFiltersLoading ? (
<div className="quick-filters-skeleton">
{Array.from({ length: 5 }).map((_, index) => (
<Skeleton.Input
active
size="small"
// eslint-disable-next-line react/no-array-index-key
key={index}
/>
// eslint-disable-next-line react/no-array-index-key
<Skeleton.Input active size="small" key={index} />
))}
</div>
) : (
<OverlayScrollbar>
<>
{source === QuickFiltersSource.API_MONITORING && (
<div className="api-quick-filters-header">
<Typography.Text>Show IP addresses</Typography.Text>
<Switch
size="small"
style={{ marginLeft: 'auto' }}
checked={showIP ?? true}
onClick={(): void => {
logEvent('API Monitoring: Show IP addresses clicked', {
showIP: !(showIP ?? true),
});
setParams({ showIP });
}}
/>
</div>
)}
<section className="filters">
{filterConfig.map((filter) => {
switch (filter.type) {
case FiltersType.CHECKBOX:
return (
<Checkbox
source={source}
filter={filter}
onFilterChange={onFilterChange}
/>
);
case FiltersType.DURATION:
return <Duration filter={filter} onFilterChange={onFilterChange} />;
case FiltersType.SLIDER:
return <Slider filter={filter} />;
// eslint-disable-next-line sonarjs/no-duplicated-branches
default:
return (
<Checkbox
source={source}
filter={filter}
onFilterChange={onFilterChange}
/>
);
}
})}
{filterConfig.length === 0 && (
<div className="no-filters-container">
<Frown size={16} />
<Typography.Text>No filters found</Typography.Text>
</div>
)}
</section>
</>
</OverlayScrollbar>
<OverlayScrollbar>{renderContent()}</OverlayScrollbar>
)}
</div>
<div className="quick-filters-settings-container">

View File

@@ -141,9 +141,12 @@ function OtherFilters({
const renderFilters = (): React.ReactNode => {
const isLoading =
isFetchingSuggestions || isFetchingAggregateKeys || isLoadingFieldKeys;
if (isLoading) return <OtherFiltersSkeleton />;
if (!otherFilters?.length)
if (isLoading) {
return <OtherFiltersSkeleton />;
}
if (!otherFilters?.length) {
return <div className="no-values-found">No values found</div>;
}
return otherFilters.map((filter) => (
<div key={filter.key} className="qf-filter-item other-filters-item">

View File

@@ -122,6 +122,103 @@ describe('Quick Filters', () => {
expect(screen.getByText(QUERY_NAME)).toBeInTheDocument();
});
it('should display and allow selection from query dropdown when multiple queries exist', async () => {
const setLastUsedQuery = jest.fn();
const user = userEvent.setup({ pointerEventsCheck: 0 });
(useQueryBuilder as jest.Mock).mockReturnValue({
currentQuery: {
builder: {
queryData: [
{
queryName: 'Query A',
filters: { items: [] },
},
{
queryName: 'Query B',
filters: { items: [] },
},
{
queryName: 'Query C',
filters: { items: [] },
},
],
},
},
lastUsedQuery: 0,
setLastUsedQuery,
redirectWithQueryBuilderData,
panelType: 'graph', // not LIST view
});
render(<TestQuickFilters />);
// The dropdown trigger should show the first query name
const trigger = screen.getByText('Query A');
expect(trigger).toBeInTheDocument();
// Click to open the dropdown
await user.click(trigger);
// All query options should be visible
await waitFor(() => {
expect(screen.getByRole('option', { name: 'Query A' })).toBeInTheDocument();
expect(screen.getByRole('option', { name: 'Query B' })).toBeInTheDocument();
expect(screen.getByRole('option', { name: 'Query C' })).toBeInTheDocument();
});
// Select Query B
const queryBOption = screen.getByRole('option', { name: 'Query B' });
await user.click(queryBOption);
// Verify setLastUsedQuery was called with index 1
await waitFor(() => {
expect(setLastUsedQuery).toHaveBeenCalledWith(1);
});
});
it('should not display query dropdown in ListView', () => {
(useQueryBuilder as jest.Mock).mockReturnValue({
currentQuery: {
builder: {
queryData: [
{
queryName: 'Query A',
filters: { items: [] },
},
{
queryName: 'Query B',
filters: { items: [] },
},
],
},
},
lastUsedQuery: 0,
redirectWithQueryBuilderData,
panelType: 'list', // ListView
});
render(<TestQuickFilters />);
// Should show static query name without dropdown
expect(screen.getByText('Query A')).toBeInTheDocument();
// Dropdown trigger should not be interactive (no button/combobox)
const queryText = screen.getByText('Query A');
expect(queryText.tagName).not.toBe('BUTTON');
});
it('should display static query name when only one query exists', () => {
render(<TestQuickFilters />);
// Should show static query name
expect(screen.getByText(QUERY_NAME)).toBeInTheDocument();
// No dropdown should be present
const queryText = screen.getByText(QUERY_NAME);
expect(queryText.closest('[role="combobox"]')).not.toBeInTheDocument();
});
it('should add filter data to query when checkbox is clicked', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });

View File

@@ -43,7 +43,9 @@ function ResizeTable({
const updateAllColumnWidths = useRef(
debounce((widthsConfig: Record<string, number>) => {
if (!widgetId || !shouldPersistColumnWidths) return;
if (!widgetId || !shouldPersistColumnWidths) {
return;
}
setColumnWidths?.((prev) => ({
...prev,
[widgetId]: widthsConfig,
@@ -127,7 +129,9 @@ function ResizeTable({
}, [columns, columnWidths]);
useEffect(() => {
if (!shouldPersistColumnWidths) return;
if (!shouldPersistColumnWidths) {
return;
}
// Collect all column widths in a single object
const newColumnWidths: Record<string, number> = {};

View File

@@ -4,10 +4,14 @@ import { ArrowUp, ChevronUp, Command, Option } from 'lucide-react';
import { ReactNode } from 'react';
export function formatShortcut(shortcut?: string[]): ReactNode {
if (!shortcut || shortcut.length === 0) return null;
if (!shortcut || shortcut.length === 0) {
return null;
}
const combo = shortcut.find((s) => typeof s === 'string' && s.trim());
if (!combo) return null;
if (!combo) {
return null;
}
return combo.split('+').map((key) => {
const k = key.trim().toLowerCase();

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