mirror of
https://github.com/SigNoz/signoz.git
synced 2026-09-05 11:00:41 +01:00
Compare commits
88 Commits
chore/scaf
...
nv/heatmap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
510d6985d0 | ||
|
|
758aacb065 | ||
|
|
5599c352d0 | ||
|
|
96d0a2340c | ||
|
|
c6b415ad04 | ||
|
|
9b922f297f | ||
|
|
e81a4c4046 | ||
|
|
9ba13848ea | ||
|
|
2578f25dd4 | ||
|
|
82352973bb | ||
|
|
3eb55692f1 | ||
|
|
61ceb6d300 | ||
|
|
e33fc20579 | ||
|
|
b130a61049 | ||
|
|
132e9bb740 | ||
|
|
9d577731e1 | ||
|
|
4d54568fe1 | ||
|
|
6f82624523 | ||
|
|
da0bc4f438 | ||
|
|
2dcb764632 | ||
|
|
1bc25e16b8 | ||
|
|
eebc6b400d | ||
|
|
30c4508113 | ||
|
|
c4fe619920 | ||
|
|
d597adddda | ||
|
|
9a05f33e7a | ||
|
|
3812937c6f | ||
|
|
34aa719cba | ||
|
|
cdfce4c4ab | ||
|
|
d8ef672f83 | ||
|
|
e0da06f76d | ||
|
|
85f9924b4b | ||
|
|
c015622258 | ||
|
|
0f36cb9334 | ||
|
|
e1ee386016 | ||
|
|
717d37a945 | ||
|
|
63b130ccd1 | ||
|
|
618031ddaa | ||
|
|
8680361c68 | ||
|
|
bfddd10dc6 | ||
|
|
b232ecf01c | ||
|
|
7faab60ea7 | ||
|
|
00efffc127 | ||
|
|
a75442f31e | ||
|
|
52588c4582 | ||
|
|
e485f50221 | ||
|
|
b3b547f34a | ||
|
|
be9a045455 | ||
|
|
dec922a83f | ||
|
|
297d3dd44b | ||
|
|
e84a61d43f | ||
|
|
afb1eb4a41 | ||
|
|
4f6414ef61 | ||
|
|
70335dc707 | ||
|
|
eb2d094b1f | ||
|
|
7c50fe3763 | ||
|
|
160a1b018c | ||
|
|
27acdbd970 | ||
|
|
7eb610287e | ||
|
|
74c946fe79 | ||
|
|
23dd98bee7 | ||
|
|
aca35a1309 | ||
|
|
c65f6fa77d | ||
|
|
4d015a927e | ||
|
|
abebea532b | ||
|
|
764fe8ec69 | ||
|
|
da9b4644df | ||
|
|
095821264e | ||
|
|
5069bf80b0 | ||
|
|
1086914a3b | ||
|
|
3e2daaea0e | ||
|
|
1b8155fea9 | ||
|
|
dac406eb93 | ||
|
|
f69bce998a | ||
|
|
ae9f58ba44 | ||
|
|
a930da0901 | ||
|
|
5314cb7828 | ||
|
|
02c5555a48 | ||
|
|
0bdc7bf6a1 | ||
|
|
a8c04cb563 | ||
|
|
73719a3f60 | ||
|
|
724f7ce78b | ||
|
|
6f4af0a2a1 | ||
|
|
fe68b8e8b7 | ||
|
|
77fbf74092 | ||
|
|
9997c3da9c | ||
|
|
485aed0e1a | ||
|
|
4d69e3f9e5 |
@@ -20,6 +20,16 @@ You are the Playwright Test Generator for the SigNoz frontend. You take a plan w
|
||||
await expect(page.getByRole('tab', { name: /alert rules/i })).toBeVisible();
|
||||
});
|
||||
```
|
||||
- **Extended fixtures:** For features needing complex setup (seeded data, API calls, cleanup), import from domain-specific fixtures that extend `auth`. See [docs/contributing/tests/e2e.md](../../docs/contributing/tests/e2e.md) for the full pattern.
|
||||
- `fixtures/alerts/alert-rules` — worker-scoped rule list + test-scoped rule factory
|
||||
- `fixtures/alerts/alert-history` — extends alert-rules, adds history fixtures (waits on ruler evaluation)
|
||||
```ts
|
||||
// Alert list tests - need rules, no history
|
||||
import { test, expect } from '../../../fixtures/alerts/alert-rules';
|
||||
|
||||
// Alert history tests - need evaluated history rows
|
||||
import { test, expect } from '../../../fixtures/alerts/alert-history';
|
||||
```
|
||||
- **Test titles:** `TC-NN <short description>` — matches the planner's IDs.
|
||||
- **Self-contained state.** The bootstrap creates a fresh stack with **zero** dashboards / alerts / etc. — never assume pre-existing data. Two cleanup shapes are valid; pick based on the spec size:
|
||||
- **Per-test `try / finally`** — small specs (~ <10 scenarios) where each test owns its data.
|
||||
|
||||
@@ -49,6 +49,7 @@ Don't try to start the stack yourself — it can take ~4 minutes on a cold build
|
||||
- **The list pages render zero-state when the workspace is empty.** Many locators (search input, sort button, `new-dashboard-cta` testid, "All Dashboards" header) are absent in zero-state. A 30s timeout on those usually means the workspace was empty — seed first via `createDashboardViaApi`.
|
||||
- **The "Enter dashboard name…" inline field is a `RequestDashboardBtn` (template-request feedback form), not a create flow.** Tests that try to use it to create a named dashboard will silently no-op. The only UI create paths are the "New dashboard" dropdown → "Create dashboard" (default name "Sample Title", see `DEFAULT_DASHBOARD_TITLE`) or "Import JSON".
|
||||
- **Auth.** `tests/e2e/fixtures/auth.ts` logs in once per worker and caches `storageState` (cookies + localStorage with `AUTH_TOKEN`). For API-driven seeding/cleanup, use `authToken(page)` from `helpers/dashboards.ts` and pass `Authorization: Bearer <token>`. Never re-implement login.
|
||||
- **Extended fixtures.** Domain-specific fixtures extend `auth` and add seeded data. Alerts uses `fixtures/alerts/alert-rules` (worker-scoped rule list, test-scoped factory) and `fixtures/alerts/alert-history` (extends alert-rules, waits on ruler evaluation). See [docs/contributing/tests/e2e.md](../../docs/contributing/tests/e2e.md) for the pattern. When a test fails on missing data, check if it imports the wrong fixture level.
|
||||
- **Ant Design popovers** (sort menu, action menu) are click-toggle. The trigger element is often an inline `<svg>` with a `data-testid` — clicking it opens the popover; clicking it again closes. After selecting an option, the popover auto-closes. If a test interacts with the popover twice, wait for the menu items to be visible explicitly between toggles.
|
||||
- **Artifacts.** Every failed test writes to `tests/e2e/artifacts/results/<test-slug>/` — the `error-context.md` accessibility snapshot is the fastest way to see what the page actually looked like when it failed.
|
||||
- **Type-check.** After edits, run `npx tsc --noEmit -p tests/e2e/tsconfig.json` if it succeeds, or rely on `npx playwright test --list` to validate the spec parses.
|
||||
|
||||
28
.github/CODEOWNERS
vendored
28
.github/CODEOWNERS
vendored
@@ -152,39 +152,29 @@ go.mod @therealpandey
|
||||
|
||||
## Dashboard Types
|
||||
|
||||
/frontend/src/api/types/dashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/types/api/dashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/types/api/widgets/ @SigNoz/pulse-frontend
|
||||
|
||||
## Dashboard List
|
||||
## Widget Card
|
||||
|
||||
/frontend/src/pages/DashboardsListPage/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/ListOfDashboard/ @SigNoz/pulse-frontend
|
||||
|
||||
# Dashboard Widget Page
|
||||
|
||||
/frontend/src/pages/DashboardWidget/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/NewWidget/ @SigNoz/pulse-frontend
|
||||
|
||||
## Dashboard Page
|
||||
|
||||
/frontend/src/pages/DashboardPage/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/DashboardContainer/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/GridCardLayout/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/WidgetCard/ @SigNoz/pulse-frontend
|
||||
|
||||
## Public Dashboard Page
|
||||
|
||||
/frontend/src/pages/PublicDashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/container/PublicDashboardContainer/ @SigNoz/pulse-frontend
|
||||
|
||||
## Dashboard Libs + Components
|
||||
|
||||
/frontend/src/lib/uPlotV2/ @SigNoz/pulse-frontend
|
||||
/frontend/src/lib/visualization/ @SigNoz/pulse-frontend
|
||||
/frontend/src/lib/dashboard/ @SigNoz/pulse-frontend
|
||||
/frontend/src/lib/dashboardVariables/ @SigNoz/pulse-frontend
|
||||
/frontend/src/components/NewSelect/ @SigNoz/pulse-frontend
|
||||
|
||||
## Dashboard V2
|
||||
/frontend/src/pages/DashboardPageV2/ @SigNoz/pulse-frontend
|
||||
/frontend/src/pages/DashboardsListPageV2/ @SigNoz/pulse-frontend
|
||||
## Dashboard Pages
|
||||
|
||||
/frontend/src/pages/DashboardPage/ @SigNoz/pulse-frontend
|
||||
/frontend/src/pages/DashboardsListPage/ @SigNoz/pulse-frontend
|
||||
|
||||
## Infrastructure Monitoring
|
||||
/frontend/src/pages/InfrastructureMonitoring/ @SigNoz/pulse-frontend
|
||||
|
||||
1
.github/workflows/build-enterprise.yaml
vendored
1
.github/workflows/build-enterprise.yaml
vendored
@@ -103,7 +103,6 @@ jobs:
|
||||
-X github.com/SigNoz/signoz/pkg/version.branch=${{ needs.prepare.outputs.branch }}
|
||||
-X github.com/SigNoz/signoz/ee/zeus.url=https://api.signoz.cloud
|
||||
-X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=https://license.signoz.io
|
||||
-X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.signoz.io/api/v1
|
||||
-X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr'
|
||||
DOCKER_BASE_IMAGES: '{"alpine": "alpine:3.20.3"}'
|
||||
DOCKER_DOCKERFILE_PATH: ./cmd/enterprise/Dockerfile.multi-arch
|
||||
|
||||
1
.github/workflows/build-staging.yaml
vendored
1
.github/workflows/build-staging.yaml
vendored
@@ -109,7 +109,6 @@ jobs:
|
||||
-X github.com/SigNoz/signoz/pkg/version.branch=${{ needs.prepare.outputs.branch }}
|
||||
-X github.com/SigNoz/signoz/ee/zeus.url=https://api.staging.signoz.cloud
|
||||
-X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=https://license.staging.signoz.cloud
|
||||
-X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.staging.signoz.cloud/api/v1
|
||||
-X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr'
|
||||
DOCKER_BASE_IMAGES: '{"alpine": "alpine:3.20.3"}'
|
||||
DOCKER_DOCKERFILE_PATH: ./cmd/enterprise/Dockerfile.multi-arch
|
||||
|
||||
3
.github/workflows/integrationci.yaml
vendored
3
.github/workflows/integrationci.yaml
vendored
@@ -50,6 +50,7 @@ jobs:
|
||||
- logspipelines
|
||||
- passwordauthn
|
||||
- preference
|
||||
- quickfilter
|
||||
- querierlogs
|
||||
- queriertraces
|
||||
- queriermetrics
|
||||
@@ -58,10 +59,12 @@ jobs:
|
||||
- querierai
|
||||
- rawexportdata
|
||||
- promqlconformance
|
||||
- promapiconformance
|
||||
- querierauthz
|
||||
- role
|
||||
- rootuser
|
||||
- savedview
|
||||
- semconvfamilies
|
||||
- serviceaccount
|
||||
- spanmapper
|
||||
- querier_json_body
|
||||
|
||||
@@ -96,6 +96,7 @@ func runGenerateAuthz(_ context.Context) error {
|
||||
coretypes.NewResourceRef(coretypes.ResourceServiceAccount).String(): true,
|
||||
coretypes.NewResourceRef(coretypes.ResourceRole).String(): true,
|
||||
coretypes.NewResourceRef(coretypes.ResourceMetaResourceFactorAPIKey).String(): true,
|
||||
coretypes.NewResourceRef(coretypes.ResourceMetaResourceLicense).String(): true,
|
||||
coretypes.NewResourceRef(coretypes.ResourceTelemetryResourceLogs).String(): true,
|
||||
coretypes.NewResourceRef(coretypes.ResourceTelemetryResourceTraces).String(): true,
|
||||
coretypes.NewResourceRef(coretypes.ResourceTelemetryResourceMetrics).String(): true,
|
||||
|
||||
@@ -44,8 +44,11 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/ruler/signozruler"
|
||||
"github.com/SigNoz/signoz/pkg/signoz"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/subscription"
|
||||
"github.com/SigNoz/signoz/pkg/subscription/noopsubscription"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/SigNoz/signoz/pkg/version"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
@@ -86,6 +89,9 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
func(_ sqlstore.SQLStore, _ zeus.Zeus, _ organization.Getter, _ analytics.Analytics) factory.ProviderFactory[licensing.Licensing, licensing.Config] {
|
||||
return nooplicensing.NewFactory()
|
||||
},
|
||||
func(_ zeus.Zeus, _ licensing.Licensing) subscription.Subscription {
|
||||
return noopsubscription.New()
|
||||
},
|
||||
signoz.NewEmailingProviderFactories(),
|
||||
signoz.NewCacheProviderFactories(),
|
||||
signoz.NewWebProviderFactories(config.Global),
|
||||
@@ -103,8 +109,8 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
|
||||
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx), openfgaDataStore, authtypes.NewRegistry()), nil
|
||||
},
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing, tagModule tag.Module) dashboard.Module {
|
||||
return impldashboard.NewModule(impldashboard.NewStore(store), settings, analytics, orgGetter, queryParser, tagModule)
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing, tagModule tag.Module, systemDashboardRegistry dashboardtypes.SystemDashboardRegistry) dashboard.Module {
|
||||
return impldashboard.NewModule(impldashboard.NewStore(store), settings, analytics, orgGetter, queryParser, tagModule, systemDashboardRegistry)
|
||||
},
|
||||
func(_ licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
|
||||
return noopgateway.NewProviderFactory()
|
||||
|
||||
@@ -31,7 +31,6 @@ builds:
|
||||
- -X github.com/SigNoz/signoz/pkg/version.branch={{ .Branch }}
|
||||
- -X github.com/SigNoz/signoz/ee/zeus.url=https://api.signoz.cloud
|
||||
- -X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=https://license.signoz.io
|
||||
- -X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.signoz.io/api/v1
|
||||
- -X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr
|
||||
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||
tags:
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
eequerier "github.com/SigNoz/signoz/ee/querier"
|
||||
enterpriseapp "github.com/SigNoz/signoz/ee/query-service/app"
|
||||
eerules "github.com/SigNoz/signoz/ee/query-service/rules"
|
||||
"github.com/SigNoz/signoz/ee/subscription/httpsubscription"
|
||||
enterprisezeus "github.com/SigNoz/signoz/ee/zeus"
|
||||
"github.com/SigNoz/signoz/ee/zeus/httpzeus"
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager"
|
||||
@@ -60,9 +61,11 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/ruler/signozruler"
|
||||
"github.com/SigNoz/signoz/pkg/signoz"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/subscription"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/SigNoz/signoz/pkg/version"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
@@ -102,6 +105,9 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
func(sqlstore sqlstore.SQLStore, zeus zeus.Zeus, orgGetter organization.Getter, analytics analytics.Analytics) factory.ProviderFactory[licensing.Licensing, licensing.Config] {
|
||||
return httplicensing.NewProviderFactory(sqlstore, zeus, orgGetter, analytics)
|
||||
},
|
||||
func(zeus zeus.Zeus, licensing licensing.Licensing) subscription.Subscription {
|
||||
return httpsubscription.New(zeus, licensing)
|
||||
},
|
||||
signoz.NewEmailingProviderFactories(),
|
||||
signoz.NewCacheProviderFactories(),
|
||||
signoz.NewWebProviderFactories(config.Global),
|
||||
@@ -136,8 +142,8 @@ func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) e
|
||||
}
|
||||
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx), openfgaDataStore, licensing, onBeforeRoleDelete, authtypes.NewRegistry()), nil
|
||||
},
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing, tagModule tag.Module) dashboard.Module {
|
||||
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, queryParser, querier, licensing, tagModule)
|
||||
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing, tagModule tag.Module, systemDashboardRegistry dashboardtypes.SystemDashboardRegistry) dashboard.Module {
|
||||
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, queryParser, querier, licensing, tagModule, systemDashboardRegistry)
|
||||
},
|
||||
func(licensing licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
|
||||
return httpgateway.NewProviderFactory(licensing)
|
||||
|
||||
2455
docs/api/openapi.yml
2455
docs/api/openapi.yml
File diff suppressed because it is too large
Load Diff
@@ -299,8 +299,11 @@ substituted. One subtlety makes it exact: we write stale markers at absent
|
||||
grid points. Without them, the engine's lookback would resurrect a point
|
||||
from up to `lookback` earlier. The marker encodes "absent here" the way the
|
||||
engine itself encodes it. Units evaluate concurrently. Each unit is one
|
||||
series lookup plus one grid statement. A step of 0 is an instant query: a
|
||||
single evaluation at `end`.
|
||||
grid statement: the group-key join resolves the matchers, and the samples
|
||||
primary key takes the metric name straight from the selector. Only a
|
||||
selector without a static `__name__` runs the series lookup first, to learn
|
||||
the concrete metric names. A step of 0 is an instant query: a single
|
||||
evaluation at `end`.
|
||||
|
||||
A note on the window sliver: when the window is narrower than the step, the
|
||||
grid windows cover only `window/step` of the timeline. A sample in a gap
|
||||
@@ -315,8 +318,9 @@ selectors and `last_over_time` transpile at window < step too.
|
||||
|
||||
## Series lookup
|
||||
|
||||
Both paths resolve matchers the same way, once per selector
|
||||
(`selectSeries`). The series tables hold one row per (fingerprint, bucket)
|
||||
The engine path resolves matchers once per selector (`selectSeries`); the
|
||||
transpiled path builds the same conditions into its group-key join. Both
|
||||
read the same tables. The series tables hold one row per (fingerprint, bucket)
|
||||
at 1h/6h/1d/1w granularities. The shared schema package
|
||||
(`pkg/telemetryschema/metricstelemetryschema`) picks the table whose bucket
|
||||
fits the window. It rounds the window start down to the bucket boundary, so
|
||||
|
||||
@@ -112,6 +112,41 @@ These two folders look similar but mean different things:
|
||||
|
||||
Rule of thumb: if it's a `test.extend` fixture, put it in `fixtures/`. If it's a function you call explicitly (or a constant the function uses), put it in `helpers/`. If it's a static file the helpers read, put it in `testdata/`.
|
||||
|
||||
### Extended fixtures
|
||||
|
||||
For features needing complex setup (API-seeded data, ruler evaluation waits, cleanup), create domain-specific fixtures that extend `auth`. Group them in `fixtures/<domain>/`.
|
||||
|
||||
**Fixture scopes:**
|
||||
- **test scope** — fresh data per test. Use for mutations (edit, delete, rename).
|
||||
- **worker scope** — shared across tests in one worker. Use for read-only data. Worker scope pays the setup cost once per worker instead of once per test.
|
||||
|
||||
**The alerts pattern** (`fixtures/alerts/`) demonstrates extending fixtures:
|
||||
|
||||
```
|
||||
fixtures/alerts/
|
||||
├── alert-rules.ts # extends auth — worker-scoped rule list + test-scoped factory
|
||||
└── alert-history.ts # extends alert-rules — adds history fixtures (waits on ruler)
|
||||
```
|
||||
|
||||
Specs import from the fixture they need:
|
||||
|
||||
```ts
|
||||
// List tests — just need rules, no history
|
||||
import { test, expect } from '../../../fixtures/alerts/alert-rules';
|
||||
|
||||
// History tests — need history rows from ruler evaluation
|
||||
import { test, expect } from '../../../fixtures/alerts/alert-history';
|
||||
```
|
||||
|
||||
**When creating new fixtures:**
|
||||
|
||||
1. **Identify scope** — Will tests mutate the data? If yes, test-scoped. If read-only, worker-scoped.
|
||||
2. **Group by domain** — Put fixtures in `fixtures/<domain>/`. Helpers in `helpers/<domain>/`.
|
||||
3. **Extend existing fixtures** — Chain from `auth` or another fixture to inherit its setup.
|
||||
4. **Handle timeouts** — Worker-scoped fixtures that wait on backend processing need explicit timeouts.
|
||||
5. **Clean up** — Always delete seeded data in the fixture teardown (after `use()`).
|
||||
6. **Extract logic into functions** — Keep the `test.extend()` block lean; move setup/teardown logic to named functions so the extend block reads as a manifest of "what fixtures exist."
|
||||
|
||||
Each spec follows these principles:
|
||||
|
||||
1. **Directory per feature**: `tests/e2e/tests/<feature>/*.spec.ts`. Cross-resource junction concerns (e.g. cascade-delete) go in their own file, not packed into one giant spec.
|
||||
@@ -232,11 +267,14 @@ cd tests/e2e
|
||||
# Single feature dir
|
||||
npx playwright test tests/alerts/ --project=chromium
|
||||
|
||||
# Single sub-area
|
||||
npx playwright test tests/alerts/history/ --project=chromium
|
||||
|
||||
# Single file
|
||||
npx playwright test tests/alerts/alerts.spec.ts --project=chromium
|
||||
npx playwright test tests/alerts/page.spec.ts --project=chromium
|
||||
|
||||
# Single test by title grep
|
||||
npx playwright test --project=chromium -g "TC-01"
|
||||
npx playwright test --project=chromium -g "AL-01"
|
||||
```
|
||||
|
||||
### Iterative modes
|
||||
@@ -270,7 +308,14 @@ yarn test:staging
|
||||
| `SIGNOZ_E2E_PASSWORD` | Admin password. Bootstrap writes the integration-test default. |
|
||||
| `SIGNOZ_E2E_SEEDER_URL` | Seeder HTTP base URL — hit by specs that need per-test telemetry. |
|
||||
|
||||
Loading order in `playwright.config.ts`: `.env` first (user-provided, staging), then `.env.local` with `override: true` (bootstrap-generated, local mode). Anything already set in `process.env` at yarn-test time wins because dotenv doesn't touch vars that are already present.
|
||||
Precedence in `playwright.config.ts`, lowest to highest: `.env` (user-provided, staging) → `.env.local` (bootstrap-generated, local mode) → whatever is already in `process.env`. The config parses both files itself and only fills in keys the environment does not already define, so exporting a variable always wins:
|
||||
|
||||
```bash
|
||||
# runs against a locally served frontend, not whatever .env.local points at
|
||||
SIGNOZ_E2E_BASE_URL=http://127.0.0.1:3301 pnpm test tests/alerts
|
||||
```
|
||||
|
||||
This is deliberately not `dotenv.config({ override: true })`. That flag makes the *file* beat `process.env`, which silently discarded exported values — including the `SIGNOZ_E2E_BASE_URL` in `pnpm test:staging`, whenever a `.env.local` happened to exist.
|
||||
|
||||
### Playwright options
|
||||
|
||||
|
||||
@@ -108,6 +108,20 @@ func (provider *Provider) SearchIngestionKeysByName(ctx context.Context, orgID v
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetIngestionKey(ctx context.Context, orgID valuer.UUID, keyID string) (*gatewaytypes.IngestionKey, error) {
|
||||
responseBody, err := provider.do(ctx, orgID, http.MethodGet, "/v1/workspaces/me/keys/"+keyID, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ingestionKey gatewaytypes.IngestionKey
|
||||
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &ingestionKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ingestionKey, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) CreateIngestionKey(ctx context.Context, orgID valuer.UUID, name string, tags []string, expiresAt time.Time) (*gatewaytypes.GettableCreatedIngestionKey, error) {
|
||||
requestBody := gatewaytypes.PostableIngestionKey{
|
||||
Name: name,
|
||||
@@ -161,7 +175,7 @@ func (provider *Provider) DeleteIngestionKey(ctx context.Context, orgID valuer.U
|
||||
}
|
||||
|
||||
func (provider *Provider) CreateIngestionKeyLimit(ctx context.Context, orgID valuer.UUID, keyID string, signal string, limitConfig gatewaytypes.LimitConfig, tags []string) (*gatewaytypes.GettableCreatedIngestionKeyLimit, error) {
|
||||
requestBody := gatewaytypes.PostableIngestionKeyLimit{
|
||||
requestBody := gatewaytypes.DeprecatedPostableIngestionKeyLimit{
|
||||
Signal: signal,
|
||||
Config: limitConfig,
|
||||
Tags: tags,
|
||||
@@ -184,6 +198,34 @@ func (provider *Provider) CreateIngestionKeyLimit(ctx context.Context, orgID val
|
||||
return &createdIngestionKeyLimitResponse, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetIngestionKeyLimit(ctx context.Context, orgID valuer.UUID, limitID string) (*gatewaytypes.Limit, error) {
|
||||
responseBody, err := provider.do(ctx, orgID, http.MethodGet, "/v1/workspaces/me/limits/"+limitID, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var limit gatewaytypes.Limit
|
||||
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &limit); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &limit, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetIngestionKeyLimits(ctx context.Context, orgID valuer.UUID, keyID string) ([]gatewaytypes.Limit, error) {
|
||||
responseBody, err := provider.do(ctx, orgID, http.MethodGet, "/v1/workspaces/me/keys/"+keyID+"/limits", nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var limits []gatewaytypes.Limit
|
||||
if err := json.Unmarshal([]byte(gjson.GetBytes(responseBody, "data").String()), &limits); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return limits, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) UpdateIngestionKeyLimit(ctx context.Context, orgID valuer.UUID, limitID string, limitConfig gatewaytypes.LimitConfig, tags []string) error {
|
||||
requestBody := gatewaytypes.UpdatableIngestionKeyLimit{
|
||||
Config: limitConfig,
|
||||
|
||||
@@ -22,89 +22,6 @@ func NewLicensingAPI(licensing licensing.Licensing) licensing.API {
|
||||
return &licensingAPI{licensing: licensing}
|
||||
}
|
||||
|
||||
func (api *licensingAPI) Activate(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
claims, err := authtypes.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
orgID, err := valuer.NewUUID(claims.OrgID)
|
||||
if err != nil {
|
||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "orgId is invalid"))
|
||||
return
|
||||
}
|
||||
|
||||
req := new(licensetypes.PostableLicense)
|
||||
err = json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = api.licensing.Activate(r.Context(), orgID, req.Key)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
render.Success(rw, http.StatusAccepted, nil)
|
||||
}
|
||||
|
||||
func (api *licensingAPI) GetActive(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
claims, err := authtypes.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
orgID, err := valuer.NewUUID(claims.OrgID)
|
||||
if err != nil {
|
||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "orgId is invalid"))
|
||||
return
|
||||
}
|
||||
|
||||
license, err := api.licensing.GetActive(r.Context(), orgID)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
gettableLicense := licensetypes.NewGettableLicense(license.Data, license.Key)
|
||||
render.Success(rw, http.StatusOK, gettableLicense)
|
||||
}
|
||||
|
||||
func (api *licensingAPI) Refresh(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
claims, err := authtypes.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
orgID, err := valuer.NewUUID(claims.OrgID)
|
||||
if err != nil {
|
||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "orgId is invalid"))
|
||||
return
|
||||
}
|
||||
|
||||
err = api.licensing.Refresh(r.Context(), orgID)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
render.Success(rw, http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
func (api *licensingAPI) Checkout(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -95,24 +95,65 @@ func (provider *provider) Validate(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (provider *provider) Activate(ctx context.Context, organizationID valuer.UUID, key string) error {
|
||||
data, err := provider.zeus.GetLicense(ctx, key)
|
||||
func (provider *provider) Activate(ctx context.Context, organizationID valuer.UUID, key string) (*licensetypes.License, error) {
|
||||
zeusLicense, err := provider.zeus.GetLicense(ctx, key)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "unable to fetch license data with upstream server")
|
||||
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "unable to fetch license data with upstream server")
|
||||
}
|
||||
|
||||
license, err := licensetypes.NewLicense(data, organizationID)
|
||||
license, err := licensetypes.NewLicense(zeusLicense, organizationID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to create license entity")
|
||||
return nil, errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to create license entity")
|
||||
}
|
||||
|
||||
storableLicense := licensetypes.NewStorableLicenseFromLicense(license)
|
||||
err = provider.store.Create(ctx, storableLicense)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return license, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Get(ctx context.Context, organizationID valuer.UUID, licenseID valuer.UUID) (*licensetypes.License, error) {
|
||||
storableLicense, err := provider.store.Get(ctx, organizationID, licenseID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return licensetypes.NewLicenseFromStorableLicense(storableLicense)
|
||||
}
|
||||
|
||||
func (provider *provider) List(ctx context.Context, organizationID valuer.UUID) ([]*licensetypes.License, error) {
|
||||
storableLicenses, err := provider.store.GetAll(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
licenses := make([]*licensetypes.License, 0, len(storableLicenses))
|
||||
for _, storableLicense := range storableLicenses {
|
||||
license, err := licensetypes.NewLicenseFromStorableLicense(storableLicense)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
licenses = append(licenses, license)
|
||||
}
|
||||
|
||||
return licenses, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Delete(ctx context.Context, organizationID valuer.UUID, licenseID valuer.UUID) error {
|
||||
license, err := provider.Get(ctx, organizationID, licenseID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
if err := license.ErrIfCloud(); err != nil {
|
||||
return errors.WithAdditionalf(err, "license %s cannot be deleted", licenseID.StringValue())
|
||||
}
|
||||
|
||||
return provider.store.Delete(ctx, organizationID, licenseID)
|
||||
}
|
||||
|
||||
func (provider *provider) GetActive(ctx context.Context, organizationID valuer.UUID) (*licensetypes.License, error) {
|
||||
@@ -139,7 +180,7 @@ func (provider *provider) Refresh(ctx context.Context, organizationID valuer.UUI
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := provider.zeus.GetLicense(ctx, activeLicense.Key)
|
||||
zeusLicense, err := provider.zeus.GetLicense(ctx, activeLicense.Key)
|
||||
if err != nil {
|
||||
if time.Since(activeLicense.LastValidatedAt) > time.Duration(provider.config.FailureThreshold)*provider.config.PollInterval {
|
||||
activeLicense.UpdateFeatures(licensetypes.BasicPlan)
|
||||
@@ -154,7 +195,7 @@ func (provider *provider) Refresh(ctx context.Context, organizationID valuer.UUI
|
||||
return err
|
||||
}
|
||||
|
||||
err = activeLicense.Update(data)
|
||||
err = activeLicense.Update(zeusLicense)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to create license entity from license data")
|
||||
}
|
||||
|
||||
@@ -64,6 +64,22 @@ func (store *store) GetAll(ctx context.Context, organizationID valuer.UUID) ([]*
|
||||
return storableLicenses, nil
|
||||
}
|
||||
|
||||
func (store *store) Delete(ctx context.Context, organizationID valuer.UUID, licenseID valuer.UUID) error {
|
||||
_, err := store.
|
||||
sqlstore.
|
||||
BunDB().
|
||||
NewDelete().
|
||||
Model(new(licensetypes.StorableLicense)).
|
||||
Where("org_id = ?", organizationID).
|
||||
Where("id = ?", licenseID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "unable to delete license with ID: %s", licenseID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *store) Update(ctx context.Context, organizationID valuer.UUID, storableLicense *licensetypes.StorableLicense) error {
|
||||
_, err := store.
|
||||
sqlstore.
|
||||
|
||||
@@ -32,9 +32,9 @@ type module struct {
|
||||
tagModule tag.Module
|
||||
}
|
||||
|
||||
func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing, tagModule tag.Module) dashboard.Module {
|
||||
func NewModule(store dashboardtypes.Store, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing, tagModule tag.Module, systemDashboardRegistry dashboardtypes.SystemDashboardRegistry) dashboard.Module {
|
||||
scopedProviderSettings := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/ee/modules/dashboard/impldashboard")
|
||||
pkgDashboardModule := pkgimpldashboard.NewModule(store, settings, analytics, orgGetter, queryParser, tagModule)
|
||||
pkgDashboardModule := pkgimpldashboard.NewModule(store, settings, analytics, orgGetter, queryParser, tagModule, systemDashboardRegistry)
|
||||
|
||||
return &module{
|
||||
pkgDashboardModule: pkgDashboardModule,
|
||||
@@ -361,6 +361,14 @@ func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valu
|
||||
return module.pkgDashboardModule.LockUnlock(ctx, orgID, id, updatedBy, isAdmin, lock)
|
||||
}
|
||||
|
||||
func (module *module) ReconcileSystemDashboards(ctx context.Context, orgID valuer.UUID) error {
|
||||
return module.pkgDashboardModule.ReconcileSystemDashboards(ctx, orgID)
|
||||
}
|
||||
|
||||
func (module *module) GetSystemDashboard(ctx context.Context, orgID valuer.UUID, name string) (*dashboardtypes.DashboardV2, error) {
|
||||
return module.pkgDashboardModule.GetSystemDashboard(ctx, orgID, name)
|
||||
}
|
||||
|
||||
func (module *module) delete(ctx context.Context, orgID, 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) {
|
||||
|
||||
@@ -67,7 +67,7 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
|
||||
// note: add ee override methods first
|
||||
|
||||
// routes available only in ee version
|
||||
router.HandleFunc("/api/v1/features", am.ViewAccess(ah.getFeatureFlags)).Methods(http.MethodGet)
|
||||
router.HandleFunc("/api/v1/features", am.OpenAccess(ah.getFeatureFlags)).Methods(http.MethodGet)
|
||||
|
||||
// base overrides
|
||||
router.HandleFunc("/api/v1/version", am.OpenAccess(ah.getVersion)).Methods(http.MethodGet)
|
||||
@@ -76,11 +76,6 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
|
||||
router.HandleFunc("/api/v1/billing", am.AdminAccess(ah.getBilling)).Methods(http.MethodGet)
|
||||
router.HandleFunc("/api/v1/portal", am.AdminAccess(ah.LicensingAPI.Portal)).Methods(http.MethodPost)
|
||||
|
||||
// v3
|
||||
router.HandleFunc("/api/v3/licenses", am.AdminAccess(ah.LicensingAPI.Activate)).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v3/licenses", am.AdminAccess(ah.LicensingAPI.Refresh)).Methods(http.MethodPut)
|
||||
router.HandleFunc("/api/v3/licenses/active", am.ViewAccess(ah.LicensingAPI.GetActive)).Methods(http.MethodGet)
|
||||
|
||||
// v4
|
||||
router.HandleFunc("/api/v4/query_range", am.ViewAccess(ah.queryRangeV4)).Methods(http.MethodPost)
|
||||
|
||||
|
||||
@@ -5,12 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/SigNoz/signoz/ee/query-service/constants"
|
||||
"github.com/SigNoz/signoz/ee/query-service/model"
|
||||
"github.com/SigNoz/signoz/pkg/flagger"
|
||||
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||||
"github.com/SigNoz/signoz/pkg/types/featuretypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
type DayWiseBreakdown struct {
|
||||
@@ -57,11 +52,6 @@ type billingData struct {
|
||||
SubscriptionStatus string `json:"subscriptionStatus"`
|
||||
}
|
||||
|
||||
type billingDetails struct {
|
||||
Status string `json:"status"`
|
||||
Data billingData `json:"data"`
|
||||
}
|
||||
|
||||
func (ah *APIHandler) getBilling(w http.ResponseWriter, r *http.Request) {
|
||||
licenseKey := r.URL.Query().Get("licenseKey")
|
||||
|
||||
@@ -70,53 +60,17 @@ func (ah *APIHandler) getBilling(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||
data, err := ah.Signoz.Zeus.GetMeters(r.Context(), licenseKey)
|
||||
if err != nil {
|
||||
RespondError(w, model.InternalError(err), nil)
|
||||
return
|
||||
}
|
||||
|
||||
orgID := valuer.MustNewUUID(claims.OrgID)
|
||||
evalCtx := featuretypes.NewFlaggerEvaluationContext(orgID)
|
||||
useZeus := ah.Signoz.Flagger.BooleanOrEmpty(r.Context(), flagger.FeatureGetMetersFromZeus, evalCtx)
|
||||
|
||||
if useZeus {
|
||||
data, err := ah.Signoz.Zeus.GetMeters(r.Context(), licenseKey)
|
||||
if err != nil {
|
||||
RespondError(w, model.InternalError(err), nil)
|
||||
return
|
||||
}
|
||||
|
||||
var billing billingData
|
||||
if err := json.Unmarshal(data, &billing); err != nil {
|
||||
RespondError(w, model.InternalError(err), nil)
|
||||
return
|
||||
}
|
||||
|
||||
ah.Respond(w, billing)
|
||||
return
|
||||
}
|
||||
|
||||
billingURL := fmt.Sprintf("%s/usage?licenseKey=%s", constants.LicenseSignozIo, licenseKey)
|
||||
|
||||
hClient := &http.Client{}
|
||||
req, err := http.NewRequest("GET", billingURL, nil)
|
||||
if err != nil {
|
||||
RespondError(w, model.InternalError(err), nil)
|
||||
return
|
||||
}
|
||||
req.Header.Add("X-SigNoz-SecretKey", constants.LicenseAPIKey)
|
||||
billingResp, err := hClient.Do(req)
|
||||
if err != nil {
|
||||
var billing billingData
|
||||
if err := json.Unmarshal(data, &billing); err != nil {
|
||||
RespondError(w, model.InternalError(err), nil)
|
||||
return
|
||||
}
|
||||
|
||||
var billingResponse billingDetails
|
||||
if err := json.NewDecoder(billingResp.Body).Decode(&billingResponse); err != nil {
|
||||
RespondError(w, model.InternalError(err), nil)
|
||||
return
|
||||
}
|
||||
|
||||
ah.Respond(w, billingResponse.Data)
|
||||
ah.Respond(w, billing)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var LicenseSignozIo = "https://license.signoz.io/api/v1"
|
||||
var LicenseAPIKey = GetOrDefaultEnv("SIGNOZ_LICENSE_API_KEY", "")
|
||||
var SaasSegmentKey = GetOrDefaultEnv("SIGNOZ_SAAS_SEGMENT_KEY", "")
|
||||
var FetchFeatures = GetOrDefaultEnv("FETCH_FEATURES", "false")
|
||||
var ZeusFeaturesURL = GetOrDefaultEnv("ZEUS_FEATURES_URL", "ZeusFeaturesURL")
|
||||
|
||||
95
ee/subscription/httpsubscription/provider.go
Normal file
95
ee/subscription/httpsubscription/provider.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package httpsubscription
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/licensing"
|
||||
"github.com/SigNoz/signoz/pkg/subscription"
|
||||
"github.com/SigNoz/signoz/pkg/types/subscriptiontypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
const upstreamTimeout = 10 * time.Second
|
||||
|
||||
type provider struct {
|
||||
zeus zeus.Zeus
|
||||
licensing licensing.Licensing
|
||||
}
|
||||
|
||||
func New(zeus zeus.Zeus, licensing licensing.Licensing) subscription.Subscription {
|
||||
return &provider{
|
||||
zeus: zeus,
|
||||
licensing: licensing,
|
||||
}
|
||||
}
|
||||
|
||||
func (provider *provider) Create(ctx context.Context, organizationID valuer.UUID, postableSubscription *subscriptiontypes.PostableSubscription) (*subscriptiontypes.GettableSubscription, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, upstreamTimeout)
|
||||
defer cancel()
|
||||
|
||||
license, err := provider.licensing.GetActive(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := json.Marshal(postableSubscription)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to marshal subscription payload")
|
||||
}
|
||||
|
||||
response, err := provider.zeus.GetCheckoutURL(ctx, license.Key, body)
|
||||
if err != nil {
|
||||
if errors.Ast(err, errors.TypeAlreadyExists) {
|
||||
return nil, errors.WithAdditionalf(err, "checkout has already been completed for this account. Please click 'Refresh Status' to sync your subscription")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &subscriptiontypes.GettableSubscription{RedirectURL: gjson.GetBytes(response, "url").String()}, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Update(ctx context.Context, organizationID valuer.UUID, postableSubscription *subscriptiontypes.PostableSubscription) (*subscriptiontypes.GettableSubscription, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, upstreamTimeout)
|
||||
defer cancel()
|
||||
|
||||
license, err := provider.licensing.GetActive(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := json.Marshal(postableSubscription)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to marshal subscription payload")
|
||||
}
|
||||
|
||||
response, err := provider.zeus.GetPortalURL(ctx, license.Key, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &subscriptiontypes.GettableSubscription{RedirectURL: gjson.GetBytes(response, "url").String()}, nil
|
||||
}
|
||||
|
||||
func (provider *provider) Get(ctx context.Context, organizationID valuer.UUID) (*subscriptiontypes.GettableSubscriptionUsage, error) {
|
||||
license, err := provider.licensing.GetActive(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := provider.zeus.GetMeters(ctx, license.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
usage, err := subscriptiontypes.NewGettableSubscriptionUsage(data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, errors.TypeInternal, zeus.ErrCodeResponseMalformed, "failed to unmarshal subscription usage")
|
||||
}
|
||||
|
||||
return usage, nil
|
||||
}
|
||||
@@ -51,7 +51,7 @@ func New(ctx context.Context, providerSettings factory.ProviderSettings, config
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetLicense(ctx context.Context, key string) ([]byte, error) {
|
||||
func (provider *Provider) GetLicense(ctx context.Context, key string) (*zeustypes.License, error) {
|
||||
response, err := provider.do(
|
||||
ctx,
|
||||
provider.config.URL.JoinPath("/v2/licenses/me"),
|
||||
@@ -63,7 +63,12 @@ func (provider *Provider) GetLicense(ctx context.Context, key string) ([]byte, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []byte(gjson.GetBytes(response, "data").String()), nil
|
||||
license := new(zeustypes.License)
|
||||
if err := json.Unmarshal([]byte(gjson.GetBytes(response, "data").String()), license); err != nil {
|
||||
return nil, errors.Wrapf(err, errors.TypeInternal, zeus.ErrCodeResponseMalformed, "failed to unmarshal license data")
|
||||
}
|
||||
|
||||
return license, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) GetCheckoutURL(ctx context.Context, key string, body []byte) ([]byte, error) {
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
---
|
||||
name: scaffold-feature
|
||||
description: Scaffold the co-located feature structure in frontend/src. Use when creating a new page, feature, view (tab), or component folder, when a feature needs a shell with tabs, or when moving existing code out of src/container into src/pages. Generates the full folder tree (components/hooks/store/types/utils/constants/__tests__/README) with one command.
|
||||
---
|
||||
|
||||
# Scaffold a feature
|
||||
|
||||
The frontend is moving to a co-located layout (Bulletproof React / FSD): everything a
|
||||
feature owns lives in the feature's folder. Read `references/layout.md` for the full
|
||||
target structure and the rules about what may live where.
|
||||
|
||||
**Never hand-create these folders.** Run the generator so every feature comes out
|
||||
identical, then fill it in.
|
||||
|
||||
## Command
|
||||
|
||||
```bash
|
||||
pnpm scaffold page <Name> [options] # a page/feature under src/pages
|
||||
pnpm scaffold component <Name> [options] # a component folder
|
||||
```
|
||||
|
||||
| Option | Applies to | Effect |
|
||||
| --- | --- | --- |
|
||||
| `--views A,B,C` | `page` | Makes the page a shell with tab switching and generates one view folder per name. |
|
||||
| `--parent <path>` | `component` | Parent, relative to `src` (default `components`). A feature path like `pages/Traces/Explorer` nests the component under that feature's `components/`. |
|
||||
| `--full` | `component` | Also adds `components/`, `hooks/`, `store/`, `types.ts`, `utils.ts`, `constants.ts`, `README.md` for a component that owns children. |
|
||||
| `--no-tests` | both | Skips `__tests__/`. |
|
||||
| `--dry-run` | both | Prints what would be written, writes nothing. |
|
||||
| `--force` | both | Overwrites files that already exist (off by default; existing entries are reported as skipped). |
|
||||
|
||||
Folder names keep the casing you type, with the first letter forced up, so
|
||||
`LLMObservability` stays `LLMObservability` rather than being re-cased. Separated names
|
||||
collapse to PascalCase: `api-monitoring` and `api monitoring` both give
|
||||
`pages/ApiMonitoring`. Test ids, headings, tab paths and constants are all derived from
|
||||
that folder name — `TracesFunnels` gives `traces-funnels-page`, `Traces Funnels` and
|
||||
`TRACES_FUNNELS_TABS`.
|
||||
|
||||
## What you get
|
||||
|
||||
```
|
||||
pages/ApiMonitoring/
|
||||
index.tsx # the page component
|
||||
ApiMonitoring.module.scss
|
||||
components/ hooks/ store/ # empty, ready for the first file
|
||||
types.ts utils.ts constants.ts
|
||||
__tests__/ApiMonitoring.test.tsx
|
||||
README.md
|
||||
```
|
||||
|
||||
With `--views`, the root becomes a `RouteTab` shell (`index.tsx` + `constants.ts` with the
|
||||
tab definitions) and each view gets the tree above.
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
pnpm scaffold page ApiMonitoring # leaf page, no shell
|
||||
pnpm scaffold page Traces --views Explorer,Funnels,Views # shell + 3 views
|
||||
pnpm scaffold page Traces/Explorer # one more view under an existing shell
|
||||
pnpm scaffold component DataTable # global, src/components/DataTable
|
||||
pnpm scaffold component QueryBar --parent pages/Traces/Explorer # feature-local component
|
||||
```
|
||||
|
||||
## After generating
|
||||
|
||||
1. **Wire the route** (pages only) — the generator does not touch shared files:
|
||||
- add the path to `src/constants/routes.ts`
|
||||
- add a `Loadable` lazy import to `src/AppRoutes/pageComponents.ts`
|
||||
- add the entry to `src/AppRoutes/routes.ts`
|
||||
- for a shell, replace the local `BASE_PATH` strings in `constants.ts` with those `ROUTES` entries
|
||||
2. **Delete the placeholders you don't need** — empty `types.ts` / `utils.ts` /
|
||||
`constants.ts`, and any of `components/`, `hooks/`, `store/` the feature won't use.
|
||||
Those three folders are created empty; git only picks them up once they hold a file.
|
||||
3. **Fill the README** — the generated file has the prompts; a feature folder without a
|
||||
filled-in README is not done.
|
||||
4. **Follow the repo rules while filling it in**: `@signozhq/ui` + `@signozhq/icons` only,
|
||||
CSS Modules (`docs/css-modules-guide.md`), React Query for server state (prefer
|
||||
`api/generated` hooks), nuqs for URL state, Zustand for client state, `data-testid` on
|
||||
every interactive element.
|
||||
5. **Verify** before reporting done:
|
||||
```bash
|
||||
pnpm tsgo --noEmit
|
||||
pnpm oxlint src/pages/<Feature>
|
||||
pnpm jest src/pages/<Feature>
|
||||
```
|
||||
|
||||
## Editing the templates
|
||||
|
||||
Templates live in `templates/` — `feature/`, `shell/`, `component/` and
|
||||
`component-extras/` (the `--full` additions). Every template file ends in `.tmpl`, which
|
||||
keeps TypeScript, lint and your editor from reading them as source; the generator strips
|
||||
that suffix on the way out, so `index.tsx.tmpl` becomes `index.tsx`. Tokens are
|
||||
substituted in both file names and contents: `__Pascal__`, `__kebab__`, `__camel__`,
|
||||
`__CONST__`, `__Title__`. The shell's `constants.ts` additionally takes
|
||||
`__VIEW_IMPORTS__` and `__TAB_ENTRIES__`, which the generator builds from `--views`. The
|
||||
empty folders come from `FEATURE_DIRS` in `scaffold.mjs`. Change these, not the generated
|
||||
output, when the team's conventions move.
|
||||
@@ -1,102 +0,0 @@
|
||||
# Frontend layout
|
||||
|
||||
Target structure for `frontend/src`. Inspired by Bulletproof React and Feature-Sliced
|
||||
Design: a feature owns its components, hooks, state, types and tests, and nothing outside
|
||||
the feature folder reaches into it.
|
||||
|
||||
```
|
||||
src/
|
||||
app/ # bootstrap: routing, global styles/theme
|
||||
pages/
|
||||
Traces/ # has a shell
|
||||
index.tsx # shell — tab switching only
|
||||
constants.ts # tab definitions
|
||||
Explorer/ # a view
|
||||
index.tsx # view entry — composition, no business logic
|
||||
components/
|
||||
QueryBar/ # same shape as a global component, nests further as needed
|
||||
QueryBar.tsx
|
||||
QueryBar.module.scss
|
||||
components/
|
||||
hooks/
|
||||
__tests__/
|
||||
hooks/ # feature hooks + React Query wrappers over api/generated
|
||||
store/ # Zustand stores for feature-local client state
|
||||
types.ts
|
||||
utils.ts
|
||||
constants.ts
|
||||
__tests__/
|
||||
README.md
|
||||
Funnels/
|
||||
Views/
|
||||
ApiMonitoring/ # no shell — same shape, one level up
|
||||
index.tsx
|
||||
components/
|
||||
hooks/
|
||||
store/
|
||||
types.ts
|
||||
utils.ts
|
||||
constants.ts
|
||||
__tests__/
|
||||
README.md
|
||||
components/ # cross-feature components, same internal shape as above
|
||||
DataTable/
|
||||
DataTable.tsx
|
||||
DataTable.module.scss
|
||||
components/
|
||||
hooks/
|
||||
store/
|
||||
types.ts
|
||||
utils.ts
|
||||
constants.ts
|
||||
__tests__/
|
||||
README.md
|
||||
lib/
|
||||
utils/
|
||||
types/
|
||||
constants/
|
||||
store/ # app-wide client state only
|
||||
i18n/
|
||||
api/
|
||||
generated/ # Orval output — never edited by hand
|
||||
client/ # axios instances, interceptors, error handlers
|
||||
index.tsx
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- **Folder names are PascalCase**, spelled the way the feature is spelled in the product
|
||||
(`ApiMonitoring`, `LLMObservability`). This holds for shells, views and components alike.
|
||||
- **A page folder is the unit of ownership.** Anything used by exactly one feature lives
|
||||
inside it, however deeply nested. Promote to `src/components` / `src/utils` / `src/hooks`
|
||||
only when a second feature needs it.
|
||||
- **`index.tsx` is the entry**, and it composes. Business logic goes to `hooks/`, data
|
||||
shaping to `utils.ts`, state to `store/`.
|
||||
- **Nested components repeat the same shape.** A component folder may hold its own
|
||||
`components/`, `hooks/`, `store/`, `types.ts`, `utils.ts`, `constants.ts`, `__tests__/`.
|
||||
Nest as deep as ownership actually goes; don't flatten a component that owns children.
|
||||
- **Shell vs no shell.** A page with tabs gets a shell `index.tsx` whose only job is tab
|
||||
switching, plus one folder per view. A page without tabs is just the feature folder.
|
||||
- **Tests.** Feature-root tests in `__tests__/`; a component's tests next to the component
|
||||
(its own `__tests__/`). Never reach across features in a test.
|
||||
- **No barrel files.** A page's `index.tsx` is the route entry (a component), not a
|
||||
re-export hub. Import components by their own path.
|
||||
- **File size.** Split past ~300 LOC: extract components, and behaviour into
|
||||
`use<Component>Callbacks`-style hooks. More than ~3 type declarations in a file means a
|
||||
`types.ts`, and more than ~3 in `types.ts` means a `types/` folder.
|
||||
- **Styling.** CSS Modules (`<Name>.module.scss`) next to the component — see
|
||||
`docs/css-modules-guide.md`. Semantic tokens only.
|
||||
- **State.** Server → React Query (prefer `api/generated` hooks); URL → nuqs; client →
|
||||
Zustand, one store per file, always with a selector. No Redux or Context for new code.
|
||||
|
||||
## Migrating existing code
|
||||
|
||||
Most feature code still lives in `src/container` and `src/modules`, with a thin wrapper in
|
||||
`src/pages`. When touching one of those features:
|
||||
|
||||
1. Scaffold the target with `pnpm scaffold page <Name>` (see `../SKILL.md`).
|
||||
2. Move files in, one concern per commit — components, then hooks, then state.
|
||||
3. Update importers; keep `src/container/<Feature>` deleted, not re-exported. A shim
|
||||
directory is how the old layout survives.
|
||||
4. Do the dead-code pass first: unused props, exports, imports and debug logs go before the
|
||||
move, in their own commit.
|
||||
@@ -1,379 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
statSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs';
|
||||
import { dirname, join, relative, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const SKILL_DIR = dirname(fileURLToPath(import.meta.url));
|
||||
const TEMPLATES = join(SKILL_DIR, 'templates');
|
||||
const FRONTEND = resolve(SKILL_DIR, '..', '..', '..');
|
||||
const SRC = join(FRONTEND, 'src');
|
||||
|
||||
// Created empty, so the folder exists before it has a file to justify it.
|
||||
const FEATURE_DIRS = ['components', 'hooks', 'store'];
|
||||
|
||||
const USAGE = `usage:
|
||||
pnpm scaffold page <Name> [--views A,B,C] [--no-tests] [--dry-run] [--force]
|
||||
pnpm scaffold component <Name> [--parent <path>] [--full] [--no-tests] [--dry-run] [--force]
|
||||
|
||||
examples:
|
||||
pnpm scaffold page ApiMonitoring
|
||||
pnpm scaffold page Traces --views Explorer,Funnels,Views
|
||||
pnpm scaffold page Traces/Explorer
|
||||
pnpm scaffold component DataTable
|
||||
pnpm scaffold component QueryBar --parent pages/Traces/Explorer`;
|
||||
|
||||
function fail(message) {
|
||||
process.stderr.write(`error: ${message}\n\n${USAGE}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function expandEquals(argv) {
|
||||
return argv.flatMap((arg) =>
|
||||
arg.startsWith('--') && arg.includes('=')
|
||||
? [arg.slice(0, arg.indexOf('=')), arg.slice(arg.indexOf('=') + 1)]
|
||||
: [arg],
|
||||
);
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const flags = {
|
||||
views: [],
|
||||
parent: 'components',
|
||||
full: false,
|
||||
tests: true,
|
||||
dryRun: false,
|
||||
force: false,
|
||||
};
|
||||
const positional = [];
|
||||
const provided = new Set();
|
||||
|
||||
for (let i = 0; i < argv.length; i += 1) {
|
||||
const arg = argv[i];
|
||||
provided.add(arg);
|
||||
if (arg === '--views' || arg === '--parent') {
|
||||
const value = argv[i + 1];
|
||||
if (!value || value.startsWith('--')) {
|
||||
fail(`${arg} needs a value`);
|
||||
}
|
||||
if (arg === '--views') {
|
||||
flags.views = value
|
||||
.split(',')
|
||||
.map((view) => view.trim())
|
||||
.filter(Boolean);
|
||||
if (!flags.views.length) {
|
||||
fail('--views needs at least one name');
|
||||
}
|
||||
} else {
|
||||
flags.parent = value;
|
||||
}
|
||||
i += 1;
|
||||
} else if (arg === '--full') {
|
||||
flags.full = true;
|
||||
} else if (arg === '--no-tests') {
|
||||
flags.tests = false;
|
||||
} else if (arg === '--dry-run') {
|
||||
flags.dryRun = true;
|
||||
} else if (arg === '--force') {
|
||||
flags.force = true;
|
||||
} else if (arg === '-h' || arg === '--help') {
|
||||
process.stdout.write(`${USAGE}\n`);
|
||||
process.exit(0);
|
||||
} else if (arg.startsWith('-')) {
|
||||
fail(`unknown option: ${arg}`);
|
||||
} else {
|
||||
positional.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
return { positional, flags, provided };
|
||||
}
|
||||
|
||||
const capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
|
||||
|
||||
// Folder names keep the casing the author typed — only the first letter is forced
|
||||
// up — so acronyms like `LLMObservability` survive. Separated names
|
||||
// (`api-monitoring`, `api monitoring`) collapse to PascalCase.
|
||||
function toDirName(value) {
|
||||
const name = value.trim().replace(/[^a-zA-Z0-9\-_ ]/g, '');
|
||||
if (!name) {
|
||||
fail(`"${value}" has no usable name characters`);
|
||||
}
|
||||
return /[-_\s]/.test(name)
|
||||
? name
|
||||
.split(/[-_\s]+/)
|
||||
.filter(Boolean)
|
||||
.map(capitalize)
|
||||
.join('')
|
||||
: capitalize(name);
|
||||
}
|
||||
|
||||
const splitHumps = (name, separator) =>
|
||||
name
|
||||
.replace(/([a-z0-9])([A-Z])/g, `$1${separator}$2`)
|
||||
.replace(/([A-Z]+)([A-Z][a-z])/g, `$1${separator}$2`);
|
||||
|
||||
const toKebab = (value) => splitHumps(toDirName(value), '-').toLowerCase();
|
||||
const toTitle = (value) => splitHumps(toDirName(value), ' ');
|
||||
const toConst = (value) => toKebab(value).replace(/-/g, '_').toUpperCase();
|
||||
const toCamel = (value) => {
|
||||
const dir = toDirName(value);
|
||||
return dir.charAt(0).toLowerCase() + dir.slice(1);
|
||||
};
|
||||
|
||||
function tokensFor(name) {
|
||||
return {
|
||||
__Pascal__: toDirName(name),
|
||||
__kebab__: toKebab(name),
|
||||
__camel__: toCamel(name),
|
||||
__CONST__: toConst(name),
|
||||
__Title__: toTitle(name),
|
||||
};
|
||||
}
|
||||
|
||||
function substitute(text, tokens) {
|
||||
return Object.entries(tokens).reduce(
|
||||
(acc, [token, value]) => acc.split(token).join(value),
|
||||
text,
|
||||
);
|
||||
}
|
||||
|
||||
const created = [];
|
||||
const skipped = [];
|
||||
let targetExisted = false;
|
||||
|
||||
function writeFile(target, contents, flags) {
|
||||
const rel = relative(FRONTEND, target);
|
||||
if (existsSync(target) && !flags.force) {
|
||||
skipped.push(rel);
|
||||
return;
|
||||
}
|
||||
if (!flags.dryRun) {
|
||||
mkdirSync(dirname(target), { recursive: true });
|
||||
writeFileSync(target, contents);
|
||||
}
|
||||
created.push(rel);
|
||||
}
|
||||
|
||||
function createDirs(targetDir, dirs, flags) {
|
||||
for (const dir of dirs) {
|
||||
const target = join(targetDir, dir);
|
||||
const rel = `${relative(FRONTEND, target)}/`;
|
||||
if (existsSync(target)) {
|
||||
skipped.push(rel);
|
||||
continue;
|
||||
}
|
||||
if (!flags.dryRun) {
|
||||
mkdirSync(target, { recursive: true });
|
||||
}
|
||||
created.push(rel);
|
||||
}
|
||||
}
|
||||
|
||||
// Template files carry a `.tmpl` suffix so no TypeScript, lint or editor tooling
|
||||
// treats them as source; the suffix is dropped on the way out.
|
||||
function renderTree(templateDir, targetDir, tokens, flags) {
|
||||
for (const entry of readdirSync(templateDir).sort()) {
|
||||
const from = join(templateDir, entry);
|
||||
const name = substitute(entry.replace(/\.tmpl$/, ''), tokens);
|
||||
if (statSync(from).isDirectory()) {
|
||||
if (!flags.tests && name === '__tests__') {
|
||||
continue;
|
||||
}
|
||||
renderTree(from, join(targetDir, name), tokens, flags);
|
||||
} else {
|
||||
writeFile(
|
||||
join(targetDir, name),
|
||||
substitute(readFileSync(from, 'utf8'), tokens),
|
||||
flags,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function shellTokens(views) {
|
||||
const viewImports = views
|
||||
.map((view) => `import ${toDirName(view)} from './${toDirName(view)}';`)
|
||||
.join('\n');
|
||||
const tabEntries = views
|
||||
.map((view) => {
|
||||
const path = '`${BASE_PATH}/' + toKebab(view) + '`';
|
||||
return [
|
||||
'\t{',
|
||||
`\t\tComponent: ${toDirName(view)},`,
|
||||
`\t\tname: '${toTitle(view)}',`,
|
||||
`\t\troute: ${path},`,
|
||||
`\t\tkey: ${path},`,
|
||||
'\t},',
|
||||
].join('\n');
|
||||
})
|
||||
.join('\n');
|
||||
return { __VIEW_IMPORTS__: viewImports, __TAB_ENTRIES__: `${tabEntries}\n` };
|
||||
}
|
||||
|
||||
function scaffoldFeature(targetDir, name, flags) {
|
||||
renderTree(join(TEMPLATES, 'feature'), targetDir, tokensFor(name), flags);
|
||||
createDirs(targetDir, FEATURE_DIRS, flags);
|
||||
}
|
||||
|
||||
function scaffoldPage(name, flags) {
|
||||
const segments = name.split('/').filter(Boolean).map(toDirName);
|
||||
if (!segments.length) {
|
||||
fail('page needs a name');
|
||||
}
|
||||
|
||||
const viewDirs = flags.views.map(toDirName);
|
||||
const duplicate = viewDirs.find((dir, index) => viewDirs.indexOf(dir) !== index);
|
||||
if (duplicate) {
|
||||
fail(`duplicate view: ${duplicate}`);
|
||||
}
|
||||
|
||||
const targetDir = join(SRC, 'pages', ...segments);
|
||||
const leaf = segments[segments.length - 1];
|
||||
targetExisted = existsSync(targetDir);
|
||||
|
||||
if (flags.views.length) {
|
||||
renderTree(
|
||||
join(TEMPLATES, 'shell'),
|
||||
targetDir,
|
||||
{ ...tokensFor(leaf), ...shellTokens(flags.views) },
|
||||
flags,
|
||||
);
|
||||
for (const view of flags.views) {
|
||||
scaffoldFeature(join(targetDir, toDirName(view)), view, flags);
|
||||
}
|
||||
} else {
|
||||
scaffoldFeature(targetDir, leaf, flags);
|
||||
}
|
||||
|
||||
return targetDir;
|
||||
}
|
||||
|
||||
function resolveParent(parent) {
|
||||
const segments = parent
|
||||
.replace(/^src\//, '')
|
||||
.replace(/\/components\/?$/, '')
|
||||
.split('/')
|
||||
.filter(Boolean);
|
||||
if (segments[0] === 'pages') {
|
||||
return ['pages', ...segments.slice(1).map(toDirName)];
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
function scaffoldComponent(name, flags) {
|
||||
const tokens = tokensFor(name);
|
||||
const parent = resolveParent(flags.parent);
|
||||
const isGlobal = parent.length === 1 && parent[0] === 'components';
|
||||
const componentsDir = isGlobal
|
||||
? join(SRC, 'components')
|
||||
: join(SRC, ...parent, 'components');
|
||||
|
||||
if (relative(SRC, componentsDir).startsWith('..')) {
|
||||
fail(`--parent must stay inside src: ${flags.parent}`);
|
||||
}
|
||||
if (parent[0] === 'pages' && parent.length < 2) {
|
||||
fail('a component under pages/ needs a feature: --parent pages/<Feature>');
|
||||
}
|
||||
if (!isGlobal && !existsSync(join(SRC, ...parent))) {
|
||||
fail(`parent does not exist: src/${parent.join('/')}`);
|
||||
}
|
||||
|
||||
const targetDir = join(componentsDir, tokens.__Pascal__);
|
||||
targetExisted = existsSync(targetDir);
|
||||
|
||||
renderTree(join(TEMPLATES, 'component'), targetDir, tokens, flags);
|
||||
if (flags.full) {
|
||||
renderTree(join(TEMPLATES, 'component-extras'), targetDir, tokens, flags);
|
||||
createDirs(targetDir, FEATURE_DIRS, flags);
|
||||
}
|
||||
|
||||
return targetDir;
|
||||
}
|
||||
|
||||
function report(kind, targetDir, flags) {
|
||||
const rel = relative(FRONTEND, targetDir);
|
||||
const verb = flags.dryRun ? 'would create' : 'created';
|
||||
|
||||
if (targetExisted) {
|
||||
process.stdout.write(
|
||||
`\nwarning: ${rel} already existed — only missing entries were added\n`,
|
||||
);
|
||||
}
|
||||
|
||||
process.stdout.write(`\n${verb} ${created.length} entr(ies) in ${rel}\n`);
|
||||
for (const entry of created) {
|
||||
process.stdout.write(` + ${entry}\n`);
|
||||
}
|
||||
|
||||
if (skipped.length) {
|
||||
process.stdout.write(
|
||||
`\nskipped ${skipped.length} existing entr(ies) — pass --force to overwrite files\n`,
|
||||
);
|
||||
for (const entry of skipped) {
|
||||
process.stdout.write(` = ${entry}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
const steps =
|
||||
kind === 'page'
|
||||
? [
|
||||
'register the route: src/constants/routes.ts, src/AppRoutes/pageComponents.ts, src/AppRoutes/routes.ts',
|
||||
...(flags.views.length
|
||||
? ['swap BASE_PATH in constants.ts for the new ROUTES entries']
|
||||
: []),
|
||||
'delete the placeholders you do not need (empty types/utils/constants, unused folders)',
|
||||
'fill in README.md',
|
||||
`verify: pnpm tsgo --noEmit && pnpm oxlint ${rel} && pnpm jest ${rel}`,
|
||||
]
|
||||
: [
|
||||
'delete the placeholders you do not need (empty types/utils/constants, unused folders)',
|
||||
`verify: pnpm tsgo --noEmit && pnpm oxlint ${rel} && pnpm jest ${rel}`,
|
||||
];
|
||||
|
||||
process.stdout.write('\nnext:\n');
|
||||
steps.forEach((step, index) => {
|
||||
process.stdout.write(` ${index + 1}. ${step}\n`);
|
||||
});
|
||||
process.stdout.write(
|
||||
'\nnote: git does not track empty folders — components/, hooks/ and store/ only\n' +
|
||||
'show up in a commit once they hold a file.\n',
|
||||
);
|
||||
}
|
||||
|
||||
const { positional, flags, provided } = parseArgs(expandEquals(process.argv.slice(2)));
|
||||
const [kind, name] = positional;
|
||||
|
||||
if (!kind || !name) {
|
||||
fail('a command and a name are required');
|
||||
}
|
||||
if (positional.length > 2) {
|
||||
fail(`unexpected argument: ${positional[2]}`);
|
||||
}
|
||||
|
||||
function rejectFlags(unsupported) {
|
||||
for (const flag of unsupported) {
|
||||
if (provided.has(flag)) {
|
||||
fail(`${flag} does not apply to \`${kind}\``);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let targetDir;
|
||||
if (kind === 'page') {
|
||||
rejectFlags(['--parent', '--full']);
|
||||
targetDir = scaffoldPage(name, flags);
|
||||
} else if (kind === 'component') {
|
||||
rejectFlags(['--views']);
|
||||
targetDir = scaffoldComponent(name, flags);
|
||||
} else {
|
||||
fail(`unknown command: ${kind}`);
|
||||
}
|
||||
|
||||
report(kind, targetDir, flags);
|
||||
@@ -1,21 +0,0 @@
|
||||
# __Pascal__
|
||||
|
||||
<!-- What this component renders, and the features that use it. -->
|
||||
|
||||
## API
|
||||
|
||||
<!-- Props, and the behaviour each one controls. -->
|
||||
|
||||
## Structure
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| `__Pascal__.tsx` | The component. |
|
||||
| `__Pascal__.module.scss` | Styles. |
|
||||
| `components/` | Child components this one owns. |
|
||||
| `hooks/` | Behaviour extracted out of the component. |
|
||||
| `store/` | Zustand stores this component owns. |
|
||||
| `types.ts` | Types shared inside this folder. |
|
||||
| `utils.ts` | Pure helpers. |
|
||||
| `constants.ts` | Constants. |
|
||||
| `__tests__/` | Tests. |
|
||||
@@ -1,4 +0,0 @@
|
||||
.__camel__ {
|
||||
display: flex;
|
||||
color: var(--l1-foreground);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import styles from './__Pascal__.module.scss';
|
||||
|
||||
function __Pascal__(): JSX.Element {
|
||||
return <div className={styles.__camel__} data-testid="__kebab__" />;
|
||||
}
|
||||
|
||||
export default __Pascal__;
|
||||
@@ -1,11 +0,0 @@
|
||||
import { render, screen } from 'tests/test-utils';
|
||||
|
||||
import __Pascal__ from '../__Pascal__';
|
||||
|
||||
describe('__Pascal__', () => {
|
||||
it('renders', () => {
|
||||
render(<__Pascal__ />);
|
||||
|
||||
expect(screen.getByTestId('__kebab__')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
# __Title__
|
||||
|
||||
<!-- One paragraph: what this feature does, who uses it, and where it is reachable from. -->
|
||||
|
||||
## Structure
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| `index.tsx` | Feature entry. Composition only — no business logic. |
|
||||
| `components/` | Feature-local components, nested as `components/<Name>/`. |
|
||||
| `hooks/` | Feature hooks, including React Query wrappers over `api/generated`. |
|
||||
| `store/` | Zustand stores for feature-local client state. |
|
||||
| `types.ts` | Shared feature types. Split into `types/` past ~3 declarations. |
|
||||
| `utils.ts` | Pure helpers. |
|
||||
| `constants.ts` | Feature constants. |
|
||||
| `__tests__/` | Feature-root tests. Component tests live with the component. |
|
||||
|
||||
## Data
|
||||
|
||||
<!-- Endpoints this feature reads/writes, and the hooks that wrap them. -->
|
||||
|
||||
## State
|
||||
|
||||
<!-- What lives in the URL (nuqs), what lives in React Query, what lives in store/. -->
|
||||
|
||||
## Routing
|
||||
|
||||
<!-- Route key in constants/routes.ts, lazy import in AppRoutes/pageComponents.ts, entry in AppRoutes/routes.ts. -->
|
||||
@@ -1,12 +0,0 @@
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-3);
|
||||
padding: var(--spacing-4);
|
||||
background: var(--l1-background);
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--l1-foreground);
|
||||
font-size: var(--font-size-lg);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { render, screen } from 'tests/test-utils';
|
||||
|
||||
import __Pascal__ from '../index';
|
||||
|
||||
describe('__Pascal__', () => {
|
||||
it('renders the page', () => {
|
||||
render(<__Pascal__ />);
|
||||
|
||||
expect(screen.getByTestId('__kebab__-page')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import styles from './__Pascal__.module.scss';
|
||||
|
||||
function __Pascal__(): JSX.Element {
|
||||
return (
|
||||
<section className={styles.container} data-testid="__kebab__-page">
|
||||
<h1 className={styles.title}>__Title__</h1>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default __Pascal__;
|
||||
@@ -1,18 +0,0 @@
|
||||
# __Title__
|
||||
|
||||
<!-- One paragraph: what this section of the product is, and what each tab is for. -->
|
||||
|
||||
## Structure
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| `index.tsx` | Shell. Tab switching only — no feature logic. |
|
||||
| `constants.ts` | Tab definitions (`TabRoutes`). |
|
||||
| `<View>/` | One folder per tab, each a self-contained feature. |
|
||||
|
||||
## Routing
|
||||
|
||||
`constants.ts` builds tab paths from a local `BASE_PATH`. Register those paths in
|
||||
`src/constants/routes.ts`, add the lazy import to `src/AppRoutes/pageComponents.ts` and
|
||||
the entries to `src/AppRoutes/routes.ts`, then replace `BASE_PATH` with the `ROUTES`
|
||||
entries so there is a single source of truth for each path.
|
||||
@@ -1,6 +0,0 @@
|
||||
.shell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: var(--l1-background);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { render, screen } from 'tests/test-utils';
|
||||
|
||||
import __Pascal__ from '../index';
|
||||
|
||||
describe('__Pascal__', () => {
|
||||
it('renders the tab shell', () => {
|
||||
render(<__Pascal__ />);
|
||||
|
||||
expect(screen.getByTestId('__kebab__-shell')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import { TabRoutes } from 'components/RouteTab/types';
|
||||
|
||||
__VIEW_IMPORTS__
|
||||
|
||||
const BASE_PATH = '/__kebab__';
|
||||
|
||||
export const __CONST___TABS: TabRoutes[] = [
|
||||
__TAB_ENTRIES__];
|
||||
@@ -1,25 +0,0 @@
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import RouteTab from 'components/RouteTab';
|
||||
import history from 'lib/history';
|
||||
|
||||
import { __CONST___TABS } from './constants';
|
||||
|
||||
import styles from './__Pascal__.module.scss';
|
||||
|
||||
function __Pascal__(): JSX.Element {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
return (
|
||||
<div className={styles.shell} data-testid="__kebab__-shell">
|
||||
<RouteTab
|
||||
routes={__CONST___TABS}
|
||||
activeKey={pathname}
|
||||
history={history}
|
||||
showRightSection={false}
|
||||
defaultActiveKey={__CONST___TABS[0].key}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default __Pascal__;
|
||||
@@ -323,9 +323,10 @@
|
||||
"name": "react",
|
||||
"importNames": [
|
||||
"createContext",
|
||||
"useContext"
|
||||
"useContext",
|
||||
"useSyncExternalStore"
|
||||
],
|
||||
"message": "[State mgmt] React Context is deprecated. Migrate shared state to Zustand."
|
||||
"message": "[State mgmt] React Context and hand-rolled external stores are deprecated. Migrate shared state to Zustand."
|
||||
},
|
||||
{
|
||||
"name": "immer",
|
||||
@@ -565,12 +566,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// Root V2 pages own the dashboard fetch lifecycle; useDashboardFetchRequired wraps it.
|
||||
// Root dashboard pages own the fetch lifecycle; useDashboardFetchRequired wraps it.
|
||||
// Everywhere else must use useDashboardFetchRequired().
|
||||
"files": [
|
||||
"src/pages/DashboardPageV2/DashboardPageV2.tsx",
|
||||
"src/pages/DashboardPageV2/PanelEditorPage/PanelEditorPage.tsx",
|
||||
"src/pages/DashboardPageV2/DashboardContainer/hooks/useDashboardFetchRequired.ts"
|
||||
"src/pages/DashboardPage/DashboardPage.tsx",
|
||||
"src/pages/DashboardPage/PanelEditorPage/PanelEditorPage.tsx",
|
||||
"src/pages/DashboardPage/DashboardContainer/hooks/useDashboardFetchRequired.ts"
|
||||
],
|
||||
"rules": {
|
||||
"signoz/no-dashboard-fetch-outside-root": "off"
|
||||
|
||||
@@ -62,6 +62,40 @@ if (typeof window.ResizeObserver === 'undefined') {
|
||||
(window as any).ResizeObserver = ResizeObserverMock;
|
||||
}
|
||||
|
||||
if (typeof globalThis.DOMRect === 'undefined') {
|
||||
(globalThis as any).DOMRect = class DOMRect {
|
||||
x = 0;
|
||||
y = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
top = 0;
|
||||
right = 0;
|
||||
bottom = 0;
|
||||
left = 0;
|
||||
constructor(x = 0, y = 0, width = 0, height = 0) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.top = y;
|
||||
this.right = x + width;
|
||||
this.bottom = y + height;
|
||||
this.left = x;
|
||||
}
|
||||
toJSON(): any {
|
||||
return { x: this.x, y: this.y, width: this.width, height: this.height };
|
||||
}
|
||||
static fromRect(rect?: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
}): DOMRect {
|
||||
return new DOMRect(rect?.x, rect?.y, rect?.width, rect?.height);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Patch getComputedStyle to handle CSS parsing errors from @signozhq/* packages.
|
||||
// These packages inject CSS at import time via style-inject / vite-plugin-css-injected-by-js.
|
||||
// jsdom's nwsapi cannot parse some of the injected selectors (e.g. Tailwind's :animate-in),
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"i18n:generate-hash": "node ./i18-generate-hash.cjs",
|
||||
"dev": "vite",
|
||||
"scaffold": "node .claude/skills/scaffold-feature/scaffold.mjs",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prettify": "oxfmt",
|
||||
@@ -49,9 +48,9 @@
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@sentry/react": "10.57.0",
|
||||
"@sentry/vite-plugin": "5.3.0",
|
||||
"@signozhq/design-tokens": "2.1.4",
|
||||
"@signozhq/design-tokens": "2.1.6",
|
||||
"@signozhq/icons": "0.4.0",
|
||||
"@signozhq/ui": "0.0.23",
|
||||
"@signozhq/ui": "0.1.0",
|
||||
"@tanstack/react-table": "8.21.3",
|
||||
"@tanstack/react-virtual": "3.13.22",
|
||||
"@uiw/codemirror-theme-copilot": "4.23.11",
|
||||
@@ -239,4 +238,4 @@
|
||||
"tmp@<0.2.6": ">=0.2.6 <0.3.0",
|
||||
"yaml@>=1.0.0 <1.10.3": ">=1.10.3 <2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
823
frontend/pnpm-lock.yaml
generated
823
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,75 @@
|
||||
"tooltip_ms_teams_url": "The URL of the Microsoft Teams [webhook](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498) to send alerts to. Learn more about Microsoft Teams integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/ms-teams/).",
|
||||
"tooltip_google_chat_url": "The URL of the Google Chat space [incoming webhook](https://developers.google.com/workspace/chat/quickstart/webhooks) to send alerts to. It must be an https URL on chat.googleapis.com.",
|
||||
"google_chat_webhook_url_invalid": "Webhook URL must be an https URL on chat.googleapis.com",
|
||||
"field_jira_site": "Site URL",
|
||||
"tooltip_jira_site": "Your Jira Cloud base URL, e.g. https://your-domain.atlassian.net. Only Jira Cloud is supported.",
|
||||
"jira_site_invalid": "Site URL must be an https URL on an atlassian.net domain",
|
||||
"jira_required_fields": "Site URL, email, API token, project and issue type are required",
|
||||
"jira_service_account_tip": "Recommended: use a Jira service account so alerts aren't reported under a personal name and the channel keeps working when someone leaves.",
|
||||
"jira_service_account_tip_link": "Learn how",
|
||||
"field_jira_email": "Email",
|
||||
"help_jira_email": "The Atlassian account email used for authentication.",
|
||||
"field_jira_api_token": "API token",
|
||||
"help_jira_api_token": "Create one at id.atlassian.com under Security → API tokens.",
|
||||
"field_jira_project": "Project key",
|
||||
"field_jira_issue_type": "Issue type",
|
||||
"help_jira_issue_type": "An issue type that exists in the project, e.g. Task, Bug or Incident.",
|
||||
"field_jira_summary": "Summary (issue title)",
|
||||
"help_jira_summary": "Template for the Jira issue title.",
|
||||
"field_jira_description": "Description",
|
||||
"help_jira_description": "Template for the issue description. Rendered as rich text with a status panel and links back to SigNoz.",
|
||||
"jira_advanced_section": "Advanced Options",
|
||||
"field_jira_priority": "Priority",
|
||||
"placeholder_jira_priority": "Leave empty to use the project default",
|
||||
"help_jira_priority": "Must match a priority in the project's scheme, e.g. High.",
|
||||
"field_jira_labels": "Labels",
|
||||
"placeholder_jira_labels": "Type a label and press Enter",
|
||||
"help_jira_labels": "signoz and a deduplication label are added automatically.",
|
||||
"field_jira_resolve_transition": "Resolve transition",
|
||||
"field_jira_reopen_transition": "Reopen transition",
|
||||
"help_jira_resolve_transition": "When the alert resolves, SigNoz moves the Jira issue to a \"Done\" status via a workflow transition. This is auto-detected — leave it empty unless your project has more than one \"Done\" transition (e.g. Done vs. Won't Do) and you want to force a specific one by name.",
|
||||
"help_jira_reopen_transition": "When a resolved alert fires again (within the reopen window), SigNoz moves the issue back out of \"Done\" to an active status via a workflow transition. This is auto-detected — leave it empty unless you want to force a specific one by name (e.g. To Do or Reopen).",
|
||||
"placeholder_jira_resolve_transition": "Auto-detected, e.g. Done",
|
||||
"placeholder_jira_reopen_transition": "Auto-detected, e.g. To Do",
|
||||
"field_jira_wont_fix_resolution": "Won't-fix resolution",
|
||||
"help_jira_wont_fix_resolution": "If the issue was resolved with this resolution (e.g. Won't Do), SigNoz won't reopen it when the alert fires again; a new issue is created instead. Leave empty to always reopen.",
|
||||
"placeholder_jira_wont_fix_resolution": "e.g. Won't Do",
|
||||
"field_jira_reopen_duration": "Reopen window",
|
||||
"placeholder_jira_reopen_duration": "e.g. 72h",
|
||||
"help_jira_reopen_duration": "If a resolved alert fires again within this window, the same ticket is reopened; after the window, a re-fire opens a new ticket instead. Default: 3d.",
|
||||
"tooltip_jira_reopen_duration": "Accepted units: m (minutes), h (hours), d (days), w (weeks), y (years) — e.g. 30m, 72h or 3d. Minimum 1m.",
|
||||
"jira_reopen_duration_invalid": "Reopen window must be a duration like 30m, 72h or 3d (minimum 1m)",
|
||||
"jsmops_tip": "Create an API integration on your JSM team's Operations page and paste its key below.",
|
||||
"jsmops_tip_link": "Learn how",
|
||||
"field_jsmops_api_key": "API key",
|
||||
"help_jsmops_api_key": "The JSM Ops integration API key, from your team's Operations → Integrations → API. Make sure the integration is turned on.",
|
||||
"field_jsmops_message": "Message (alert title)",
|
||||
"help_jsmops_message": "Template for the alert title. Truncated to 130 characters.",
|
||||
"field_jsmops_description": "Description",
|
||||
"help_jsmops_description": "Template for the alert description. Rendered as rich text; kept under 15,000 characters.",
|
||||
"jsmops_advanced_section": "Advanced Options",
|
||||
"field_jsmops_priority": "Priority",
|
||||
"help_jsmops_priority": "Template resolving to one of P1–P5. Leave as-is to map from alert severity.",
|
||||
"field_jsmops_tags": "Tags",
|
||||
"placeholder_jsmops_tags": "Type a tag and press Enter",
|
||||
"help_jsmops_tags": "Tags added to every alert.",
|
||||
"incidentio_tip": "Create an HTTP alert source in incident.io (On-call \u2192 Alert routing \u2192 Sources) and paste its URL and token below.",
|
||||
"incidentio_tip_link": "Learn how",
|
||||
"field_incidentio_url": "Alert source URL",
|
||||
"help_incidentio_url": "The alert events URL from the source's setup page, e.g. https://api.incident.io/v2/alert_events/http/<source_config_id>.",
|
||||
"field_incidentio_token": "Token",
|
||||
"help_incidentio_token": "The alert source's secret token, from the same setup page.",
|
||||
"field_incidentio_title": "Title",
|
||||
"help_incidentio_title": "Template for the alert title. Kept stable while the alert fires \u2014 incident.io ignores content updates on repeat events.",
|
||||
"field_incidentio_description": "Description",
|
||||
"help_incidentio_description": "Template for the alert description. Markdown, rendered natively by incident.io.",
|
||||
"incidentio_required_fields": "Alert source URL and token are required",
|
||||
"incidentio_url_invalid": "URL must be an incident.io alert events URL (https://api.incident.io/v2/alert_events/http/<source_config_id>)",
|
||||
"field_incidentio_metadata": "Additional metadata",
|
||||
"help_incidentio_metadata": "Key-value pairs added to every alert's metadata, on top of the alert's labels (these win on a key clash). Values may use templates, e.g. {{ .CommonLabels.severity }}.",
|
||||
"placeholder_incidentio_metadata_key": "Key",
|
||||
"placeholder_incidentio_metadata_value": "Value",
|
||||
"button_incidentio_add_metadata": "Add metadata",
|
||||
|
||||
"field_slack_recipient": "Recipient",
|
||||
"field_slack_title": "Title",
|
||||
|
||||
@@ -26,6 +26,75 @@
|
||||
"tooltip_ms_teams_url": "The URL of the Microsoft Teams [webhook](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498) to send alerts to. Learn more about Microsoft Teams integration in the docs [here](https://signoz.io/docs/alerts-management/notification-channel/ms-teams/).",
|
||||
"tooltip_google_chat_url": "The URL of the Google Chat space [incoming webhook](https://developers.google.com/workspace/chat/quickstart/webhooks) to send alerts to. It must be an https URL on chat.googleapis.com.",
|
||||
"google_chat_webhook_url_invalid": "Webhook URL must be an https URL on chat.googleapis.com",
|
||||
"field_jira_site": "Site URL",
|
||||
"tooltip_jira_site": "Your Jira Cloud base URL, e.g. https://your-domain.atlassian.net. Only Jira Cloud is supported.",
|
||||
"jira_site_invalid": "Site URL must be an https URL on an atlassian.net domain",
|
||||
"jira_required_fields": "Site URL, email, API token, project and issue type are required",
|
||||
"jira_service_account_tip": "Recommended: use a Jira service account so alerts aren't reported under a personal name and the channel keeps working when someone leaves.",
|
||||
"jira_service_account_tip_link": "Learn how",
|
||||
"field_jira_email": "Email",
|
||||
"help_jira_email": "The Atlassian account email used for authentication.",
|
||||
"field_jira_api_token": "API token",
|
||||
"help_jira_api_token": "Create one at id.atlassian.com under Security → API tokens.",
|
||||
"field_jira_project": "Project key",
|
||||
"field_jira_issue_type": "Issue type",
|
||||
"help_jira_issue_type": "An issue type that exists in the project, e.g. Task, Bug or Incident.",
|
||||
"field_jira_summary": "Summary (issue title)",
|
||||
"help_jira_summary": "Template for the Jira issue title.",
|
||||
"field_jira_description": "Description",
|
||||
"help_jira_description": "Template for the issue description. Rendered as rich text with a status panel and links back to SigNoz.",
|
||||
"jira_advanced_section": "Advanced Options",
|
||||
"field_jira_priority": "Priority",
|
||||
"placeholder_jira_priority": "Leave empty to use the project default",
|
||||
"help_jira_priority": "Must match a priority in the project's scheme, e.g. High.",
|
||||
"field_jira_labels": "Labels",
|
||||
"placeholder_jira_labels": "Type a label and press Enter",
|
||||
"help_jira_labels": "signoz and a deduplication label are added automatically.",
|
||||
"field_jira_resolve_transition": "Resolve transition",
|
||||
"field_jira_reopen_transition": "Reopen transition",
|
||||
"help_jira_resolve_transition": "When the alert resolves, SigNoz moves the Jira issue to a \"Done\" status via a workflow transition. This is auto-detected — leave it empty unless your project has more than one \"Done\" transition (e.g. Done vs. Won't Do) and you want to force a specific one by name.",
|
||||
"help_jira_reopen_transition": "When a resolved alert fires again (within the reopen window), SigNoz moves the issue back out of \"Done\" to an active status via a workflow transition. This is auto-detected — leave it empty unless you want to force a specific one by name (e.g. To Do or Reopen).",
|
||||
"placeholder_jira_resolve_transition": "Auto-detected, e.g. Done",
|
||||
"placeholder_jira_reopen_transition": "Auto-detected, e.g. To Do",
|
||||
"field_jira_wont_fix_resolution": "Won't-fix resolution",
|
||||
"help_jira_wont_fix_resolution": "If the issue was resolved with this resolution (e.g. Won't Do), SigNoz won't reopen it when the alert fires again; a new issue is created instead. Leave empty to always reopen.",
|
||||
"placeholder_jira_wont_fix_resolution": "e.g. Won't Do",
|
||||
"field_jira_reopen_duration": "Reopen window",
|
||||
"placeholder_jira_reopen_duration": "e.g. 72h",
|
||||
"help_jira_reopen_duration": "If a resolved alert fires again within this window, the same ticket is reopened; after the window, a re-fire opens a new ticket instead. Default: 3d.",
|
||||
"tooltip_jira_reopen_duration": "Accepted units: m (minutes), h (hours), d (days), w (weeks), y (years) — e.g. 30m, 72h or 3d. Minimum 1m.",
|
||||
"jira_reopen_duration_invalid": "Reopen window must be a duration like 30m, 72h or 3d (minimum 1m)",
|
||||
"jsmops_tip": "Create an API integration on your JSM team's Operations page and paste its key below.",
|
||||
"jsmops_tip_link": "Learn how",
|
||||
"field_jsmops_api_key": "API key",
|
||||
"help_jsmops_api_key": "The JSM Ops integration API key, from your team's Operations → Integrations → API. Make sure the integration is turned on.",
|
||||
"field_jsmops_message": "Message (alert title)",
|
||||
"help_jsmops_message": "Template for the alert title. Truncated to 130 characters.",
|
||||
"field_jsmops_description": "Description",
|
||||
"help_jsmops_description": "Template for the alert description. Rendered as rich text; kept under 15,000 characters.",
|
||||
"jsmops_advanced_section": "Advanced Options",
|
||||
"field_jsmops_priority": "Priority",
|
||||
"help_jsmops_priority": "Template resolving to one of P1–P5. Leave as-is to map from alert severity.",
|
||||
"field_jsmops_tags": "Tags",
|
||||
"placeholder_jsmops_tags": "Type a tag and press Enter",
|
||||
"help_jsmops_tags": "Tags added to every alert.",
|
||||
"incidentio_tip": "Create an HTTP alert source in incident.io (On-call \u2192 Alert routing \u2192 Sources) and paste its URL and token below.",
|
||||
"incidentio_tip_link": "Learn how",
|
||||
"field_incidentio_url": "Alert source URL",
|
||||
"help_incidentio_url": "The alert events URL from the source's setup page, e.g. https://api.incident.io/v2/alert_events/http/<source_config_id>.",
|
||||
"field_incidentio_token": "Token",
|
||||
"help_incidentio_token": "The alert source's secret token, from the same setup page.",
|
||||
"field_incidentio_title": "Title",
|
||||
"help_incidentio_title": "Template for the alert title. Kept stable while the alert fires \u2014 incident.io ignores content updates on repeat events.",
|
||||
"field_incidentio_description": "Description",
|
||||
"help_incidentio_description": "Template for the alert description. Markdown, rendered natively by incident.io.",
|
||||
"incidentio_required_fields": "Alert source URL and token are required",
|
||||
"incidentio_url_invalid": "URL must be an incident.io alert events URL (https://api.incident.io/v2/alert_events/http/<source_config_id>)",
|
||||
"field_incidentio_metadata": "Additional metadata",
|
||||
"help_incidentio_metadata": "Key-value pairs added to every alert's metadata, on top of the alert's labels (these win on a key clash). Values may use templates, e.g. {{ .CommonLabels.severity }}.",
|
||||
"placeholder_incidentio_metadata_key": "Key",
|
||||
"placeholder_incidentio_metadata_value": "Value",
|
||||
"button_incidentio_add_metadata": "Add metadata",
|
||||
"field_slack_recipient": "Recipient",
|
||||
"field_slack_title": "Title",
|
||||
"field_slack_description": "Description",
|
||||
|
||||
@@ -103,30 +103,30 @@ function createMockLicense(
|
||||
overrides: Partial<LicenseResModel> = {},
|
||||
): LicenseResModel {
|
||||
return {
|
||||
key: 'test-key',
|
||||
event_queue: {
|
||||
created_at: '0',
|
||||
id: 'test-license-id',
|
||||
eventQueue: {
|
||||
createdAt: '0',
|
||||
event: LicenseEvent.NO_EVENT,
|
||||
scheduled_at: '0',
|
||||
scheduledAt: '0',
|
||||
status: '',
|
||||
updated_at: '0',
|
||||
updatedAt: '0',
|
||||
},
|
||||
state: LicenseState.ACTIVATED,
|
||||
status: LicenseStatus.VALID,
|
||||
platform: LicensePlatform.CLOUD,
|
||||
created_at: '0',
|
||||
createdAt: '0',
|
||||
plan: {
|
||||
created_at: '0',
|
||||
id: '0',
|
||||
createdAt: '0',
|
||||
description: '',
|
||||
is_active: true,
|
||||
isActive: true,
|
||||
name: '',
|
||||
updated_at: '0',
|
||||
updatedAt: '0',
|
||||
},
|
||||
plan_id: '0',
|
||||
free_until: '0',
|
||||
updated_at: '0',
|
||||
valid_from: 0,
|
||||
valid_until: 0,
|
||||
freeUntil: '0',
|
||||
updatedAt: '0',
|
||||
validFrom: 0,
|
||||
validUntil: 0,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
@@ -850,6 +850,22 @@ describe('PrivateRoute', () => {
|
||||
assertStaysOnRoute(ROUTES.WORKSPACE_LOCKED);
|
||||
});
|
||||
|
||||
it('should keep a custom role (ANONYMOUS) on workspace locked instead of bouncing to unauthorized', () => {
|
||||
renderPrivateRoute({
|
||||
initialRoute: ROUTES.WORKSPACE_LOCKED,
|
||||
appContext: {
|
||||
isLoggedIn: true,
|
||||
isFetchingActiveLicense: false,
|
||||
activeLicense: createMockLicense({ platform: LicensePlatform.CLOUD }),
|
||||
trialInfo: createMockTrialInfo({ workSpaceBlock: true }),
|
||||
user: createMockUser({ role: USER_ROLES.ANONYMOUS as ROLES }),
|
||||
},
|
||||
isCloudUser: true,
|
||||
});
|
||||
|
||||
assertStaysOnRoute(ROUTES.WORKSPACE_LOCKED);
|
||||
});
|
||||
|
||||
it('should not redirect self-hosted users to workspace locked even when workSpaceBlock is true', () => {
|
||||
renderPrivateRoute({
|
||||
initialRoute: ROUTES.HOME,
|
||||
@@ -1024,6 +1040,24 @@ describe('PrivateRoute', () => {
|
||||
assertStaysOnRoute(ROUTES.WORKSPACE_SUSPENDED);
|
||||
});
|
||||
|
||||
it('should keep a custom role (ANONYMOUS) on workspace suspended instead of bouncing to unauthorized', () => {
|
||||
renderPrivateRoute({
|
||||
initialRoute: ROUTES.WORKSPACE_SUSPENDED,
|
||||
appContext: {
|
||||
isLoggedIn: true,
|
||||
isFetchingActiveLicense: false,
|
||||
activeLicense: createMockLicense({
|
||||
platform: LicensePlatform.CLOUD,
|
||||
state: LicenseState.DEFAULTED,
|
||||
}),
|
||||
user: createMockUser({ role: USER_ROLES.ANONYMOUS as ROLES }),
|
||||
},
|
||||
isCloudUser: true,
|
||||
});
|
||||
|
||||
assertStaysOnRoute(ROUTES.WORKSPACE_SUSPENDED);
|
||||
});
|
||||
|
||||
it('should not redirect self-hosted users to workspace suspended when license is defaulted', () => {
|
||||
renderPrivateRoute({
|
||||
initialRoute: ROUTES.HOME,
|
||||
@@ -1580,6 +1614,18 @@ describe('PrivateRoute', () => {
|
||||
path: ROUTES.SUPPORT,
|
||||
deniedRoles: [USER_ROLES.AUTHOR as ROLES],
|
||||
},
|
||||
WORKSPACE_LOCKED: {
|
||||
path: ROUTES.WORKSPACE_LOCKED,
|
||||
deniedRoles: DENIED_ROLES,
|
||||
},
|
||||
WORKSPACE_SUSPENDED: {
|
||||
path: ROUTES.WORKSPACE_SUSPENDED,
|
||||
deniedRoles: DENIED_ROLES,
|
||||
},
|
||||
WORKSPACE_ACCESS_RESTRICTED: {
|
||||
path: ROUTES.WORKSPACE_ACCESS_RESTRICTED,
|
||||
deniedRoles: DENIED_ROLES,
|
||||
},
|
||||
};
|
||||
|
||||
const authzRouteRolePairs: [string, string, ROLES][] = Object.entries(
|
||||
|
||||
@@ -102,15 +102,10 @@ export const DashboardPage = Loadable(
|
||||
() => import(/* webpackChunkName: "DashboardPage" */ 'pages/DashboardPage'),
|
||||
);
|
||||
|
||||
export const DashboardWidget = Loadable(
|
||||
() =>
|
||||
import(/* webpackChunkName: "DashboardWidgetPage" */ 'pages/DashboardWidget'),
|
||||
);
|
||||
|
||||
export const DashboardPanelEditorPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "DashboardPanelEditorPage" */ 'pages/DashboardPageV2/PanelEditorPage/PanelEditorPage'
|
||||
/* webpackChunkName: "DashboardPanelEditorPage" */ 'pages/DashboardPage/PanelEditorPage/PanelEditorPage'
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
DashboardPage,
|
||||
DashboardPanelEditorPage,
|
||||
DashboardsListPage,
|
||||
DashboardWidget,
|
||||
EditRulesPage,
|
||||
ErrorDetails,
|
||||
ForgotPassword,
|
||||
@@ -183,13 +182,6 @@ const routes: AppRoutes[] = [
|
||||
isPrivate: false,
|
||||
key: 'PUBLIC_DASHBOARD',
|
||||
},
|
||||
{
|
||||
path: ROUTES.DASHBOARD_WIDGET,
|
||||
exact: true,
|
||||
component: DashboardWidget,
|
||||
isPrivate: true,
|
||||
key: 'DASHBOARD_WIDGET',
|
||||
},
|
||||
{
|
||||
path: ROUTES.DASHBOARD_PANEL_EDITOR,
|
||||
exact: true,
|
||||
|
||||
@@ -53,7 +53,7 @@ export function ErrorResponseHandler(error: AxiosError): ErrorResponse {
|
||||
};
|
||||
}
|
||||
// anything else
|
||||
console.error('any');
|
||||
console.error('ErrorResponseHandler: unclassified error');
|
||||
return {
|
||||
statusCode: 500,
|
||||
payload: null,
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { DEFAULT_TIME_RANGE } from 'container/TopNav/DateTimeSelectionV2/constants';
|
||||
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>> => {
|
||||
|
||||
const { dashboardId, timeRangeEnabled = false, defaultTimeRange = DEFAULT_TIME_RANGE } = props;
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
`/dashboards/${dashboardId}/public`,
|
||||
{ timeRangeEnabled, defaultTimeRange },
|
||||
);
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default createPublicDashboard;
|
||||
@@ -1,27 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
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}`);
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default getPublicDashboardData;
|
||||
@@ -1,27 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
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`);
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default getPublicDashboardMeta;
|
||||
@@ -1,34 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { MetricRangePayloadV5 } from 'api/v5/v5';
|
||||
import { AxiosError } from 'axios';
|
||||
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`, {
|
||||
params: {
|
||||
startTime: props.startTime,
|
||||
endTime: props.endTime,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default getPublicDashboardWidgetData;
|
||||
@@ -1,29 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
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>> => {
|
||||
try {
|
||||
const response = await axios.delete<PayloadProps>(`/dashboards/${props.id}/public`);
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default revokePublicDashboardAccess;
|
||||
@@ -1,36 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { DEFAULT_TIME_RANGE } from 'container/TopNav/DateTimeSelectionV2/constants';
|
||||
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>> => {
|
||||
|
||||
const { dashboardId, timeRangeEnabled = false, defaultTimeRange = DEFAULT_TIME_RANGE } = props;
|
||||
|
||||
try {
|
||||
const response = await axios.put(
|
||||
`/dashboards/${dashboardId}/public`,
|
||||
{ timeRangeEnabled, defaultTimeRange },
|
||||
);
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default updatePublicDashboard;
|
||||
@@ -46,6 +46,8 @@ import type {
|
||||
GetPublicDashboardPathParameters,
|
||||
GetPublicDashboardWidgetQueryRange200,
|
||||
GetPublicDashboardWidgetQueryRangePathParameters,
|
||||
GetSystemDashboard200,
|
||||
GetSystemDashboardPathParameters,
|
||||
ListDashboardViews200,
|
||||
ListDashboardsForUserV2200,
|
||||
ListDashboardsForUserV2Params,
|
||||
@@ -1885,6 +1887,108 @@ export const useMigrateDashboardV2 = <
|
||||
> => {
|
||||
return useMutation(getMigrateDashboardV2MutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* Returns a dashboard SigNoz ships and owns, addressed by its stable definition name (e.g. `ai-o11y-overview`) rather than its id. System dashboards are read-only and upgraded through releases. The dashboard's own `name` field carries a reserved prefix that the path segment must not include.
|
||||
* @summary Get system dashboard
|
||||
*/
|
||||
export const getSystemDashboard = (
|
||||
{ name }: GetSystemDashboardPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetSystemDashboard200>({
|
||||
url: `/api/v2/dashboards/system/${name}`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetSystemDashboardQueryKey = ({
|
||||
name,
|
||||
}: GetSystemDashboardPathParameters) => {
|
||||
return [`/api/v2/dashboards/system/${name}`] as const;
|
||||
};
|
||||
|
||||
export const getGetSystemDashboardQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getSystemDashboard>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ name }: GetSystemDashboardPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getSystemDashboard>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetSystemDashboardQueryKey({ name });
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getSystemDashboard>>
|
||||
> = ({ signal }) => getSystemDashboard({ name }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!name,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getSystemDashboard>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetSystemDashboardQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getSystemDashboard>>
|
||||
>;
|
||||
export type GetSystemDashboardQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get system dashboard
|
||||
*/
|
||||
|
||||
export function useGetSystemDashboard<
|
||||
TData = Awaited<ReturnType<typeof getSystemDashboard>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ name }: GetSystemDashboardPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getSystemDashboard>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetSystemDashboardQueryOptions({ name }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get system dashboard
|
||||
*/
|
||||
export const invalidateGetSystemDashboard = async (
|
||||
queryClient: QueryClient,
|
||||
{ name }: GetSystemDashboardPathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetSystemDashboardQueryKey({ name }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint returns the sanitized v2-shape dashboard data for public access. Each panel query is reduced to a safe field subset, so filters and raw query strings are not exposed.
|
||||
* @summary Get public dashboard data (v2)
|
||||
|
||||
@@ -21,18 +21,28 @@ import type {
|
||||
CreateIngestionKey201,
|
||||
CreateIngestionKeyLimit201,
|
||||
CreateIngestionKeyLimitPathParameters,
|
||||
CreateIngestionLimit201,
|
||||
DeleteIngestionKeyLimitPathParameters,
|
||||
DeleteIngestionKeyPathParameters,
|
||||
DeleteIngestionLimitPathParameters,
|
||||
GatewaytypesDeprecatedPostableIngestionKeyLimitDTO,
|
||||
GatewaytypesPostableIngestionKeyDTO,
|
||||
GatewaytypesPostableIngestionKeyLimitDTO,
|
||||
GatewaytypesUpdatableIngestionKeyLimitDTO,
|
||||
GetIngestionKey200,
|
||||
GetIngestionKeyLimits200,
|
||||
GetIngestionKeyLimitsPathParameters,
|
||||
GetIngestionKeyPathParameters,
|
||||
GetIngestionKeys200,
|
||||
GetIngestionKeysParams,
|
||||
GetIngestionLimit200,
|
||||
GetIngestionLimitPathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
SearchIngestionKeys200,
|
||||
SearchIngestionKeysParams,
|
||||
UpdateIngestionKeyLimitPathParameters,
|
||||
UpdateIngestionKeyPathParameters,
|
||||
UpdateIngestionLimitPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
@@ -300,6 +310,108 @@ export const useDeleteIngestionKey = <
|
||||
> => {
|
||||
return useMutation(getDeleteIngestionKeyMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint returns an ingestion key for the workspace
|
||||
* @summary Get ingestion key for workspace
|
||||
*/
|
||||
export const getIngestionKey = (
|
||||
{ keyId }: GetIngestionKeyPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetIngestionKey200>({
|
||||
url: `/api/v2/gateway/ingestion_keys/${keyId}`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetIngestionKeyQueryKey = ({
|
||||
keyId,
|
||||
}: GetIngestionKeyPathParameters) => {
|
||||
return [`/api/v2/gateway/ingestion_keys/${keyId}`] as const;
|
||||
};
|
||||
|
||||
export const getGetIngestionKeyQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getIngestionKey>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ keyId }: GetIngestionKeyPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKey>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetIngestionKeyQueryKey({ keyId });
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getIngestionKey>>> = ({
|
||||
signal,
|
||||
}) => getIngestionKey({ keyId }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!keyId,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKey>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetIngestionKeyQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getIngestionKey>>
|
||||
>;
|
||||
export type GetIngestionKeyQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get ingestion key for workspace
|
||||
*/
|
||||
|
||||
export function useGetIngestionKey<
|
||||
TData = Awaited<ReturnType<typeof getIngestionKey>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ keyId }: GetIngestionKeyPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKey>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetIngestionKeyQueryOptions({ keyId }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get ingestion key for workspace
|
||||
*/
|
||||
export const invalidateGetIngestionKey = async (
|
||||
queryClient: QueryClient,
|
||||
{ keyId }: GetIngestionKeyPathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetIngestionKeyQueryKey({ keyId }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint updates an ingestion key for the workspace
|
||||
* @summary Update ingestion key for workspace
|
||||
@@ -400,19 +512,122 @@ export const useUpdateIngestionKey = <
|
||||
return useMutation(getUpdateIngestionKeyMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint creates an ingestion key limit
|
||||
* This endpoint returns the ingestion limits for an ingestion key
|
||||
* @summary Get limits for the ingestion key
|
||||
*/
|
||||
export const getIngestionKeyLimits = (
|
||||
{ keyId }: GetIngestionKeyLimitsPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetIngestionKeyLimits200>({
|
||||
url: `/api/v2/gateway/ingestion_keys/${keyId}/limits`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetIngestionKeyLimitsQueryKey = ({
|
||||
keyId,
|
||||
}: GetIngestionKeyLimitsPathParameters) => {
|
||||
return [`/api/v2/gateway/ingestion_keys/${keyId}/limits`] as const;
|
||||
};
|
||||
|
||||
export const getGetIngestionKeyLimitsQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getIngestionKeyLimits>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ keyId }: GetIngestionKeyLimitsPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeyLimits>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetIngestionKeyLimitsQueryKey({ keyId });
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getIngestionKeyLimits>>
|
||||
> = ({ signal }) => getIngestionKeyLimits({ keyId }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!keyId,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeyLimits>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetIngestionKeyLimitsQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getIngestionKeyLimits>>
|
||||
>;
|
||||
export type GetIngestionKeyLimitsQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get limits for the ingestion key
|
||||
*/
|
||||
|
||||
export function useGetIngestionKeyLimits<
|
||||
TData = Awaited<ReturnType<typeof getIngestionKeyLimits>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ keyId }: GetIngestionKeyLimitsPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionKeyLimits>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetIngestionKeyLimitsQueryOptions({ keyId }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get limits for the ingestion key
|
||||
*/
|
||||
export const invalidateGetIngestionKeyLimits = async (
|
||||
queryClient: QueryClient,
|
||||
{ keyId }: GetIngestionKeyLimitsPathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetIngestionKeyLimitsQueryKey({ keyId }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint creates an ingestion key limit.
|
||||
* @deprecated
|
||||
* @summary Create limit for the ingestion key
|
||||
*/
|
||||
export const createIngestionKeyLimit = (
|
||||
{ keyId }: CreateIngestionKeyLimitPathParameters,
|
||||
gatewaytypesPostableIngestionKeyLimitDTO?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>,
|
||||
gatewaytypesDeprecatedPostableIngestionKeyLimitDTO?: BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<CreateIngestionKeyLimit201>({
|
||||
url: `/api/v2/gateway/ingestion_keys/${keyId}/limits`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: gatewaytypesPostableIngestionKeyLimitDTO,
|
||||
data: gatewaytypesDeprecatedPostableIngestionKeyLimitDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
@@ -426,7 +641,7 @@ export const getCreateIngestionKeyLimitMutationOptions = <
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateIngestionKeyLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
|
||||
data?: BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
@@ -435,7 +650,7 @@ export const getCreateIngestionKeyLimitMutationOptions = <
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateIngestionKeyLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
|
||||
data?: BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
@@ -452,7 +667,7 @@ export const getCreateIngestionKeyLimitMutationOptions = <
|
||||
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
|
||||
{
|
||||
pathParams: CreateIngestionKeyLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
|
||||
data?: BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
@@ -467,12 +682,13 @@ export type CreateIngestionKeyLimitMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createIngestionKeyLimit>>
|
||||
>;
|
||||
export type CreateIngestionKeyLimitMutationBody =
|
||||
| BodyType<GatewaytypesPostableIngestionKeyLimitDTO>
|
||||
| BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>
|
||||
| undefined;
|
||||
export type CreateIngestionKeyLimitMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @summary Create limit for the ingestion key
|
||||
*/
|
||||
export const useCreateIngestionKeyLimit = <
|
||||
@@ -484,7 +700,7 @@ export const useCreateIngestionKeyLimit = <
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateIngestionKeyLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
|
||||
data?: BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
@@ -493,7 +709,7 @@ export const useCreateIngestionKeyLimit = <
|
||||
TError,
|
||||
{
|
||||
pathParams: CreateIngestionKeyLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
|
||||
data?: BodyType<GatewaytypesDeprecatedPostableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
@@ -501,6 +717,7 @@ export const useCreateIngestionKeyLimit = <
|
||||
};
|
||||
/**
|
||||
* This endpoint deletes an ingestion key limit
|
||||
* @deprecated
|
||||
* @summary Delete limit for the ingestion key
|
||||
*/
|
||||
export const deleteIngestionKeyLimit = (
|
||||
@@ -559,6 +776,7 @@ export type DeleteIngestionKeyLimitMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @summary Delete limit for the ingestion key
|
||||
*/
|
||||
export const useDeleteIngestionKeyLimit = <
|
||||
@@ -580,7 +798,8 @@ export const useDeleteIngestionKeyLimit = <
|
||||
return useMutation(getDeleteIngestionKeyLimitMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint updates an ingestion key limit
|
||||
* This endpoint updates an ingestion key limit.
|
||||
* @deprecated
|
||||
* @summary Update limit for the ingestion key
|
||||
*/
|
||||
export const updateIngestionKeyLimit = (
|
||||
@@ -653,6 +872,7 @@ export type UpdateIngestionKeyLimitMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @summary Update limit for the ingestion key
|
||||
*/
|
||||
export const useUpdateIngestionKeyLimit = <
|
||||
@@ -779,3 +999,370 @@ export const invalidateSearchIngestionKeys = async (
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint creates an ingestion limit for the ingestion key referenced by keyId
|
||||
* @summary Create ingestion limit
|
||||
*/
|
||||
export const createIngestionLimit = (
|
||||
gatewaytypesPostableIngestionKeyLimitDTO?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<CreateIngestionLimit201>({
|
||||
url: `/api/v2/gateway/ingestion_limits`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: gatewaytypesPostableIngestionKeyLimitDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCreateIngestionLimitMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createIngestionLimit>>,
|
||||
TError,
|
||||
{ data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createIngestionLimit>>,
|
||||
TError,
|
||||
{ data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['createIngestionLimit'];
|
||||
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 createIngestionLimit>>,
|
||||
{ data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return createIngestionLimit(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CreateIngestionLimitMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createIngestionLimit>>
|
||||
>;
|
||||
export type CreateIngestionLimitMutationBody =
|
||||
| BodyType<GatewaytypesPostableIngestionKeyLimitDTO>
|
||||
| undefined;
|
||||
export type CreateIngestionLimitMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Create ingestion limit
|
||||
*/
|
||||
export const useCreateIngestionLimit = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createIngestionLimit>>,
|
||||
TError,
|
||||
{ data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createIngestionLimit>>,
|
||||
TError,
|
||||
{ data?: BodyType<GatewaytypesPostableIngestionKeyLimitDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getCreateIngestionLimitMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint deletes an ingestion limit
|
||||
* @summary Delete ingestion limit
|
||||
*/
|
||||
export const deleteIngestionLimit = (
|
||||
{ limitId }: DeleteIngestionLimitPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/gateway/ingestion_limits/${limitId}`,
|
||||
method: 'DELETE',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDeleteIngestionLimitMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteIngestionLimit>>,
|
||||
TError,
|
||||
{ pathParams: DeleteIngestionLimitPathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteIngestionLimit>>,
|
||||
TError,
|
||||
{ pathParams: DeleteIngestionLimitPathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['deleteIngestionLimit'];
|
||||
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 deleteIngestionLimit>>,
|
||||
{ pathParams: DeleteIngestionLimitPathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return deleteIngestionLimit(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type DeleteIngestionLimitMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteIngestionLimit>>
|
||||
>;
|
||||
|
||||
export type DeleteIngestionLimitMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Delete ingestion limit
|
||||
*/
|
||||
export const useDeleteIngestionLimit = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteIngestionLimit>>,
|
||||
TError,
|
||||
{ pathParams: DeleteIngestionLimitPathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteIngestionLimit>>,
|
||||
TError,
|
||||
{ pathParams: DeleteIngestionLimitPathParameters },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getDeleteIngestionLimitMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint returns an ingestion limit
|
||||
* @summary Get ingestion limit
|
||||
*/
|
||||
export const getIngestionLimit = (
|
||||
{ limitId }: GetIngestionLimitPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetIngestionLimit200>({
|
||||
url: `/api/v2/gateway/ingestion_limits/${limitId}`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetIngestionLimitQueryKey = ({
|
||||
limitId,
|
||||
}: GetIngestionLimitPathParameters) => {
|
||||
return [`/api/v2/gateway/ingestion_limits/${limitId}`] as const;
|
||||
};
|
||||
|
||||
export const getGetIngestionLimitQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getIngestionLimit>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ limitId }: GetIngestionLimitPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionLimit>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetIngestionLimitQueryKey({ limitId });
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof getIngestionLimit>>
|
||||
> = ({ signal }) => getIngestionLimit({ limitId }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!limitId,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionLimit>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetIngestionLimitQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getIngestionLimit>>
|
||||
>;
|
||||
export type GetIngestionLimitQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get ingestion limit
|
||||
*/
|
||||
|
||||
export function useGetIngestionLimit<
|
||||
TData = Awaited<ReturnType<typeof getIngestionLimit>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ limitId }: GetIngestionLimitPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getIngestionLimit>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetIngestionLimitQueryOptions({ limitId }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get ingestion limit
|
||||
*/
|
||||
export const invalidateGetIngestionLimit = async (
|
||||
queryClient: QueryClient,
|
||||
{ limitId }: GetIngestionLimitPathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetIngestionLimitQueryKey({ limitId }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint updates an ingestion limit
|
||||
* @summary Update ingestion limit
|
||||
*/
|
||||
export const updateIngestionLimit = (
|
||||
{ limitId }: UpdateIngestionLimitPathParameters,
|
||||
gatewaytypesUpdatableIngestionKeyLimitDTO?: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/gateway/ingestion_limits/${limitId}`,
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: gatewaytypesUpdatableIngestionKeyLimitDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getUpdateIngestionLimitMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateIngestionLimit>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateIngestionLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateIngestionLimit>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateIngestionLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['updateIngestionLimit'];
|
||||
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 updateIngestionLimit>>,
|
||||
{
|
||||
pathParams: UpdateIngestionLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
|
||||
return updateIngestionLimit(pathParams, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateIngestionLimitMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateIngestionLimit>>
|
||||
>;
|
||||
export type UpdateIngestionLimitMutationBody =
|
||||
| BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>
|
||||
| undefined;
|
||||
export type UpdateIngestionLimitMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Update ingestion limit
|
||||
*/
|
||||
export const useUpdateIngestionLimit = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateIngestionLimit>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateIngestionLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateIngestionLimit>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateIngestionLimitPathParameters;
|
||||
data?: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getUpdateIngestionLimitMutationOptions(options));
|
||||
};
|
||||
|
||||
702
frontend/src/api/generated/services/licenses/index.ts
Normal file
702
frontend/src/api/generated/services/licenses/index.ts
Normal file
@@ -0,0 +1,702 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'pnpm generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
ActivateLicense201,
|
||||
DeleteLicensePathParameters,
|
||||
GetActiveLicense200,
|
||||
GetLicense200,
|
||||
GetLicensePathParameters,
|
||||
LicensetypesPostableLicenseDTO,
|
||||
ListLicenses200,
|
||||
RefreshLicensePathParameters,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { ErrorType, BodyType } from '../../../generatedAPIInstance';
|
||||
|
||||
/**
|
||||
* This endpoint validates the license key with the upstream server and activates the license for the organization.
|
||||
* @deprecated
|
||||
* @summary Activate a license.
|
||||
*/
|
||||
export const activateLicenseDeprecated = (
|
||||
licensetypesPostableLicenseDTO?: BodyType<LicensetypesPostableLicenseDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v3/licenses`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: licensetypesPostableLicenseDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getActivateLicenseDeprecatedMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof activateLicenseDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof activateLicenseDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['activateLicenseDeprecated'];
|
||||
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 activateLicenseDeprecated>>,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return activateLicenseDeprecated(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type ActivateLicenseDeprecatedMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof activateLicenseDeprecated>>
|
||||
>;
|
||||
export type ActivateLicenseDeprecatedMutationBody =
|
||||
| BodyType<LicensetypesPostableLicenseDTO>
|
||||
| undefined;
|
||||
export type ActivateLicenseDeprecatedMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @summary Activate a license.
|
||||
*/
|
||||
export const useActivateLicenseDeprecated = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof activateLicenseDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof activateLicenseDeprecated>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getActivateLicenseDeprecatedMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint refreshes the active license of the organization from the upstream server.
|
||||
* @deprecated
|
||||
* @summary Refresh a license.
|
||||
*/
|
||||
export const refreshLicenseDeprecated = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v3/licenses`,
|
||||
method: 'PUT',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getRefreshLicenseDeprecatedMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshLicenseDeprecated>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshLicenseDeprecated>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['refreshLicenseDeprecated'];
|
||||
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 refreshLicenseDeprecated>>,
|
||||
void
|
||||
> = () => {
|
||||
return refreshLicenseDeprecated();
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type RefreshLicenseDeprecatedMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof refreshLicenseDeprecated>>
|
||||
>;
|
||||
|
||||
export type RefreshLicenseDeprecatedMutationError =
|
||||
ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @summary Refresh a license.
|
||||
*/
|
||||
export const useRefreshLicenseDeprecated = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshLicenseDeprecated>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof refreshLicenseDeprecated>>,
|
||||
TError,
|
||||
void,
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getRefreshLicenseDeprecatedMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint lists all the licenses of the organization.
|
||||
* @summary List licenses.
|
||||
*/
|
||||
export const listLicenses = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<ListLicenses200>({
|
||||
url: `/api/v4/licenses`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListLicensesQueryKey = () => {
|
||||
return [`/api/v4/licenses`] as const;
|
||||
};
|
||||
|
||||
export const getListLicensesQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listLicenses>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listLicenses>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListLicensesQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listLicenses>>> = ({
|
||||
signal,
|
||||
}) => listLicenses(signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listLicenses>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type ListLicensesQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listLicenses>>
|
||||
>;
|
||||
export type ListLicensesQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary List licenses.
|
||||
*/
|
||||
|
||||
export function useListLicenses<
|
||||
TData = Awaited<ReturnType<typeof listLicenses>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listLicenses>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getListLicensesQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary List licenses.
|
||||
*/
|
||||
export const invalidateListLicenses = async (
|
||||
queryClient: QueryClient,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getListLicensesQueryKey() },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint validates the license key with the upstream server and activates the license for the organization.
|
||||
* @summary Activate a license.
|
||||
*/
|
||||
export const activateLicense = (
|
||||
licensetypesPostableLicenseDTO?: BodyType<LicensetypesPostableLicenseDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<ActivateLicense201>({
|
||||
url: `/api/v4/licenses`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: licensetypesPostableLicenseDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getActivateLicenseMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof activateLicense>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof activateLicense>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['activateLicense'];
|
||||
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 activateLicense>>,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return activateLicense(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type ActivateLicenseMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof activateLicense>>
|
||||
>;
|
||||
export type ActivateLicenseMutationBody =
|
||||
| BodyType<LicensetypesPostableLicenseDTO>
|
||||
| undefined;
|
||||
export type ActivateLicenseMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Activate a license.
|
||||
*/
|
||||
export const useActivateLicense = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof activateLicense>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof activateLicense>>,
|
||||
TError,
|
||||
{ data?: BodyType<LicensetypesPostableLicenseDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getActivateLicenseMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint deletes the license by id. Licenses managed by SigNoz Cloud cannot be deleted.
|
||||
* @summary Delete a license.
|
||||
*/
|
||||
export const deleteLicense = (
|
||||
{ id }: DeleteLicensePathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v4/licenses/${id}`,
|
||||
method: 'DELETE',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getDeleteLicenseMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteLicense>>,
|
||||
TError,
|
||||
{ pathParams: DeleteLicensePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteLicense>>,
|
||||
TError,
|
||||
{ pathParams: DeleteLicensePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['deleteLicense'];
|
||||
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 deleteLicense>>,
|
||||
{ pathParams: DeleteLicensePathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return deleteLicense(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type DeleteLicenseMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof deleteLicense>>
|
||||
>;
|
||||
|
||||
export type DeleteLicenseMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Delete a license.
|
||||
*/
|
||||
export const useDeleteLicense = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof deleteLicense>>,
|
||||
TError,
|
||||
{ pathParams: DeleteLicensePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof deleteLicense>>,
|
||||
TError,
|
||||
{ pathParams: DeleteLicensePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getDeleteLicenseMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint gets the license by id.
|
||||
* @summary Get a license.
|
||||
*/
|
||||
export const getLicense = (
|
||||
{ id }: GetLicensePathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetLicense200>({
|
||||
url: `/api/v4/licenses/${id}`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetLicenseQueryKey = ({ id }: GetLicensePathParameters) => {
|
||||
return [`/api/v4/licenses/${id}`] as const;
|
||||
};
|
||||
|
||||
export const getGetLicenseQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getLicense>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ id }: GetLicensePathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getLicense>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetLicenseQueryKey({ id });
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getLicense>>> = ({
|
||||
signal,
|
||||
}) => getLicense({ id }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!id,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<Awaited<ReturnType<typeof getLicense>>, TError, TData> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
};
|
||||
|
||||
export type GetLicenseQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getLicense>>
|
||||
>;
|
||||
export type GetLicenseQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get a license.
|
||||
*/
|
||||
|
||||
export function useGetLicense<
|
||||
TData = Awaited<ReturnType<typeof getLicense>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ id }: GetLicensePathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getLicense>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetLicenseQueryOptions({ id }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get a license.
|
||||
*/
|
||||
export const invalidateGetLicense = async (
|
||||
queryClient: QueryClient,
|
||||
{ id }: GetLicensePathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetLicenseQueryKey({ id }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint refreshes the active license of the organization from the upstream server.
|
||||
* @summary Refresh a license.
|
||||
*/
|
||||
export const refreshLicense = (
|
||||
{ id }: RefreshLicensePathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v4/licenses/${id}`,
|
||||
method: 'PUT',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getRefreshLicenseMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshLicense>>,
|
||||
TError,
|
||||
{ pathParams: RefreshLicensePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshLicense>>,
|
||||
TError,
|
||||
{ pathParams: RefreshLicensePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['refreshLicense'];
|
||||
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 refreshLicense>>,
|
||||
{ pathParams: RefreshLicensePathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return refreshLicense(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type RefreshLicenseMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof refreshLicense>>
|
||||
>;
|
||||
|
||||
export type RefreshLicenseMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Refresh a license.
|
||||
*/
|
||||
export const useRefreshLicense = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof refreshLicense>>,
|
||||
TError,
|
||||
{ pathParams: RefreshLicensePathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof refreshLicense>>,
|
||||
TError,
|
||||
{ pathParams: RefreshLicensePathParameters },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getRefreshLicenseMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint gets the active license of the organization.
|
||||
* @summary Get the active license.
|
||||
*/
|
||||
export const getActiveLicense = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<GetActiveLicense200>({
|
||||
url: `/api/v4/licenses/active`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetActiveLicenseQueryKey = () => {
|
||||
return [`/api/v4/licenses/active`] as const;
|
||||
};
|
||||
|
||||
export const getGetActiveLicenseQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getActiveLicense>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getActiveLicense>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetActiveLicenseQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getActiveLicense>>> = ({
|
||||
signal,
|
||||
}) => getActiveLicense(signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getActiveLicense>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetActiveLicenseQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getActiveLicense>>
|
||||
>;
|
||||
export type GetActiveLicenseQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get the active license.
|
||||
*/
|
||||
|
||||
export function useGetActiveLicense<
|
||||
TData = Awaited<ReturnType<typeof getActiveLicense>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getActiveLicense>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetActiveLicenseQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get the active license.
|
||||
*/
|
||||
export const invalidateGetActiveLicense = async (
|
||||
queryClient: QueryClient,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetActiveLicenseQueryKey() },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
396
frontend/src/api/generated/services/prometheus/index.ts
Normal file
396
frontend/src/api/generated/services/prometheus/index.ts
Normal file
@@ -0,0 +1,396 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'pnpm generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
PrometheusErrorResponseSchemaDTO,
|
||||
PrometheusQueryParams,
|
||||
PrometheusQueryPostParams,
|
||||
PrometheusQueryRangeParams,
|
||||
PrometheusQueryRangePostParams,
|
||||
PrometheusSuccessResponseSchemaDTO,
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { ErrorType } from '../../../generatedAPIInstance';
|
||||
|
||||
/**
|
||||
* Prometheus-compatible endpoint: the request and response contract is the upstream Prometheus HTTP API (https://prometheus.io/docs/prometheus/latest/querying/api/). Parameters are accepted as URL query parameters or a form-encoded body, on GET and POST alike.
|
||||
* @summary Prometheus instant query
|
||||
*/
|
||||
export const prometheusQuery = (
|
||||
params: PrometheusQueryParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<PrometheusSuccessResponseSchemaDTO>({
|
||||
url: `/prometheus/api/v1/query`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getPrometheusQueryQueryKey = (params?: PrometheusQueryParams) => {
|
||||
return [`/prometheus/api/v1/query`, ...(params ? [params] : [])] as const;
|
||||
};
|
||||
|
||||
export const getPrometheusQueryQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof prometheusQuery>>,
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
>(
|
||||
params: PrometheusQueryParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof prometheusQuery>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getPrometheusQueryQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof prometheusQuery>>> = ({
|
||||
signal,
|
||||
}) => prometheusQuery(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof prometheusQuery>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type PrometheusQueryQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof prometheusQuery>>
|
||||
>;
|
||||
export type PrometheusQueryQueryError = ErrorType<
|
||||
PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO
|
||||
>;
|
||||
|
||||
/**
|
||||
* @summary Prometheus instant query
|
||||
*/
|
||||
|
||||
export function usePrometheusQuery<
|
||||
TData = Awaited<ReturnType<typeof prometheusQuery>>,
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
>(
|
||||
params: PrometheusQueryParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof prometheusQuery>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getPrometheusQueryQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Prometheus instant query
|
||||
*/
|
||||
export const invalidatePrometheusQuery = async (
|
||||
queryClient: QueryClient,
|
||||
params: PrometheusQueryParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getPrometheusQueryQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prometheus-compatible endpoint: the request and response contract is the upstream Prometheus HTTP API (https://prometheus.io/docs/prometheus/latest/querying/api/). Parameters are accepted as URL query parameters or a form-encoded body, on GET and POST alike.
|
||||
* @summary Prometheus instant query
|
||||
*/
|
||||
export const prometheusQueryPost = (
|
||||
params: PrometheusQueryPostParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<PrometheusSuccessResponseSchemaDTO>({
|
||||
url: `/prometheus/api/v1/query`,
|
||||
method: 'POST',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getPrometheusQueryPostMutationOptions = <
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryPost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryPostParams },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryPost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryPostParams },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['prometheusQueryPost'];
|
||||
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 prometheusQueryPost>>,
|
||||
{ params: PrometheusQueryPostParams }
|
||||
> = (props) => {
|
||||
const { params } = props ?? {};
|
||||
|
||||
return prometheusQueryPost(params);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type PrometheusQueryPostMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof prometheusQueryPost>>
|
||||
>;
|
||||
|
||||
export type PrometheusQueryPostMutationError = ErrorType<
|
||||
PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO
|
||||
>;
|
||||
|
||||
/**
|
||||
* @summary Prometheus instant query
|
||||
*/
|
||||
export const usePrometheusQueryPost = <
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryPost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryPostParams },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof prometheusQueryPost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryPostParams },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getPrometheusQueryPostMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* Prometheus-compatible endpoint: the request and response contract is the upstream Prometheus HTTP API (https://prometheus.io/docs/prometheus/latest/querying/api/). Parameters are accepted as URL query parameters or a form-encoded body, on GET and POST alike.
|
||||
* @summary Prometheus range query
|
||||
*/
|
||||
export const prometheusQueryRange = (
|
||||
params: PrometheusQueryRangeParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<PrometheusSuccessResponseSchemaDTO>({
|
||||
url: `/prometheus/api/v1/query_range`,
|
||||
method: 'GET',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getPrometheusQueryRangeQueryKey = (
|
||||
params?: PrometheusQueryRangeParams,
|
||||
) => {
|
||||
return [
|
||||
`/prometheus/api/v1/query_range`,
|
||||
...(params ? [params] : []),
|
||||
] as const;
|
||||
};
|
||||
|
||||
export const getPrometheusQueryRangeQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof prometheusQueryRange>>,
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
>(
|
||||
params: PrometheusQueryRangeParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryRange>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getPrometheusQueryRangeQueryKey(params);
|
||||
|
||||
const queryFn: QueryFunction<
|
||||
Awaited<ReturnType<typeof prometheusQueryRange>>
|
||||
> = ({ signal }) => prometheusQueryRange(params, signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryRange>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type PrometheusQueryRangeQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof prometheusQueryRange>>
|
||||
>;
|
||||
export type PrometheusQueryRangeQueryError = ErrorType<
|
||||
PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO
|
||||
>;
|
||||
|
||||
/**
|
||||
* @summary Prometheus range query
|
||||
*/
|
||||
|
||||
export function usePrometheusQueryRange<
|
||||
TData = Awaited<ReturnType<typeof prometheusQueryRange>>,
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
>(
|
||||
params: PrometheusQueryRangeParams,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryRange>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getPrometheusQueryRangeQueryOptions(params, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Prometheus range query
|
||||
*/
|
||||
export const invalidatePrometheusQueryRange = async (
|
||||
queryClient: QueryClient,
|
||||
params: PrometheusQueryRangeParams,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getPrometheusQueryRangeQueryKey(params) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prometheus-compatible endpoint: the request and response contract is the upstream Prometheus HTTP API (https://prometheus.io/docs/prometheus/latest/querying/api/). Parameters are accepted as URL query parameters or a form-encoded body, on GET and POST alike.
|
||||
* @summary Prometheus range query
|
||||
*/
|
||||
export const prometheusQueryRangePost = (
|
||||
params: PrometheusQueryRangePostParams,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<PrometheusSuccessResponseSchemaDTO>({
|
||||
url: `/prometheus/api/v1/query_range`,
|
||||
method: 'POST',
|
||||
params,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getPrometheusQueryRangePostMutationOptions = <
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryRangePost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryRangePostParams },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryRangePost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryRangePostParams },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['prometheusQueryRangePost'];
|
||||
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 prometheusQueryRangePost>>,
|
||||
{ params: PrometheusQueryRangePostParams }
|
||||
> = (props) => {
|
||||
const { params } = props ?? {};
|
||||
|
||||
return prometheusQueryRangePost(params);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type PrometheusQueryRangePostMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof prometheusQueryRangePost>>
|
||||
>;
|
||||
|
||||
export type PrometheusQueryRangePostMutationError = ErrorType<
|
||||
PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO
|
||||
>;
|
||||
|
||||
/**
|
||||
* @summary Prometheus range query
|
||||
*/
|
||||
export const usePrometheusQueryRangePost = <
|
||||
TError = ErrorType<PrometheusErrorResponseSchemaDTO | RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof prometheusQueryRangePost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryRangePostParams },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof prometheusQueryRangePost>>,
|
||||
TError,
|
||||
{ params: PrometheusQueryRangePostParams },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getPrometheusQueryRangePostMutationOptions(options));
|
||||
};
|
||||
316
frontend/src/api/generated/services/quick-filter/index.ts
Normal file
316
frontend/src/api/generated/services/quick-filter/index.ts
Normal file
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'pnpm generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
GetQuickFilters200,
|
||||
GetQuickFiltersPathParameters,
|
||||
ListQuickFilters200,
|
||||
QuickfiltertypesUpdatableQuickFiltersDTO,
|
||||
RenderErrorResponseDTO,
|
||||
UpdateQuickFiltersPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { ErrorType, BodyType } from '../../../generatedAPIInstance';
|
||||
|
||||
/**
|
||||
* Returns the org's quick filters for every source, each filter as a telemetry field key.
|
||||
* @summary List quick filters
|
||||
*/
|
||||
export const listQuickFilters = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<ListQuickFilters200>({
|
||||
url: `/api/v2/quick_filters`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getListQuickFiltersQueryKey = () => {
|
||||
return [`/api/v2/quick_filters`] as const;
|
||||
};
|
||||
|
||||
export const getListQuickFiltersQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof listQuickFilters>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listQuickFilters>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getListQuickFiltersQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof listQuickFilters>>> = ({
|
||||
signal,
|
||||
}) => listQuickFilters(signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listQuickFilters>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type ListQuickFiltersQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof listQuickFilters>>
|
||||
>;
|
||||
export type ListQuickFiltersQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary List quick filters
|
||||
*/
|
||||
|
||||
export function useListQuickFilters<
|
||||
TData = Awaited<ReturnType<typeof listQuickFilters>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof listQuickFilters>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getListQuickFiltersQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary List quick filters
|
||||
*/
|
||||
export const invalidateListQuickFilters = async (
|
||||
queryClient: QueryClient,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getListQuickFiltersQueryKey() },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the org's quick filters for one source, each filter as a telemetry field key.
|
||||
* @summary Get a source's quick filters
|
||||
*/
|
||||
export const getQuickFilters = (
|
||||
{ source }: GetQuickFiltersPathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<GetQuickFilters200>({
|
||||
url: `/api/v2/quick_filters/${source}`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetQuickFiltersQueryKey = ({
|
||||
source,
|
||||
}: GetQuickFiltersPathParameters) => {
|
||||
return [`/api/v2/quick_filters/${source}`] as const;
|
||||
};
|
||||
|
||||
export const getGetQuickFiltersQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getQuickFilters>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ source }: GetQuickFiltersPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getQuickFilters>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey =
|
||||
queryOptions?.queryKey ?? getGetQuickFiltersQueryKey({ source });
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getQuickFilters>>> = ({
|
||||
signal,
|
||||
}) => getQuickFilters({ source }, signal);
|
||||
|
||||
return {
|
||||
queryKey,
|
||||
queryFn,
|
||||
enabled: !!source,
|
||||
...queryOptions,
|
||||
} as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getQuickFilters>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetQuickFiltersQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getQuickFilters>>
|
||||
>;
|
||||
export type GetQuickFiltersQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get a source's quick filters
|
||||
*/
|
||||
|
||||
export function useGetQuickFilters<
|
||||
TData = Awaited<ReturnType<typeof getQuickFilters>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(
|
||||
{ source }: GetQuickFiltersPathParameters,
|
||||
options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getQuickFilters>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
},
|
||||
): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetQuickFiltersQueryOptions({ source }, options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get a source's quick filters
|
||||
*/
|
||||
export const invalidateGetQuickFilters = async (
|
||||
queryClient: QueryClient,
|
||||
{ source }: GetQuickFiltersPathParameters,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetQuickFiltersQueryKey({ source }) },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* Replaces the org's quick filters for the source named in the path.
|
||||
* @summary Update quick filters
|
||||
*/
|
||||
export const updateQuickFilters = (
|
||||
{ source }: UpdateQuickFiltersPathParameters,
|
||||
quickfiltertypesUpdatableQuickFiltersDTO?: BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<void>({
|
||||
url: `/api/v2/quick_filters/${source}`,
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: quickfiltertypesUpdatableQuickFiltersDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getUpdateQuickFiltersMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateQuickFilters>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateQuickFiltersPathParameters;
|
||||
data?: BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateQuickFilters>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateQuickFiltersPathParameters;
|
||||
data?: BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['updateQuickFilters'];
|
||||
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 updateQuickFilters>>,
|
||||
{
|
||||
pathParams: UpdateQuickFiltersPathParameters;
|
||||
data?: BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>;
|
||||
}
|
||||
> = (props) => {
|
||||
const { pathParams, data } = props ?? {};
|
||||
|
||||
return updateQuickFilters(pathParams, data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateQuickFiltersMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateQuickFilters>>
|
||||
>;
|
||||
export type UpdateQuickFiltersMutationBody =
|
||||
| BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>
|
||||
| undefined;
|
||||
export type UpdateQuickFiltersMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Update quick filters
|
||||
*/
|
||||
export const useUpdateQuickFilters = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateQuickFilters>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateQuickFiltersPathParameters;
|
||||
data?: BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>;
|
||||
},
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateQuickFilters>>,
|
||||
TError,
|
||||
{
|
||||
pathParams: UpdateQuickFiltersPathParameters;
|
||||
data?: BodyType<QuickfiltertypesUpdatableQuickFiltersDTO>;
|
||||
},
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getUpdateQuickFiltersMutationOptions(options));
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
280
frontend/src/api/generated/services/subscriptions/index.ts
Normal file
280
frontend/src/api/generated/services/subscriptions/index.ts
Normal file
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* ! Do not edit manually
|
||||
* * The file has been auto-generated using Orval for SigNoz
|
||||
* * regenerate with 'pnpm generate:api'
|
||||
* SigNoz
|
||||
*/
|
||||
import { useMutation, useQuery } from 'react-query';
|
||||
import type {
|
||||
InvalidateOptions,
|
||||
MutationFunction,
|
||||
QueryClient,
|
||||
QueryFunction,
|
||||
QueryKey,
|
||||
UseMutationOptions,
|
||||
UseMutationResult,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
CreateSubscription201,
|
||||
GetSubscription200,
|
||||
RenderErrorResponseDTO,
|
||||
SubscriptiontypesPostableSubscriptionDTO,
|
||||
UpdateSubscription200,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { ErrorType, BodyType } from '../../../generatedAPIInstance';
|
||||
|
||||
/**
|
||||
* This endpoint gets the organization's subscription along with its usage and billing details.
|
||||
* @summary Get the subscription.
|
||||
*/
|
||||
export const getSubscription = (signal?: AbortSignal) => {
|
||||
return GeneratedAPIInstance<GetSubscription200>({
|
||||
url: `/api/v1/subscriptions`,
|
||||
method: 'GET',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getGetSubscriptionQueryKey = () => {
|
||||
return [`/api/v1/subscriptions`] as const;
|
||||
};
|
||||
|
||||
export const getGetSubscriptionQueryOptions = <
|
||||
TData = Awaited<ReturnType<typeof getSubscription>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getSubscription>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}) => {
|
||||
const { query: queryOptions } = options ?? {};
|
||||
|
||||
const queryKey = queryOptions?.queryKey ?? getGetSubscriptionQueryKey();
|
||||
|
||||
const queryFn: QueryFunction<Awaited<ReturnType<typeof getSubscription>>> = ({
|
||||
signal,
|
||||
}) => getSubscription(signal);
|
||||
|
||||
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getSubscription>>,
|
||||
TError,
|
||||
TData
|
||||
> & { queryKey: QueryKey };
|
||||
};
|
||||
|
||||
export type GetSubscriptionQueryResult = NonNullable<
|
||||
Awaited<ReturnType<typeof getSubscription>>
|
||||
>;
|
||||
export type GetSubscriptionQueryError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Get the subscription.
|
||||
*/
|
||||
|
||||
export function useGetSubscription<
|
||||
TData = Awaited<ReturnType<typeof getSubscription>>,
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
>(options?: {
|
||||
query?: UseQueryOptions<
|
||||
Awaited<ReturnType<typeof getSubscription>>,
|
||||
TError,
|
||||
TData
|
||||
>;
|
||||
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
|
||||
const queryOptions = getGetSubscriptionQueryOptions(options);
|
||||
|
||||
const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & {
|
||||
queryKey: QueryKey;
|
||||
};
|
||||
|
||||
return { ...query, queryKey: queryOptions.queryKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get the subscription.
|
||||
*/
|
||||
export const invalidateGetSubscription = async (
|
||||
queryClient: QueryClient,
|
||||
options?: InvalidateOptions,
|
||||
): Promise<QueryClient> => {
|
||||
await queryClient.invalidateQueries(
|
||||
{ queryKey: getGetSubscriptionQueryKey() },
|
||||
options,
|
||||
);
|
||||
|
||||
return queryClient;
|
||||
};
|
||||
|
||||
/**
|
||||
* This endpoint creates a subscription for the organization.
|
||||
* @summary Create a subscription.
|
||||
*/
|
||||
export const createSubscription = (
|
||||
subscriptiontypesPostableSubscriptionDTO?: BodyType<SubscriptiontypesPostableSubscriptionDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<CreateSubscription201>({
|
||||
url: `/api/v1/subscriptions`,
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: subscriptiontypesPostableSubscriptionDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCreateSubscriptionMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['createSubscription'];
|
||||
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 createSubscription>>,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return createSubscription(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CreateSubscriptionMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof createSubscription>>
|
||||
>;
|
||||
export type CreateSubscriptionMutationBody =
|
||||
| BodyType<SubscriptiontypesPostableSubscriptionDTO>
|
||||
| undefined;
|
||||
export type CreateSubscriptionMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Create a subscription.
|
||||
*/
|
||||
export const useCreateSubscription = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof createSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof createSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getCreateSubscriptionMutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint updates the organization's subscription.
|
||||
* @summary Update the subscription.
|
||||
*/
|
||||
export const updateSubscription = (
|
||||
subscriptiontypesPostableSubscriptionDTO?: BodyType<SubscriptiontypesPostableSubscriptionDTO>,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<UpdateSubscription200>({
|
||||
url: `/api/v1/subscriptions`,
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data: subscriptiontypesPostableSubscriptionDTO,
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getUpdateSubscriptionMutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['updateSubscription'];
|
||||
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 updateSubscription>>,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> }
|
||||
> = (props) => {
|
||||
const { data } = props ?? {};
|
||||
|
||||
return updateSubscription(data);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type UpdateSubscriptionMutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof updateSubscription>>
|
||||
>;
|
||||
export type UpdateSubscriptionMutationBody =
|
||||
| BodyType<SubscriptiontypesPostableSubscriptionDTO>
|
||||
| undefined;
|
||||
export type UpdateSubscriptionMutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Update the subscription.
|
||||
*/
|
||||
export const useUpdateSubscription = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof updateSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof updateSubscription>>,
|
||||
TError,
|
||||
{ data?: BodyType<SubscriptiontypesPostableSubscriptionDTO> },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getUpdateSubscriptionMutationOptions(options));
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/dashboard/create';
|
||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||
|
||||
const create = async (props: Props): Promise<SuccessResponseV2<Dashboard>> => {
|
||||
try {
|
||||
const response = await axios.post<PayloadProps>('/dashboards', {
|
||||
...props,
|
||||
});
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default create;
|
||||
@@ -1,19 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { Dashboard, PayloadProps } from 'types/api/dashboard/getAll';
|
||||
|
||||
const getAll = async (): Promise<SuccessResponseV2<Dashboard[]>> => {
|
||||
try {
|
||||
const response = await axios.get<PayloadProps>('/dashboards');
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default getAll;
|
||||
@@ -1,21 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/dashboard/delete';
|
||||
|
||||
const deleteDashboard = async (
|
||||
props: Props,
|
||||
): Promise<SuccessResponseV2<null>> => {
|
||||
try {
|
||||
const response = await axios.delete<PayloadProps>(`/dashboards/${props.id}`);
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: null,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default deleteDashboard;
|
||||
@@ -1,20 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/dashboard/get';
|
||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||
|
||||
const get = async (props: Props): Promise<SuccessResponseV2<Dashboard>> => {
|
||||
try {
|
||||
const response = await axios.get<PayloadProps>(`/dashboards/${props.id}`);
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default get;
|
||||
@@ -1,23 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/dashboard/lockUnlock';
|
||||
|
||||
const lock = async (props: Props): Promise<SuccessResponseV2<null>> => {
|
||||
try {
|
||||
const response = await axios.put<PayloadProps>(
|
||||
`/dashboards/${props.id}/lock`,
|
||||
{ lock: props.lock },
|
||||
);
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default lock;
|
||||
@@ -1,23 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||
import { PayloadProps, Props } from 'types/api/dashboard/update';
|
||||
|
||||
const update = async (props: Props): Promise<SuccessResponseV2<Dashboard>> => {
|
||||
try {
|
||||
const response = await axios.put<PayloadProps>(`/dashboards/${props.id}`, {
|
||||
...props.data,
|
||||
});
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default update;
|
||||
@@ -1,25 +0,0 @@
|
||||
import { ApiV3Instance as axios } from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import {
|
||||
LicenseEventQueueResModel,
|
||||
PayloadProps,
|
||||
} from 'types/api/licensesV3/getActive';
|
||||
|
||||
const getActive = async (): Promise<
|
||||
SuccessResponseV2<LicenseEventQueueResModel>
|
||||
> => {
|
||||
try {
|
||||
const response = await axios.get<PayloadProps>('/licenses/active');
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default getActive;
|
||||
@@ -1,24 +0,0 @@
|
||||
import { ApiV3Instance as axios } from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { PayloadProps, Props } from 'types/api/licenses/apply';
|
||||
|
||||
const apply = async (
|
||||
props: Props,
|
||||
): Promise<SuccessResponseV2<PayloadProps>> => {
|
||||
try {
|
||||
const response = await axios.post<PayloadProps>('/licenses', {
|
||||
key: props.key,
|
||||
});
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default apply;
|
||||
@@ -1,20 +0,0 @@
|
||||
import { ApiV3Instance as axios } from 'api';
|
||||
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ErrorV2Resp, SuccessResponseV2 } from 'types/api';
|
||||
import { PayloadProps } from 'types/api/licenses/apply';
|
||||
|
||||
const apply = async (): Promise<SuccessResponseV2<PayloadProps>> => {
|
||||
try {
|
||||
const response = await axios.put<PayloadProps>('/licenses');
|
||||
|
||||
return {
|
||||
httpStatusCode: response.status,
|
||||
data: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
|
||||
}
|
||||
};
|
||||
|
||||
export default apply;
|
||||
@@ -6,6 +6,7 @@ import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
|
||||
import getStartEndRangeTime from 'lib/getStartEndRangeTime';
|
||||
import { mapQueryDataToApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataToApi';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { DynamicVariableSuggestion } from 'providers/Dashboard/store/dynamicVariableSuggestions';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import {
|
||||
IBuilderQuery,
|
||||
@@ -545,20 +546,22 @@ function reduceQueriesToObject(queryArray: any[]): {
|
||||
/**
|
||||
* Prepares V5 query range payload from GetQueryResultsProps
|
||||
*/
|
||||
export const prepareQueryRangePayloadV5 = ({
|
||||
query,
|
||||
globalSelectedInterval,
|
||||
graphType,
|
||||
selectedTime,
|
||||
tableParams,
|
||||
variables = {},
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
formatForWeb,
|
||||
originalGraphType,
|
||||
fillGaps,
|
||||
dynamicVariables,
|
||||
}: GetQueryResultsProps): PrepareQueryRangePayloadV5Result => {
|
||||
export const prepareQueryRangePayloadV5 = (
|
||||
{
|
||||
query,
|
||||
globalSelectedInterval,
|
||||
graphType,
|
||||
selectedTime,
|
||||
tableParams,
|
||||
variables = {},
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
formatForWeb,
|
||||
originalGraphType,
|
||||
fillGaps,
|
||||
}: GetQueryResultsProps,
|
||||
dynamicVariables: DynamicVariableSuggestion[] = [],
|
||||
): PrepareQueryRangePayloadV5Result => {
|
||||
let legendMap: Record<string, string> = {};
|
||||
const requestType = mapPanelTypeToRequestType(graphType);
|
||||
let queries: QueryEnvelope[] = [];
|
||||
@@ -671,9 +674,9 @@ export const prepareQueryRangePayloadV5 = ({
|
||||
(acc, [key, value]) => {
|
||||
acc[key] = {
|
||||
value,
|
||||
type: dynamicVariables
|
||||
?.find((v) => v.name === key)
|
||||
?.type?.toLowerCase() as VariableType,
|
||||
type: dynamicVariables.some((v) => v.name === key)
|
||||
? ('dynamic' as VariableType)
|
||||
: undefined,
|
||||
};
|
||||
return acc;
|
||||
},
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
export default function ApacheIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8.7112 1.05739C8.3796 1.30831 8.08524 1.60498 7.83691 1.93853L8.17977 2.58567C8.40218 2.26279 8.64677 1.95576 8.91177 1.66681C8.93063 1.64581 8.94091 1.63596 8.94091 1.63596L8.91177 1.66681C8.66003 1.95965 8.43081 2.27111 8.22606 2.59853C8.67305 2.56672 9.11808 2.51165 9.55934 2.43353C9.60936 2.25525 9.62374 2.06886 9.60168 1.88502C9.57962 1.70118 9.52154 1.52349 9.43077 1.3621C9.43077 1.3621 9.09991 0.828957 8.7112 1.05739Z"
|
||||
fill="url(#paint0_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M7.55932 6.49365L7.42432 6.51722L7.49332 6.50651C7.51432 6.50265 7.53703 6.49837 7.55932 6.49365Z"
|
||||
fill="#BE202E"
|
||||
/>
|
||||
<path
|
||||
opacity="0.35"
|
||||
d="M7.55932 6.49365L7.42432 6.51722L7.49332 6.50651C7.51432 6.50265 7.53703 6.49837 7.55932 6.49365Z"
|
||||
fill="#BE202E"
|
||||
/>
|
||||
<path
|
||||
d="M7.67407 5.92858L7.6955 5.92558C7.72464 5.9213 7.75336 5.91616 7.78122 5.91016L7.67493 5.92816L7.67407 5.92858Z"
|
||||
fill="#BE202E"
|
||||
/>
|
||||
<path
|
||||
opacity="0.35"
|
||||
d="M7.67407 5.92858L7.6955 5.92558C7.72464 5.9213 7.75336 5.91616 7.78122 5.91016L7.67493 5.92816L7.67407 5.92858Z"
|
||||
fill="#BE202E"
|
||||
/>
|
||||
<path
|
||||
d="M7.16872 4.25736C7.273 4.0625 7.37858 3.87221 7.48543 3.6865C7.59629 3.49393 7.70829 3.3075 7.82143 3.12721L7.84115 3.09507C7.95315 2.91793 8.066 2.74779 8.17972 2.58464L7.83686 1.9375L7.75886 2.03393C7.65986 2.15736 7.55743 2.29107 7.452 2.43036C7.33329 2.58893 7.21115 2.75779 7.08729 2.93564C6.97286 3.09979 6.85672 3.27164 6.74058 3.44993C6.64158 3.60121 6.54258 3.75721 6.444 3.91707L6.43286 3.93507L6.879 4.8145C6.97443 4.62707 7.071 4.44136 7.16872 4.25736Z"
|
||||
fill="url(#paint1_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M5.13606 9.22519C5.07692 9.38748 5.01763 9.55305 4.95821 9.72191L4.95563 9.72919L4.93035 9.80076C4.89049 9.91476 4.85535 10.015 4.77563 10.2503C4.92444 10.3467 5.0416 10.4847 5.11249 10.6472C5.10283 10.4581 5.01907 10.2804 4.87935 10.1526C5.16043 10.1981 5.44862 10.1654 5.71236 10.0581C5.97609 9.95074 6.20521 9.77291 6.37463 9.54405C6.40102 9.50088 6.42464 9.45607 6.44535 9.40991C6.37459 9.49741 6.28141 9.56408 6.17575 9.6028C6.07008 9.64152 5.95589 9.65084 5.84535 9.62976C6.20937 9.49539 6.51802 9.24316 6.72221 8.91319C6.76978 8.83691 6.81563 8.75376 6.86278 8.66162C6.6974 8.84328 6.48756 8.97872 6.25393 9.05463C6.02029 9.13053 5.77091 9.14426 5.53035 9.09448L5.16949 9.13391C5.15706 9.16434 5.14721 9.19476 5.13606 9.22519Z"
|
||||
fill="url(#paint2_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M5.30448 8.417C5.38248 8.21528 5.46276 8.01157 5.54533 7.80586C5.62419 7.60871 5.70519 7.41057 5.78833 7.21143C5.87148 7.01228 5.95633 6.81228 6.0429 6.61143C6.1309 6.40828 6.22076 6.20557 6.31248 6.00328C6.40419 5.801 6.49633 5.60257 6.5889 5.408C6.62262 5.33714 6.65662 5.26643 6.6909 5.19586C6.75005 5.07414 6.80962 4.95343 6.86962 4.83371C6.87262 4.82728 6.87605 4.82086 6.87948 4.81443L6.4329 3.93457L6.41105 3.97014C6.30733 4.14157 6.20362 4.313 6.10205 4.49128C6.00048 4.66957 5.89848 4.853 5.80205 5.03814C5.7189 5.19443 5.63776 5.35157 5.55862 5.50957L5.51148 5.606C5.41419 5.80614 5.32633 5.99943 5.24705 6.18543C5.15705 6.396 5.07762 6.59686 5.00876 6.788C4.9629 6.91357 4.92305 7.03486 4.88362 7.151C4.85233 7.25043 4.82276 7.34986 4.79448 7.451C4.72762 7.68471 4.67048 7.91771 4.62305 8.15L5.07133 9.035C5.13076 8.87671 5.19162 8.71614 5.2539 8.55328L5.30448 8.417Z"
|
||||
fill="url(#paint3_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M4.615 8.18082C4.55868 8.46014 4.51975 8.74268 4.49843 9.02682C4.49843 9.03668 4.49843 9.04653 4.49629 9.05639C4.3547 8.8778 4.1801 8.72808 3.982 8.61539C4.24526 8.95089 4.41819 9.34823 4.48429 9.76953C4.28982 9.78674 4.0942 9.75338 3.91643 9.67268C4.05057 9.80984 4.21714 9.91096 4.40072 9.96668C4.14974 10.0146 3.9168 10.1307 3.72743 10.3022C3.97375 10.178 4.25059 10.1271 4.525 10.1557C4.21858 11.024 3.91129 11.9827 3.604 13.0001C3.64664 12.988 3.6856 12.9655 3.71739 12.9346C3.74918 12.9037 3.7728 12.8654 3.78615 12.8231C3.841 12.6388 4.20443 11.4298 4.77443 9.84068L4.82372 9.70439L4.83743 9.66625C4.89772 9.49968 4.96015 9.32968 5.02472 9.15625L5.06758 9.03753V9.03539L4.62143 8.15039C4.61929 8.16025 4.61672 8.17053 4.615 8.18082Z"
|
||||
fill="url(#paint4_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M6.94843 4.89059L6.90986 4.96987C6.87129 5.04959 6.83214 5.13102 6.79243 5.21416C6.74957 5.30416 6.70671 5.3963 6.66386 5.49059C6.64157 5.53816 6.621 5.58573 6.59743 5.63416C6.53057 5.7793 6.46286 5.92916 6.39429 6.08373C6.30857 6.27402 6.22286 6.47173 6.13714 6.67687C6.054 6.87259 5.96971 7.07516 5.88429 7.28459C5.80314 7.48459 5.721 7.68973 5.63786 7.90002C5.56386 8.08888 5.48914 8.28273 5.41371 8.48159C5.40986 8.49145 5.40643 8.50087 5.403 8.51073C5.32814 8.70873 5.25257 8.91187 5.17629 9.12016L5.17114 9.1343L5.532 9.09487L5.51057 9.09102C6.039 8.98351 6.52026 8.7126 6.88629 8.31659C7.0686 8.1182 7.22683 7.89896 7.35771 7.66345C7.47147 7.46033 7.57252 7.25036 7.66029 7.03473C7.74386 6.83245 7.824 6.61387 7.90114 6.37645C7.79448 6.43086 7.68084 6.47037 7.56343 6.49388C7.54157 6.49859 7.52057 6.50287 7.49657 6.50673C7.47257 6.51059 7.45071 6.51445 7.42757 6.51745C7.80325 6.36305 8.10458 6.06924 8.26843 5.69759C8.12155 5.79773 7.95733 5.86966 7.78414 5.90973C7.75586 5.91616 7.72757 5.92087 7.69843 5.92516L7.677 5.92816C7.80484 5.87656 7.92565 5.80903 8.03657 5.72716C8.05843 5.71087 8.07943 5.69373 8.1 5.67573C8.13129 5.64873 8.16086 5.62045 8.18914 5.59002C8.20714 5.57116 8.22471 5.55145 8.24186 5.53087C8.28293 5.48179 8.32059 5.42996 8.35457 5.37573C8.36529 5.35859 8.376 5.34145 8.38629 5.32345C8.39957 5.29773 8.41243 5.27245 8.42486 5.24716C8.481 5.13402 8.526 5.03288 8.56157 4.94459C8.57957 4.90173 8.595 4.85888 8.60829 4.82116C8.61386 4.80616 8.619 4.79116 8.62371 4.7783C8.63786 4.73545 8.64943 4.69816 8.65843 4.66473C8.66941 4.62595 8.67828 4.58661 8.685 4.54688C8.67015 4.5586 8.65454 4.56934 8.63829 4.57902C8.4822 4.66169 8.31419 4.71953 8.14029 4.75045H8.13257L8.08157 4.75859L8.09057 4.75473L6.957 4.87902L6.94843 4.89059Z"
|
||||
fill="url(#paint5_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M8.22475 2.59871C8.12404 2.75343 8.01389 2.92914 7.89561 3.12843L7.87675 3.16014C7.77446 3.33157 7.66604 3.52114 7.55147 3.72886C7.45261 3.90771 7.34989 4.10014 7.24332 4.30614C7.15018 4.48586 7.05418 4.67671 6.95532 4.87871L8.08889 4.75443C8.33914 4.65567 8.55501 4.48583 8.70989 4.26586C8.74804 4.211 8.78618 4.15357 8.82432 4.09443C8.94089 3.91271 9.05489 3.71257 9.15689 3.51371C9.25018 3.33322 9.33429 3.14813 9.40889 2.95914C9.44758 2.86102 9.48092 2.76087 9.50875 2.65914C9.52932 2.58028 9.54561 2.50571 9.55804 2.43457C9.11675 2.51236 8.67172 2.56715 8.22475 2.59871Z"
|
||||
fill="url(#paint6_linear_2061_4195)"
|
||||
/>
|
||||
<path
|
||||
d="M7.49234 6.50635C7.46963 6.5102 7.44648 6.51406 7.42334 6.51706C7.44648 6.51406 7.47134 6.5102 7.49234 6.50635Z"
|
||||
fill="#BE202E"
|
||||
/>
|
||||
<path
|
||||
opacity="0.35"
|
||||
d="M7.49234 6.50635C7.46963 6.5102 7.44648 6.51406 7.42334 6.51706C7.44648 6.51406 7.47134 6.5102 7.49234 6.50635Z"
|
||||
fill="#BE202E"
|
||||
/>
|
||||
<path
|
||||
d="M7.49234 6.50635C7.46963 6.5102 7.44648 6.51406 7.42334 6.51706C7.44648 6.51406 7.47134 6.5102 7.49234 6.50635Z"
|
||||
fill="url(#paint7_linear_2061_4195)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_2061_4195"
|
||||
x1="7.26579"
|
||||
y1="1.16584"
|
||||
x2="9.7782"
|
||||
y2="0.46843"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#F69923" />
|
||||
<stop offset="0.312" stopColor="#F79A23" />
|
||||
<stop offset="0.838" stopColor="#E97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_2061_4195"
|
||||
x1="1.76109"
|
||||
y1="12.4382"
|
||||
x2="6.87606"
|
||||
y2="1.48267"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.323" stopColor="#9E2064" />
|
||||
<stop offset="0.63" stopColor="#C92037" />
|
||||
<stop offset="0.751" stopColor="#CD2335" />
|
||||
<stop offset="1" stopColor="#E97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint2_linear_2061_4195"
|
||||
x1="3.47784"
|
||||
y1="11.6287"
|
||||
x2="6.5258"
|
||||
y2="5.10046"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#282662" />
|
||||
<stop offset="0.095" stopColor="#662E8D" />
|
||||
<stop offset="0.788" stopColor="#9F2064" />
|
||||
<stop offset="0.949" stopColor="#CD2032" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint3_linear_2061_4195"
|
||||
x1="1.94596"
|
||||
y1="11.7748"
|
||||
x2="7.06094"
|
||||
y2="0.819304"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.323" stopColor="#9E2064" />
|
||||
<stop offset="0.63" stopColor="#C92037" />
|
||||
<stop offset="0.751" stopColor="#CD2335" />
|
||||
<stop offset="1" stopColor="#E97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint4_linear_2061_4195"
|
||||
x1="2.46768"
|
||||
y1="11.0455"
|
||||
x2="5.15578"
|
||||
y2="5.28798"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#282662" />
|
||||
<stop offset="0.095" stopColor="#662E8D" />
|
||||
<stop offset="0.788" stopColor="#9F2064" />
|
||||
<stop offset="0.949" stopColor="#CD2032" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint5_linear_2061_4195"
|
||||
x1="3.08048"
|
||||
y1="12.3044"
|
||||
x2="8.19546"
|
||||
y2="1.3489"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.323" stopColor="#9E2064" />
|
||||
<stop offset="0.63" stopColor="#C92037" />
|
||||
<stop offset="0.751" stopColor="#CD2335" />
|
||||
<stop offset="1" stopColor="#E97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint6_linear_2061_4195"
|
||||
x1="2.70679"
|
||||
y1="12.9581"
|
||||
x2="7.82195"
|
||||
y2="2.00223"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.323" stopColor="#9E2064" />
|
||||
<stop offset="0.63" stopColor="#C92037" />
|
||||
<stop offset="0.751" stopColor="#CD2335" />
|
||||
<stop offset="1" stopColor="#E97826" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint7_linear_2061_4195"
|
||||
x1="3.41759"
|
||||
y1="12.4619"
|
||||
x2="8.53277"
|
||||
y2="1.50629"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.323" stopColor="#9E2064" />
|
||||
<stop offset="0.63" stopColor="#C92037" />
|
||||
<stop offset="0.751" stopColor="#CD2335" />
|
||||
<stop offset="1" stopColor="#E97826" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
export default function DockerIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_2061_4220)">
|
||||
<path
|
||||
d="M13.574 5.82107C13.2652 5.60679 12.5575 5.52644 12.0042 5.63358C11.9398 5.09788 11.6439 4.62915 11.1292 4.21399L10.8332 3.99971L10.6274 4.30774C10.37 4.70951 10.2413 5.27198 10.2799 5.80768C10.2928 5.99517 10.3571 6.32998 10.5502 6.62461C10.37 6.73175 9.99686 6.86567 9.50789 6.86567H0.204685L0.17895 6.97281C0.0888774 7.5085 0.0888774 9.18254 1.14401 10.4682C1.9418 11.4458 3.12561 11.9414 4.68258 11.9414C8.05386 11.9414 10.5502 10.3209 11.7211 7.38797C12.1843 7.40136 13.1751 7.38797 13.677 6.38354C13.6898 6.35676 13.7156 6.30319 13.8056 6.10231L13.8571 5.99517L13.574 5.82107ZM7.6421 2.04443H6.22668V3.38367H7.6421V2.04443ZM7.6421 3.65151H6.22668V4.99074H7.6421V3.65151ZM5.96933 3.65151H4.5539V4.99074H5.96933V3.65151ZM4.29655 3.65151H2.88113V4.99074H4.29655V3.65151ZM2.62378 5.25859H1.20835V6.59782H2.62378V5.25859ZM4.29655 5.25859H2.88113V6.59782H4.29655V5.25859ZM5.96933 5.25859H4.5539V6.59782H5.96933V5.25859ZM7.6421 5.25859H6.22668V6.59782H7.6421V5.25859ZM9.31488 5.25859H7.89945V6.59782H9.31488V5.25859Z"
|
||||
fill="#2396ED"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2061_4220">
|
||||
<rect
|
||||
width="13.7143"
|
||||
height="13.7143"
|
||||
fill="white"
|
||||
transform="translate(0.142822 0.143066)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
export default function ElasticSearchIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.38041 6.94508L9.70241 8.45858L13.0524 5.52158C13.1019 5.27892 13.1255 5.03171 13.1229 4.78408C13.1236 3.9846 12.8681 3.20592 12.3941 2.56216C11.92 1.9184 11.2522 1.44339 10.4885 1.20675C9.72487 0.970101 8.9055 0.984259 8.15047 1.24714C7.39544 1.51003 6.74446 2.00782 6.29291 2.66758L5.73291 5.56008L6.38041 6.94508Z"
|
||||
fill="#FED10A"
|
||||
/>
|
||||
<path
|
||||
d="M2.943 10.4593C2.89356 10.7062 2.86994 10.9575 2.8725 11.2093C2.87361 12.012 3.13177 12.7932 3.60915 13.4385C4.08654 14.0838 4.75804 14.5592 5.52528 14.7952C6.29252 15.0311 7.11514 15.0151 7.87262 14.7495C8.63009 14.4839 9.28259 13.9827 9.7345 13.3193L10.2845 10.4398L9.55 9.02928L6.215 7.50928L2.943 10.4593Z"
|
||||
fill="#24BBB1"
|
||||
/>
|
||||
<path
|
||||
d="M2.92394 4.71302L5.19994 5.25002L5.69994 2.66552C5.39077 2.43015 5.01365 2.30134 4.62509 2.29839C4.23654 2.29544 3.8575 2.41852 3.54479 2.64916C3.23208 2.8798 3.00256 3.20559 2.89063 3.57768C2.77869 3.94978 2.79039 4.34813 2.92394 4.71302Z"
|
||||
fill="#EF5098"
|
||||
/>
|
||||
<path
|
||||
d="M2.72503 5.2583C2.23266 5.42016 1.80253 5.73058 1.49379 6.14687C1.18505 6.56317 1.01286 7.0649 1.00091 7.58305C0.988962 8.1012 1.13784 8.61033 1.42706 9.04041C1.71628 9.4705 2.13164 9.80042 2.61603 9.9848L5.81003 7.0998L5.22653 5.8498L2.72503 5.2583Z"
|
||||
fill="#17A8E0"
|
||||
/>
|
||||
<path
|
||||
d="M10.312 13.3197C10.6209 13.5543 10.9975 13.6825 11.3853 13.6851C11.7732 13.6877 12.1514 13.5646 12.4634 13.3342C12.7755 13.1038 13.0044 12.7785 13.116 12.407C13.2276 12.0356 13.2159 11.6379 13.0825 11.2737L10.812 10.7412L10.312 13.3197Z"
|
||||
fill="#93C83E"
|
||||
/>
|
||||
<path
|
||||
d="M10.7735 10.145L13.2735 10.7285C13.7666 10.5672 14.1976 10.257 14.507 9.84058C14.8165 9.42415 14.9891 8.922 15.0013 8.40333C15.0134 7.88467 14.8643 7.375 14.5747 6.94457C14.2851 6.51414 13.8691 6.18413 13.384 6L10.1135 8.8665L10.7735 10.145Z"
|
||||
fill="#0779A1"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
function HerokuIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_2061_4245)">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M13.6285 0H2.10787C1.31283 0 0.666748 0.644312 0.666748 1.44112V14.5602C0.666748 15.3557 1.31283 16 2.10787 16H13.6285C14.4237 16 15.0678 15.3557 15.0678 14.5602V1.44112C15.0678 0.644312 14.4237 0 13.6285 0ZM14.2677 14.5602C14.2677 14.9135 13.9815 15.1994 13.6285 15.1994H2.10787C1.75506 15.1994 1.46688 14.9135 1.46688 14.5602V1.44112C1.46688 1.08654 1.75506 0.800133 2.10787 0.800133H13.6285C13.9815 0.800133 14.2677 1.08654 14.2677 1.44112V14.5602ZM4.26699 13.6009L6.06823 12.0002L4.26699 10.3999V13.6009ZM10.7719 7.11485C10.4481 6.78927 9.8569 6.40038 8.86819 6.40038C7.78342 6.40038 6.66611 6.68302 5.86752 6.94177V2.40082H4.26704V9.33907L5.39807 8.82667C5.41688 8.81826 7.24025 8.00086 8.86819 8.00086C9.68027 8.00086 9.86022 8.44796 9.86885 8.82158V13.6009H11.4676V8.801C11.4693 8.6983 11.4592 7.81051 10.7719 7.11485ZM8.66761 5.00027H10.2681C10.9912 4.1811 11.3597 3.30903 11.4677 2.40066H9.86881C9.69063 3.30726 9.29643 4.17424 8.66761 5.00027Z"
|
||||
fill="#6762A6"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2061_4245">
|
||||
<rect width="16" height="16" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default HerokuIcon;
|
||||
File diff suppressed because one or more lines are too long
@@ -1,68 +0,0 @@
|
||||
export default function MongoDBIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7.26568 13.0004L6.94382 12.8937C6.94382 12.8937 6.98668 11.2651 6.39739 11.1507C6.01168 10.7015 6.45439 -8.02403 7.86439 11.0868C7.59687 11.2225 7.39217 11.4564 7.29311 11.7395C7.24001 12.1577 7.23082 12.5803 7.26568 13.0004Z"
|
||||
fill="url(#paint0_linear_2061_4238)"
|
||||
/>
|
||||
<path
|
||||
d="M7.43957 11.4272C8.29654 10.7821 8.95282 9.90701 9.33214 8.90369C9.71147 7.90037 9.79826 6.81 9.58243 5.75931C8.95243 2.98002 7.46058 2.06631 7.29986 1.71745C7.1612 1.50022 7.04284 1.27068 6.94629 1.03174L7.065 8.7756C7.065 8.7756 6.819 11.1422 7.43957 11.4272Z"
|
||||
fill="url(#paint1_linear_2061_4238)"
|
||||
/>
|
||||
<path
|
||||
d="M6.78015 11.5296C6.78015 11.5296 4.15687 9.74286 4.30858 6.58214C4.32273 5.62928 4.54121 4.69054 4.94926 3.82935C5.3573 2.96816 5.94542 2.20456 6.67387 1.59014C6.759 1.51782 6.82663 1.42715 6.87168 1.32493C6.91674 1.22272 6.93805 1.11163 6.93401 1C7.0973 1.35143 7.07072 6.247 7.08787 6.81957C7.1543 9.04686 6.96401 11.1091 6.78015 11.5296Z"
|
||||
fill="url(#paint2_linear_2061_4238)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_2061_4238"
|
||||
x1="5.1021"
|
||||
y1="7.10853"
|
||||
x2="8.80138"
|
||||
y2="8.36386"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.231" stopColor="#999875" />
|
||||
<stop offset="0.563" stopColor="#9B9977" />
|
||||
<stop offset="0.683" stopColor="#A09F7E" />
|
||||
<stop offset="0.768" stopColor="#A9A889" />
|
||||
<stop offset="0.837" stopColor="#B7B69A" />
|
||||
<stop offset="0.896" stopColor="#C9C7B0" />
|
||||
<stop offset="0.948" stopColor="#DEDDCB" />
|
||||
<stop offset="0.994" stopColor="#F8F6EB" />
|
||||
<stop offset="1" stopColor="#FBF9EF" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_2061_4238"
|
||||
x1="6.45855"
|
||||
y1="0.976404"
|
||||
x2="8.09399"
|
||||
y2="11.1888"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#48A547" />
|
||||
<stop offset="1" stopColor="#3F9143" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint2_linear_2061_4238"
|
||||
x1="4.08293"
|
||||
y1="6.89501"
|
||||
x2="8.47176"
|
||||
y2="5.42519"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#41A247" />
|
||||
<stop offset="0.352" stopColor="#4BA74B" />
|
||||
<stop offset="0.956" stopColor="#67B554" />
|
||||
<stop offset="1" stopColor="#69B655" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,22 +0,0 @@
|
||||
function NginxIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.97775 1H7.00561C7.14837 1.068 7.28743 1.14353 7.42218 1.22629C8.97332 2.11829 10.5245 3.01057 12.0756 3.90314C12.1356 3.93517 12.1846 3.9845 12.2163 4.04472C12.2479 4.10493 12.2607 4.17327 12.253 4.24086C12.2496 6.12186 12.253 8.00243 12.2509 9.88257C12.2307 9.9723 12.1759 10.0504 12.0983 10.0999C10.4489 11.0496 8.79932 11.9987 7.14961 12.9473C7.10963 12.9778 7.06144 12.9956 7.01125 12.9984C6.96106 13.0012 6.91118 12.9889 6.86803 12.9631C5.21661 12.0163 3.56675 11.0677 1.91846 10.1174C1.86489 10.0921 1.82003 10.0515 1.78952 10.0007C1.75901 9.94988 1.74423 9.89119 1.74703 9.832C1.74703 7.95143 1.74703 6.071 1.74703 4.19071C1.74299 4.13178 1.75661 4.07299 1.78616 4.02184C1.8157 3.97069 1.85983 3.92951 1.91289 3.90357C3.46203 3.01271 5.01118 2.12129 6.56032 1.22929C6.69832 1.15043 6.83375 1.06686 6.97775 1Z"
|
||||
fill="#019639"
|
||||
/>
|
||||
<path
|
||||
d="M3.90007 4.65924C3.90007 6.21039 3.90007 7.76167 3.90007 9.3131C3.89809 9.39901 3.91326 9.48446 3.94468 9.56445C3.9761 9.64444 4.02315 9.71736 4.08307 9.77896C4.19794 9.89243 4.34824 9.96309 4.5089 9.97916C4.66956 9.99522 4.83087 9.95572 4.96593 9.86724C5.05634 9.80581 5.13035 9.72321 5.18152 9.62662C5.23269 9.53003 5.25946 9.4224 5.2595 9.3131C5.2595 8.19024 5.25736 7.06739 5.2595 5.94453C6.28322 7.17024 7.30907 8.39424 8.33707 9.61653C8.4799 9.76122 8.65676 9.86772 8.85145 9.92628C9.04614 9.98484 9.25242 9.99357 9.45136 9.95167C9.59184 9.924 9.71973 9.85198 9.81624 9.74622C9.91275 9.64045 9.97278 9.50652 9.9875 9.3641C9.98979 7.78096 9.98979 6.19796 9.9875 4.6151C9.97275 4.44614 9.8952 4.28884 9.77016 4.17425C9.64512 4.05966 9.48168 3.99609 9.31207 3.99609C9.14247 3.99609 8.97902 4.05966 8.85399 4.17425C8.72895 4.28884 8.6514 4.44614 8.63665 4.6151C8.63665 5.75596 8.62979 6.89553 8.63665 8.03596C7.63122 6.85053 6.63822 5.65481 5.63665 4.4651C5.5046 4.29578 5.32979 4.16474 5.13023 4.08549C4.93067 4.00624 4.71359 3.98165 4.50136 4.01424C4.34059 4.03214 4.19154 4.10704 4.08124 4.22536C3.97093 4.34369 3.90666 4.49761 3.90007 4.65924Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default NginxIcon;
|
||||
File diff suppressed because one or more lines are too long
@@ -1,60 +0,0 @@
|
||||
export default function RedisIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_2061_4282)">
|
||||
<path
|
||||
d="M13.3198 10.158C12.5879 10.5395 8.79654 12.0984 7.98938 12.5192C7.18221 12.94 6.73382 12.936 6.09616 12.6312C5.45855 12.3263 1.42388 10.6966 0.697072 10.3492C0.333858 10.1756 0.142822 10.029 0.142822 9.8906V8.50438C0.142822 8.50438 5.3955 7.3609 6.24348 7.05667C7.09141 6.75244 7.38563 6.74145 8.10723 7.00578C8.82895 7.2702 13.1439 8.0487 13.8571 8.30992L13.8568 9.67653C13.8569 9.81356 13.6923 9.96388 13.3198 10.158Z"
|
||||
fill="#912626"
|
||||
/>
|
||||
<path
|
||||
d="M13.3195 8.77972C12.5877 9.16104 8.79642 10.72 7.98926 11.1407C7.18215 11.5616 6.73376 11.5575 6.09615 11.2527C5.45849 10.9481 1.42397 9.31805 0.697221 8.97086C-0.029529 8.62345 -0.0447433 8.38436 0.66915 8.10482C1.38304 7.82518 5.39544 6.25098 6.24353 5.94675C7.09145 5.64263 7.38561 5.63154 8.10722 5.89597C8.82888 6.16029 12.5975 7.66034 13.3106 7.9215C14.024 8.18298 14.0513 8.39829 13.3195 8.77972Z"
|
||||
fill="#C6302B"
|
||||
/>
|
||||
<path
|
||||
d="M13.3198 7.91483C12.5879 8.29637 8.79654 9.85519 7.98938 10.2762C7.18221 10.6968 6.73382 10.6928 6.09616 10.388C5.4585 10.0833 1.42388 8.45338 0.697072 8.10597C0.333858 7.9324 0.142822 7.78604 0.142822 7.64756V6.26119C0.142822 6.26119 5.3955 5.11776 6.24348 4.81353C7.09141 4.50929 7.38563 4.49826 8.10723 4.76263C8.829 5.02701 13.144 5.80535 13.8571 6.06661L13.8568 7.43338C13.8569 7.57036 13.6923 7.72069 13.3198 7.91483Z"
|
||||
fill="#912626"
|
||||
/>
|
||||
<path
|
||||
d="M13.3195 6.53701C12.5877 6.91844 8.79642 8.47726 7.98926 8.89817C7.18215 9.31892 6.73376 9.3148 6.09615 9.00998C5.45849 8.70537 1.42397 7.07541 0.697221 6.72816C-0.029529 6.38085 -0.0447433 6.14171 0.66915 5.86207C1.38304 5.58258 5.39549 4.00828 6.24353 3.7041C7.09145 3.39992 7.38561 3.38889 8.10722 3.65326C8.82888 3.91758 12.5975 5.41753 13.3106 5.6788C14.024 5.94023 14.0513 6.15558 13.3195 6.53701Z"
|
||||
fill="#C6302B"
|
||||
/>
|
||||
<path
|
||||
d="M13.3198 5.58855C12.5879 5.96998 8.79654 7.5289 7.98938 7.94987C7.18221 8.37062 6.73382 8.36649 6.09616 8.06167C5.4585 7.75701 1.42388 6.12705 0.697072 5.7798C0.333858 5.60607 0.142822 5.45965 0.142822 5.32133V3.9349C0.142822 3.9349 5.3955 2.79153 6.24348 2.48735C7.09141 2.18307 7.38563 2.17214 8.10723 2.43646C8.829 2.70083 13.144 3.47917 13.8571 3.74044L13.8568 5.10715C13.8569 5.24403 13.6923 5.39435 13.3198 5.58855Z"
|
||||
fill="#912626"
|
||||
/>
|
||||
<path
|
||||
d="M13.3195 4.21078C12.5876 4.59221 8.79639 6.15113 7.98923 6.57188C7.18212 6.99263 6.73373 6.98851 6.09612 6.68385C5.45852 6.37903 1.42394 4.74917 0.697248 4.40187C-0.0295558 4.05462 -0.0447165 3.81542 0.669123 3.53583C1.38302 3.2563 5.39546 1.68221 6.2435 1.37792C7.09143 1.07369 7.38559 1.06276 8.1072 1.32714C8.82886 1.59151 12.5975 3.09146 13.3106 3.35272C14.0239 3.61394 14.0513 3.82935 13.3195 4.21078Z"
|
||||
fill="#C6302B"
|
||||
/>
|
||||
<path
|
||||
d="M8.67572 2.86218L7.49661 2.9846L7.23267 3.61974L6.80635 2.91099L5.44483 2.78863L6.46076 2.42226L6.15594 1.85986L7.1071 2.23186L8.00378 1.93829L7.76142 2.51981L8.67572 2.86218ZM7.16228 5.94351L4.96172 5.03081L8.11494 4.54679L7.16228 5.94351ZM4.11138 3.21522C5.04219 3.21522 5.79674 3.50772 5.79674 3.86847C5.79674 4.22933 5.04219 4.52177 4.11138 4.52177C3.18058 4.52177 2.42603 4.22927 2.42603 3.86847C2.42603 3.50772 3.18058 3.21522 4.11138 3.21522Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M10.0693 3.0357L11.9355 3.77316L10.0709 4.50993L10.0693 3.0357Z"
|
||||
fill="#621B1C"
|
||||
/>
|
||||
<path
|
||||
d="M8.00464 3.85234L10.0693 3.03564L10.0709 4.50988L9.86844 4.58906L8.00464 3.85234Z"
|
||||
fill="#9A2928"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2061_4282">
|
||||
<rect
|
||||
width="13.7143"
|
||||
height="13.7143"
|
||||
fill="white"
|
||||
transform="translate(0.142822 0.143066)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -8,12 +8,14 @@ export interface AlertBreadcrumbProps {
|
||||
items: BreadcrumbItemConfig[];
|
||||
className?: string;
|
||||
showDivider?: boolean;
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
function AlertBreadcrumb({
|
||||
items,
|
||||
className,
|
||||
showDivider = true,
|
||||
testId,
|
||||
}: AlertBreadcrumbProps): JSX.Element {
|
||||
const breadcrumbItems = items.map((item) => ({
|
||||
title: <BreadcrumbItem {...item} />,
|
||||
@@ -24,6 +26,7 @@ function AlertBreadcrumb({
|
||||
<Breadcrumb
|
||||
className={`${styles.breadcrumb} ${className || ''}`}
|
||||
items={breadcrumbItems}
|
||||
data-testid={testId}
|
||||
/>
|
||||
{showDivider && <Divider className={styles.divider} />}
|
||||
</>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import dayjs from 'dayjs';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { X } from '@signozhq/icons';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/widgets/widget';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
|
||||
@@ -5,16 +5,16 @@ import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { ViewMenuAction } from 'container/GridCardLayout/config';
|
||||
import GridCard from 'container/GridCardLayout/GridCard';
|
||||
import { Card } from 'container/GridCardLayout/styles';
|
||||
import { ViewMenuAction } from 'container/WidgetCard/config';
|
||||
import GridCard from 'container/WidgetCard/Card';
|
||||
import { Card } from 'container/WidgetCard/styles';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/widgets/widget';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
import { CaptureDataProps } from '../CeleryTaskDetail/CeleryTaskDetail';
|
||||
|
||||
@@ -5,15 +5,15 @@ import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { ENTITY_VERSION_V4 } from 'constants/app';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { ViewMenuAction } from 'container/GridCardLayout/config';
|
||||
import GridCard from 'container/GridCardLayout/GridCard';
|
||||
import { Card } from 'container/GridCardLayout/styles';
|
||||
import { ViewMenuAction } from 'container/WidgetCard/config';
|
||||
import GridCard from 'container/WidgetCard/Card';
|
||||
import { Card } from 'container/WidgetCard/styles';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { getStartAndEndTimesInMilliseconds } from 'pages/MessagingQueues/MessagingQueuesUtils';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/widgets/widget';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
|
||||
import { CaptureDataProps } from '../CeleryTaskDetail/CeleryTaskDetail';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useSelector } from 'react-redux';
|
||||
import { Card } from 'antd';
|
||||
import { Typography } from '@signozhq/ui/typography';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { CardContainer } from 'container/GridCardLayout/styles';
|
||||
import { CardContainer } from 'container/WidgetCard/styles';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
import { ChevronDown, ChevronUp } from '@signozhq/icons';
|
||||
import { AppState } from 'store/reducers';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
||||
import { getWidgetQuery } from 'pages/MessagingQueues/MQDetails/MetricPage/MetricPageUtil';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/widgets/widget';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource, ReduceOperators } from 'types/common/queryBuilder';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@@ -6,9 +6,9 @@ import { Col, Row } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { ViewMenuAction } from 'container/GridCardLayout/config';
|
||||
import GridCard from 'container/GridCardLayout/GridCard';
|
||||
import { Card } from 'container/GridCardLayout/styles';
|
||||
import { ViewMenuAction } from 'container/WidgetCard/config';
|
||||
import GridCard from 'container/WidgetCard/Card';
|
||||
import { Card } from 'container/WidgetCard/styles';
|
||||
import { Button } from 'container/MetricsApplication/Tabs/styles';
|
||||
import { useGraphClickHandler } from 'container/MetricsApplication/Tabs/util';
|
||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||
|
||||
@@ -8,7 +8,7 @@ import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
||||
import { getQueryPayloadFromWidgetsData } from 'pages/Celery/CeleryOverview/CeleryOverviewUtils';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { SuccessResponse } from 'types/api';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/widgets/widget';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { History, Location } from 'history';
|
||||
import getRenderer from 'lib/uPlotLib/utils/getRenderer';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/widgets/widget';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
@@ -4,10 +4,9 @@ import { useSelector } from 'react-redux';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import ROUTES from 'constants/routes';
|
||||
import useUpdatedQuery from 'container/GridCardLayout/useResolveQuery';
|
||||
import useUpdatedQuery from 'container/WidgetCard/hooks/useResolveQuery';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useNotifications } from 'hooks/useNotifications';
|
||||
import { useDashboardStore } from 'providers/Dashboard/store/useDashboardStore';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
|
||||
@@ -80,7 +79,6 @@ export function useNavigateToExplorer(): (
|
||||
);
|
||||
|
||||
const { getUpdatedQuery } = useUpdatedQuery();
|
||||
const { dashboardData } = useDashboardStore();
|
||||
const { notifications } = useNotifications();
|
||||
|
||||
return useCallback(
|
||||
@@ -112,7 +110,6 @@ export function useNavigateToExplorer(): (
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
},
|
||||
dashboardData,
|
||||
})
|
||||
.then((query) => {
|
||||
preparedQuery = query;
|
||||
@@ -136,13 +133,6 @@ export function useNavigateToExplorer(): (
|
||||
|
||||
window.open(withBasePath(newExplorerPath), sameTab ? '_self' : '_blank');
|
||||
},
|
||||
[
|
||||
prepareQuery,
|
||||
minTime,
|
||||
maxTime,
|
||||
getUpdatedQuery,
|
||||
dashboardData,
|
||||
notifications,
|
||||
],
|
||||
[prepareQuery, minTime, maxTime, getUpdatedQuery, notifications],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,9 +7,8 @@ import axios from 'axios';
|
||||
import TextToolTip from 'components/TextToolTip';
|
||||
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { useOptionsMenu } from 'container/OptionsMenu';
|
||||
import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam';
|
||||
import { useGetSavedViewParams } from 'hooks/saveViews/useGetSavedViewParams';
|
||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||
import { useDeleteView } from 'hooks/saveViews/useDeleteView';
|
||||
import { useGetAllViews } from 'hooks/saveViews/useGetAllViews';
|
||||
@@ -69,9 +68,7 @@ function ExplorerCard({
|
||||
setIsOpen(newOpen);
|
||||
};
|
||||
|
||||
const viewName = useGetSearchQueryParam(QueryParams.viewName) || '';
|
||||
|
||||
const viewKey = useGetSearchQueryParam(QueryParams.viewKey) || '';
|
||||
const { viewName, viewKey } = useGetSavedViewParams();
|
||||
|
||||
const { options } = useOptionsMenu({
|
||||
storageKey:
|
||||
|
||||
@@ -57,8 +57,8 @@ function MenuItemGenerator({
|
||||
|
||||
handleExplorerTabChange(currentPanelType, {
|
||||
query,
|
||||
name,
|
||||
id,
|
||||
viewName: name,
|
||||
viewKey: id,
|
||||
});
|
||||
},
|
||||
[viewData, handleExplorerTabChange],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user