Compare commits

...

84 Commits

Author SHA1 Message Date
Abhi Kumar
04e5d87986 test: added test for tooltip plugin 2026-02-09 13:16:20 +05:30
Abhi kumar
e5867cc2ad chore: updated chart theme colors (#10233)
* chore: updated chart theme colors

* fix: fixed failing tests
2026-02-09 12:25:36 +05:30
Srikanth Chekuri
b420ca494e chore: remove inline enum and implement jsonschema.Enum for metric types (#10238)
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-02-09 07:02:32 +05:30
Piyush Singariya
e4693ce64c fix: improve qbtoexpr test suite (#10217)
Some checks failed
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (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
* fix: improve qbtoexpr test suite

* fix: assert eq order

---------

Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2026-02-06 15:15:56 +00:00
Ashwin Bhatkal
ca9b3a910a chore: separate out query and custom variable (#10221)
* chore: separate out query and custom variable

* chore: resolve own comments
2026-02-06 19:06:30 +05:30
Karan Balani
9dc7d2389a fix: minor changes for gateway and forgot password apis (#10204)
* fix: make size and count included in json if zero

* fix: make forgot password api fields required

* fix: openapi spec

* fix: error message casing for frontend

* chore: fix openapi spec

* fix: openapi specs
2026-02-06 18:00:33 +05:30
Abhi kumar
da5860297f feat: added new time series panel (#10207)
* feat: added new time series panel

* fix: pr review comments

* fix: pr review comments

* chore: memoized data creation in chartmanager
2026-02-06 16:35:30 +05:30
Ashwin Bhatkal
54fca5ba44 chore: separate out textbox variable into it's own component (#10206)
* chore: initiliase fetch store

* chore: small refactor

* chore: separate out textbox component into it's own component
2026-02-06 16:19:49 +05:30
Ashwin Bhatkal
66f4c3d6ec chore: add max-params eslint rule and update contribution guidelines (#10200)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (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
* chore: add max-params eslint rule and update contribution guidelines

* chore: add no-cycle rule
2026-02-06 13:03:59 +05:30
Srikanth Chekuri
a0f407a848 chore(metricsexplorer): update tags and regenerate (#10197) 2026-02-06 12:10:11 +05:30
Abhi kumar
3562de8fbb fix: added fix for tooltip sizing (#10205)
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-02-05 22:46:17 +05:30
Abhi kumar
ef80fb39fd feat: added new time-series graph (#10201)
* feat: added new time-series graph

* chore: updated types for charts
2026-02-05 11:29:21 +00:00
Abhi kumar
594d4dc737 feat: added changes to compute legend items width for virtualization (#10196)
* feat: added changes to compute legend items width for virtualization

* feat: added support for single row in legends
2026-02-05 16:27:43 +05:30
Abhishek Kumar Singh
01415b58be chore: made group_wait and group_interval configuration dynamic for alert manager (#10198) 2026-02-05 09:56:27 +00:00
Ashwin Bhatkal
f7728c9019 chore: update variables store with derived values (#10194)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (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
* chore: remove redundant sort

* chore: use sorted variables array

* chore: update variables store with derived values

* chore: fix types

* chore: resolve cursor comments
2026-02-05 14:09:46 +05:30
Amlan Kumar Nandy
3fffe6e198 chore: use single reducer in create alerts flow (#10179) 2026-02-05 07:39:07 +00:00
Aditya Singh
4594f4ffe3 Fix/query label fix (#10158)
* feat: function idon func added

* feat: test update

* fix: minor refactor
2026-02-05 12:19:16 +05:30
Abhi kumar
b660dc8573 fix: added fix for storing legend preferences (#10184)
* fix: added fix for storing legend preferences

* fix: fixed tsc

* fix: cursor reviews

* fix: cursor reviews

* fix: added fix for legend visibility issue

* fix: pr review changes
2026-02-05 12:05:09 +05:30
Karan Balani
c7b9c0d36c fix: add missing query params for gateway apis (#10190) 2026-02-05 07:49:43 +05:30
Aditya Singh
4433d22c09 Allow saving previous query in query builder (#10122)
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
* feat: allow saving previous query in qb

* feat: test cases added

* feat: test cases added

* feat: save only one prev query

* feat: minor refactor

* feat: lint fix

* feat: minor refactor

* fix: clear previous query before

* fix: save one query per dataSource
2026-02-04 12:17:41 +00:00
Abhi kumar
9443c42334 fix: minor fix in tooltip rendering (#10175)
* fix: minor fix in tooltip rendering

* fix: pr review fixes

* fix: pr review fixes

* fix: pr review fixes

* fix: pr review fixes
2026-02-04 16:29:14 +05:30
Tushar Vats
9387c96023 fix: handling of traces intrinsic fields colliding with attributes (#10170)
This pull request introduces several improvements and fixes to the trace query builder logic, especially around handling deprecated and corrupt field metadata, and ensures more robust SQL generation and query results. The changes also add new tests to verify these behaviours.
2026-02-04 10:06:13 +00:00
SagarRajput-7
ff2555d8dd feat: consume new semantic token and automatic light and dark mode theming (#10104)
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
* feat: consume new semantic token and automatic light and dark mode theming

* feat: added the semantic token imports

* feat: removed backup hex in variables and comments addressed

* feat: updated the global tooltip style

* feat: updated styles

* feat: updated the data-theme setter to html body itself

* feat: updated design-token version
2026-02-04 07:49:56 +00:00
Amlan Kumar Nandy
85953c9a4c chore: update error state for alert not found (#10132) 2026-02-04 07:13:10 +00:00
SagarRajput-7
0155cc38cb feat: updated the generated apis (#10171) 2026-02-04 12:08:44 +05:30
Ashwin Bhatkal
c217cc96c3 chore: variable store set function (#10174)
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
* chore: variable store set function

* chore: fix var
2026-02-03 14:49:44 +00:00
Vikrant Gupta
580cf32eb5 feat(authz): migrate rbac to authz (#10134)
* feat(authz): migrate rbac to authz

* feat(authz): handle public dashboard migration

* feat(authz): fix integration tests

* feat(authz): fix integration tests

* feat(authz): keep the error same as today
2026-02-03 19:54:07 +05:30
Abhi kumar
6d3580cbfa feat: added a new tooltip plugin (#10167)
* feat: added a new tooltip plugin

* fix: pr review comments

* fix: pr review comments

* fix: pr review comments

* chore: remove global.d.ts override
2026-02-03 14:06:16 +00:00
Abhi kumar
6c5d36caa9 fix: small fixes for scale + legend sizing (#10168)
* fix: small fixes for scale + legend sizing

* fix: minor naming fix
2026-02-03 17:55:17 +05:30
Abhishek Kumar Singh
c4a6c7e277 test(integration): alert firing verification fixture (#10131)
* chore: fixture for notification channel

* chore: return notification channel info in Create notification channel API

* fix: change scope of create channel fixture to function level

* test: added fixture for creating alert rule

* chore: added debug message on assertion failure

* refactor: improve error handling in webhook notification channel deletion

* fix: enhance error handling in alert rule creation and deletion

* chore: ran py linter and fmt

* chore: ran py linter and fmt

* fix: add timeout to alert rule creation and deletion requests

* fix: silenced pylint on too broad exception

* fix: suppress pylint warnings for broad exception handling in alert rule deletion

* test: added fixture for inserting alert data

* refactor: added fixture for getting test data file path

* feat: add alerts to integration CI workflow

* chore: linter fixes

* chore: changed scope for get_testdata_file_path

* feat: alert firing verification fixture

* feat: broken fixture for collect firing alerts

* chore: py-formatter

* chore: py-formatter

* refactor: updated expected alert to dataclass

* chore: updated get_testdata_file_path fixture to a util function

* chore: removed wrong ref

* chore: lint and formatted

* chore: moved utils function to alertutils from fixtures

* chore: return firing alert from collect alert func

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-02-03 16:51:39 +05:30
SagarRajput-7
c9cd974dca feat: sidebar enhancement (#10157)
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
* feat: sidebar enhancement (#9748)

* fix: sidebar enhancement

* fix: new source btn changes

* fix: shortcut order changes

* fix: changes in more section collapse behaviour

* fix: sidebar shortcut changes, consistency, cleanup in collapse mode

* fix: sidebar pin, tooltip and other changes

* feat: updated alignment issues

* fix: sidenav enhancement - fixes

* fix: code fix

* fix: sidenav enhancement

* feat: addressed comments and feedback

* feat: fix default shortcut empty issue

* feat: code clean and improvements

* feat: refactor and cleanup

* feat: refactor and addressed comment

* feat: removed isscrolled

* feat: corrected the ref intialization
2026-02-03 07:58:21 +00:00
Abhi kumar
5b3f121431 feat: added line styling options for uplot (#10166) 2026-02-03 13:14:35 +05:30
Jatinderjit Singh
c79373314a fix: add missing data for promql and anomaly rules (#10097) 2026-02-03 11:48:16 +05:30
Ashwin Bhatkal
858cd287fa chore: query builder / hooks to use new variable store (#10148)
* chore: query builder / hooks to use new variable store

* chore: fix tests
2026-02-03 09:33:02 +05:30
Abhishek Kumar Singh
afdb674068 test(integration): added fixture for inserting alert data (#10101)
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
* chore: fixture for notification channel

* chore: return notification channel info in Create notification channel API

* fix: change scope of create channel fixture to function level

* test: added fixture for creating alert rule

* chore: added debug message on assertion failure

* refactor: improve error handling in webhook notification channel deletion

* fix: enhance error handling in alert rule creation and deletion

* chore: ran py linter and fmt

* chore: ran py linter and fmt

* fix: add timeout to alert rule creation and deletion requests

* fix: silenced pylint on too broad exception

* fix: suppress pylint warnings for broad exception handling in alert rule deletion

* test: added fixture for inserting alert data

* refactor: added fixture for getting test data file path

* feat: add alerts to integration CI workflow

* chore: linter fixes

* chore: changed scope for get_testdata_file_path

* chore: py-formatter

* chore: py-formatter

* chore: updated get_testdata_file_path fixture to a util function

* chore: removed wrong ref

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-02-02 23:37:14 +05:30
Aditya Singh
30a6721472 Add cancel query functionality to dashboard edit panel (#10152)
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
* feat: add cancel query functionality for dashboard panels

* feat: pass loading query from edit panel

* feat: revert loading
2026-02-02 15:02:42 +00:00
Abhi kumar
518dfcbe59 fix: minor fix for uplot scale (#10164) 2026-02-02 13:24:45 +00:00
Ashwin Bhatkal
424127c27c chore: dashboard grid / widget / hooks to use new variable store (#10147)
* chore: dashboard grid / widget / hooks to use new variable store

* chore: fix tests
2026-02-02 12:54:34 +00:00
Abhi kumar
2dcb817de1 feat: Added ChartLayout component + utils to correctly position Legends and Chart in the view (#10160)
* feat: added chartlayout component to render charts and legends

* fix: added fix for legenditemsSet calculation

* chore: added pulse frontend as codeowners for uplotv2

* chore: cleaned up the legend size calculations function

* chore: removed config from deps in charlayout

* fix: added fix for height calculation

* fix: pr review changes
2026-02-02 17:27:14 +05:30
Ashwin Bhatkal
f6f8c78aaf chore: dashboard container to use new variable store (#10146)
* chore: dashboard container to use new variable store

* chore: fix tests
2026-02-02 15:20:47 +05:30
Abhishek Kumar Singh
3c99dfdfa5 test(integration): added fixture for creating alert rule (#10092)
* chore: fixture for notification channel

* chore: return notification channel info in Create notification channel API

* fix: change scope of create channel fixture to function level

* test: added fixture for creating alert rule

* chore: added debug message on assertion failure

* refactor: improve error handling in webhook notification channel deletion

* fix: enhance error handling in alert rule creation and deletion

* chore: ran py linter and fmt

* chore: ran py linter and fmt

* fix: add timeout to alert rule creation and deletion requests

* fix: silenced pylint on too broad exception

* fix: suppress pylint warnings for broad exception handling in alert rule deletion

* feat: add alerts to integration CI workflow

* chore: py-formatter

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Vikrant Gupta <vikrant@signoz.io>
2026-02-02 14:56:33 +05:30
Abhi kumar
6ed72519b8 feat: implement uPlot builder pattern API for chart configuration (#10069)
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
* feat: implement uPlot builder pattern API for chart configuration

* feat: added panel context wrapper

* chore: removed console logs

* chore: minor cleanup

* chore: fixed uplot lib

* chore: added datautils

* chore: type fixes

* chore: fixed linter issues

* fix: added fix for removehook + legend state sync

* fix: added fix for orphand plot

* fix: legend animation frame race condition

* fix: added fix for skipping series with no data

* fix: added fix for header title when cursorIdx is 0

* fix: fixed cursor comments

* fix: fixed cursor comments

* fix: added safeguard for setseries visibility

* chore: updated context placement

* chore: added changes for storing legendstate in localstorage

* chore: added changes related to yaxisunit and decimalprecision

* chore: minor changes in the builders

* chore: minor updates

* chore: variable updates in useLegendSync

* chore: added thresold hook and restructured the code

* chore: pr review comments

* chore: moved uplot specific files to uplotv2

* chore: pr review changes

* chore: pr review changes

* chore: pr review changes

* chore: types fixes

* chore: linted and added comments

* chore: series visibility update fix

* chore: fixed pr review comments

* chore: updated normalize plot utils

* chore: added memoization in plotcontext

* chore: minor changes

* chore: fixed cursor comments

* chore: fixed cursor comments

* chore: fixed cursor comments

* chore: restructured files

* fix: renaming

* fix: renaming

* chore: minor fix

* chore: timestamp fix

* fix: added fix for tooltip label generation

* fix: pr review changes

* fix: pr review changes

* fix: pr review changes

* fix: pr review changes

* fix: pr review changes

* fix: pr review changes

* fix: cursor review

* fix: cursor review

* fix: cursor review
2026-02-02 12:45:00 +05:30
primus-bot[bot]
fe910aaa0f chore(release): bump to v0.110.1 (#10159)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-02-02 12:22:06 +05:30
gkarthi-signoz
0d362b3ba8 Fix typo in LLM Observability section (#10155)
Some checks failed
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (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
2026-01-31 03:02:46 +00:00
gkarthi-signoz
51e9ffb847 Adding LLM Observability Docs Ref to README.md (#10142)
* adding LLM Observability ref to README

* Update README.md
2026-01-31 00:30:10 +00:00
Ashwin Bhatkal
f497a154a2 chore: variable store set up (#10145)
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
* chore: update CODEOWNERS file for dashboards

* chore: variable store set up
2026-01-31 00:18:26 +05:30
Abhi kumar
659fa361ef fix: added fix for useDimensions returing 0,0 on mount (#10154)
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-30 18:51:33 +05:30
Manika Malhotra
84e77182f6 feat: pass region to docs (#10068)
* chore: init pass region and ingestion key to docs

* chore: test add staging url

* fix: pass ingestion region from url

* chore: remove ingestion key from param

* fix: set search param only if url matches

* revert: docs url

* fix: region parsing

* fix: resolve comments
2026-01-30 12:04:25 +00:00
Aditya Singh
32619869e7 Show both tag/resource variants for identical keys in pipeline filter options (#10150)
* feat: show multiple labels with differing tags and types in filter options

* feat: test fix
2026-01-30 10:29:09 +00:00
Ashwin Bhatkal
e9093126b2 chore: update CODEOWNERS file for dashboards (#10144)
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-29 14:36:19 +00:00
Ashwin Bhatkal
195f44802d chore: add eslint rules for import export sorting rules (#10074)
* chore: updated eslint base config with comments

* chore: add eslint rules for no-else-return and curly

* chore: use isNumber from lodash-es

* chore: add eslint rules for no-console

* chore: update eslint overrides

* chore: sort all files

* chore: fix tests
2026-01-29 11:44:07 +00:00
Abhishek Kumar Singh
948bdb7881 test(integration): fixture for notification channel (#10089)
* chore: fixture for notification channel

* chore: return notification channel info in Create notification channel API

* fix: change scope of create channel fixture to function level

* chore: added debug message on assertion failure

* refactor: improve error handling in webhook notification channel deletion

* chore: ran py linter and fmt

* fix: silenced pylint on too broad exception

* feat: add alerts to integration CI workflow

* chore: removed clean from notification channel creation fixture + changes fixture scope of get_token

* chore: reverted fixture scopes to function

* fix: breaking alert test due to alert manager not registered for newly created org

* chore: formatted and fix lint

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-01-29 17:00:44 +05:30
Piyush Singariya
7274d51236 feat: has function support New JSON QB (#10050)
* feat: has JSON QB

* fix: tests expected queries and values

* fix: ignored .vscode in gitignore

* fix: tests GroupBy

* revert: gitignore change

* fix: build json plans in metadata

* fix: empty filteredArrays condition

* fix: tests

* fix: tests

* fix: json qb test fix

* fix: review based on tushar

* fix: changes based on review from Srikanth

* fix: remove unnecessary bool checking

* fix: removed comment

* chore: var renamed

* fix: merge conflict

* test: fix

* fix: tests

* fix: go test flakiness

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-01-29 14:53:54 +05:30
Aditya Singh
5b580f8e63 Fix broken Group By behaviour (#10100)
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
* fix: set appropriate datasource in grp by

* feat: test cases added

* feat: fix styles

* feat: update test
2026-01-29 06:27:08 +00:00
primus-bot[bot]
5ce1f0b855 chore(release): bump to v0.110.0 (#10139)
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
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
Co-authored-by: Pandey <vibhupandey28@gmail.com>
2026-01-28 15:13:15 +00:00
Pandey
291e6a2af8 Revert "feat: sidebar enhancement (#9748)" (#10137)
This reverts commit c0e2dad3b5.
2026-01-28 14:57:42 +00:00
primus-bot[bot]
3a34fb4813 chore(release): bump to v0.109.3 (#10136)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-01-28 14:34:27 +00:00
Tushar Vats
189781748a fix: dont filter out static fields in metadata store (#10135)
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 introduces several improvements and bug fixes in the telemetry logs and traces statement builders, metadata key filtering, and integration tests. The most significant changes ensure that required fields are always present in queries, deprecated fields are handled correctly, and test coverage is expanded to handle edge cases such as corrupt data. Additionally, some code cleanup and formatting improvements are made.
2026-01-28 19:42:04 +05:30
Vishal Sharma
e7c812e07f feat: remove search input and add view data sources button in integrations header (#10123)
- Removed search functionality from integrations
- Added "View 150+ Data Sources" button that navigates to GET_STARTED_WITH_CLOUD route
- Updated subtitle text to reflect curated integrations
- Removed RequestIntegrationBtn from the page
2026-01-28 13:13:53 +00:00
SagarRajput-7
c0e2dad3b5 feat: sidebar enhancement (#9748)
* fix: sidebar enhancement

* fix: new source btn changes

* fix: shortcut order changes

* fix: changes in more section collapse behaviour

* fix: sidebar shortcut changes, consistency, cleanup in collapse mode

* fix: sidebar pin, tooltip and other changes

* feat: updated alignment issues

* fix: sidenav enhancement - fixes

* fix: code fix

* fix: sidenav enhancement

* feat: addressed comments and feedback

* feat: fix default shortcut empty issue

* feat: code clean and improvements

* feat: refactor and cleanup

* feat: refactor and addressed comment

* feat: removed isscrolled
2026-01-28 16:55:03 +05:30
primus-bot[bot]
bb3ccfae3b chore(release): bump to v0.109.2 (#10130)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-01-28 13:54:24 +05:30
Ashwin Bhatkal
08f261b0f0 chore: add node version in gor yaml files (#10128) 2026-01-28 07:18:11 +00:00
primus-bot[bot]
9b4fd46d2c chore(release): bump to v0.109.0 (#10127)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-01-28 12:13:32 +05:30
Tushar Vats
f348f47951 feat: improved keys adjustment logic (#9927)
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 introduces a new utility file, `collision.go`, to the `querybuilder` package, which provides robust logic for handling duplicate and ambiguous field keys in query builder queries. The new functions ensure that queries are more resilient to naming collisions and ambiguities, especially when dealing with JSON and promoted fields. Additionally, several test cases have been updated to reflect improved handling and warning messages for ambiguous keys.
2026-01-28 11:25:14 +05:30
Yunus M
9d700563c1 fix: handle custom time ranges in timezones correctly (#10094)
* feat: handle custom time ranges in timezones correctly

* fix: improve timezone UI

* fix: prettier issues

* fix: show time in user selected timezone, overflow issue (#10096)

* fix: show time in user selected timezone, overflow issue, metadata loading

* fix: add gap to popover row

* fix: use inline conditional render for startTimeMs

* fix: remove unused variable in CustomTimePicker

* fix: remove unused variable in CustomTimePicker, TraceMetadata

* fix: update timezone mock in SpanHoverCard test case
2026-01-28 10:30:40 +05:30
Vishal Sharma
54b80c3949 feat: add new onboarding partner logos and update documentation to enforce SVG format (#10120)
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-27 17:33:22 +00:00
Vikrant Gupta
1c815b130c feat(authz): scafolding for rbac migration (#10121)
* feat(authz): initial commit for migrating rbac to openfga

* feat(authz): make the role updates idempotant

* feat(authz): split role module into role and grant

* feat(authz): some naming changes

* feat(authz): integrate the grant module

* feat(authz): add support for migrating existing user role

* feat(authz): add support for migrating existing user role

* feat(authz): figure out the * selector

* feat(authz): merge main

* feat(authz): merge main

* feat(authz): address couple of todos

* feat(authz): address couple of todos

* feat(authz): fix tests and revert public dashboard change

* feat(authz): fix tests and revert public dashboard change

* feat(authz): add open api spec

* feat(authz): add open api spec

* feat(authz): add api key changes and missing migration

* feat(authz): split role into getter and setter

* feat(authz): add integration tests for authz register

* feat(authz): add more tests for user invite and delete

* feat(authz): update user tests

* feat(authz): rename grant to granter

* feat(authz): address review comments

* feat(authz): address review comments

* feat(authz): address review comments

* feat(authz): add the migration for existing roles

* feat(authz): go mod tidy

* feat(authz): fix integration tests

* feat(authz): handle community changes

* feat(authz): handle community changes

* feat(authz): role selectors for open claims

* feat(authz): role selectors for open claims

* feat(authz): prevent duplicate entries for changelog

* feat(authz): scafolding for rbac migration

* feat(authz): scafolding for rbac migration

* feat(authz): scafolding for rbac migration

* feat(authz): scafolding for rbac migration

* feat(authz): scafolding for rbac migration
2026-01-27 21:24:36 +05:30
Vikrant Gupta
9e9879fc8d chore(env): add docs base url (#10112)
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
* chore(env): add docs base url for staging and production

* chore(env): add docs base url for staging and production

* chore(env): add docs base url for staging and production
2026-01-27 18:14:05 +05:30
Abhishek Kumar Singh
af87c2e80b chore: added Validate function for QueryBuilderFormula struct (#10041) 2026-01-27 15:48:14 +05:30
Karan Balani
e1ac992e5a feat: forgot password api and token expiry (#10073) 2026-01-27 15:31:15 +05:30
Aditya Singh
15161c09e8 Feat: show (cmd + return) as helper text in Run Query button (#10082)
* feat: create common run query btn

* feat: update run query in explorer

* feat: comment

* feat: fix styles

* feat: fix styles

* feat: update style

* feat: update btn in alerts

* feat: added test cases

* feat: replace run query btn

* feat: bg change run query
2026-01-27 14:52:03 +05:30
Ashwin Bhatkal
ee5fbe41eb chore: add eslint rules for no-unused-vars (#10072)
* chore: updated eslint base config with comments

* chore: add eslint rules for no-else-return and curly

* chore: add eslint rules for no-console

* chore: add eslint rules for no-unused-vars

* chore: fix more cases
2026-01-27 14:14:26 +05:30
Vikrant Gupta
f2f3a7b24a chore(lint): enable wastedassign (#10103)
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-26 20:40:49 +05:30
Ashwin Bhatkal
dd0738ac70 chore: add eslint rules for no-console (#10071)
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-23 19:06:05 +00:00
Pandey
1c4dfc931f chore: move to clone instead of json marshal (#10076) 2026-01-23 16:34:30 +00:00
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
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
1510 changed files with 28980 additions and 8725 deletions

View File

@@ -42,7 +42,7 @@ services:
timeout: 5s
retries: 3
schema-migrator-sync:
image: signoz/signoz-schema-migrator:v0.129.12
image: signoz/signoz-schema-migrator:v0.129.13
container_name: schema-migrator-sync
command:
- sync
@@ -55,7 +55,7 @@ services:
condition: service_healthy
restart: on-failure
schema-migrator-async:
image: signoz/signoz-schema-migrator:v0.129.12
image: signoz/signoz-schema-migrator:v0.129.13
container_name: schema-migrator-async
command:
- async

4
.github/CODEOWNERS vendored
View File

@@ -110,6 +110,7 @@
# Dashboard Owners
/frontend/src/hooks/dashboard/ @SigNoz/pulse-frontend
/frontend/src/providers/Dashboard/ @SigNoz/pulse-frontend
## Dashboard Types
@@ -131,3 +132,6 @@
/frontend/src/pages/PublicDashboard/ @SigNoz/pulse-frontend
/frontend/src/container/PublicDashboardContainer/ @SigNoz/pulse-frontend
## UplotV2
/frontend/src/lib/uPlotV2/ @SigNoz/pulse-frontend

View File

@@ -70,6 +70,7 @@ jobs:
echo 'PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> frontend/.env
echo 'APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> frontend/.env
echo 'PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> frontend/.env
echo 'DOCS_BASE_URL="https://signoz.io"' >> frontend/.env
- name: cache-dotenv
uses: actions/cache@v4
with:

View File

@@ -69,6 +69,7 @@ jobs:
echo 'PYLON_APP_ID="${{ secrets.NP_PYLON_APP_ID }}"' >> frontend/.env
echo 'APPCUES_APP_ID="${{ secrets.NP_APPCUES_APP_ID }}"' >> frontend/.env
echo 'PYLON_IDENTITY_SECRET="${{ secrets.NP_PYLON_IDENTITY_SECRET }}"' >> frontend/.env
echo 'DOCS_BASE_URL="https://staging.signoz.io"' >> frontend/.env
- name: cache-dotenv
uses: actions/cache@v4
with:

View File

@@ -3,8 +3,8 @@ name: gor-signoz-community
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
permissions:
contents: write
@@ -21,6 +21,10 @@ jobs:
shell: bash
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: node-setup
uses: actions/setup-node@v5
with:
node-version: "22"
- name: build-frontend
run: make js-build
- name: upload-frontend-artifact
@@ -89,7 +93,7 @@ jobs:
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: '~> v2'
version: "~> v2"
args: release --config ${{ env.CONFIG_PATH }} --clean --split
workdir: .
env:
@@ -147,7 +151,7 @@ jobs:
if: steps.cache-linux.outputs.cache-hit == 'true' && steps.cache-darwin.outputs.cache-hit == 'true' # only run if caches hit
with:
distribution: goreleaser-pro
version: '~> v2'
version: "~> v2"
args: continue --merge
workdir: .
env:

View File

@@ -3,8 +3,8 @@ name: gor-signoz
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
permissions:
contents: write
@@ -36,8 +36,13 @@ jobs:
echo 'PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> .env
echo 'APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> .env
echo 'PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> .env
echo 'DOCS_BASE_URL="https://signoz.io"' >> .env
- name: node-setup
uses: actions/setup-node@v5
with:
node-version: "22"
- name: build-frontend
run: make js-build
run: make js-build
- name: upload-frontend-artifact
uses: actions/upload-artifact@v4
with:
@@ -104,7 +109,7 @@ jobs:
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: '~> v2'
version: "~> v2"
args: release --config ${{ env.CONFIG_PATH }} --clean --split
workdir: .
env:
@@ -161,7 +166,7 @@ jobs:
if: steps.cache-linux.outputs.cache-hit == 'true' && steps.cache-darwin.outputs.cache-hit == 'true' # only run if caches hit
with:
distribution: goreleaser-pro
version: '~> v2'
version: "~> v2"
args: continue --merge
workdir: .
env:

View File

@@ -42,10 +42,12 @@ jobs:
- callbackauthn
- cloudintegrations
- dashboard
- querier
- ttl
- preference
- logspipelines
- preference
- querier
- role
- ttl
- alerts
sqlstore-provider:
- postgres
- sqlite

1
.gitignore vendored
View File

@@ -57,7 +57,6 @@ bin/
.local/
*/query-service/queries.active
ee/query-service/db
# e2e
e2e/node_modules/

View File

@@ -12,6 +12,7 @@ linters:
- misspell
- nilnil
- sloglint
- wastedassign
- unparam
- unused
settings:

View File

@@ -1,5 +1,7 @@
{
"eslint.workingDirectories": ["./frontend"],
"eslint.workingDirectories": [
"./frontend"
],
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
@@ -9,5 +11,8 @@
"[go]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "golang.go"
},
"[sql]": {
"editor.defaultFormatter": "adpyke.vscode-sql-formatter"
}
}

View File

@@ -66,6 +66,17 @@ Read [more](https://signoz.io/metrics-and-dashboards/).
![metrics-n-dashboards-cover](https://github.com/user-attachments/assets/a536fd71-1d2c-4681-aa7e-516d754c47a5)
### LLM Observability
Monitor and debug your LLM applications with comprehensive observability. Track LLM calls, analyze token usage, monitor performance, and gain insights into your AI application's behavior in production.
SigNoz LLM observability helps you understand how your language models are performing, identify issues with prompts and responses, track token usage and costs, and optimize your AI applications for better performance and reliability.
[Get started with LLM Observability →](https://signoz.io/docs/llm-observability/)
![llm-observability-cover](https://github.com/user-attachments/assets/a6cc0ca3-59df-48f9-9c16-7c843fccff96)
### Alerts
Use alerts in SigNoz to get notified when anything unusual happens in your application. You can set alerts on any type of telemetry signal (logs, metrics, traces), create thresholds and set up a notification channel to get notified. Advanced features like alert history and anomaly detection can help you create smarter alerts.

View File

@@ -19,6 +19,7 @@ import (
"github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/role"
"github.com/SigNoz/signoz/pkg/modules/role/implrole"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/queryparser"
@@ -80,12 +81,15 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
func(ctx context.Context, sqlstore sqlstore.SQLStore) factory.ProviderFactory[authz.AuthZ, authz.Config] {
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx))
},
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, _ role.Module, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing) dashboard.Module {
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, _ role.Setter, _ role.Granter, 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()
},
func(store sqlstore.SQLStore, authz authz.AuthZ, licensing licensing.Licensing, _ []role.RegisterTypeable) role.Setter {
return implrole.NewSetter(implrole.NewStore(store), authz)
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create signoz", "error", err)

View File

@@ -14,6 +14,7 @@ import (
enterpriselicensing "github.com/SigNoz/signoz/ee/licensing"
"github.com/SigNoz/signoz/ee/licensing/httplicensing"
"github.com/SigNoz/signoz/ee/modules/dashboard/impldashboard"
"github.com/SigNoz/signoz/ee/modules/role/implrole"
enterpriseapp "github.com/SigNoz/signoz/ee/query-service/app"
"github.com/SigNoz/signoz/ee/sqlschema/postgressqlschema"
"github.com/SigNoz/signoz/ee/sqlstore/postgressqlstore"
@@ -29,6 +30,7 @@ import (
pkgimpldashboard "github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/role"
pkgimplrole "github.com/SigNoz/signoz/pkg/modules/role/implrole"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/queryparser"
"github.com/SigNoz/signoz/pkg/signoz"
@@ -119,13 +121,17 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
func(ctx context.Context, sqlstore sqlstore.SQLStore) factory.ProviderFactory[authz.AuthZ, authz.Config] {
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx))
},
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(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, roleSetter role.Setter, granter role.Granter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, roleSetter, granter, queryParser, querier, licensing)
},
func(licensing licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return httpgateway.NewProviderFactory(licensing)
},
func(store sqlstore.SQLStore, authz authz.AuthZ, licensing licensing.Licensing, registry []role.RegisterTypeable) role.Setter {
return implrole.NewSetter(pkgimplrole.NewStore(store), authz, licensing, registry)
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create signoz", "error", err)
return err

View File

@@ -291,3 +291,12 @@ flagger:
float:
integer:
object:
##################### User #####################
user:
password:
reset:
# Whether to allow users to reset their password themselves.
allow_self: true
# The duration within which a user can reset their password.
max_token_lifetime: 6h

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.108.0
image: signoz/signoz:v0.110.1
command:
- --config=/root/config/prometheus.yml
ports:
@@ -209,7 +209,7 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.129.12
image: signoz/signoz-otel-collector:v0.129.13
command:
- --config=/etc/otel-collector-config.yaml
- --manager-config=/etc/manager-config.yaml
@@ -233,7 +233,7 @@ services:
- signoz
schema-migrator:
!!merge <<: *common
image: signoz/signoz-schema-migrator:v0.129.12
image: signoz/signoz-schema-migrator:v0.129.13
deploy:
restart_policy:
condition: on-failure

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.108.0
image: signoz/signoz:v0.110.1
command:
- --config=/root/config/prometheus.yml
ports:
@@ -150,7 +150,7 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.129.12
image: signoz/signoz-otel-collector:v0.129.13
command:
- --config=/etc/otel-collector-config.yaml
- --manager-config=/etc/manager-config.yaml
@@ -176,7 +176,7 @@ services:
- signoz
schema-migrator:
!!merge <<: *common
image: signoz/signoz-schema-migrator:v0.129.12
image: signoz/signoz-schema-migrator:v0.129.13
deploy:
restart_policy:
condition: on-failure

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.108.0}
image: signoz/signoz:${VERSION:-v0.110.1}
container_name: signoz
command:
- --config=/root/config/prometheus.yml
@@ -213,7 +213,7 @@ services:
# TODO: support otel-collector multiple replicas. Nginx/Traefik for loadbalancing?
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.129.12}
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.129.13}
container_name: signoz-otel-collector
command:
- --config=/etc/otel-collector-config.yaml
@@ -239,7 +239,7 @@ services:
condition: service_healthy
schema-migrator-sync:
!!merge <<: *common
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.13}
container_name: schema-migrator-sync
command:
- sync
@@ -250,7 +250,7 @@ services:
condition: service_healthy
schema-migrator-async:
!!merge <<: *db-depend
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.13}
container_name: schema-migrator-async
command:
- async

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.108.0}
image: signoz/signoz:${VERSION:-v0.110.1}
container_name: signoz
command:
- --config=/root/config/prometheus.yml
@@ -144,7 +144,7 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.129.12}
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.129.13}
container_name: signoz-otel-collector
command:
- --config=/etc/otel-collector-config.yaml
@@ -166,7 +166,7 @@ services:
condition: service_healthy
schema-migrator-sync:
!!merge <<: *common
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.13}
container_name: schema-migrator-sync
command:
- sync
@@ -178,7 +178,7 @@ services:
restart: on-failure
schema-migrator-async:
!!merge <<: *db-depend
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.12}
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-v0.129.13}
container_name: schema-migrator-async
command:
- async

View File

@@ -209,7 +209,7 @@ paths:
/api/v1/dashboards/{id}/public:
delete:
deprecated: false
description: This endpoints deletes the public sharing config and disables the
description: This endpoint deletes the public sharing config and disables the
public sharing of a dashboard
operationId: DeletePublicDashboard
parameters:
@@ -253,7 +253,7 @@ paths:
- dashboard
get:
deprecated: false
description: This endpoints returns public sharing config for a dashboard
description: This endpoint returns public sharing config for a dashboard
operationId: GetPublicDashboard
parameters:
- in: path
@@ -301,7 +301,7 @@ paths:
- dashboard
post:
deprecated: false
description: This endpoints creates public sharing config and enables public
description: This endpoint creates public sharing config and enables public
sharing of the dashboard
operationId: CreatePublicDashboard
parameters:
@@ -355,7 +355,7 @@ paths:
- dashboard
put:
deprecated: false
description: This endpoints updates the public sharing config for a dashboard
description: This endpoint updates the public sharing config for a dashboard
operationId: UpdatePublicDashboard
parameters:
- in: path
@@ -671,7 +671,7 @@ paths:
/api/v1/global/config:
get:
deprecated: false
description: This endpoints returns global config
description: This endpoint returns global config
operationId: GetGlobalConfig
responses:
"200":
@@ -1447,8 +1447,7 @@ paths:
/api/v1/public/dashboards/{id}:
get:
deprecated: false
description: This endpoints returns the sanitized dashboard data for public
access
description: This endpoint returns the sanitized dashboard data for public access
operationId: GetPublicDashboardData
parameters:
- in: path
@@ -1579,6 +1578,228 @@ paths:
summary: Reset password
tags:
- users
/api/v1/roles:
get:
deprecated: false
description: This endpoint lists all roles
operationId: ListRoles
responses:
"200":
content:
application/json:
schema:
properties:
data:
items:
$ref: '#/components/schemas/RoletypesRole'
type: array
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: List roles
tags:
- role
post:
deprecated: false
description: This endpoint creates a role
operationId: CreateRole
responses:
"201":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/TypesIdentifiable'
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 role
tags:
- role
/api/v1/roles/{id}:
delete:
deprecated: false
description: This endpoint deletes a role
operationId: DeleteRole
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"204":
content:
application/json:
schema:
type: string
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 role
tags:
- role
get:
deprecated: false
description: This endpoint gets a role
operationId: GetRole
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/RoletypesRole'
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 role
tags:
- role
patch:
deprecated: false
description: This endpoint patches a role
operationId: PatchRole
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
"204":
content:
application/json:
schema:
type: string
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: Patch role
tags:
- role
/api/v1/user:
get:
deprecated: false
@@ -1985,6 +2206,41 @@ paths:
summary: Update user preference
tags:
- preferences
/api/v2/factor_password/forgot:
post:
deprecated: false
description: This endpoint initiates the forgot password flow by sending a reset
password email
operationId: ForgotPassword
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TypesPostableForgotPassword'
responses:
"204":
description: No Content
"400":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Bad Request
"422":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unprocessable Entity
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
summary: Forgot password
tags:
- users
/api/v2/features:
get:
deprecated: false
@@ -2035,6 +2291,15 @@ paths:
deprecated: false
description: This endpoint returns the ingestion keys for a workspace
operationId: GetIngestionKeys
parameters:
- in: query
name: page
schema:
type: integer
- in: query
name: per_page
schema:
type: integer
responses:
"200":
content:
@@ -2347,6 +2612,19 @@ paths:
deprecated: false
description: This endpoint returns the ingestion keys for a workspace
operationId: SearchIngestionKeys
parameters:
- in: query
name: name
schema:
type: string
- in: query
name: page
schema:
type: integer
- in: query
name: per_page
schema:
type: integer
responses:
"200":
content:
@@ -2390,6 +2668,12 @@ paths:
deprecated: false
description: This endpoint returns associated alerts for a specified metric
operationId: GetMetricAlerts
parameters:
- in: query
name: metricName
required: true
schema:
type: string
responses:
"200":
content:
@@ -2439,6 +2723,12 @@ paths:
deprecated: false
description: This endpoint returns associated dashboards for a specified metric
operationId: GetMetricDashboards
parameters:
- in: query
name: metricName
required: true
schema:
type: string
responses:
"200":
content:
@@ -2489,6 +2779,12 @@ 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
required: true
schema:
type: string
responses:
"200":
content:
@@ -2650,6 +2946,12 @@ 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
required: true
schema:
type: string
responses:
"200":
content:
@@ -3515,6 +3817,9 @@ components:
type: string
alertName:
type: string
required:
- alertName
- alertId
type: object
MetricsexplorertypesMetricAlertsResponse:
properties:
@@ -3523,6 +3828,8 @@ components:
$ref: '#/components/schemas/MetricsexplorertypesMetricAlert'
nullable: true
type: array
required:
- alerts
type: object
MetricsexplorertypesMetricAttribute:
properties:
@@ -3536,6 +3843,10 @@ components:
type: string
nullable: true
type: array
required:
- key
- values
- valueCount
type: object
MetricsexplorertypesMetricAttributesRequest:
properties:
@@ -3547,6 +3858,8 @@ components:
start:
nullable: true
type: integer
required:
- metricName
type: object
MetricsexplorertypesMetricAttributesResponse:
properties:
@@ -3558,6 +3871,9 @@ components:
totalKeys:
format: int64
type: integer
required:
- attributes
- totalKeys
type: object
MetricsexplorertypesMetricDashboard:
properties:
@@ -3569,6 +3885,11 @@ components:
type: string
widgetName:
type: string
required:
- dashboardName
- dashboardId
- widgetId
- widgetName
type: object
MetricsexplorertypesMetricDashboardsResponse:
properties:
@@ -3577,6 +3898,8 @@ components:
$ref: '#/components/schemas/MetricsexplorertypesMetricDashboard'
nullable: true
type: array
required:
- dashboards
type: object
MetricsexplorertypesMetricHighlightsResponse:
properties:
@@ -3592,6 +3915,11 @@ components:
totalTimeSeries:
minimum: 0
type: integer
required:
- dataPoints
- lastReceived
- totalTimeSeries
- activeTimeSeries
type: object
MetricsexplorertypesMetricMetadata:
properties:
@@ -3600,11 +3928,17 @@ components:
isMonotonic:
type: boolean
temporality:
type: string
$ref: '#/components/schemas/MetrictypesTemporality'
type:
type: string
$ref: '#/components/schemas/MetrictypesType'
unit:
type: string
required:
- description
- type
- unit
- temporality
- isMonotonic
type: object
MetricsexplorertypesStat:
properties:
@@ -3619,9 +3953,16 @@ components:
minimum: 0
type: integer
type:
type: string
$ref: '#/components/schemas/MetrictypesType'
unit:
type: string
required:
- metricName
- description
- type
- unit
- timeseries
- samples
type: object
MetricsexplorertypesStatsRequest:
properties:
@@ -3639,6 +3980,10 @@ components:
start:
format: int64
type: integer
required:
- start
- end
- limit
type: object
MetricsexplorertypesStatsResponse:
properties:
@@ -3650,6 +3995,9 @@ components:
total:
minimum: 0
type: integer
required:
- metrics
- total
type: object
MetricsexplorertypesTreemapEntry:
properties:
@@ -3661,7 +4009,16 @@ components:
totalValue:
minimum: 0
type: integer
required:
- metricName
- percentage
- totalValue
type: object
MetricsexplorertypesTreemapMode:
enum:
- timeseries
- samples
type: string
MetricsexplorertypesTreemapRequest:
properties:
end:
@@ -3672,10 +4029,15 @@ components:
limit:
type: integer
mode:
type: string
$ref: '#/components/schemas/MetricsexplorertypesTreemapMode'
start:
format: int64
type: integer
required:
- start
- end
- limit
- mode
type: object
MetricsexplorertypesTreemapResponse:
properties:
@@ -3689,6 +4051,9 @@ components:
$ref: '#/components/schemas/MetricsexplorertypesTreemapEntry'
nullable: true
type: array
required:
- timeseries
- samples
type: object
MetricsexplorertypesUpdateMetricMetadataRequest:
properties:
@@ -3699,12 +4064,33 @@ components:
metricName:
type: string
temporality:
type: string
$ref: '#/components/schemas/MetrictypesTemporality'
type:
type: string
$ref: '#/components/schemas/MetrictypesType'
unit:
type: string
required:
- metricName
- type
- description
- unit
- temporality
- isMonotonic
type: object
MetrictypesTemporality:
enum:
- delta
- cumulative
- unspecified
type: string
MetrictypesType:
enum:
- gauge
- sum
- histogram
- summary
- exponentialhistogram
type: string
PreferencetypesPreference:
properties:
allowedScopes:
@@ -3839,6 +4225,25 @@ components:
status:
type: string
type: object
RoletypesRole:
properties:
createdAt:
format: date-time
type: string
description:
type: string
id:
type: string
name:
type: string
orgId:
type: string
type:
type: string
updatedAt:
format: date-time
type: string
type: object
TypesChangePasswordRequest:
properties:
newPassword:
@@ -3959,6 +4364,18 @@ components:
token:
type: string
type: object
TypesPostableForgotPassword:
properties:
email:
type: string
frontendBaseURL:
type: string
orgId:
type: string
required:
- orgId
- email
type: object
TypesPostableInvite:
properties:
email:
@@ -3979,6 +4396,9 @@ components:
type: object
TypesResetPasswordToken:
properties:
expiresAt:
format: date-time
type: string
id:
type: string
passwordId:

View File

@@ -24,7 +24,7 @@ The configuration file is a JSON array containing data source objects. Each obje
| `label` | `string` | Display name shown to users (e.g., `"AWS EC2"`) |
| `tags` | `string[]` | Array of category tags for grouping (e.g., `["AWS"]`, `["database"]`) |
| `module` | `string` | Destination module after onboarding completion |
| `imgUrl` | `string` | Path to the logo/icon (e.g., `"/Logos/ec2.svg"`) |
| `imgUrl` | `string` | Path to the logo/icon **(SVG required)** (e.g., `"/Logos/ec2.svg"`) |
### Optional Keys

View File

@@ -47,7 +47,7 @@ func (provider *provider) Check(ctx context.Context, tuple *openfgav1.TupleKey)
return provider.pkgAuthzService.Check(ctx, tuple)
}
func (provider *provider) CheckWithTupleCreation(ctx context.Context, claims authtypes.Claims, orgID valuer.UUID, relation authtypes.Relation, _ authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector) error {
func (provider *provider) CheckWithTupleCreation(ctx context.Context, claims authtypes.Claims, orgID valuer.UUID, relation authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector, _ []authtypes.Selector) error {
subject, err := authtypes.NewSubject(authtypes.TypeableUser, claims.UserID, orgID, nil)
if err != nil {
return err
@@ -66,7 +66,7 @@ func (provider *provider) CheckWithTupleCreation(ctx context.Context, claims aut
return nil
}
func (provider *provider) CheckWithTupleCreationWithoutClaims(ctx context.Context, orgID valuer.UUID, relation authtypes.Relation, _ authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector) error {
func (provider *provider) CheckWithTupleCreationWithoutClaims(ctx context.Context, orgID valuer.UUID, relation authtypes.Relation, typeable authtypes.Typeable, selectors []authtypes.Selector, _ []authtypes.Selector) error {
subject, err := authtypes.NewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.String(), orgID, nil)
if err != nil {
return err

View File

@@ -26,12 +26,13 @@ type module struct {
pkgDashboardModule dashboard.Module
store dashboardtypes.Store
settings factory.ScopedProviderSettings
role role.Module
roleSetter role.Setter
granter role.Granter
querier querier.Querier
licensing licensing.Licensing
}
func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, role role.Module, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, roleSetter role.Setter, granter role.Granter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
scopedProviderSettings := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/ee/modules/dashboard/impldashboard")
pkgDashboardModule := pkgimpldashboard.NewModule(store, settings, analytics, orgGetter, queryParser)
@@ -39,7 +40,8 @@ func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, an
pkgDashboardModule: pkgDashboardModule,
store: store,
settings: scopedProviderSettings,
role: role,
roleSetter: roleSetter,
granter: granter,
querier: querier,
licensing: licensing,
}
@@ -59,12 +61,12 @@ func (module *module) CreatePublic(ctx context.Context, orgID valuer.UUID, publi
return errors.Newf(errors.TypeAlreadyExists, dashboardtypes.ErrCodePublicDashboardAlreadyExists, "dashboard with id %s is already public", storablePublicDashboard.DashboardID)
}
role, err := module.role.GetOrCreate(ctx, roletypes.NewRole(roletypes.AnonymousUserRoleName, roletypes.AnonymousUserRoleDescription, roletypes.RoleTypeManaged.StringValue(), orgID))
role, err := module.roleSetter.GetOrCreate(ctx, orgID, roletypes.NewRole(roletypes.SigNozAnonymousRoleName, roletypes.SigNozAnonymousRoleDescription, roletypes.RoleTypeManaged, orgID))
if err != nil {
return err
}
err = module.role.Assign(ctx, role.ID, orgID, authtypes.MustNewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.StringValue(), orgID, nil))
err = module.granter.Grant(ctx, orgID, roletypes.SigNozAnonymousRoleName, authtypes.MustNewSubject(authtypes.TypeableAnonymous, authtypes.AnonymousUser.StringValue(), orgID, nil))
if err != nil {
return err
}
@@ -77,7 +79,7 @@ func (module *module) CreatePublic(ctx context.Context, orgID valuer.UUID, publi
authtypes.MustNewSelector(authtypes.TypeMetaResource, publicDashboard.ID.String()),
)
err = module.role.PatchObjects(ctx, orgID, role.ID, authtypes.RelationRead, []*authtypes.Object{additionObject}, nil)
err = module.roleSetter.PatchObjects(ctx, orgID, role.Name, authtypes.RelationRead, []*authtypes.Object{additionObject}, nil)
if err != nil {
return err
}
@@ -193,7 +195,7 @@ func (module *module) DeletePublic(ctx context.Context, orgID valuer.UUID, dashb
return err
}
role, err := module.role.GetOrCreate(ctx, roletypes.NewRole(roletypes.AnonymousUserRoleName, roletypes.AnonymousUserRoleDescription, roletypes.RoleTypeManaged.StringValue(), orgID))
role, err := module.roleSetter.GetOrCreate(ctx, orgID, roletypes.NewRole(roletypes.SigNozAnonymousRoleName, roletypes.SigNozAnonymousRoleDescription, roletypes.RoleTypeManaged, orgID))
if err != nil {
return err
}
@@ -206,7 +208,7 @@ func (module *module) DeletePublic(ctx context.Context, orgID valuer.UUID, dashb
authtypes.MustNewSelector(authtypes.TypeMetaResource, publicDashboard.ID.String()),
)
err = module.role.PatchObjects(ctx, orgID, role.ID, authtypes.RelationRead, nil, []*authtypes.Object{deletionObject})
err = module.roleSetter.PatchObjects(ctx, orgID, role.Name, authtypes.RelationRead, nil, []*authtypes.Object{deletionObject})
if err != nil {
return err
}
@@ -270,7 +272,7 @@ func (module *module) deletePublic(ctx context.Context, orgID valuer.UUID, dashb
return err
}
role, err := module.role.GetOrCreate(ctx, roletypes.NewRole(roletypes.AnonymousUserRoleName, roletypes.AnonymousUserRoleDescription, roletypes.RoleTypeManaged.StringValue(), orgID))
role, err := module.roleSetter.GetOrCreate(ctx, orgID, roletypes.NewRole(roletypes.SigNozAnonymousRoleName, roletypes.SigNozAnonymousRoleDescription, roletypes.RoleTypeManaged, orgID))
if err != nil {
return err
}
@@ -283,7 +285,7 @@ func (module *module) deletePublic(ctx context.Context, orgID valuer.UUID, dashb
authtypes.MustNewSelector(authtypes.TypeMetaResource, publicDashboard.ID.String()),
)
err = module.role.PatchObjects(ctx, orgID, role.ID, authtypes.RelationRead, nil, []*authtypes.Object{deletionObject})
err = module.roleSetter.PatchObjects(ctx, orgID, role.Name, authtypes.RelationRead, nil, []*authtypes.Object{deletionObject})
if err != nil {
return err
}

View File

@@ -0,0 +1,165 @@
package implrole
import (
"context"
"slices"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/role"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/roletypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
type setter struct {
store roletypes.Store
authz authz.AuthZ
licensing licensing.Licensing
registry []role.RegisterTypeable
}
func NewSetter(store roletypes.Store, authz authz.AuthZ, licensing licensing.Licensing, registry []role.RegisterTypeable) role.Setter {
return &setter{
store: store,
authz: authz,
licensing: licensing,
registry: registry,
}
}
func (setter *setter) Create(ctx context.Context, orgID valuer.UUID, role *roletypes.Role) error {
_, err := setter.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
return setter.store.Create(ctx, roletypes.NewStorableRoleFromRole(role))
}
func (setter *setter) GetOrCreate(ctx context.Context, orgID valuer.UUID, role *roletypes.Role) (*roletypes.Role, error) {
_, err := setter.licensing.GetActive(ctx, orgID)
if err != nil {
return nil, errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
existingRole, err := setter.store.GetByOrgIDAndName(ctx, role.OrgID, role.Name)
if err != nil {
if !errors.Ast(err, errors.TypeNotFound) {
return nil, err
}
}
if existingRole != nil {
return roletypes.NewRoleFromStorableRole(existingRole), nil
}
err = setter.store.Create(ctx, roletypes.NewStorableRoleFromRole(role))
if err != nil {
return nil, err
}
return role, nil
}
func (setter *setter) GetResources(_ context.Context) []*authtypes.Resource {
typeables := make([]authtypes.Typeable, 0)
for _, register := range setter.registry {
typeables = append(typeables, register.MustGetTypeables()...)
}
// role module cannot self register itself!
typeables = append(typeables, setter.MustGetTypeables()...)
resources := make([]*authtypes.Resource, 0)
for _, typeable := range typeables {
resources = append(resources, &authtypes.Resource{Name: typeable.Name(), Type: typeable.Type()})
}
return resources
}
func (setter *setter) GetObjects(ctx context.Context, orgID valuer.UUID, id valuer.UUID, relation authtypes.Relation) ([]*authtypes.Object, error) {
storableRole, err := setter.store.Get(ctx, orgID, id)
if err != nil {
return nil, err
}
objects := make([]*authtypes.Object, 0)
for _, resource := range setter.GetResources(ctx) {
if slices.Contains(authtypes.TypeableRelations[resource.Type], relation) {
resourceObjects, err := setter.
authz.
ListObjects(
ctx,
authtypes.MustNewSubject(authtypes.TypeableRole, storableRole.ID.String(), orgID, &authtypes.RelationAssignee),
relation,
authtypes.MustNewTypeableFromType(resource.Type, resource.Name),
)
if err != nil {
return nil, err
}
objects = append(objects, resourceObjects...)
}
}
return objects, nil
}
func (setter *setter) Patch(ctx context.Context, orgID valuer.UUID, role *roletypes.Role) error {
_, err := setter.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
return setter.store.Update(ctx, orgID, roletypes.NewStorableRoleFromRole(role))
}
func (setter *setter) PatchObjects(ctx context.Context, orgID valuer.UUID, name string, relation authtypes.Relation, additions, deletions []*authtypes.Object) error {
_, err := setter.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
additionTuples, err := roletypes.GetAdditionTuples(name, orgID, relation, additions)
if err != nil {
return err
}
deletionTuples, err := roletypes.GetDeletionTuples(name, orgID, relation, deletions)
if err != nil {
return err
}
err = setter.authz.Write(ctx, additionTuples, deletionTuples)
if err != nil {
return err
}
return nil
}
func (setter *setter) Delete(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error {
_, err := setter.licensing.GetActive(ctx, orgID)
if err != nil {
return errors.New(errors.TypeLicenseUnavailable, errors.CodeLicenseUnavailable, "a valid license is not available").WithAdditional("this feature requires a valid license").WithAdditional(err.Error())
}
storableRole, err := setter.store.Get(ctx, orgID, id)
if err != nil {
return err
}
role := roletypes.NewRoleFromStorableRole(storableRole)
err = role.CanEditDelete()
if err != nil {
return err
}
return setter.store.Delete(ctx, orgID, id)
}
func (setter *setter) MustGetTypeables() []authtypes.Typeable {
return []authtypes.Typeable{authtypes.TypeableRole, roletypes.TypeableResourcesRoles}
}

View File

@@ -50,7 +50,7 @@ type GetAnomaliesResponse struct {
//
// ^ ^
// | |
// (rounded value for past peiod) + (seasonal growth)
// (rounded value for past period) + (seasonal growth)
//
// score = abs(value - prediction) / stddev (current_season_query)
type anomalyQueryParams struct {
@@ -74,12 +74,12 @@ type anomalyQueryParams struct {
// : For daily seasonality, this is the query range params for the (now-2d-5m, now-1d)
// : For hourly seasonality, this is the query range params for the (now-2h-5m, now-1h)
PastSeasonQuery *v3.QueryRangeParamsV3
// Past2SeasonQuery is the query range params for past 2 seasonal period to the current season
// Past2SeasonQuery is the query range params for past 2 seasonal periods to the current season
// Example: For weekly seasonality, this is the query range params for the (now-3w-5m, now-2w)
// : For daily seasonality, this is the query range params for the (now-3d-5m, now-2d)
// : For hourly seasonality, this is the query range params for the (now-3h-5m, now-2h)
Past2SeasonQuery *v3.QueryRangeParamsV3
// Past3SeasonQuery is the query range params for past 3 seasonal period to the current season
// Past3SeasonQuery is the query range params for past 3 seasonal periods to the current season
// Example: For weekly seasonality, this is the query range params for the (now-4w-5m, now-3w)
// : For daily seasonality, this is the query range params for the (now-4d-5m, now-3d)
// : For hourly seasonality, this is the query range params for the (now-4h-5m, now-3h)

View File

@@ -211,7 +211,7 @@ func (s Server) HealthCheckStatus() chan healthcheck.Status {
func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*http.Server, error) {
r := baseapp.NewRouter()
am := middleware.NewAuthZ(s.signoz.Instrumentation.Logger(), s.signoz.Modules.OrgGetter, s.signoz.Authz)
am := middleware.NewAuthZ(s.signoz.Instrumentation.Logger(), s.signoz.Modules.OrgGetter, s.signoz.Authz, s.signoz.Modules.RoleGetter)
r.Use(otelmux.Middleware(
"apiserver",

View File

@@ -234,6 +234,11 @@ func (r *AnomalyRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID, t
}
}
hasData := len(queryResult.AnomalyScores) > 0
if missingDataAlert := r.HandleMissingDataAlert(ctx, ts, hasData); missingDataAlert != nil {
return ruletypes.Vector{*missingDataAlert}, nil
}
var resultVector ruletypes.Vector
scoresJSON, _ := json.Marshal(queryResult.AnomalyScores)
@@ -285,6 +290,11 @@ func (r *AnomalyRule) buildAndRunQueryV5(ctx context.Context, orgID valuer.UUID,
queryResult := transition.ConvertV5TimeSeriesDataToV4Result(qbResult)
hasData := len(queryResult.AnomalyScores) > 0
if missingDataAlert := r.HandleMissingDataAlert(ctx, ts, hasData); missingDataAlert != nil {
return ruletypes.Vector{*missingDataAlert}, nil
}
var resultVector ruletypes.Vector
scoresJSON, _ := json.Marshal(queryResult.AnomalyScores)

View File

@@ -0,0 +1,268 @@
package rules
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/SigNoz/signoz/ee/query-service/anomaly"
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
"github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"github.com/SigNoz/signoz/pkg/telemetrystore"
"github.com/SigNoz/signoz/pkg/telemetrystore/telemetrystoretest"
"github.com/SigNoz/signoz/pkg/types/ruletypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
// mockAnomalyProvider is a mock implementation of anomaly.Provider for testing.
// We need this because the anomaly provider makes 6 different queries for various
// time periods (current, past period, current season, past season, past 2 seasons,
// past 3 seasons), making it cumbersome to create mock data.
type mockAnomalyProvider struct {
responses []*anomaly.GetAnomaliesResponse
callCount int
}
func (m *mockAnomalyProvider) GetAnomalies(ctx context.Context, orgID valuer.UUID, req *anomaly.GetAnomaliesRequest) (*anomaly.GetAnomaliesResponse, error) {
if m.callCount >= len(m.responses) {
return &anomaly.GetAnomaliesResponse{Results: []*v3.Result{}}, nil
}
resp := m.responses[m.callCount]
m.callCount++
return resp, nil
}
func TestAnomalyRule_NoData_AlertOnAbsent(t *testing.T) {
// Test basic AlertOnAbsent functionality (without AbsentFor grace period)
baseTime := time.Unix(1700000000, 0)
evalWindow := 5 * time.Minute
evalTime := baseTime.Add(5 * time.Minute)
target := 500.0
postableRule := ruletypes.PostableRule{
AlertName: "Test anomaly no data",
AlertType: ruletypes.AlertTypeMetric,
RuleType: RuleTypeAnomaly,
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
EvalWindow: ruletypes.Duration(evalWindow),
Frequency: ruletypes.Duration(1 * time.Minute),
}},
RuleCondition: &ruletypes.RuleCondition{
CompareOp: ruletypes.ValueIsAbove,
MatchType: ruletypes.AtleastOnce,
Target: &target,
CompositeQuery: &v3.CompositeQuery{
QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{
"A": {
QueryName: "A",
Expression: "A",
DataSource: v3.DataSourceMetrics,
Temporality: v3.Unspecified,
},
},
},
SelectedQuery: "A",
Seasonality: "daily",
Thresholds: &ruletypes.RuleThresholdData{
Kind: ruletypes.BasicThresholdKind,
Spec: ruletypes.BasicRuleThresholds{{
Name: "Test anomaly no data",
TargetValue: &target,
MatchType: ruletypes.AtleastOnce,
CompareOp: ruletypes.ValueIsAbove,
}},
},
},
}
responseNoData := &anomaly.GetAnomaliesResponse{
Results: []*v3.Result{
{
QueryName: "A",
AnomalyScores: []*v3.Series{},
},
},
}
cases := []struct {
description string
alertOnAbsent bool
expectAlerts int
}{
{
description: "AlertOnAbsent=false",
alertOnAbsent: false,
expectAlerts: 0,
},
{
description: "AlertOnAbsent=true",
alertOnAbsent: true,
expectAlerts: 1,
},
}
logger := instrumentationtest.New().Logger()
for _, c := range cases {
t.Run(c.description, func(t *testing.T) {
postableRule.RuleCondition.AlertOnAbsent = c.alertOnAbsent
telemetryStore := telemetrystoretest.New(telemetrystore.Config{}, nil)
options := clickhouseReader.NewOptions("primaryNamespace")
reader := clickhouseReader.NewReader(nil, telemetryStore, nil, "", time.Second, nil, nil, options)
rule, err := NewAnomalyRule(
"test-anomaly-rule",
valuer.GenerateUUID(),
&postableRule,
reader,
nil,
logger,
nil,
)
require.NoError(t, err)
rule.provider = &mockAnomalyProvider{
responses: []*anomaly.GetAnomaliesResponse{responseNoData},
}
alertsFound, err := rule.Eval(context.Background(), evalTime)
require.NoError(t, err)
assert.Equal(t, c.expectAlerts, alertsFound)
})
}
}
func TestAnomalyRule_NoData_AbsentFor(t *testing.T) {
// Test missing data alert with AbsentFor grace period
// 1. Call Eval with data at time t1, to populate lastTimestampWithDatapoints
// 2. Call Eval without data at time t2
// 3. Alert fires only if t2 - t1 > AbsentFor
baseTime := time.Unix(1700000000, 0)
evalWindow := 5 * time.Minute
// Set target higher than test data so regular threshold alerts don't fire
target := 500.0
postableRule := ruletypes.PostableRule{
AlertName: "Test anomaly no data with AbsentFor",
AlertType: ruletypes.AlertTypeMetric,
RuleType: RuleTypeAnomaly,
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
EvalWindow: ruletypes.Duration(evalWindow),
Frequency: ruletypes.Duration(time.Minute),
}},
RuleCondition: &ruletypes.RuleCondition{
CompareOp: ruletypes.ValueIsAbove,
MatchType: ruletypes.AtleastOnce,
AlertOnAbsent: true,
Target: &target,
CompositeQuery: &v3.CompositeQuery{
QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{
"A": {
QueryName: "A",
Expression: "A",
DataSource: v3.DataSourceMetrics,
Temporality: v3.Unspecified,
},
},
},
SelectedQuery: "A",
Seasonality: "daily",
Thresholds: &ruletypes.RuleThresholdData{
Kind: ruletypes.BasicThresholdKind,
Spec: ruletypes.BasicRuleThresholds{{
Name: "Test anomaly no data with AbsentFor",
TargetValue: &target,
MatchType: ruletypes.AtleastOnce,
CompareOp: ruletypes.ValueIsAbove,
}},
},
},
}
responseNoData := &anomaly.GetAnomaliesResponse{
Results: []*v3.Result{
{
QueryName: "A",
AnomalyScores: []*v3.Series{},
},
},
}
cases := []struct {
description string
absentFor uint64
timeBetweenEvals time.Duration
expectAlertOnEval2 int
}{
{
description: "WithinGracePeriod",
absentFor: 5,
timeBetweenEvals: 4 * time.Minute,
expectAlertOnEval2: 0,
},
{
description: "AfterGracePeriod",
absentFor: 5,
timeBetweenEvals: 6 * time.Minute,
expectAlertOnEval2: 1,
},
}
logger := instrumentationtest.New().Logger()
for _, c := range cases {
t.Run(c.description, func(t *testing.T) {
postableRule.RuleCondition.AbsentFor = c.absentFor
t1 := baseTime.Add(5 * time.Minute)
t2 := t1.Add(c.timeBetweenEvals)
responseWithData := &anomaly.GetAnomaliesResponse{
Results: []*v3.Result{
{
QueryName: "A",
AnomalyScores: []*v3.Series{
{
Labels: map[string]string{"test": "label"},
Points: []v3.Point{
{Timestamp: baseTime.UnixMilli(), Value: 1.0},
{Timestamp: baseTime.Add(time.Minute).UnixMilli(), Value: 1.5},
},
},
},
},
},
}
telemetryStore := telemetrystoretest.New(telemetrystore.Config{}, nil)
options := clickhouseReader.NewOptions("primaryNamespace")
reader := clickhouseReader.NewReader(nil, telemetryStore, nil, "", time.Second, nil, nil, options)
rule, err := NewAnomalyRule("test-anomaly-rule", valuer.GenerateUUID(), &postableRule, reader, nil, logger, nil)
require.NoError(t, err)
rule.provider = &mockAnomalyProvider{
responses: []*anomaly.GetAnomaliesResponse{responseWithData, responseNoData},
}
alertsFound1, err := rule.Eval(context.Background(), t1)
require.NoError(t, err)
assert.Equal(t, 0, alertsFound1, "First eval with data should not alert")
alertsFound2, err := rule.Eval(context.Background(), t2)
require.NoError(t, err)
assert.Equal(t, c.expectAlertOnEval2, alertsFound2)
})
}
}

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', // Correct spellings
],
settings: {
react: {
@@ -47,84 +52,115 @@ 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)
'no-console': ['error', { allow: ['warn', 'error'] }], // Warns on console.log, allows console.warn/error
// TODO: Change this to error in May 2026
'max-params': ['warn', 3], // a function can have max 3 params after which it should become an object
// TypeScript rules
'@typescript-eslint/explicit-function-return-type': 'error', // Requires explicit return types on functions
'@typescript-eslint/no-unused-vars': [
// Disallows unused variables/args
'error',
{
argsIgnorePattern: '^_', // Allows unused args prefixed with _ (e.g., _unusedParam)
varsIgnorePattern: '^_', // Allows unused vars prefixed with _ (e.g., _unusedVar)
},
],
'@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': [
// 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', // Warns about circular dependencies
// Import sorting rules
'simple-import-sort/imports': [
'error',
{
required: {
some: ['nesting', 'id'],
},
groups: [
['^react', '^@?\\w'], // React first, then external packages
['^@/'], // Absolute imports with @ alias
['^\\u0000'], // Side effect imports (import './file')
['^\\.'], // Relative imports
['^.+\\.s?css$'], // Style imports
],
},
],
// 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'],
'simple-import-sort/exports': 'error', // Auto-sorts exports
// 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',
// 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: [
'**/*.test.{js,jsx,ts,tsx}',
'**/*.spec.{js,jsx,ts,tsx}',
'**/__tests__/**/*.{js,jsx,ts,tsx}',
],
rules: {
// Tests often have intentional duplication and complexity - disable SonarJS rules
'sonarjs/cognitive-complexity': 'off', // Tests can be complex
'sonarjs/no-identical-functions': 'off', // Similar test patterns are OK
'sonarjs/no-small-switch': 'off', // Small switches are OK in tests
},
},
{
files: ['src/api/generated/**/*.ts'],
rules: {
@@ -132,7 +168,6 @@ module.exports = {
'@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",

View File

@@ -2,6 +2,11 @@
Embrace the spirit of collaboration and contribute to the success of our open-source project by adhering to these frontend development guidelines with precision and passion.
### Export Style
- **React components** (`src/components/`, `src/container/`, `src/pages/`): Prefer **default exports** for the main component in each file
- **Utilities, hooks, APIs, types, constants** (`src/utils/`, `src/hooks/`, `src/api/`, `src/lib/`, `src/types/`, `src/constants/`): Prefer **named exports** for better tree-shaking and explicit imports
### React and Components
- Strive to create small and modular components, ensuring they are divided into individual pieces for improved maintainability and reusability.

View File

@@ -51,7 +51,7 @@
"@signozhq/checkbox": "0.0.2",
"@signozhq/combobox": "0.0.2",
"@signozhq/command": "0.0.0",
"@signozhq/design-tokens": "1.1.4",
"@signozhq/design-tokens": "2.1.1",
"@signozhq/input": "0.0.2",
"@signozhq/popover": "0.0.0",
"@signozhq/resizable": "0.0.0",
@@ -105,6 +105,7 @@
"i18next": "^21.6.12",
"i18next-browser-languagedetector": "^6.1.3",
"i18next-http-backend": "^1.3.2",
"immer": "11.1.3",
"jest": "^27.5.1",
"js-base64": "^3.7.2",
"less": "^4.1.2",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Groq</title><path d="M12.036 2c-3.853-.035-7 3-7.036 6.781-.035 3.782 3.055 6.872 6.908 6.907h2.42v-2.566h-2.292c-2.407.028-4.38-1.866-4.408-4.23-.029-2.362 1.901-4.298 4.308-4.326h.1c2.407 0 4.358 1.915 4.365 4.278v6.305c0 2.342-1.944 4.25-4.323 4.279a4.375 4.375 0 01-3.033-1.252l-1.851 1.818A7 7 0 0012.029 22h.092c3.803-.056 6.858-3.083 6.879-6.816v-6.5C18.907 4.963 15.817 2 12.036 2z"></path></svg>

After

Width:  |  Height:  |  Size: 568 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet">
<image width="200" height="200" href="data:image/webp;base64,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" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 256 256" preserveAspectRatio="xMidYMid meet">
<image width="256" height="256" href="data:image/webp;base64,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" />
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1,3 +1,6 @@
import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react';
import { useQuery } from 'react-query';
import { matchPath, useLocation } from 'react-router-dom';
import getLocalStorageApi from 'api/browser/localstorage/get';
import setLocalStorageApi from 'api/browser/localstorage/set';
import getAll from 'api/v1/user/get';
@@ -9,9 +12,6 @@ import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
import history from 'lib/history';
import { isEmpty } from 'lodash-es';
import { useAppContext } from 'providers/App/App';
import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react';
import { useQuery } from 'react-query';
import { matchPath, useLocation } from 'react-router-dom';
import { SuccessResponseV2 } from 'types/api';
import APIError from 'types/api/error';
import { LicensePlatform, LicenseState } from 'types/api/licensesV3/getActive';

View File

@@ -1,3 +1,6 @@
import { Suspense, useCallback, useEffect, useState } from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import * as Sentry from '@sentry/react';
import { ConfigProvider } from 'antd';
import getLocalStorageApi from 'api/browser/localstorage/get';
@@ -30,9 +33,6 @@ import { DashboardProvider } from 'providers/Dashboard/Dashboard';
import { ErrorModalProvider } from 'providers/ErrorModalProvider';
import { PreferenceContextProvider } from 'providers/preferences/context/PreferenceContextProvider';
import { QueryBuilderProvider } from 'providers/QueryBuilder';
import { Suspense, useCallback, useEffect, useState } from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { LicenseStatus } from 'types/api/licensesV3/getActive';
import { extractDomain } from 'utils/app';

View File

@@ -1,8 +1,8 @@
import { RouteProps } from 'react-router-dom';
import ROUTES from 'constants/routes';
import AlertTypeSelectionPage from 'pages/AlertTypeSelection';
import MessagingQueues from 'pages/MessagingQueues';
import MeterExplorer from 'pages/MeterExplorer';
import { RouteProps } from 'react-router-dom';
import {
AlertHistory,

View File

@@ -1,7 +1,7 @@
import { initReactI18next } from 'react-i18next';
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';
import cacheBursting from '../../i18n-translations-hash.json';

View File

@@ -36,14 +36,17 @@ 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) =>
GeneratedAPIInstance<ListAuthDomains200>({
export const listAuthDomains = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListAuthDomains200>({
url: `/api/v1/domains`,
method: 'GET',
signal,
});
};
export const getListAuthDomainsQueryKey = () => ['listAuthDomains'] as const;
export const getListAuthDomainsQueryKey = () => {
return ['listAuthDomains'] as const;
};
export const getListAuthDomainsQueryOptions = <
TData = Awaited<ReturnType<typeof listAuthDomains>>,
@@ -122,14 +125,15 @@ export const invalidateListAuthDomains = async (
export const createAuthDomain = (
authtypesPostableAuthDomainDTO: AuthtypesPostableAuthDomainDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreateAuthDomain200>({
) => {
return GeneratedAPIInstance<CreateAuthDomain200>({
url: `/api/v1/domains`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesPostableAuthDomainDTO,
signal,
});
};
export const getCreateAuthDomainMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -201,11 +205,12 @@ export const useCreateAuthDomain = <
* This endpoint deletes an auth domain
* @summary Delete auth domain
*/
export const deleteAuthDomain = ({ id }: DeleteAuthDomainPathParameters) =>
GeneratedAPIInstance<void>({
export const deleteAuthDomain = ({ id }: DeleteAuthDomainPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/domains/${id}`,
method: 'DELETE',
});
};
export const getDeleteAuthDomainMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -280,13 +285,14 @@ export const useDeleteAuthDomain = <
export const updateAuthDomain = (
{ id }: UpdateAuthDomainPathParameters,
authtypesUpdateableAuthDomainDTO: AuthtypesUpdateableAuthDomainDTO,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/domains/${id}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: authtypesUpdateableAuthDomainDTO,
});
};
export const getUpdateAuthDomainMutationOptions = <
TError = RenderErrorResponseDTO,

View File

@@ -39,16 +39,17 @@ 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
* This endpoint deletes the public sharing config and disables the public sharing of a dashboard
* @summary Delete public dashboard
*/
export const deletePublicDashboard = ({
id,
}: DeletePublicDashboardPathParameters) =>
GeneratedAPIInstance<string>({
}: DeletePublicDashboardPathParameters) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
method: 'DELETE',
});
};
export const getDeletePublicDashboardMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -117,22 +118,25 @@ export const useDeletePublicDashboard = <
return useMutation(mutationOptions);
};
/**
* This endpoints returns public sharing config for a dashboard
* This endpoint returns public sharing config for a dashboard
* @summary Get public dashboard
*/
export const getPublicDashboard = (
{ id }: GetPublicDashboardPathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetPublicDashboard200>({
) => {
return GeneratedAPIInstance<GetPublicDashboard200>({
url: `/api/v1/dashboards/${id}/public`,
method: 'GET',
signal,
});
};
export const getGetPublicDashboardQueryKey = ({
id,
}: GetPublicDashboardPathParameters) => ['getPublicDashboard'] as const;
}: GetPublicDashboardPathParameters) => {
return ['getPublicDashboard'] as const;
};
export const getGetPublicDashboardQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboard>>,
@@ -218,21 +222,22 @@ export const invalidateGetPublicDashboard = async (
};
/**
* This endpoints creates public sharing config and enables public sharing of the dashboard
* This endpoint creates public sharing config and enables public sharing of the dashboard
* @summary Create public dashboard
*/
export const createPublicDashboard = (
{ id }: CreatePublicDashboardPathParameters,
dashboardtypesPostablePublicDashboardDTO: DashboardtypesPostablePublicDashboardDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreatePublicDashboard201>({
) => {
return GeneratedAPIInstance<CreatePublicDashboard201>({
url: `/api/v1/dashboards/${id}/public`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: dashboardtypesPostablePublicDashboardDTO,
signal,
});
};
export const getCreatePublicDashboardMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -316,19 +321,20 @@ export const useCreatePublicDashboard = <
return useMutation(mutationOptions);
};
/**
* This endpoints updates the public sharing config for a dashboard
* This endpoint updates the public sharing config for a dashboard
* @summary Update public dashboard
*/
export const updatePublicDashboard = (
{ id }: UpdatePublicDashboardPathParameters,
dashboardtypesUpdatablePublicDashboardDTO: DashboardtypesUpdatablePublicDashboardDTO,
) =>
GeneratedAPIInstance<string>({
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: dashboardtypesUpdatablePublicDashboardDTO,
});
};
export const getUpdatePublicDashboardMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -412,22 +418,25 @@ export const useUpdatePublicDashboard = <
return useMutation(mutationOptions);
};
/**
* This endpoints returns the sanitized dashboard data for public access
* This endpoint returns the sanitized dashboard data for public access
* @summary Get public dashboard data
*/
export const getPublicDashboardData = (
{ id }: GetPublicDashboardDataPathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetPublicDashboardData200>({
) => {
return GeneratedAPIInstance<GetPublicDashboardData200>({
url: `/api/v1/public/dashboards/${id}`,
method: 'GET',
signal,
});
};
export const getGetPublicDashboardDataQueryKey = ({
id,
}: GetPublicDashboardDataPathParameters) => ['getPublicDashboardData'] as const;
}: GetPublicDashboardDataPathParameters) => {
return ['getPublicDashboardData'] as const;
};
export const getGetPublicDashboardDataQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboardData>>,
@@ -519,18 +528,20 @@ export const invalidateGetPublicDashboardData = async (
export const getPublicDashboardWidgetQueryRange = (
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetPublicDashboardWidgetQueryRange200>({
) => {
return GeneratedAPIInstance<GetPublicDashboardWidgetQueryRange200>({
url: `/api/v1/public/dashboards/${id}/widgets/${idx}/query_range`,
method: 'GET',
signal,
});
};
export const getGetPublicDashboardWidgetQueryRangeQueryKey = ({
id,
idx,
}: GetPublicDashboardWidgetQueryRangePathParameters) =>
['getPublicDashboardWidgetQueryRange'] as const;
}: GetPublicDashboardWidgetQueryRangePathParameters) => {
return ['getPublicDashboardWidgetQueryRange'] as const;
};
export const getGetPublicDashboardWidgetQueryRangeQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,

View File

@@ -25,14 +25,17 @@ 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) =>
GeneratedAPIInstance<GetFeatures200>({
export const getFeatures = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetFeatures200>({
url: `/api/v2/features`,
method: 'GET',
signal,
});
};
export const getGetFeaturesQueryKey = () => ['getFeatures'] as const;
export const getGetFeaturesQueryKey = () => {
return ['getFeatures'] as const;
};
export const getGetFeaturesQueryOptions = <
TData = Awaited<ReturnType<typeof getFeatures>>,

View File

@@ -28,8 +28,10 @@ import type {
GatewaytypesPostableIngestionKeyLimitDTO,
GatewaytypesUpdatableIngestionKeyLimitDTO,
GetIngestionKeys200,
GetIngestionKeysParams,
RenderErrorResponseDTO,
SearchIngestionKeys200,
SearchIngestionKeysParams,
UpdateIngestionKeyLimitPathParameters,
UpdateIngestionKeyPathParameters,
} from '../sigNoz.schemas';
@@ -42,32 +44,44 @@ 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) =>
GeneratedAPIInstance<GetIngestionKeys200>({
export const getIngestionKeys = (
params?: GetIngestionKeysParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetIngestionKeys200>({
url: `/api/v2/gateway/ingestion_keys`,
method: 'GET',
params,
signal,
});
};
export const getGetIngestionKeysQueryKey = () => ['getIngestionKeys'] as const;
export const getGetIngestionKeysQueryKey = (
params?: GetIngestionKeysParams,
) => {
return ['getIngestionKeys', ...(params ? [params] : [])] as const;
};
export const getGetIngestionKeysQueryOptions = <
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
TError,
TData
>;
}) => {
>(
params?: GetIngestionKeysParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetIngestionKeysQueryKey();
const queryKey = queryOptions?.queryKey ?? getGetIngestionKeysQueryKey(params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof getIngestionKeys>>> = ({
signal,
}) => getIngestionKeys(signal);
}) => getIngestionKeys(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
@@ -88,14 +102,17 @@ export type GetIngestionKeysQueryError = RenderErrorResponseDTO;
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);
>(
params?: GetIngestionKeysParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getIngestionKeys>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetIngestionKeysQueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
@@ -111,10 +128,11 @@ export function useGetIngestionKeys<
*/
export const invalidateGetIngestionKeys = async (
queryClient: QueryClient,
params?: GetIngestionKeysParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetIngestionKeysQueryKey() },
{ queryKey: getGetIngestionKeysQueryKey(params) },
options,
);
@@ -128,14 +146,15 @@ export const invalidateGetIngestionKeys = async (
export const createIngestionKey = (
gatewaytypesPostableIngestionKeyDTO: GatewaytypesPostableIngestionKeyDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreateIngestionKey200>({
) => {
return GeneratedAPIInstance<CreateIngestionKey200>({
url: `/api/v2/gateway/ingestion_keys`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: gatewaytypesPostableIngestionKeyDTO,
signal,
});
};
export const getCreateIngestionKeyMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -209,11 +228,12 @@ export const useCreateIngestionKey = <
*/
export const deleteIngestionKey = ({
keyId,
}: DeleteIngestionKeyPathParameters) =>
GeneratedAPIInstance<void>({
}: DeleteIngestionKeyPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/${keyId}`,
method: 'DELETE',
});
};
export const getDeleteIngestionKeyMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -288,13 +308,14 @@ export const useDeleteIngestionKey = <
export const updateIngestionKey = (
{ keyId }: UpdateIngestionKeyPathParameters,
gatewaytypesPostableIngestionKeyDTO: GatewaytypesPostableIngestionKeyDTO,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/${keyId}`,
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
data: gatewaytypesPostableIngestionKeyDTO,
});
};
export const getUpdateIngestionKeyMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -385,14 +406,15 @@ export const createIngestionKeyLimit = (
{ keyId }: CreateIngestionKeyLimitPathParameters,
gatewaytypesPostableIngestionKeyLimitDTO: GatewaytypesPostableIngestionKeyLimitDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreateIngestionKeyLimit201>({
) => {
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,
@@ -481,11 +503,12 @@ export const useCreateIngestionKeyLimit = <
*/
export const deleteIngestionKeyLimit = ({
limitId,
}: DeleteIngestionKeyLimitPathParameters) =>
GeneratedAPIInstance<void>({
}: DeleteIngestionKeyLimitPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/limits/${limitId}`,
method: 'DELETE',
});
};
export const getDeleteIngestionKeyLimitMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -560,13 +583,14 @@ export const useDeleteIngestionKeyLimit = <
export const updateIngestionKeyLimit = (
{ limitId }: UpdateIngestionKeyLimitPathParameters,
gatewaytypesUpdatableIngestionKeyLimitDTO: GatewaytypesUpdatableIngestionKeyLimitDTO,
) =>
GeneratedAPIInstance<void>({
) => {
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,
@@ -653,33 +677,45 @@ export const useUpdateIngestionKeyLimit = <
* This endpoint returns the ingestion keys for a workspace
* @summary Search ingestion keys for workspace
*/
export const searchIngestionKeys = (signal?: AbortSignal) =>
GeneratedAPIInstance<SearchIngestionKeys200>({
export const searchIngestionKeys = (
params?: SearchIngestionKeysParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<SearchIngestionKeys200>({
url: `/api/v2/gateway/ingestion_keys/search`,
method: 'GET',
params,
signal,
});
};
export const getSearchIngestionKeysQueryKey = () =>
['searchIngestionKeys'] as const;
export const getSearchIngestionKeysQueryKey = (
params?: SearchIngestionKeysParams,
) => {
return ['searchIngestionKeys', ...(params ? [params] : [])] as const;
};
export const getSearchIngestionKeysQueryOptions = <
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
TError,
TData
>;
}) => {
>(
params?: SearchIngestionKeysParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getSearchIngestionKeysQueryKey();
const queryKey =
queryOptions?.queryKey ?? getSearchIngestionKeysQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof searchIngestionKeys>>
> = ({ signal }) => searchIngestionKeys(signal);
> = ({ signal }) => searchIngestionKeys(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
@@ -700,14 +736,17 @@ export type SearchIngestionKeysQueryError = RenderErrorResponseDTO;
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);
>(
params?: SearchIngestionKeysParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof searchIngestionKeys>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getSearchIngestionKeysQueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
@@ -723,10 +762,11 @@ export function useSearchIngestionKeys<
*/
export const invalidateSearchIngestionKeys = async (
queryClient: QueryClient,
params?: SearchIngestionKeysParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getSearchIngestionKeysQueryKey() },
{ queryKey: getSearchIngestionKeysQueryKey(params) },
options,
);

View File

@@ -25,17 +25,20 @@ type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoints returns global config
* This endpoint returns global config
* @summary Get global config
*/
export const getGlobalConfig = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetGlobalConfig200>({
export const getGlobalConfig = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetGlobalConfig200>({
url: `/api/v1/global/config`,
method: 'GET',
signal,
});
};
export const getGetGlobalConfigQueryKey = () => ['getGlobalConfig'] as const;
export const getGetGlobalConfigQueryKey = () => {
return ['getGlobalConfig'] as const;
};
export const getGetGlobalConfigQueryOptions = <
TData = Awaited<ReturnType<typeof getGlobalConfig>>,

View File

@@ -32,15 +32,17 @@ 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) =>
GeneratedAPIInstance<ListPromotedAndIndexedPaths200>({
export const listPromotedAndIndexedPaths = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListPromotedAndIndexedPaths200>({
url: `/api/v1/logs/promote_paths`,
method: 'GET',
signal,
});
};
export const getListPromotedAndIndexedPathsQueryKey = () =>
['listPromotedAndIndexedPaths'] as const;
export const getListPromotedAndIndexedPathsQueryKey = () => {
return ['listPromotedAndIndexedPaths'] as const;
};
export const getListPromotedAndIndexedPathsQueryOptions = <
TData = Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
@@ -120,14 +122,15 @@ export const invalidateListPromotedAndIndexedPaths = async (
export const handlePromoteAndIndexPaths = (
promotetypesPromotePathDTONull: PromotetypesPromotePathDTO[] | null,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/logs/promote_paths`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: promotetypesPromotePathDTONull,
signal,
});
};
export const getHandlePromoteAndIndexPathsMutationOptions = <
TError = RenderErrorResponseDTO,

View File

@@ -20,10 +20,14 @@ import { useMutation, useQuery } from 'react-query';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetMetricAlerts200,
GetMetricAlertsParams,
GetMetricAttributes200,
GetMetricDashboards200,
GetMetricDashboardsParams,
GetMetricHighlights200,
GetMetricHighlightsParams,
GetMetricMetadata200,
GetMetricMetadataParams,
GetMetricsStats200,
GetMetricsTreemap200,
MetricsexplorertypesMetricAttributesRequestDTO,
@@ -42,32 +46,42 @@ 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 = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetMetricAlerts200>({
export const getMetricAlerts = (
params: GetMetricAlertsParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricAlerts200>({
url: `/api/v2/metric/alerts`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricAlertsQueryKey = () => ['getMetricAlerts'] as const;
export const getGetMetricAlertsQueryKey = (params?: GetMetricAlertsParams) => {
return ['getMetricAlerts', ...(params ? [params] : [])] as const;
};
export const getGetMetricAlertsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
TError,
TData
>;
}) => {
>(
params: GetMetricAlertsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetMetricAlertsQueryKey();
const queryKey = queryOptions?.queryKey ?? getGetMetricAlertsQueryKey(params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof getMetricAlerts>>> = ({
signal,
}) => getMetricAlerts(signal);
}) => getMetricAlerts(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
@@ -88,14 +102,17 @@ export type GetMetricAlertsQueryError = RenderErrorResponseDTO;
export function useGetMetricAlerts<
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricAlerts>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricAlertsQueryOptions(options);
>(
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;
@@ -111,10 +128,11 @@ export function useGetMetricAlerts<
*/
export const invalidateGetMetricAlerts = async (
queryClient: QueryClient,
params: GetMetricAlertsParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricAlertsQueryKey() },
{ queryKey: getGetMetricAlertsQueryKey(params) },
options,
);
@@ -125,33 +143,45 @@ export const invalidateGetMetricAlerts = async (
* This endpoint returns associated dashboards for a specified metric
* @summary Get metric dashboards
*/
export const getMetricDashboards = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetMetricDashboards200>({
export const getMetricDashboards = (
params: GetMetricDashboardsParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricDashboards200>({
url: `/api/v2/metric/dashboards`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricDashboardsQueryKey = () =>
['getMetricDashboards'] as const;
export const getGetMetricDashboardsQueryKey = (
params?: GetMetricDashboardsParams,
) => {
return ['getMetricDashboards', ...(params ? [params] : [])] as const;
};
export const getGetMetricDashboardsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
TError,
TData
>;
}) => {
>(
params: GetMetricDashboardsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetMetricDashboardsQueryKey();
const queryKey =
queryOptions?.queryKey ?? getGetMetricDashboardsQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMetricDashboards>>
> = ({ signal }) => getMetricDashboards(signal);
> = ({ signal }) => getMetricDashboards(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
@@ -172,14 +202,17 @@ export type GetMetricDashboardsQueryError = RenderErrorResponseDTO;
export function useGetMetricDashboards<
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricDashboards>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricDashboardsQueryOptions(options);
>(
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;
@@ -195,10 +228,11 @@ export function useGetMetricDashboards<
*/
export const invalidateGetMetricDashboards = async (
queryClient: QueryClient,
params: GetMetricDashboardsParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricDashboardsQueryKey() },
{ queryKey: getGetMetricDashboardsQueryKey(params) },
options,
);
@@ -209,33 +243,45 @@ export const invalidateGetMetricDashboards = async (
* 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 = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetMetricHighlights200>({
export const getMetricHighlights = (
params: GetMetricHighlightsParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricHighlights200>({
url: `/api/v2/metric/highlights`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricHighlightsQueryKey = () =>
['getMetricHighlights'] as const;
export const getGetMetricHighlightsQueryKey = (
params?: GetMetricHighlightsParams,
) => {
return ['getMetricHighlights', ...(params ? [params] : [])] as const;
};
export const getGetMetricHighlightsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
TError,
TData
>;
}) => {
>(
params: GetMetricHighlightsParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetMetricHighlightsQueryKey();
const queryKey =
queryOptions?.queryKey ?? getGetMetricHighlightsQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMetricHighlights>>
> = ({ signal }) => getMetricHighlights(signal);
> = ({ signal }) => getMetricHighlights(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
@@ -256,14 +302,17 @@ export type GetMetricHighlightsQueryError = RenderErrorResponseDTO;
export function useGetMetricHighlights<
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricHighlights>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricHighlightsQueryOptions(options);
>(
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;
@@ -279,10 +328,11 @@ export function useGetMetricHighlights<
*/
export const invalidateGetMetricHighlights = async (
queryClient: QueryClient,
params: GetMetricHighlightsParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricHighlightsQueryKey() },
{ queryKey: getGetMetricHighlightsQueryKey(params) },
options,
);
@@ -297,14 +347,15 @@ export const updateMetricMetadata = (
{ metricName }: UpdateMetricMetadataPathParameters,
metricsexplorertypesUpdateMetricMetadataRequestDTO: MetricsexplorertypesUpdateMetricMetadataRequestDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<string>({
) => {
return GeneratedAPIInstance<string>({
url: `/api/v2/metrics/${metricName}/metadata`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesUpdateMetricMetadataRequestDTO,
signal,
});
};
export const getUpdateMetricMetadataMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -394,14 +445,15 @@ export const useUpdateMetricMetadata = <
export const getMetricAttributes = (
metricsexplorertypesMetricAttributesRequestDTO: MetricsexplorertypesMetricAttributesRequestDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetMetricAttributes200>({
) => {
return GeneratedAPIInstance<GetMetricAttributes200>({
url: `/api/v2/metrics/attributes`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesMetricAttributesRequestDTO,
signal,
});
};
export const getGetMetricAttributesMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -473,33 +525,45 @@ export const useGetMetricAttributes = <
* This endpoint returns metadata information like metric description, unit, type, temporality, monotonicity for a specified metric
* @summary Get metric metadata
*/
export const getMetricMetadata = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetMetricMetadata200>({
export const getMetricMetadata = (
params: GetMetricMetadataParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricMetadata200>({
url: `/api/v2/metrics/metadata`,
method: 'GET',
params,
signal,
});
};
export const getGetMetricMetadataQueryKey = () =>
['getMetricMetadata'] as const;
export const getGetMetricMetadataQueryKey = (
params?: GetMetricMetadataParams,
) => {
return ['getMetricMetadata', ...(params ? [params] : [])] as const;
};
export const getGetMetricMetadataQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
TError,
TData
>;
}) => {
>(
params: GetMetricMetadataParams,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetMetricMetadataQueryKey();
const queryKey =
queryOptions?.queryKey ?? getGetMetricMetadataQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getMetricMetadata>>
> = ({ signal }) => getMetricMetadata(signal);
> = ({ signal }) => getMetricMetadata(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
@@ -520,14 +584,17 @@ export type GetMetricMetadataQueryError = RenderErrorResponseDTO;
export function useGetMetricMetadata<
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMetricMetadata>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetMetricMetadataQueryOptions(options);
>(
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;
@@ -543,10 +610,11 @@ export function useGetMetricMetadata<
*/
export const invalidateGetMetricMetadata = async (
queryClient: QueryClient,
params: GetMetricMetadataParams,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetMetricMetadataQueryKey() },
{ queryKey: getGetMetricMetadataQueryKey(params) },
options,
);
@@ -560,14 +628,15 @@ export const invalidateGetMetricMetadata = async (
export const getMetricsStats = (
metricsexplorertypesStatsRequestDTO: MetricsexplorertypesStatsRequestDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetMetricsStats200>({
) => {
return GeneratedAPIInstance<GetMetricsStats200>({
url: `/api/v2/metrics/stats`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesStatsRequestDTO,
signal,
});
};
export const getGetMetricsStatsMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -642,14 +711,15 @@ export const useGetMetricsStats = <
export const getMetricsTreemap = (
metricsexplorertypesTreemapRequestDTO: MetricsexplorertypesTreemapRequestDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetMetricsTreemap200>({
) => {
return GeneratedAPIInstance<GetMetricsTreemap200>({
url: `/api/v2/metrics/treemap`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: metricsexplorertypesTreemapRequestDTO,
signal,
});
};
export const getGetMetricsTreemapMutationOptions = <
TError = RenderErrorResponseDTO,

View File

@@ -32,15 +32,17 @@ 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) =>
GeneratedAPIInstance<GetMyOrganization200>({
export const getMyOrganization = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetMyOrganization200>({
url: `/api/v2/orgs/me`,
method: 'GET',
signal,
});
};
export const getGetMyOrganizationQueryKey = () =>
['getMyOrganization'] as const;
export const getGetMyOrganizationQueryKey = () => {
return ['getMyOrganization'] as const;
};
export const getGetMyOrganizationQueryOptions = <
TData = Awaited<ReturnType<typeof getMyOrganization>>,
@@ -118,13 +120,14 @@ export const invalidateGetMyOrganization = async (
*/
export const updateMyOrganization = (
typesOrganizationDTO: TypesOrganizationDTO,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/orgs/me`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: typesOrganizationDTO,
});
};
export const getUpdateMyOrganizationMutationOptions = <
TError = RenderErrorResponseDTO,

View File

@@ -39,15 +39,17 @@ 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) =>
GeneratedAPIInstance<ListOrgPreferences200>({
export const listOrgPreferences = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListOrgPreferences200>({
url: `/api/v1/org/preferences`,
method: 'GET',
signal,
});
};
export const getListOrgPreferencesQueryKey = () =>
['listOrgPreferences'] as const;
export const getListOrgPreferencesQueryKey = () => {
return ['listOrgPreferences'] as const;
};
export const getListOrgPreferencesQueryOptions = <
TData = Awaited<ReturnType<typeof listOrgPreferences>>,
@@ -126,16 +128,19 @@ export const invalidateListOrgPreferences = async (
export const getOrgPreference = (
{ name }: GetOrgPreferencePathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetOrgPreference200>({
) => {
return GeneratedAPIInstance<GetOrgPreference200>({
url: `/api/v1/org/preferences/${name}`,
method: 'GET',
signal,
});
};
export const getGetOrgPreferenceQueryKey = ({
name,
}: GetOrgPreferencePathParameters) => ['getOrgPreference'] as const;
}: GetOrgPreferencePathParameters) => {
return ['getOrgPreference'] as const;
};
export const getGetOrgPreferenceQueryOptions = <
TData = Awaited<ReturnType<typeof getOrgPreference>>,
@@ -227,13 +232,14 @@ export const invalidateGetOrgPreference = async (
export const updateOrgPreference = (
{ name }: UpdateOrgPreferencePathParameters,
preferencetypesUpdatablePreferenceDTO: PreferencetypesUpdatablePreferenceDTO,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/org/preferences/${name}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: preferencetypesUpdatablePreferenceDTO,
});
};
export const getUpdateOrgPreferenceMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -320,15 +326,17 @@ export const useUpdateOrgPreference = <
* This endpoint lists all user preferences
* @summary List user preferences
*/
export const listUserPreferences = (signal?: AbortSignal) =>
GeneratedAPIInstance<ListUserPreferences200>({
export const listUserPreferences = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListUserPreferences200>({
url: `/api/v1/user/preferences`,
method: 'GET',
signal,
});
};
export const getListUserPreferencesQueryKey = () =>
['listUserPreferences'] as const;
export const getListUserPreferencesQueryKey = () => {
return ['listUserPreferences'] as const;
};
export const getListUserPreferencesQueryOptions = <
TData = Awaited<ReturnType<typeof listUserPreferences>>,
@@ -407,16 +415,19 @@ export const invalidateListUserPreferences = async (
export const getUserPreference = (
{ name }: GetUserPreferencePathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetUserPreference200>({
) => {
return GeneratedAPIInstance<GetUserPreference200>({
url: `/api/v1/user/preferences/${name}`,
method: 'GET',
signal,
});
};
export const getGetUserPreferenceQueryKey = ({
name,
}: GetUserPreferencePathParameters) => ['getUserPreference'] as const;
}: GetUserPreferencePathParameters) => {
return ['getUserPreference'] as const;
};
export const getGetUserPreferenceQueryOptions = <
TData = Awaited<ReturnType<typeof getUserPreference>>,
@@ -508,13 +519,14 @@ export const invalidateGetUserPreference = async (
export const updateUserPreference = (
{ name }: UpdateUserPreferencePathParameters,
preferencetypesUpdatablePreferenceDTO: PreferencetypesUpdatablePreferenceDTO,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/user/preferences/${name}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: preferencetypesUpdatablePreferenceDTO,
});
};
export const getUpdateUserPreferenceMutationOptions = <
TError = RenderErrorResponseDTO,

View File

@@ -0,0 +1,433 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'yarn generate:api'
* SigNoz
*/
import type {
InvalidateOptions,
MutationFunction,
QueryClient,
QueryFunction,
QueryKey,
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import { GeneratedAPIInstance } from '../../../index';
import type {
CreateRole201,
DeleteRolePathParameters,
GetRole200,
GetRolePathParameters,
ListRoles200,
PatchRolePathParameters,
RenderErrorResponseDTO,
} from '../sigNoz.schemas';
type AwaitedInput<T> = PromiseLike<T> | T;
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
/**
* This endpoint lists all roles
* @summary List roles
*/
export const listRoles = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListRoles200>({
url: `/api/v1/roles`,
method: 'GET',
signal,
});
};
export const getListRolesQueryKey = () => {
return ['listRoles'] as const;
};
export const getListRolesQueryOptions = <
TData = Awaited<ReturnType<typeof listRoles>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListRolesQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof listRoles>>> = ({
signal,
}) => listRoles(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listRoles>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListRolesQueryResult = NonNullable<
Awaited<ReturnType<typeof listRoles>>
>;
export type ListRolesQueryError = RenderErrorResponseDTO;
/**
* @summary List roles
*/
export function useListRoles<
TData = Awaited<ReturnType<typeof listRoles>>,
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListRolesQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary List roles
*/
export const invalidateListRoles = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListRolesQueryKey() },
options,
);
return queryClient;
};
/**
* This endpoint creates a role
* @summary Create role
*/
export const createRole = (signal?: AbortSignal) => {
return GeneratedAPIInstance<CreateRole201>({
url: `/api/v1/roles`,
method: 'POST',
signal,
});
};
export const getCreateRoleMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createRole>>,
TError,
void,
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createRole>>,
TError,
void,
TContext
> => {
const mutationKey = ['createRole'];
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 createRole>>,
void
> = () => {
return createRole();
};
return { mutationFn, ...mutationOptions };
};
export type CreateRoleMutationResult = NonNullable<
Awaited<ReturnType<typeof createRole>>
>;
export type CreateRoleMutationError = RenderErrorResponseDTO;
/**
* @summary Create role
*/
export const useCreateRole = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createRole>>,
TError,
void,
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createRole>>,
TError,
void,
TContext
> => {
const mutationOptions = getCreateRoleMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint deletes a role
* @summary Delete role
*/
export const deleteRole = ({ id }: DeleteRolePathParameters) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}`,
method: 'DELETE',
});
};
export const getDeleteRoleMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteRole>>,
TError,
{ pathParams: DeleteRolePathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteRole>>,
TError,
{ pathParams: DeleteRolePathParameters },
TContext
> => {
const mutationKey = ['deleteRole'];
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 deleteRole>>,
{ pathParams: DeleteRolePathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deleteRole(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteRoleMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteRole>>
>;
export type DeleteRoleMutationError = RenderErrorResponseDTO;
/**
* @summary Delete role
*/
export const useDeleteRole = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteRole>>,
TError,
{ pathParams: DeleteRolePathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteRole>>,
TError,
{ pathParams: DeleteRolePathParameters },
TContext
> => {
const mutationOptions = getDeleteRoleMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* This endpoint gets a role
* @summary Get role
*/
export const getRole = (
{ id }: GetRolePathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetRole200>({
url: `/api/v1/roles/${id}`,
method: 'GET',
signal,
});
};
export const getGetRoleQueryKey = ({ id }: GetRolePathParameters) => {
return ['getRole'] as const;
};
export const getGetRoleQueryOptions = <
TData = Awaited<ReturnType<typeof getRole>>,
TError = RenderErrorResponseDTO
>(
{ id }: GetRolePathParameters,
options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getRole>>, TError, TData>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetRoleQueryKey({ id });
const queryFn: QueryFunction<Awaited<ReturnType<typeof getRole>>> = ({
signal,
}) => getRole({ id }, signal);
return {
queryKey,
queryFn,
enabled: !!id,
...queryOptions,
} as UseQueryOptions<Awaited<ReturnType<typeof getRole>>, TError, TData> & {
queryKey: QueryKey;
};
};
export type GetRoleQueryResult = NonNullable<
Awaited<ReturnType<typeof getRole>>
>;
export type GetRoleQueryError = RenderErrorResponseDTO;
/**
* @summary Get role
*/
export function useGetRole<
TData = Awaited<ReturnType<typeof getRole>>,
TError = RenderErrorResponseDTO
>(
{ id }: GetRolePathParameters,
options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getRole>>, TError, TData>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetRoleQueryOptions({ id }, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Get role
*/
export const invalidateGetRole = async (
queryClient: QueryClient,
{ id }: GetRolePathParameters,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetRoleQueryKey({ id }) },
options,
);
return queryClient;
};
/**
* This endpoint patches a role
* @summary Patch role
*/
export const patchRole = ({ id }: PatchRolePathParameters) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}`,
method: 'PATCH',
});
};
export const getPatchRoleMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof patchRole>>,
TError,
{ pathParams: PatchRolePathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof patchRole>>,
TError,
{ pathParams: PatchRolePathParameters },
TContext
> => {
const mutationKey = ['patchRole'];
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 patchRole>>,
{ pathParams: PatchRolePathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return patchRole(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type PatchRoleMutationResult = NonNullable<
Awaited<ReturnType<typeof patchRole>>
>;
export type PatchRoleMutationError = RenderErrorResponseDTO;
/**
* @summary Patch role
*/
export const usePatchRole = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof patchRole>>,
TError,
{ pathParams: PatchRolePathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof patchRole>>,
TError,
{ pathParams: PatchRolePathParameters },
TContext
> => {
const mutationOptions = getPatchRoleMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -19,7 +19,6 @@ import { useMutation, useQuery } from 'react-query';
import { GeneratedAPIInstance } from '../../../index';
import type {
AuthtypesDeprecatedPostableLoginDTO,
AuthtypesPostableEmailPasswordSessionDTO,
AuthtypesPostableRotateTokenDTO,
CreateSessionByEmailPassword200,
@@ -28,7 +27,6 @@ import type {
CreateSessionBySAMLCallback303,
CreateSessionBySAMLCallbackBody,
CreateSessionBySAMLCallbackParams,
DeprecatedCreateSessionByEmailPassword200,
GetSessionContext200,
RenderErrorResponseDTO,
RotateSession200,
@@ -42,15 +40,17 @@ 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) =>
GeneratedAPIInstance<unknown>({
export const createSessionByGoogleCallback = (signal?: AbortSignal) => {
return GeneratedAPIInstance<unknown>({
url: `/api/v1/complete/google`,
method: 'GET',
signal,
});
};
export const getCreateSessionByGoogleCallbackQueryKey = () =>
['createSessionByGoogleCallback'] as const;
export const getCreateSessionByGoogleCallbackQueryKey = () => {
return ['createSessionByGoogleCallback'] as const;
};
export const getCreateSessionByGoogleCallbackQueryOptions = <
TData = Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
@@ -129,15 +129,17 @@ export const invalidateCreateSessionByGoogleCallback = async (
* This endpoint creates a session for a user using oidc callback
* @summary Create session by oidc callback
*/
export const createSessionByOIDCCallback = (signal?: AbortSignal) =>
GeneratedAPIInstance<unknown>({
export const createSessionByOIDCCallback = (signal?: AbortSignal) => {
return GeneratedAPIInstance<unknown>({
url: `/api/v1/complete/oidc`,
method: 'GET',
signal,
});
};
export const getCreateSessionByOIDCCallbackQueryKey = () =>
['createSessionByOIDCCallback'] as const;
export const getCreateSessionByOIDCCallbackQueryKey = () => {
return ['createSessionByOIDCCallback'] as const;
};
export const getCreateSessionByOIDCCallbackQueryOptions = <
TData = Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
@@ -328,101 +330,16 @@ export const useCreateSessionBySAMLCallback = <
return useMutation(mutationOptions);
};
/**
* This endpoint is deprecated and will be removed in the future
* @deprecated
* @summary Deprecated create session by email password
*/
export const deprecatedCreateSessionByEmailPassword = (
authtypesDeprecatedPostableLoginDTO: AuthtypesDeprecatedPostableLoginDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<DeprecatedCreateSessionByEmailPassword200>({
url: `/api/v1/login`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesDeprecatedPostableLoginDTO,
signal,
});
export const getDeprecatedCreateSessionByEmailPasswordMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deprecatedCreateSessionByEmailPassword>>,
TError,
{ data: AuthtypesDeprecatedPostableLoginDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deprecatedCreateSessionByEmailPassword>>,
TError,
{ data: AuthtypesDeprecatedPostableLoginDTO },
TContext
> => {
const mutationKey = ['deprecatedCreateSessionByEmailPassword'];
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 deprecatedCreateSessionByEmailPassword>>,
{ data: AuthtypesDeprecatedPostableLoginDTO }
> = (props) => {
const { data } = props ?? {};
return deprecatedCreateSessionByEmailPassword(data);
};
return { mutationFn, ...mutationOptions };
};
export type DeprecatedCreateSessionByEmailPasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof deprecatedCreateSessionByEmailPassword>>
>;
export type DeprecatedCreateSessionByEmailPasswordMutationBody = AuthtypesDeprecatedPostableLoginDTO;
export type DeprecatedCreateSessionByEmailPasswordMutationError = RenderErrorResponseDTO;
/**
* @deprecated
* @summary Deprecated create session by email password
*/
export const useDeprecatedCreateSessionByEmailPassword = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deprecatedCreateSessionByEmailPassword>>,
TError,
{ data: AuthtypesDeprecatedPostableLoginDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deprecatedCreateSessionByEmailPassword>>,
TError,
{ data: AuthtypesDeprecatedPostableLoginDTO },
TContext
> => {
const mutationOptions = getDeprecatedCreateSessionByEmailPasswordMutationOptions(
options,
);
return useMutation(mutationOptions);
};
/**
* This endpoint deletes the session
* @summary Delete session
*/
export const deleteSession = () =>
GeneratedAPIInstance<void>({
export const deleteSession = () => {
return GeneratedAPIInstance<void>({
url: `/api/v2/sessions`,
method: 'DELETE',
});
};
export const getDeleteSessionMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -452,7 +369,9 @@ export const getDeleteSessionMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteSession>>,
void
> = () => deleteSession();
> = () => {
return deleteSession();
};
return { mutationFn, ...mutationOptions };
};
@@ -490,15 +409,17 @@ export const useDeleteSession = <
* This endpoint returns the context for the session
* @summary Get session context
*/
export const getSessionContext = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetSessionContext200>({
export const getSessionContext = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetSessionContext200>({
url: `/api/v2/sessions/context`,
method: 'GET',
signal,
});
};
export const getGetSessionContextQueryKey = () =>
['getSessionContext'] as const;
export const getGetSessionContextQueryKey = () => {
return ['getSessionContext'] as const;
};
export const getGetSessionContextQueryOptions = <
TData = Awaited<ReturnType<typeof getSessionContext>>,
@@ -577,14 +498,15 @@ export const invalidateGetSessionContext = async (
export const createSessionByEmailPassword = (
authtypesPostableEmailPasswordSessionDTO: AuthtypesPostableEmailPasswordSessionDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreateSessionByEmailPassword200>({
) => {
return GeneratedAPIInstance<CreateSessionByEmailPassword200>({
url: `/api/v2/sessions/email_password`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesPostableEmailPasswordSessionDTO,
signal,
});
};
export const getCreateSessionByEmailPasswordMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -661,14 +583,15 @@ export const useCreateSessionByEmailPassword = <
export const rotateSession = (
authtypesPostableRotateTokenDTO: AuthtypesPostableRotateTokenDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<RotateSession200>({
) => {
return GeneratedAPIInstance<RotateSession200>({
url: `/api/v2/sessions/rotate`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: authtypesPostableRotateTokenDTO,
signal,
});
};
export const getRotateSessionMutationOptions = <
TError = RenderErrorResponseDTO,

View File

@@ -70,28 +70,6 @@ export interface AuthtypesCallbackAuthNSupportDTO {
url?: string;
}
export interface AuthtypesDeprecatedGettableLoginDTO {
/**
* @type string
*/
accessJwt?: string;
/**
* @type string
*/
userId?: string;
}
export interface AuthtypesDeprecatedPostableLoginDTO {
/**
* @type string
*/
email?: string;
/**
* @type string
*/
password?: string;
}
export interface AuthtypesGettableAuthDomainDTO {
authNProviderInfo?: AuthtypesAuthNProviderInfoDTO;
/**
@@ -672,11 +650,11 @@ export interface MetricsexplorertypesMetricAlertDTO {
/**
* @type string
*/
alertId?: string;
alertId: string;
/**
* @type string
*/
alertName?: string;
alertName: string;
}
export interface MetricsexplorertypesMetricAlertsResponseDTO {
@@ -684,24 +662,24 @@ export interface MetricsexplorertypesMetricAlertsResponseDTO {
* @type array
* @nullable true
*/
alerts?: MetricsexplorertypesMetricAlertDTO[] | null;
alerts: MetricsexplorertypesMetricAlertDTO[] | null;
}
export interface MetricsexplorertypesMetricAttributeDTO {
/**
* @type string
*/
key?: string;
key: string;
/**
* @type integer
* @minimum 0
*/
valueCount?: number;
valueCount: number;
/**
* @type array
* @nullable true
*/
values?: string[] | null;
values: string[] | null;
}
export interface MetricsexplorertypesMetricAttributesRequestDTO {
@@ -713,7 +691,7 @@ export interface MetricsexplorertypesMetricAttributesRequestDTO {
/**
* @type string
*/
metricName?: string;
metricName: string;
/**
* @type integer
* @nullable true
@@ -726,31 +704,31 @@ export interface MetricsexplorertypesMetricAttributesResponseDTO {
* @type array
* @nullable true
*/
attributes?: MetricsexplorertypesMetricAttributeDTO[] | null;
attributes: MetricsexplorertypesMetricAttributeDTO[] | null;
/**
* @type integer
* @format int64
*/
totalKeys?: number;
totalKeys: number;
}
export interface MetricsexplorertypesMetricDashboardDTO {
/**
* @type string
*/
dashboardId?: string;
dashboardId: string;
/**
* @type string
*/
dashboardName?: string;
dashboardName: string;
/**
* @type string
*/
widgetId?: string;
widgetId: string;
/**
* @type string
*/
widgetName?: string;
widgetName: string;
}
export interface MetricsexplorertypesMetricDashboardsResponseDTO {
@@ -758,7 +736,7 @@ export interface MetricsexplorertypesMetricDashboardsResponseDTO {
* @type array
* @nullable true
*/
dashboards?: MetricsexplorertypesMetricDashboardDTO[] | null;
dashboards: MetricsexplorertypesMetricDashboardDTO[] | null;
}
export interface MetricsexplorertypesMetricHighlightsResponseDTO {
@@ -766,74 +744,65 @@ export interface MetricsexplorertypesMetricHighlightsResponseDTO {
* @type integer
* @minimum 0
*/
activeTimeSeries?: number;
activeTimeSeries: number;
/**
* @type integer
* @minimum 0
*/
dataPoints?: number;
dataPoints: number;
/**
* @type integer
* @minimum 0
*/
lastReceived?: number;
lastReceived: number;
/**
* @type integer
* @minimum 0
*/
totalTimeSeries?: number;
totalTimeSeries: number;
}
export interface MetricsexplorertypesMetricMetadataDTO {
/**
* @type string
*/
description?: string;
description: string;
/**
* @type boolean
*/
isMonotonic?: boolean;
isMonotonic: boolean;
temporality: MetrictypesTemporalityDTO;
type: MetrictypesTypeDTO;
/**
* @type string
*/
temporality?: string;
/**
* @type string
*/
type?: string;
/**
* @type string
*/
unit?: string;
unit: string;
}
export interface MetricsexplorertypesStatDTO {
/**
* @type string
*/
description?: string;
description: string;
/**
* @type string
*/
metricName?: string;
metricName: string;
/**
* @type integer
* @minimum 0
*/
samples?: number;
samples: number;
/**
* @type integer
* @minimum 0
*/
timeseries?: number;
timeseries: number;
type: MetrictypesTypeDTO;
/**
* @type string
*/
type?: string;
/**
* @type string
*/
unit?: string;
unit: string;
}
export interface MetricsexplorertypesStatsRequestDTO {
@@ -841,12 +810,12 @@ export interface MetricsexplorertypesStatsRequestDTO {
* @type integer
* @format int64
*/
end?: number;
end: number;
filter?: Querybuildertypesv5FilterDTO;
/**
* @type integer
*/
limit?: number;
limit: number;
/**
* @type integer
*/
@@ -856,7 +825,7 @@ export interface MetricsexplorertypesStatsRequestDTO {
* @type integer
* @format int64
*/
start?: number;
start: number;
}
export interface MetricsexplorertypesStatsResponseDTO {
@@ -864,51 +833,52 @@ export interface MetricsexplorertypesStatsResponseDTO {
* @type array
* @nullable true
*/
metrics?: MetricsexplorertypesStatDTO[] | null;
metrics: MetricsexplorertypesStatDTO[] | null;
/**
* @type integer
* @minimum 0
*/
total?: number;
total: number;
}
export interface MetricsexplorertypesTreemapEntryDTO {
/**
* @type string
*/
metricName?: string;
metricName: string;
/**
* @type number
* @format double
*/
percentage?: number;
percentage: number;
/**
* @type integer
* @minimum 0
*/
totalValue?: number;
totalValue: number;
}
export enum MetricsexplorertypesTreemapModeDTO {
timeseries = 'timeseries',
samples = 'samples',
}
export interface MetricsexplorertypesTreemapRequestDTO {
/**
* @type integer
* @format int64
*/
end?: number;
end: number;
filter?: Querybuildertypesv5FilterDTO;
/**
* @type integer
*/
limit?: number;
/**
* @type string
*/
mode?: string;
limit: number;
mode: MetricsexplorertypesTreemapModeDTO;
/**
* @type integer
* @format int64
*/
start?: number;
start: number;
}
export interface MetricsexplorertypesTreemapResponseDTO {
@@ -916,41 +886,47 @@ export interface MetricsexplorertypesTreemapResponseDTO {
* @type array
* @nullable true
*/
samples?: MetricsexplorertypesTreemapEntryDTO[] | null;
samples: MetricsexplorertypesTreemapEntryDTO[] | null;
/**
* @type array
* @nullable true
*/
timeseries?: MetricsexplorertypesTreemapEntryDTO[] | null;
timeseries: MetricsexplorertypesTreemapEntryDTO[] | null;
}
export interface MetricsexplorertypesUpdateMetricMetadataRequestDTO {
/**
* @type string
*/
description?: string;
description: string;
/**
* @type boolean
*/
isMonotonic?: boolean;
isMonotonic: boolean;
/**
* @type string
*/
metricName?: string;
metricName: string;
temporality: MetrictypesTemporalityDTO;
type: MetrictypesTypeDTO;
/**
* @type string
*/
temporality?: string;
/**
* @type string
*/
type?: string;
/**
* @type string
*/
unit?: string;
unit: string;
}
export enum MetrictypesTemporalityDTO {
delta = 'delta',
cumulative = 'cumulative',
unspecified = 'unspecified',
}
export enum MetrictypesTypeDTO {
gauge = 'gauge',
sum = 'sum',
histogram = 'histogram',
summary = 'summary',
exponentialhistogram = 'exponentialhistogram',
}
export interface PreferencetypesPreferenceDTO {
/**
* @type array
@@ -1132,6 +1108,39 @@ export interface RenderErrorResponseDTO {
status?: string;
}
export interface RoletypesRoleDTO {
/**
* @type string
* @format date-time
*/
createdAt?: Date;
/**
* @type string
*/
description?: string;
/**
* @type string
*/
id?: string;
/**
* @type string
*/
name?: string;
/**
* @type string
*/
orgId?: string;
/**
* @type string
*/
type?: string;
/**
* @type string
* @format date-time
*/
updatedAt?: Date;
}
export interface TypesChangePasswordRequestDTO {
/**
* @type string
@@ -1332,6 +1341,21 @@ export interface TypesPostableAcceptInviteDTO {
token?: string;
}
export interface TypesPostableForgotPasswordDTO {
/**
* @type string
*/
email: string;
/**
* @type string
*/
frontendBaseURL?: string;
/**
* @type string
*/
orgId: string;
}
export interface TypesPostableInviteDTO {
/**
* @type string
@@ -1363,6 +1387,11 @@ export interface TypesPostableResetPasswordDTO {
}
export interface TypesResetPasswordTokenDTO {
/**
* @type string
* @format date-time
*/
expiresAt?: Date;
/**
* @type string
*/
@@ -1619,14 +1648,6 @@ export type AcceptInvite201 = {
status?: string;
};
export type DeprecatedCreateSessionByEmailPassword200 = {
data?: AuthtypesDeprecatedGettableLoginDTO;
/**
* @type string
*/
status?: string;
};
export type ListPromotedAndIndexedPaths200 = {
/**
* @type array
@@ -1712,6 +1733,42 @@ export type GetPublicDashboardWidgetQueryRange200 = {
status?: string;
};
export type ListRoles200 = {
/**
* @type array
*/
data?: RoletypesRoleDTO[];
/**
* @type string
*/
status?: string;
};
export type CreateRole201 = {
data?: TypesIdentifiableDTO;
/**
* @type string
*/
status?: string;
};
export type DeleteRolePathParameters = {
id: string;
};
export type GetRolePathParameters = {
id: string;
};
export type GetRole200 = {
data?: RoletypesRoleDTO;
/**
* @type string
*/
status?: string;
};
export type PatchRolePathParameters = {
id: string;
};
export type ListUsers200 = {
/**
* @type array
@@ -1792,6 +1849,19 @@ export type GetFeatures200 = {
status?: string;
};
export type GetIngestionKeysParams = {
/**
* @type integer
* @description undefined
*/
page?: number;
/**
* @type integer
* @description undefined
*/
per_page?: number;
};
export type GetIngestionKeys200 = {
data?: GatewaytypesGettableIngestionKeysDTO;
/**
@@ -1831,6 +1901,24 @@ export type DeleteIngestionKeyLimitPathParameters = {
export type UpdateIngestionKeyLimitPathParameters = {
limitId: string;
};
export type SearchIngestionKeysParams = {
/**
* @type string
* @description undefined
*/
name?: string;
/**
* @type integer
* @description undefined
*/
page?: number;
/**
* @type integer
* @description undefined
*/
per_page?: number;
};
export type SearchIngestionKeys200 = {
data?: GatewaytypesGettableIngestionKeysDTO;
/**
@@ -1839,6 +1927,14 @@ export type SearchIngestionKeys200 = {
status?: string;
};
export type GetMetricAlertsParams = {
/**
* @type string
* @description undefined
*/
metricName: string;
};
export type GetMetricAlerts200 = {
data?: MetricsexplorertypesMetricAlertsResponseDTO;
/**
@@ -1847,6 +1943,14 @@ export type GetMetricAlerts200 = {
status?: string;
};
export type GetMetricDashboardsParams = {
/**
* @type string
* @description undefined
*/
metricName: string;
};
export type GetMetricDashboards200 = {
data?: MetricsexplorertypesMetricDashboardsResponseDTO;
/**
@@ -1855,6 +1959,14 @@ export type GetMetricDashboards200 = {
status?: string;
};
export type GetMetricHighlightsParams = {
/**
* @type string
* @description undefined
*/
metricName: string;
};
export type GetMetricHighlights200 = {
data?: MetricsexplorertypesMetricHighlightsResponseDTO;
/**
@@ -1874,6 +1986,14 @@ export type GetMetricAttributes200 = {
status?: string;
};
export type GetMetricMetadataParams = {
/**
* @type string
* @description undefined
*/
metricName: string;
};
export type GetMetricMetadata200 = {
data?: MetricsexplorertypesMetricMetadataDTO;
/**

View File

@@ -40,6 +40,7 @@ import type {
TypesChangePasswordRequestDTO,
TypesPostableAcceptInviteDTO,
TypesPostableAPIKeyDTO,
TypesPostableForgotPasswordDTO,
TypesPostableInviteDTO,
TypesPostableResetPasswordDTO,
TypesStorableAPIKeyDTO,
@@ -61,14 +62,15 @@ export const changePassword = (
{ id }: ChangePasswordPathParameters,
typesChangePasswordRequestDTO: TypesChangePasswordRequestDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/changePassword/${id}`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesChangePasswordRequestDTO,
signal,
});
};
export const getChangePasswordMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -158,16 +160,19 @@ export const useChangePassword = <
export const getResetPasswordToken = (
{ id }: GetResetPasswordTokenPathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetResetPasswordToken200>({
) => {
return GeneratedAPIInstance<GetResetPasswordToken200>({
url: `/api/v1/getResetPasswordToken/${id}`,
method: 'GET',
signal,
});
};
export const getGetResetPasswordTokenQueryKey = ({
id,
}: GetResetPasswordTokenPathParameters) => ['getResetPasswordToken'] as const;
}: GetResetPasswordTokenPathParameters) => {
return ['getResetPasswordToken'] as const;
};
export const getGetResetPasswordTokenQueryOptions = <
TData = Awaited<ReturnType<typeof getResetPasswordToken>>,
@@ -256,14 +261,17 @@ export const invalidateGetResetPasswordToken = async (
* This endpoint lists all invites
* @summary List invites
*/
export const listInvite = (signal?: AbortSignal) =>
GeneratedAPIInstance<ListInvite200>({
export const listInvite = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListInvite200>({
url: `/api/v1/invite`,
method: 'GET',
signal,
});
};
export const getListInviteQueryKey = () => ['listInvite'] as const;
export const getListInviteQueryKey = () => {
return ['listInvite'] as const;
};
export const getListInviteQueryOptions = <
TData = Awaited<ReturnType<typeof listInvite>>,
@@ -334,14 +342,15 @@ export const invalidateListInvite = async (
export const createInvite = (
typesPostableInviteDTO: TypesPostableInviteDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreateInvite201>({
) => {
return GeneratedAPIInstance<CreateInvite201>({
url: `/api/v1/invite`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesPostableInviteDTO,
signal,
});
};
export const getCreateInviteMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -413,11 +422,12 @@ export const useCreateInvite = <
* This endpoint deletes an invite by id
* @summary Delete invite
*/
export const deleteInvite = ({ id }: DeleteInvitePathParameters) =>
GeneratedAPIInstance<void>({
export const deleteInvite = ({ id }: DeleteInvitePathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/invite/${id}`,
method: 'DELETE',
});
};
export const getDeleteInviteMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -492,15 +502,17 @@ export const useDeleteInvite = <
export const getInvite = (
{ token }: GetInvitePathParameters,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<GetInvite200>({
) => {
return GeneratedAPIInstance<GetInvite200>({
url: `/api/v1/invite/${token}`,
method: 'GET',
signal,
});
};
export const getGetInviteQueryKey = ({ token }: GetInvitePathParameters) =>
['getInvite'] as const;
export const getGetInviteQueryKey = ({ token }: GetInvitePathParameters) => {
return ['getInvite'] as const;
};
export const getGetInviteQueryOptions = <
TData = Awaited<ReturnType<typeof getInvite>>,
@@ -581,14 +593,15 @@ export const invalidateGetInvite = async (
export const acceptInvite = (
typesPostableAcceptInviteDTO: TypesPostableAcceptInviteDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<AcceptInvite201>({
) => {
return GeneratedAPIInstance<AcceptInvite201>({
url: `/api/v1/invite/accept`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesPostableAcceptInviteDTO,
signal,
});
};
export const getAcceptInviteMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -663,14 +676,15 @@ export const useAcceptInvite = <
export const createBulkInvite = (
typesPostableInviteDTO: TypesPostableInviteDTO[],
signal?: AbortSignal,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/invite/bulk`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesPostableInviteDTO,
signal,
});
};
export const getCreateBulkInviteMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -742,14 +756,17 @@ export const useCreateBulkInvite = <
* This endpoint lists all api keys
* @summary List api keys
*/
export const listAPIKeys = (signal?: AbortSignal) =>
GeneratedAPIInstance<ListAPIKeys200>({
export const listAPIKeys = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListAPIKeys200>({
url: `/api/v1/pats`,
method: 'GET',
signal,
});
};
export const getListAPIKeysQueryKey = () => ['listAPIKeys'] as const;
export const getListAPIKeysQueryKey = () => {
return ['listAPIKeys'] as const;
};
export const getListAPIKeysQueryOptions = <
TData = Awaited<ReturnType<typeof listAPIKeys>>,
@@ -828,14 +845,15 @@ export const invalidateListAPIKeys = async (
export const createAPIKey = (
typesPostableAPIKeyDTO: TypesPostableAPIKeyDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<CreateAPIKey201>({
) => {
return GeneratedAPIInstance<CreateAPIKey201>({
url: `/api/v1/pats`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesPostableAPIKeyDTO,
signal,
});
};
export const getCreateAPIKeyMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -907,11 +925,12 @@ export const useCreateAPIKey = <
* This endpoint revokes an api key
* @summary Revoke api key
*/
export const revokeAPIKey = ({ id }: RevokeAPIKeyPathParameters) =>
GeneratedAPIInstance<void>({
export const revokeAPIKey = ({ id }: RevokeAPIKeyPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/pats/${id}`,
method: 'DELETE',
});
};
export const getRevokeAPIKeyMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -986,13 +1005,14 @@ export const useRevokeAPIKey = <
export const updateAPIKey = (
{ id }: UpdateAPIKeyPathParameters,
typesStorableAPIKeyDTO: TypesStorableAPIKeyDTO,
) =>
GeneratedAPIInstance<string>({
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/pats/${id}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: typesStorableAPIKeyDTO,
});
};
export const getUpdateAPIKeyMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -1067,14 +1087,15 @@ export const useUpdateAPIKey = <
export const resetPassword = (
typesPostableResetPasswordDTO: TypesPostableResetPasswordDTO,
signal?: AbortSignal,
) =>
GeneratedAPIInstance<void>({
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/resetPassword`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesPostableResetPasswordDTO,
signal,
});
};
export const getResetPasswordMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -1146,14 +1167,17 @@ export const useResetPassword = <
* This endpoint lists all users
* @summary List users
*/
export const listUsers = (signal?: AbortSignal) =>
GeneratedAPIInstance<ListUsers200>({
export const listUsers = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListUsers200>({
url: `/api/v1/user`,
method: 'GET',
signal,
});
};
export const getListUsersQueryKey = () => ['listUsers'] as const;
export const getListUsersQueryKey = () => {
return ['listUsers'] as const;
};
export const getListUsersQueryOptions = <
TData = Awaited<ReturnType<typeof listUsers>>,
@@ -1221,11 +1245,12 @@ export const invalidateListUsers = async (
* This endpoint deletes the user by id
* @summary Delete user
*/
export const deleteUser = ({ id }: DeleteUserPathParameters) =>
GeneratedAPIInstance<void>({
export const deleteUser = ({ id }: DeleteUserPathParameters) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/user/${id}`,
method: 'DELETE',
});
};
export const getDeleteUserMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -1297,15 +1322,20 @@ export const useDeleteUser = <
* This endpoint returns the user by id
* @summary Get user
*/
export const getUser = ({ id }: GetUserPathParameters, signal?: AbortSignal) =>
GeneratedAPIInstance<GetUser200>({
export const getUser = (
{ id }: GetUserPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetUser200>({
url: `/api/v1/user/${id}`,
method: 'GET',
signal,
});
};
export const getGetUserQueryKey = ({ id }: GetUserPathParameters) =>
['getUser'] as const;
export const getGetUserQueryKey = ({ id }: GetUserPathParameters) => {
return ['getUser'] as const;
};
export const getGetUserQueryOptions = <
TData = Awaited<ReturnType<typeof getUser>>,
@@ -1386,13 +1416,14 @@ export const invalidateGetUser = async (
export const updateUser = (
{ id }: UpdateUserPathParameters,
typesUserDTO: TypesUserDTO,
) =>
GeneratedAPIInstance<UpdateUser200>({
) => {
return GeneratedAPIInstance<UpdateUser200>({
url: `/api/v1/user/${id}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: typesUserDTO,
});
};
export const getUpdateUserMutationOptions = <
TError = RenderErrorResponseDTO,
@@ -1464,14 +1495,17 @@ export const useUpdateUser = <
* This endpoint returns the user I belong to
* @summary Get my user
*/
export const getMyUser = (signal?: AbortSignal) =>
GeneratedAPIInstance<GetMyUser200>({
export const getMyUser = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetMyUser200>({
url: `/api/v1/user/me`,
method: 'GET',
signal,
});
};
export const getGetMyUserQueryKey = () => ['getMyUser'] as const;
export const getGetMyUserQueryKey = () => {
return ['getMyUser'] as const;
};
export const getGetMyUserQueryOptions = <
TData = Awaited<ReturnType<typeof getMyUser>>,
@@ -1534,3 +1568,87 @@ export const invalidateGetMyUser = async (
return queryClient;
};
/**
* This endpoint initiates the forgot password flow by sending a reset password email
* @summary Forgot password
*/
export const forgotPassword = (
typesPostableForgotPasswordDTO: TypesPostableForgotPasswordDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/factor_password/forgot`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: typesPostableForgotPasswordDTO,
signal,
});
};
export const getForgotPasswordMutationOptions = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: TypesPostableForgotPasswordDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: TypesPostableForgotPasswordDTO },
TContext
> => {
const mutationKey = ['forgotPassword'];
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 forgotPassword>>,
{ data: TypesPostableForgotPasswordDTO }
> = (props) => {
const { data } = props ?? {};
return forgotPassword(data);
};
return { mutationFn, ...mutationOptions };
};
export type ForgotPasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof forgotPassword>>
>;
export type ForgotPasswordMutationBody = TypesPostableForgotPasswordDTO;
export type ForgotPasswordMutationError = RenderErrorResponseDTO;
/**
* @summary Forgot password
*/
export const useForgotPassword = <
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: TypesPostableForgotPasswordDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: TypesPostableForgotPasswordDTO },
TContext
> => {
const mutationOptions = getForgotPasswordMutationOptions(options);
return useMutation(mutationOptions);
};

View File

@@ -1,6 +1,7 @@
/* eslint-disable sonarjs/cognitive-complexity */
/* eslint-disable no-param-reassign */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { QueryClient } from 'react-query';
import getLocalStorageApi from 'api/browser/localstorage/get';
import post from 'api/v2/sessions/rotate/post';
import afterLogin from 'AppRoutes/utils';
@@ -12,7 +13,6 @@ import axios, {
import { ENVIRONMENT } from 'constants/env';
import { Events } from 'constants/events';
import { LOCALSTORAGE } from 'constants/localStorage';
import { QueryClient } from 'react-query';
import { eventEmitter } from 'utils/getEventEmitter';
import apiV1, {

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

@@ -41,7 +41,7 @@ export const getConsumerLagDetails = async (
> => {
const { detailType, ...restProps } = props;
const response = await axios.post(
`/messaging-queues/kafka/consumer-lag/${props.detailType}`,
`/messaging-queues/kafka/consumer-lag/${detailType}`,
{
...restProps,
},

View File

@@ -1,5 +1,5 @@
import axios from 'api';
import { useMutation, UseMutationResult } from 'react-query';
import axios from 'api';
export interface DeleteDowntimeScheduleProps {
id?: number;

View File

@@ -1,7 +1,7 @@
import { useQuery, UseQueryResult } from 'react-query';
import axios from 'api';
import { AxiosError, AxiosResponse } from 'axios';
import { Option } from 'container/PlannedDowntime/PlannedDowntimeutils';
import { useQuery, UseQueryResult } from 'react-query';
export type Recurrence = {
startTime?: string | null;

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

@@ -1,7 +1,7 @@
import './Filters.styles.scss';
import DateTimeSelector from 'container/TopNav/DateTimeSelectionV2';
import './Filters.styles.scss';
export function Filters(): JSX.Element {
return (
<div className="filters">

View File

@@ -1,10 +1,10 @@
import './AppLoading.styles.scss';
import { Typography } from 'antd';
import get from 'api/browser/localstorage/get';
import { LOCALSTORAGE } from 'constants/localStorage';
import { THEME_MODE } from 'hooks/useDarkMode/constant';
import './AppLoading.styles.scss';
function AppLoading(): JSX.Element {
// Get theme from localStorage directly to avoid context dependency
const getThemeFromStorage = (): boolean => {

View File

@@ -1,9 +1,9 @@
import './AuthError.styles.scss';
import ErrorContent from 'components/ErrorModal/components/ErrorContent';
import { CircleAlert } from 'lucide-react';
import APIError from 'types/api/error';
import './AuthError.styles.scss';
interface AuthErrorProps {
error: APIError;
}

View File

@@ -16,8 +16,8 @@
justify-content: center;
gap: 16px;
padding: 12px;
background: var(--bg-ink-400, #121317);
border: 1px solid var(--bg-ink-200, #23262e);
background: var(--bg-ink-400);
border: 1px solid var(--bg-ink-200);
border-radius: 4px;
}
@@ -49,7 +49,7 @@
font-size: 11px;
font-weight: 400;
line-height: 1;
color: var(--text-neutral-dark-100, #adb4c2);
color: var(--text-neutral-dark-100);
text-align: center;
}
@@ -67,7 +67,7 @@
.auth-footer-link-icon {
flex-shrink: 0;
color: var(--text-neutral-dark-50, #eceef2);
color: var(--text-neutral-dark-50);
}
.auth-footer-link-status {
@@ -84,14 +84,14 @@
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--bg-ink-200, #23262e);
background: var(--bg-ink-200);
flex-shrink: 0;
}
.lightMode {
.auth-footer-content {
background: var(--bg-base-white, #ffffff);
border-color: var(--bg-vanilla-300, #e9e9e9);
background: var(--bg-base-white);
border-color: var(--bg-vanilla-300);
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.08);
}
@@ -102,14 +102,14 @@
}
.auth-footer-text {
color: var(--text-neutral-light-200, #80828d);
color: var(--text-neutral-light-200);
}
.auth-footer-link-icon {
color: var(--text-neutral-light-100, #62636c);
color: var(--text-neutral-light-100);
}
.auth-footer-separator {
background: var(--bg-vanilla-300, #e9e9e9);
background: var(--bg-vanilla-300);
}
}

View File

@@ -1,7 +1,7 @@
import './AuthFooter.styles.scss';
import { ArrowUpRight } from 'lucide-react';
import React from 'react';
import { ArrowUpRight } from 'lucide-react';
import './AuthFooter.styles.scss';
interface FooterItem {
icon?: string;

View File

@@ -30,7 +30,7 @@
font-size: 15.4px;
font-weight: 500;
line-height: 17.5px;
color: var(--text-neutral-dark-50, #eceef2);
color: var(--text-neutral-dark-50);
white-space: nowrap;
}
@@ -41,7 +41,7 @@
gap: 8px;
height: 32px;
padding: 10px 16px;
background: var(--bg-ink-400, #121317);
background: var(--bg-ink-400);
border: none;
border-radius: 2px;
cursor: pointer;
@@ -52,13 +52,13 @@
font-size: 11px;
font-weight: 500;
line-height: 1;
color: var(--text-neutral-dark-100, #adb4c2);
color: var(--text-neutral-dark-100);
text-align: center;
}
svg {
flex-shrink: 0;
color: var(--text-neutral-dark-100, #adb4c2);
color: var(--text-neutral-dark-100);
}
&:hover {
@@ -68,15 +68,15 @@
.lightMode {
.auth-header-logo-text {
color: var(--text-neutral-light-100, #62636c);
color: var(--text-neutral-light-100);
}
.auth-header-help-button {
background: var(--bg-vanilla-200, #f5f5f5);
background: var(--bg-vanilla-200);
span,
svg {
color: var(--text-neutral-light-200, #80828d);
color: var(--text-neutral-light-200);
}
}
}

View File

@@ -1,8 +1,8 @@
import './AuthHeader.styles.scss';
import { useCallback } from 'react';
import { Button } from '@signozhq/button';
import { LifeBuoy } from 'lucide-react';
import { useCallback } from 'react';
import './AuthHeader.styles.scss';
function AuthHeader(): JSX.Element {
const handleGetHelp = useCallback((): void => {

View File

@@ -4,7 +4,7 @@
position: relative;
min-height: 100vh;
width: 100%;
background: var(--bg-neutral-dark-1000, #0a0c10);
background: var(--bg-neutral-dark-1000);
display: flex;
flex-direction: column;
}
@@ -33,7 +33,7 @@
.bg-dot-pattern {
background: radial-gradient(
circle,
var(--bg-neutral-dark-50, #eceef2) 1px,
var(--bg-neutral-dark-50) 1px,
transparent 1px
);
background-size: 12px 12px;
@@ -85,8 +85,8 @@
height: 100%;
background-image: repeating-linear-gradient(
to bottom,
var(--bg-ink-200, #23262e) 0px,
var(--bg-ink-200, #23262e) 4px,
var(--bg-ink-200) 0px,
var(--bg-ink-200) 4px,
transparent 4px,
transparent 8px
);
@@ -146,7 +146,7 @@
.lightMode {
.auth-page-wrapper {
background: var(--bg-base-white, #ffffff);
background: var(--bg-base-white);
}
.bg-dot-pattern {
@@ -172,8 +172,8 @@
.auth-page-line-right {
background-image: repeating-linear-gradient(
to bottom,
var(--bg-vanilla-300, #e9e9e9) 0px,
var(--bg-vanilla-300, #e9e9e9) 4px,
var(--bg-vanilla-300) 0px,
var(--bg-vanilla-300) 4px,
transparent 4px,
transparent 8px
);

View File

@@ -1,10 +1,10 @@
import './AuthPageContainer.styles.scss';
import { PropsWithChildren } from 'react';
import AuthFooter from './AuthFooter';
import AuthHeader from './AuthHeader';
import './AuthPageContainer.styles.scss';
type AuthPageContainerProps = PropsWithChildren<{
isOnboarding?: boolean;
}>;

View File

@@ -1,5 +1,5 @@
import './CeleryOverviewConfigOptions.styles.scss';
import { useCallback, useMemo, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Row, Select, Spin } from 'antd';
import {
getValuesFromQueryParams,
@@ -9,8 +9,8 @@ import { useCeleryFilterOptions } from 'components/CeleryTask/useCeleryFilterOpt
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
import { QueryParams } from 'constants/query';
import useUrlQuery from 'hooks/useUrlQuery';
import { useCallback, useMemo, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import './CeleryOverviewConfigOptions.styles.scss';
export interface SelectOptionConfig {
placeholder: string;

View File

@@ -1,5 +1,6 @@
import './CeleryOverviewTable.styles.scss';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useMutation } from 'react-query';
import { useSelector } from 'react-redux';
import { LoadingOutlined, SearchOutlined } from '@ant-design/icons';
import { Color } from '@signozhq/design-tokens';
import {
@@ -20,7 +21,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';
@@ -28,11 +28,11 @@ import useDragColumns from 'hooks/useDragColumns';
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
import useUrlQuery from 'hooks/useUrlQuery';
import { isEmpty } from 'lodash-es';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
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';
import './CeleryOverviewTable.styles.scss';
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

@@ -1,10 +1,8 @@
import './CeleryTaskConfigOptions.styles.scss';
import { useHistory, useLocation } from 'react-router-dom';
import { Select, Spin, Typography } from 'antd';
import { SelectMaxTagPlaceholder } from 'components/MessagingQueues/MQCommon/MQCommon';
import { QueryParams } from 'constants/query';
import useUrlQuery from 'hooks/useUrlQuery';
import { useHistory, useLocation } from 'react-router-dom';
import {
getValuesFromQueryParams,
@@ -12,6 +10,8 @@ import {
} from '../CeleryUtils';
import { useCeleryFilterOptions } from '../useCeleryFilterOptions';
import './CeleryTaskConfigOptions.styles.scss';
function CeleryTaskConfigOptions(): JSX.Element {
const { handleSearch, isFetching, options } = useCeleryFilterOptions(
'celery.task_name',

View File

@@ -1,10 +1,10 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { DefaultOptionType } from 'antd/es/select';
import { getAttributesValues } from 'api/queryBuilder/getAttributesValues';
import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder';
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
import { useQuery } from 'react-query';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { DataSource } from 'types/common/queryBuilder';
@@ -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

@@ -1,5 +1,4 @@
import './CeleryTaskDetail.style.scss';
import { useState } from 'react';
import { Color, Spacing } from '@signozhq/design-tokens';
import { Divider, Drawer, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
@@ -7,7 +6,6 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
import dayjs from 'dayjs';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { X } from 'lucide-react';
import { useState } from 'react';
import { Widgets } from 'types/api/dashboard/getAll';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { DataSource } from 'types/common/queryBuilder';
@@ -16,6 +14,8 @@ import CeleryTaskGraph from '../CeleryTaskGraph/CeleryTaskGraph';
import { createFiltersFromData } from '../CeleryUtils';
import { useNavigateToExplorer } from '../useNavigateToExplorer';
import './CeleryTaskDetail.style.scss';
export type CeleryTaskData = {
entity: string;
value: string | number;

View File

@@ -1,5 +1,6 @@
import './CeleryTaskGraph.style.scss';
import { useCallback, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { Color } from '@signozhq/design-tokens';
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder';
@@ -10,9 +11,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
import useUrlQuery from 'hooks/useUrlQuery';
import { isEmpty } from 'lodash-es';
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
import { useCallback, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { UpdateTimeInterval } from 'store/actions';
import { AppState } from 'store/reducers';
import { Widgets } from 'types/api/dashboard/getAll';
@@ -39,6 +37,8 @@ import {
CeleryTaskStateGraphConfig,
} from './CeleryTaskStateGraphConfig';
import './CeleryTaskGraph.style.scss';
function CeleryTaskBar({
onClick,
queryEnabled,

View File

@@ -1,3 +1,6 @@
import { useCallback, useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder';
@@ -8,9 +11,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
import useUrlQuery from 'hooks/useUrlQuery';
import { RowData } from 'lib/query/createTableColumnsFromQuery';
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
import { useCallback, useMemo } from 'react';
import { useDispatch } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { UpdateTimeInterval } from 'store/actions';
import { Widgets } from 'types/api/dashboard/getAll';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';

View File

@@ -1,12 +1,10 @@
import './CeleryTaskGraph.style.scss';
import { useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { Card, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import { CardContainer } from 'container/GridCardLayout/styles';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { ChevronDown, ChevronUp } from 'lucide-react';
import { useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { DataSource } from 'types/common/queryBuilder';
@@ -24,6 +22,8 @@ import {
} from './CeleryTaskGraphUtils';
import CeleryTaskLatencyGraph from './CeleryTaskLatencyGraph';
import './CeleryTaskGraph.style.scss';
export default function CeleryTaskGraphGrid({
onClick,
queryEnabled,

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

@@ -1,5 +1,6 @@
import './CeleryTaskGraph.style.scss';
import { useCallback, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { Col, Row } from 'antd';
import logEvent from 'api/common/logEvent';
import { QueryParams } from 'constants/query';
@@ -13,9 +14,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
import useUrlQuery from 'hooks/useUrlQuery';
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
import { useCallback, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { UpdateTimeInterval } from 'store/actions';
import { AppState } from 'store/reducers';
import { DataSource } from 'types/common/queryBuilder';
@@ -29,6 +27,8 @@ import {
import { useNavigateToExplorer } from '../useNavigateToExplorer';
import { celeryTaskLatencyWidgetData } from './CeleryTaskGraphUtils';
import './CeleryTaskGraph.style.scss';
interface TabData {
label: string;
key: string;

View File

@@ -1,11 +1,9 @@
/* eslint-disable no-nested-ternary */
import './CeleryTaskGraph.style.scss';
import { Dispatch, SetStateAction, useMemo } from 'react';
import { Col, Row } from 'antd';
import logEvent from 'api/common/logEvent';
import { QueryParams } from 'constants/query';
import useUrlQuery from 'hooks/useUrlQuery';
import { Dispatch, SetStateAction, useMemo } from 'react';
import {
applyCeleryFilterOnWidgetData,
@@ -19,6 +17,8 @@ import {
} from './CeleryTaskGraphUtils';
import { useGetValueFromWidget } from './useGetValueFromWidget';
import './CeleryTaskGraph.style.scss';
interface TabData {
label: string;
key: string;

View File

@@ -1,10 +1,10 @@
import { useCallback } from 'react';
import { useQueries } from 'react-query';
import { useSelector } from 'react-redux';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
import { getQueryPayloadFromWidgetsData } from 'pages/Celery/CeleryOverview/CeleryOverviewUtils';
import { useCallback } from 'react';
import { useQueries } from 'react-query';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { SuccessResponse } from 'types/api';
import { Widgets } from 'types/api/dashboard/getAll';
@@ -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

@@ -1,6 +1,6 @@
import { useState } from 'react';
import { DefaultOptionType } from 'antd/es/select';
import useDebouncedFn from 'hooks/useDebouncedFunction';
import { useState } from 'react';
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { DataSource } from 'types/common/queryBuilder';

View File

@@ -1,3 +1,5 @@
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
@@ -5,8 +7,6 @@ import useUpdatedQuery from 'container/GridCardLayout/useResolveQuery';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useNotifications } from 'hooks/useNotifications';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
@@ -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

@@ -1,9 +1,9 @@
import './ChangePercentagePill.styles.scss';
import { Color } from '@signozhq/design-tokens';
import cx from 'classnames';
import { ArrowDown, ArrowUp } from 'lucide-react';
import './ChangePercentagePill.styles.scss';
interface ChangePercentagePillProps {
percentage: number;
direction: number;

View File

@@ -1,5 +1,5 @@
import './ChangelogModal.styles.scss';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useMutation } from 'react-query';
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { Button, Modal } from 'antd';
import updateUserPreference from 'api/v1/user/preferences/name/update';
@@ -9,13 +9,13 @@ import dayjs from 'dayjs';
import { useGetTenantLicense } from 'hooks/useGetTenantLicense';
import { ChevronsDown, ScrollText } from 'lucide-react';
import { useAppContext } from 'providers/App/App';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useMutation } from 'react-query';
import { ChangelogSchema } from 'types/api/changelog/getChangelogByVersion';
import { UserPreference } from 'types/api/preferences/preference';
import ChangelogRenderer from './components/ChangelogRenderer';
import './ChangelogModal.styles.scss';
interface Props {
changelog: ChangelogSchema;
onClose: () => void;

View File

@@ -1,7 +1,5 @@
import './ChangelogRenderer.styles.scss';
import dayjs from 'dayjs';
import ReactMarkdown from 'react-markdown';
import dayjs from 'dayjs';
import {
ChangelogSchema,
Media,
@@ -9,6 +7,8 @@ import {
SupportedVideoTypes,
} from 'types/api/changelog/getChangelogByVersion';
import './ChangelogRenderer.styles.scss';
interface Props {
changelog: ChangelogSchema;
}

View File

@@ -1,11 +1,11 @@
import { useState } from 'react';
import { useMutation } from 'react-query';
import { useLocation } from 'react-router-dom';
import { Button, Modal, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import updateCreditCardApi from 'api/v1/checkout/create';
import { useNotifications } from 'hooks/useNotifications';
import { CreditCard, MessageSquareText, X } from 'lucide-react';
import { useState } from 'react';
import { useMutation } from 'react-query';
import { useLocation } from 'react-router-dom';
import { SuccessResponseV2 } from 'types/api';
import { CheckoutSuccessPayloadProps } from 'types/api/billing/checkout';
import APIError from 'types/api/error';

View File

@@ -1,7 +1,13 @@
/* eslint-disable sonarjs/cognitive-complexity */
import './ClientSideQBSearch.styles.scss';
import {
KeyboardEvent,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { Color } from '@signozhq/design-tokens';
import { Select, Tag, Tooltip } from 'antd';
import {
@@ -33,14 +39,6 @@ import { useIsDarkMode } from 'hooks/useDarkMode';
import { isArray, isEmpty, isEqual, isObject } from 'lodash-es';
import { ChevronDown, ChevronUp } from 'lucide-react';
import type { BaseSelectRef } from 'rc-select';
import {
KeyboardEvent,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import {
BaseAutocompleteData,
DataTypes,
@@ -52,6 +50,8 @@ import {
import { popupContainer } from 'utils/selectPopupContainer';
import { v4 as uuid } from 'uuid';
import './ClientSideQBSearch.styles.scss';
export interface AttributeKey {
key: string;
}
@@ -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

@@ -1,9 +1,9 @@
import './Common.styles.scss';
import { Typography } from 'antd';
import APIError from '../../types/api/error';
import './Common.styles.scss';
interface ErrorStateComponentProps {
message?: string;
error?: APIError;

View File

@@ -131,6 +131,45 @@
border-top: 1px solid var(--bg-ink-200);
padding: 8px 14px;
.timezone-container {
display: flex;
align-items: center;
justify-content: space-between;
&__left {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
.timezone__name {
font-size: 12px;
line-height: 16px;
color: var(--bg-robin-400);
font-weight: 500;
}
.timezone__separator {
font-size: 12px;
line-height: 16px;
color: var(--bg-robin-300);
font-weight: 500;
}
.timezone__offset {
font-size: 11px;
line-height: 14px;
color: var(--bg-robin-400);
font-weight: 500;
}
}
&__right {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
&,
.timezone {
font-family: Inter;
@@ -138,6 +177,7 @@
line-height: 16px;
letter-spacing: -0.06px;
}
display: flex;
align-items: center;
color: var(--bg-vanilla-400);
@@ -156,18 +196,21 @@
}
}
}
.timezone-badge {
display: flex;
align-items: center;
justify-content: center;
padding: 0 4px;
border-radius: 2px;
background: rgba(171, 189, 255, 0.04);
color: var(--bg-vanilla-100);
font-size: 12px;
color: var(--bg-vanilla-400);
background-color: var(--bg-ink-200);
font-size: 9px;
font-weight: 400;
line-height: 16px;
letter-spacing: -0.06px;
line-height: 12px;
letter-spacing: -0.045px;
margin-right: 4px;
width: 72px;
cursor: pointer;
}
@@ -183,6 +226,7 @@
font-size: 11px;
color: var(--bg-vanilla-400);
background-color: var(--bg-ink-200);
cursor: pointer;
&.is-live {
background-color: transparent;
@@ -238,11 +282,10 @@
.date-time-popover__footer {
border-color: var(--bg-vanilla-400);
}
.timezone-container {
color: var(--bg-ink-400);
&__clock-icon {
stroke: var(--bg-ink-400);
}
.timezone {
color: var(--bg-ink-100);
background: rgb(179 179 179 / 15%);

View File

@@ -1,10 +1,16 @@
/* eslint-disable sonarjs/cognitive-complexity */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import './CustomTimePicker.styles.scss';
import {
ChangeEvent,
Dispatch,
SetStateAction,
useEffect,
useRef,
useState,
} from 'react';
import { useLocation } from 'react-router-dom';
import { Input, InputRef, Popover, Tooltip } from 'antd';
import logEvent from 'api/common/logEvent';
import cx from 'classnames';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
@@ -18,23 +24,14 @@ import { isValidShortHandDateTimeFormat } from 'lib/getMinMax';
import { defaultTo, isFunction, noop } from 'lodash-es';
import { ChevronDown, ChevronUp } from 'lucide-react';
import { useTimezone } from 'providers/Timezone';
import {
ChangeEvent,
Dispatch,
SetStateAction,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { useLocation } from 'react-router-dom';
import { getTimeDifference, validateEpochRange } from 'utils/epochUtils';
import { popupContainer } from 'utils/selectPopupContainer';
import { TimeRangeValidationResult, validateTimeRange } from 'utils/timeUtils';
import CustomTimePickerPopoverContent from './CustomTimePickerPopoverContent';
import './CustomTimePicker.styles.scss';
const maxAllowedMinTimeInMonths = 15;
type ViewType = 'datetime' | 'timezone';
const DEFAULT_VIEW: ViewType = 'datetime';
@@ -113,22 +110,8 @@ function CustomTimePicker({
const [activeView, setActiveView] = useState<ViewType>(DEFAULT_VIEW);
const { timezone, browserTimezone } = useTimezone();
const { timezone } = useTimezone();
const activeTimezoneOffset = timezone.offset;
const isTimezoneOverridden = useMemo(
() => timezone.offset !== browserTimezone.offset,
[timezone, browserTimezone],
);
const handleViewChange = useCallback(
(newView: 'timezone' | 'datetime'): void => {
if (activeView !== newView) {
setActiveView(newView);
}
setOpen(true);
},
[activeView, setOpen],
);
const [isOpenedFromFooter, setIsOpenedFromFooter] = useState(false);
@@ -371,6 +354,7 @@ function CustomTimePicker({
startTime,
endTime,
DATE_TIME_FORMATS.UK_DATETIME_SECONDS,
timezone.value,
);
if (!isValidTimeRange) {
@@ -422,8 +406,8 @@ function CustomTimePicker({
</div>
);
const handleOpen = (e: React.SyntheticEvent): void => {
e.stopPropagation();
const handleOpen = (e?: React.SyntheticEvent): void => {
e?.stopPropagation?.();
if (showLiveLogs) {
setOpen(true);
@@ -436,12 +420,12 @@ function CustomTimePicker({
// reset the input status and error message as we reset the time to previous correct value
resetErrorStatus();
const startTime = dayjs(minTime / 1000_000).format(
DATE_TIME_FORMATS.UK_DATETIME_SECONDS,
);
const endTime = dayjs(maxTime / 1000_000).format(
DATE_TIME_FORMATS.UK_DATETIME_SECONDS,
);
const startTime = dayjs(minTime / 1000_000)
.tz(timezone.value)
.format(DATE_TIME_FORMATS.UK_DATETIME_SECONDS);
const endTime = dayjs(maxTime / 1000_000)
.tz(timezone.value)
.format(DATE_TIME_FORMATS.UK_DATETIME_SECONDS);
setInputValue(`${startTime} - ${endTime}`);
};
@@ -468,18 +452,6 @@ function CustomTimePicker({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location.pathname]);
const handleTimezoneHintClick = (e: React.MouseEvent): void => {
e.stopPropagation();
handleViewChange('timezone');
setIsOpenedFromFooter(false);
logEvent(
'DateTimePicker: Timezone picker opened from time range input badge',
{
page: location.pathname,
},
);
};
const handleInputBlur = (): void => {
resetErrorStatus();
};
@@ -498,20 +470,28 @@ function CustomTimePicker({
return '';
};
const focusInput = (): void => {
// Use setTimeout to wait for React to update the DOM and make input editable
setTimeout(() => {
const inputElement = inputRef.current?.input;
if (inputElement) {
inputElement.focus();
inputElement.select();
}
}, 100);
};
// Focus and select input text when popover opens
useEffect(() => {
if (open && inputRef.current) {
// Use setTimeout to wait for React to update the DOM and make input editable
setTimeout(() => {
const inputElement = inputRef.current?.input;
if (inputElement) {
inputElement.focus();
inputElement.select();
}
}, 0);
focusInput();
}
}, [open]);
const handleTimezoneChange = (): void => {
focusInput();
};
return (
<div className="custom-time-picker">
<Tooltip title={getTooltipTitle()} placement="top">
@@ -532,6 +512,7 @@ function CustomTimePicker({
customDateTimeVisible={defaultTo(customDateTimeVisible, false)}
onCustomDateHandler={defaultTo(onCustomDateHandler, noop)}
onSelectHandler={handleSelect}
onTimezoneChange={handleTimezoneChange}
onGoLive={defaultTo(onGoLive, noop)}
onExitLiveLogs={defaultTo(onExitLiveLogs, noop)}
options={items}
@@ -583,8 +564,8 @@ function CustomTimePicker({
prefix={getInputPrefix()}
suffix={
<div className="time-input-suffix">
{!!isTimezoneOverridden && activeTimezoneOffset && (
<div className="timezone-badge" onClick={handleTimezoneHintClick}>
{activeTimezoneOffset && (
<div className="timezone-badge">
<span>{activeTimezoneOffset}</span>
</div>
)}

View File

@@ -1,5 +1,12 @@
import './CustomTimePicker.styles.scss';
import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { useLocation } from 'react-router-dom';
import { Color } from '@signozhq/design-tokens';
import { Button } from 'antd';
import logEvent from 'api/common/logEvent';
@@ -16,21 +23,15 @@ import {
import dayjs from 'dayjs';
import { Clock, PenLine, TriangleAlertIcon } from 'lucide-react';
import { useTimezone } from 'providers/Timezone';
import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { useLocation } from 'react-router-dom';
import { getCustomTimeRanges } from 'utils/customTimeRangeUtils';
import { TimeRangeValidationResult } from 'utils/timeUtils';
import CalendarContainer from './CalendarContainer';
import { CustomTimePickerInputStatus } from './CustomTimePicker';
import TimezonePicker from './TimezonePicker';
import { Timezone } from './timezoneUtils';
import './CustomTimePicker.styles.scss';
const TO_MILLISECONDS_FACTOR = 1000_000;
@@ -52,6 +53,7 @@ interface CustomTimePickerPopoverContentProps {
lexicalContext?: LexicalContext,
) => void;
onSelectHandler: (label: string, value: string) => void;
onTimezoneChange: (timezone: Timezone) => void;
onGoLive: () => void;
selectedTime: string;
activeView: 'datetime' | 'timezone';
@@ -101,6 +103,7 @@ function CustomTimePickerPopoverContent({
setCustomDTPickerVisible,
onCustomDateHandler,
onSelectHandler,
onTimezoneChange,
onGoLive,
selectedTime,
activeView,
@@ -208,6 +211,7 @@ function CustomTimePickerPopoverContent({
setActiveView={setActiveView}
setIsOpen={setIsOpen}
isOpenedFromFooter={isOpenedFromFooter}
onTimezoneSelect={onTimezoneChange}
/>
</div>
);
@@ -352,26 +356,30 @@ function CustomTimePickerPopoverContent({
<div className="date-time-popover__footer">
<div className="timezone-container">
<Clock
color={Color.BG_VANILLA_400}
className="timezone-container__clock-icon"
height={12}
width={12}
/>
<span className="timezone__icon">Current timezone</span>
<div></div>
<button
type="button"
className="timezone"
onClick={handleTimezoneHintClick}
>
<span>{activeTimezoneOffset}</span>
<PenLine
color={Color.BG_VANILLA_100}
className="timezone__icon"
size={10}
<div className="timezone-container__left">
<Clock
color={Color.BG_ROBIN_400}
className="timezone-container__clock-icon"
height={12}
width={12}
/>
</button>
<span className="timezone__name">{timezone.name}</span>
<span className="timezone__separator"></span>
<span className="timezone__offset">{activeTimezoneOffset}</span>
</div>
<div className="timezone-container__right">
<Button
type="text"
size="small"
className="periscope-btn text timezone-change-button"
onClick={handleTimezoneHintClick}
icon={<PenLine size={10} />}
>
Change Timezone
</Button>
</div>
</div>
</div>
</>

View File

@@ -1,6 +1,6 @@
/* eslint-disable react/jsx-props-no-spreading */
import './RangePickerModal.styles.scss';
import { Dispatch, SetStateAction, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { DatePicker } from 'antd';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
@@ -11,11 +11,11 @@ import {
} from 'container/TopNav/DateTimeSelectionV2/types';
import dayjs, { Dayjs } from 'dayjs';
import { useTimezone } from 'providers/Timezone';
import { Dispatch, SetStateAction, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
import './RangePickerModal.styles.scss';
interface RangePickerModalProps {
setCustomDTPickerVisible: Dispatch<SetStateAction<boolean>>;
setIsOpen: Dispatch<SetStateAction<boolean>>;

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