mirror of
https://github.com/SigNoz/signoz.git
synced 2026-06-16 21:40:34 +01:00
Compare commits
52 Commits
ns/flamegr
...
nv/clone-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fee0c21e9c | ||
|
|
b39073a035 | ||
|
|
2c41ad5a4d | ||
|
|
0aa9045b86 | ||
|
|
ac2b843389 | ||
|
|
5d711377ec | ||
|
|
c5d0fd8966 | ||
|
|
ed04ff09ff | ||
|
|
e1e9d516ac | ||
|
|
58b55c922d | ||
|
|
629ea3b8be | ||
|
|
287b60cbe6 | ||
|
|
e206625e5f | ||
|
|
4f3b7647d3 | ||
|
|
76ab0f25c0 | ||
|
|
59501ce4a7 | ||
|
|
3e51b9556e | ||
|
|
abd4436388 | ||
|
|
30f52ecb6d | ||
|
|
629d24547c | ||
|
|
080aae9567 | ||
|
|
45a9183c82 | ||
|
|
76e7e88641 | ||
|
|
1b7954faaf | ||
|
|
6f79d6b18d | ||
|
|
e57a9556e3 | ||
|
|
bf35748db5 | ||
|
|
2781f73057 | ||
|
|
7eb0095133 | ||
|
|
df26eb1c1d | ||
|
|
36334309bb | ||
|
|
cfcd58b341 | ||
|
|
45fedefbab | ||
|
|
01ae688b58 | ||
|
|
f4e1465c13 | ||
|
|
b22eef6a65 | ||
|
|
4d3d1ef423 | ||
|
|
c775d7e398 | ||
|
|
27603e09d0 | ||
|
|
7b2882abde | ||
|
|
30f1c2d92d | ||
|
|
446dd4589f | ||
|
|
c0c9039428 | ||
|
|
a014e9c0cb | ||
|
|
b898269ddc | ||
|
|
8fdad21a2e | ||
|
|
2e0d25479a | ||
|
|
73c2c15200 | ||
|
|
34203c781f | ||
|
|
1ba9b90855 | ||
|
|
927951b67a | ||
|
|
05ad8d113d |
4
.github/workflows/build-staging.yaml
vendored
4
.github/workflows/build-staging.yaml
vendored
@@ -64,6 +64,10 @@ 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
|
||||
|
||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -19,5 +19,8 @@
|
||||
"editor.defaultFormatter": "vscode.html-language-features"
|
||||
},
|
||||
"python-envs.defaultEnvManager": "ms-python.python:system",
|
||||
"python-envs.pythonProjects": []
|
||||
"python-envs.pythonProjects": [],
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.127.1
|
||||
image: signoz/signoz:v0.128.0
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
# - "6060:6060" # pprof port
|
||||
|
||||
@@ -117,7 +117,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.127.1
|
||||
image: signoz/signoz:v0.128.0
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
volumes:
|
||||
|
||||
@@ -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.127.1}
|
||||
image: signoz/signoz:${VERSION:-v0.128.0}
|
||||
container_name: signoz
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
|
||||
@@ -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.127.1}
|
||||
image: signoz/signoz:${VERSION:-v0.128.0}
|
||||
container_name: signoz
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -109,6 +109,20 @@ 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:
|
||||
@@ -333,6 +347,50 @@ 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?
|
||||
|
||||
@@ -343,3 +401,4 @@ func (Step) JSONSchema() (jsonschema.Schema, error) {
|
||||
- **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.
|
||||
|
||||
@@ -217,6 +217,10 @@ 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)
|
||||
}
|
||||
@@ -229,10 +233,39 @@ 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) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.Dashboard, error) {
|
||||
return module.pkgDashboardModule.Get(ctx, orgID, id)
|
||||
}
|
||||
|
||||
@@ -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 := json.NewDecoder(req.Body).Decode(&queryRangeRequest); err != nil {
|
||||
render.Error(rw, errors.NewInvalidInputf(errors.CodeInvalidInput, "failed to decode request body: %v", err))
|
||||
if err := binding.JSON.BindBody(req.Body, &queryRangeRequest); err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -185,6 +185,7 @@ 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)
|
||||
|
||||
|
||||
@@ -16,10 +16,11 @@ func newFormatter(dialect schema.Dialect) sqlstore.SQLFormatter {
|
||||
}
|
||||
|
||||
func (f *formatter) JSONExtractString(column, path string) []byte {
|
||||
var sql []byte
|
||||
sql = f.bunf.AppendIdent(sql, column)
|
||||
sql = append(sql, f.convertJSONPathToPostgres(path)...)
|
||||
return sql
|
||||
ops := f.convertJSONPathToPostgres(path)
|
||||
if len(ops) == 0 {
|
||||
return f.bunf.AppendIdent(nil, column)
|
||||
}
|
||||
return append(f.TextToJsonColumn(column), ops...)
|
||||
}
|
||||
|
||||
func (f *formatter) JSONType(column, path string) []byte {
|
||||
|
||||
@@ -18,19 +18,19 @@ func TestJSONExtractString(t *testing.T) {
|
||||
name: "simple path",
|
||||
column: "data",
|
||||
path: "$.field",
|
||||
expected: `"data"->>'field'`,
|
||||
expected: `"data"::jsonb->>'field'`,
|
||||
},
|
||||
{
|
||||
name: "nested path",
|
||||
column: "metadata",
|
||||
path: "$.user.name",
|
||||
expected: `"metadata"->'user'->>'name'`,
|
||||
expected: `"metadata"::jsonb->'user'->>'name'`,
|
||||
},
|
||||
{
|
||||
name: "deeply nested path",
|
||||
column: "json_col",
|
||||
path: "$.level1.level2.level3",
|
||||
expected: `"json_col"->'level1'->'level2'->>'level3'`,
|
||||
expected: `"json_col"::jsonb->'level1'->'level2'->>'level3'`,
|
||||
},
|
||||
{
|
||||
name: "root path",
|
||||
|
||||
@@ -291,6 +291,8 @@
|
||||
// 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",
|
||||
{
|
||||
|
||||
@@ -2,9 +2,33 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
plugins: [path.join(__dirname, 'stylelint-rules/no-unsupported-asset-url.js')],
|
||||
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'),
|
||||
],
|
||||
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' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -23,6 +23,8 @@ 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`
|
||||
|
||||
513
frontend/docs/css-modules-guide.md
Normal file
513
frontend/docs/css-modules-guide.md
Normal file
@@ -0,0 +1,513 @@
|
||||
# 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.
|
||||
@@ -192,9 +192,9 @@
|
||||
"lint-staged": "^17.0.4",
|
||||
"msw": "1.3.2",
|
||||
"orval": "8.9.1",
|
||||
"oxfmt": "0.47.0",
|
||||
"oxlint": "1.62.0",
|
||||
"oxlint-tsgolint": "0.22.1",
|
||||
"oxfmt": "0.54.0",
|
||||
"oxlint": "1.69.0",
|
||||
"oxlint-tsgolint": "0.23.0",
|
||||
"postcss": "8.5.14",
|
||||
"postcss-scss": "4.0.9",
|
||||
"react-resizable": "3.0.4",
|
||||
|
||||
144
frontend/plugins/rules/no-css-module-bracket-access.mjs
Normal file
144
frontend/plugins/rules/no-css-module-bracket-access.mjs
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* 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('');
|
||||
}
|
||||
@@ -11,6 +11,7 @@ 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: {
|
||||
@@ -23,5 +24,6 @@ export default {
|
||||
'no-raw-absolute-path': noRawAbsolutePath,
|
||||
'no-antd-components': noAntdComponents,
|
||||
'no-signozhq-ui-barrel': noSignozhqUiBarrel,
|
||||
'no-css-module-bracket-access': noCssModuleBracketAccess,
|
||||
},
|
||||
};
|
||||
|
||||
413
frontend/pnpm-lock.yaml
generated
413
frontend/pnpm-lock.yaml
generated
@@ -462,14 +462,14 @@ importers:
|
||||
specifier: 8.9.1
|
||||
version: 8.9.1(prettier@3.8.3)(typescript@5.9.3)
|
||||
oxfmt:
|
||||
specifier: 0.47.0
|
||||
version: 0.47.0
|
||||
specifier: 0.54.0
|
||||
version: 0.54.0
|
||||
oxlint:
|
||||
specifier: 1.62.0
|
||||
version: 1.62.0(oxlint-tsgolint@0.22.1)
|
||||
specifier: 1.69.0
|
||||
version: 1.69.0(oxlint-tsgolint@0.23.0)
|
||||
oxlint-tsgolint:
|
||||
specifier: 0.22.1
|
||||
version: 0.22.1
|
||||
specifier: 0.23.0
|
||||
version: 0.23.0
|
||||
postcss:
|
||||
specifier: 8.5.14
|
||||
version: 8.5.14
|
||||
@@ -505,7 +505,7 @@ importers:
|
||||
version: 1.6.0(react@18.2.0)
|
||||
vite-plugin-checker:
|
||||
specifier: 0.12.0
|
||||
version: 0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.62.0(oxlint-tsgolint@0.22.1))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3)
|
||||
version: 0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.69.0(oxlint-tsgolint@0.23.0))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3)
|
||||
vite-plugin-compression:
|
||||
specifier: 0.5.1
|
||||
version: 0.5.1(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))
|
||||
@@ -2123,276 +2123,276 @@ packages:
|
||||
'@oxc-project/types@0.101.0':
|
||||
resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==}
|
||||
|
||||
'@oxfmt/binding-android-arm-eabi@0.47.0':
|
||||
resolution: {integrity: sha512-KrMQRdMi/upr81qT4ijK6X6BNp6jqpMY7FwILQnwIy9QLc3qpnhUx5rsCLGzn4ewsCQ0CNAspN2ogmP1GXLyLw==}
|
||||
'@oxfmt/binding-android-arm-eabi@0.54.0':
|
||||
resolution: {integrity: sha512-NAtpl/SiaeU103e7/OmZw0MvUnsUUopW7hEm/ecegJg7YM0skQaA0IXEZoyTV6NUdiNPupdIUreRqUZTShbn/g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@oxfmt/binding-android-arm64@0.47.0':
|
||||
resolution: {integrity: sha512-r4ixS/PeUpAFKgrpDoZ5pSkthjZzVzKd95525Aazj+aOv9H4ulK5zYHGb7wFY5n5kZxHK8TbOJUZgoEb1ohddQ==}
|
||||
'@oxfmt/binding-android-arm64@0.54.0':
|
||||
resolution: {integrity: sha512-B4VZfBUlKK1rmMChsssNZbkZjE8+FzG3avMjGgMDwbGxXRoXkoeXiAZ+78Oa+eyDPHvDCiUb4zH/vmCOUSafLQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@oxfmt/binding-darwin-arm64@0.47.0':
|
||||
resolution: {integrity: sha512-CLWxiKpMl+195cm09CuaWEhJK0CirRkoMa07aR9+9AFPat2LfIKtwx1JqxZM0MTvcMe6+adlJNdVL6jdInvq3g==}
|
||||
'@oxfmt/binding-darwin-arm64@0.54.0':
|
||||
resolution: {integrity: sha512-i02vF75b+ePsQP3tHqSxVYI5S6b8X/xqdPu7/mDHXtpgXLTYXi3jJmfHU0j+dnZZDKaYTx/ioCK7QYJmtiJR2g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxfmt/binding-darwin-x64@0.47.0':
|
||||
resolution: {integrity: sha512-Xq5fjTYDC50faUeLSm0rZdBqoTgleXEdD7NpJdARtQIczkCJn3xNjMUSQQkUmh4CtxkKTNL68lytcOK3e/osgg==}
|
||||
'@oxfmt/binding-darwin-x64@0.54.0':
|
||||
resolution: {integrity: sha512-8VMFvGvooXj7mswkbrhdVZ2/sgiDaBzWpkkbtO+qGDLV4EfJd67nQadHkQC0ZNbaWA9ajXfqI6i7PZLIeDzxEQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxfmt/binding-freebsd-x64@0.47.0':
|
||||
resolution: {integrity: sha512-QOU9ZIJ52p5askcEC0QJvvr8trHAWoonul8bgISo6gYUL3s50zkqafBYcNAr9LJZQbsZtPfIWHk9+5+nUp1qJQ==}
|
||||
'@oxfmt/binding-freebsd-x64@0.54.0':
|
||||
resolution: {integrity: sha512-0cRHnp43WN1Jrc5s0BdbdKgR1XirdvHy7TAFi3JEsoEVQVJxTXMbpVd76sxXlgRswNMDhVFSJw+y7Eb8mEavFQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.47.0':
|
||||
resolution: {integrity: sha512-oJxDM1aBhPvz9gmElBv8UpxyiqhwfjcbrSxT5F0xtuUzY6dQI27/AQPIt3eu3Z5Yvn0kQl5R7MA3Z+MbnRvCBw==}
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.54.0':
|
||||
resolution: {integrity: sha512-JyQAk3hK/OEtup7Rw6kZwfdzbKqTVD5jXXb8Xpfay29suwZyfBDMVW/bj4RqEPySYWc6zCp198pOluf8n5uYzg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.47.0':
|
||||
resolution: {integrity: sha512-g8Lh50VS4ibGz2q6v7r9UZY4D0dM16SdrFYOMzhqIoCwGcai8VMIRUAcqn1/jlCsOOzUXJ741+kCeJt0cofakQ==}
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.54.0':
|
||||
resolution: {integrity: sha512-qnvLatTpM8vtvjOfcckBOzJjk+n6ce/wwpP8OFeUrD5aNLYcKyWAitwj+Rk3PK9jGanbZvKsJnv14JGQ6XqFdw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-YrNT1vQ0asaXoRbrvYENPqmBfOQ9Xr8enPNOULeYfg44VjCcrUowFy5QZr+WawE0zyP8cH9e9Gxxg0fDEFzhcg==}
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-SMkhnCzIYZYDk9vw3W/80eeYKmrMpGF0Giuxt4HruFlCH7jEtnPeb3SdQKMfgYi/dgtaf+hZAb5XWPYnxqCQ3w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-arm64-musl@0.47.0':
|
||||
resolution: {integrity: sha512-IxtQC/sbBi4ubbY+MdwdanRWrG9InQJVZqyMsBa5IUaQcnSg86gQme574HxXMC1p4bo4YhV99zQ+wNnGCvEgzw==}
|
||||
'@oxfmt/binding-linux-arm64-musl@0.54.0':
|
||||
resolution: {integrity: sha512-QrwJlBFFKnxOd95TAaszpMbZBLzMoYMpGaQTZF8oibacnF5rv8l12IhILhQRPmksWiBqg0YSe2Mnl7ayeJAHSA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-EWXEhOMbWO0q6eJSbu0QLkU8cKi0ljlYLngeDs2Ocu/pm1rrLwyQiYzlFbdnMRURI4w9ndr1sI9rSbhlJ5o23Q==}
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-WILatiol/TUHTlhod7R09+7Az/XlhKwmY1MHfLZNmewltPWNN/EwxP2rQSHahibZ/cB8gmckEBjBOByD+5bYsQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-tZrjS11TUiDuEpRaqdk8K9F9xETRyKXfuZKmdeW+Gj7coBnm7+8sBEfyt033EAFEQSlkniAXvBLh+Qja2ioGBQ==}
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-f05YMG4BH4G8S4ME6UM6fi1MnJ9094mrnvO5Pa4SJlMfWlUM+1/ZWMEF4NnjM7shZAvbHsHRuVYpUo0PHC4P9Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.47.0':
|
||||
resolution: {integrity: sha512-KBFy+2CFKUCZzYwX2ZOPQKck1vjQbz+hextuc19G4r0WRJwadfAeuQMQRQvB+Ivc8brlbOVg7et8K7E467440g==}
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.54.0':
|
||||
resolution: {integrity: sha512-UfL+2hj1ClNqcCRT9s8vBU4axDpjxgVxX96G+9DYAYjoc5b0u15CJtn2jgsi9iM+EbGNc5CW1HVRgwVu76UsSA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-REUPFKVGSiK99B+9eaPhluEVglzaoj/SMykNC5SUiV2RSsBfV5lWN7Y0iCIc251Wz3GaeAGZsJ/zj3gjarxdFg==}
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-3/XZe931Hka+J6NjnaqJzYpsWWxDTuRdUdwSQHnOuJEgbC+SehIMFJS8hsEjV7LBhVSL2OCnRLvbVW8O97XIyw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-x64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-KVftVSVEDeIfRW3TIeLe3aNI/iY4m1fu5mDwHcisKMZSCMKLkrhFsjowC7o9RoqNPxbbglm2+/6KAKBIts2t0Q==}
|
||||
'@oxfmt/binding-linux-x64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-Ik93RlObtu43GbxApafayFjwYE06L6Xr08cSwpBPYbDrLp2ReZx0Jm1DqwRyYRnukUJy+rK2WaEvUQOxdytU9Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-x64-musl@0.47.0':
|
||||
resolution: {integrity: sha512-DTsmGEaA2860Aq5VUyDO8/MT9NFxwVL93RnRYmpMwK6DsSkThmvEpqoUDDljziEpAedMRG19SCogrNbINSbLUQ==}
|
||||
'@oxfmt/binding-linux-x64-musl@0.54.0':
|
||||
resolution: {integrity: sha512-yZcakmPlD86CNymknd7KfW+FH+qfbqJH+i0h69CYfV1+KMoVeM9UED+8+TDVoU4haxI0NxY7RPCvRLy3Sqd2Qg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-openharmony-arm64@0.47.0':
|
||||
resolution: {integrity: sha512-8r5BDro7fLOBoq1JXHLVSs55OlrxQhEso4HVo0TcY7OXJUPYfjPoOaYL5us+yIwqyP9rQwN+rxuiNFSmaxSuOQ==}
|
||||
'@oxfmt/binding-openharmony-arm64@0.54.0':
|
||||
resolution: {integrity: sha512-GiVBZNnEZnKu00f1jTg49nomv187d0GQX+O+ocykoLeiaALuEO+swoTehHn9TehTfi7V8H0i0e/yvUjCqnwk1w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.47.0':
|
||||
resolution: {integrity: sha512-qtz/gzm8IjSPUlseZ0ofW8zyHLoZsuP5HTfcGGkWkUblB89JT8GNYH3ICqjbDsqsGqXum0/ZndXTFplSdXFIcg==}
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.54.0':
|
||||
resolution: {integrity: sha512-J0SSB8Z1Fre2sxRolYcW6Rl1RQmKdQ2hnHyq4YJrfBRiXTObLw4DXnIVraM/UyqGqwOi7yTrQA4VT7DPxlHVKA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.47.0':
|
||||
resolution: {integrity: sha512-5vIcdcIDE7nCx+MXN6sm8kbC4zajDB31E86rez4i45iHNH/2NjdKlJ720xcHTr3eeiMcttCGPHPhE1TjtBDGZw==}
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.54.0':
|
||||
resolution: {integrity: sha512-O61UDVj8zz6yXJjkHPf05VaMLOXmEF8P5kf/N0W7AQMmd6bcQogl+KJc7rMutKTL524oE9iH32JXZClBFmEQIg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@oxfmt/binding-win32-x64-msvc@0.47.0':
|
||||
resolution: {integrity: sha512-Sr59Y5ms54ONBjxFeWhVlGyQcHXxcl9DxC23f6yXlRkcos7LXBLoO+KDfxexjHIOZh7cWqrWduzvUjJ+pHp8cQ==}
|
||||
'@oxfmt/binding-win32-x64-msvc@0.54.0':
|
||||
resolution: {integrity: sha512-1MDpqJPiFqxWtIHas8vkb1VZ7f7eKyTffAwmO8isxQYMaG1OFKsH666BWLeXQLO+IWNfiMssLD55hbR1lIPTqg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint-tsgolint/darwin-arm64@0.22.1':
|
||||
resolution: {integrity: sha512-4150Lpgc1YM09GcjA6GSrra1JoPjC7aOpfywLjWEY4vW0Sd1qKzqHF1WRaiw0/qUZ40OATYdv3aRd7ipPkWQbw==}
|
||||
'@oxlint-tsgolint/darwin-arm64@0.23.0':
|
||||
resolution: {integrity: sha512-gOs9PVr2wEg4ox9z0aJo+RKhhImW86YL5N6yav8BK/rgPsIrwN/igSZ+pbRr723NFvUNKde9fgMhRA6JrXAOZw==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint-tsgolint/darwin-x64@0.22.1':
|
||||
resolution: {integrity: sha512-vFWcPWYOgZs4HWcgS1EjUZg33NLcNfEYU49KGImmCfZWkflENrmBYV4HN/C0YeAPum6ZZ/goPSvQrB/cOD+NfA==}
|
||||
'@oxlint-tsgolint/darwin-x64@0.23.0':
|
||||
resolution: {integrity: sha512-kjJ8B+7n4tB9VJdxS5A9GdJt6/bYpzbu4lXp2uO1S3sRmCB5gDEABlGoiePNApRWaW+xqL4b4xgiE727jSLhuA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint-tsgolint/linux-arm64@0.22.1':
|
||||
resolution: {integrity: sha512-6LiUpP0Zir3+29FvBm7Y28q/dBjSHqTZ5MhG1Ckw4fGhI4cAvbcwXaKvbjx1TP7rRmBNOoq/M5xdpHjTb+GAew==}
|
||||
'@oxlint-tsgolint/linux-arm64@0.23.0':
|
||||
resolution: {integrity: sha512-6dCZuKNu135seMXilkRk9SpCx6i1XgmiipYGalLij5WVRX6ZYS8c4xI7preN/zv9fCXhsQclTIMDu2Y/cytTjw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint-tsgolint/linux-x64@0.22.1':
|
||||
resolution: {integrity: sha512-fuX1hEQfpHauUbXADsfqVhRzrUrGabzGXbj5wsp2vKhV5uk/Rze8Mba9GdjFGECzvXudMGqHqxB4r6jGRdhxVA==}
|
||||
'@oxlint-tsgolint/linux-x64@0.23.0':
|
||||
resolution: {integrity: sha512-3bdilnyA7kmSTjK27rvjIjSxL5SIg3wt7vwNiRkouWB83ytssyKnuGvxSYJxgMEmFpSutzaBzcCUM2jDtPGcgA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint-tsgolint/win32-arm64@0.22.1':
|
||||
resolution: {integrity: sha512-8SZidAj+jrbZf9ZjBEYW0tiNZ+KasqB2zgW26qdiPpQSF/DzURnPmXz651IeA9YsmbVdHGIooEHUmev6QJdquA==}
|
||||
'@oxlint-tsgolint/win32-arm64@0.23.0':
|
||||
resolution: {integrity: sha512-j+OEp44SVYiQ+ZD+uttsX7u6L9SvmbbQ77SO1pSFCcJlsVMeCk8qZsjhKfGKuT/jIA+ipOJMVs/+pqUfObBWNw==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint-tsgolint/win32-x64@0.22.1':
|
||||
resolution: {integrity: sha512-QweSk9H5lFh5Y+WUf2Kq/OAN88V6+62ZwGhP38gqdRotI90luXSMkruFTj7Q2rYrzH4ZVNaSqx7NY8JpSfIzqg==}
|
||||
'@oxlint-tsgolint/win32-x64@0.23.0':
|
||||
resolution: {integrity: sha512-5MyjFuqf+g8OUPJBSGWHJtmoWnzFJYyOg4To9WMQshZYEWig/vtu7JtJ03VWnzHv9LJkAUeApY0gVCOywFR/iQ==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/binding-android-arm-eabi@1.62.0':
|
||||
resolution: {integrity: sha512-pKsthNECyvJh8lPTICz6VcwVy2jOqdhhsp1rlxCkhgZR47aKvXPmaRWQDv+zlXpRae4qm1MaaTnutkaOk5aofg==}
|
||||
'@oxlint/binding-android-arm-eabi@1.69.0':
|
||||
resolution: {integrity: sha512-DKQQbD5cZ/MYfDgDI7YGyGD9FSxABlsBsYFo5p26lloob543tP9+4N3guwdXIYJN+7HSZxLe8YJuwcOWw5qnHg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@oxlint/binding-android-arm64@1.62.0':
|
||||
resolution: {integrity: sha512-b1AUNViByvgmR2xJDubvLIr+dSuu3uraG7bsAoKo+xrpspPvu6RIn6Fhr2JUhobfep3jwUTy18Huco6GkwdvGQ==}
|
||||
'@oxlint/binding-android-arm64@1.69.0':
|
||||
resolution: {integrity: sha512-lEhb+I5pr4inux+JFwfCa1HRq3Os7NirEFQ0H1I35SVEHPm6byX0Ah47xmRha3qi6LAkxUcxViL8o/9PivjzBg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@oxlint/binding-darwin-arm64@1.62.0':
|
||||
resolution: {integrity: sha512-iG+Tvf70UJ6otfwFYIHk36Sjq9cpPP5YLxkoggANNRtzgi3Tj3g8q6Ybqi6AtkU3+yg9QwF7bDCkCS6bbL4PCg==}
|
||||
'@oxlint/binding-darwin-arm64@1.69.0':
|
||||
resolution: {integrity: sha512-GY2YE8lOZW59BW1Ia1y+1gR0XyjrZRvVWHAr8LGeGhYHE0OQJ/7cRKXTkx1P+E9/6awEc3SX8a68SFTjh/E//A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint/binding-darwin-x64@1.62.0':
|
||||
resolution: {integrity: sha512-oOWI6YPPr5AJUx+yIDlxmuUbQjS5gZX3OH3QisawYvsZgLiQVvZtR0rPBcJTxLWqt2ClrWg0DlSrlUiG5SQNHg==}
|
||||
'@oxlint/binding-darwin-x64@1.69.0':
|
||||
resolution: {integrity: sha512-ax1oZnOjHX3LB7myQyHEaQkDwfLb6str3/nSP6O7EVUviQGNkEGzGV0EqcBJWK+Ufwx0l4xPgyYayurvhAdl2Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint/binding-freebsd-x64@1.62.0':
|
||||
resolution: {integrity: sha512-dLP33T7VLCmLVv4cvjkVX+rmkcwNk2UfxmsZPNur/7BQHoQR60zJ7XLiRvNUawlzn0u8ngCa3itjEG73MAMa/w==}
|
||||
'@oxlint/binding-freebsd-x64@1.69.0':
|
||||
resolution: {integrity: sha512-kHWeHv4g2h8NY+mpCxzCtY4uerMJWTN/TSnNj1CPbakFpHEJ6cTya2wWV0pDSYWOJ2+0UiEbhn3AtXxHtsnKjg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.62.0':
|
||||
resolution: {integrity: sha512-fl//LWNks6qo9chNY60UDYyIwtp7a5cEx4Y/rHPjaarhuwqx6jtbzEpD5V5AqmdL4a6Y5D8zeXg5HF2Cr0QmSQ==}
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.69.0':
|
||||
resolution: {integrity: sha512-gq84vM1a1oEehXo27YCDzGVcxPsZDI1yswZwz2Da1/cbnWtrL16XZZnz0G/+gIU8edtHpfjxq5c+vWEHqJfWoQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.62.0':
|
||||
resolution: {integrity: sha512-i5vkAuxvueTODV3J2dL61/TXewDHhMFKvtD156cIsk7GsdfiAu7zW7kY0NJXhKeFHeiMZIh7eFNjkPYH6J47HQ==}
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.69.0':
|
||||
resolution: {integrity: sha512-kIqEa98JQ0VRyrcncxA417m2AzasqTlD+FyVT1AksjvjkqQcvm7pBWYvoW3/mpyOP2XYvi5nSCCTIe6De1yu5g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/binding-linux-arm64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-QwN19LLuIGuOjEflSeJkZmOTfBdBMlTmW8xbMf8TZhjd//cxVNYQPq75q7oKZBJc6hRx3gY7sX0Egc8cEIFZYg==}
|
||||
'@oxlint/binding-linux-arm64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-j+xYiXozxGWx2cpjCrwwGR4awTxPFsRv3JZrv23RCogEPMc4R7UqjHW47p/RG0aRlbWiROCJ8coUfCwy0dvzHA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-arm64-musl@1.62.0':
|
||||
resolution: {integrity: sha512-8eCy3FCDuWUM5hWujAv6heMvfZPbcCOU3SdQUAkixZLu5bSzOkNfirJiLGoQFO943xceOKkiQRMQNzH++jM3WA==}
|
||||
'@oxlint/binding-linux-arm64-musl@1.69.0':
|
||||
resolution: {integrity: sha512-xEPpNppTfN1l/nM7gYSf9iocscu/as+p/7vxkLeLEKnYU+09Dm+5V6IhDYDh+Uz6FajEupWwCLt5SOG0y1PCKg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-NjQ7K7tpTPDe9J+yq8p/s/J0E7lRCkK2uDBDqvT4XIT6f4Z0tlnr59OBg/WcrmVHER1AbrcfyxhGTXgcG8ytWg==}
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-Ug0+eU7HJBlek+SjklYH62IlOMirEJsdxpihH0kSqX0XdrDD4NdHpQc10fK1JC35yn6KrrcN+uYzlHD38XAf8Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-oKZed9gmSwze29dEt3/Wnsv6l/Ygw/FUst+8Kfpv2SGeS/glEoTGZAMQw37SVyzFV76UTHJN2snGgxK2t2+8ow==}
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-iEyI3GIg0l/s3G4qy2TlaaWKdzj4PJJStwtlocpDTC00PY9hZueotf6OKUj9+yfQh0lrpBW/pLMgTztbAHKJEg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-riscv64-musl@1.62.0':
|
||||
resolution: {integrity: sha512-gBjBxQ+9lGpAYq+ELqw0w8QXsBnkZclFc7GRX2r0LnEVn3ZTEqeIKpKcGjucmp76Q53bvJD0i4qBWBhcfhSfGA==}
|
||||
'@oxlint/binding-linux-riscv64-musl@1.69.0':
|
||||
resolution: {integrity: sha512-NjHjpiI4WIKSMwuoJSZi5VToPeoYOS1FR52HLIDG6lidMdqquusgtODb4iLk0+lb1q3Z0nv2/aPRcC/olmpQGg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-linux-s390x-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-Ew2Kxs9EQ9/mbAIJ2hvocMC0wsOu6YKzStI2eFBDt+Td5O8seVC/oxgRIHqCcl5sf5ratA1nozQBAuv7tphkHg==}
|
||||
'@oxlint/binding-linux-s390x-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-Ai/prDewoItkDXbp38gwGZi41DycZbUTZJ3UidwoHgQC0/DaqC2TGdtBTQLJ6hSD+SAxASzh8+/eSBPmxfOacA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-x64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-5z25jcAA0gfKyVwz71A0VXgaPlocPoTAxhlv/hgoK6tlCrfoNuw7haWbDHvGMfjXhdic4EqVXGRv5XsTqFnbRQ==}
|
||||
'@oxlint/binding-linux-x64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-Gt3KHgp46mRKz4sJeaASmKvD8ayXookRw07RMf+NowhEztGGDZ7VrXpoW96XuKJLjFukWizOFVNjmYb/u7caNQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-x64-musl@1.62.0':
|
||||
resolution: {integrity: sha512-IWpHmMB6ZDllPvqWDkG6AmXrN7JF5e/c4g/0PuURsmlK+vHoYZPB70rr4u1bn3I4LsKCSpqqfveyx6UCOC8wdg==}
|
||||
'@oxlint/binding-linux-x64-musl@1.69.0':
|
||||
resolution: {integrity: sha512-7tQhJ2+p/oHv1zcfnjYI7YVzC/7iBaVOfIvFYtxdJ5F45mWgEdrCyXZXZGfiLey5t/5JhOhsaMnnv1kAzckd7g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-openharmony-arm64@1.62.0':
|
||||
resolution: {integrity: sha512-fjlSxxrD5pA594vkyikCS9MnPRjQawW6/BLgyTYkO+73wwPlYjkcZ7LSd974l0Q2zkHQmu4DPvJFLYA7o8xrxQ==}
|
||||
'@oxlint/binding-openharmony-arm64@1.69.0':
|
||||
resolution: {integrity: sha512-vmWz6TKp/3hfA4lksR0zHBv/6xuX1jhym6eqOjdH2DXsDDHZWcp2f0KG0VCAnlVbIrjk29G4wAWMXb/Hn1YobA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@oxlint/binding-win32-arm64-msvc@1.62.0':
|
||||
resolution: {integrity: sha512-EiFXr8loNS0Ul3Gu80+9nr1T8jRmnKocqmHHg16tj5ZqTgUXyb97l2rrspVHdDluyFn9JfR4PoJFdNzw4paHww==}
|
||||
'@oxlint/binding-win32-arm64-msvc@1.69.0':
|
||||
resolution: {integrity: sha512-9RExaLgmaw6IoIkU9cTpT71mLfI0xZ86iZH8x518LVsOkjquJMYqb9P7KpC8lgd1t0Dxs41p2pxynq4XR3Ttzw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/binding-win32-ia32-msvc@1.62.0':
|
||||
resolution: {integrity: sha512-IgOFvL73li1bFgab+hThXYA0N2Xms2kV2MvZN95cebV+fmrZ9AVui1JSxfeeqRLo3CpPxKZlzhyq4G0cnaAvIw==}
|
||||
'@oxlint/binding-win32-ia32-msvc@1.69.0':
|
||||
resolution: {integrity: sha512-1907kRPF8/PrcIw1E7LMs9JbVrpgnt/MvFdss3an8oDkYNAACXzTntV3t3869ZZhMZxb2AzRGbz1pA/jdFatXA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/binding-win32-x64-msvc@1.62.0':
|
||||
resolution: {integrity: sha512-6hMpyDWQ2zGA1OXFKBrdYMUveUCO8UJhkO6JdwZPd78xIdHZNhjx+pib+4fC2Cljuhjyl0QwA2F3df/bs4Bp6A==}
|
||||
'@oxlint/binding-win32-x64-msvc@1.69.0':
|
||||
resolution: {integrity: sha512-w8SOXv3mT9Fi6jY8OXdXCfnvX/3KNLXGNr4HEz2TA7S4Mv/PYAOmpB8y/ge40mxvBMgGNaSaaDwZpAsQn7HtWA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -6885,24 +6885,35 @@ packages:
|
||||
overlayscrollbars@2.9.2:
|
||||
resolution: {integrity: sha512-iDT84r39i7oWP72diZN2mbJUsn/taCq568aQaIrc84S87PunBT7qtsVltAF2esk7ORTRjQDnfjVYoqqTzgs8QA==}
|
||||
|
||||
oxfmt@0.47.0:
|
||||
resolution: {integrity: sha512-OFbkbzxKCpooQEnRmpTDnuwTX8KHXzZTQ4Df/hz85fpS67Pl+lxPEFvUtin56HIIS0B1k4X8oIzTXRZPufA2CA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
oxlint-tsgolint@0.22.1:
|
||||
resolution: {integrity: sha512-YUSGSLUnoolsu8gxISEDio3q1rtsCozwfOzASUn3DT2mR2EeQ93uEEnen7s+6LpF+lyTQFln1pQfqwBh/fsVEg==}
|
||||
hasBin: true
|
||||
|
||||
oxlint@1.62.0:
|
||||
resolution: {integrity: sha512-1uFkg6HakjsGIpW9wNdeW4/2LOHW9MEkoWjZUTUfQtIHyLIZPYt00w3Sg+H3lH+206FgBPHBbW5dVE5l2ExECQ==}
|
||||
oxfmt@0.54.0:
|
||||
resolution: {integrity: sha512-DjnMwn7smSLF+Mc2+pRItnuPftm/dkUFpY/d4+33y9TfKrsHZo8GLhmUg9BrOIUEy94Rlom1Q11N6vuhE+e0oQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
oxlint-tsgolint: '>=0.18.0'
|
||||
svelte: ^5.0.0
|
||||
vite-plus: '*'
|
||||
peerDependenciesMeta:
|
||||
svelte:
|
||||
optional: true
|
||||
vite-plus:
|
||||
optional: true
|
||||
|
||||
oxlint-tsgolint@0.23.0:
|
||||
resolution: {integrity: sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA==}
|
||||
hasBin: true
|
||||
|
||||
oxlint@1.69.0:
|
||||
resolution: {integrity: sha512-ypZkK/aDc5NQV8zIR6s2H2Tl3aNW8FmJ1m9+2qsaYuRenl8vgnHNCGwTHviWJdUQzglOlHFchgopdtGhSy17Rw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
oxlint-tsgolint: '>=0.22.1'
|
||||
vite-plus: '*'
|
||||
peerDependenciesMeta:
|
||||
oxlint-tsgolint:
|
||||
optional: true
|
||||
vite-plus:
|
||||
optional: true
|
||||
|
||||
p-limit@2.3.0:
|
||||
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
|
||||
@@ -11039,136 +11050,136 @@ snapshots:
|
||||
|
||||
'@oxc-project/types@0.101.0': {}
|
||||
|
||||
'@oxfmt/binding-android-arm-eabi@0.47.0':
|
||||
'@oxfmt/binding-android-arm-eabi@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-android-arm64@0.47.0':
|
||||
'@oxfmt/binding-android-arm64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-darwin-arm64@0.47.0':
|
||||
'@oxfmt/binding-darwin-arm64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-darwin-x64@0.47.0':
|
||||
'@oxfmt/binding-darwin-x64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-freebsd-x64@0.47.0':
|
||||
'@oxfmt/binding-freebsd-x64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.47.0':
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.47.0':
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm64-musl@0.47.0':
|
||||
'@oxfmt/binding-linux-arm64-musl@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.47.0':
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-x64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-x64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-x64-musl@0.47.0':
|
||||
'@oxfmt/binding-linux-x64-musl@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-openharmony-arm64@0.47.0':
|
||||
'@oxfmt/binding-openharmony-arm64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.47.0':
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.47.0':
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-win32-x64-msvc@0.47.0':
|
||||
'@oxfmt/binding-win32-x64-msvc@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/darwin-arm64@0.22.1':
|
||||
'@oxlint-tsgolint/darwin-arm64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/darwin-x64@0.22.1':
|
||||
'@oxlint-tsgolint/darwin-x64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/linux-arm64@0.22.1':
|
||||
'@oxlint-tsgolint/linux-arm64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/linux-x64@0.22.1':
|
||||
'@oxlint-tsgolint/linux-x64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/win32-arm64@0.22.1':
|
||||
'@oxlint-tsgolint/win32-arm64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/win32-x64@0.22.1':
|
||||
'@oxlint-tsgolint/win32-x64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-android-arm-eabi@1.62.0':
|
||||
'@oxlint/binding-android-arm-eabi@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-android-arm64@1.62.0':
|
||||
'@oxlint/binding-android-arm64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-darwin-arm64@1.62.0':
|
||||
'@oxlint/binding-darwin-arm64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-darwin-x64@1.62.0':
|
||||
'@oxlint/binding-darwin-x64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-freebsd-x64@1.62.0':
|
||||
'@oxlint/binding-freebsd-x64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.62.0':
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.62.0':
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-arm64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm64-musl@1.62.0':
|
||||
'@oxlint/binding-linux-arm64-musl@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-riscv64-musl@1.62.0':
|
||||
'@oxlint/binding-linux-riscv64-musl@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-s390x-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-s390x-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-x64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-x64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-x64-musl@1.62.0':
|
||||
'@oxlint/binding-linux-x64-musl@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-openharmony-arm64@1.62.0':
|
||||
'@oxlint/binding-openharmony-arm64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-win32-arm64-msvc@1.62.0':
|
||||
'@oxlint/binding-win32-arm64-msvc@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-win32-ia32-msvc@1.62.0':
|
||||
'@oxlint/binding-win32-ia32-msvc@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-win32-x64-msvc@1.62.0':
|
||||
'@oxlint/binding-win32-x64-msvc@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@parcel/watcher-android-arm64@2.5.1':
|
||||
@@ -16377,61 +16388,61 @@ snapshots:
|
||||
|
||||
overlayscrollbars@2.9.2: {}
|
||||
|
||||
oxfmt@0.47.0:
|
||||
oxfmt@0.54.0:
|
||||
dependencies:
|
||||
tinypool: 2.1.0
|
||||
optionalDependencies:
|
||||
'@oxfmt/binding-android-arm-eabi': 0.47.0
|
||||
'@oxfmt/binding-android-arm64': 0.47.0
|
||||
'@oxfmt/binding-darwin-arm64': 0.47.0
|
||||
'@oxfmt/binding-darwin-x64': 0.47.0
|
||||
'@oxfmt/binding-freebsd-x64': 0.47.0
|
||||
'@oxfmt/binding-linux-arm-gnueabihf': 0.47.0
|
||||
'@oxfmt/binding-linux-arm-musleabihf': 0.47.0
|
||||
'@oxfmt/binding-linux-arm64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-arm64-musl': 0.47.0
|
||||
'@oxfmt/binding-linux-ppc64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-riscv64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-riscv64-musl': 0.47.0
|
||||
'@oxfmt/binding-linux-s390x-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-x64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-x64-musl': 0.47.0
|
||||
'@oxfmt/binding-openharmony-arm64': 0.47.0
|
||||
'@oxfmt/binding-win32-arm64-msvc': 0.47.0
|
||||
'@oxfmt/binding-win32-ia32-msvc': 0.47.0
|
||||
'@oxfmt/binding-win32-x64-msvc': 0.47.0
|
||||
'@oxfmt/binding-android-arm-eabi': 0.54.0
|
||||
'@oxfmt/binding-android-arm64': 0.54.0
|
||||
'@oxfmt/binding-darwin-arm64': 0.54.0
|
||||
'@oxfmt/binding-darwin-x64': 0.54.0
|
||||
'@oxfmt/binding-freebsd-x64': 0.54.0
|
||||
'@oxfmt/binding-linux-arm-gnueabihf': 0.54.0
|
||||
'@oxfmt/binding-linux-arm-musleabihf': 0.54.0
|
||||
'@oxfmt/binding-linux-arm64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-arm64-musl': 0.54.0
|
||||
'@oxfmt/binding-linux-ppc64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-riscv64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-riscv64-musl': 0.54.0
|
||||
'@oxfmt/binding-linux-s390x-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-x64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-x64-musl': 0.54.0
|
||||
'@oxfmt/binding-openharmony-arm64': 0.54.0
|
||||
'@oxfmt/binding-win32-arm64-msvc': 0.54.0
|
||||
'@oxfmt/binding-win32-ia32-msvc': 0.54.0
|
||||
'@oxfmt/binding-win32-x64-msvc': 0.54.0
|
||||
|
||||
oxlint-tsgolint@0.22.1:
|
||||
oxlint-tsgolint@0.23.0:
|
||||
optionalDependencies:
|
||||
'@oxlint-tsgolint/darwin-arm64': 0.22.1
|
||||
'@oxlint-tsgolint/darwin-x64': 0.22.1
|
||||
'@oxlint-tsgolint/linux-arm64': 0.22.1
|
||||
'@oxlint-tsgolint/linux-x64': 0.22.1
|
||||
'@oxlint-tsgolint/win32-arm64': 0.22.1
|
||||
'@oxlint-tsgolint/win32-x64': 0.22.1
|
||||
'@oxlint-tsgolint/darwin-arm64': 0.23.0
|
||||
'@oxlint-tsgolint/darwin-x64': 0.23.0
|
||||
'@oxlint-tsgolint/linux-arm64': 0.23.0
|
||||
'@oxlint-tsgolint/linux-x64': 0.23.0
|
||||
'@oxlint-tsgolint/win32-arm64': 0.23.0
|
||||
'@oxlint-tsgolint/win32-x64': 0.23.0
|
||||
|
||||
oxlint@1.62.0(oxlint-tsgolint@0.22.1):
|
||||
oxlint@1.69.0(oxlint-tsgolint@0.23.0):
|
||||
optionalDependencies:
|
||||
'@oxlint/binding-android-arm-eabi': 1.62.0
|
||||
'@oxlint/binding-android-arm64': 1.62.0
|
||||
'@oxlint/binding-darwin-arm64': 1.62.0
|
||||
'@oxlint/binding-darwin-x64': 1.62.0
|
||||
'@oxlint/binding-freebsd-x64': 1.62.0
|
||||
'@oxlint/binding-linux-arm-gnueabihf': 1.62.0
|
||||
'@oxlint/binding-linux-arm-musleabihf': 1.62.0
|
||||
'@oxlint/binding-linux-arm64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-arm64-musl': 1.62.0
|
||||
'@oxlint/binding-linux-ppc64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-riscv64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-riscv64-musl': 1.62.0
|
||||
'@oxlint/binding-linux-s390x-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-x64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-x64-musl': 1.62.0
|
||||
'@oxlint/binding-openharmony-arm64': 1.62.0
|
||||
'@oxlint/binding-win32-arm64-msvc': 1.62.0
|
||||
'@oxlint/binding-win32-ia32-msvc': 1.62.0
|
||||
'@oxlint/binding-win32-x64-msvc': 1.62.0
|
||||
oxlint-tsgolint: 0.22.1
|
||||
'@oxlint/binding-android-arm-eabi': 1.69.0
|
||||
'@oxlint/binding-android-arm64': 1.69.0
|
||||
'@oxlint/binding-darwin-arm64': 1.69.0
|
||||
'@oxlint/binding-darwin-x64': 1.69.0
|
||||
'@oxlint/binding-freebsd-x64': 1.69.0
|
||||
'@oxlint/binding-linux-arm-gnueabihf': 1.69.0
|
||||
'@oxlint/binding-linux-arm-musleabihf': 1.69.0
|
||||
'@oxlint/binding-linux-arm64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-arm64-musl': 1.69.0
|
||||
'@oxlint/binding-linux-ppc64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-riscv64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-riscv64-musl': 1.69.0
|
||||
'@oxlint/binding-linux-s390x-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-x64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-x64-musl': 1.69.0
|
||||
'@oxlint/binding-openharmony-arm64': 1.69.0
|
||||
'@oxlint/binding-win32-arm64-msvc': 1.69.0
|
||||
'@oxlint/binding-win32-ia32-msvc': 1.69.0
|
||||
'@oxlint/binding-win32-x64-msvc': 1.69.0
|
||||
oxlint-tsgolint: 0.23.0
|
||||
|
||||
p-limit@2.3.0:
|
||||
dependencies:
|
||||
@@ -18476,7 +18487,7 @@ snapshots:
|
||||
unist-util-stringify-position: 4.0.0
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite-plugin-checker@0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.62.0(oxlint-tsgolint@0.22.1))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3):
|
||||
vite-plugin-checker@0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.69.0(oxlint-tsgolint@0.23.0))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.29.0
|
||||
chokidar: 4.0.3
|
||||
@@ -18491,7 +18502,7 @@ snapshots:
|
||||
eslint: 10.2.1(jiti@2.6.1)
|
||||
meow: 13.2.0
|
||||
optionator: 0.9.4
|
||||
oxlint: 1.62.0(oxlint-tsgolint@0.22.1)
|
||||
oxlint: 1.69.0(oxlint-tsgolint@0.23.0)
|
||||
stylelint: 17.7.0(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
|
||||
|
||||
@@ -5,6 +5,13 @@ 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> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -5,6 +5,13 @@ 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}`);
|
||||
|
||||
@@ -4,6 +4,13 @@ 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');
|
||||
|
||||
@@ -5,6 +5,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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}`);
|
||||
|
||||
@@ -4,6 +4,13 @@ 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`);
|
||||
|
||||
@@ -6,6 +6,13 @@ 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`, {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -5,6 +5,13 @@ 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>> => {
|
||||
|
||||
@@ -9,6 +9,13 @@ 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,
|
||||
|
||||
@@ -8,6 +8,12 @@ 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',
|
||||
|
||||
@@ -11,6 +11,12 @@ 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',
|
||||
|
||||
@@ -18,6 +18,8 @@ import type {
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
CloneDashboardV2201,
|
||||
CloneDashboardV2PathParameters,
|
||||
CreateDashboardV2201,
|
||||
CreatePublicDashboard201,
|
||||
CreatePublicDashboardPathParameters,
|
||||
@@ -26,6 +28,7 @@ import type {
|
||||
DashboardtypesPostablePublicDashboardDTO,
|
||||
DashboardtypesUpdatableDashboardV2DTO,
|
||||
DashboardtypesUpdatablePublicDashboardDTO,
|
||||
DeleteDashboardV2PathParameters,
|
||||
DeletePublicDashboardPathParameters,
|
||||
GetDashboardV2200,
|
||||
GetDashboardV2PathParameters,
|
||||
@@ -35,11 +38,17 @@ import type {
|
||||
GetPublicDashboardPathParameters,
|
||||
GetPublicDashboardWidgetQueryRange200,
|
||||
GetPublicDashboardWidgetQueryRangePathParameters,
|
||||
ListDashboardsForUserV2200,
|
||||
ListDashboardsForUserV2Params,
|
||||
ListDashboardsV2200,
|
||||
ListDashboardsV2Params,
|
||||
LockDashboardV2PathParameters,
|
||||
PatchDashboardV2200,
|
||||
PatchDashboardV2PathParameters,
|
||||
PinDashboardV2PathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
UnlockDashboardV2PathParameters,
|
||||
UnpinDashboardV2PathParameters,
|
||||
UpdateDashboardV2200,
|
||||
UpdateDashboardV2PathParameters,
|
||||
UpdatePublicDashboardPathParameters,
|
||||
@@ -56,7 +65,7 @@ export const deletePublicDashboard = (
|
||||
{ id }: DeletePublicDashboardPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/dashboards/${id}/public`,
|
||||
method: 'DELETE',
|
||||
signal,
|
||||
@@ -339,7 +348,7 @@ export const updatePublicDashboard = (
|
||||
dashboardtypesUpdatablePublicDashboardDTO?: BodyType<DashboardtypesUpdatablePublicDashboardDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/dashboards/${id}/public`,
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -641,6 +650,103 @@ export const invalidateGetPublicDashboardWidgetQueryRange = async (
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -724,6 +830,85 @@ 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)
|
||||
@@ -1023,6 +1208,85 @@ 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)
|
||||
@@ -1031,7 +1295,7 @@ export const unlockDashboardV2 = (
|
||||
{ id }: UnlockDashboardV2PathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/dashboards/${id}/lock`,
|
||||
method: 'DELETE',
|
||||
signal,
|
||||
@@ -1110,7 +1374,7 @@ export const lockDashboardV2 = (
|
||||
{ id }: LockDashboardV2PathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/dashboards/${id}/lock`,
|
||||
method: 'PUT',
|
||||
signal,
|
||||
@@ -1181,3 +1445,260 @@ 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));
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ export const handleExportRawDataPOST = (
|
||||
params?: HandleExportRawDataPOSTParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/export_raw_data`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
||||
@@ -680,7 +680,7 @@ export const updateMetricMetadata = (
|
||||
metricsexplorertypesUpdateMetricMetadataRequestDTO?: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/metrics/${metricName}/metadata`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
||||
@@ -203,7 +203,7 @@ export const deleteRole = (
|
||||
{ id }: DeleteRolePathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/roles/${id}`,
|
||||
method: 'DELETE',
|
||||
signal,
|
||||
@@ -372,7 +372,7 @@ export const patchRole = (
|
||||
authtypesPatchableRoleDTO?: BodyType<AuthtypesPatchableRoleDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
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<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/roles/${id}/relations/${relation}/objects`,
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
||||
@@ -222,7 +222,7 @@ export const deleteServiceAccount = (
|
||||
{ id }: DeleteServiceAccountPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/service_accounts/${id}`,
|
||||
method: 'DELETE',
|
||||
signal,
|
||||
@@ -405,7 +405,7 @@ export const updateServiceAccount = (
|
||||
serviceaccounttypesPostableServiceAccountDTO?: BodyType<ServiceaccounttypesPostableServiceAccountDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
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<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
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<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
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<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
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<string>({
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v1/service_accounts/me`,
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
|
||||
@@ -413,21 +413,11 @@ 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 {
|
||||
@@ -441,7 +431,7 @@ export interface AlertmanagertypesScheduleDTO {
|
||||
* @type string
|
||||
* @format date-time
|
||||
*/
|
||||
startTime?: string;
|
||||
startTime: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -2153,6 +2143,10 @@ export interface ErrorsResponseerroradditionalDTO {
|
||||
* @type string
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
suggestions?: string[];
|
||||
}
|
||||
|
||||
export interface ErrorsResponseretryjsonDTO {
|
||||
@@ -2168,10 +2162,6 @@ export interface ErrorsJSONDTO {
|
||||
* @type array
|
||||
*/
|
||||
errors?: ErrorsResponseerroradditionalDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
invalidReferences?: string[];
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -2651,8 +2641,18 @@ 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,17 +3154,6 @@ export interface DashboardLinkDTO {
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export interface DashboardPanelDisplayDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface VariableDisplayDTO {
|
||||
/**
|
||||
* @type string
|
||||
@@ -3493,6 +3482,9 @@ export interface TelemetrytypesTelemetryFieldKeyDTO {
|
||||
unit?: string;
|
||||
}
|
||||
|
||||
export enum Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregationDTOSignal {
|
||||
logs = 'logs',
|
||||
}
|
||||
export enum TelemetrytypesSourceDTO {
|
||||
meter = 'meter',
|
||||
}
|
||||
@@ -3548,7 +3540,11 @@ export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTyp
|
||||
* @type array
|
||||
*/
|
||||
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
|
||||
signal?: TelemetrytypesSignalDTO;
|
||||
/**
|
||||
* @enum logs
|
||||
* @type string
|
||||
*/
|
||||
signal: Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregationDTOSignal;
|
||||
source?: TelemetrytypesSourceDTO;
|
||||
stepInterval?: Querybuildertypesv5StepDTO;
|
||||
}
|
||||
@@ -3614,6 +3610,9 @@ export interface Querybuildertypesv5MetricAggregationDTO {
|
||||
timeAggregation?: MetrictypesTimeAggregationDTO;
|
||||
}
|
||||
|
||||
export enum Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregationDTOSignal {
|
||||
metrics = 'metrics',
|
||||
}
|
||||
export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregationDTO {
|
||||
/**
|
||||
* @type array
|
||||
@@ -3666,7 +3665,11 @@ export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTyp
|
||||
* @type array
|
||||
*/
|
||||
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
|
||||
signal?: TelemetrytypesSignalDTO;
|
||||
/**
|
||||
* @enum metrics
|
||||
* @type string
|
||||
*/
|
||||
signal: Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregationDTOSignal;
|
||||
source?: TelemetrytypesSourceDTO;
|
||||
stepInterval?: Querybuildertypesv5StepDTO;
|
||||
}
|
||||
@@ -3682,6 +3685,9 @@ export interface Querybuildertypesv5TraceAggregationDTO {
|
||||
expression?: string;
|
||||
}
|
||||
|
||||
export enum Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregationDTOSignal {
|
||||
traces = 'traces',
|
||||
}
|
||||
export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregationDTO {
|
||||
/**
|
||||
* @type array
|
||||
@@ -3734,7 +3740,11 @@ export interface Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTyp
|
||||
* @type array
|
||||
*/
|
||||
selectFields?: TelemetrytypesTelemetryFieldKeyDTO[];
|
||||
signal?: TelemetrytypesSignalDTO;
|
||||
/**
|
||||
* @enum traces
|
||||
* @type string
|
||||
*/
|
||||
signal: Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregationDTOSignal;
|
||||
source?: TelemetrytypesSourceDTO;
|
||||
stepInterval?: Querybuildertypesv5StepDTO;
|
||||
}
|
||||
@@ -3869,6 +3879,17 @@ 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',
|
||||
}
|
||||
@@ -4417,42 +4438,36 @@ 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?: DashboardPanelDisplayDTO;
|
||||
display: DashboardtypesDisplayDTO;
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
links?: DashboardLinkDTO[];
|
||||
plugin?: DashboardtypesPanelPluginDTO;
|
||||
plugin: DashboardtypesPanelPluginDTO;
|
||||
/**
|
||||
* @type array
|
||||
* @type array,null
|
||||
*/
|
||||
queries?: DashboardtypesQueryDTO[];
|
||||
queries: DashboardtypesQueryDTO[] | null;
|
||||
}
|
||||
|
||||
export interface DashboardtypesPanelDTO {
|
||||
kind?: DashboardtypesPanelKindDTO;
|
||||
spec?: DashboardtypesPanelSpecDTO;
|
||||
kind: DashboardtypesPanelKindDTO;
|
||||
spec: DashboardtypesPanelSpecDTO;
|
||||
}
|
||||
|
||||
export type DashboardtypesDashboardSpecDTOPanelsAnyOf = {
|
||||
export type DashboardtypesDashboardSpecDTOPanels = {
|
||||
[key: string]: DashboardtypesPanelDTO;
|
||||
};
|
||||
|
||||
/**
|
||||
* @nullable
|
||||
*/
|
||||
export type DashboardtypesDashboardSpecDTOPanels =
|
||||
DashboardtypesDashboardSpecDTOPanelsAnyOf | null;
|
||||
|
||||
export enum DashboardtypesLayoutEnvelopeGithubComPersesSpecGoDashboardGridLayoutSpecDTOKind {
|
||||
Grid = 'Grid',
|
||||
}
|
||||
@@ -4549,7 +4564,7 @@ export interface DashboardtypesListVariableSpecDTO {
|
||||
*/
|
||||
customAllValue?: string;
|
||||
defaultValue?: VariableDefaultValueDTO;
|
||||
display?: VariableDisplayDTO;
|
||||
display: DashboardtypesDisplayDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -4591,23 +4606,23 @@ export interface DashboardtypesDashboardSpecDTO {
|
||||
* @type object
|
||||
*/
|
||||
datasources?: DashboardtypesDashboardSpecDTODatasources;
|
||||
display?: CommonDisplayDTO;
|
||||
display: DashboardtypesDisplayDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
duration?: string;
|
||||
/**
|
||||
* @type array,null
|
||||
* @type array
|
||||
*/
|
||||
layouts?: DashboardtypesLayoutDTO[] | null;
|
||||
layouts: DashboardtypesLayoutDTO[];
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
links?: DashboardLinkDTO[];
|
||||
/**
|
||||
* @type object,null
|
||||
* @type object
|
||||
*/
|
||||
panels?: DashboardtypesDashboardSpecDTOPanels;
|
||||
panels: DashboardtypesDashboardSpecDTOPanels;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -4615,13 +4630,13 @@ export interface DashboardtypesDashboardSpecDTO {
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
variables?: DashboardtypesVariableDTO[];
|
||||
variables: DashboardtypesVariableDTO[];
|
||||
}
|
||||
|
||||
export enum DashboardtypesDatasourcePluginKindDTO {
|
||||
'signoz/Datasource' = 'signoz/Datasource',
|
||||
}
|
||||
export interface TagtypesPostableTagDTO {
|
||||
export interface TagtypesGettableTagDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -4671,7 +4686,7 @@ export interface DashboardtypesGettableDashboardV2DTO {
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
tags: TagtypesPostableTagDTO[] | null;
|
||||
tags: TagtypesGettableTagDTO[] | null;
|
||||
/**
|
||||
* @type string
|
||||
* @format date-time
|
||||
@@ -4729,6 +4744,157 @@ export interface DashboardtypesJSONPatchOperationDTO {
|
||||
value?: unknown;
|
||||
}
|
||||
|
||||
export enum DashboardtypesListOrderDTO {
|
||||
asc = 'asc',
|
||||
desc = 'desc',
|
||||
}
|
||||
export enum DashboardtypesListSortDTO {
|
||||
updated_at = 'updated_at',
|
||||
created_at = 'created_at',
|
||||
name = 'name',
|
||||
}
|
||||
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 enum DashboardtypesPanelPluginKindDTO {
|
||||
'signoz/TimeSeriesPanel' = 'signoz/TimeSeriesPanel',
|
||||
'signoz/BarChartPanel' = 'signoz/BarChartPanel',
|
||||
@@ -4745,6 +4911,17 @@ export type DashboardtypesPatchableDashboardV2DTO =
|
||||
| DashboardtypesJSONPatchOperationDTO[]
|
||||
| null;
|
||||
|
||||
export interface TagtypesPostableTagDTO {
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface DashboardtypesPostableDashboardV2DTO {
|
||||
/**
|
||||
* @type boolean
|
||||
@@ -8093,10 +8270,6 @@ export interface SpantypesWaterfallSpanDTO {
|
||||
}
|
||||
|
||||
export interface SpantypesGettableWaterfallTraceDTO {
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
aggregations?: SpantypesSpanAggregationResultDTO[] | null;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
@@ -8216,15 +8389,6 @@ export interface SpantypesPostableTraceAggregationsDTO {
|
||||
}
|
||||
|
||||
export interface SpantypesPostableWaterfallDTO {
|
||||
/**
|
||||
* @type array,null
|
||||
*/
|
||||
aggregations?: SpantypesSpanAggregationDTO[] | null;
|
||||
/**
|
||||
* @type integer
|
||||
* @minimum 0
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
@@ -9580,6 +9744,19 @@ export type UpdateSpanMapperPathParameters = {
|
||||
groupId: string;
|
||||
mapperId: string;
|
||||
};
|
||||
export type GetStats200Data = { [key: string]: unknown };
|
||||
|
||||
export type GetStats200 = {
|
||||
/**
|
||||
* @type object
|
||||
*/
|
||||
data: GetStats200Data;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetTraceAggregationsPathParameters = {
|
||||
traceID: string;
|
||||
};
|
||||
@@ -9660,6 +9837,40 @@ export type GetUserPreference200 = {
|
||||
export type UpdateUserPreferencePathParameters = {
|
||||
name: 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;
|
||||
/**
|
||||
@@ -9668,6 +9879,9 @@ export type CreateDashboardV2201 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type DeleteDashboardV2PathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type GetDashboardV2PathParameters = {
|
||||
id: string;
|
||||
};
|
||||
@@ -9701,6 +9915,17 @@ export type UpdateDashboardV2200 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type CloneDashboardV2PathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type CloneDashboardV2201 = {
|
||||
data: DashboardtypesGettableDashboardV2DTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type UnlockDashboardV2PathParameters = {
|
||||
id: string;
|
||||
};
|
||||
@@ -10500,6 +10725,46 @@ 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;
|
||||
/**
|
||||
@@ -10519,17 +10784,6 @@ export type GetFlamegraph200 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetWaterfallPathParameters = {
|
||||
traceID: string;
|
||||
};
|
||||
export type GetWaterfall200 = {
|
||||
data: SpantypesGettableWaterfallTraceDTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type GetWaterfallV4PathParameters = {
|
||||
traceID: string;
|
||||
};
|
||||
|
||||
96
frontend/src/api/generated/services/stats/index.ts
Normal file
96
frontend/src/api/generated/services/stats/index.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* ! 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;
|
||||
};
|
||||
@@ -16,8 +16,6 @@ import type {
|
||||
GetFlamegraphPathParameters,
|
||||
GetTraceAggregations200,
|
||||
GetTraceAggregationsPathParameters,
|
||||
GetWaterfall200,
|
||||
GetWaterfallPathParameters,
|
||||
GetWaterfallV4200,
|
||||
GetWaterfallV4PathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
@@ -228,105 +226,6 @@ export const useGetFlamegraph = <
|
||||
> => {
|
||||
return useMutation(getGetFlamegraphMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* 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 getWaterfall = (
|
||||
{ traceID }: GetWaterfallPathParameters,
|
||||
spantypesPostableWaterfallDTO?: BodyType<SpantypesPostableWaterfallDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetWaterfall200>({
|
||||
url: `/api/v3/traces/${traceID}/waterfall`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: spantypesPostableWaterfallDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetWaterfallMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof getWaterfall>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: GetWaterfallPathParameters;
|
||||
data?: BodyType<SpantypesPostableWaterfallDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof getWaterfall>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: GetWaterfallPathParameters;
|
||||
data?: BodyType<SpantypesPostableWaterfallDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['getWaterfall'];
|
||||
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 getWaterfall>>,
|
||||
{
|
||||
pathParams: GetWaterfallPathParameters;
|
||||
data?: BodyType<SpantypesPostableWaterfallDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
|
||||
return getWaterfall(pathParams, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type GetWaterfallMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getWaterfall>>
|
||||
>;
|
||||
export type GetWaterfallMutationBody =
|
||||
| BodyType<SpantypesPostableWaterfallDTO>
|
||||
| undefined;
|
||||
export type GetWaterfallMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get waterfall view for a trace
|
||||
*/
|
||||
export const useGetWaterfall = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof getWaterfall>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: GetWaterfallPathParameters;
|
||||
data?: BodyType<SpantypesPostableWaterfallDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof getWaterfall>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: GetWaterfallPathParameters;
|
||||
data?: BodyType<SpantypesPostableWaterfallDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
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
|
||||
* @summary Get waterfall view for a trace
|
||||
|
||||
@@ -5,6 +5,13 @@ 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>> => {
|
||||
|
||||
@@ -5,6 +5,13 @@ 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>> => {
|
||||
|
||||
@@ -15,6 +15,13 @@ 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<
|
||||
|
||||
@@ -8,6 +8,13 @@ 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<
|
||||
|
||||
@@ -20,6 +20,13 @@ 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>,
|
||||
|
||||
@@ -15,6 +15,13 @@ 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,
|
||||
|
||||
@@ -27,7 +27,6 @@ const getTraceV4 = async (
|
||||
{
|
||||
selectedSpanId: props.selectedSpanId,
|
||||
uncollapsedSpans,
|
||||
limit: 10000,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -5,6 +5,13 @@ 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[]>
|
||||
> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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}`, {
|
||||
|
||||
@@ -5,6 +5,13 @@ 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`);
|
||||
|
||||
@@ -5,6 +5,13 @@ 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>> => {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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}`, {
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>> => {
|
||||
|
||||
@@ -3,6 +3,13 @@ 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');
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>>(
|
||||
|
||||
@@ -4,6 +4,13 @@ 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>>(
|
||||
|
||||
@@ -8,6 +8,13 @@ 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,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// 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;
|
||||
@@ -117,7 +123,23 @@
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
font-family: 'Space Mono', monospace !important;
|
||||
min-height: 200px !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;
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.3rem;
|
||||
@@ -133,6 +155,19 @@
|
||||
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;
|
||||
@@ -159,11 +194,78 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,15 @@ import {
|
||||
import { validateQuery } from 'utils/queryValidationUtils';
|
||||
import { unquote } from 'utils/stringUtils';
|
||||
|
||||
import { queryExamples } from './constants';
|
||||
import { combineInitialAndUserExpression } from './utils';
|
||||
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 './QuerySearch.styles.scss';
|
||||
|
||||
@@ -1250,6 +1257,41 @@ 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);
|
||||
@@ -1398,11 +1440,12 @@ function QuerySearch({
|
||||
})}
|
||||
extensions={[
|
||||
autocompletion({
|
||||
override: [autoSuggestions],
|
||||
override: [combinedSuggestions],
|
||||
defaultKeymap: true,
|
||||
closeOnBlur: true,
|
||||
activateOnTyping: true,
|
||||
maxRenderedOptions: 50,
|
||||
addToOptions: [{ render: renderRecentDeleteButton, position: 100 }],
|
||||
}),
|
||||
javascript({ jsx: false, typescript: false }),
|
||||
EditorView.lineWrapping,
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
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',
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
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,
|
||||
@@ -38,3 +54,106 @@ 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;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ export const REACT_QUERY_KEY = {
|
||||
GET_TRACE_V4_WATERFALL: 'GET_TRACE_V4_WATERFALL',
|
||||
GET_TRACE_AGGREGATIONS: 'GET_TRACE_AGGREGATIONS',
|
||||
GET_TRACE_V2_FLAMEGRAPH: 'GET_TRACE_V2_FLAMEGRAPH',
|
||||
GET_TRACE_V3_FLAMEGRAPH: 'GET_TRACE_V3_FLAMEGRAPH',
|
||||
GET_POD_LIST: 'GET_POD_LIST',
|
||||
GET_NODE_LIST: 'GET_NODE_LIST',
|
||||
GET_DEPLOYMENT_LIST: 'GET_DEPLOYMENT_LIST',
|
||||
|
||||
@@ -70,6 +70,7 @@ export const AIAssistantOpenSource = {
|
||||
Icon: 'icon',
|
||||
Shortcut: 'shortcut',
|
||||
Cmdk: 'cmdk',
|
||||
TraceDetails: 'trace_details',
|
||||
} as const;
|
||||
export type AIAssistantOpenSource =
|
||||
(typeof AIAssistantOpenSource)[keyof typeof AIAssistantOpenSource];
|
||||
|
||||
@@ -40,13 +40,31 @@ type SpeechRecognitionConstructor = new () => ISpeechRecognition;
|
||||
|
||||
// ── Vendor-prefix shim for Safari / older browsers ────────────────────────────
|
||||
|
||||
const SpeechRecognitionAPI: SpeechRecognitionConstructor | null =
|
||||
typeof window !== 'undefined'
|
||||
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
((window as any).SpeechRecognition ??
|
||||
// Some hardened/enterprise browsers install a getter
|
||||
// on window.SpeechRecognition that THROWS on access ("Web Speech API is disabled
|
||||
// due to your security policy") instead of leaving the property undefined.
|
||||
// Because this resolves at module-evaluation time, an uncaught throw here aborts
|
||||
// the entire bundle and the app renders a blank page. Read defensively so a
|
||||
// throwing getter degrades to "unsupported" rather than crashing the app.
|
||||
function resolveSpeechRecognitionAPI(): SpeechRecognitionConstructor | null {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).SpeechRecognition ??
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any).webkitSpeechRecognition ??
|
||||
null)
|
||||
: null;
|
||||
null
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const SpeechRecognitionAPI: SpeechRecognitionConstructor | null =
|
||||
resolveSpeechRecognitionAPI();
|
||||
|
||||
export type SpeechRecognitionError =
|
||||
| 'not-supported'
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
.billingContainer {
|
||||
margin-bottom: var(--spacing-20);
|
||||
padding-top: 36px;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
margin: 0 auto var(--spacing-20);
|
||||
|
||||
.pageHeader {
|
||||
margin-bottom: var(--spacing-8);
|
||||
|
||||
@@ -67,3 +67,40 @@
|
||||
background: var(--secondary-background);
|
||||
border: 1px solid var(--l1-border);
|
||||
}
|
||||
|
||||
.fallbackBody {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-4);
|
||||
}
|
||||
|
||||
.fallbackHint {
|
||||
font-size: var(--paragraph-base-400-font-size);
|
||||
font-weight: var(--paragraph-base-400-font-weight);
|
||||
line-height: var(--paragraph-base-400-line-height);
|
||||
color: var(--l2-foreground);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.fallbackEmail {
|
||||
font-size: var(--paragraph-base-500-font-size);
|
||||
font-weight: var(--paragraph-base-500-font-weight);
|
||||
color: var(--l1-foreground);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.fallbackActions {
|
||||
display: flex;
|
||||
gap: var(--spacing-3);
|
||||
flex-wrap: wrap;
|
||||
padding-top: var(--padding-4);
|
||||
}
|
||||
|
||||
.retryLink {
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,37 @@ jest.mock('utils/basePath', () => ({
|
||||
getBaseUrl: (): string => 'https://test.signoz.io',
|
||||
}));
|
||||
|
||||
function mockMailto(): {
|
||||
mockClick: jest.Mock;
|
||||
appendSpy: jest.SpyInstance;
|
||||
removeSpy: jest.SpyInstance;
|
||||
} {
|
||||
const mockClick = jest.fn();
|
||||
const realCreateElement = document.createElement.bind(document);
|
||||
|
||||
// Create a real anchor so JSDOM's appendChild/removeChild accept it.
|
||||
// Override its click() so no navigation occurs.
|
||||
jest
|
||||
.spyOn(document, 'createElement')
|
||||
.mockImplementation((tag: string, options?: ElementCreationOptions) => {
|
||||
if (tag === 'a') {
|
||||
const anchor = realCreateElement('a') as HTMLAnchorElement;
|
||||
anchor.click = mockClick;
|
||||
return anchor;
|
||||
}
|
||||
return realCreateElement(tag, options);
|
||||
});
|
||||
|
||||
const appendSpy = jest.spyOn(document.body, 'appendChild');
|
||||
const removeSpy = jest.spyOn(document.body, 'removeChild');
|
||||
return { mockClick, appendSpy, removeSpy };
|
||||
}
|
||||
|
||||
describe('CancelSubscriptionBanner', () => {
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('renders banner with title and subtitle', () => {
|
||||
render(<CancelSubscriptionBanner />);
|
||||
expect(
|
||||
@@ -35,12 +65,10 @@ describe('CancelSubscriptionBanner', () => {
|
||||
screen.getByText(/Cancelling your subscription would stop your data/i),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/Type/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByPlaceholderText(/Enter the word cancel/i),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByTestId('cancel-confirm-input')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /go back/i })).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
screen.getByTestId('cancel-subscription-confirm-btn'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -52,12 +80,10 @@ describe('CancelSubscriptionBanner', () => {
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
|
||||
const confirmButton = screen.getByRole('button', {
|
||||
name: /cancel subscription/i,
|
||||
});
|
||||
const confirmButton = screen.getByTestId('cancel-subscription-confirm-btn');
|
||||
expect(confirmButton).toBeDisabled();
|
||||
|
||||
const input = screen.getByPlaceholderText(/Enter the word cancel/i);
|
||||
const input = screen.getByTestId('cancel-confirm-input');
|
||||
await user.type(input, 'canc');
|
||||
expect(confirmButton).toBeDisabled();
|
||||
|
||||
@@ -73,7 +99,7 @@ describe('CancelSubscriptionBanner', () => {
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
|
||||
const input = screen.getByPlaceholderText(/Enter the word cancel/i);
|
||||
const input = screen.getByTestId('cancel-confirm-input');
|
||||
await user.type(input, 'cancel');
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /go back/i }));
|
||||
@@ -84,19 +110,11 @@ describe('CancelSubscriptionBanner', () => {
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
expect(screen.getByPlaceholderText(/Enter the word cancel/i)).toHaveValue('');
|
||||
expect(screen.getByTestId('cancel-confirm-input')).toHaveValue('');
|
||||
});
|
||||
|
||||
it('sends mailto to cloud-support with correct subject after typing "cancel"', async () => {
|
||||
const realCreateElement = document.createElement.bind(document);
|
||||
const mockClick = jest.fn();
|
||||
const mockAnchor = { href: '', click: mockClick };
|
||||
jest.spyOn(document, 'createElement').mockImplementation((tag: string) => {
|
||||
if (tag === 'a') {
|
||||
return mockAnchor as unknown as HTMLAnchorElement;
|
||||
}
|
||||
return realCreateElement(tag);
|
||||
});
|
||||
it('fires mailto via DOM-attached anchor and shows fallback view after confirming', async () => {
|
||||
const { mockClick, appendSpy, removeSpy } = mockMailto();
|
||||
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<CancelSubscriptionBanner />);
|
||||
@@ -104,18 +122,85 @@ describe('CancelSubscriptionBanner', () => {
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
await user.type(screen.getByTestId('cancel-confirm-input'), 'cancel');
|
||||
await user.click(screen.getByTestId('cancel-subscription-confirm-btn'));
|
||||
|
||||
const input = screen.getByPlaceholderText(/Enter the word cancel/i);
|
||||
await user.type(input, 'cancel');
|
||||
const appendedAnchor = appendSpy.mock.calls
|
||||
.map(([node]) => node)
|
||||
.find(
|
||||
(node): node is HTMLAnchorElement =>
|
||||
node instanceof HTMLAnchorElement && node.href.startsWith('mailto:'),
|
||||
);
|
||||
expect(appendedAnchor).toBeDefined();
|
||||
expect(mockClick).toHaveBeenCalledTimes(1);
|
||||
expect(removeSpy.mock.calls.some(([node]) => node === appendedAnchor)).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText(/An email draft has been opened/i),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText('cloud-support@signoz.io')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('copy-email-template-btn')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('retry-mailto-btn')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('copies email template to clipboard when Copy button is clicked', async () => {
|
||||
mockMailto();
|
||||
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<CancelSubscriptionBanner />);
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
await user.type(screen.getByTestId('cancel-confirm-input'), 'cancel');
|
||||
await user.click(screen.getByTestId('cancel-subscription-confirm-btn'));
|
||||
|
||||
expect(mockAnchor.href).toContain('mailto:cloud-support@signoz.io');
|
||||
expect(mockAnchor.href).toContain('Cancel%20My%20SigNoz%20Subscription');
|
||||
expect(mockClick).toHaveBeenCalledTimes(1);
|
||||
await user.click(screen.getByTestId('copy-email-template-btn'));
|
||||
|
||||
jest.restoreAllMocks();
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId('copy-email-template-btn')).toHaveTextContent(
|
||||
'Copied!',
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('retry link is a native anchor with correct mailto href in fallback view', async () => {
|
||||
mockMailto();
|
||||
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<CancelSubscriptionBanner />);
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
await user.type(screen.getByTestId('cancel-confirm-input'), 'cancel');
|
||||
await user.click(screen.getByTestId('cancel-subscription-confirm-btn'));
|
||||
|
||||
const retryLink = screen.getByTestId('retry-mailto-btn');
|
||||
expect(retryLink.tagName).toBe('A');
|
||||
expect(retryLink).toHaveAttribute(
|
||||
'href',
|
||||
expect.stringContaining('mailto:cloud-support@signoz.io'),
|
||||
);
|
||||
});
|
||||
|
||||
it('closes fallback view when Close is clicked and resets state', async () => {
|
||||
mockMailto();
|
||||
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
render(<CancelSubscriptionBanner />);
|
||||
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /cancel subscription/i }),
|
||||
);
|
||||
await user.type(screen.getByTestId('cancel-confirm-input'), 'cancel');
|
||||
await user.click(screen.getByTestId('cancel-subscription-confirm-btn'));
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /close/i }));
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,27 +1,100 @@
|
||||
import { useState } from 'react';
|
||||
import { SolidInfoCircle, Undo2, X } from '@signozhq/icons';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
CircleCheck,
|
||||
Copy,
|
||||
MailOpen,
|
||||
SolidInfoCircle,
|
||||
Undo2,
|
||||
X,
|
||||
} from '@signozhq/icons';
|
||||
import { Button } from '@signozhq/ui/button';
|
||||
import { DialogWrapper } from '@signozhq/ui/dialog';
|
||||
import { Input } from '@signozhq/ui/input';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { pick } from 'lodash-es';
|
||||
import { useAppContext } from 'providers/App/App';
|
||||
import { useCopyToClipboard } from 'react-use';
|
||||
import { getBaseUrl } from 'utils/basePath';
|
||||
|
||||
import styles from './CancelSubscriptionBanner.module.scss';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
|
||||
import styles from './CancelSubscriptionBanner.module.scss';
|
||||
|
||||
const SUPPORT_EMAIL = 'cloud-support@signoz.io';
|
||||
const MAX_MAILTO_URI_LENGTH = 1800;
|
||||
|
||||
type DialogView = 'confirm' | 'fallback';
|
||||
|
||||
function buildEmailBody(orgName: string, userEmail: string): string {
|
||||
return [
|
||||
'Hi SigNoz Team,',
|
||||
'',
|
||||
'I would like to cancel my SigNoz Cloud subscription.',
|
||||
'Please find my account details below.',
|
||||
'',
|
||||
'Account Details:',
|
||||
` • SigNoz URL: ${getBaseUrl()}`,
|
||||
...(orgName ? [` • Organization: ${orgName}`] : []),
|
||||
` • Account Email: ${userEmail}`,
|
||||
'',
|
||||
'Reason for Cancellation:',
|
||||
'[Please share the reason for cancellation]',
|
||||
'',
|
||||
'Additional feedback (optional):',
|
||||
'[Any other feedback]',
|
||||
'',
|
||||
'Regards,',
|
||||
'[user name or team name]',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
function buildMailtoUri(orgName: string, userEmail: string): string {
|
||||
const subject = encodeURIComponent('Cancel My SigNoz Subscription');
|
||||
const body = encodeURIComponent(buildEmailBody(orgName, userEmail));
|
||||
const full = `mailto:${SUPPORT_EMAIL}?subject=${subject}&body=${body}`;
|
||||
if (full.length <= MAX_MAILTO_URI_LENGTH) {
|
||||
return full;
|
||||
}
|
||||
const shortBody = encodeURIComponent(
|
||||
'Hi SigNoz Team,\n\nI would like to cancel my SigNoz Cloud subscription.\nPlease find my account details and reason for cancellation below.\n\n[Your details here]\n\nRegards,',
|
||||
);
|
||||
return `mailto:${SUPPORT_EMAIL}?subject=${subject}&body=${shortBody}`;
|
||||
}
|
||||
|
||||
function openMailto(uri: string): void {
|
||||
const link = document.createElement('a');
|
||||
link.href = uri;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
function CancelSubscriptionBanner(): JSX.Element {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [dialogView, setDialogView] = useState<DialogView | null>(null);
|
||||
const [confirmText, setConfirmText] = useState('');
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [, copyToClipboard] = useCopyToClipboard();
|
||||
const copyTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const { user, org } = useAppContext();
|
||||
|
||||
useEffect(
|
||||
() => (): void => {
|
||||
if (copyTimerRef.current) {
|
||||
clearTimeout(copyTimerRef.current);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const orgName = org?.[0]?.displayName ?? '';
|
||||
const userEmail = user?.email ?? '';
|
||||
|
||||
const handleOpenCancelDialog = (): void => {
|
||||
void logEvent('Billing : Cancel Subscription Clicked', {
|
||||
user: pick(user, ['email', 'displayName', 'role', 'organization']),
|
||||
role: user?.role,
|
||||
});
|
||||
setOpen(true);
|
||||
setDialogView('confirm');
|
||||
};
|
||||
|
||||
const handleContactSupport = (): void => {
|
||||
@@ -29,43 +102,41 @@ function CancelSubscriptionBanner(): JSX.Element {
|
||||
user: pick(user, ['email', 'displayName', 'role', 'organization']),
|
||||
role: user?.role,
|
||||
});
|
||||
const subject = encodeURIComponent('Cancel My SigNoz Subscription');
|
||||
const orgName = org?.[0]?.displayName ?? '';
|
||||
const body = encodeURIComponent(
|
||||
[
|
||||
'Hi SigNoz Team,',
|
||||
'',
|
||||
'I would like to cancel my SigNoz Cloud subscription.',
|
||||
'Please find my account details below.',
|
||||
'',
|
||||
'Account Details:',
|
||||
` • SigNoz URL: ${getBaseUrl()}`,
|
||||
...(orgName ? [` • Organization: ${orgName}`] : []),
|
||||
` • Account Email: ${user?.email ?? ''}`,
|
||||
'',
|
||||
'Reason for Cancellation:',
|
||||
'[Please share the reason for cancellation]',
|
||||
'',
|
||||
'Additional feedback (optional):',
|
||||
'[Any other feedback]',
|
||||
'',
|
||||
'Regards,',
|
||||
'[user name or team name]',
|
||||
].join('\n'),
|
||||
);
|
||||
const link = document.createElement('a');
|
||||
link.href = `mailto:cloud-support@signoz.io?subject=${subject}&body=${body}`;
|
||||
link.click();
|
||||
setOpen(false);
|
||||
openMailto(buildMailtoUri(orgName, userEmail));
|
||||
setConfirmText('');
|
||||
setDialogView('fallback');
|
||||
};
|
||||
|
||||
const handleCopyTemplate = (): void => {
|
||||
void logEvent('Billing : Cancel Subscription Email Template Copied', {
|
||||
user: pick(user, ['email', 'displayName', 'role', 'organization']),
|
||||
role: user?.role,
|
||||
});
|
||||
copyToClipboard(buildEmailBody(orgName, userEmail));
|
||||
setCopied(true);
|
||||
if (copyTimerRef.current) {
|
||||
clearTimeout(copyTimerRef.current);
|
||||
}
|
||||
copyTimerRef.current = setTimeout(() => setCopied(false), 2000);
|
||||
};
|
||||
|
||||
const handleRetryMailto = (): void => {
|
||||
void logEvent('Billing : Cancel Subscription Email Client Reopened', {
|
||||
user: pick(user, ['email', 'displayName', 'role', 'organization']),
|
||||
role: user?.role,
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = (): void => {
|
||||
setOpen(false);
|
||||
if (copyTimerRef.current) {
|
||||
clearTimeout(copyTimerRef.current);
|
||||
}
|
||||
setDialogView(null);
|
||||
setConfirmText('');
|
||||
setCopied(false);
|
||||
};
|
||||
|
||||
const footer = (
|
||||
const confirmFooter = (
|
||||
<>
|
||||
<Button
|
||||
variant="solid"
|
||||
@@ -81,12 +152,19 @@ function CancelSubscriptionBanner(): JSX.Element {
|
||||
prefix={<X size={14} />}
|
||||
disabled={confirmText !== 'cancel'}
|
||||
onClick={handleContactSupport}
|
||||
data-testid="cancel-subscription-confirm-btn"
|
||||
>
|
||||
Cancel subscription
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
|
||||
const fallbackFooter = (
|
||||
<Button variant="solid" color="secondary" onClick={handleClose}>
|
||||
Close
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.banner}>
|
||||
@@ -111,27 +189,67 @@ function CancelSubscriptionBanner(): JSX.Element {
|
||||
</Button>
|
||||
</div>
|
||||
<DialogWrapper
|
||||
open={open}
|
||||
open={dialogView !== null}
|
||||
onOpenChange={handleClose}
|
||||
title="Cancel your subscription?"
|
||||
width="narrow"
|
||||
showCloseButton={false}
|
||||
footer={footer}
|
||||
footer={dialogView === 'confirm' ? confirmFooter : fallbackFooter}
|
||||
>
|
||||
<div className={styles.dialogBody}>
|
||||
<p className={styles.dialogDescription}>
|
||||
Cancelling your subscription would stop your data from being ingested to
|
||||
SigNoz. All the data that has been already sent will also be deleted.
|
||||
</p>
|
||||
<p className={styles.dialogConfirmLabel}>
|
||||
Type <code>cancel</code> to confirm the cancellation.
|
||||
</p>
|
||||
<Input
|
||||
placeholder="Enter the word cancel..."
|
||||
value={confirmText}
|
||||
onChange={(e): void => setConfirmText(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
{dialogView === 'confirm' && (
|
||||
<div className={styles.dialogBody}>
|
||||
<p className={styles.dialogDescription}>
|
||||
Cancelling your subscription would stop your data from being ingested to
|
||||
SigNoz. All the data that has been already sent will also be deleted.
|
||||
</p>
|
||||
<p className={styles.dialogConfirmLabel}>
|
||||
Type <code>cancel</code> to confirm the cancellation.
|
||||
</p>
|
||||
<Input
|
||||
placeholder="Enter the word cancel..."
|
||||
value={confirmText}
|
||||
onChange={(e): void => setConfirmText(e.target.value)}
|
||||
data-testid="cancel-confirm-input"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{dialogView === 'fallback' && (
|
||||
<div className={styles.fallbackBody}>
|
||||
<p className={styles.fallbackHint}>
|
||||
An email draft has been opened. If it did not open, send your
|
||||
cancellation request directly to:
|
||||
</p>
|
||||
<span className={styles.fallbackEmail}>{SUPPORT_EMAIL}</span>
|
||||
<div className={styles.fallbackActions}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
prefix={copied ? <CircleCheck size={14} /> : <Copy size={14} />}
|
||||
onClick={handleCopyTemplate}
|
||||
data-testid="copy-email-template-btn"
|
||||
>
|
||||
{copied ? 'Copied!' : 'Copy email template'}
|
||||
</Button>
|
||||
<Button
|
||||
asChild
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
data-testid="retry-mailto-btn"
|
||||
>
|
||||
<a
|
||||
href={buildMailtoUri(orgName, userEmail)}
|
||||
onClick={handleRetryMailto}
|
||||
className={styles.retryLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<MailOpen size={14} />
|
||||
Reopen email client
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</DialogWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.license-key-callout {
|
||||
margin: var(--spacing-4) var(--spacing-6);
|
||||
width: auto;
|
||||
width: auto !important;
|
||||
|
||||
.license-key-callout__description {
|
||||
display: flex;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { useQueries } from 'react-query';
|
||||
import { render, screen } from 'tests/test-utils';
|
||||
|
||||
import GeneralSettings from '../index';
|
||||
|
||||
jest.mock('react-query', () => ({
|
||||
...jest.requireActual('react-query'),
|
||||
useQueries: jest.fn(),
|
||||
}));
|
||||
|
||||
const baseQueryResult = {
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
isFetching: false,
|
||||
isSuccess: true,
|
||||
data: undefined,
|
||||
error: null,
|
||||
refetch: jest.fn(),
|
||||
};
|
||||
|
||||
describe('GeneralSettings index', () => {
|
||||
it('renders fallback message when logs query fails with a non-APIError', () => {
|
||||
(useQueries as jest.Mock).mockReturnValue([
|
||||
{ ...baseQueryResult },
|
||||
{ ...baseQueryResult },
|
||||
{
|
||||
...baseQueryResult,
|
||||
isError: true,
|
||||
isSuccess: false,
|
||||
error: new TypeError(
|
||||
"Cannot read properties of undefined (reading 'code')",
|
||||
),
|
||||
},
|
||||
{ ...baseQueryResult },
|
||||
]);
|
||||
|
||||
render(<GeneralSettings />);
|
||||
|
||||
expect(screen.getByText('something_went_wrong')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -76,7 +76,9 @@ function GeneralSettings(): JSX.Element {
|
||||
if (getRetentionPeriodLogsApiResponse.isError || getDisksResponse.isError) {
|
||||
return (
|
||||
<Typography>
|
||||
{(getRetentionPeriodLogsApiResponse.error as APIError).getErrorMessage() ||
|
||||
{(getRetentionPeriodLogsApiResponse.error instanceof APIError
|
||||
? getRetentionPeriodLogsApiResponse.error.getErrorMessage()
|
||||
: undefined) ||
|
||||
getDisksResponse.data?.error ||
|
||||
t('something_went_wrong')}
|
||||
</Typography>
|
||||
|
||||
@@ -796,7 +796,7 @@ export const getClusterMetricsQueryPayload = (
|
||||
key: k8sDeploymentDesiredKey,
|
||||
type: 'Gauge',
|
||||
},
|
||||
aggregateOperator: 'avg',
|
||||
aggregateOperator: 'latest',
|
||||
dataSource: DataSource.METRICS,
|
||||
disabled: false,
|
||||
expression: 'B',
|
||||
@@ -839,7 +839,7 @@ export const getClusterMetricsQueryPayload = (
|
||||
reduceTo: ReduceOperators.LAST,
|
||||
spaceAggregation: 'sum',
|
||||
stepInterval: 60,
|
||||
timeAggregation: 'avg',
|
||||
timeAggregation: 'latest',
|
||||
},
|
||||
],
|
||||
queryFormulas: [],
|
||||
|
||||
@@ -40,6 +40,7 @@ import { K8S_ENTITY_EVENTS_EXPRESSION_KEY, useEntityEvents } from './hooks';
|
||||
import { getEntityEventsQueryPayload, isEventsKeyNotFoundError } from './utils';
|
||||
|
||||
import styles from './EntityEvents.module.scss';
|
||||
import { useTimezone } from 'providers/Timezone';
|
||||
|
||||
interface EventDataType {
|
||||
key: string;
|
||||
@@ -167,17 +168,25 @@ function EntityEventsContent({
|
||||
[events],
|
||||
);
|
||||
|
||||
const columns: TableColumnsType<EventDataType> = [
|
||||
{ title: 'Severity', dataIndex: 'severity', key: 'severity', width: 100 },
|
||||
{
|
||||
title: 'Timestamp',
|
||||
dataIndex: 'timestamp',
|
||||
width: 240,
|
||||
ellipsis: true,
|
||||
key: 'timestamp',
|
||||
},
|
||||
{ title: 'Body', dataIndex: 'body', key: 'body' },
|
||||
];
|
||||
const { formatTimezoneAdjustedTimestamp } = useTimezone();
|
||||
const columns: TableColumnsType<EventDataType> = useMemo(
|
||||
() => [
|
||||
{ title: 'Severity', dataIndex: 'severity', key: 'severity', width: 100 },
|
||||
{
|
||||
title: 'Timestamp',
|
||||
dataIndex: 'timestamp',
|
||||
width: 240,
|
||||
ellipsis: true,
|
||||
key: 'timestamp',
|
||||
render: (value: string | number): string =>
|
||||
formatTimezoneAdjustedTimestamp(
|
||||
typeof value === 'string' ? value : value / 1e6,
|
||||
),
|
||||
},
|
||||
{ title: 'Body', dataIndex: 'body', key: 'body' },
|
||||
],
|
||||
[formatTimezoneAdjustedTimestamp],
|
||||
);
|
||||
|
||||
const handleExpandRowIcon = ({
|
||||
expanded,
|
||||
|
||||
@@ -41,6 +41,7 @@ import { getTraceListColumns } from './traceListColumns';
|
||||
import { getEntityTracesQueryPayload } from './utils';
|
||||
|
||||
import styles from './EntityTraces.module.scss';
|
||||
import { useTimezone } from 'providers/Timezone';
|
||||
|
||||
interface Props {
|
||||
timeRange: {
|
||||
@@ -136,7 +137,11 @@ function EntityTracesContent({
|
||||
[timeRange.startTime, timeRange.endTime, userExpression],
|
||||
);
|
||||
|
||||
const traceListColumns = getTraceListColumns(selectedEntityTracesColumns);
|
||||
const { formatTimezoneAdjustedTimestamp } = useTimezone();
|
||||
const traceListColumns = getTraceListColumns(
|
||||
selectedEntityTracesColumns,
|
||||
formatTimezoneAdjustedTimestamp,
|
||||
);
|
||||
|
||||
const isKeyNotFound = isKeyNotFoundError(error);
|
||||
const isDataEmpty =
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { TableColumnsType as ColumnsType } from 'antd';
|
||||
import { Badge } from '@signozhq/ui/badge';
|
||||
import { Typography } from '@signozhq/ui/typography';
|
||||
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
||||
import { getMs } from 'container/Trace/Filters/Panel/PanelBody/Duration/util';
|
||||
import {
|
||||
BlockLink,
|
||||
getTraceLink,
|
||||
} from 'container/TracesExplorer/ListView/utils';
|
||||
import dayjs from 'dayjs';
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { FormatTimezoneAdjustedTimestamp } from 'hooks/useTimezoneFormatter/useTimezoneFormatter';
|
||||
|
||||
const keyToLabelMap: Record<string, string> = {
|
||||
timestamp: 'Timestamp',
|
||||
@@ -59,6 +58,7 @@ const getValueForKey = (data: Record<string, any>, key: string): any => {
|
||||
|
||||
export const getTraceListColumns = (
|
||||
selectedColumns: BaseAutocompleteData[],
|
||||
formatTimezoneAdjustedTimestamp: FormatTimezoneAdjustedTimestamp,
|
||||
): ColumnsType<RowData> => {
|
||||
const columns: ColumnsType<RowData> =
|
||||
selectedColumns.map(({ dataType, key, type }) => ({
|
||||
@@ -73,8 +73,8 @@ export const getTraceListColumns = (
|
||||
if (primaryKey === 'timestamp') {
|
||||
const date =
|
||||
typeof value === 'string'
|
||||
? dayjs(value).format(DATE_TIME_FORMATS.ISO_DATETIME_MS)
|
||||
: dayjs(value / 1e6).format(DATE_TIME_FORMATS.ISO_DATETIME_MS);
|
||||
? formatTimezoneAdjustedTimestamp(value)
|
||||
: formatTimezoneAdjustedTimestamp(value / 1e6);
|
||||
|
||||
return (
|
||||
<BlockLink to={getTraceLink(itemData)} openInNewTab>
|
||||
|
||||
@@ -1366,7 +1366,7 @@ export const getPodMetricsQueryPayload = (
|
||||
orderBy: [],
|
||||
queryName: 'B',
|
||||
reduceTo: ReduceOperators.AVG,
|
||||
spaceAggregation: 'avg',
|
||||
spaceAggregation: 'sum',
|
||||
stepInterval: 60,
|
||||
timeAggregation: 'avg',
|
||||
},
|
||||
|
||||
@@ -86,9 +86,9 @@ export const k8sVolumesColumnsConfig: TableColumnDef<K8sVolumesData>[] = [
|
||||
},
|
||||
{
|
||||
id: 'capacity',
|
||||
header: 'Volume Capacity',
|
||||
header: 'Capacity',
|
||||
accessorFn: (row): number => row.volumeCapacity,
|
||||
width: { min: 220 },
|
||||
width: { min: 140 },
|
||||
enableSort: true,
|
||||
cell: ({ value }): React.ReactNode => {
|
||||
const capacity = value as number;
|
||||
@@ -105,9 +105,9 @@ export const k8sVolumesColumnsConfig: TableColumnDef<K8sVolumesData>[] = [
|
||||
},
|
||||
{
|
||||
id: 'usage',
|
||||
header: 'Volume Utilization',
|
||||
header: 'Used',
|
||||
accessorFn: (row): number => row.volumeUsage,
|
||||
width: { min: 220 },
|
||||
width: { min: 140 },
|
||||
enableSort: true,
|
||||
cell: ({ value }): React.ReactNode => {
|
||||
const usage = value as number;
|
||||
@@ -124,9 +124,9 @@ export const k8sVolumesColumnsConfig: TableColumnDef<K8sVolumesData>[] = [
|
||||
},
|
||||
{
|
||||
id: 'available',
|
||||
header: 'Volume Available',
|
||||
header: 'Available',
|
||||
accessorFn: (row): number => row.volumeAvailable,
|
||||
width: { min: 220 },
|
||||
width: { min: 140 },
|
||||
enableSort: true,
|
||||
cell: ({ value }): React.ReactNode => {
|
||||
const available = value as number;
|
||||
@@ -141,4 +141,61 @@ export const k8sVolumesColumnsConfig: TableColumnDef<K8sVolumesData>[] = [
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'inodes',
|
||||
header: 'Inodes',
|
||||
accessorFn: (row): number => row.volumeInodes,
|
||||
width: { min: 140 },
|
||||
enableSort: true,
|
||||
cell: ({ value }): React.ReactNode => {
|
||||
const inodes = value as number;
|
||||
return (
|
||||
<ValidateColumnValueWrapper
|
||||
value={inodes}
|
||||
entity={InfraMonitoringEntity.VOLUMES}
|
||||
attribute="inodes metric"
|
||||
>
|
||||
<TanStackTable.Text>{inodes}</TanStackTable.Text>
|
||||
</ValidateColumnValueWrapper>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'inodesUsed',
|
||||
header: 'Inodes Used',
|
||||
accessorFn: (row): number => row.volumeInodesUsed,
|
||||
width: { min: 160 },
|
||||
enableSort: true,
|
||||
cell: ({ value }): React.ReactNode => {
|
||||
const inodesUsed = value as number;
|
||||
return (
|
||||
<ValidateColumnValueWrapper
|
||||
value={inodesUsed}
|
||||
entity={InfraMonitoringEntity.VOLUMES}
|
||||
attribute="inodes used metric"
|
||||
>
|
||||
<TanStackTable.Text>{inodesUsed}</TanStackTable.Text>
|
||||
</ValidateColumnValueWrapper>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'inodesFree',
|
||||
header: 'Inodes Free',
|
||||
accessorFn: (row): number => row.volumeInodesFree,
|
||||
width: { min: 160 },
|
||||
enableSort: true,
|
||||
cell: ({ value }): React.ReactNode => {
|
||||
const inodesFree = value as number;
|
||||
return (
|
||||
<ValidateColumnValueWrapper
|
||||
value={inodesFree}
|
||||
entity={InfraMonitoringEntity.VOLUMES}
|
||||
attribute="inodes free metric"
|
||||
>
|
||||
<TanStackTable.Text>{inodesFree}</TanStackTable.Text>
|
||||
</ValidateColumnValueWrapper>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -151,6 +151,11 @@ export function PlannedDowntimeForm(
|
||||
|
||||
const saveHandler = useCallback(
|
||||
async (values: PlannedDowntimeFormData) => {
|
||||
const { startTime, timezone } = values;
|
||||
if (!startTime || !timezone) {
|
||||
// unreachable: required fields should always be present on submitting.
|
||||
return;
|
||||
}
|
||||
const data: AlertmanagertypesPostablePlannedMaintenanceDTO = {
|
||||
alertIds:
|
||||
values.alertRuleScope === 'all'
|
||||
@@ -161,9 +166,9 @@ export function PlannedDowntimeForm(
|
||||
name: values.name,
|
||||
scope: values.scope,
|
||||
schedule: {
|
||||
startTime: values.startTime?.format(),
|
||||
startTime: startTime.format(),
|
||||
endTime: values.endTime?.format(),
|
||||
timezone: values.timezone!,
|
||||
timezone,
|
||||
recurrence: values.recurrence,
|
||||
},
|
||||
};
|
||||
@@ -200,25 +205,17 @@ export function PlannedDowntimeForm(
|
||||
],
|
||||
);
|
||||
const onFinish = async (values: PlannedDowntimeFormData): Promise<void> => {
|
||||
const { recurrence } = values;
|
||||
const recurrenceData =
|
||||
!recurrence ||
|
||||
recurrence.repeatType === recurrenceOptions.doesNotRepeat.value
|
||||
? undefined
|
||||
: {
|
||||
duration: recurrence.duration
|
||||
? `${recurrence.duration}${durationUnit}`
|
||||
: '',
|
||||
startTime: values.startTime!.format(),
|
||||
endTime: values.endTime?.format(),
|
||||
repeatOn: recurrence.repeatOn,
|
||||
repeatType: recurrence.repeatType,
|
||||
};
|
||||
const rec = values.recurrence;
|
||||
const recurrence =
|
||||
rec && rec.repeatType !== recurrenceOptions.doesNotRepeat.value
|
||||
? {
|
||||
duration: `${rec.duration}${durationUnit}`,
|
||||
repeatOn: rec.repeatOn,
|
||||
repeatType: rec.repeatType,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
await saveHandler({
|
||||
...values,
|
||||
recurrence: recurrenceData,
|
||||
});
|
||||
await saveHandler({ ...values, recurrence });
|
||||
};
|
||||
|
||||
const handleFormData = (data: Partial<PlannedDowntimeFormData>): void => {
|
||||
@@ -275,9 +272,6 @@ export function PlannedDowntimeForm(
|
||||
|
||||
const formattedInitialValues = useMemo((): PlannedDowntimeFormData => {
|
||||
const { schedule } = initialValues;
|
||||
const startTime = schedule?.recurrence?.startTime || schedule?.startTime;
|
||||
const endTime = schedule?.recurrence?.endTime || schedule?.endTime;
|
||||
|
||||
const initialAlertIds = initialValues.alertIds || [];
|
||||
|
||||
return {
|
||||
@@ -285,8 +279,12 @@ export function PlannedDowntimeForm(
|
||||
alertRuleScope:
|
||||
isEditMode && initialAlertIds.length === 0 ? 'all' : 'specific',
|
||||
alertRules: getAlertOptionsFromIds(initialAlertIds, alertOptions),
|
||||
startTime: startTime ? dayjs(startTime).tz(schedule.timezone) : null,
|
||||
endTime: endTime ? dayjs(endTime).tz(schedule.timezone) : null,
|
||||
startTime: schedule?.startTime
|
||||
? dayjs(schedule.startTime).tz(schedule.timezone)
|
||||
: null,
|
||||
endTime: schedule?.endTime
|
||||
? dayjs(schedule.endTime).tz(schedule.timezone)
|
||||
: null,
|
||||
recurrence: {
|
||||
...schedule?.recurrence,
|
||||
repeatType: !isScheduleRecurring(schedule)
|
||||
@@ -297,7 +295,7 @@ export function PlannedDowntimeForm(
|
||||
timezone: schedule?.timezone as string,
|
||||
scope: initialValues.scope || '',
|
||||
};
|
||||
}, [initialValues, alertOptions]);
|
||||
}, [initialValues, isEditMode, alertOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedTags(formattedInitialValues.alertRules);
|
||||
@@ -341,7 +339,7 @@ export function PlannedDowntimeForm(
|
||||
const formattedEndTime = endTime.format(TIME_FORMAT);
|
||||
const formattedEndDate = endTime.format(DATE_FORMAT);
|
||||
return `Scheduled to end maintenance on ${formattedEndDate} at ${formattedEndTime}.`;
|
||||
}, [formData, recurrenceType]);
|
||||
}, [formData]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
||||
@@ -142,7 +142,6 @@ export function CollapseListContent({
|
||||
updated_by_name?: string;
|
||||
alertOptions?: DefaultOptionType[];
|
||||
}): JSX.Element {
|
||||
const repeats = schedule?.recurrence;
|
||||
const renderItems = (title: string, value: ReactNode): JSX.Element => (
|
||||
<div className="render-item-collapse-list">
|
||||
<Typography>{title}</Typography>
|
||||
@@ -193,10 +192,7 @@ export function CollapseListContent({
|
||||
'Timezone',
|
||||
<Typography>{schedule?.timezone || '-'}</Typography>,
|
||||
)}
|
||||
{renderItems(
|
||||
'Repeats',
|
||||
<Typography>{recurrenceInfo(repeats, schedule?.timezone)}</Typography>,
|
||||
)}
|
||||
{renderItems('Repeats', <Typography>{recurrenceInfo(schedule)}</Typography>)}
|
||||
{renderItems(
|
||||
'Alerts silenced',
|
||||
alertOptions?.length ? (
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
DeleteDowntimeScheduleByIDPathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
AlertmanagertypesPlannedMaintenanceDTO,
|
||||
AlertmanagertypesRecurrenceDTO,
|
||||
AlertmanagertypesScheduleDTO,
|
||||
} from 'api/generated/services/sigNoz.schemas';
|
||||
import type { ErrorType } from 'api/generatedAPIInstance';
|
||||
import { AxiosError } from 'axios';
|
||||
@@ -66,14 +66,17 @@ export const getAlertOptionsFromIds = (
|
||||
);
|
||||
|
||||
export const recurrenceInfo = (
|
||||
recurrence?: AlertmanagertypesRecurrenceDTO | null,
|
||||
timezone?: string,
|
||||
schedule?: AlertmanagertypesScheduleDTO | null,
|
||||
): string => {
|
||||
if (!schedule) {
|
||||
return 'No';
|
||||
}
|
||||
const { startTime, endTime, timezone, recurrence } = schedule;
|
||||
if (!recurrence) {
|
||||
return 'No';
|
||||
}
|
||||
|
||||
const { startTime, duration, repeatOn, repeatType, endTime } = recurrence;
|
||||
const { duration, repeatOn, repeatType } = recurrence;
|
||||
|
||||
const formattedStartTime = startTime
|
||||
? formatDateTime(startTime, timezone)
|
||||
@@ -95,7 +98,7 @@ export const defaultInitialValues: Partial<AlertmanagertypesPlannedMaintenanceDT
|
||||
timezone: '',
|
||||
endTime: undefined,
|
||||
recurrence: undefined,
|
||||
startTime: undefined,
|
||||
startTime: '',
|
||||
},
|
||||
alertIds: [],
|
||||
createdAt: undefined,
|
||||
|
||||
@@ -11,7 +11,7 @@ export const buildSchedule = (
|
||||
schedule: Partial<AlertmanagertypesScheduleDTO>,
|
||||
): AlertmanagertypesScheduleDTO => ({
|
||||
timezone: schedule?.timezone ?? '',
|
||||
startTime: schedule?.startTime,
|
||||
startTime: schedule?.startTime ?? '',
|
||||
endTime: schedule?.endTime,
|
||||
recurrence: schedule?.recurrence,
|
||||
});
|
||||
|
||||
@@ -142,6 +142,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.reset-password-back-action {
|
||||
margin-top: var(--spacing-12);
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { CircleAlert } from '@signozhq/icons';
|
||||
import { ArrowLeft, CircleAlert } from '@signozhq/icons';
|
||||
import { Button } from '@signozhq/ui/button';
|
||||
import { Typography } from '@signozhq/ui/typography';
|
||||
import AuthError from 'components/AuthError/AuthError';
|
||||
import AuthPageContainer from 'components/AuthPageContainer';
|
||||
import ROUTES from 'constants/routes';
|
||||
import history from 'lib/history';
|
||||
import APIError from 'types/api/error';
|
||||
|
||||
import './ResetPassword.styles.scss';
|
||||
@@ -59,6 +62,16 @@ function TokenError({ error }: TokenErrorProps): JSX.Element {
|
||||
</Typography.Text>
|
||||
</div>
|
||||
{error && <AuthError error={error} />}
|
||||
<div className="reset-password-back-action">
|
||||
<Button
|
||||
variant="solid"
|
||||
data-testid="back-to-login"
|
||||
prefix={<ArrowLeft size={12} />}
|
||||
onClick={(): void => history.push(ROUTES.LOGIN)}
|
||||
>
|
||||
Back to login
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</AuthPageContainer>
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user