Compare commits

..

2 Commits

Author SHA1 Message Date
Nityananda Gohain
0436655a43 Merge branch 'main' into issue_5123_2 2026-06-08 12:34:18 +05:30
nityanandagohain
301d496092 chore: add normalize for QueryRangeRequest 2026-06-05 12:31:19 +05:30
750 changed files with 7997 additions and 84953 deletions

View File

@@ -64,10 +64,6 @@ jobs:
run: |
mkdir -p frontend
echo 'CI=1' > frontend/.env
echo 'VITE_SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
echo 'VITE_SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
echo 'VITE_SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
echo 'VITE_SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
echo 'VITE_TUNNEL_URL="${{ secrets.NP_TUNNEL_URL }}"' >> frontend/.env
echo 'VITE_TUNNEL_DOMAIN="${{ secrets.NP_TUNNEL_DOMAIN }}"' >> frontend/.env
echo 'VITE_PYLON_APP_ID="${{ secrets.NP_PYLON_APP_ID }}"' >> frontend/.env

View File

@@ -39,12 +39,10 @@ jobs:
matrix:
suite:
- alerts
- basepath
- callbackauthn
- cloudintegrations
- dashboard
- ingestionkeys
- inframonitoring
- logspipelines
- passwordauthn
- preference
@@ -85,7 +83,7 @@ jobs:
run: |
cd tests && uv sync
- name: webdriver
if: matrix.suite == 'callbackauthn' || matrix.suite == 'basepath'
if: matrix.suite == 'callbackauthn'
run: |
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list.d/google-chrome.list

View File

@@ -19,8 +19,5 @@
"editor.defaultFormatter": "vscode.html-language-features"
},
"python-envs.defaultEnvManager": "ms-python.python:system",
"python-envs.pythonProjects": [],
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
}
"python-envs.pythonProjects": []
}

View File

@@ -91,7 +91,7 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
sqlstoreProviderFactories(),
signoz.NewTelemetryStoreProviderFactories(),
func(ctx context.Context, providerSettings factory.ProviderSettings, store authtypes.AuthNStore, licensing licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
return signoz.NewAuthNs(ctx, providerSettings, store, licensing, config.Global)
return signoz.NewAuthNs(ctx, providerSettings, store, licensing)
},
func(ctx context.Context, sqlstore sqlstore.SQLStore, config authz.Config, _ licensing.Licensing, _ []authz.OnBeforeRoleDelete) (factory.ProviderFactory[authz.AuthZ, authz.Config], error) {
openfgaDataStore, err := openfgaserver.NewSQLStore(sqlstore, config)

View File

@@ -107,17 +107,17 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
sqlstoreProviderFactories(),
signoz.NewTelemetryStoreProviderFactories(),
func(ctx context.Context, providerSettings factory.ProviderSettings, store authtypes.AuthNStore, licensing licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
samlCallbackAuthN, err := samlcallbackauthn.New(ctx, store, licensing, config.Global)
samlCallbackAuthN, err := samlcallbackauthn.New(ctx, store, licensing)
if err != nil {
return nil, err
}
oidcCallbackAuthN, err := oidccallbackauthn.New(store, licensing, providerSettings, config.Global)
oidcCallbackAuthN, err := oidccallbackauthn.New(store, licensing, providerSettings)
if err != nil {
return nil, err
}
authNs, err := signoz.NewAuthNs(ctx, providerSettings, store, licensing, config.Global)
authNs, err := signoz.NewAuthNs(ctx, providerSettings, store, licensing)
if err != nil {
return nil, err
}

View File

@@ -440,17 +440,6 @@ traces:
max_depth_to_auto_expand: 5
# Threshold below which all spans are returned without windowing.
max_limit_to_select_all_spans: 10000
flamegraph:
# Maximum number of BFS depth levels included in a windowed response.
max_selected_levels: 50
# Maximum spans per level before sampling is applied.
max_spans_per_level: 100
# Number of highest-latency spans always included when sampling a level.
sampling_top_latency_count: 5
# Number of timestamp buckets used for uniform sampling within a level.
sampling_bucket_count: 50
# Threshold below which all spans are returned without windowing or sampling.
select_all_spans_limit: 100000
##################### Authz #################################
authz:

View File

@@ -190,7 +190,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:v0.129.0
image: signoz/signoz:v0.127.1
ports:
- "8080:8080" # signoz port
# - "6060:6060" # pprof port

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.129.0
image: signoz/signoz:v0.127.1
ports:
- "8080:8080" # signoz port
volumes:

View File

@@ -181,7 +181,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.129.0}
image: signoz/signoz:${VERSION:-v0.127.1}
container_name: signoz
ports:
- "8080:8080" # signoz port

View File

@@ -109,7 +109,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.129.0}
image: signoz/signoz:${VERSION:-v0.127.1}
container_name: signoz
ports:
- "8080:8080" # signoz port

File diff suppressed because it is too large Load Diff

View File

@@ -109,20 +109,6 @@ func (h *handler) CreateThing(rw http.ResponseWriter, req *http.Request) {
}
```
When you need an ID from `claims` as a `valuer.UUID` (for example to pass it to a module), derive it with the `Must*` constructor instead of `NewUUID` plus an error check. Claims are validated by the auth middleware, so the conversion cannot fail and the error branch would be dead code:
```go
// Good — claims are pre-validated, the conversion cannot fail.
orgID := valuer.MustNewUUID(claims.OrgID)
// Avoid — the error path is unreachable.
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
```
### 3. Register the handler in `signozapiserver`
In `pkg/apiserver/signozapiserver`, add a route in the appropriate `add*Routes` function (`addUserRoutes`, `addSessionRoutes`, `addOrgRoutes`, etc.). The pattern is:
@@ -347,50 +333,6 @@ func (Step) JSONSchema() (jsonschema.Schema, error) {
}
```
### `oneOf` with a discriminator
For a sum type whose variants are keyed by a property (e.g. `kind`), expose the variants via `JSONSchemaOneOf()` and add a discriminator. Without it, code generators intersect the variants (`A & B & C`) instead of producing a clean discriminated union (`A | B | C`).
The parent keeps its `JSONSchemaOneOf()` (the `oneOf` itself) and *additionally* tags it via `PrepareJSONSchema` with the `x-signoz-discriminator` extension; `signoz.attachDiscriminators` then promotes that marker to a real OpenAPI 3 `discriminator` (and strips the duplicate parent properties) after reflection.
```go
// On the parent: expose the oneOf variants...
func (Plugin) JSONSchemaOneOf() []any {
return []any{FooVariant{}}
}
// ...and tag that same oneOf with the discriminator marker.
func (Plugin) PrepareJSONSchema(s *jsonschema.Schema) error {
if s.ExtraProperties == nil {
s.ExtraProperties = map[string]any{}
}
s.ExtraProperties["x-signoz-discriminator"] = map[string]any{
"propertyName": "kind",
"mapping": map[string]string{
"signoz/Foo": "#/components/schemas/FooVariant",
},
}
return nil
}
```
Each variant must declare the discriminator property (`kind`) and mark it `required`.
This produces the following in the generated OpenAPI spec:
```yaml
Plugin:
discriminator:
propertyName: kind
mapping:
signoz/Foo: '#/components/schemas/FooVariant'
oneOf:
- $ref: '#/components/schemas/FooVariant'
type: object
```
Note the discriminator property lives in the variants, not on the parent — the parent is only the union.
## What should I remember?
@@ -401,4 +343,3 @@ Note the discriminator property lives in the variants, not on the parent — the
- **Add `nullable:"true"`** on fields that can be `null`. Pay special attention to slices and maps -- in Go these default to `nil` which serializes to `null`. If the field should always be an array, initialize it and do not mark it nullable.
- **Implement `Enum()`** on every type that has a fixed set of acceptable values so the JSON schema generates proper `enum` constraints.
- **Add request examples** via `RequestExamples` in `OpenAPIDef` for any non-trivial endpoint. See `pkg/apiserver/signozapiserver/querier.go` for reference.
- **Derive IDs from `claims` with `valuer.MustNewUUID`** (e.g. `claims.OrgID`, `claims.UserID`). Claims are pre-validated by the auth middleware, so use the `Must*` constructor — don't write `NewUUID` followed by an `if err != nil { render.Error(...); return }` block.

View File

@@ -5,12 +5,10 @@ import (
"fmt"
"log/slog"
"net/url"
"path"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/http/client"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/types/authtypes"
@@ -28,14 +26,13 @@ var defaultScopes []string = []string{"email", "profile", oidc.ScopeOpenID}
var _ authn.CallbackAuthN = (*AuthN)(nil)
type AuthN struct {
settings factory.ScopedProviderSettings
store authtypes.AuthNStore
licensing licensing.Licensing
httpClient *client.Client
globalConfig global.Config
settings factory.ScopedProviderSettings
store authtypes.AuthNStore
licensing licensing.Licensing
httpClient *client.Client
}
func New(store authtypes.AuthNStore, licensing licensing.Licensing, providerSettings factory.ProviderSettings, globalConfig global.Config) (*AuthN, error) {
func New(store authtypes.AuthNStore, licensing licensing.Licensing, providerSettings factory.ProviderSettings) (*AuthN, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/ee/authn/callbackauthn/oidccallbackauthn")
httpClient, err := client.New(providerSettings.Logger, providerSettings.TracerProvider, providerSettings.MeterProvider)
@@ -44,11 +41,10 @@ func New(store authtypes.AuthNStore, licensing licensing.Licensing, providerSett
}
return &AuthN{
settings: settings,
store: store,
licensing: licensing,
httpClient: httpClient,
globalConfig: globalConfig,
settings: settings,
store: store,
licensing: licensing,
httpClient: httpClient,
}, nil
}
@@ -201,7 +197,7 @@ func (a *AuthN) oidcProviderAndoauth2Config(ctx context.Context, siteURL *url.UR
RedirectURL: (&url.URL{
Scheme: siteURL.Scheme,
Host: siteURL.Host,
Path: path.Join(a.globalConfig.ExternalPath(), redirectPath),
Path: redirectPath,
}).String(),
}, nil
}

View File

@@ -6,12 +6,10 @@ import (
"encoding/base64"
"encoding/pem"
"net/url"
"path"
"strings"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/valuer"
@@ -26,16 +24,14 @@ const (
var _ authn.CallbackAuthN = (*AuthN)(nil)
type AuthN struct {
store authtypes.AuthNStore
licensing licensing.Licensing
globalConfig global.Config
store authtypes.AuthNStore
licensing licensing.Licensing
}
func New(ctx context.Context, store authtypes.AuthNStore, licensing licensing.Licensing, globalConfig global.Config) (*AuthN, error) {
func New(ctx context.Context, store authtypes.AuthNStore, licensing licensing.Licensing) (*AuthN, error) {
return &AuthN{
store: store,
licensing: licensing,
globalConfig: globalConfig,
store: store,
licensing: licensing,
}, nil
}
@@ -136,7 +132,7 @@ func (a *AuthN) serviceProvider(siteURL *url.URL, authDomain *authtypes.AuthDoma
return nil, err
}
acsURL := &url.URL{Scheme: siteURL.Scheme, Host: siteURL.Host, Path: path.Join(a.globalConfig.ExternalPath(), redirectPath)}
acsURL := &url.URL{Scheme: siteURL.Scheme, Host: siteURL.Host, Path: redirectPath}
// Note:
// The ServiceProviderIssuer is the client id in case of keycloak. Since we set it to the host here, we need to set the client id == host in keycloak.

View File

@@ -217,10 +217,6 @@ func (module *module) CreateV2(ctx context.Context, orgID valuer.UUID, createdBy
return module.pkgDashboardModule.CreateV2(ctx, orgID, createdBy, creator, source, postable)
}
func (module *module) CloneV2(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error) {
return module.pkgDashboardModule.CloneV2(ctx, orgID, createdBy, creator, id)
}
func (module *module) GetV2(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error) {
return module.pkgDashboardModule.GetV2(ctx, orgID, id)
}
@@ -233,55 +229,10 @@ func (module *module) PatchV2(ctx context.Context, orgID valuer.UUID, id valuer.
return module.pkgDashboardModule.PatchV2(ctx, orgID, id, updatedBy, patch)
}
func (module *module) DeleteV2(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error {
return module.store.RunInTx(ctx, func(ctx context.Context) error {
if err := module.store.DeletePublic(ctx, id.String()); err != nil && !errors.Ast(err, errors.TypeNotFound) {
return err
}
return module.pkgDashboardModule.DeleteV2(ctx, orgID, id)
})
}
func (module *module) LockUnlockV2(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, isAdmin bool, lock bool) error {
return module.pkgDashboardModule.LockUnlockV2(ctx, orgID, id, updatedBy, isAdmin, lock)
}
func (module *module) ListV2(ctx context.Context, orgID valuer.UUID, params *dashboardtypes.ListDashboardsV2Params) (*dashboardtypes.ListableDashboardV2, error) {
return module.pkgDashboardModule.ListV2(ctx, orgID, params)
}
func (module *module) ListForUserV2(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, params *dashboardtypes.ListDashboardsV2Params) (*dashboardtypes.ListableDashboardForUserV2, error) {
return module.pkgDashboardModule.ListForUserV2(ctx, orgID, userID, params)
}
func (module *module) PinV2(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, id valuer.UUID) error {
return module.pkgDashboardModule.PinV2(ctx, orgID, userID, id)
}
func (module *module) UnpinV2(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, id valuer.UUID) error {
return module.pkgDashboardModule.UnpinV2(ctx, orgID, userID, id)
}
func (module *module) DeletePreferencesForUser(ctx context.Context, orgID valuer.UUID, userID valuer.UUID) error {
return module.pkgDashboardModule.DeletePreferencesForUser(ctx, orgID, userID)
}
func (module *module) CreateView(ctx context.Context, orgID valuer.UUID, postable dashboardtypes.PostableDashboardView) (*dashboardtypes.DashboardView, error) {
return module.pkgDashboardModule.CreateView(ctx, orgID, postable)
}
func (module *module) ListViews(ctx context.Context, orgID valuer.UUID) (*dashboardtypes.ListableDashboardView, error) {
return module.pkgDashboardModule.ListViews(ctx, orgID)
}
func (module *module) UpdateView(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updateable dashboardtypes.UpdatableDashboardView) (*dashboardtypes.DashboardView, error) {
return module.pkgDashboardModule.UpdateView(ctx, orgID, id, updateable)
}
func (module *module) DeleteView(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error {
return module.pkgDashboardModule.DeleteView(ctx, orgID, id)
}
func (module *module) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.Dashboard, error) {
return module.pkgDashboardModule.Get(ctx, orgID, id)
}

View File

@@ -3,13 +3,13 @@ package querier
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
anomalyV2 "github.com/SigNoz/signoz/ee/anomaly"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/http/binding"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/types/authtypes"
@@ -48,8 +48,8 @@ func (h *handler) QueryRange(rw http.ResponseWriter, req *http.Request) {
}
var queryRangeRequest qbtypes.QueryRangeRequest
if err := binding.JSON.BindBody(req.Body, &queryRangeRequest); err != nil {
render.Error(rw, err)
if err := json.NewDecoder(req.Body).Decode(&queryRangeRequest); err != nil {
render.Error(rw, errors.NewInvalidInputf(errors.CodeInvalidInput, "failed to decode request body: %v", err))
return
}

View File

@@ -10,6 +10,7 @@ import (
"go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
"go.opentelemetry.io/otel/propagation"
"github.com/SigNoz/signoz/pkg/cache/memorycache"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/gorilla/handlers"
@@ -19,6 +20,7 @@ import (
"github.com/SigNoz/signoz/ee/query-service/app/api"
"github.com/SigNoz/signoz/ee/query-service/usage"
"github.com/SigNoz/signoz/pkg/cache"
"github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/web"
@@ -57,12 +59,25 @@ type Server struct {
// NewServer creates and initializes Server
func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
cacheForTraceDetail, err := memorycache.New(context.TODO(), signoz.Instrumentation.ToProviderSettings(), cache.Config{
Provider: "memory",
Memory: cache.Memory{
NumCounters: 10 * 10000,
MaxCost: 1 << 27, // 128 MB
},
})
if err != nil {
return nil, err
}
reader := clickhouseReader.NewReader(
signoz.Instrumentation.Logger(),
signoz.SQLStore,
signoz.TelemetryStore,
signoz.Prometheus,
signoz.TelemetryStore.Cluster(),
config.Querier.FluxInterval,
cacheForTraceDetail,
signoz.Cache,
nil,
)
@@ -170,7 +185,6 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*h
s.config.APIServer.Timeout.Default,
s.config.APIServer.Timeout.Max,
).Wrap)
r.Use(middleware.NewResource(s.signoz.Instrumentation.Logger()).Wrap)
r.Use(middleware.NewAudit(s.signoz.Instrumentation.Logger(), s.config.APIServer.Logging.ExcludedRoutes, s.signoz.Auditor).Wrap)
r.Use(middleware.NewComment().Wrap)

View File

@@ -16,11 +16,10 @@ func newFormatter(dialect schema.Dialect) sqlstore.SQLFormatter {
}
func (f *formatter) JSONExtractString(column, path string) []byte {
ops := f.convertJSONPathToPostgres(path)
if len(ops) == 0 {
return f.bunf.AppendIdent(nil, column)
}
return append(f.TextToJsonColumn(column), ops...)
var sql []byte
sql = f.bunf.AppendIdent(sql, column)
sql = append(sql, f.convertJSONPathToPostgres(path)...)
return sql
}
func (f *formatter) JSONType(column, path string) []byte {

View File

@@ -18,19 +18,19 @@ func TestJSONExtractString(t *testing.T) {
name: "simple path",
column: "data",
path: "$.field",
expected: `"data"::jsonb->>'field'`,
expected: `"data"->>'field'`,
},
{
name: "nested path",
column: "metadata",
path: "$.user.name",
expected: `"metadata"::jsonb->'user'->>'name'`,
expected: `"metadata"->'user'->>'name'`,
},
{
name: "deeply nested path",
column: "json_col",
path: "$.level1.level2.level3",
expected: `"json_col"::jsonb->'level1'->'level2'->>'level3'`,
expected: `"json_col"->'level1'->'level2'->>'level3'`,
},
{
name: "root path",

View File

@@ -291,8 +291,6 @@
// Prevents the usage of specific antd components in favor of our lib
"signoz/no-signozhq-ui-barrel": "error",
// Forces subpath imports (@signozhq/ui/<component>) instead of the eagerly-loaded barrel
"signoz/no-css-module-bracket-access": "warn",
// Prevents bracket access on CSS modules (styles['kebab-case']) which fails with camelCaseOnly config
"no-restricted-globals": [
"error",
{

View File

@@ -2,33 +2,9 @@
const path = require('path');
module.exports = {
plugins: [
path.join(__dirname, 'stylelint-rules/no-unsupported-asset-url.js'),
path.join(__dirname, 'stylelint-rules/css-modules/no-deep-nesting.js'),
path.join(__dirname, 'stylelint-rules/css-modules/no-id-selectors.js'),
path.join(
__dirname,
'stylelint-rules/css-modules/no-bare-element-selectors.js',
),
path.join(__dirname, 'stylelint-rules/css-modules/prefer-css-variables.js'),
path.join(__dirname, 'stylelint-rules/css-modules/class-name-pattern.js'),
],
plugins: [path.join(__dirname, 'stylelint-rules/no-unsupported-asset-url.js')],
customSyntax: 'postcss-scss',
rules: {
// Applies to all SCSS files
'local/no-unsupported-asset-url': true,
},
overrides: [
{
// CSS module-specific rules
files: ['**/*.module.scss'],
rules: {
'local/no-deep-nesting': [true, { severity: 'warning' }],
'local/no-id-selectors': true,
'local/no-bare-element-selectors': true,
'local/prefer-css-variables': [true, { severity: 'warning' }],
'local/class-name-pattern': [true, { severity: 'warning' }],
},
},
],
};

View File

@@ -23,8 +23,6 @@ You are operating within a constrained context window and strict system prompts.
- Always add data-testid or testId (if supported) to critical/behavioral components like inputs, buttons, etc...
- When creating test, these IDs should be used instead of finding by role.
- Never create barrel files.
- When writing new css, prefer CSS Modules
- Use ./docs/css-modules-guide.md as reference on how to write good CSS Modules.
3. FORCED VERIFICATION: Your internal tools mark file writes as successful even if the code does not compile. You are FORBIDDEN from reporting a task as complete until you have:
- Run `pnpm tsgo --noEmit`

View File

@@ -1,513 +0,0 @@
# CSS Modules Guide
## Checklist Before Committing
- [ ] All class names use camelCase in CSS
- [ ] State classes use `is-`/`has-` prefix (e.g., `isActive`, `hasError`)
- [ ] No bracket access (`styles['...']`) in JS unless verified
- [ ] No dynamic class lookup - use explicit variant maps instead
- [ ] No deep class nesting (max 3 class levels; pseudo-classes/elements and parent-reference selectors like `&.active`, `&#bar` are not counted)
- [ ] No hardcoded colors - use `--l1/l2/l3-*` semantic tokens (not `--bg-*` primitives)
- [ ] No magic numbers - use `--spacing-*` tokens
- [ ] Typography uses `--periscope-font-size-*` or `--font-size-*` tokens
- [ ] @signozhq/ui overrides use CSS variables, not direct class overrides
- [ ] Global escapes only for third-party overrides
- [ ] No ID selectors
- [ ] No bare element selectors
- [ ] Keyframes use `:local(@keyframes name)` to avoid global collisions
## Config (vite.config.ts)
```ts
css: {
modules: {
localsConvention: 'camelCaseOnly',
},
}
```
**Critical:** `camelCaseOnly` exports ONLY camelCase keys. Original kebab-case NOT accessible.
## Quick Reference
| CSS Class | JS Access | Works? | Preferred? |
|-----------|-----------|--------|----------------------------|
| `.alertHistory` | `styles.alertHistory` | Yes | Yes |
| `.alert-history` | `styles.alertHistory` | Yes | No, use `.alertHistory` |
| `.alert-history` | `styles['alert-history']` | NO - undefined | Never, use `.alertHistory` |
## Bad Patterns
### Class Naming
```scss
// BAD: Bracket access won't work
.my-class { }
// Then in JS: styles['my-class'] -> undefined
// BAD: Collision - both become same key
.alertHistory { }
.alert-history { } // -> styles.alertHistory (conflicts)
// BAD: Underscore inconsistency
.my_class { } // -> styles.myClass (confusing)
// GOOD: Direct camelCase
.alertHistory { }
.statsCard { }
// GOOD: State classes with is-/has- prefix
.isDisabled { }
.isActive { }
.hasError { }
.isLoading { }
```
### Nesting
```scss
// BAD: Deep nesting - specificity wars, hard to override
.container {
.wrapper {
.inner {
.content { }
}
}
}
// BAD: Nesting creates separate classes you might not expect
.button {
.icon { } // -> styles.icon (separate class, not scoped under .button)
}
// GOOD: Flat structure
.container { }
.containerWrapper { }
.containerContent { }
// GOOD: Nesting only for pseudo/states
.button {
&:hover { }
&:disabled { }
&::before { }
}
```
### Global Escapes
```scss
// BAD: Overusing global
:global {
.everything { }
.in-here { }
.is-global { }
}
// BAD: Global without necessity
:global(.myComponent) { } // defeats purpose of modules
// GOOD: Targeted global for third-party overrides
.container {
:global(.ant-modal-content) {
padding: 0;
}
}
```
### Selectors
```scss
// BAD: ID selectors - not reusable
#myComponent { }
// BAD: Element selectors without scope
div { } // affects ALL divs in component
// BAD: Complex selectors
.container > div + span ~ p { }
// GOOD: Class-only selectors
.container { }
.title { }
```
### Variables & Values
```scss
// BAD: Hardcoded colors
.button {
background: #1890ff;
color: white;
}
// BAD: Magic numbers
.container {
padding: 17px;
margin-left: 43px;
}
// GOOD: Semantic tokens (theme-aware)
.button {
background: var(--primary-background);
color: var(--primary-foreground);
}
.card {
background: var(--l2-background);
color: var(--l2-foreground);
}
// GOOD: Spacing system
.container {
padding: var(--spacing-4);
margin-left: var(--spacing-5);
}
```
## Design Tokens (@signozhq/design-tokens)
Prefer semantic tokens over hardcoded values.
You can read the ./node_modules/@signozhq/design-tokens/dist/style.css to find complete list of available tokens.
### Spacing
```scss
// Spacing scale (index -> px):
// --spacing-0=0 --spacing-1=2 --spacing-2=4 --spacing-3=6 --spacing-4=8
// --spacing-5=10 --spacing-6=12 --spacing-7=14 --spacing-8=16 --spacing-10=20
// --spacing-12=24 --spacing-16=32 --spacing-20=40 --spacing-24=48 --spacing-32=64
// --spacing-40=80 --spacing-48=96 --spacing-56=112 --spacing-64=128
// (index != px; --spacing-2 is 4px, not 2px)
.container {
padding: var(--spacing-4); // 8px
gap: var(--spacing-6); // 12px
margin-bottom: var(--spacing-8); // 16px
}
// Also available: --padding-* and --margin-* (rem-based)
// --padding-1 = 0.25rem, --padding-4 = 1rem, etc.
```
### Typography
```scss
// Font sizes (preferred)
.title {
font-size: var(--periscope-font-size-large); // 18px
font-size: var(--periscope-font-size-medium); // 16px
font-size: var(--periscope-font-size-base); // 13px
font-size: var(--periscope-font-size-small); // 11px
}
// Alternative scale (rem-based)
.heading {
font-size: var(--font-size-xl); // 1.25rem
font-size: var(--font-size-lg); // 1.125rem
font-size: var(--font-size-base); // 1rem
font-size: var(--font-size-sm); // 0.875rem
}
// Font weights
.bold {
font-weight: var(--font-weight-semibold); // 600
font-weight: var(--font-weight-medium); // 500
font-weight: var(--font-weight-normal); // 400
}
// Line heights
.text {
line-height: var(--line-height-20); // 20px
line-height: var(--line-height-24); // 24px
}
```
### Colors (Prefer Semantic Tokens)
Use L1/L2/L3 semantic tokens - they handle light/dark theme automatically.
```scss
// BAD: Primitive tokens (fixed value across themes, won't swap on theme change)
.card {
background: var(--bg-ink-400);
color: var(--text-vanilla-100);
}
// GOOD: L1/L2/L3 tokens (theme-aware - swap automatically light/dark)
.card {
background: var(--l1-background); // base layer
color: var(--l1-foreground); // primary text
}
.panel {
background: var(--l2-background); // elevated surface
color: var(--l2-foreground); // secondary text
border-color: var(--l2-border);
}
.nested {
background: var(--l3-background); // nested/inset
color: var(--l3-foreground); // tertiary text
}
// Hover states
.card:hover {
background: var(--l1-background-hover);
color: var(--l1-foreground-hover);
}
// Semantic action colors (also theme-aware)
.primary {
background: var(--primary-background);
color: var(--primary-foreground);
}
.danger {
background: var(--danger-background);
color: var(--danger-foreground);
}
.success {
background: var(--success-background);
color: var(--success-foreground);
}
.warning {
background: var(--warning-background);
color: var(--warning-foreground);
}
// Accent colors (for highlights, badges, etc.)
.accent {
background: var(--accent-primary); // robin blue
background: var(--accent-forest); // green
background: var(--accent-cherry); // red
background: var(--accent-amber); // yellow
}
```
**Token hierarchy:**
- Primitive tokens (`--bg-*`, `--text-*`, etc.) have fixed values across themes.
- Semantic tokens (L1/L2/L3, `--primary-*`, `--danger-*`, etc.) automatically swap based on theme.
- L1 = base/root layer
- L2 = elevated surfaces (cards, panels)
- L3 = nested/inset elements
## Overriding @signozhq/ui Components
Components expose CSS variables for customization.
You can ensure they exist by looking at ./node_modules/@signozhq/ui/dist.
Never write a override without confirm it exists.
Override via:
### Method 1: CSS Variables (Preferred)
Each component exposes `--<component>-<property>` variables:
```scss
// Override Button
.customButton {
--button-background: var(--success-background);
--button-border-radius: var(--radius-2);
--button-padding: var(--spacing-4) var(--spacing-8);
--button-font-size: var(--periscope-font-size-base);
}
// Override Input
.customInput {
--input-height: 2.5rem;
--input-border-color: var(--l2-border);
--input-padding: var(--spacing-2) var(--spacing-6);
--input-placeholder-color: var(--l3-foreground);
}
// Override nested parts
.customInput {
--input-prefix-padding: 0 var(--spacing-4) 0 var(--spacing-6);
--input-suffix-color: var(--accent-primary);
}
```
### Method 2: Data Attributes
Components use data attributes for variants/states. Target them for state-specific overrides:
```scss
// Target variant
.wrapper :global([data-variant="outlined"]) {
--button-border-color: var(--accent-primary);
}
// Target size
.wrapper :global([data-size="sm"]) {
--button-font-size: var(--periscope-font-size-small);
}
// Target color
.wrapper :global([data-color="destructive"]) {
--button-background: var(--danger-background);
}
// Target state (Radix patterns)
.popover :global([data-state="open"]) {
opacity: 1;
}
.tooltip :global([data-side="top"]) {
margin-bottom: var(--spacing-2);
}
```
### Common Component CSS Variables
**Button:**
- `--button-background`, `--button-border-radius`, `--button-padding`
- `--button-font-size`, `--button-height`, `--button-gap`
- `--button-hover-background`, `--button-disabled-opacity`
**Input:**
- `--input-height`, `--input-border-color`, `--input-background`
- `--input-padding`, `--input-font-size`, `--input-placeholder-color`
- `--input-focus-outline-color`, `--input-hover-border-color`
- `--input-prefix-*`, `--input-suffix-*` for adornments
**General pattern:** `--<component>-<property>` or `--<component>-<state>-<property>`
## Good Patterns
### Structure
```scss
// Flat, descriptive, component-scoped
.alertHistory { }
.alertHistoryHeader { }
.alertHistoryContent { }
.alertHistoryFooter { }
// State modifiers as separate classes
.alertHistory { }
.alertHistoryLoading { }
.alertHistoryEmpty { }
.alertHistoryError { }
```
### Composition
```scss
// GOOD: Composing styles
.baseButton {
padding: var(--spacing-2) var(--spacing-4);
border-radius: var(--radius-2);
}
.primaryButton {
composes: baseButton;
background: var(--primary-background);
}
```
### Pseudo Elements
```scss
.button {
// States
&:hover { opacity: 0.9; }
&:focus { outline: 2px solid var(--ring); outline-offset: 2px; }
&:disabled { opacity: 0.5; cursor: not-allowed; }
// Pseudo elements
&::before { content: ''; }
&::after { content: ''; }
}
```
### Media Queries
```scss
.container {
display: flex;
flex-direction: column;
@media (min-width: 768px) {
flex-direction: row;
}
}
```
### Keyframes (Local Scoping)
Without `:local()`, keyframe names are global and can clash across modules:
```scss
// BAD: Global keyframe - can conflict with other modules
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
// GOOD: Locally scoped keyframe
:local(@keyframes fadeIn) {
from { opacity: 0; }
to { opacity: 1; }
}
.modal {
animation: fadeIn 200ms ease;
}
```
## JS Import Patterns
```tsx
// GOOD
import styles from './Component.module.scss';
<div className={styles.container}>
<span className={styles.title}>Title</span>
</div>
// GOOD: Conditional classes
<div className={`${styles.button} ${isActive ? styles.buttonActive : ''}`}>
// GOOD: With clsx/classnames
<div className={clsx(styles.button, { [styles.buttonActive]: isActive })}>
// BAD: Bracket access (may be undefined)
<div className={styles['button-active']}> // undefined if CSS has .button-active
// BAD: String interpolation for class names
<div className={`${styles.button}-active`}> // won't work
// BAD: Dynamic class lookup - can't be statically analyzed
const cls = styles[`variant${props.type}`]; // Vite can't tree-shake or type-check
// GOOD: Explicit map for dynamic variants
const variantMap = {
primary: styles.variantPrimary,
secondary: styles.variantSecondary,
ghost: styles.variantGhost,
};
const cls = variantMap[props.type];
```
## Lint Rules
### JS/TS (oxlint)
| Rule | Severity | Catches |
|------|----------|---------|
| `signoz/no-css-module-bracket-access` | warn | `styles['kebab-case']`, dynamic access |
### CSS/SCSS (stylelint)
| Rule | Severity | Catches |
|------|----------|---------|
| `local/no-deep-nesting` | warning | class nesting >3 levels (pseudo-classes/elements and parent-reference selectors `&.foo`, `&#bar` not counted; configurable via `maxDepth` secondary option) |
| `local/no-id-selectors` | error | `#id` selectors |
| `local/no-bare-element-selectors` | error | root-level `div`, `span` etc |
| `local/prefer-css-variables` | warning | hardcoded colors |
| `local/class-name-pattern` | warning | kebab-case, snake_case, PascalCase |
Run: `pnpm lint:styles` to check CSS modules.

View File

@@ -41,15 +41,6 @@ if (typeof window.IntersectionObserver === 'undefined') {
(window as any).IntersectionObserver = IntersectionObserverMock;
}
if (typeof window.ResizeObserver === 'undefined') {
class ResizeObserverMock {
observe(): void {}
unobserve(): void {}
disconnect(): void {}
}
(window as any).ResizeObserver = ResizeObserverMock;
}
// Patch getComputedStyle to handle CSS parsing errors from @signozhq/* packages.
// These packages inject CSS at import time via style-inject / vite-plugin-css-injected-by-js.
// jsdom's nwsapi cannot parse some of the injected selectors (e.g. Tailwind's :animate-in),

View File

@@ -45,8 +45,8 @@
"@dnd-kit/utilities": "3.2.2",
"@grafana/data": "^11.6.14",
"@monaco-editor/react": "^4.7.0",
"@sentry/react": "10.57.0",
"@sentry/vite-plugin": "5.3.0",
"@sentry/react": "8.41.0",
"@sentry/vite-plugin": "2.22.6",
"@signozhq/design-tokens": "2.1.4",
"@signozhq/icons": "0.4.0",
"@signozhq/resizable": "0.0.2",
@@ -192,9 +192,9 @@
"lint-staged": "^17.0.4",
"msw": "1.3.2",
"orval": "8.9.1",
"oxfmt": "0.54.0",
"oxlint": "1.69.0",
"oxlint-tsgolint": "0.23.0",
"oxfmt": "0.47.0",
"oxlint": "1.62.0",
"oxlint-tsgolint": "0.22.1",
"postcss": "8.5.14",
"postcss-scss": "4.0.9",
"react-resizable": "3.0.4",

View File

@@ -1,144 +0,0 @@
/**
* Rule: no-css-module-bracket-access
*
* Prevents bracket access on CSS module imports that may fail with camelCaseOnly config.
*
* With Vite's `localsConvention: 'camelCaseOnly'`, kebab-case class names are
* converted to camelCase and the original key is NOT exported.
*
* This rule catches patterns like:
* styles['my-class'] // BAD - undefined if CSS has .my-class
* styles['myClass'] // OK but prefer dot notation
* styles.myClass // GOOD
*
* Catches:
* - Bracket access with kebab-case strings (always fails)
* - Bracket access with any string literal (warn - prefer dot notation)
* - Dynamic bracket access (warn - risky)
*/
const CSS_MODULE_IMPORT_NAMES = new Set([
'styles',
'classes',
'css',
'classNames',
]);
function looksLikeCssModuleImport(name) {
// Common patterns: styles, componentStyles, alertHistoryStyles
return (
CSS_MODULE_IMPORT_NAMES.has(name) ||
name.endsWith('Styles') ||
name.endsWith('Classes') ||
name.endsWith('Css')
);
}
function isKebabCase(str) {
return str.includes('-');
}
function isSnakeCase(str) {
return str.includes('_');
}
export default {
create(context) {
return {
MemberExpression(node) {
// Only check bracket notation: styles['...']
if (!node.computed) {
return;
}
const object = node.object;
if (object.type !== 'Identifier') {
return;
}
// Check if this looks like a CSS module import
if (!looksLikeCssModuleImport(object.name)) {
return;
}
const property = node.property;
// Dynamic access: styles[variable]
if (property.type === 'Identifier') {
context.report({
node,
message: `Dynamic CSS module access '${object.name}[${property.name}]' is risky. With 'camelCaseOnly' config, kebab-case keys don't exist. Use dot notation or verify the key exists.`,
});
return;
}
// Template literal: styles[\`...\`]
if (property.type === 'TemplateLiteral') {
context.report({
node,
message: `Template literal CSS module access is risky. With 'camelCaseOnly' config, kebab-case keys don't exist. Prefer dot notation.`,
});
return;
}
// Numeric / boolean / null literal: styles[0]. Not a class lookup; ignore.
if (property.type === 'Literal' && typeof property.value !== 'string') {
return;
}
// String literal: styles['...']
if (property.type === 'Literal' && typeof property.value === 'string') {
const className = property.value;
// Kebab-case will definitely fail
if (isKebabCase(className)) {
context.report({
node,
message: `CSS module class '${className}' uses kebab-case which won't work with 'camelCaseOnly' config. Use '${object.name}.${toCamelCase(className)}' instead.`,
});
return;
}
// Snake_case is suspicious
if (isSnakeCase(className)) {
context.report({
node,
message: `CSS module class '${className}' uses snake_case which may not work as expected. Prefer camelCase: '${object.name}.${toCamelCase(className)}'.`,
});
return;
}
// Valid camelCase but using bracket notation - prefer dot
if (/^[a-z][a-zA-Z0-9]*$/.test(className)) {
context.report({
node,
message: `Prefer dot notation: '${object.name}.${className}' instead of '${object.name}['${className}']'.`,
});
}
return;
}
// Catch-all for other dynamic expressions:
// styles['prefix' + suffix] (BinaryExpression)
// styles[isActive && 'foo'] (LogicalExpression)
// styles[isActive ? 'a' : 'b'] (ConditionalExpression)
// styles[fn()] (CallExpression)
context.report({
node,
message: `Dynamic CSS module access on '${object.name}' is risky. With 'camelCaseOnly' config, kebab-case keys don't exist. Use dot notation or verify each key resolves to an exported camelCase class.`,
});
},
};
},
};
function toCamelCase(str) {
return str
.split(/[-_]/)
.map((part, i) =>
i === 0
? part.toLowerCase()
: part.charAt(0).toUpperCase() + part.slice(1).toLowerCase(),
)
.join('');
}

View File

@@ -11,7 +11,6 @@ import noUnsupportedAssetPattern from './rules/no-unsupported-asset-pattern.mjs'
import noRawAbsolutePath from './rules/no-raw-absolute-path.mjs';
import noAntdComponents from './rules/no-antd-components.mjs';
import noSignozhqUiBarrel from './rules/no-signozhq-ui-barrel.mjs';
import noCssModuleBracketAccess from './rules/no-css-module-bracket-access.mjs';
export default {
meta: {
@@ -24,6 +23,5 @@ export default {
'no-raw-absolute-path': noRawAbsolutePath,
'no-antd-components': noAntdComponents,
'no-signozhq-ui-barrel': noSignozhqUiBarrel,
'no-css-module-bracket-access': noCssModuleBracketAccess,
},
};

696
frontend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -64,17 +64,10 @@ export const TraceDetail = Loadable(
),
);
export const TraceDetailOldRedirect = Loadable(
() =>
import(
/* webpackChunkName: "TraceDetailOldRedirect" */ 'pages/TraceDetailOldRedirect/index'
),
);
export const TraceDetailV3 = Loadable(
() =>
import(
/* webpackChunkName: "TraceDetailV3 Page" */ 'pages/TraceDetailsV3/index'
/* webpackChunkName: "TraceDetailV3 Page" */ 'pages/TraceDetailV3Page/index'
),
);

View File

@@ -47,7 +47,7 @@ import {
SomethingWentWrong,
StatusPage,
SupportPage,
TraceDetailOldRedirect,
TraceDetail,
TraceDetailV3,
TraceFilter,
TracesExplorer,
@@ -139,11 +139,13 @@ const routes: AppRoutes[] = [
exact: true,
key: 'LOGS_SAVE_VIEWS',
},
// Legacy /trace-old/:id redirects to the current /trace/:id view.
// V3 trace details is gated until release: /trace serves V2 (public),
// /trace-old serves V3 (URL-only access). Flip the two `component`
// values back to release V3.
{
path: ROUTES.TRACE_DETAIL_OLD,
exact: true,
component: TraceDetailOldRedirect,
component: TraceDetail,
isPrivate: true,
key: 'TRACE_DETAIL_OLD',
},

View File

@@ -55,9 +55,6 @@ import type {
ThreadDetailResponseDTO,
ThreadListResponseDTO,
ThreadSummaryDTO,
ChipDTO,
ChipsResponseDTO,
PageTypeDTO,
ToolCallEventDTO,
ToolResultEventDTO,
} from './sigNozAIAssistantAPI.schemas';
@@ -544,19 +541,3 @@ export async function submitFeedback(
comment: comment ?? null,
});
}
// ---------------------------------------------------------------------------
// Contextual empty-state chips
// GET /api/v1/assistant/empty-state/chips?page_type=… → { chips }
// ---------------------------------------------------------------------------
export async function getEmptyStateChips(
pageType: PageTypeDTO,
signal?: AbortSignal,
): Promise<ChipDTO[]> {
const response = await AIAssistantInstance.get<ChipsResponseDTO>(
'/empty-state/chips',
{ params: { page_type: pageType }, signal },
);
return response.data.chips;
}

View File

@@ -26,7 +26,6 @@ import type {
CancelApiV1AssistantCancelPostHeaders,
CancelRequestDTO,
CancelResponseDTO,
ChipsResponseDTO,
ClarifyApiV1AssistantClarifyPostHeaders,
ClarifyRequestDTO,
ClarifyResponseDTO,
@@ -40,11 +39,8 @@ import type {
ErrorResponseDTO,
FeedbackRequestDTO,
FeedbackResponseDTO,
GetChipsApiV1AssistantEmptyStateChipsGetHeaders,
GetChipsApiV1AssistantEmptyStateChipsGetParams,
GetThreadApiV1AssistantThreadsThreadIdGetHeaders,
GetThreadApiV1AssistantThreadsThreadIdGetPathParameters,
GetUsageApiV1AssistantUsageGetHeaders,
HTTPValidationErrorDTO,
HealthResponseDTO,
ListThreadsApiV1AssistantThreadsGetHeaders,
@@ -69,89 +65,93 @@ import type {
UpdateThreadApiV1AssistantThreadsThreadIdPatchHeaders,
UpdateThreadApiV1AssistantThreadsThreadIdPatchPathParameters,
UpdateThreadRequestDTO,
UsageResponseDTO,
} from './sigNozAIAssistantAPI.schemas';
import { GeneratedAPIInstance } from '../generatedAPIInstance';
import {
GeneratedAPIInstance,
getGeneratedAPIQueryKeyHeaders,
} from '../generatedAPIInstance';
import type { ErrorType, BodyType } from '../generatedAPIInstance';
/**
* @summary Healthz
* @summary Health
*/
export const healthzHealthzGet = (signal?: AbortSignal) => {
export const healthHealthGet = (signal?: AbortSignal) => {
return GeneratedAPIInstance<HealthResponseDTO>({
url: `/healthz`,
url: `/health`,
method: 'GET',
signal,
});
};
export const getHealthzHealthzGetQueryKey = () => {
return [`/healthz`] as const;
export const getHealthHealthGetQueryKey = () => {
return [`/health`] as const;
};
export const getHealthzHealthzGetQueryOptions = <
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
export const getHealthHealthGetQueryOptions = <
TData = Awaited<ReturnType<typeof healthHealthGet>>,
TError = ErrorType<unknown>,
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
Awaited<ReturnType<typeof healthHealthGet>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getHealthzHealthzGetQueryKey();
const queryKey = queryOptions?.queryKey ?? getHealthHealthGetQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof healthzHealthzGet>>
> = ({ signal }) => healthzHealthzGet(signal);
const queryFn: QueryFunction<Awaited<ReturnType<typeof healthHealthGet>>> = ({
signal,
}) => healthHealthGet(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
Awaited<ReturnType<typeof healthHealthGet>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type HealthzHealthzGetQueryResult = NonNullable<
Awaited<ReturnType<typeof healthzHealthzGet>>
export type HealthHealthGetQueryResult = NonNullable<
Awaited<ReturnType<typeof healthHealthGet>>
>;
export type HealthzHealthzGetQueryError = ErrorType<unknown>;
export type HealthHealthGetQueryError = ErrorType<unknown>;
/**
* @summary Healthz
* @summary Health
*/
export function useHealthzHealthzGet<
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
export function useHealthHealthGet<
TData = Awaited<ReturnType<typeof healthHealthGet>>,
TError = ErrorType<unknown>,
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
Awaited<ReturnType<typeof healthHealthGet>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getHealthzHealthzGetQueryOptions(options);
const queryOptions = getHealthHealthGetQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Healthz
* @summary Health
*/
export const invalidateHealthzHealthzGet = async (
export const invalidateHealthHealthGet = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getHealthzHealthzGetQueryKey() },
{ queryKey: getHealthHealthGetQueryKey() },
options,
);
@@ -159,82 +159,84 @@ export const invalidateHealthzHealthzGet = async (
};
/**
* @summary Readyz
* @summary Ready
*/
export const readyzReadyzGet = (signal?: AbortSignal) => {
export const readyReadyGet = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ReadinessResponseDTO>({
url: `/readyz`,
url: `/ready`,
method: 'GET',
signal,
});
};
export const getReadyzReadyzGetQueryKey = () => {
return [`/readyz`] as const;
export const getReadyReadyGetQueryKey = () => {
return [`/ready`] as const;
};
export const getReadyzReadyzGetQueryOptions = <
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
export const getReadyReadyGetQueryOptions = <
TData = Awaited<ReturnType<typeof readyReadyGet>>,
TError = ErrorType<ReadinessResponseDTO>,
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof readyzReadyzGet>>,
Awaited<ReturnType<typeof readyReadyGet>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getReadyzReadyzGetQueryKey();
const queryKey = queryOptions?.queryKey ?? getReadyReadyGetQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof readyzReadyzGet>>> = ({
const queryFn: QueryFunction<Awaited<ReturnType<typeof readyReadyGet>>> = ({
signal,
}) => readyzReadyzGet(signal);
}) => readyReadyGet(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof readyzReadyzGet>>,
Awaited<ReturnType<typeof readyReadyGet>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ReadyzReadyzGetQueryResult = NonNullable<
Awaited<ReturnType<typeof readyzReadyzGet>>
export type ReadyReadyGetQueryResult = NonNullable<
Awaited<ReturnType<typeof readyReadyGet>>
>;
export type ReadyzReadyzGetQueryError = ErrorType<ReadinessResponseDTO>;
export type ReadyReadyGetQueryError = ErrorType<ReadinessResponseDTO>;
/**
* @summary Readyz
* @summary Ready
*/
export function useReadyzReadyzGet<
TData = Awaited<ReturnType<typeof readyzReadyzGet>>,
export function useReadyReadyGet<
TData = Awaited<ReturnType<typeof readyReadyGet>>,
TError = ErrorType<ReadinessResponseDTO>,
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof readyzReadyzGet>>,
Awaited<ReturnType<typeof readyReadyGet>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getReadyzReadyzGetQueryOptions(options);
const queryOptions = getReadyReadyGetQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary Readyz
* @summary Ready
*/
export const invalidateReadyzReadyzGet = async (
export const invalidateReadyReadyGet = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getReadyzReadyzGetQueryKey() },
{ queryKey: getReadyReadyGetQueryKey() },
options,
);
@@ -245,7 +247,7 @@ export const invalidateReadyzReadyzGet = async (
* @summary Create a new thread
*/
export const createThreadApiV1AssistantThreadsPost = (
createThreadApiV1AssistantThreadsPostBody?: BodyType<CreateThreadApiV1AssistantThreadsPostBody>,
createThreadApiV1AssistantThreadsPostBody: BodyType<CreateThreadApiV1AssistantThreadsPostBody>,
headers?: CreateThreadApiV1AssistantThreadsPostHeaders,
signal?: AbortSignal,
) => {
@@ -266,7 +268,7 @@ export const getCreateThreadApiV1AssistantThreadsPostMutationOptions = <
Awaited<ReturnType<typeof createThreadApiV1AssistantThreadsPost>>,
TError,
{
data?: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
data: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
headers?: CreateThreadApiV1AssistantThreadsPostHeaders;
},
TContext
@@ -275,7 +277,7 @@ export const getCreateThreadApiV1AssistantThreadsPostMutationOptions = <
Awaited<ReturnType<typeof createThreadApiV1AssistantThreadsPost>>,
TError,
{
data?: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
data: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
headers?: CreateThreadApiV1AssistantThreadsPostHeaders;
},
TContext
@@ -292,7 +294,7 @@ export const getCreateThreadApiV1AssistantThreadsPostMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createThreadApiV1AssistantThreadsPost>>,
{
data?: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
data: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
headers?: CreateThreadApiV1AssistantThreadsPostHeaders;
}
> = (props) => {
@@ -308,8 +310,7 @@ export type CreateThreadApiV1AssistantThreadsPostMutationResult = NonNullable<
Awaited<ReturnType<typeof createThreadApiV1AssistantThreadsPost>>
>;
export type CreateThreadApiV1AssistantThreadsPostMutationBody =
| BodyType<CreateThreadApiV1AssistantThreadsPostBody>
| undefined;
BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
export type CreateThreadApiV1AssistantThreadsPostMutationError = ErrorType<
ErrorResponseDTO | HTTPValidationErrorDTO
>;
@@ -325,7 +326,7 @@ export const useCreateThreadApiV1AssistantThreadsPost = <
Awaited<ReturnType<typeof createThreadApiV1AssistantThreadsPost>>,
TError,
{
data?: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
data: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
headers?: CreateThreadApiV1AssistantThreadsPostHeaders;
},
TContext
@@ -334,14 +335,15 @@ export const useCreateThreadApiV1AssistantThreadsPost = <
Awaited<ReturnType<typeof createThreadApiV1AssistantThreadsPost>>,
TError,
{
data?: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
data: BodyType<CreateThreadApiV1AssistantThreadsPostBody>;
headers?: CreateThreadApiV1AssistantThreadsPostHeaders;
},
TContext
> => {
return useMutation(
getCreateThreadApiV1AssistantThreadsPostMutationOptions(options),
);
const mutationOptions =
getCreateThreadApiV1AssistantThreadsPostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Cursor-based pagination, sorted by updatedAt desc. Use `archived=true|false|all` to filter.
@@ -363,8 +365,13 @@ export const listThreadsApiV1AssistantThreadsGet = (
export const getListThreadsApiV1AssistantThreadsGetQueryKey = (
params?: ListThreadsApiV1AssistantThreadsGetParams,
headers?: ListThreadsApiV1AssistantThreadsGetHeaders,
) => {
return [`/api/v1/assistant/threads`, ...(params ? [params] : [])] as const;
return [
`/api/v1/assistant/threads`,
...(params ? [params] : []),
...getGeneratedAPIQueryKeyHeaders(headers),
] as const;
};
export const getListThreadsApiV1AssistantThreadsGetQueryOptions = <
@@ -385,7 +392,7 @@ export const getListThreadsApiV1AssistantThreadsGetQueryOptions = <
const queryKey =
queryOptions?.queryKey ??
getListThreadsApiV1AssistantThreadsGetQueryKey(params);
getListThreadsApiV1AssistantThreadsGetQueryKey(params, headers);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof listThreadsApiV1AssistantThreadsGet>>
@@ -434,7 +441,9 @@ export function useListThreadsApiV1AssistantThreadsGet<
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
query.queryKey = queryOptions.queryKey;
return query;
}
/**
@@ -447,7 +456,7 @@ export const invalidateListThreadsApiV1AssistantThreadsGet = async (
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListThreadsApiV1AssistantThreadsGetQueryKey(params) },
{ queryKey: getListThreadsApiV1AssistantThreadsGetQueryKey(params, headers) },
options,
);
@@ -471,10 +480,14 @@ export const getThreadApiV1AssistantThreadsThreadIdGet = (
});
};
export const getGetThreadApiV1AssistantThreadsThreadIdGetQueryKey = ({
threadId,
}: GetThreadApiV1AssistantThreadsThreadIdGetPathParameters) => {
return [`/api/v1/assistant/threads/${threadId}`] as const;
export const getGetThreadApiV1AssistantThreadsThreadIdGetQueryKey = (
{ threadId }: GetThreadApiV1AssistantThreadsThreadIdGetPathParameters,
headers?: GetThreadApiV1AssistantThreadsThreadIdGetHeaders,
) => {
return [
`/api/v1/assistant/threads/${threadId}`,
...getGeneratedAPIQueryKeyHeaders(headers),
] as const;
};
export const getGetThreadApiV1AssistantThreadsThreadIdGetQueryOptions = <
@@ -495,7 +508,7 @@ export const getGetThreadApiV1AssistantThreadsThreadIdGetQueryOptions = <
const queryKey =
queryOptions?.queryKey ??
getGetThreadApiV1AssistantThreadsThreadIdGetQueryKey({ threadId });
getGetThreadApiV1AssistantThreadsThreadIdGetQueryKey({ threadId }, headers);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getThreadApiV1AssistantThreadsThreadIdGet>>
@@ -549,7 +562,9 @@ export function useGetThreadApiV1AssistantThreadsThreadIdGet<
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
query.queryKey = queryOptions.queryKey;
return query;
}
/**
@@ -563,7 +578,10 @@ export const invalidateGetThreadApiV1AssistantThreadsThreadIdGet = async (
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{
queryKey: getGetThreadApiV1AssistantThreadsThreadIdGetQueryKey({ threadId }),
queryKey: getGetThreadApiV1AssistantThreadsThreadIdGetQueryKey(
{ threadId },
headers,
),
},
options,
);
@@ -578,14 +596,12 @@ export const updateThreadApiV1AssistantThreadsThreadIdPatch = (
{ threadId }: UpdateThreadApiV1AssistantThreadsThreadIdPatchPathParameters,
updateThreadRequestDTO: BodyType<UpdateThreadRequestDTO>,
headers?: UpdateThreadApiV1AssistantThreadsThreadIdPatchHeaders,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<ThreadSummaryDTO>({
url: `/api/v1/assistant/threads/${threadId}`,
method: 'PATCH',
headers: { 'Content-Type': 'application/json', ...headers },
data: updateThreadRequestDTO,
signal,
});
};
@@ -679,9 +695,10 @@ export const useUpdateThreadApiV1AssistantThreadsThreadIdPatch = <
},
TContext
> => {
return useMutation(
getUpdateThreadApiV1AssistantThreadsThreadIdPatchMutationOptions(options),
);
const mutationOptions =
getUpdateThreadApiV1AssistantThreadsThreadIdPatchMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Persists the user message, creates an execution (state: queued), kicks off the agent loop asynchronously, and returns immediately. Open `GET /executions/{executionId}/events` for the SSE stream.
@@ -808,11 +825,12 @@ export const useCreateMessageApiV1AssistantThreadsThreadIdMessagesPost = <
},
TContext
> => {
return useMutation(
const mutationOptions =
getCreateMessageApiV1AssistantThreadsThreadIdMessagesPostMutationOptions(
options,
),
);
);
return useMutation(mutationOptions);
};
/**
* Clean-slate regeneration. Starts a fresh execution with conversation history up to (excluding) the original assistant response.
@@ -943,11 +961,12 @@ export const useRegenerateMessageApiV1AssistantMessagesMessageIdRegeneratePost =
},
TContext
> => {
return useMutation(
const mutationOptions =
getRegenerateMessageApiV1AssistantMessagesMessageIdRegeneratePostMutationOptions(
options,
),
);
);
return useMutation(mutationOptions);
};
/**
* Triggers a replay execution that runs the stored tool call with exact params. Returns a new executionId — open SSE for that execution.
@@ -1047,9 +1066,10 @@ export const useApproveApiV1AssistantApprovePost = <
},
TContext
> => {
return useMutation(
getApproveApiV1AssistantApprovePostMutationOptions(options),
);
const mutationOptions =
getApproveApiV1AssistantApprovePostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Marks the approval as rejected. The execution completes with no tool execution.
@@ -1149,7 +1169,10 @@ export const useRejectApiV1AssistantRejectPost = <
},
TContext
> => {
return useMutation(getRejectApiV1AssistantRejectPostMutationOptions(options));
const mutationOptions =
getRejectApiV1AssistantRejectPostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Provides structured answers to a clarification request. Persists the answers as a user transcript message, emits `user_message` as the first replayable event on the new execution stream, and resumes the agent with the answers as tool results.
@@ -1249,9 +1272,10 @@ export const useClarifyApiV1AssistantClarifyPost = <
},
TContext
> => {
return useMutation(
getClarifyApiV1AssistantClarifyPostMutationOptions(options),
);
const mutationOptions =
getClarifyApiV1AssistantClarifyPostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Cooperative cancel. The agent loop finishes its current step, emits a truncated message if streaming, and transitions to canceled.
@@ -1351,7 +1375,10 @@ export const useCancelApiV1AssistantCancelPost = <
},
TContext
> => {
return useMutation(getCancelApiV1AssistantCancelPostMutationOptions(options));
const mutationOptions =
getCancelApiV1AssistantCancelPostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Deletes the resource that was created by the assistant.
@@ -1450,7 +1477,9 @@ export const useUndoApiV1AssistantUndoPost = <
},
TContext
> => {
return useMutation(getUndoApiV1AssistantUndoPostMutationOptions(options));
const mutationOptions = getUndoApiV1AssistantUndoPostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Rolls back the resource to its pre-change snapshot.
@@ -1550,7 +1579,10 @@ export const useRevertApiV1AssistantRevertPost = <
},
TContext
> => {
return useMutation(getRevertApiV1AssistantRevertPostMutationOptions(options));
const mutationOptions =
getRevertApiV1AssistantRevertPostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* Recreates the resource from its pre-delete snapshot.
@@ -1650,9 +1682,10 @@ export const useRestoreApiV1AssistantRestorePost = <
},
TContext
> => {
return useMutation(
getRestoreApiV1AssistantRestorePostMutationOptions(options),
);
const mutationOptions =
getRestoreApiV1AssistantRestorePostMutationOptions(options);
return useMutation(mutationOptions);
};
/**
* @summary Submit feedback on an assistant message
@@ -1778,221 +1811,10 @@ export const useSubmitFeedbackApiV1AssistantMessagesMessageIdFeedbackPost = <
},
TContext
> => {
return useMutation(
const mutationOptions =
getSubmitFeedbackApiV1AssistantMessagesMessageIdFeedbackPostMutationOptions(
options,
),
);
};
/**
* @summary Current rate-limit usage for the authenticated user + org
*/
export const getUsageApiV1AssistantUsageGet = (
headers?: GetUsageApiV1AssistantUsageGetHeaders,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<UsageResponseDTO>({
url: `/api/v1/assistant/usage`,
method: 'GET',
headers,
signal,
});
};
export const getGetUsageApiV1AssistantUsageGetQueryKey = () => {
return [`/api/v1/assistant/usage`] as const;
};
export const getGetUsageApiV1AssistantUsageGetQueryOptions = <
TData = Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>,
TError = ErrorType<ErrorResponseDTO | HTTPValidationErrorDTO>,
>(
headers?: GetUsageApiV1AssistantUsageGetHeaders,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getGetUsageApiV1AssistantUsageGetQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>
> = ({ signal }) => getUsageApiV1AssistantUsageGet(headers, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetUsageApiV1AssistantUsageGetQueryResult = NonNullable<
Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>
>;
export type GetUsageApiV1AssistantUsageGetQueryError = ErrorType<
ErrorResponseDTO | HTTPValidationErrorDTO
>;
/**
* @summary Current rate-limit usage for the authenticated user + org
*/
export function useGetUsageApiV1AssistantUsageGet<
TData = Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>,
TError = ErrorType<ErrorResponseDTO | HTTPValidationErrorDTO>,
>(
headers?: GetUsageApiV1AssistantUsageGetHeaders,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getUsageApiV1AssistantUsageGet>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetUsageApiV1AssistantUsageGetQueryOptions(
headers,
options,
);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
}
/**
* @summary Current rate-limit usage for the authenticated user + org
*/
export const invalidateGetUsageApiV1AssistantUsageGet = async (
queryClient: QueryClient,
headers?: GetUsageApiV1AssistantUsageGetHeaders,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetUsageApiV1AssistantUsageGetQueryKey() },
options,
);
return queryClient;
};
/**
* @summary Contextual empty-state chips
*/
export const getChipsApiV1AssistantEmptyStateChipsGet = (
params: GetChipsApiV1AssistantEmptyStateChipsGetParams,
headers?: GetChipsApiV1AssistantEmptyStateChipsGetHeaders,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<ChipsResponseDTO>({
url: `/api/v1/assistant/empty-state/chips`,
method: 'GET',
headers,
params,
signal,
});
};
export const getGetChipsApiV1AssistantEmptyStateChipsGetQueryKey = (
params?: GetChipsApiV1AssistantEmptyStateChipsGetParams,
) => {
return [
`/api/v1/assistant/empty-state/chips`,
...(params ? [params] : []),
] as const;
};
export const getGetChipsApiV1AssistantEmptyStateChipsGetQueryOptions = <
TData = Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>,
TError = ErrorType<ErrorResponseDTO | HTTPValidationErrorDTO>,
>(
params: GetChipsApiV1AssistantEmptyStateChipsGetParams,
headers?: GetChipsApiV1AssistantEmptyStateChipsGetHeaders,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ??
getGetChipsApiV1AssistantEmptyStateChipsGetQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>
> = ({ signal }) =>
getChipsApiV1AssistantEmptyStateChipsGet(params, headers, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetChipsApiV1AssistantEmptyStateChipsGetQueryResult = NonNullable<
Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>
>;
export type GetChipsApiV1AssistantEmptyStateChipsGetQueryError = ErrorType<
ErrorResponseDTO | HTTPValidationErrorDTO
>;
/**
* @summary Contextual empty-state chips
*/
export function useGetChipsApiV1AssistantEmptyStateChipsGet<
TData = Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>,
TError = ErrorType<ErrorResponseDTO | HTTPValidationErrorDTO>,
>(
params: GetChipsApiV1AssistantEmptyStateChipsGetParams,
headers?: GetChipsApiV1AssistantEmptyStateChipsGetHeaders,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getChipsApiV1AssistantEmptyStateChipsGet>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetChipsApiV1AssistantEmptyStateChipsGetQueryOptions(
params,
headers,
options,
);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
}
/**
* @summary Contextual empty-state chips
*/
export const invalidateGetChipsApiV1AssistantEmptyStateChipsGet = async (
queryClient: QueryClient,
params: GetChipsApiV1AssistantEmptyStateChipsGetParams,
headers?: GetChipsApiV1AssistantEmptyStateChipsGetHeaders,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetChipsApiV1AssistantEmptyStateChipsGetQueryKey(params) },
options,
);
return queryClient;
);
return useMutation(mutationOptions);
};

View File

@@ -159,25 +159,6 @@ export interface CancelResponseDTO {
state: ExecutionStateDTO;
}
export interface ChipDTO {
/**
* @type string
* @description Stable chip id. Rule-engine chips use intent ids.
*/
id: string;
/**
* @type string
*/
text: string;
}
export interface ChipsResponseDTO {
/**
* @type array
*/
chips: ChipDTO[];
}
export type ClarificationFieldDTOOptions = string[] | null;
export type ClarificationFieldDTODefault = string | string[] | null;
@@ -405,74 +386,15 @@ export type ErrorBodyDTOErrors = ErrorResponseAdditionalDTO[] | null;
export type ErrorBodyDTOUrl = string | null;
/**
* Machine-readable error codes carried on ``ErrorBody.code``.
**Extensible set.** This enum is the single source of truth for every code
the backend can emit, on both the REST envelope and the SSE ``ErrorEvent``.
It is published in the OpenAPI schema (and therefore the generated TS
client) so clients get autocomplete and a typed discriminant. The set is
expected to *grow*: adding a member is a backward-compatible change (the
wire is still a plain JSON string), so clients MUST treat unknown codes
gracefully — branch on the codes they handle and keep a default fallback,
never hard-reject an unrecognized value. Re-exported from ``app.errors``
for convenience; ``AssistantError(code=...)`` requires a member of this
enum so a typo can never reach a client.
*/
export enum ErrorCodeDTO {
missing_signoz_url = 'missing_signoz_url',
invalid_signoz_url = 'invalid_signoz_url',
invalid_content_length = 'invalid_content_length',
invalid_fork_target = 'invalid_fork_target',
rate_limit_override_exceeds_ceiling = 'rate_limit_override_exceeds_ceiling',
thread_message_limit = 'thread_message_limit',
validation_error = 'validation_error',
missing_token = 'missing_token',
invalid_token = 'invalid_token',
permission_denied = 'permission_denied',
user_disabled = 'user_disabled',
org_disabled = 'org_disabled',
thread_not_found = 'thread_not_found',
message_not_found = 'message_not_found',
execution_not_found = 'execution_not_found',
approval_not_found = 'approval_not_found',
clarification_not_found = 'clarification_not_found',
action_metadata_not_found = 'action_metadata_not_found',
user_not_found = 'user_not_found',
region_not_configured = 'region_not_configured',
thread_busy = 'thread_busy',
thread_has_active_execution = 'thread_has_active_execution',
no_active_execution = 'no_active_execution',
approval_superseded = 'approval_superseded',
clarification_superseded = 'clarification_superseded',
undo_conflict = 'undo_conflict',
revert_conflict = 'revert_conflict',
revert_expired = 'revert_expired',
restore_expired = 'restore_expired',
connection_limit_exceeded = 'connection_limit_exceeded',
hourly_message_limit = 'hourly_message_limit',
daily_message_limit = 'daily_message_limit',
daily_token_limit = 'daily_token_limit',
daily_cost_limit = 'daily_cost_limit',
upstream_auth_error = 'upstream_auth_error',
max_turns_exceeded = 'max_turns_exceeded',
budget_exceeded = 'budget_exceeded',
agent_execution_error = 'agent_execution_error',
cli_not_found = 'cli_not_found',
cli_connection_error = 'cli_connection_error',
cli_process_error = 'cli_process_error',
sandbox_unavailable = 'sandbox_unavailable',
mcp_unavailable = 'mcp_unavailable',
internal_error = 'internal_error',
region_unreachable = 'region_unreachable',
heartbeat_expired = 'heartbeat_expired',
replay_unavailable = 'replay_unavailable',
}
/**
* Inner error object — matches Go ErrorsJSON.
*/
export interface ErrorBodyDTO {
code: ErrorCodeDTO;
/**
* @type string
* @pattern ^[a-z_]+$
*/
code: string;
/**
* @type string
*/
@@ -568,23 +490,6 @@ export type MessageActionDTOQuery = MessageActionDTOQueryAnyOf | null;
export type MessageActionDTOUrl = string | null;
/**
* Explorer namespace a saved view belongs to — its ``sourcePage``.
Mirrors the SigNoz product's saved-view ``sourcePage`` values so the
frontend can route an ``open_resource`` action for a view to the right
Explorer via its existing ``SOURCEPAGE_VS_ROUTES`` map. ``meter`` is the
Cost Meter Explorer and is intentionally distinct from ``metrics`` (the
product persists and lists meter views under ``sourcePage="meter"``).
*/
export enum SavedViewEntityDTO {
logs = 'logs',
traces = 'traces',
metrics = 'metrics',
meter = 'meter',
}
export type MessageActionDTOEntity = SavedViewEntityDTO | null;
export enum MessageActionKindDTO {
undo = 'undo',
revert = 'revert',
@@ -595,7 +500,7 @@ export enum MessageActionKindDTO {
apply_filter = 'apply_filter',
}
/**
* Assistant action. Kind-specific requirements: rollback actions require actionMetadataId/resourceType/resourceId; follow_up requires input.intent; open_resource requires resourceType/resourceId; apply_filter requires signal and query; open_docs requires a SigNoz docs url. open_resource for a saved view also carries entity (logs/traces/metrics/meter) so the frontend routes to the correct Explorer.
* Assistant action. Kind-specific requirements: rollback actions require actionMetadataId/resourceType/resourceId; follow_up requires input.intent; open_resource requires resourceType/resourceId; apply_filter requires signal and query; open_docs requires a SigNoz docs url.
*/
export interface MessageActionDTO {
kind: MessageActionKindDTO;
@@ -612,7 +517,6 @@ export interface MessageActionDTO {
signal?: MessageActionDTOSignal;
query?: MessageActionDTOQuery;
url?: MessageActionDTOUrl;
entity?: MessageActionDTOEntity;
}
export enum MessageContentTypeDTO {
@@ -686,26 +590,6 @@ export interface MessageSummaryDTO {
updatedAt: string;
}
export enum PageTypeDTO {
homepage = 'homepage',
dashboard_detail = 'dashboard_detail',
dashboard_list = 'dashboard_list',
panel_edit = 'panel_edit',
panel_fullscreen = 'panel_fullscreen',
logs_explorer = 'logs_explorer',
log_detail = 'log_detail',
traces_explorer = 'traces_explorer',
trace_detail = 'trace_detail',
metrics_explorer = 'metrics_explorer',
service_detail = 'service_detail',
services_list = 'services_list',
alert_edit = 'alert_edit',
alert_list = 'alert_list',
alert_new = 'alert_new',
alerts_triggered = 'alerts_triggered',
infra_entity_detail = 'infra_entity_detail',
other = 'other',
}
export enum ReadinessChecksDTODatabase {
ok = 'ok',
failed = 'failed',
@@ -1106,10 +990,8 @@ export type MessageActionEventDTOQuery = MessageActionEventDTOQueryAnyOf | null;
export type MessageActionEventDTOUrl = string | null;
export type MessageActionEventDTOEntity = SavedViewEntityDTO | null;
/**
* Assistant action. Kind-specific requirements: rollback actions require actionMetadataId/resourceType/resourceId; follow_up requires input.intent; open_resource requires resourceType/resourceId; apply_filter requires signal and query; open_docs requires a SigNoz docs url. open_resource for a saved view also carries entity (logs/traces/metrics/meter) so the frontend routes to the correct Explorer.
* Assistant action. Kind-specific requirements: rollback actions require actionMetadataId/resourceType/resourceId; follow_up requires input.intent; open_resource requires resourceType/resourceId; apply_filter requires signal and query; open_docs requires a SigNoz docs url.
*/
export interface MessageActionEventDTO {
kind: MessageActionKindDTO;
@@ -1126,7 +1008,6 @@ export interface MessageActionEventDTO {
signal?: MessageActionEventDTOSignal;
query?: MessageActionEventDTOQuery;
url?: MessageActionEventDTOUrl;
entity?: MessageActionEventDTOEntity;
}
export type MessageEventDTOActions = MessageActionEventDTO[] | null;
@@ -1504,21 +1385,3 @@ export type GetUsageApiV1AssistantUsageGetHeaders = {
*/
'X-SigNoz-URL'?: string | null;
};
export type GetChipsApiV1AssistantEmptyStateChipsGetParams = {
/**
* @description Frontend-declared page type. Typed as an enum, but unrecognized values are coerced to 'other' (not rejected) so a new frontend page type works before the backend knows it. The page type alone identifies the focused entity (e.g. trace_detail) for the 'Explain this …' chip; the agent reads the concrete entity from page context once a chip is clicked, so no separate entity id is needed.
*/
page_type: PageTypeDTO;
};
export type GetChipsApiV1AssistantEmptyStateChipsGetHeaders = {
/**
* @description SigNoz auth token (Bearer or raw JWT)
*/
authorization?: string | null;
/**
* @description SigNoz instance base URL for multi-tenant deployments. Falls back to SIGNOZ_API_URL env var when omitted.
*/
'X-SigNoz-URL'?: string | null;
};

View File

@@ -5,13 +5,6 @@ import convertObjectIntoParams from 'lib/query/convertObjectIntoParams';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/alerts/getTriggered';
/**
* @deprecated Use the generated `useGetAlerts` hook (or `getAlerts` fetcher) from
* `api/generated/services/alerts` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const getTriggered = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createEmail';
/**
* @deprecated Use the generated `useCreateChannel` hook (or `createChannel` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const create = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createMsTeams';
/**
* @deprecated Use the generated `useCreateChannel` hook (or `createChannel` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const create = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createOpsgenie';
/**
* @deprecated Use the generated `useCreateChannel` hook (or `createChannel` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const create = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createPager';
/**
* @deprecated Use the generated `useCreateChannel` hook (or `createChannel` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const create = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createSlack';
/**
* @deprecated Use the generated `useCreateChannel` hook (or `createChannel` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const create = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createWebhook';
/**
* @deprecated Use the generated `useCreateChannel` hook (or `createChannel` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const create = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/delete';
/**
* @deprecated Use the generated `useDeleteChannelByID` hook (or `deleteChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const deleteChannel = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editEmail';
/**
* @deprecated Use the generated `useUpdateChannelByID` hook (or `updateChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const editEmail = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editMsTeams';
/**
* @deprecated Use the generated `useUpdateChannelByID` hook (or `updateChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const editMsTeams = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorResponse, ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editOpsgenie';
/**
* @deprecated Use the generated `useUpdateChannelByID` hook (or `updateChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const editOpsgenie = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps> | ErrorResponse> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editPager';
/**
* @deprecated Use the generated `useUpdateChannelByID` hook (or `updateChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const editPager = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editSlack';
/**
* @deprecated Use the generated `useUpdateChannelByID` hook (or `updateChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const editSlack = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editWebhook';
/**
* @deprecated Use the generated `useUpdateChannelByID` hook (or `updateChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const editWebhook = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -5,13 +5,6 @@ import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/get';
import { Channels } from 'types/api/channels/getAll';
/**
* @deprecated Use the generated `useGetChannelByID` hook (or `getChannelByID` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const get = async (props: Props): Promise<SuccessResponseV2<Channels>> => {
try {
const response = await axios.get<PayloadProps>(`/channels/${props.id}`);

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { Channels, PayloadProps } from 'types/api/channels/getAll';
/**
* @deprecated Use the generated `useListChannels` hook (or `listChannels` fetcher) from
* `api/generated/services/channels` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const getAll = async (): Promise<SuccessResponseV2<Channels[]>> => {
try {
const response = await axios.get<PayloadProps>('/channels');

View File

@@ -5,13 +5,6 @@ import { DEFAULT_TIME_RANGE } from 'container/TopNav/DateTimeSelectionV2/constan
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { CreatePublicDashboardProps } from 'types/api/dashboard/public/create';
/**
* @deprecated Use the generated `useCreatePublicDashboard` hook (or `createPublicDashboard` fetcher) from
* `api/generated/services/dashboard` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const createPublicDashboard = async (
props: CreatePublicDashboardProps,
): Promise<SuccessResponseV2<CreatePublicDashboardProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { GetPublicDashboardDataProps, PayloadProps,PublicDashboardDataProps } from 'types/api/dashboard/public/get';
/**
* @deprecated Use the generated `useGetPublicDashboardData` hook (or `getPublicDashboardData` fetcher) from
* `api/generated/services/dashboard` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const getPublicDashboardData = async (props: GetPublicDashboardDataProps): Promise<SuccessResponseV2<PublicDashboardDataProps>> => {
try {
const response = await axios.get<PayloadProps>(`/public/dashboards/${props.id}`);

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { GetPublicDashboardMetaProps, PayloadProps,PublicDashboardMetaProps } from 'types/api/dashboard/public/getMeta';
/**
* @deprecated Use the generated `useGetPublicDashboard` hook (or `getPublicDashboard` fetcher) from
* `api/generated/services/dashboard` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const getPublicDashboardMeta = async (props: GetPublicDashboardMetaProps): Promise<SuccessResponseV2<PublicDashboardMetaProps>> => {
try {
const response = await axios.get<PayloadProps>(`/dashboards/${props.id}/public`);

View File

@@ -6,13 +6,6 @@ import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { GetPublicDashboardWidgetDataProps } from 'types/api/dashboard/public/getWidgetData';
/**
* @deprecated Use the generated `useGetPublicDashboardWidgetQueryRange` hook (or `getPublicDashboardWidgetQueryRange` fetcher) from
* `api/generated/services/dashboard` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const getPublicDashboardWidgetData = async (props: GetPublicDashboardWidgetDataProps): Promise<SuccessResponseV2<MetricRangePayloadV5>> => {
try {
const response = await axios.get(`/public/dashboards/${props.id}/widgets/${props.index}/query_range`, {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps,RevokePublicDashboardAccessProps } from 'types/api/dashboard/public/delete';
/**
* @deprecated Use the generated `useDeletePublicDashboard` hook (or `deletePublicDashboard` fetcher) from
* `api/generated/services/dashboard` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const revokePublicDashboardAccess = async (
props: RevokePublicDashboardAccessProps,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -5,13 +5,6 @@ import { DEFAULT_TIME_RANGE } from 'container/TopNav/DateTimeSelectionV2/constan
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { UpdatePublicDashboardProps } from 'types/api/dashboard/public/update';
/**
* @deprecated Use the generated `useUpdatePublicDashboard` hook (or `updatePublicDashboard` fetcher) from
* `api/generated/services/dashboard` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const updatePublicDashboard = async (
props: UpdatePublicDashboardProps,
): Promise<SuccessResponseV2<UpdatePublicDashboardProps>> => {

View File

@@ -9,13 +9,6 @@ interface ISubstituteVars {
compositeQuery: ICompositeMetricQuery;
}
/**
* @deprecated Use the generated `useReplaceVariables` hook (or `replaceVariables` fetcher) from
* `api/generated/services/querier` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getSubstituteVars = async (
props?: Partial<QueryRangePayloadV5>,
signal?: AbortSignal,

View File

@@ -8,12 +8,6 @@ import { FieldKeyResponse } from 'types/api/dynamicVariables/getFieldKeys';
* Get field keys for a given signal type
* @param signal Type of signal (traces, logs, metrics)
* @param name Optional search text
*
* @deprecated Use the generated `useGetFieldsKeys` hook (or `getFieldsKeys` fetcher) from
* `api/generated/services/fields` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getFieldKeys = async (
signal?: 'traces' | 'logs' | 'metrics',

View File

@@ -11,12 +11,6 @@ import { FieldValueResponse } from 'types/api/dynamicVariables/getFieldValues';
* @param name Name of the attribute for which values are being fetched
* @param value Optional search text
* @param existingQuery Optional existing query - across all present dynamic variables
*
* @deprecated Use the generated `useGetFieldsValues` hook (or `getFieldsValues` fetcher) from
* `api/generated/services/fields` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getFieldValues = async (
signal?: 'traces' | 'logs' | 'metrics',

View File

@@ -18,20 +18,14 @@ import type {
} from 'react-query';
import type {
CloneDashboardV2201,
CloneDashboardV2PathParameters,
CreateDashboardV2201,
CreateDashboardView201,
CreatePublicDashboard201,
CreatePublicDashboardPathParameters,
DashboardtypesPatchableDashboardV2DTO,
DashboardtypesPostableDashboardV2DTO,
DashboardtypesPostableDashboardViewDTO,
DashboardtypesPostablePublicDashboardDTO,
DashboardtypesUpdatableDashboardV2DTO,
DashboardtypesUpdatablePublicDashboardDTO,
DeleteDashboardV2PathParameters,
DeleteDashboardViewPathParameters,
DeletePublicDashboardPathParameters,
GetDashboardV2200,
GetDashboardV2PathParameters,
@@ -41,22 +35,13 @@ import type {
GetPublicDashboardPathParameters,
GetPublicDashboardWidgetQueryRange200,
GetPublicDashboardWidgetQueryRangePathParameters,
ListDashboardViews200,
ListDashboardsForUserV2200,
ListDashboardsForUserV2Params,
ListDashboardsV2200,
ListDashboardsV2Params,
LockDashboardV2PathParameters,
PatchDashboardV2200,
PatchDashboardV2PathParameters,
PinDashboardV2PathParameters,
RenderErrorResponseDTO,
UnlockDashboardV2PathParameters,
UnpinDashboardV2PathParameters,
UpdateDashboardV2200,
UpdateDashboardV2PathParameters,
UpdateDashboardView200,
UpdateDashboardViewPathParameters,
UpdatePublicDashboardPathParameters,
} from '../sigNoz.schemas';
@@ -71,7 +56,7 @@ export const deletePublicDashboard = (
{ id }: DeletePublicDashboardPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
method: 'DELETE',
signal,
@@ -354,7 +339,7 @@ export const updatePublicDashboard = (
dashboardtypesUpdatablePublicDashboardDTO?: BodyType<DashboardtypesUpdatablePublicDashboardDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
@@ -656,451 +641,6 @@ export const invalidateGetPublicDashboardWidgetQueryRange = async (
return queryClient;
};
/**
* Returns every saved view in the calling user's org. Saved views are shared org-wide.
* @summary List dashboard saved views
*/
export const listDashboardViews = (signal?: AbortSignal) => {
return GeneratedAPIInstance<ListDashboardViews200>({
url: `/api/v2/dashboard_views`,
method: 'GET',
signal,
});
};
export const getListDashboardViewsQueryKey = () => {
return [`/api/v2/dashboard_views`] as const;
};
export const getListDashboardViewsQueryOptions = <
TData = Awaited<ReturnType<typeof listDashboardViews>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listDashboardViews>>,
TError,
TData
>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListDashboardViewsQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof listDashboardViews>>
> = ({ signal }) => listDashboardViews(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listDashboardViews>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListDashboardViewsQueryResult = NonNullable<
Awaited<ReturnType<typeof listDashboardViews>>
>;
export type ListDashboardViewsQueryError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary List dashboard saved views
*/
export function useListDashboardViews<
TData = Awaited<ReturnType<typeof listDashboardViews>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listDashboardViews>>,
TError,
TData
>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListDashboardViewsQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
}
/**
* @summary List dashboard saved views
*/
export const invalidateListDashboardViews = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListDashboardViewsQueryKey() },
options,
);
return queryClient;
};
/**
* Persists the calling user's dashboard listing state (query, sort, order) as a named, reusable view shared across the org.
* @summary Create dashboard saved view
*/
export const createDashboardView = (
dashboardtypesPostableDashboardViewDTO?: BodyType<DashboardtypesPostableDashboardViewDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateDashboardView201>({
url: `/api/v2/dashboard_views`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: dashboardtypesPostableDashboardViewDTO,
signal,
});
};
export const getCreateDashboardViewMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createDashboardView>>,
TError,
{ data?: BodyType<DashboardtypesPostableDashboardViewDTO> },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createDashboardView>>,
TError,
{ data?: BodyType<DashboardtypesPostableDashboardViewDTO> },
TContext
> => {
const mutationKey = ['createDashboardView'];
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 createDashboardView>>,
{ data?: BodyType<DashboardtypesPostableDashboardViewDTO> }
> = (props) => {
const { data } = props ?? {};
return createDashboardView(data);
};
return { mutationFn, ...mutationOptions };
};
export type CreateDashboardViewMutationResult = NonNullable<
Awaited<ReturnType<typeof createDashboardView>>
>;
export type CreateDashboardViewMutationBody =
| BodyType<DashboardtypesPostableDashboardViewDTO>
| undefined;
export type CreateDashboardViewMutationError =
ErrorType<RenderErrorResponseDTO>;
/**
* @summary Create dashboard saved view
*/
export const useCreateDashboardView = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createDashboardView>>,
TError,
{ data?: BodyType<DashboardtypesPostableDashboardViewDTO> },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createDashboardView>>,
TError,
{ data?: BodyType<DashboardtypesPostableDashboardViewDTO> },
TContext
> => {
return useMutation(getCreateDashboardViewMutationOptions(options));
};
/**
* Removes a saved view. Saved views are shared org-wide. Deleting a non-existent view returns 404.
* @summary Delete dashboard saved view
*/
export const deleteDashboardView = (
{ id }: DeleteDashboardViewPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/dashboard_views/${id}`,
method: 'DELETE',
signal,
});
};
export const getDeleteDashboardViewMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteDashboardView>>,
TError,
{ pathParams: DeleteDashboardViewPathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteDashboardView>>,
TError,
{ pathParams: DeleteDashboardViewPathParameters },
TContext
> => {
const mutationKey = ['deleteDashboardView'];
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 deleteDashboardView>>,
{ pathParams: DeleteDashboardViewPathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deleteDashboardView(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteDashboardViewMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteDashboardView>>
>;
export type DeleteDashboardViewMutationError =
ErrorType<RenderErrorResponseDTO>;
/**
* @summary Delete dashboard saved view
*/
export const useDeleteDashboardView = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteDashboardView>>,
TError,
{ pathParams: DeleteDashboardViewPathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteDashboardView>>,
TError,
{ pathParams: DeleteDashboardViewPathParameters },
TContext
> => {
return useMutation(getDeleteDashboardViewMutationOptions(options));
};
/**
* Replaces a saved view's name and data. Saved views are shared org-wide.
* @summary Update dashboard saved view
*/
export const updateDashboardView = (
{ id }: UpdateDashboardViewPathParameters,
dashboardtypesPostableDashboardViewDTO?: BodyType<DashboardtypesPostableDashboardViewDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<UpdateDashboardView200>({
url: `/api/v2/dashboard_views/${id}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
data: dashboardtypesPostableDashboardViewDTO,
signal,
});
};
export const getUpdateDashboardViewMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateDashboardView>>,
TError,
{
pathParams: UpdateDashboardViewPathParameters;
data?: BodyType<DashboardtypesPostableDashboardViewDTO>;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateDashboardView>>,
TError,
{
pathParams: UpdateDashboardViewPathParameters;
data?: BodyType<DashboardtypesPostableDashboardViewDTO>;
},
TContext
> => {
const mutationKey = ['updateDashboardView'];
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 updateDashboardView>>,
{
pathParams: UpdateDashboardViewPathParameters;
data?: BodyType<DashboardtypesPostableDashboardViewDTO>;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return updateDashboardView(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateDashboardViewMutationResult = NonNullable<
Awaited<ReturnType<typeof updateDashboardView>>
>;
export type UpdateDashboardViewMutationBody =
| BodyType<DashboardtypesPostableDashboardViewDTO>
| undefined;
export type UpdateDashboardViewMutationError =
ErrorType<RenderErrorResponseDTO>;
/**
* @summary Update dashboard saved view
*/
export const useUpdateDashboardView = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateDashboardView>>,
TError,
{
pathParams: UpdateDashboardViewPathParameters;
data?: BodyType<DashboardtypesPostableDashboardViewDTO>;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateDashboardView>>,
TError,
{
pathParams: UpdateDashboardViewPathParameters;
data?: BodyType<DashboardtypesPostableDashboardViewDTO>;
},
TContext
> => {
return useMutation(getUpdateDashboardViewMutationOptions(options));
};
/**
* Returns a page of v2-shape dashboards for the org. This is the pure, user-independent list — it carries no pin state. Use ListDashboardsForUserV2 for the personalized, pin-aware list. Supports a filter DSL (`query`), sort (`updated_at`/`created_at`/`name`), order (`asc`/`desc`), and offset-based pagination (`limit`/`offset`).
* @summary List dashboards (v2)
*/
export const listDashboardsV2 = (
params?: ListDashboardsV2Params,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<ListDashboardsV2200>({
url: `/api/v2/dashboards`,
method: 'GET',
params,
signal,
});
};
export const getListDashboardsV2QueryKey = (
params?: ListDashboardsV2Params,
) => {
return [`/api/v2/dashboards`, ...(params ? [params] : [])] as const;
};
export const getListDashboardsV2QueryOptions = <
TData = Awaited<ReturnType<typeof listDashboardsV2>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(
params?: ListDashboardsV2Params,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listDashboardsV2>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListDashboardsV2QueryKey(params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listDashboardsV2>>> = ({
signal,
}) => listDashboardsV2(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listDashboardsV2>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListDashboardsV2QueryResult = NonNullable<
Awaited<ReturnType<typeof listDashboardsV2>>
>;
export type ListDashboardsV2QueryError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary List dashboards (v2)
*/
export function useListDashboardsV2<
TData = Awaited<ReturnType<typeof listDashboardsV2>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(
params?: ListDashboardsV2Params,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listDashboardsV2>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListDashboardsV2QueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
}
/**
* @summary List dashboards (v2)
*/
export const invalidateListDashboardsV2 = async (
queryClient: QueryClient,
params?: ListDashboardsV2Params,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListDashboardsV2QueryKey(params) },
options,
);
return queryClient;
};
/**
* This endpoint creates a dashboard in the v2 format that follows Perses spec.
* @summary Create dashboard (v2)
@@ -1184,85 +724,6 @@ export const useCreateDashboardV2 = <
> => {
return useMutation(getCreateDashboardV2MutationOptions(options));
};
/**
* This endpoint deletes a v2-shape dashboard along with its tag relations. Locked dashboards are rejected.
* @summary Delete dashboard (v2)
*/
export const deleteDashboardV2 = (
{ id }: DeleteDashboardV2PathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/dashboards/${id}`,
method: 'DELETE',
signal,
});
};
export const getDeleteDashboardV2MutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteDashboardV2>>,
TError,
{ pathParams: DeleteDashboardV2PathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteDashboardV2>>,
TError,
{ pathParams: DeleteDashboardV2PathParameters },
TContext
> => {
const mutationKey = ['deleteDashboardV2'];
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 deleteDashboardV2>>,
{ pathParams: DeleteDashboardV2PathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return deleteDashboardV2(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteDashboardV2MutationResult = NonNullable<
Awaited<ReturnType<typeof deleteDashboardV2>>
>;
export type DeleteDashboardV2MutationError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Delete dashboard (v2)
*/
export const useDeleteDashboardV2 = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteDashboardV2>>,
TError,
{ pathParams: DeleteDashboardV2PathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof deleteDashboardV2>>,
TError,
{ pathParams: DeleteDashboardV2PathParameters },
TContext
> => {
return useMutation(getDeleteDashboardV2MutationOptions(options));
};
/**
* This endpoint returns a v2-shape dashboard.
* @summary Get dashboard (v2)
@@ -1562,85 +1023,6 @@ export const useUpdateDashboardV2 = <
> => {
return useMutation(getUpdateDashboardV2MutationOptions(options));
};
/**
* This endpoint clones an existing v2-shape dashboard. User and integration dashboards can be cloned; system dashboards are rejected. The clone keeps the source's display name, panels, and tags, but gets a freshly generated unique internal name and is always created as an unlocked user dashboard owned by the caller.
* @summary Clone dashboard (v2)
*/
export const cloneDashboardV2 = (
{ id }: CloneDashboardV2PathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CloneDashboardV2201>({
url: `/api/v2/dashboards/${id}/clone`,
method: 'POST',
signal,
});
};
export const getCloneDashboardV2MutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof cloneDashboardV2>>,
TError,
{ pathParams: CloneDashboardV2PathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof cloneDashboardV2>>,
TError,
{ pathParams: CloneDashboardV2PathParameters },
TContext
> => {
const mutationKey = ['cloneDashboardV2'];
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 cloneDashboardV2>>,
{ pathParams: CloneDashboardV2PathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return cloneDashboardV2(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type CloneDashboardV2MutationResult = NonNullable<
Awaited<ReturnType<typeof cloneDashboardV2>>
>;
export type CloneDashboardV2MutationError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Clone dashboard (v2)
*/
export const useCloneDashboardV2 = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof cloneDashboardV2>>,
TError,
{ pathParams: CloneDashboardV2PathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof cloneDashboardV2>>,
TError,
{ pathParams: CloneDashboardV2PathParameters },
TContext
> => {
return useMutation(getCloneDashboardV2MutationOptions(options));
};
/**
* This endpoint unlocks a v2-shape dashboard. Only the dashboard's creator or an org admin may lock or unlock.
* @summary Unlock dashboard (v2)
@@ -1649,7 +1031,7 @@ export const unlockDashboardV2 = (
{ id }: UnlockDashboardV2PathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v2/dashboards/${id}/lock`,
method: 'DELETE',
signal,
@@ -1728,7 +1110,7 @@ export const lockDashboardV2 = (
{ id }: LockDashboardV2PathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v2/dashboards/${id}/lock`,
method: 'PUT',
signal,
@@ -1799,260 +1181,3 @@ export const useLockDashboardV2 = <
> => {
return useMutation(getLockDashboardV2MutationOptions(options));
};
/**
* Same as ListDashboardsV2 but personalized for the calling user: each dashboard carries the caller's `pinned` state, and pinned dashboards float to the top of the requested ordering. Supports the same filter DSL, sort, order, and pagination.
* @summary List dashboards for the current user (v2)
*/
export const listDashboardsForUserV2 = (
params?: ListDashboardsForUserV2Params,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<ListDashboardsForUserV2200>({
url: `/api/v2/users/me/dashboards`,
method: 'GET',
params,
signal,
});
};
export const getListDashboardsForUserV2QueryKey = (
params?: ListDashboardsForUserV2Params,
) => {
return [`/api/v2/users/me/dashboards`, ...(params ? [params] : [])] as const;
};
export const getListDashboardsForUserV2QueryOptions = <
TData = Awaited<ReturnType<typeof listDashboardsForUserV2>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(
params?: ListDashboardsForUserV2Params,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listDashboardsForUserV2>>,
TError,
TData
>;
},
) => {
const { query: queryOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ?? getListDashboardsForUserV2QueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof listDashboardsForUserV2>>
> = ({ signal }) => listDashboardsForUserV2(params, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof listDashboardsForUserV2>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type ListDashboardsForUserV2QueryResult = NonNullable<
Awaited<ReturnType<typeof listDashboardsForUserV2>>
>;
export type ListDashboardsForUserV2QueryError =
ErrorType<RenderErrorResponseDTO>;
/**
* @summary List dashboards for the current user (v2)
*/
export function useListDashboardsForUserV2<
TData = Awaited<ReturnType<typeof listDashboardsForUserV2>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(
params?: ListDashboardsForUserV2Params,
options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listDashboardsForUserV2>>,
TError,
TData
>;
},
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getListDashboardsForUserV2QueryOptions(params, options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
}
/**
* @summary List dashboards for the current user (v2)
*/
export const invalidateListDashboardsForUserV2 = async (
queryClient: QueryClient,
params?: ListDashboardsForUserV2Params,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getListDashboardsForUserV2QueryKey(params) },
options,
);
return queryClient;
};
/**
* Removes the pin for the calling user. Idempotent — unpinning a dashboard that wasn't pinned still returns 204.
* @summary Unpin a dashboard for the current user (v2)
*/
export const unpinDashboardV2 = (
{ id }: UnpinDashboardV2PathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/users/me/dashboards/${id}/pins`,
method: 'DELETE',
signal,
});
};
export const getUnpinDashboardV2MutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof unpinDashboardV2>>,
TError,
{ pathParams: UnpinDashboardV2PathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof unpinDashboardV2>>,
TError,
{ pathParams: UnpinDashboardV2PathParameters },
TContext
> => {
const mutationKey = ['unpinDashboardV2'];
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 unpinDashboardV2>>,
{ pathParams: UnpinDashboardV2PathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return unpinDashboardV2(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type UnpinDashboardV2MutationResult = NonNullable<
Awaited<ReturnType<typeof unpinDashboardV2>>
>;
export type UnpinDashboardV2MutationError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Unpin a dashboard for the current user (v2)
*/
export const useUnpinDashboardV2 = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof unpinDashboardV2>>,
TError,
{ pathParams: UnpinDashboardV2PathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof unpinDashboardV2>>,
TError,
{ pathParams: UnpinDashboardV2PathParameters },
TContext
> => {
return useMutation(getUnpinDashboardV2MutationOptions(options));
};
/**
* Pins the dashboard for the calling user. A user can pin at most 10 dashboards; pinning when at the limit returns 409. Re-pinning an already-pinned dashboard is a no-op success.
* @summary Pin a dashboard for the current user (v2)
*/
export const pinDashboardV2 = (
{ id }: PinDashboardV2PathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/users/me/dashboards/${id}/pins`,
method: 'PUT',
signal,
});
};
export const getPinDashboardV2MutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof pinDashboardV2>>,
TError,
{ pathParams: PinDashboardV2PathParameters },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof pinDashboardV2>>,
TError,
{ pathParams: PinDashboardV2PathParameters },
TContext
> => {
const mutationKey = ['pinDashboardV2'];
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 pinDashboardV2>>,
{ pathParams: PinDashboardV2PathParameters }
> = (props) => {
const { pathParams } = props ?? {};
return pinDashboardV2(pathParams);
};
return { mutationFn, ...mutationOptions };
};
export type PinDashboardV2MutationResult = NonNullable<
Awaited<ReturnType<typeof pinDashboardV2>>
>;
export type PinDashboardV2MutationError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Pin a dashboard for the current user (v2)
*/
export const usePinDashboardV2 = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof pinDashboardV2>>,
TError,
{ pathParams: PinDashboardV2PathParameters },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof pinDashboardV2>>,
TError,
{ pathParams: PinDashboardV2PathParameters },
TContext
> => {
return useMutation(getPinDashboardV2MutationOptions(options));
};

View File

@@ -37,7 +37,7 @@ export const handleExportRawDataPOST = (
params?: HandleExportRawDataPOSTParams,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/export_raw_data`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },

View File

@@ -680,7 +680,7 @@ export const updateMetricMetadata = (
metricsexplorertypesUpdateMetricMetadataRequestDTO?: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v2/metrics/${metricName}/metadata`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },

View File

@@ -203,7 +203,7 @@ export const deleteRole = (
{ id }: DeleteRolePathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}`,
method: 'DELETE',
signal,
@@ -372,7 +372,7 @@ export const patchRole = (
authtypesPatchableRoleDTO?: BodyType<AuthtypesPatchableRoleDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}`,
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
@@ -572,7 +572,7 @@ export const patchObjects = (
coretypesPatchableObjectsDTO?: BodyType<CoretypesPatchableObjectsDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}/relations/${relation}/objects`,
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },

View File

@@ -222,7 +222,7 @@ export const deleteServiceAccount = (
{ id }: DeleteServiceAccountPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/service_accounts/${id}`,
method: 'DELETE',
signal,
@@ -405,7 +405,7 @@ export const updateServiceAccount = (
serviceaccounttypesPostableServiceAccountDTO?: BodyType<ServiceaccounttypesPostableServiceAccountDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/service_accounts/${id}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
@@ -707,7 +707,7 @@ export const revokeServiceAccountKey = (
{ id, fid }: RevokeServiceAccountKeyPathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/service_accounts/${id}/keys/${fid}`,
method: 'DELETE',
signal,
@@ -788,7 +788,7 @@ export const updateServiceAccountKey = (
serviceaccounttypesUpdatableFactorAPIKeyDTO?: BodyType<ServiceaccounttypesUpdatableFactorAPIKeyDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/service_accounts/${id}/keys/${fid}`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
@@ -1090,7 +1090,7 @@ export const deleteServiceAccountRole = (
{ id, rid }: DeleteServiceAccountRolePathParameters,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/service_accounts/${id}/roles/${rid}`,
method: 'DELETE',
signal,
@@ -1254,7 +1254,7 @@ export const updateMyServiceAccount = (
serviceaccounttypesPostableServiceAccountDTO?: BodyType<ServiceaccounttypesPostableServiceAccountDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
return GeneratedAPIInstance<string>({
url: `/api/v1/service_accounts/me`,
method: 'PUT',
headers: { 'Content-Type': 'application/json' },

View File

@@ -413,11 +413,21 @@ export interface AlertmanagertypesRecurrenceDTO {
* @type string
*/
duration: string;
/**
* @type string,null
* @format date-time
*/
endTime?: string | null;
/**
* @type array,null
*/
repeatOn?: AlertmanagertypesRepeatOnDTO[] | null;
repeatType: AlertmanagertypesRepeatTypeDTO;
/**
* @type string
* @format date-time
*/
startTime: string;
}
export interface AlertmanagertypesScheduleDTO {
@@ -431,7 +441,7 @@ export interface AlertmanagertypesScheduleDTO {
* @type string
* @format date-time
*/
startTime: string;
startTime?: string;
/**
* @type string
*/
@@ -2143,10 +2153,6 @@ export interface ErrorsResponseerroradditionalDTO {
* @type string
*/
message?: string;
/**
* @type array
*/
suggestions?: string[];
}
export interface ErrorsResponseretryjsonDTO {
@@ -2162,6 +2168,10 @@ export interface ErrorsJSONDTO {
* @type array
*/
errors?: ErrorsResponseerroradditionalDTO[];
/**
* @type array
*/
invalidReferences?: string[];
/**
* @type string
*/
@@ -2641,18 +2651,6 @@ export enum CloudintegrationtypesServiceIDDTO {
sqs = 'sqs',
storageaccountsblob = 'storageaccountsblob',
cdnprofile = 'cdnprofile',
virtualmachine = 'virtualmachine',
appservice = 'appservice',
containerapp = 'containerapp',
aks = 'aks',
sqldatabase = 'sqldatabase',
sqldatabasemi = 'sqldatabasemi',
mysqlflexibleserver = 'mysqlflexibleserver',
postgresqlflexibleserver = 'postgresqlflexibleserver',
mongodb = 'mongodb',
cosmosdb = 'cosmosdb',
cassandradb = 'cassandradb',
redis = 'redis',
}
export type CloudintegrationtypesCloudIntegrationServiceDTOAnyOf = {
/**
@@ -3154,6 +3152,17 @@ export interface DashboardLinkDTO {
url?: string;
}
export interface DashboardPanelDisplayDTO {
/**
* @type string
*/
description?: string;
/**
* @type string
*/
name?: string;
}
export interface VariableDisplayDTO {
/**
* @type string
@@ -3482,9 +3491,6 @@ export interface TelemetrytypesTelemetryFieldKeyDTO {
unit?: string;
}
export enum Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregationDTOSignal {
logs = 'logs',
}
export enum TelemetrytypesSourceDTO {
meter = 'meter',
}
@@ -3540,11 +3546,7 @@ export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTyp
* @type array
*/
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
/**
* @enum logs
* @type string
*/
signal: Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregationDTOSignal;
signal?: TelemetrytypesSignalDTO;
source?: TelemetrytypesSourceDTO;
stepInterval?: Querybuildertypesv5StepDTO;
}
@@ -3610,9 +3612,6 @@ export interface Querybuildertypesv5MetricAggregationDTO {
timeAggregation?: MetrictypesTimeAggregationDTO;
}
export enum Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregationDTOSignal {
metrics = 'metrics',
}
export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregationDTO {
/**
* @type array
@@ -3665,11 +3664,7 @@ export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTyp
* @type array
*/
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
/**
* @enum metrics
* @type string
*/
signal: Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregationDTOSignal;
signal?: TelemetrytypesSignalDTO;
source?: TelemetrytypesSourceDTO;
stepInterval?: Querybuildertypesv5StepDTO;
}
@@ -3685,9 +3680,6 @@ export interface Querybuildertypesv5TraceAggregationDTO {
expression?: string;
}
export enum Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregationDTOSignal {
traces = 'traces',
}
export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregationDTO {
/**
* @type array
@@ -3740,11 +3732,7 @@ export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTyp
* @type array
*/
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
/**
* @enum traces
* @type string
*/
signal: Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregationDTOSignal;
signal?: TelemetrytypesSignalDTO;
source?: TelemetrytypesSourceDTO;
stepInterval?: Querybuildertypesv5StepDTO;
}
@@ -3879,17 +3867,6 @@ export type DashboardtypesDashboardSpecDTODatasources = {
export enum DashboardtypesPanelKindDTO {
Panel = 'Panel',
}
export interface DashboardtypesDisplayDTO {
/**
* @type string
*/
description?: string;
/**
* @type string
*/
name: string;
}
export enum DashboardtypesPanelPluginVariantGithubComSigNozSignozPkgTypesDashboardtypesTimeSeriesPanelSpecDTOKind {
'signoz/TimeSeriesPanel' = 'signoz/TimeSeriesPanel',
}
@@ -4438,36 +4415,42 @@ export interface DashboardtypesQuerySpecDTO {
* @type string
*/
name?: string;
plugin: DashboardtypesQueryPluginDTO;
plugin?: DashboardtypesQueryPluginDTO;
}
export interface DashboardtypesQueryDTO {
kind: Querybuildertypesv5RequestTypeDTO;
spec: DashboardtypesQuerySpecDTO;
kind?: Querybuildertypesv5RequestTypeDTO;
spec?: DashboardtypesQuerySpecDTO;
}
export interface DashboardtypesPanelSpecDTO {
display: DashboardtypesDisplayDTO;
display?: DashboardPanelDisplayDTO;
/**
* @type array
*/
links?: DashboardLinkDTO[];
plugin: DashboardtypesPanelPluginDTO;
plugin?: DashboardtypesPanelPluginDTO;
/**
* @type array,null
* @type array
*/
queries: DashboardtypesQueryDTO[] | null;
queries?: DashboardtypesQueryDTO[];
}
export interface DashboardtypesPanelDTO {
kind: DashboardtypesPanelKindDTO;
spec: DashboardtypesPanelSpecDTO;
kind?: DashboardtypesPanelKindDTO;
spec?: DashboardtypesPanelSpecDTO;
}
export type DashboardtypesDashboardSpecDTOPanels = {
export type DashboardtypesDashboardSpecDTOPanelsAnyOf = {
[key: string]: DashboardtypesPanelDTO;
};
/**
* @nullable
*/
export type DashboardtypesDashboardSpecDTOPanels =
DashboardtypesDashboardSpecDTOPanelsAnyOf | null;
export enum DashboardtypesLayoutEnvelopeGithubComPersesSpecGoDashboardGridLayoutSpecDTOKind {
Grid = 'Grid',
}
@@ -4564,7 +4547,7 @@ export interface DashboardtypesListVariableSpecDTO {
*/
customAllValue?: string;
defaultValue?: VariableDefaultValueDTO;
display: DashboardtypesDisplayDTO;
display?: VariableDisplayDTO;
/**
* @type string
*/
@@ -4606,23 +4589,23 @@ export interface DashboardtypesDashboardSpecDTO {
* @type object
*/
datasources?: DashboardtypesDashboardSpecDTODatasources;
display: DashboardtypesDisplayDTO;
display?: CommonDisplayDTO;
/**
* @type string
*/
duration?: string;
/**
* @type array
* @type array,null
*/
layouts: DashboardtypesLayoutDTO[];
layouts?: DashboardtypesLayoutDTO[] | null;
/**
* @type array
*/
links?: DashboardLinkDTO[];
/**
* @type object
* @type object,null
*/
panels: DashboardtypesDashboardSpecDTOPanels;
panels?: DashboardtypesDashboardSpecDTOPanels;
/**
* @type string
*/
@@ -4630,61 +4613,13 @@ export interface DashboardtypesDashboardSpecDTO {
/**
* @type array
*/
variables: DashboardtypesVariableDTO[];
}
export enum DashboardtypesListOrderDTO {
asc = 'asc',
desc = 'desc',
}
export enum DashboardtypesListSortDTO {
updated_at = 'updated_at',
created_at = 'created_at',
name = 'name',
}
export interface DashboardtypesDashboardViewDataDTO {
order?: DashboardtypesListOrderDTO;
/**
* @type string
*/
query?: string;
sort?: DashboardtypesListSortDTO;
/**
* @type string
*/
version: string;
}
export interface DashboardtypesDashboardViewDTO {
/**
* @type string
* @format date-time
*/
createdAt?: string;
data: DashboardtypesDashboardViewDataDTO;
/**
* @type string
*/
id: string;
/**
* @type string
*/
name: string;
/**
* @type string
*/
orgId: string;
/**
* @type string
* @format date-time
*/
updatedAt?: string;
variables?: DashboardtypesVariableDTO[];
}
export enum DashboardtypesDatasourcePluginKindDTO {
'signoz/Datasource' = 'signoz/Datasource',
}
export interface TagtypesGettableTagDTO {
export interface TagtypesPostableTagDTO {
/**
* @type string
*/
@@ -4734,7 +4669,7 @@ export interface DashboardtypesGettableDashboardV2DTO {
/**
* @type array,null
*/
tags: TagtypesGettableTagDTO[] | null;
tags: TagtypesPostableTagDTO[] | null;
/**
* @type string
* @format date-time
@@ -4792,155 +4727,6 @@ export interface DashboardtypesJSONPatchOperationDTO {
value?: unknown;
}
export interface DashboardtypesListedDashboardV2SpecDTO {
display?: DashboardtypesDisplayDTO;
}
export interface DashboardtypesListedDashboardForUserV2DTO {
/**
* @type string
* @format date-time
*/
createdAt?: string;
/**
* @type string
*/
createdBy?: string;
/**
* @type string
*/
id: string;
/**
* @type string
*/
image?: string;
/**
* @type boolean
*/
locked: boolean;
/**
* @type string
*/
name: string;
/**
* @type string
*/
orgId: string;
/**
* @type boolean
*/
pinned: boolean;
/**
* @type string
*/
schemaVersion: string;
source: DashboardtypesSourceDTO;
spec: DashboardtypesListedDashboardV2SpecDTO;
/**
* @type array
*/
tags: TagtypesGettableTagDTO[];
/**
* @type string
* @format date-time
*/
updatedAt?: string;
/**
* @type string
*/
updatedBy?: string;
}
export interface DashboardtypesListableDashboardForUserV2DTO {
/**
* @type array
*/
dashboards: DashboardtypesListedDashboardForUserV2DTO[];
/**
* @type array
*/
tags: TagtypesGettableTagDTO[];
/**
* @type integer
* @format int64
*/
total: number;
}
export interface DashboardtypesListedDashboardV2DTO {
/**
* @type string
* @format date-time
*/
createdAt?: string;
/**
* @type string
*/
createdBy?: string;
/**
* @type string
*/
id: string;
/**
* @type string
*/
image?: string;
/**
* @type boolean
*/
locked: boolean;
/**
* @type string
*/
name: string;
/**
* @type string
*/
orgId: string;
/**
* @type string
*/
schemaVersion: string;
source: DashboardtypesSourceDTO;
spec: DashboardtypesListedDashboardV2SpecDTO;
/**
* @type array
*/
tags: TagtypesGettableTagDTO[];
/**
* @type string
* @format date-time
*/
updatedAt?: string;
/**
* @type string
*/
updatedBy?: string;
}
export interface DashboardtypesListableDashboardV2DTO {
/**
* @type array
*/
dashboards: DashboardtypesListedDashboardV2DTO[];
/**
* @type array
*/
tags: TagtypesGettableTagDTO[];
/**
* @type integer
* @format int64
*/
total: number;
}
export interface DashboardtypesListableDashboardViewDTO {
/**
* @type array
*/
views: DashboardtypesDashboardViewDTO[];
}
export enum DashboardtypesPanelPluginKindDTO {
'signoz/TimeSeriesPanel' = 'signoz/TimeSeriesPanel',
'signoz/BarChartPanel' = 'signoz/BarChartPanel',
@@ -4957,17 +4743,6 @@ export type DashboardtypesPatchableDashboardV2DTO =
| DashboardtypesJSONPatchOperationDTO[]
| null;
export interface TagtypesPostableTagDTO {
/**
* @type string
*/
key: string;
/**
* @type string
*/
value: string;
}
export interface DashboardtypesPostableDashboardV2DTO {
/**
* @type boolean
@@ -4992,14 +4767,6 @@ export interface DashboardtypesPostableDashboardV2DTO {
tags: TagtypesPostableTagDTO[] | null;
}
export interface DashboardtypesPostableDashboardViewDTO {
data: DashboardtypesDashboardViewDataDTO;
/**
* @type string
*/
name: string;
}
export interface DashboardtypesPostablePublicDashboardDTO {
/**
* @type string
@@ -8002,77 +7769,6 @@ export enum SpantypesFieldContextDTO {
attribute = 'attribute',
resource = 'resource',
}
export type SpantypesFlamegraphSpanDTOAttributes = { [key: string]: unknown };
export type SpantypesFlamegraphSpanDTOResource = { [key: string]: string };
export interface SpantypesFlamegraphSpanDTO {
/**
* @type object
*/
attributes: SpantypesFlamegraphSpanDTOAttributes;
/**
* @type integer
* @minimum 0
*/
durationNano: number;
/**
* @type array
*/
event: SpantypesEventDTO[];
/**
* @type boolean
*/
hasError: boolean;
/**
* @type integer
* @format int64
*/
level: number;
/**
* @type string
*/
name: string;
/**
* @type string
*/
parentSpanId: string;
/**
* @type object
*/
resource: SpantypesFlamegraphSpanDTOResource;
/**
* @type string
*/
spanId: string;
/**
* @type integer
* @minimum 0
*/
timestamp: number;
}
export interface SpantypesGettableFlamegraphTraceDTO {
/**
* @type integer
* @format int64
*/
endTimestampMillis: number;
/**
* @type boolean
*/
hasMore: boolean;
/**
* @type array
*/
spans: SpantypesFlamegraphSpanDTO[][];
/**
* @type integer
* @format int64
*/
startTimestampMillis: number;
}
export type SpantypesSpanMapperGroupConditionDTOAnyOf = {
/**
* @type array,null
@@ -8135,44 +7831,6 @@ export interface SpantypesGettableSpanMapperGroupsDTO {
items: SpantypesSpanMapperGroupDTO[];
}
export type SpantypesSpanMapperTestSpanDTOAttributesAnyOf = {
[key: string]: unknown;
};
/**
* @nullable
*/
export type SpantypesSpanMapperTestSpanDTOAttributes =
SpantypesSpanMapperTestSpanDTOAttributesAnyOf | null;
export type SpantypesSpanMapperTestSpanDTOResourceAnyOf = {
[key: string]: unknown;
};
/**
* @nullable
*/
export type SpantypesSpanMapperTestSpanDTOResource =
SpantypesSpanMapperTestSpanDTOResourceAnyOf | null;
export interface SpantypesSpanMapperTestSpanDTO {
/**
* @type object,null
*/
attributes?: SpantypesSpanMapperTestSpanDTOAttributes;
/**
* @type object,null
*/
resource?: SpantypesSpanMapperTestSpanDTOResource;
}
export interface SpantypesGettableSpanMapperTestDTO {
/**
* @type array,null
*/
spans: SpantypesSpanMapperTestSpanDTO[] | null;
}
export enum SpantypesSpanAggregationTypeDTO {
span_count = 'span_count',
execution_time_percentage = 'execution_time_percentage',
@@ -8362,6 +8020,10 @@ export interface SpantypesWaterfallSpanDTO {
}
export interface SpantypesGettableWaterfallTraceDTO {
/**
* @type array,null
*/
aggregations?: SpantypesSpanAggregationResultDTO[] | null;
/**
* @type integer
* @minimum 0
@@ -8408,17 +8070,6 @@ export interface SpantypesGettableWaterfallTraceDTO {
uncollapsedSpans?: string[] | null;
}
export interface SpantypesPostableFlamegraphDTO {
/**
* @type array
*/
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
/**
* @type string
*/
selectedSpanId?: string;
}
export enum SpantypesSpanMapperOperationDTO {
move = 'move',
copy = 'copy',
@@ -8468,33 +8119,6 @@ export interface SpantypesPostableSpanMapperGroupDTO {
name: string;
}
export interface SpantypesPostableSpanMapperTestGroupDTO {
condition: SpantypesSpanMapperGroupConditionDTO | null;
/**
* @type boolean
*/
enabled?: boolean;
/**
* @type array,null
*/
mappers?: SpantypesPostableSpanMapperDTO[] | null;
/**
* @type string
*/
name: string;
}
export interface SpantypesPostableSpanMapperTestDTO {
/**
* @type array,null
*/
groups: SpantypesPostableSpanMapperTestGroupDTO[] | null;
/**
* @type array,null
*/
spans: SpantypesSpanMapperTestSpanDTO[] | null;
}
export interface SpantypesSpanAggregationDTO {
aggregation: SpantypesSpanAggregationTypeDTO;
field: TelemetrytypesTelemetryFieldKeyDTO;
@@ -8508,6 +8132,15 @@ export interface SpantypesPostableTraceAggregationsDTO {
}
export interface SpantypesPostableWaterfallDTO {
/**
* @type array,null
*/
aggregations?: SpantypesSpanAggregationDTO[] | null;
/**
* @type integer
* @minimum 0
*/
limit?: number;
/**
* @type string
*/
@@ -9863,27 +9496,6 @@ export type UpdateSpanMapperPathParameters = {
groupId: string;
mapperId: string;
};
export type TestSpanMappers200 = {
data: SpantypesGettableSpanMapperTestDTO;
/**
* @type string
*/
status: string;
};
export type GetStats200Data = { [key: string]: unknown };
export type GetStats200 = {
/**
* @type object
*/
data: GetStats200Data;
/**
* @type string
*/
status: string;
};
export type GetTraceAggregationsPathParameters = {
traceID: string;
};
@@ -9964,70 +9576,6 @@ export type GetUserPreference200 = {
export type UpdateUserPreferencePathParameters = {
name: string;
};
export type ListDashboardViews200 = {
data: DashboardtypesListableDashboardViewDTO;
/**
* @type string
*/
status: string;
};
export type CreateDashboardView201 = {
data: DashboardtypesDashboardViewDTO;
/**
* @type string
*/
status: string;
};
export type DeleteDashboardViewPathParameters = {
id: string;
};
export type UpdateDashboardViewPathParameters = {
id: string;
};
export type UpdateDashboardView200 = {
data: DashboardtypesDashboardViewDTO;
/**
* @type string
*/
status: string;
};
export type ListDashboardsV2Params = {
/**
* @type string
* @description undefined
*/
query?: string;
/**
* @description undefined
*/
sort?: DashboardtypesListSortDTO;
/**
* @description undefined
*/
order?: DashboardtypesListOrderDTO;
/**
* @type integer
* @description undefined
*/
limit?: number;
/**
* @type integer
* @description undefined
*/
offset?: number;
};
export type ListDashboardsV2200 = {
data: DashboardtypesListableDashboardV2DTO;
/**
* @type string
*/
status: string;
};
export type CreateDashboardV2201 = {
data: DashboardtypesGettableDashboardV2DTO;
/**
@@ -10036,9 +9584,6 @@ export type CreateDashboardV2201 = {
status: string;
};
export type DeleteDashboardV2PathParameters = {
id: string;
};
export type GetDashboardV2PathParameters = {
id: string;
};
@@ -10072,17 +9617,6 @@ export type UpdateDashboardV2200 = {
status: string;
};
export type CloneDashboardV2PathParameters = {
id: string;
};
export type CloneDashboardV2201 = {
data: DashboardtypesGettableDashboardV2DTO;
/**
* @type string
*/
status: string;
};
export type UnlockDashboardV2PathParameters = {
id: string;
};
@@ -10882,46 +10416,6 @@ export type GetMyUser200 = {
status: string;
};
export type ListDashboardsForUserV2Params = {
/**
* @type string
* @description undefined
*/
query?: string;
/**
* @description undefined
*/
sort?: DashboardtypesListSortDTO;
/**
* @description undefined
*/
order?: DashboardtypesListOrderDTO;
/**
* @type integer
* @description undefined
*/
limit?: number;
/**
* @type integer
* @description undefined
*/
offset?: number;
};
export type ListDashboardsForUserV2200 = {
data: DashboardtypesListableDashboardForUserV2DTO;
/**
* @type string
*/
status: string;
};
export type UnpinDashboardV2PathParameters = {
id: string;
};
export type PinDashboardV2PathParameters = {
id: string;
};
export type GetHosts200 = {
data: ZeustypesGettableHostDTO;
/**
@@ -10930,11 +10424,11 @@ export type GetHosts200 = {
status: string;
};
export type GetFlamegraphPathParameters = {
export type GetWaterfallPathParameters = {
traceID: string;
};
export type GetFlamegraph200 = {
data: SpantypesGettableFlamegraphTraceDTO;
export type GetWaterfall200 = {
data: SpantypesGettableWaterfallTraceDTO;
/**
* @type string
*/

View File

@@ -30,10 +30,8 @@ import type {
RenderErrorResponseDTO,
SpantypesPostableSpanMapperDTO,
SpantypesPostableSpanMapperGroupDTO,
SpantypesPostableSpanMapperTestDTO,
SpantypesUpdatableSpanMapperDTO,
SpantypesUpdatableSpanMapperGroupDTO,
TestSpanMappers200,
UpdateSpanMapperGroupPathParameters,
UpdateSpanMapperPathParameters,
} from '../sigNoz.schemas';
@@ -782,86 +780,3 @@ export const useUpdateSpanMapper = <
> => {
return useMutation(getUpdateSpanMapperMutationOptions(options));
};
/**
* Tests how span mappers would transform sample spans
* @summary Test span mappers against sample spans
*/
export const testSpanMappers = (
spantypesPostableSpanMapperTestDTO?: BodyType<SpantypesPostableSpanMapperTestDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<TestSpanMappers200>({
url: `/api/v1/span_mapper_groups/test`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: spantypesPostableSpanMapperTestDTO,
signal,
});
};
export const getTestSpanMappersMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof testSpanMappers>>,
TError,
{ data?: BodyType<SpantypesPostableSpanMapperTestDTO> },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof testSpanMappers>>,
TError,
{ data?: BodyType<SpantypesPostableSpanMapperTestDTO> },
TContext
> => {
const mutationKey = ['testSpanMappers'];
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 testSpanMappers>>,
{ data?: BodyType<SpantypesPostableSpanMapperTestDTO> }
> = (props) => {
const { data } = props ?? {};
return testSpanMappers(data);
};
return { mutationFn, ...mutationOptions };
};
export type TestSpanMappersMutationResult = NonNullable<
Awaited<ReturnType<typeof testSpanMappers>>
>;
export type TestSpanMappersMutationBody =
| BodyType<SpantypesPostableSpanMapperTestDTO>
| undefined;
export type TestSpanMappersMutationError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Test span mappers against sample spans
*/
export const useTestSpanMappers = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof testSpanMappers>>,
TError,
{ data?: BodyType<SpantypesPostableSpanMapperTestDTO> },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof testSpanMappers>>,
TError,
{ data?: BodyType<SpantypesPostableSpanMapperTestDTO> },
TContext
> => {
return useMutation(getTestSpanMappersMutationOptions(options));
};

View File

@@ -1,96 +0,0 @@
/**
* ! Do not edit manually
* * The file has been auto-generated using Orval for SigNoz
* * regenerate with 'pnpm generate:api'
* SigNoz
*/
import { useQuery } from 'react-query';
import type {
InvalidateOptions,
QueryClient,
QueryFunction,
QueryKey,
UseQueryOptions,
UseQueryResult,
} from 'react-query';
import type { GetStats200, RenderErrorResponseDTO } from '../sigNoz.schemas';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import type { ErrorType } from '../../../generatedAPIInstance';
/**
* This endpoint returns the collected stats for the organization
* @summary Get stats
*/
export const getStats = (signal?: AbortSignal) => {
return GeneratedAPIInstance<GetStats200>({
url: `/api/v1/stats`,
method: 'GET',
signal,
});
};
export const getGetStatsQueryKey = () => {
return [`/api/v1/stats`] as const;
};
export const getGetStatsQueryOptions = <
TData = Awaited<ReturnType<typeof getStats>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getStats>>, TError, TData>;
}) => {
const { query: queryOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetStatsQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof getStats>>> = ({
signal,
}) => getStats(signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof getStats>>,
TError,
TData
> & { queryKey: QueryKey };
};
export type GetStatsQueryResult = NonNullable<
Awaited<ReturnType<typeof getStats>>
>;
export type GetStatsQueryError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Get stats
*/
export function useGetStats<
TData = Awaited<ReturnType<typeof getStats>>,
TError = ErrorType<RenderErrorResponseDTO>,
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getStats>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
const queryOptions = getGetStatsQueryOptions(options);
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
queryKey: QueryKey;
};
return { ...query, queryKey: queryOptions.queryKey };
}
/**
* @summary Get stats
*/
export const invalidateGetStats = async (
queryClient: QueryClient,
options?: InvalidateOptions,
): Promise<QueryClient> => {
await queryClient.invalidateQueries(
{ queryKey: getGetStatsQueryKey() },
options,
);
return queryClient;
};

View File

@@ -12,14 +12,13 @@ import type {
} from 'react-query';
import type {
GetFlamegraph200,
GetFlamegraphPathParameters,
GetTraceAggregations200,
GetTraceAggregationsPathParameters,
GetWaterfall200,
GetWaterfallPathParameters,
GetWaterfallV4200,
GetWaterfallV4PathParameters,
RenderErrorResponseDTO,
SpantypesPostableFlamegraphDTO,
SpantypesPostableTraceAggregationsDTO,
SpantypesPostableWaterfallDTO,
} from '../sigNoz.schemas';
@@ -128,46 +127,46 @@ export const useGetTraceAggregations = <
return useMutation(getGetTraceAggregationsMutationOptions(options));
};
/**
* Returns the flamegraph view of spans for a given trace ID.
* @summary Get flamegraph view for a trace
* Returns the waterfall view of spans for a given trace ID with tree structure, metadata, and windowed pagination
* @summary Get waterfall view for a trace
*/
export const getFlamegraph = (
{ traceID }: GetFlamegraphPathParameters,
spantypesPostableFlamegraphDTO?: BodyType<SpantypesPostableFlamegraphDTO>,
export const getWaterfall = (
{ traceID }: GetWaterfallPathParameters,
spantypesPostableWaterfallDTO?: BodyType<SpantypesPostableWaterfallDTO>,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetFlamegraph200>({
url: `/api/v3/traces/${traceID}/flamegraph`,
return GeneratedAPIInstance<GetWaterfall200>({
url: `/api/v3/traces/${traceID}/waterfall`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: spantypesPostableFlamegraphDTO,
data: spantypesPostableWaterfallDTO,
signal,
});
};
export const getGetFlamegraphMutationOptions = <
export const getGetWaterfallMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getFlamegraph>>,
Awaited<ReturnType<typeof getWaterfall>>,
TError,
{
pathParams: GetFlamegraphPathParameters;
data?: BodyType<SpantypesPostableFlamegraphDTO>;
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof getFlamegraph>>,
Awaited<ReturnType<typeof getWaterfall>>,
TError,
{
pathParams: GetFlamegraphPathParameters;
data?: BodyType<SpantypesPostableFlamegraphDTO>;
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
},
TContext
> => {
const mutationKey = ['getFlamegraph'];
const mutationKey = ['getWaterfall'];
const { mutation: mutationOptions } = options
? options.mutation &&
'mutationKey' in options.mutation &&
@@ -177,54 +176,54 @@ export const getGetFlamegraphMutationOptions = <
: { mutation: { mutationKey } };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof getFlamegraph>>,
Awaited<ReturnType<typeof getWaterfall>>,
{
pathParams: GetFlamegraphPathParameters;
data?: BodyType<SpantypesPostableFlamegraphDTO>;
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
}
> = (props) => {
const { pathParams, data } = props ?? {};
return getFlamegraph(pathParams, data);
return getWaterfall(pathParams, data);
};
return { mutationFn, ...mutationOptions };
};
export type GetFlamegraphMutationResult = NonNullable<
Awaited<ReturnType<typeof getFlamegraph>>
export type GetWaterfallMutationResult = NonNullable<
Awaited<ReturnType<typeof getWaterfall>>
>;
export type GetFlamegraphMutationBody =
| BodyType<SpantypesPostableFlamegraphDTO>
export type GetWaterfallMutationBody =
| BodyType<SpantypesPostableWaterfallDTO>
| undefined;
export type GetFlamegraphMutationError = ErrorType<RenderErrorResponseDTO>;
export type GetWaterfallMutationError = ErrorType<RenderErrorResponseDTO>;
/**
* @summary Get flamegraph view for a trace
* @summary Get waterfall view for a trace
*/
export const useGetFlamegraph = <
export const useGetWaterfall = <
TError = ErrorType<RenderErrorResponseDTO>,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getFlamegraph>>,
Awaited<ReturnType<typeof getWaterfall>>,
TError,
{
pathParams: GetFlamegraphPathParameters;
data?: BodyType<SpantypesPostableFlamegraphDTO>;
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof getFlamegraph>>,
Awaited<ReturnType<typeof getWaterfall>>,
TError,
{
pathParams: GetFlamegraphPathParameters;
data?: BodyType<SpantypesPostableFlamegraphDTO>;
pathParams: GetWaterfallPathParameters;
data?: BodyType<SpantypesPostableWaterfallDTO>;
},
TContext
> => {
return useMutation(getGetFlamegraphMutationOptions(options));
return useMutation(getGetWaterfallMutationOptions(options));
};
/**
* Returns the waterfall view of spans including all spans if total spans are under a limit, a max count otherwise. Aggregations are dropped compared to v3

View File

@@ -5,13 +5,6 @@ import {
QueryKeySuggestionsResponseProps,
} from 'types/api/querySuggestions/types';
/**
* @deprecated Use the generated `useGetFieldsKeys` hook (or `getFieldsKeys` fetcher) from
* `api/generated/services/fields` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getKeySuggestions = (
props: QueryKeyRequestProps,
): Promise<AxiosResponse<QueryKeySuggestionsResponseProps>> => {

View File

@@ -5,13 +5,6 @@ import {
QueryKeyValueSuggestionsResponseProps,
} from 'types/api/querySuggestions/types';
/**
* @deprecated Use the generated `useGetFieldsValues` hook (or `getFieldsValues` fetcher) from
* `api/generated/services/fields` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getValueSuggestions = (
props: QueryKeyValueRequestProps,
): Promise<AxiosResponse<QueryKeyValueSuggestionsResponseProps>> => {

View File

@@ -15,13 +15,6 @@ export interface CreateRoutingPolicyResponse {
message: string;
}
/**
* @deprecated Use the generated `useCreateRoutePolicy` hook (or `createRoutePolicy` fetcher) from
* `api/generated/services/routepolicies` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const createRoutingPolicy = async (
props: CreateRoutingPolicyBody,
): Promise<

View File

@@ -8,13 +8,6 @@ export interface DeleteRoutingPolicyResponse {
message: string;
}
/**
* @deprecated Use the generated `useDeleteRoutePolicyByID` hook (or `deleteRoutePolicyByID` fetcher) from
* `api/generated/services/routepolicies` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const deleteRoutingPolicy = async (
routingPolicyId: string,
): Promise<

View File

@@ -20,13 +20,6 @@ export interface GetRoutingPoliciesResponse {
data?: ApiRoutingPolicy[];
}
/**
* @deprecated Use the generated `useGetAllRoutePolicies` hook (or `getAllRoutePolicies` fetcher) from
* `api/generated/services/routepolicies` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getRoutingPolicies = async (
signal?: AbortSignal,
headers?: Record<string, string>,

View File

@@ -15,13 +15,6 @@ export interface UpdateRoutingPolicyResponse {
message: string;
}
/**
* @deprecated Use the generated `useUpdateRoutePolicy` hook (or `updateRoutePolicy` fetcher) from
* `api/generated/services/routepolicies` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const updateRoutingPolicy = async (
id: string,
props: UpdateRoutingPolicyBody,

View File

@@ -1,24 +0,0 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import { ViewProps } from 'types/api/saveViews/types';
/**
* Fetches a single saved view by ID (`GET /api/v1/explorer/views/{viewId}`).
*
* Hand-maintained alongside the other `api/saveView/*` clients — explorer views
* are not in `docs/api/openapi.yml`, so Orval does not generate a hook here
* (unlike e.g. `useGetChannelByID` under `api/generated/services/channels`).
*
* Used by the AI assistant "Open view" action to load `compositeQuery` and
* navigate to the correct explorer without listing every view per source page.
* See `container/AIAssistant/components/ActionsSection/utils/openSavedView.ts`.
*/
export interface GetViewByIdProps {
status: string;
data: ViewProps;
}
export const getViewById = (
viewKey: string,
): Promise<AxiosResponse<GetViewByIdProps>> =>
axios.get(`/explorer/views/${viewKey}`);

View File

@@ -27,6 +27,7 @@ const getTraceV4 = async (
{
selectedSpanId: props.selectedSpanId,
uncollapsedSpans,
limit: 10000,
},
);

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/user/resetPassword';
/**
* @deprecated Use the generated `useResetPassword` hook (or `resetPassword` fetcher) from
* `api/generated/services/users` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const resetPassword = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { UsersProps } from 'types/api/user/inviteUsers';
/**
* @deprecated Use the generated `useCreateBulkInvite` hook (or `createBulkInvite` fetcher) from
* `api/generated/services/users` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const inviteUsers = async (
users: UsersProps,
): Promise<SuccessResponseV2<null>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/user/setInvite';
/**
* @deprecated Use the generated `useCreateInvite` hook (or `createInvite` fetcher) from
* `api/generated/services/users` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const sendInvite = async (
props: Props,
): Promise<SuccessResponseV2<PayloadProps>> => {

View File

@@ -5,13 +5,6 @@ import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps } from 'types/api/preferences/list';
import { OrgPreference } from 'types/api/preferences/preference';
/**
* @deprecated Use the generated `useListOrgPreferences` hook (or `listOrgPreferences` fetcher) from
* `api/generated/services/preferences` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const listPreference = async (): Promise<
SuccessResponseV2<OrgPreference[]>
> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { Props } from 'types/api/preferences/update';
/**
* @deprecated Use the generated `useUpdateOrgPreference` hook (or `updateOrgPreference` fetcher) from
* `api/generated/services/preferences` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const update = async (props: Props): Promise<SuccessResponseV2<null>> => {
try {
const response = await axios.put(`/org/preferences/${props.name}`, {

View File

@@ -5,13 +5,6 @@ import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps } from 'types/api/preferences/list';
import { UserPreference } from 'types/api/preferences/preference';
/**
* @deprecated Use the generated `useListUserPreferences` hook (or `listUserPreferences` fetcher) from
* `api/generated/services/preferences` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const list = async (): Promise<SuccessResponseV2<UserPreference[]>> => {
try {
const response = await axios.get<PayloadProps>(`/user/preferences`);

View File

@@ -5,13 +5,6 @@ import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { PayloadProps, Props } from 'types/api/preferences/get';
import { UserPreference } from 'types/api/preferences/preference';
/**
* @deprecated Use the generated `useGetUserPreference` hook (or `getUserPreference` fetcher) from
* `api/generated/services/preferences` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const get = async (
props: Props,
): Promise<SuccessResponseV2<UserPreference>> => {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
import { Props } from 'types/api/preferences/update';
/**
* @deprecated Use the generated `useUpdateUserPreference` hook (or `updateUserPreference` fetcher) from
* `api/generated/services/preferences` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const update = async (props: Props): Promise<SuccessResponseV2<null>> => {
try {
const response = await axios.put(`/user/preferences/${props.name}`, {

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, RawSuccessResponse, SuccessResponseV2 } from 'types/api';
import { Props, SessionsContext } from 'types/api/v2/sessions/context/get';
/**
* @deprecated Use the generated `useGetSessionContext` hook (or `getSessionContext` fetcher) from
* `api/generated/services/sessions` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const get = async (
props: Props,
): Promise<SuccessResponseV2<SessionsContext>> => {

View File

@@ -3,13 +3,6 @@ import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
import { AxiosError } from 'axios';
import { ErrorV2Resp, RawSuccessResponse, SuccessResponseV2 } from 'types/api';
/**
* @deprecated Use the generated `useDeleteSession` hook (or `deleteSession` fetcher) from
* `api/generated/services/sessions` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const deleteSession = async (): Promise<SuccessResponseV2<null>> => {
try {
const response = await axios.delete<RawSuccessResponse<null>>('/sessions');

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, RawSuccessResponse, SuccessResponseV2 } from 'types/api';
import { Props, Token } from 'types/api/v2/sessions/email_password/post';
/**
* @deprecated Use the generated `useCreateSessionByEmailPassword` hook (or `createSessionByEmailPassword` fetcher) from
* `api/generated/services/sessions` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const post = async (props: Props): Promise<SuccessResponseV2<Token>> => {
try {
const response = await axios.post<RawSuccessResponse<Token>>(

View File

@@ -4,13 +4,6 @@ import { AxiosError } from 'axios';
import { ErrorV2Resp, RawSuccessResponse, SuccessResponseV2 } from 'types/api';
import { Props, Token } from 'types/api/v2/sessions/rotate/post';
/**
* @deprecated Use the generated `useRotateSession` hook (or `rotateSession` fetcher) from
* `api/generated/services/sessions` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
const post = async (props: Props): Promise<SuccessResponseV2<Token>> => {
try {
const response = await axios.post<RawSuccessResponse<Token>>(

View File

@@ -8,13 +8,6 @@ import {
QueryRangePayloadV5,
} from 'types/api/v5/queryRange';
/**
* @deprecated Use the generated `useQueryRangeV5` hook (or `queryRangeV5` fetcher) from
* `api/generated/services/querier` instead. This hand-written client targets the
* same endpoint and will be removed once call sites migrate.
*
* Part of https://github.com/SigNoz/engineering-pod/issues/5289, add a comment or update when removing this method.
*/
export const getQueryRangeV5 = async (
props: QueryRangePayloadV5,
version: string,

View File

@@ -1,11 +1,5 @@
// TODO: Improve the styling of the query aggregation container and its components. - @YounixM , @H4ad
$dropdown-base-height: 250px;
$recents-header-height: 30px;
$recent-row-height: 36px;
// how many recents are rendered, this caps how tall the dropdown can grow to fit them.
$max-recents-shown: 5;
.code-mirror-where-clause {
width: 100%;
display: flex;
@@ -123,23 +117,7 @@ $max-recents-shown: 5;
width: 100% !important;
max-width: 100% !important;
font-family: 'Space Mono', monospace !important;
max-height: $dropdown-base-height !important;
overflow-y: auto !important;
// Recents render at the top of the dropdown ahead of regular suggestions.
// At the base max-height, having recents in view would crowd out the
// suggestion list below. This loop grows the dropdown by one row's worth
// of height for every recent present (up to $max-recents-shown), plus the
// section header. `:has(> li:nth-of-type(N) .cm-completionIcon-recent)`
// matches when the Nth child of <ul> is a recent — i.e. there are at
// least N recents visible.
@for $i from 1 through $max-recents-shown {
&:has(> li:nth-of-type(#{$i}) .cm-completionIcon-recent) {
max-height: $dropdown-base-height +
$recents-header-height +
($i * $recent-row-height) !important;
}
}
min-height: 200px !important;
&::-webkit-scrollbar {
width: 0.3rem;
@@ -155,19 +133,6 @@ $max-recents-shown: 5;
background: transparent;
}
completion-section {
display: block;
padding: 10px 12px 6px;
font-size: 10px !important;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--l3-foreground, var(--l2-foreground));
opacity: 0.7;
border-bottom: 0;
background-color: transparent;
}
li {
width: 100% !important;
max-width: 100% !important;
@@ -194,78 +159,11 @@ $max-recents-shown: 5;
display: none !important;
}
.cm-completionDetail {
margin-left: auto;
font-style: normal;
font-size: var(--periscope-font-size-small, 11px);
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
opacity: 0.55;
}
&[aria-selected='true'] {
background: var(--l3-background) !important;
font-weight: 600 !important;
}
}
li:has(.cm-completionIcon-recent) {
&:hover .cm-recent-delete,
&[aria-selected='true'] .cm-recent-delete {
opacity: 1;
}
}
li .cm-completionLabel {
flex: 1;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cm-recent-delete {
margin-left: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
padding: 0;
border: 0;
border-radius: 4px;
background: transparent;
color: var(--l2-foreground);
font-size: 18px;
line-height: 1;
cursor: pointer;
opacity: 0.5;
transition:
opacity 0.12s ease,
background-color 0.12s ease;
&:hover {
opacity: 1;
background: color-mix(in srgb, var(--l2-foreground) 18%, transparent);
}
}
}
&::after {
content: '↓↑ to navigate · ↵ to apply · esc to dismiss';
display: block;
padding: 8px 12px;
border-top: 1px solid var(--l1-border);
font-family: 'Space Mono', monospace;
font-size: 11px;
font-weight: 500;
letter-spacing: 0.02em;
color: var(--l2-foreground);
opacity: 0.6;
background: color-mix(in srgb, var(--l1-background) 50%, transparent);
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
}

View File

@@ -46,15 +46,8 @@ import {
import { validateQuery } from 'utils/queryValidationUtils';
import { unquote } from 'utils/stringUtils';
import { getRecentQueries } from 'lib/recentQueries/getRecentQueries';
import type { SignalType } from 'types/api/v5/queryRange';
import { queryExamples, SUGGESTIONS_SECTION } from './constants';
import {
combineInitialAndUserExpression,
getRecentOptions,
renderRecentDeleteButton,
} from './utils';
import { queryExamples } from './constants';
import { combineInitialAndUserExpression } from './utils';
import './QuerySearch.styles.scss';
@@ -1257,41 +1250,6 @@ function QuerySearch({
};
}
const signal = dataSource as SignalType;
function combinedSuggestions(
context: CompletionContext,
): CompletionResult | null {
const fullDoc = context.state.doc.toString();
const recentOptions = getRecentOptions(
getRecentQueries(signal, signalSource ?? ''),
fullDoc,
);
const result = autoSuggestions(context);
const suggestionOptions = (result?.options || []).map((opt) => ({
...opt,
section: SUGGESTIONS_SECTION,
}));
if (recentOptions.length === 0 && suggestionOptions.length === 0) {
return result;
}
if (!result) {
return {
from: 0,
to: fullDoc.length,
options: recentOptions,
};
}
return {
...result,
options: [...recentOptions, ...suggestionOptions],
};
}
// Effect to handle focus state and trigger suggestions
useEffect(() => {
const clearTimeout = toggleSuggestions(10);
@@ -1440,12 +1398,11 @@ function QuerySearch({
})}
extensions={[
autocompletion({
override: [combinedSuggestions],
override: [autoSuggestions],
defaultKeymap: true,
closeOnBlur: true,
activateOnTyping: true,
maxRenderedOptions: 50,
addToOptions: [{ render: renderRecentDeleteButton, position: 100 }],
}),
javascript({ jsx: false, typescript: false }),
EditorView.lineWrapping,

View File

@@ -1,14 +1,3 @@
export const RECENTS_SECTION = { name: 'Recent searches', rank: 1 } as const;
export const SUGGESTIONS_SECTION = { name: 'Suggestions', rank: 2 } as const;
// Custom CodeMirror Completion.type for recent-query entries. Used to discriminate
// recents from regular autocomplete completions in renderers and event handlers.
export const RECENT_COMPLETION_TYPE = 'recent';
// Max number of recents rendered in the autocomplete dropdown.
// Do change $max-recents-shown: in QuerySearch.styles.scss if you change this.
export const RECENTS_DISPLAY_CAP = 5;
export const queryExamples = [
{
label: 'Basic Query',

View File

@@ -1,19 +1,3 @@
import { closeCompletion, startCompletion } from '@codemirror/autocomplete';
import type { Completion } from '@codemirror/autocomplete';
import type { EditorView } from '@uiw/react-codemirror';
import dayjs from 'dayjs';
import { normalizeFilterExpression } from 'lib/recentQueries/normalize';
import * as recentQueriesStore from 'lib/recentQueries/recentQueriesStore';
import type { RecentQueryEntry } from 'lib/recentQueries/types';
import type { SignalType } from 'types/api/v5/queryRange';
import 'utils/timeUtils';
import {
RECENT_COMPLETION_TYPE,
RECENTS_DISPLAY_CAP,
RECENTS_SECTION,
} from './constants';
export function combineInitialAndUserExpression(
initial: string,
user: string,
@@ -54,106 +38,3 @@ export function getUserExpressionFromCombined(
}
return c;
}
// Filters and projects a list of recent-query entries into CodeMirror completions.
// Entries are supplied by the caller (typically via the useRecents hook) so this
// function stays pure and React doesn't have to re-subscribe inside CodeMirror's
// autocomplete callback.
export function getRecentOptions(
entries: RecentQueryEntry[],
fullDoc: string,
): Completion[] {
const normalizedDoc = normalizeFilterExpression(fullDoc);
const matches = entries
.filter((e) => {
const normalizedRecent = normalizeFilterExpression(e.filter.expression);
if (normalizedRecent === normalizedDoc) {
return false;
}
if (normalizedDoc === '') {
return true;
}
return normalizedRecent.includes(normalizedDoc);
})
.slice(0, RECENTS_DISPLAY_CAP);
return matches.map((entry, index) => ({
label: entry.filter.expression,
type: RECENT_COMPLETION_TYPE,
// CodeMirror sorts within a section by boost desc, then label asc. The store
// returns entries newest-first, so we mirror that by giving the newest entry
// the highest boost — otherwise CM falls back to alphabetical order and the
// "most recently used" expectation breaks. Stays within the recents section
// because section.rank keeps recents above suggestions regardless of boost.
boost: matches.length - index,
section: RECENTS_SECTION,
detail: dayjs(entry.lastUsedAt).fromNow(),
recentId: entry.id,
recentSignal: entry.signal,
recentSource: entry.source,
apply: (view: EditorView): void => {
view.dispatch({
changes: {
from: 0,
to: view.state.doc.length,
insert: entry.filter.expression,
},
selection: { anchor: entry.filter.expression.length },
});
closeCompletion(view);
},
}));
}
export function renderRecentDeleteButton(
completion: Completion,
_state: unknown,
view: EditorView | null,
): Node | null {
if (completion.type !== RECENT_COMPLETION_TYPE) {
return null;
}
const c = completion as Completion & {
recentId?: string;
recentSignal?: SignalType;
recentSource?: string;
};
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'cm-recent-delete';
btn.setAttribute('aria-label', 'Remove from recent searches');
btn.title = 'Remove from recent searches';
btn.textContent = '×';
queueMicrotask(() => {
if (btn.parentElement) {
btn.parentElement.title = completion.label;
}
});
const stop = (e: Event): void => {
e.preventDefault();
e.stopPropagation();
};
// CodeMirror's autocomplete closes the popup on pointerdown / mousedown outside
// the editor. The delete button lives inside the popup, so we must stop those
// events early — otherwise clicking × would dismiss the dropdown before the
// click handler fires and the entry wouldn't actually get removed.
btn.addEventListener('pointerdown', stop);
btn.addEventListener('mousedown', stop);
btn.addEventListener('click', (e) => {
stop(e);
if (!c.recentId || !c.recentSignal) {
return;
}
recentQueriesStore.remove(c.recentId, c.recentSignal, c.recentSource ?? '');
if (view) {
view.focus();
startCompletion(view);
}
});
return btn;
}

View File

@@ -1,29 +1,67 @@
/* eslint-disable sonarjs/no-identical-functions */
import { Fragment, useMemo, useState } from 'react';
import { Input } from '@signozhq/ui/input';
import { Skeleton } from 'antd';
import { Button, Skeleton } from 'antd';
import { Checkbox } from '@signozhq/ui/checkbox';
import { Typography } from '@signozhq/ui/typography';
import cx from 'classnames';
import { removeKeysFromExpression } from 'components/QueryBuilderV2/utils';
import {
IQuickFiltersConfig,
QuickFiltersSource,
} from 'components/QuickFilters/types';
import { OPERATORS } from 'constants/antlrQueryConstants';
import {
DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY,
PANEL_TYPES,
} from 'constants/queryBuilder';
import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig';
import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
import { useGetAggregateValues } from 'hooks/queryBuilder/useGetAggregateValues';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useGetQueryKeyValueSuggestions } from 'hooks/querySuggestions/useGetQueryKeyValueSuggestions';
import useDebouncedFn from 'hooks/useDebouncedFunction';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import { cloneDeep, isArray, isFunction } from 'lodash-es';
import { ChevronDown, ChevronRight } from '@signozhq/icons';
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder';
import { v4 as uuid } from 'uuid';
import CheckboxFilterHeader from './CheckboxFilterHeader';
import CheckboxValueRow from './CheckboxValueRow';
import LogsQuickFilterEmptyState from './LogsQuickFilterEmptyState';
import useActiveQueryIndex from './useActiveQueryIndex';
import useCheckboxDisclosure from './useCheckboxDisclosure';
import useCheckboxFilterActions from './useCheckboxFilterActions';
import useCheckboxFilterState from './useCheckboxFilterState';
import useCheckboxFilterValues from './useCheckboxFilterValues';
import { isKeyMatch } from './utils';
import './Checkbox.styles.scss';
const SELECTED_OPERATORS = [OPERATORS['='], 'in'];
const NON_SELECTED_OPERATORS = [OPERATORS['!='], 'not in', 'nin'];
const SOURCES_WITH_EMPTY_STATE_ENABLED = [QuickFiltersSource.LOGS_EXPLORER];
// Sources that use backend APIs expecting short operator format (e.g., 'nin' instead of 'not in')
const SOURCES_WITH_SHORT_OPERATORS = [QuickFiltersSource.INFRA_MONITORING];
/**
* Returns the correct NOT_IN operator value based on source.
* InfraMonitoring backend expects 'nin', others expect 'not in'.
*/
function getNotInOperator(source: QuickFiltersSource): string {
if (SOURCES_WITH_SHORT_OPERATORS.includes(source)) {
return 'nin';
}
return getOperatorValue('NOT_IN');
}
function setDefaultValues(
values: string[],
trueOrFalse: boolean,
): Record<string, boolean> {
const defaultState: Record<string, boolean> = {};
values.forEach((val) => {
defaultState[val] = trueOrFalse;
});
return defaultState;
}
interface ICheckboxProps {
filter: IQuickFiltersConfig;
source: QuickFiltersSource;
@@ -34,39 +72,194 @@ interface ICheckboxProps {
export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
const { source, filter, onFilterChange } = props;
const [searchText, setSearchText] = useState<string>('');
const activeQueryIndex = useActiveQueryIndex(source);
// null = no user action, true = user opened, false = user closed
const [userToggleState, setUserToggleState] = useState<boolean | null>(null);
const [visibleItemsCount, setVisibleItemsCount] = useState<number>(10);
const {
isOpen,
lastUsedQuery,
currentQuery,
redirectWithQueryBuilderData,
panelType,
} = useQueryBuilder();
// Determine if we're in ListView mode
const isListView = panelType === PANEL_TYPES.LIST;
// In ListView mode, use index 0 for most sources; for TRACES_EXPLORER, use lastUsedQuery
// Otherwise use lastUsedQuery for non-ListView modes
const activeQueryIndex = useMemo(() => {
if (isListView) {
return source === QuickFiltersSource.TRACES_EXPLORER
? lastUsedQuery || 0
: 0;
}
return lastUsedQuery || 0;
}, [isListView, source, lastUsedQuery]);
// Check if this filter has active filters in the query
const isSomeFilterPresentForCurrentAttribute = useMemo(
() =>
currentQuery.builder.queryData?.[activeQueryIndex]?.filters?.items?.some(
(item) => isKeyMatch(item.key?.key, filter.attributeKey.key),
),
[currentQuery.builder.queryData, activeQueryIndex, filter.attributeKey.key],
);
// Derive isOpen from filter state + user action
const isOpen = useMemo(() => {
// If user explicitly toggled, respect that
if (userToggleState !== null) {
return userToggleState;
}
// Auto-open if this filter has active filters in the query
if (isSomeFilterPresentForCurrentAttribute) {
return true;
}
// Otherwise use default behavior (first 2 filters open)
return filter.defaultOpen;
}, [
userToggleState,
isSomeFilterPresentForCurrentAttribute,
visibleItemsCount,
onToggleOpen,
onShowMore,
} = useCheckboxDisclosure({ filter, activeQueryIndex });
filter.defaultOpen,
]);
const { attributeValues, isLoading } = useCheckboxFilterValues({
filter,
source,
searchText,
isOpen,
});
const { data, isLoading } = useGetAggregateValues(
{
aggregateOperator: filter.aggregateOperator || 'noop',
dataSource: filter.dataSource || DataSource.LOGS,
aggregateAttribute: filter.aggregateAttribute || '',
attributeKey: filter.attributeKey.key,
filterAttributeKeyDataType: filter.attributeKey.dataType || DataTypes.EMPTY,
tagType: filter.attributeKey.type || '',
searchText: searchText ?? '',
},
{
enabled: isOpen && source !== QuickFiltersSource.METER_EXPLORER,
keepPreviousData: true,
},
);
const { currentFilterState, isFilterDisabled, isMultipleValuesTrueForTheKey } =
useCheckboxFilterState({ filter, attributeValues, activeQueryIndex });
const { data: keyValueSuggestions, isLoading: isLoadingKeyValueSuggestions } =
useGetQueryKeyValueSuggestions({
key: filter.attributeKey.key,
signal: filter.dataSource || DataSource.LOGS,
signalSource: 'meter',
options: {
enabled: isOpen && source === QuickFiltersSource.METER_EXPLORER,
keepPreviousData: true,
},
});
const { onChange, onClear } = useCheckboxFilterActions({
filter,
source,
attributeValues,
activeQueryIndex,
onFilterChange,
});
const attributeValues: string[] = useMemo(() => {
const dataType = filter.attributeKey.dataType || DataTypes.String;
if (source === QuickFiltersSource.METER_EXPLORER && keyValueSuggestions) {
// Process the response data
const responseData = keyValueSuggestions?.data as any;
const values = responseData.data?.values || {};
const stringValues = values.stringValues || [];
const numberValues = values.numberValues || [];
// Generate options from string values - explicitly handle empty strings
const stringOptions = stringValues
// Strict filtering for empty string - we'll handle it as a special case if needed
.filter(
(value: string | null | undefined): value is string =>
value !== null && value !== undefined && value !== '',
);
// Generate options from number values
const numberOptions = numberValues
.filter(
(value: number | null | undefined): value is number =>
value !== null && value !== undefined,
)
.map((value: number) => value.toString());
// Combine all options and make sure we don't have duplicate labels
return [...stringOptions, ...numberOptions];
}
const key = DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY[dataType];
return (data?.payload?.[key] || []).filter(
(val) => val !== undefined && val !== null,
);
}, [data?.payload, filter.attributeKey.dataType, keyValueSuggestions, source]);
const setSearchTextDebounced = useDebouncedFn((...args) => {
setSearchText(args[0] as string);
}, DEBOUNCE_DELAY);
// derive the state of each filter key here in the renderer itself and keep it in sync with current query
// also we need to keep a note of last focussed query.
// eslint-disable-next-line sonarjs/cognitive-complexity
const currentFilterState = useMemo(() => {
let filterState: Record<string, boolean> = setDefaultValues(
attributeValues,
false,
);
const filterSync = currentQuery?.builder.queryData?.[
activeQueryIndex
]?.filters?.items.find((item) =>
isKeyMatch(item.key?.key, filter.attributeKey.key),
);
if (filterSync) {
if (SELECTED_OPERATORS.includes(filterSync.op)) {
if (isArray(filterSync.value)) {
filterSync.value.forEach((val) => {
filterState[String(val)] = true;
});
} else if (typeof filterSync.value === 'string') {
filterState[filterSync.value] = true;
} else if (typeof filterSync.value === 'boolean') {
filterState[String(filterSync.value)] = true;
} else if (typeof filterSync.value === 'number') {
filterState[String(filterSync.value)] = true;
}
} else if (NON_SELECTED_OPERATORS.includes(filterSync.op)) {
filterState = setDefaultValues(attributeValues, true);
if (isArray(filterSync.value)) {
filterSync.value.forEach((val) => {
filterState[String(val)] = false;
});
} else if (typeof filterSync.value === 'string') {
filterState[filterSync.value] = false;
} else if (typeof filterSync.value === 'boolean') {
filterState[String(filterSync.value)] = false;
} else if (typeof filterSync.value === 'number') {
filterState[String(filterSync.value)] = false;
}
}
} else {
filterState = setDefaultValues(attributeValues, true);
}
return filterState;
}, [
attributeValues,
currentQuery?.builder.queryData,
filter.attributeKey,
activeQueryIndex,
]);
// disable the filter when there are multiple entries of the same attribute key present in the filter bar
const isFilterDisabled = useMemo(
() =>
(currentQuery?.builder?.queryData?.[
activeQueryIndex
]?.filters?.items?.filter((item) =>
isKeyMatch(item.key?.key, filter.attributeKey.key),
)?.length || 0) > 1,
[currentQuery?.builder?.queryData, activeQueryIndex, filter.attributeKey],
);
// variable to check if the current filter has multiple values to its name in the key op value section
const isMultipleValuesTrueForTheKey =
Object.values(currentFilterState).filter((val) => val).length > 1;
// Sort checked items to the top, then unchecked items
const currentAttributeKeys = useMemo(() => {
const checkedValues = attributeValues.filter(
@@ -84,6 +277,293 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
[currentAttributeKeys, currentFilterState],
);
const handleClearFilterAttribute = (): void => {
const preparedQuery: Query = {
...currentQuery,
builder: {
...currentQuery.builder,
queryData: currentQuery.builder.queryData.map((item, idx) => ({
...item,
filter: {
expression: removeKeysFromExpression(item.filter?.expression ?? '', [
filter.attributeKey.key,
]),
},
filters: {
...item.filters,
items:
idx === activeQueryIndex
? item.filters?.items?.filter(
(fil) => !isKeyMatch(fil.key?.key, filter.attributeKey.key),
) || []
: [...(item.filters?.items || [])],
op: item.filters?.op || 'AND',
},
})),
},
};
if (onFilterChange && isFunction(onFilterChange)) {
onFilterChange(preparedQuery);
} else {
redirectWithQueryBuilderData(preparedQuery);
}
};
const onChange = (
value: string,
checked: boolean,
isOnlyOrAllClicked: boolean,
// eslint-disable-next-line sonarjs/cognitive-complexity
): void => {
const query = cloneDeep(currentQuery.builder.queryData?.[activeQueryIndex]);
// if only or all are clicked we do not need to worry about anything just override whatever we have
// by either adding a new IN operator value clause in case of ONLY or remove everything we have for ALL.
if (isOnlyOrAllClicked && query?.filters?.items) {
const isOnlyOrAll = isSomeFilterPresentForCurrentAttribute
? currentFilterState[value] && !isMultipleValuesTrueForTheKey
? 'All'
: 'Only'
: 'Only';
query.filters.items = query.filters.items.filter(
(q) => !isKeyMatch(q.key?.key, filter.attributeKey.key),
);
if (query.filter?.expression) {
query.filter.expression = removeKeysFromExpression(
query.filter.expression,
[filter.attributeKey.key],
);
}
if (isOnlyOrAll === 'Only') {
const newFilterItem: TagFilterItem = {
id: uuid(),
op: getOperatorValue(OPERATORS.IN),
key: filter.attributeKey,
value,
};
query.filters.items = [...query.filters.items, newFilterItem];
}
} else if (query?.filters?.items) {
if (
query.filters?.items?.some((item) =>
isKeyMatch(item.key?.key, filter.attributeKey.key),
)
) {
// if there is already a running filter for the current attribute key then
// we split the cases by which particular operator is present right now!
const currentFilter = query.filters?.items?.find((q) =>
isKeyMatch(q.key?.key, filter.attributeKey.key),
);
if (currentFilter) {
const runningOperator = currentFilter?.op;
switch (runningOperator) {
case 'in':
if (checked) {
// if it's an IN operator then if we are checking another value it get's added to the
// filter clause. example - key IN [value1, currentSelectedValue]
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: [...currentFilter.value, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else {
// if the current state wasn't an array we make it one and add our value
const newFilter = {
...currentFilter,
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else if (!checked) {
// if we are removing some value when the running operator is IN we filter.
// example - key IN [value1,currentSelectedValue] becomes key IN [value1] in case of array
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: currentFilter.value.filter((val) => val !== value),
};
if (newFilter.value.length === 0) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
} else {
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else {
// if not an array remove the whole thing altogether!
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
}
break;
case 'nin':
case 'not in':
// if the current running operator is NIN then when unchecking the value it gets
// added to the clause like key NIN [value1 , currentUnselectedValue]
if (!checked) {
// in case of array add the currentUnselectedValue to the list.
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: [...currentFilter.value, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else {
// in case of not an array make it one!
const newFilter = {
...currentFilter,
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else if (checked) {
// opposite of above!
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: currentFilter.value.filter((val) => val !== value),
};
if (newFilter.value.length === 0) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
if (query.filter?.expression) {
query.filter.expression = removeKeysFromExpression(
query.filter.expression,
[filter.attributeKey.key],
);
}
} else {
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else {
const newFilter = {
...currentFilter,
value: currentFilter.value === value ? null : currentFilter.value,
};
if (newFilter.value === null && query.filter?.expression) {
query.filter.expression = removeKeysFromExpression(
query.filter.expression,
[filter.attributeKey.key],
);
}
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
}
break;
case '=':
if (checked) {
const newFilter = {
...currentFilter,
op: getOperatorValue(OPERATORS.IN),
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else if (!checked) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
break;
case '!=':
if (!checked) {
const newFilter = {
...currentFilter,
op: getNotInOperator(source),
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else if (checked) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
break;
default:
break;
}
}
} else {
// case - when there is no filter for the current key that means all are selected right now.
const newFilterItem: TagFilterItem = {
id: uuid(),
op: getNotInOperator(source),
key: filter.attributeKey,
value,
};
query.filters.items = [...query.filters.items, newFilterItem];
}
}
const finalQuery = {
...currentQuery,
builder: {
...currentQuery.builder,
queryData: [
...currentQuery.builder.queryData.map((q, idx) => {
if (idx === activeQueryIndex) {
return query;
}
return q;
}),
],
},
};
if (onFilterChange && isFunction(onFilterChange)) {
onFilterChange(finalQuery);
} else {
redirectWithQueryBuilderData(finalQuery);
}
};
const isEmptyStateWithDocsEnabled =
SOURCES_WITH_EMPTY_STATE_ENABLED.includes(source) &&
!searchText &&
@@ -91,19 +571,48 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
return (
<div className="checkbox-filter">
<CheckboxFilterHeader
title={filter.title}
isOpen={isOpen}
showClearAll={!!attributeValues.length}
onToggleOpen={onToggleOpen}
onClear={onClear}
/>
{isOpen && isLoading && !attributeValues.length && (
<section className="loading">
<Skeleton paragraph={{ rows: 4 }} />
<section
className="filter-header-checkbox"
onClick={(): void => {
if (isOpen) {
setUserToggleState(false);
setVisibleItemsCount(10);
} else {
setUserToggleState(true);
}
}}
>
<section className="left-action">
{isOpen ? (
<ChevronDown size={13} cursor="pointer" />
) : (
<ChevronRight size={13} cursor="pointer" />
)}
<Typography.Text className="title">{filter.title}</Typography.Text>
</section>
)}
{isOpen && !isLoading && (
<section className="right-action">
{isOpen && !!attributeValues.length && (
<Typography.Text
className="clear-all"
onClick={(e): void => {
e.stopPropagation();
e.preventDefault();
handleClearFilterAttribute();
}}
>
Clear All
</Typography.Text>
)}
</section>
</section>
{isOpen &&
(isLoading || isLoadingKeyValueSuggestions) &&
!attributeValues.length && (
<section className="loading">
<Skeleton paragraph={{ rows: 4 }} />
</section>
)}
{isOpen && !isLoading && !isLoadingKeyValueSuggestions && (
<>
{!isEmptyStateWithDocsEnabled && (
<section className="search">
@@ -125,24 +634,48 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
data-testid="filter-separator"
/>
)}
<CheckboxValueRow
value={value}
checked={currentFilterState[value]}
disabled={isFilterDisabled}
title={filter.title}
onlyButtonLabel={
isSomeFilterPresentForCurrentAttribute
? currentFilterState[value] && !isMultipleValuesTrueForTheKey
? 'All'
: 'Only'
: 'Only'
}
customRendererForValue={filter.customRendererForValue}
onCheckboxChange={(checked): void => onChange(value, checked, false)}
onOnlyOrAllClick={(): void =>
onChange(value, currentFilterState[value], true)
}
/>
<div className="value">
<Checkbox
onChange={(checked): void =>
onChange(value, checked === true, false)
}
value={currentFilterState[value]}
disabled={isFilterDisabled}
className="check-box"
/>
<div
className={cx(
'checkbox-value-section',
isFilterDisabled ? 'filter-disabled' : '',
)}
onClick={(): void => {
if (isFilterDisabled) {
return;
}
onChange(value, currentFilterState[value], true);
}}
>
<div className={`${filter.title} label-${value}`} />
{filter.customRendererForValue ? (
filter.customRendererForValue(value)
) : (
<Typography.Text className="value-string" truncate={1}>
{String(value)}
</Typography.Text>
)}
<Button type="text" className="only-btn">
{isSomeFilterPresentForCurrentAttribute
? currentFilterState[value] && !isMultipleValuesTrueForTheKey
? 'All'
: 'Only'
: 'Only'}
</Button>
<Button type="text" className="toggle-btn">
Toggle
</Button>
</div>
</div>
</Fragment>
))}
</section>
@@ -155,7 +688,10 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
)}
{visibleItemsCount < attributeValues?.length && (
<section className="show-more">
<Typography.Text className="show-more-text" onClick={onShowMore}>
<Typography.Text
className="show-more-text"
onClick={(): void => setVisibleItemsCount((prev) => prev + 10)}
>
Show More...
</Typography.Text>
</section>

View File

@@ -1,47 +0,0 @@
import { Typography } from '@signozhq/ui/typography';
import { ChevronDown, ChevronRight } from '@signozhq/icons';
interface CheckboxFilterHeaderProps {
title: string;
isOpen: boolean;
showClearAll: boolean;
onToggleOpen: () => void;
onClear: () => void;
}
function CheckboxFilterHeader({
title,
isOpen,
showClearAll,
onToggleOpen,
onClear,
}: CheckboxFilterHeaderProps): JSX.Element {
return (
<section className="filter-header-checkbox" onClick={onToggleOpen}>
<section className="left-action">
{isOpen ? (
<ChevronDown size={13} cursor="pointer" />
) : (
<ChevronRight size={13} cursor="pointer" />
)}
<Typography.Text className="title">{title}</Typography.Text>
</section>
<section className="right-action">
{isOpen && showClearAll && (
<Typography.Text
className="clear-all"
onClick={(e): void => {
e.stopPropagation();
e.preventDefault();
onClear();
}}
>
Clear All
</Typography.Text>
)}
</section>
</section>
);
}
export default CheckboxFilterHeader;

View File

@@ -1,68 +0,0 @@
import { Button } from 'antd';
import { Checkbox } from '@signozhq/ui/checkbox';
import { Typography } from '@signozhq/ui/typography';
import cx from 'classnames';
interface CheckboxValueRowProps {
value: string;
checked: boolean;
disabled: boolean;
title: string;
onlyButtonLabel: string;
customRendererForValue?: (value: string) => JSX.Element;
onCheckboxChange: (checked: boolean) => void;
onOnlyOrAllClick: () => void;
}
function CheckboxValueRow({
value,
checked,
disabled,
title,
onlyButtonLabel,
customRendererForValue,
onCheckboxChange,
onOnlyOrAllClick,
}: CheckboxValueRowProps): JSX.Element {
return (
<div className="value">
<Checkbox
onChange={(isChecked): void => onCheckboxChange(isChecked === true)}
value={checked}
disabled={disabled}
className="check-box"
/>
<div
className={cx('checkbox-value-section', disabled ? 'filter-disabled' : '')}
onClick={(): void => {
if (disabled) {
return;
}
onOnlyOrAllClick();
}}
>
<div className={`${title} label-${value}`} />
{customRendererForValue ? (
customRendererForValue(value)
) : (
<Typography.Text className="value-string" truncate={1}>
{String(value)}
</Typography.Text>
)}
<Button type="text" className="only-btn">
{onlyButtonLabel}
</Button>
<Button type="text" className="toggle-btn">
Toggle
</Button>
</div>
</div>
);
}
CheckboxValueRow.defaultProps = {
customRendererForValue: undefined,
};
export default CheckboxValueRow;

View File

@@ -1,417 +0,0 @@
/* eslint-disable sonarjs/no-identical-functions */
import { removeKeysFromExpression } from 'components/QueryBuilderV2/utils';
import {
IQuickFiltersConfig,
QuickFiltersSource,
} from 'components/QuickFilters/types';
import { OPERATORS } from 'constants/antlrQueryConstants';
import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
import { cloneDeep, isArray } from 'lodash-es';
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
import { v4 as uuid } from 'uuid';
import { isKeyMatch } from './utils';
export const SELECTED_OPERATORS = [OPERATORS['='], 'in'];
export const NON_SELECTED_OPERATORS = [OPERATORS['!='], 'not in', 'nin'];
// Sources that use backend APIs expecting short operator format (e.g., 'nin' instead of 'not in')
const SOURCES_WITH_SHORT_OPERATORS = [QuickFiltersSource.INFRA_MONITORING];
/**
* Returns the correct NOT_IN operator value based on source.
* InfraMonitoring backend expects 'nin', others expect 'not in'.
*/
export function getNotInOperator(source: QuickFiltersSource): string {
if (SOURCES_WITH_SHORT_OPERATORS.includes(source)) {
return 'nin';
}
return getOperatorValue('NOT_IN');
}
function setDefaultValues(
values: string[],
trueOrFalse: boolean,
): Record<string, boolean> {
const defaultState: Record<string, boolean> = {};
values.forEach((val) => {
defaultState[val] = trueOrFalse;
});
return defaultState;
}
/**
* Derives the checked/unchecked state for each attribute value by reading the
* active filter clause for this attribute key out of the query.
*
* - No matching clause -> every value is checked (all selected).
* - IN / `=` clause -> only the listed values are checked.
* - NOT IN / `!=` clause -> every value is checked except the excluded ones.
*/
// eslint-disable-next-line sonarjs/cognitive-complexity
export function deriveCheckboxState({
attributeValues,
filterItems,
filterKey,
}: {
attributeValues: string[];
filterItems: TagFilterItem[] | undefined;
filterKey: string;
}): Record<string, boolean> {
let filterState: Record<string, boolean> = setDefaultValues(
attributeValues,
false,
);
const filterSync = filterItems?.find((item) =>
isKeyMatch(item.key?.key, filterKey),
);
if (filterSync) {
if (SELECTED_OPERATORS.includes(filterSync.op)) {
if (isArray(filterSync.value)) {
filterSync.value.forEach((val) => {
filterState[String(val)] = true;
});
} else if (typeof filterSync.value === 'string') {
filterState[filterSync.value] = true;
} else if (typeof filterSync.value === 'boolean') {
filterState[String(filterSync.value)] = true;
} else if (typeof filterSync.value === 'number') {
filterState[String(filterSync.value)] = true;
}
} else if (NON_SELECTED_OPERATORS.includes(filterSync.op)) {
filterState = setDefaultValues(attributeValues, true);
if (isArray(filterSync.value)) {
filterSync.value.forEach((val) => {
filterState[String(val)] = false;
});
} else if (typeof filterSync.value === 'string') {
filterState[filterSync.value] = false;
} else if (typeof filterSync.value === 'boolean') {
filterState[String(filterSync.value)] = false;
} else if (typeof filterSync.value === 'number') {
filterState[String(filterSync.value)] = false;
}
}
} else {
filterState = setDefaultValues(attributeValues, true);
}
return filterState;
}
/**
* Returns a new query with every clause for this attribute key removed, both
* from the structured filter items and the raw filter expression.
*/
export function clearFilterFromQuery({
currentQuery,
filter,
activeQueryIndex,
}: {
currentQuery: Query;
filter: IQuickFiltersConfig;
activeQueryIndex: number;
}): Query {
return {
...currentQuery,
builder: {
...currentQuery.builder,
queryData: currentQuery.builder.queryData.map((item, idx) => ({
...item,
filter: {
expression: removeKeysFromExpression(item.filter?.expression ?? '', [
filter.attributeKey.key,
]),
},
filters: {
...item.filters,
items:
idx === activeQueryIndex
? item.filters?.items?.filter(
(fil) => !isKeyMatch(fil.key?.key, filter.attributeKey.key),
) || []
: [...(item.filters?.items || [])],
op: item.filters?.op || 'AND',
},
})),
},
};
}
// eslint-disable-next-line sonarjs/cognitive-complexity
export function applyCheckboxToggle({
currentQuery,
activeQueryIndex,
filter,
source,
attributeValues,
value,
checked,
isOnlyOrAllClicked,
}: {
currentQuery: Query;
activeQueryIndex: number;
filter: IQuickFiltersConfig;
source: QuickFiltersSource;
attributeValues: string[];
value: string;
checked: boolean;
isOnlyOrAllClicked: boolean;
}): Query {
const activeItems =
currentQuery.builder.queryData?.[activeQueryIndex]?.filters?.items;
const isSomeFilterPresentForCurrentAttribute = !!activeItems?.some((item) =>
isKeyMatch(item.key?.key, filter.attributeKey.key),
);
const currentFilterState = deriveCheckboxState({
attributeValues,
filterItems: activeItems,
filterKey: filter.attributeKey.key,
});
const isMultipleValuesTrueForTheKey =
Object.values(currentFilterState).filter((val) => val).length > 1;
const query = cloneDeep(currentQuery.builder.queryData?.[activeQueryIndex]);
// if only or all are clicked we do not need to worry about anything just override whatever we have
// by either adding a new IN operator value clause in case of ONLY or remove everything we have for ALL.
if (isOnlyOrAllClicked && query?.filters?.items) {
const isOnlyOrAll = isSomeFilterPresentForCurrentAttribute
? currentFilterState[value] && !isMultipleValuesTrueForTheKey
? 'All'
: 'Only'
: 'Only';
query.filters.items = query.filters.items.filter(
(q) => !isKeyMatch(q.key?.key, filter.attributeKey.key),
);
if (query.filter?.expression) {
query.filter.expression = removeKeysFromExpression(query.filter.expression, [
filter.attributeKey.key,
]);
}
if (isOnlyOrAll === 'Only') {
const newFilterItem: TagFilterItem = {
id: uuid(),
op: getOperatorValue(OPERATORS.IN),
key: filter.attributeKey,
value,
};
query.filters.items = [...query.filters.items, newFilterItem];
}
} else if (query?.filters?.items) {
if (
query.filters?.items?.some((item) =>
isKeyMatch(item.key?.key, filter.attributeKey.key),
)
) {
// if there is already a running filter for the current attribute key then
// we split the cases by which particular operator is present right now!
const currentFilter = query.filters?.items?.find((q) =>
isKeyMatch(q.key?.key, filter.attributeKey.key),
);
if (currentFilter) {
const runningOperator = currentFilter?.op;
switch (runningOperator) {
case 'in':
if (checked) {
// if it's an IN operator then if we are checking another value it get's added to the
// filter clause. example - key IN [value1, currentSelectedValue]
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: [...currentFilter.value, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else {
// if the current state wasn't an array we make it one and add our value
const newFilter = {
...currentFilter,
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else if (!checked) {
// if we are removing some value when the running operator is IN we filter.
// example - key IN [value1,currentSelectedValue] becomes key IN [value1] in case of array
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: currentFilter.value.filter((val) => val !== value),
};
if (newFilter.value.length === 0) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
} else {
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else {
// if not an array remove the whole thing altogether!
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
}
break;
case 'nin':
case 'not in':
// if the current running operator is NIN then when unchecking the value it gets
// added to the clause like key NIN [value1 , currentUnselectedValue]
if (!checked) {
// in case of array add the currentUnselectedValue to the list.
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: [...currentFilter.value, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else {
// in case of not an array make it one!
const newFilter = {
...currentFilter,
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else if (checked) {
// opposite of above!
if (isArray(currentFilter.value)) {
const newFilter = {
...currentFilter,
value: currentFilter.value.filter((val) => val !== value),
};
if (newFilter.value.length === 0) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
if (query.filter?.expression) {
query.filter.expression = removeKeysFromExpression(
query.filter.expression,
[filter.attributeKey.key],
);
}
} else {
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
}
} else {
const newFilter = {
...currentFilter,
value: currentFilter.value === value ? null : currentFilter.value,
};
if (newFilter.value === null && query.filter?.expression) {
query.filter.expression = removeKeysFromExpression(
query.filter.expression,
[filter.attributeKey.key],
);
}
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
}
break;
case '=':
if (checked) {
const newFilter = {
...currentFilter,
op: getOperatorValue(OPERATORS.IN),
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else if (!checked) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
break;
case '!=':
if (!checked) {
const newFilter = {
...currentFilter,
op: getNotInOperator(source),
value: [currentFilter.value as string, value],
};
query.filters.items = query.filters.items.map((item) => {
if (isKeyMatch(item.key?.key, filter.attributeKey.key)) {
return newFilter;
}
return item;
});
} else if (checked) {
query.filters.items = query.filters.items.filter(
(item) => !isKeyMatch(item.key?.key, filter.attributeKey.key),
);
}
break;
default:
break;
}
}
} else {
// case - when there is no filter for the current key that means all are selected right now.
const newFilterItem: TagFilterItem = {
id: uuid(),
op: getNotInOperator(source),
key: filter.attributeKey,
value,
};
query.filters.items = [...query.filters.items, newFilterItem];
}
}
return {
...currentQuery,
builder: {
...currentQuery.builder,
queryData: [
...currentQuery.builder.queryData.map((q, idx) => {
if (idx === activeQueryIndex) {
return query;
}
return q;
}),
],
},
};
}

View File

@@ -1,27 +0,0 @@
import { useMemo } from 'react';
import { QuickFiltersSource } from 'components/QuickFilters/types';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
/**
* Resolves which query-builder query index the checkbox filter reads from and
* writes to.
*
* In ListView most sources use index 0; TRACES_EXPLORER and every non-ListView
* mode track the last focused query.
*/
function useActiveQueryIndex(source: QuickFiltersSource): number {
const { lastUsedQuery, panelType } = useQueryBuilder();
const isListView = panelType === PANEL_TYPES.LIST;
return useMemo(() => {
if (isListView) {
return source === QuickFiltersSource.TRACES_EXPLORER
? lastUsedQuery || 0
: 0;
}
return lastUsedQuery || 0;
}, [isListView, source, lastUsedQuery]);
}
export default useActiveQueryIndex;

View File

@@ -1,90 +0,0 @@
import { useMemo, useState } from 'react';
import { IQuickFiltersConfig } from 'components/QuickFilters/types';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { isKeyMatch } from './utils';
const DEFAULT_VISIBLE_ITEMS_COUNT = 10;
interface UseCheckboxDisclosureProps {
filter: IQuickFiltersConfig;
activeQueryIndex: number;
}
interface UseCheckboxDisclosureReturn {
isOpen: boolean;
isSomeFilterPresentForCurrentAttribute: boolean;
visibleItemsCount: number;
onToggleOpen: () => void;
onShowMore: () => void;
}
/**
* Owns the open/collapsed state of a checkbox filter section and how many
* values are visible.
*
* Auto-opens when the query already has a clause for this attribute, otherwise
* falls back to `filter.defaultOpen`. An explicit user toggle always wins.
* Collapsing resets the visible count.
*/
function useCheckboxDisclosure({
filter,
activeQueryIndex,
}: UseCheckboxDisclosureProps): UseCheckboxDisclosureReturn {
const { currentQuery } = useQueryBuilder();
// null = no user action, true = user opened, false = user closed
const [userToggleState, setUserToggleState] = useState<boolean | null>(null);
const [visibleItemsCount, setVisibleItemsCount] = useState<number>(
DEFAULT_VISIBLE_ITEMS_COUNT,
);
const isSomeFilterPresentForCurrentAttribute = useMemo(
() =>
!!currentQuery.builder.queryData?.[activeQueryIndex]?.filters?.items?.some(
(item) => isKeyMatch(item.key?.key, filter.attributeKey.key),
),
[currentQuery.builder.queryData, activeQueryIndex, filter.attributeKey.key],
);
const isOpen = useMemo(() => {
// If user explicitly toggled, respect that
if (userToggleState !== null) {
return userToggleState;
}
// Auto-open if this filter has active filters in the query
if (isSomeFilterPresentForCurrentAttribute) {
return true;
}
// Otherwise use default behavior (first 2 filters open)
return filter.defaultOpen;
}, [
userToggleState,
isSomeFilterPresentForCurrentAttribute,
filter.defaultOpen,
]);
const onToggleOpen = (): void => {
if (isOpen) {
setUserToggleState(false);
setVisibleItemsCount(DEFAULT_VISIBLE_ITEMS_COUNT);
} else {
setUserToggleState(true);
}
};
const onShowMore = (): void => {
setVisibleItemsCount((prev) => prev + DEFAULT_VISIBLE_ITEMS_COUNT);
};
return {
isOpen,
isSomeFilterPresentForCurrentAttribute,
visibleItemsCount,
onToggleOpen,
onShowMore,
};
}
export default useCheckboxDisclosure;

View File

@@ -1,78 +0,0 @@
import {
IQuickFiltersConfig,
QuickFiltersSource,
} from 'components/QuickFilters/types';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { isFunction } from 'lodash-es';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import {
applyCheckboxToggle,
clearFilterFromQuery,
} from './checkboxFilterQuery';
interface UseCheckboxFilterActionsProps {
filter: IQuickFiltersConfig;
source: QuickFiltersSource;
attributeValues: string[];
activeQueryIndex: number;
onFilterChange?: ((query: Query) => void) | null;
}
interface UseCheckboxFilterActionsReturn {
onChange: (
value: string,
checked: boolean,
isOnlyOrAllClicked: boolean,
) => void;
onClear: () => void;
}
/**
* Wires the pure checkbox query algebra to query-builder dispatch: the
* caller-provided `onFilterChange` when present, otherwise a URL redirect.
*/
function useCheckboxFilterActions({
filter,
source,
attributeValues,
activeQueryIndex,
onFilterChange,
}: UseCheckboxFilterActionsProps): UseCheckboxFilterActionsReturn {
const { currentQuery, redirectWithQueryBuilderData } = useQueryBuilder();
const dispatch = (query: Query): void => {
if (onFilterChange && isFunction(onFilterChange)) {
onFilterChange(query);
} else {
redirectWithQueryBuilderData(query);
}
};
const onChange = (
value: string,
checked: boolean,
isOnlyOrAllClicked: boolean,
): void => {
dispatch(
applyCheckboxToggle({
currentQuery,
activeQueryIndex,
filter,
source,
attributeValues,
value,
checked,
isOnlyOrAllClicked,
}),
);
};
const onClear = (): void => {
dispatch(clearFilterFromQuery({ currentQuery, filter, activeQueryIndex }));
};
return { onChange, onClear };
}
export default useCheckboxFilterActions;

View File

@@ -1,71 +0,0 @@
import { useMemo } from 'react';
import { IQuickFiltersConfig } from 'components/QuickFilters/types';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { deriveCheckboxState } from './checkboxFilterQuery';
import { isKeyMatch } from './utils';
interface UseCheckboxFilterStateProps {
filter: IQuickFiltersConfig;
attributeValues: string[];
activeQueryIndex: number;
}
interface UseCheckboxFilterStateReturn {
currentFilterState: Record<string, boolean>;
isFilterDisabled: boolean;
isMultipleValuesTrueForTheKey: boolean;
}
/**
* Reads the active query and derives the per-value checked state for this
* attribute, whether the filter is disabled (same key used more than once in
* the filter bar), and whether more than one value is currently selected.
*/
function useCheckboxFilterState({
filter,
attributeValues,
activeQueryIndex,
}: UseCheckboxFilterStateProps): UseCheckboxFilterStateReturn {
const { currentQuery } = useQueryBuilder();
// derive the state of each filter key here and keep it in sync with current query
const currentFilterState = useMemo(
() =>
deriveCheckboxState({
attributeValues,
filterItems:
currentQuery?.builder.queryData?.[activeQueryIndex]?.filters?.items,
filterKey: filter.attributeKey.key,
}),
[
attributeValues,
currentQuery?.builder.queryData,
filter.attributeKey,
activeQueryIndex,
],
);
// disable the filter when there are multiple entries of the same attribute key present in the filter bar
const isFilterDisabled = useMemo(
() =>
(currentQuery?.builder?.queryData?.[
activeQueryIndex
]?.filters?.items?.filter((item) =>
isKeyMatch(item.key?.key, filter.attributeKey.key),
)?.length || 0) > 1,
[currentQuery?.builder?.queryData, activeQueryIndex, filter.attributeKey],
);
// whether the current filter has multiple values to its name in the key op value section
const isMultipleValuesTrueForTheKey =
Object.values(currentFilterState).filter((val) => val).length > 1;
return {
currentFilterState,
isFilterDisabled,
isMultipleValuesTrueForTheKey,
};
}
export default useCheckboxFilterState;

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