mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-06 05:42:02 +00:00
Compare commits
16 Commits
light-mode
...
chore/issu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c26aa6ed8e | ||
|
|
e4f99ffee7 | ||
|
|
57fe84046d | ||
|
|
129d18a1b7 | ||
|
|
48ccdfcf64 | ||
|
|
8c7dc942d0 | ||
|
|
0e1bb5fd91 | ||
|
|
d7a743cea9 | ||
|
|
850dc10983 | ||
|
|
e8e85a3790 | ||
|
|
20d9d5ae38 | ||
|
|
9a046ab89d | ||
|
|
ccb88ab03f | ||
|
|
4f0e245e3d | ||
|
|
a5549f6d5b | ||
|
|
1d967fadac |
26
.github/workflows/build-enterprise.yaml
vendored
26
.github/workflows/build-enterprise.yaml
vendored
@@ -58,19 +58,19 @@ jobs:
|
||||
run: |
|
||||
mkdir -p frontend
|
||||
echo 'CI=1' > frontend/.env
|
||||
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' >> frontend/.env
|
||||
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
|
||||
echo 'SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
|
||||
echo 'SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
|
||||
echo 'SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
|
||||
echo 'SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
|
||||
echo 'TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env
|
||||
echo 'TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env
|
||||
echo 'POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> frontend/.env
|
||||
echo 'PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> frontend/.env
|
||||
echo 'APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> frontend/.env
|
||||
echo 'PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> frontend/.env
|
||||
echo 'DOCS_BASE_URL="https://signoz.io"' >> frontend/.env
|
||||
echo 'VITE_INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' >> frontend/.env
|
||||
echo 'VITE_SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
|
||||
echo 'VITE_SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
|
||||
echo 'VITE_SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
|
||||
echo 'VITE_SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
|
||||
echo 'VITE_SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
|
||||
echo 'VITE_TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env
|
||||
echo 'VITE_TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env
|
||||
echo 'VITE_POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> frontend/.env
|
||||
echo 'VITE_PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> frontend/.env
|
||||
echo 'VITE_APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> frontend/.env
|
||||
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> frontend/.env
|
||||
echo 'VITE_DOCS_BASE_URL="https://signoz.io"' >> frontend/.env
|
||||
- name: cache-dotenv
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
||||
12
.github/workflows/build-staging.yaml
vendored
12
.github/workflows/build-staging.yaml
vendored
@@ -64,12 +64,12 @@ jobs:
|
||||
run: |
|
||||
mkdir -p frontend
|
||||
echo 'CI=1' > frontend/.env
|
||||
echo 'TUNNEL_URL="${{ secrets.NP_TUNNEL_URL }}"' >> frontend/.env
|
||||
echo 'TUNNEL_DOMAIN="${{ secrets.NP_TUNNEL_DOMAIN }}"' >> frontend/.env
|
||||
echo 'PYLON_APP_ID="${{ secrets.NP_PYLON_APP_ID }}"' >> frontend/.env
|
||||
echo 'APPCUES_APP_ID="${{ secrets.NP_APPCUES_APP_ID }}"' >> frontend/.env
|
||||
echo 'PYLON_IDENTITY_SECRET="${{ secrets.NP_PYLON_IDENTITY_SECRET }}"' >> frontend/.env
|
||||
echo 'DOCS_BASE_URL="https://staging.signoz.io"' >> frontend/.env
|
||||
echo 'VITE_TUNNEL_URL="${{ secrets.NP_TUNNEL_URL }}"' >> frontend/.env
|
||||
echo 'VITE_TUNNEL_DOMAIN="${{ secrets.NP_TUNNEL_DOMAIN }}"' >> frontend/.env
|
||||
echo 'VITE_PYLON_APP_ID="${{ secrets.NP_PYLON_APP_ID }}"' >> frontend/.env
|
||||
echo 'VITE_APPCUES_APP_ID="${{ secrets.NP_APPCUES_APP_ID }}"' >> frontend/.env
|
||||
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.NP_PYLON_IDENTITY_SECRET }}"' >> frontend/.env
|
||||
echo 'VITE_DOCS_BASE_URL="https://staging.signoz.io"' >> frontend/.env
|
||||
- name: cache-dotenv
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
||||
26
.github/workflows/gor-signoz.yaml
vendored
26
.github/workflows/gor-signoz.yaml
vendored
@@ -24,19 +24,19 @@ jobs:
|
||||
- name: dotenv-frontend
|
||||
working-directory: frontend
|
||||
run: |
|
||||
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > .env
|
||||
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> .env
|
||||
echo 'SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> .env
|
||||
echo 'SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> .env
|
||||
echo 'SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> .env
|
||||
echo 'SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> .env
|
||||
echo 'TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> .env
|
||||
echo 'TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> .env
|
||||
echo 'POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> .env
|
||||
echo 'PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> .env
|
||||
echo 'APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> .env
|
||||
echo 'PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> .env
|
||||
echo 'DOCS_BASE_URL="https://signoz.io"' >> .env
|
||||
echo 'VITE_INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > .env
|
||||
echo 'VITE_SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> .env
|
||||
echo 'VITE_SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> .env
|
||||
echo 'VITE_SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> .env
|
||||
echo 'VITE_SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> .env
|
||||
echo 'VITE_SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> .env
|
||||
echo 'VITE_TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> .env
|
||||
echo 'VITE_TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> .env
|
||||
echo 'VITE_POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> .env
|
||||
echo 'VITE_PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> .env
|
||||
echo 'VITE_APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> .env
|
||||
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> .env
|
||||
echo 'VITE_DOCS_BASE_URL="https://signoz.io"' >> .env
|
||||
- name: node-setup
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
|
||||
3
.github/workflows/jsci.yaml
vendored
3
.github/workflows/jsci.yaml
vendored
@@ -103,8 +103,9 @@ jobs:
|
||||
make py-test-setup
|
||||
|
||||
- name: Generate permissions.type.ts
|
||||
working-directory: ./frontend
|
||||
run: |
|
||||
node frontend/scripts/generate-permissions-type.js
|
||||
yarn generate:permissions-type
|
||||
|
||||
- name: Teardown test environment
|
||||
if: always()
|
||||
|
||||
2
Makefile
2
Makefile
@@ -238,4 +238,4 @@ py-clean: ## Clear all pycache and pytest cache from tests directory recursively
|
||||
.PHONY: gen-mocks
|
||||
gen-mocks:
|
||||
@echo ">> Generating mocks"
|
||||
@mockery --config .mockery.yml
|
||||
@mockery --config .mockery.yml
|
||||
|
||||
@@ -190,7 +190,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.113.0
|
||||
image: signoz/signoz:v0.114.0
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
# - "6060:6060" # pprof port
|
||||
@@ -213,7 +213,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.144.1
|
||||
image: signoz/signoz-otel-collector:v0.144.2
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
command:
|
||||
@@ -241,7 +241,7 @@ services:
|
||||
replicas: 3
|
||||
signoz-telemetrystore-migrator:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.144.1
|
||||
image: signoz/signoz-otel-collector:v0.144.2
|
||||
environment:
|
||||
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
|
||||
@@ -117,7 +117,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:v0.113.0
|
||||
image: signoz/signoz:v0.114.0
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
volumes:
|
||||
@@ -139,7 +139,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.144.1
|
||||
image: signoz/signoz-otel-collector:v0.144.2
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
command:
|
||||
@@ -167,7 +167,7 @@ services:
|
||||
replicas: 3
|
||||
signoz-telemetrystore-migrator:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:v0.144.1
|
||||
image: signoz/signoz-otel-collector:v0.144.2
|
||||
environment:
|
||||
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
|
||||
@@ -181,7 +181,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.113.0}
|
||||
image: signoz/signoz:${VERSION:-v0.114.0}
|
||||
container_name: signoz
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
@@ -204,7 +204,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.1}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
|
||||
container_name: signoz-otel-collector
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
@@ -229,7 +229,7 @@ services:
|
||||
- "4318:4318" # OTLP HTTP receiver
|
||||
signoz-telemetrystore-migrator:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.1}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
|
||||
container_name: signoz-telemetrystore-migrator
|
||||
environment:
|
||||
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
|
||||
@@ -109,7 +109,7 @@ services:
|
||||
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||
signoz:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz:${VERSION:-v0.113.0}
|
||||
image: signoz/signoz:${VERSION:-v0.114.0}
|
||||
container_name: signoz
|
||||
ports:
|
||||
- "8080:8080" # signoz port
|
||||
@@ -132,7 +132,7 @@ services:
|
||||
retries: 3
|
||||
otel-collector:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.1}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
|
||||
container_name: signoz-otel-collector
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
@@ -157,7 +157,7 @@ services:
|
||||
- "4318:4318" # OTLP HTTP receiver
|
||||
signoz-telemetrystore-migrator:
|
||||
!!merge <<: *db-depend
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.1}
|
||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
|
||||
container_name: signoz-telemetrystore-migrator
|
||||
environment:
|
||||
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
["@babel/preset-react", { "runtime": "automatic" }],
|
||||
"@babel/preset-typescript"
|
||||
],
|
||||
"plugins": [
|
||||
"react-hot-loader/babel",
|
||||
"@babel/plugin-proposal-class-properties"
|
||||
],
|
||||
"env": {
|
||||
"production": {
|
||||
"presets": ["minify"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ module.exports = {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
node: true,
|
||||
'jest/globals': true,
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
@@ -25,6 +24,7 @@ module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
tsconfigRootDir: __dirname,
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
@@ -37,7 +37,7 @@ module.exports = {
|
||||
'simple-import-sort', // Auto-sort imports
|
||||
'react-hooks', // React Hooks rules
|
||||
'prettier', // Code formatting
|
||||
'jest', // Jest test rules
|
||||
// 'jest', // TODO: Wait support on Biome to enable again
|
||||
'jsx-a11y', // Accessibility rules
|
||||
'import', // Import/export linting
|
||||
'sonarjs', // Code quality/complexity
|
||||
@@ -1 +1 @@
|
||||
16.15.0
|
||||
22
|
||||
|
||||
4
frontend/__mocks__/env.ts
Normal file
4
frontend/__mocks__/env.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export const ENVIRONMENT = {
|
||||
baseURL: process.env.VITE_FRONTEND_API_ENDPOINT || '',
|
||||
wsURL: process.env.VITE_WEBSOCKET_API_ENDPOINT || '',
|
||||
};
|
||||
20
frontend/babel.config.cjs
Normal file
20
frontend/babel.config.cjs
Normal file
@@ -0,0 +1,20 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', { modules: 'auto' }],
|
||||
['@babel/preset-react', { runtime: 'automatic' }],
|
||||
['@babel/preset-typescript'],
|
||||
],
|
||||
plugins: ['@babel/plugin-proposal-class-properties'],
|
||||
env: {
|
||||
test: {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{ modules: 'commonjs', targets: { node: 'current' } },
|
||||
],
|
||||
['@babel/preset-react', { runtime: 'automatic' }],
|
||||
['@babel/preset-typescript'],
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
['@babel/preset-env', { targets: { node: 'current' } }],
|
||||
'@babel/preset-typescript',
|
||||
],
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"path": "./build/**.js",
|
||||
"maxSize": "1.2MB"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
NODE_ENV="development"
|
||||
BUNDLE_ANALYSER="true"
|
||||
FRONTEND_API_ENDPOINT="http://localhost:8080/"
|
||||
PYLON_APP_ID="pylon-app-id"
|
||||
APPCUES_APP_ID="appcess-app-id"
|
||||
PYLON_IDENTITY_SECRET="pylon-identity-secret"
|
||||
VITE_FRONTEND_API_ENDPOINT="http://localhost:8080/"
|
||||
VITE_PYLON_APP_ID="pylon-app-id"
|
||||
VITE_APPCUES_APP_ID="appcess-app-id"
|
||||
VITE_PYLON_IDENTITY_SECRET="pylon-identity-secret"
|
||||
|
||||
CI="1"
|
||||
CI="1"
|
||||
|
||||
@@ -1,127 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
http-equiv="Cache-Control"
|
||||
content="no-cache, no-store, must-revalidate, max-age: 0"
|
||||
/>
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
|
||||
<!-- Preconnect to CDNs -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="preconnect" href="https://cdn.vercel.com" crossorigin />
|
||||
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<title data-react-helmet="true">
|
||||
Open source Observability platform | SigNoz
|
||||
</title>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
property="og:title"
|
||||
content="Open source Observability platform | SigNoz"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="description"
|
||||
content="SigNoz is an open source observability platform to help you find issues in your deployed applications & solve them quickly. It provides a single pane of glass for metrics, traces and logs with deep filtering and aggregation to pin down specific issues very quickly."
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
property="og:description"
|
||||
content="SigNoz is an open source observability platform to help you find issues in your deployed applications & solve them quickly. It provides a single pane of glass for metrics, traces and logs with deep filtering and aggregation to pin down specific issues very quickly."
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
property="og:image"
|
||||
content="/images/signoz-hero-image.webp"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="twitter:image"
|
||||
content="/images/signoz-hero-image.webp"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="twitter:image:alt"
|
||||
content="Image for Open source Observability platform | SigNoz"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="twitter:card"
|
||||
content="summary_large_image"
|
||||
/>
|
||||
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
|
||||
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico" />
|
||||
|
||||
<% if (htmlWebpackPlugin.options.templateParameters.preloadFonts) { %> <%
|
||||
htmlWebpackPlugin.options.templateParameters.preloadFonts.forEach(function(font)
|
||||
{ %>
|
||||
<link
|
||||
rel="preload"
|
||||
href="<%= font.href %>"
|
||||
as="<%= font.as %>"
|
||||
type="<%= font.type %>"
|
||||
crossorigin="<%= font.crossorigin %>"
|
||||
/>
|
||||
<% }); %> <% } %>
|
||||
</head>
|
||||
<body data-theme="default">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script>
|
||||
const PYLON_APP_ID = '<%= htmlWebpackPlugin.options.PYLON_APP_ID %>';
|
||||
(function () {
|
||||
var e = window;
|
||||
var t = document;
|
||||
var n = function () {
|
||||
n.e(arguments);
|
||||
};
|
||||
n.q = [];
|
||||
n.e = function (e) {
|
||||
n.q.push(e);
|
||||
};
|
||||
e.Pylon = n;
|
||||
var r = function () {
|
||||
var e = t.createElement('script');
|
||||
e.setAttribute('type', 'text/javascript');
|
||||
e.setAttribute('async', 'true');
|
||||
e.setAttribute(
|
||||
'src',
|
||||
'https://widget.usepylon.com/widget/' + PYLON_APP_ID,
|
||||
);
|
||||
var n = t.getElementsByTagName('script')[0];
|
||||
n.parentNode.insertBefore(e, n);
|
||||
};
|
||||
if (t.readyState === 'complete') {
|
||||
r();
|
||||
} else if (e.addEventListener) {
|
||||
e.addEventListener('load', r, false);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.AppcuesSettings = { enableURLDetection: true };
|
||||
</script>
|
||||
<script>
|
||||
const APPCUES_APP_ID = '<%= htmlWebpackPlugin.options.APPCUES_APP_ID %>';
|
||||
(function (d, t) {
|
||||
var a = d.createElement(t);
|
||||
a.async = 1;
|
||||
a.src = '//fast.appcues.com/' + APPCUES_APP_ID + '.js';
|
||||
var s = d.getElementsByTagName(t)[0];
|
||||
s.parentNode.insertBefore(a, s);
|
||||
})(document, 'script');
|
||||
</script>
|
||||
<link rel="stylesheet" href="/css/uPlot.min.css" />
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
http-equiv="Cache-Control"
|
||||
content="no-cache, no-store, must-revalidate, max-age: 0"
|
||||
/>
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="preconnect" href="https://cdn.vercel.com" crossorigin />
|
||||
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<title data-react-helmet="true">
|
||||
Open source Observability platform | SigNoz
|
||||
</title>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
property="og:title"
|
||||
content="Open source Observability platform | SigNoz"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="description"
|
||||
content="SigNoz is an open source observability platform to help you find issues in your deployed applications & solve them quickly. It provides a single pane of glass for metrics, traces and logs with deep filtering and aggregation to pin down specific issues very quickly."
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
property="og:description"
|
||||
content="SigNoz is an open source observability platform to help you find issues in your deployed applications & solve them quickly. It provides a single pane of glass for metrics, traces and logs with deep filtering and aggregation to pin down specific issues very quickly."
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
property="og:image"
|
||||
content="/images/signoz-hero-image.webp"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="twitter:image"
|
||||
content="/images/signoz-hero-image.webp"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="twitter:image:alt"
|
||||
content="Image for Open source Observability platform | SigNoz"
|
||||
/>
|
||||
<meta
|
||||
data-react-helmet="true"
|
||||
name="twitter:card"
|
||||
content="summary_large_image"
|
||||
/>
|
||||
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
|
||||
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<body data-theme="default">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
<script>
|
||||
var PYLON_APP_ID = '<%- PYLON_APP_ID %>';
|
||||
if (PYLON_APP_ID) {
|
||||
(function () {
|
||||
var e = window;
|
||||
var t = document;
|
||||
var n = function () {
|
||||
n.e(arguments);
|
||||
};
|
||||
n.q = [];
|
||||
n.e = function (e) {
|
||||
n.q.push(e);
|
||||
};
|
||||
e.Pylon = n;
|
||||
var r = function () {
|
||||
var e = t.createElement('script');
|
||||
e.setAttribute('type', 'text/javascript');
|
||||
e.setAttribute('async', 'true');
|
||||
e.setAttribute(
|
||||
'src',
|
||||
'https://widget.usepylon.com/widget/' + PYLON_APP_ID,
|
||||
);
|
||||
var n = t.getElementsByTagName('script')[0];
|
||||
n.parentNode.insertBefore(e, n);
|
||||
};
|
||||
if (t.readyState === 'complete') {
|
||||
r();
|
||||
} else if (e.addEventListener) {
|
||||
e.addEventListener('load', r, false);
|
||||
}
|
||||
})();
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.AppcuesSettings = { enableURLDetection: true };
|
||||
</script>
|
||||
<script>
|
||||
var APPCUES_APP_ID = '<%- APPCUES_APP_ID %>';
|
||||
if (APPCUES_APP_ID) {
|
||||
(function (d, t) {
|
||||
var a = d.createElement(t);
|
||||
a.async = 1;
|
||||
a.src = '//fast.appcues.com/' + APPCUES_APP_ID + '.js';
|
||||
var s = d.getElementsByTagName(t)[0];
|
||||
s.parentNode.insertBefore(a, s);
|
||||
})(document, 'script');
|
||||
}
|
||||
</script>
|
||||
<link rel="stylesheet" href="/css/uPlot.min.css" />
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,29 +17,53 @@ const config: Config.InitialOptions = {
|
||||
'^hooks/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
|
||||
'^src/hooks/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
|
||||
'^.*/useSafeNavigate$': USE_SAFE_NAVIGATE_MOCK_PATH,
|
||||
'^constants/env$': '<rootDir>/__mocks__/env.ts',
|
||||
'^src/constants/env$': '<rootDir>/__mocks__/env.ts',
|
||||
'^@signozhq/icons$':
|
||||
'<rootDir>/node_modules/@signozhq/icons/dist/index.esm.js',
|
||||
'^react-syntax-highlighter/dist/esm/(.*)$':
|
||||
'<rootDir>/node_modules/react-syntax-highlighter/dist/cjs/$1',
|
||||
'^@signozhq/sonner$':
|
||||
'<rootDir>/node_modules/@signozhq/sonner/dist/sonner.js',
|
||||
'^@signozhq/button$':
|
||||
'<rootDir>/node_modules/@signozhq/button/dist/button.js',
|
||||
'^@signozhq/calendar$':
|
||||
'<rootDir>/node_modules/@signozhq/calendar/dist/calendar.js',
|
||||
'^@signozhq/badge': '<rootDir>/node_modules/@signozhq/badge/dist/badge.js',
|
||||
'^@signozhq/checkbox':
|
||||
'<rootDir>/node_modules/@signozhq/checkbox/dist/checkbox.js',
|
||||
'^@signozhq/switch': '<rootDir>/node_modules/@signozhq/switch/dist/switch.js',
|
||||
'^@signozhq/callout':
|
||||
'<rootDir>/node_modules/@signozhq/callout/dist/callout.js',
|
||||
'^@signozhq/combobox':
|
||||
'<rootDir>/node_modules/@signozhq/combobox/dist/combobox.js',
|
||||
'^@signozhq/input': '<rootDir>/node_modules/@signozhq/input/dist/input.js',
|
||||
'^@signozhq/command':
|
||||
'<rootDir>/node_modules/@signozhq/command/dist/command.js',
|
||||
'^@signozhq/radio-group':
|
||||
'<rootDir>/node_modules/@signozhq/radio-group/dist/radio-group.js',
|
||||
'^@signozhq/toggle-group$':
|
||||
'<rootDir>/node_modules/@signozhq/toggle-group/dist/toggle-group.js',
|
||||
'^@signozhq/dialog$':
|
||||
'<rootDir>/node_modules/@signozhq/dialog/dist/dialog.js',
|
||||
},
|
||||
globals: {
|
||||
extensionsToTreatAsEsm: ['.ts'],
|
||||
'ts-jest': {
|
||||
useESM: true,
|
||||
isolatedModules: true,
|
||||
tsconfig: '<rootDir>/tsconfig.jest.json',
|
||||
},
|
||||
},
|
||||
extensionsToTreatAsEsm: ['.ts'],
|
||||
testMatch: ['<rootDir>/src/**/*?(*.)(test).(ts|js)?(x)'],
|
||||
preset: 'ts-jest/presets/js-with-ts-esm',
|
||||
transform: {
|
||||
'^.+\\.(ts|tsx)?$': 'ts-jest',
|
||||
'^.+\\.(ts|tsx)?$': [
|
||||
'ts-jest',
|
||||
{
|
||||
useESM: true,
|
||||
tsconfig: '<rootDir>/tsconfig.jest.json',
|
||||
},
|
||||
],
|
||||
'^.+\\.(js|jsx)$': 'babel-jest',
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios|@signozhq/design-tokens|@signozhq/table|@signozhq/calendar|@signozhq/input|@signozhq/popover|@signozhq/button|@signozhq/sonner|@signozhq/*|date-fns|d3-interpolate|d3-color|api|@codemirror|@lezer|@marijn)/)',
|
||||
'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios|@signozhq/design-tokens|@signozhq/table|@signozhq/calendar|@signozhq/input|@signozhq/popover|@signozhq/button|@signozhq/sonner|@signozhq/*|date-fns|d3-interpolate|d3-color|api|@codemirror|@lezer|@marijn|@grafana)/)',
|
||||
],
|
||||
setupFilesAfterEnv: ['<rootDir>jest.setup.ts'],
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||
testPathIgnorePatterns: ['/node_modules/', '/public/'],
|
||||
moduleDirectories: ['node_modules', 'src'],
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
|
||||
@@ -1,293 +1,285 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "webpack.config.js",
|
||||
"scripts": {
|
||||
"i18n:generate-hash": "node ./i18-generate-hash.js",
|
||||
"dev": "cross-env NODE_ENV=development webpack serve --progress",
|
||||
"build": "webpack --config=webpack.config.prod.js --progress",
|
||||
"prettify": "prettier --write .",
|
||||
"fmt": "prettier --check .",
|
||||
"lint": "eslint ./src",
|
||||
"lint:fix": "eslint ./src --fix",
|
||||
"jest": "jest",
|
||||
"jest:coverage": "jest --coverage",
|
||||
"jest:watch": "jest --watch",
|
||||
"postinstall": "yarn i18n:generate-hash && (is-ci || yarn husky:configure) && node scripts/update-registry.js",
|
||||
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
|
||||
"commitlint": "commitlint --edit $1",
|
||||
"test": "jest",
|
||||
"test:changedsince": "jest --changedSince=main --coverage --silent",
|
||||
"generate:api": "orval --config ./orval.config.ts && sh scripts/post-types-generation.sh",
|
||||
"generate:permissions-type": "node scripts/generate-permissions-type.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.15.0"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "6.0.0",
|
||||
"@ant-design/icons": "4.8.0",
|
||||
"@codemirror/autocomplete": "6.18.6",
|
||||
"@codemirror/lang-javascript": "6.2.3",
|
||||
"@dnd-kit/core": "6.1.0",
|
||||
"@dnd-kit/modifiers": "7.0.0",
|
||||
"@dnd-kit/sortable": "8.0.0",
|
||||
"@dnd-kit/utilities": "3.2.2",
|
||||
"@grafana/data": "^11.2.3",
|
||||
"@mdx-js/loader": "2.3.0",
|
||||
"@mdx-js/react": "2.3.0",
|
||||
"@monaco-editor/react": "^4.3.1",
|
||||
"@playwright/test": "1.55.1",
|
||||
"@radix-ui/react-tabs": "1.0.4",
|
||||
"@radix-ui/react-tooltip": "1.0.7",
|
||||
"@sentry/react": "8.41.0",
|
||||
"@sentry/webpack-plugin": "2.22.6",
|
||||
"@signozhq/badge": "0.0.2",
|
||||
"@signozhq/button": "0.0.2",
|
||||
"@signozhq/calendar": "0.0.0",
|
||||
"@signozhq/callout": "0.0.2",
|
||||
"@signozhq/checkbox": "0.0.2",
|
||||
"@signozhq/combobox": "0.0.2",
|
||||
"@signozhq/command": "0.0.0",
|
||||
"@signozhq/design-tokens": "2.1.1",
|
||||
"@signozhq/icons": "0.1.0",
|
||||
"@signozhq/input": "0.0.2",
|
||||
"@signozhq/popover": "0.0.0",
|
||||
"@signozhq/radio-group": "0.0.2",
|
||||
"@signozhq/resizable": "0.0.0",
|
||||
"@signozhq/sonner": "0.1.0",
|
||||
"@signozhq/switch": "0.0.2",
|
||||
"@signozhq/table": "0.3.7",
|
||||
"@signozhq/tooltip": "0.0.2",
|
||||
"@tanstack/react-table": "8.20.6",
|
||||
"@tanstack/react-virtual": "3.11.2",
|
||||
"@uiw/codemirror-theme-copilot": "4.23.11",
|
||||
"@uiw/codemirror-theme-github": "4.24.1",
|
||||
"@uiw/react-codemirror": "4.23.10",
|
||||
"@uiw/react-md-editor": "3.23.5",
|
||||
"@visx/group": "3.3.0",
|
||||
"@visx/hierarchy": "3.12.0",
|
||||
"@visx/shape": "3.5.0",
|
||||
"@visx/tooltip": "3.3.0",
|
||||
"@xstate/react": "^3.0.0",
|
||||
"ansi-to-html": "0.7.2",
|
||||
"antd": "5.11.0",
|
||||
"antd-table-saveas-excel": "2.2.1",
|
||||
"antlr4": "4.13.2",
|
||||
"axios": "1.12.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^29.6.4",
|
||||
"babel-loader": "9.1.3",
|
||||
"babel-plugin-named-asset-import": "^0.3.7",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"babel-preset-react-app": "^10.0.1",
|
||||
"chart.js": "3.9.1",
|
||||
"chartjs-adapter-date-fns": "^2.0.0",
|
||||
"chartjs-plugin-annotation": "^1.4.0",
|
||||
"classnames": "2.3.2",
|
||||
"color": "^4.2.1",
|
||||
"color-alpha": "1.1.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"crypto-js": "4.2.0",
|
||||
"css-loader": "5.0.0",
|
||||
"css-minimizer-webpack-plugin": "5.0.1",
|
||||
"d3-hierarchy": "3.1.2",
|
||||
"dayjs": "^1.10.7",
|
||||
"dompurify": "3.2.4",
|
||||
"dotenv": "8.2.0",
|
||||
"event-source-polyfill": "1.0.31",
|
||||
"eventemitter3": "5.0.1",
|
||||
"file-loader": "6.1.1",
|
||||
"fontfaceobserver": "2.3.0",
|
||||
"history": "4.10.1",
|
||||
"html-webpack-plugin": "5.5.0",
|
||||
"http-proxy-middleware": "3.0.5",
|
||||
"http-status-codes": "2.3.0",
|
||||
"i18next": "^21.6.12",
|
||||
"i18next-browser-languagedetector": "^6.1.3",
|
||||
"i18next-http-backend": "^1.3.2",
|
||||
"immer": "11.1.3",
|
||||
"jest": "^27.5.1",
|
||||
"js-base64": "^3.7.2",
|
||||
"less": "^4.1.2",
|
||||
"less-loader": "^10.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lucide-react": "0.498.0",
|
||||
"mini-css-extract-plugin": "2.4.5",
|
||||
"motion": "12.4.13",
|
||||
"nuqs": "2.8.8",
|
||||
"overlayscrollbars": "^2.8.1",
|
||||
"overlayscrollbars-react": "^0.5.6",
|
||||
"papaparse": "5.4.1",
|
||||
"posthog-js": "1.298.0",
|
||||
"rc-tween-one": "3.0.6",
|
||||
"react": "18.2.0",
|
||||
"react-addons-update": "15.6.3",
|
||||
"react-beautiful-dnd": "13.1.1",
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-drag-listview": "2.0.0",
|
||||
"react-error-boundary": "4.0.11",
|
||||
"react-force-graph-2d": "^1.29.1",
|
||||
"react-full-screen": "1.1.1",
|
||||
"react-grid-layout": "^1.3.4",
|
||||
"react-helmet-async": "1.3.0",
|
||||
"react-i18next": "^11.16.1",
|
||||
"react-lottie": "1.2.10",
|
||||
"react-markdown": "8.0.7",
|
||||
"react-query": "3.39.3",
|
||||
"react-redux": "^7.2.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-router-dom-v5-compat": "6.27.0",
|
||||
"react-syntax-highlighter": "15.5.0",
|
||||
"react-use": "^17.3.2",
|
||||
"react-virtuoso": "4.0.3",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"rehype-raw": "7.0.0",
|
||||
"rrule": "2.8.1",
|
||||
"stream": "^0.0.2",
|
||||
"style-loader": "1.3.0",
|
||||
"styled-components": "^5.3.11",
|
||||
"terser-webpack-plugin": "^5.2.5",
|
||||
"timestamp-nano": "^1.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"tsconfig-paths-webpack-plugin": "^3.5.1",
|
||||
"typescript": "^4.0.5",
|
||||
"uplot": "1.6.31",
|
||||
"uuid": "^8.3.2",
|
||||
"web-vitals": "^0.2.4",
|
||||
"webpack": "5.94.0",
|
||||
"webpack-dev-server": "^5.2.1",
|
||||
"webpack-retry-chunk-load-plugin": "3.1.1",
|
||||
"xstate": "^4.31.0",
|
||||
"zustand": "5.0.11"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.11",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-syntax-jsx": "^7.12.13",
|
||||
"@babel/preset-env": "^7.22.14",
|
||||
"@babel/preset-react": "^7.12.13",
|
||||
"@babel/preset-typescript": "^7.21.4",
|
||||
"@commitlint/cli": "^16.3.0",
|
||||
"@commitlint/config-conventional": "^16.2.4",
|
||||
"@faker-js/faker": "9.3.0",
|
||||
"@jest/globals": "^27.5.1",
|
||||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/react": "13.4.0",
|
||||
"@testing-library/user-event": "14.4.3",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/compression-webpack-plugin": "^9.0.0",
|
||||
"@types/copy-webpack-plugin": "^8.0.1",
|
||||
"@types/crypto-js": "4.2.2",
|
||||
"@types/dompurify": "^2.4.0",
|
||||
"@types/event-source-polyfill": "^1.0.0",
|
||||
"@types/fontfaceobserver": "2.1.0",
|
||||
"@types/jest": "^27.5.1",
|
||||
"@types/lodash-es": "^4.17.4",
|
||||
"@types/mini-css-extract-plugin": "^2.5.1",
|
||||
"@types/node": "^16.10.3",
|
||||
"@types/papaparse": "5.3.7",
|
||||
"@types/react": "18.0.26",
|
||||
"@types/react-addons-update": "0.14.21",
|
||||
"@types/react-beautiful-dnd": "13.1.8",
|
||||
"@types/react-dom": "18.0.10",
|
||||
"@types/react-grid-layout": "^1.1.2",
|
||||
"@types/react-helmet-async": "1.0.3",
|
||||
"@types/react-lottie": "1.2.10",
|
||||
"@types/react-redux": "^7.1.11",
|
||||
"@types/react-resizable": "3.0.3",
|
||||
"@types/react-router-dom": "^5.1.6",
|
||||
"@types/react-syntax-highlighter": "15.5.13",
|
||||
"@types/redux-mock-store": "1.0.4",
|
||||
"@types/styled-components": "^5.1.4",
|
||||
"@types/uuid": "^8.3.1",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"@types/webpack-dev-server": "^4.7.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"autoprefixer": "10.4.19",
|
||||
"babel-plugin-styled-components": "^1.12.0",
|
||||
"compression-webpack-plugin": "9.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-jest": "^26.9.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"eslint-plugin-sonarjs": "^0.12.0",
|
||||
"husky": "^7.0.4",
|
||||
"image-minimizer-webpack-plugin": "^4.0.0",
|
||||
"imagemin": "^8.0.1",
|
||||
"imagemin-svgo": "^10.0.1",
|
||||
"is-ci": "^3.0.1",
|
||||
"jest-styled-components": "^7.0.8",
|
||||
"lint-staged": "^12.5.0",
|
||||
"msw": "1.3.2",
|
||||
"npm-run-all": "latest",
|
||||
"orval": "7.18.0",
|
||||
"portfinder-sync": "^0.0.2",
|
||||
"postcss": "8.4.38",
|
||||
"prettier": "2.2.1",
|
||||
"prop-types": "15.8.1",
|
||||
"raw-loader": "4.0.2",
|
||||
"react-hooks-testing-library": "0.6.0",
|
||||
"react-hot-loader": "^4.13.0",
|
||||
"react-resizable": "3.0.4",
|
||||
"redux-mock-store": "1.5.4",
|
||||
"sass": "1.66.1",
|
||||
"sass-loader": "13.3.2",
|
||||
"sharp": "^0.33.4",
|
||||
"ts-jest": "^27.1.5",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript-plugin-css-modules": "5.2.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(js|jsx|ts|tsx)": [
|
||||
"eslint --fix",
|
||||
"sh scripts/typecheck-staged.sh"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "18.0.26",
|
||||
"@types/react-dom": "18.0.10",
|
||||
"debug": "4.3.4",
|
||||
"semver": "7.5.4",
|
||||
"xml2js": "0.5.0",
|
||||
"phin": "^3.7.1",
|
||||
"body-parser": "1.20.3",
|
||||
"http-proxy-middleware": "3.0.5",
|
||||
"cross-spawn": "7.0.5",
|
||||
"cookie": "^0.7.1",
|
||||
"serialize-javascript": "6.0.2",
|
||||
"prismjs": "1.30.0",
|
||||
"got": "11.8.5",
|
||||
"form-data": "4.0.4",
|
||||
"brace-expansion": "^2.0.2",
|
||||
"on-headers": "^1.1.0",
|
||||
"tmp": "0.2.4"
|
||||
}
|
||||
}
|
||||
"name": "frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"i18n:generate-hash": "node ./i18-generate-hash.cjs",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prettify": "prettier --write .",
|
||||
"fmt": "prettier --check .",
|
||||
"lint": "eslint ./src",
|
||||
"lint:fix": "eslint ./src --fix",
|
||||
"jest": "jest",
|
||||
"jest:coverage": "jest --coverage",
|
||||
"jest:watch": "jest --watch",
|
||||
"postinstall": "yarn i18n:generate-hash && (is-ci || yarn husky:configure) && node scripts/update-registry.cjs",
|
||||
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
|
||||
"commitlint": "commitlint --edit $1",
|
||||
"test": "jest",
|
||||
"test:changedsince": "jest --changedSince=main --coverage --silent",
|
||||
"generate:api": "orval --config ./orval.config.ts && sh scripts/post-types-generation.sh",
|
||||
"generate:permissions-type": "node scripts/generate-permissions-type.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.0.0"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "6.0.0",
|
||||
"@ant-design/icons": "4.8.0",
|
||||
"@codemirror/autocomplete": "6.18.6",
|
||||
"@codemirror/lang-javascript": "6.2.3",
|
||||
"@dnd-kit/core": "6.1.0",
|
||||
"@dnd-kit/modifiers": "7.0.0",
|
||||
"@dnd-kit/sortable": "8.0.0",
|
||||
"@dnd-kit/utilities": "3.2.2",
|
||||
"@grafana/data": "^11.2.3",
|
||||
"@mdx-js/loader": "2.3.0",
|
||||
"@mdx-js/react": "2.3.0",
|
||||
"@monaco-editor/react": "^4.3.1",
|
||||
"@playwright/test": "1.55.1",
|
||||
"@radix-ui/react-tabs": "1.0.4",
|
||||
"@radix-ui/react-tooltip": "1.0.7",
|
||||
"@sentry/react": "8.41.0",
|
||||
"@sentry/vite-plugin": "2.22.6",
|
||||
"@signozhq/badge": "0.0.2",
|
||||
"@signozhq/button": "0.0.2",
|
||||
"@signozhq/calendar": "0.0.0",
|
||||
"@signozhq/callout": "0.0.2",
|
||||
"@signozhq/checkbox": "0.0.2",
|
||||
"@signozhq/combobox": "0.0.2",
|
||||
"@signozhq/command": "0.0.0",
|
||||
"@signozhq/design-tokens": "2.1.1",
|
||||
"@signozhq/dialog": "^0.0.2",
|
||||
"@signozhq/icons": "0.1.0",
|
||||
"@signozhq/input": "0.0.2",
|
||||
"@signozhq/popover": "0.0.0",
|
||||
"@signozhq/radio-group": "0.0.2",
|
||||
"@signozhq/resizable": "0.0.0",
|
||||
"@signozhq/sonner": "0.1.0",
|
||||
"@signozhq/switch": "0.0.2",
|
||||
"@signozhq/table": "0.3.7",
|
||||
"@signozhq/toggle-group": "^0.0.1",
|
||||
"@signozhq/tooltip": "0.0.2",
|
||||
"@tanstack/react-table": "8.20.6",
|
||||
"@tanstack/react-virtual": "3.11.2",
|
||||
"@uiw/codemirror-theme-copilot": "4.23.11",
|
||||
"@uiw/codemirror-theme-github": "4.24.1",
|
||||
"@uiw/react-codemirror": "4.23.10",
|
||||
"@uiw/react-md-editor": "3.23.5",
|
||||
"@visx/group": "3.3.0",
|
||||
"@visx/hierarchy": "3.12.0",
|
||||
"@visx/shape": "3.5.0",
|
||||
"@visx/tooltip": "3.3.0",
|
||||
"@vitejs/plugin-react": "5.1.4",
|
||||
"@xstate/react": "^3.0.0",
|
||||
"ansi-to-html": "0.7.2",
|
||||
"antd": "5.11.0",
|
||||
"antd-table-saveas-excel": "2.2.1",
|
||||
"antlr4": "4.13.2",
|
||||
"axios": "1.12.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^29.6.4",
|
||||
"babel-loader": "9.1.3",
|
||||
"babel-plugin-named-asset-import": "^0.3.7",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"babel-preset-react-app": "^10.0.1",
|
||||
"chart.js": "3.9.1",
|
||||
"chartjs-adapter-date-fns": "^2.0.0",
|
||||
"chartjs-plugin-annotation": "^1.4.0",
|
||||
"classnames": "2.3.2",
|
||||
"color": "^4.2.1",
|
||||
"color-alpha": "2.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"crypto-js": "4.2.0",
|
||||
"d3-hierarchy": "3.1.2",
|
||||
"dayjs": "^1.10.7",
|
||||
"dompurify": "3.2.4",
|
||||
"dotenv": "8.2.0",
|
||||
"event-source-polyfill": "1.0.31",
|
||||
"eventemitter3": "5.0.1",
|
||||
"fontfaceobserver": "2.3.0",
|
||||
"history": "4.10.1",
|
||||
"http-proxy-middleware": "3.0.5",
|
||||
"http-status-codes": "2.3.0",
|
||||
"i18next": "^21.6.12",
|
||||
"i18next-browser-languagedetector": "^6.1.3",
|
||||
"i18next-http-backend": "^1.3.2",
|
||||
"immer": "11.1.3",
|
||||
"jest": "30.2.0",
|
||||
"js-base64": "^3.7.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lucide-react": "0.498.0",
|
||||
"mini-css-extract-plugin": "2.4.5",
|
||||
"motion": "12.4.13",
|
||||
"nuqs": "2.8.8",
|
||||
"overlayscrollbars": "^2.8.1",
|
||||
"overlayscrollbars-react": "^0.5.6",
|
||||
"papaparse": "5.4.1",
|
||||
"posthog-js": "1.298.0",
|
||||
"rc-tween-one": "3.0.6",
|
||||
"react": "18.2.0",
|
||||
"react-addons-update": "15.6.3",
|
||||
"react-beautiful-dnd": "13.1.1",
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-drag-listview": "2.0.0",
|
||||
"react-error-boundary": "4.0.11",
|
||||
"react-force-graph-2d": "^1.29.1",
|
||||
"react-full-screen": "1.1.1",
|
||||
"react-grid-layout": "^1.3.4",
|
||||
"react-helmet-async": "1.3.0",
|
||||
"react-i18next": "^11.16.1",
|
||||
"react-lottie": "1.2.10",
|
||||
"react-markdown": "8.0.7",
|
||||
"react-query": "3.39.3",
|
||||
"react-redux": "^7.2.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-router-dom-v5-compat": "6.27.0",
|
||||
"react-syntax-highlighter": "15.5.0",
|
||||
"react-use": "^17.3.2",
|
||||
"react-virtuoso": "4.0.3",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"rehype-raw": "7.0.0",
|
||||
"rollup-plugin-visualizer": "7.0.0",
|
||||
"rrule": "2.8.1",
|
||||
"stream": "^0.0.2",
|
||||
"styled-components": "^5.3.11",
|
||||
"timestamp-nano": "^1.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "5.9.3",
|
||||
"uplot": "1.6.31",
|
||||
"uuid": "^8.3.2",
|
||||
"vite": "npm:rolldown-vite@7.3.1",
|
||||
"vite-plugin-html": "3.2.2",
|
||||
"web-vitals": "^0.2.4",
|
||||
"xstate": "^4.31.0",
|
||||
"zustand": "5.0.11"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.11",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-syntax-jsx": "^7.12.13",
|
||||
"@babel/preset-env": "^7.22.14",
|
||||
"@babel/preset-react": "^7.12.13",
|
||||
"@babel/preset-typescript": "^7.21.4",
|
||||
"@commitlint/cli": "^20.4.2",
|
||||
"@commitlint/config-conventional": "^20.4.2",
|
||||
"@faker-js/faker": "9.3.0",
|
||||
"@jest/globals": "30.2.0",
|
||||
"@testing-library/jest-dom": "5.16.5",
|
||||
"@testing-library/react": "13.4.0",
|
||||
"@testing-library/user-event": "14.4.3",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/crypto-js": "4.2.2",
|
||||
"@types/dompurify": "^2.4.0",
|
||||
"@types/event-source-polyfill": "^1.0.0",
|
||||
"@types/fontfaceobserver": "2.1.0",
|
||||
"@types/jest": "30.0.0",
|
||||
"@types/lodash-es": "^4.17.4",
|
||||
"@types/mini-css-extract-plugin": "^2.5.1",
|
||||
"@types/node": "^16.10.3",
|
||||
"@types/papaparse": "5.3.7",
|
||||
"@types/react": "18.0.26",
|
||||
"@types/react-addons-update": "0.14.21",
|
||||
"@types/react-beautiful-dnd": "13.1.8",
|
||||
"@types/react-dom": "18.0.10",
|
||||
"@types/react-grid-layout": "^1.1.2",
|
||||
"@types/react-helmet-async": "1.0.3",
|
||||
"@types/react-lottie": "1.2.10",
|
||||
"@types/react-redux": "^7.1.11",
|
||||
"@types/react-resizable": "3.0.3",
|
||||
"@types/react-router-dom": "^5.1.6",
|
||||
"@types/react-syntax-highlighter": "15.5.13",
|
||||
"@types/redux-mock-store": "1.0.4",
|
||||
"@types/styled-components": "^5.1.4",
|
||||
"@types/uuid": "^8.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"autoprefixer": "10.4.19",
|
||||
"babel-plugin-styled-components": "^1.12.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-jest": "^29.15.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"eslint-plugin-sonarjs": "^0.12.0",
|
||||
"husky": "^7.0.4",
|
||||
"imagemin": "^8.0.1",
|
||||
"imagemin-svgo": "^10.0.1",
|
||||
"is-ci": "^3.0.1",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"jest-environment-node": "29.7.0",
|
||||
"jest-styled-components": "^7.2.0",
|
||||
"lint-staged": "^12.5.0",
|
||||
"msw": "1.3.2",
|
||||
"npm-run-all": "latest",
|
||||
"orval": "7.18.0",
|
||||
"portfinder-sync": "^0.0.2",
|
||||
"postcss": "8.5.6",
|
||||
"prettier": "2.2.1",
|
||||
"prop-types": "15.8.1",
|
||||
"react-hooks-testing-library": "0.6.0",
|
||||
"react-resizable": "3.0.4",
|
||||
"redux-mock-store": "1.5.4",
|
||||
"sass": "1.97.3",
|
||||
"sharp": "0.34.5",
|
||||
"svgo": "4.0.0",
|
||||
"ts-api-utils": "2.4.0",
|
||||
"ts-jest": "29.4.6",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript-plugin-css-modules": "5.2.0",
|
||||
"vite-plugin-checker": "0.12.0",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-image-optimizer": "2.0.3",
|
||||
"vite-tsconfig-paths": "6.1.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.(js|jsx|ts|tsx)": [
|
||||
"eslint --fix",
|
||||
"sh scripts/typecheck-staged.sh"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "18.0.26",
|
||||
"@types/react-dom": "18.0.10",
|
||||
"debug": "4.3.4",
|
||||
"semver": "7.5.4",
|
||||
"xml2js": "0.5.0",
|
||||
"phin": "^3.7.1",
|
||||
"body-parser": "1.20.3",
|
||||
"http-proxy-middleware": "3.0.5",
|
||||
"cross-spawn": "7.0.5",
|
||||
"cookie": "^0.7.1",
|
||||
"serialize-javascript": "6.0.2",
|
||||
"prismjs": "1.30.0",
|
||||
"got": "11.8.5",
|
||||
"form-data": "4.0.4",
|
||||
"brace-expansion": "^2.0.2",
|
||||
"on-headers": "^1.1.0",
|
||||
"tmp": "0.2.4",
|
||||
"vite": "npm:rolldown-vite@7.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
"pipelines": "Pipelines",
|
||||
"archives": "Archives",
|
||||
"logs_to_metrics": "Logs To Metrics",
|
||||
"roles": "Roles"
|
||||
"roles": "Roles",
|
||||
"role_details": "Role Details"
|
||||
}
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
"pipelines": "Pipelines",
|
||||
"archives": "Archives",
|
||||
"logs_to_metrics": "Logs To Metrics",
|
||||
"roles": "Roles"
|
||||
"roles": "Roles",
|
||||
"role_details": "Role Details"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ const signozPackages = Object.keys(allDeps).filter((dep) =>
|
||||
const fileContent = `// -------------------------------------------------------------------------
|
||||
// AUTO-GENERATED FILE
|
||||
// -------------------------------------------------------------------------
|
||||
// This file is generated by scripts/update-registry.js automatically
|
||||
// This file is generated by scripts/update-registry.cjs automatically
|
||||
// whenever you run 'yarn install' or 'npm install'.
|
||||
//
|
||||
// It forces VS Code to index these specific packages to fix auto-import
|
||||
@@ -218,9 +218,9 @@ function App(): JSX.Element {
|
||||
pathname === ROUTES.ONBOARDING ||
|
||||
pathname.startsWith('/public/dashboard/')
|
||||
) {
|
||||
window.Pylon('hideChatBubble');
|
||||
window.Pylon?.('hideChatBubble');
|
||||
} else {
|
||||
window.Pylon('showChatBubble');
|
||||
window.Pylon?.('showChatBubble');
|
||||
}
|
||||
}, [pathname]);
|
||||
|
||||
|
||||
@@ -165,11 +165,6 @@ export const MySettings = Loadable(
|
||||
() => import(/* webpackChunkName: "All MySettings" */ 'pages/Settings'),
|
||||
);
|
||||
|
||||
export const CustomDomainSettings = Loadable(
|
||||
() =>
|
||||
import(/* webpackChunkName: "Custom Domain Settings" */ 'pages/Settings'),
|
||||
);
|
||||
|
||||
export const Logs = Loadable(
|
||||
() => import(/* webpackChunkName: "Logs" */ 'pages/LogsModulePage'),
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { RenderErrorResponseDTO } from 'api/generated/services/sigNoz.schemas';
|
||||
import { AxiosError } from 'axios';
|
||||
import APIError from 'types/api/error';
|
||||
|
||||
// Handles errors from generated API hooks (which use RenderErrorResponseDTO)
|
||||
// @deprecated Use convertToApiError instead
|
||||
export function ErrorResponseHandlerForGeneratedAPIs(
|
||||
error: AxiosError<RenderErrorResponseDTO>,
|
||||
): never {
|
||||
@@ -46,3 +46,34 @@ export function ErrorResponseHandlerForGeneratedAPIs(
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// convertToApiError converts an AxiosError from generated API
|
||||
// hooks into an APIError.
|
||||
export function convertToApiError(
|
||||
error: AxiosError<RenderErrorResponseDTO> | null,
|
||||
): APIError | undefined {
|
||||
if (!error) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const response = error.response;
|
||||
const errorData = response?.data?.error;
|
||||
|
||||
return new APIError({
|
||||
httpStatusCode: response?.status || error.status || 500,
|
||||
error: {
|
||||
code:
|
||||
errorData?.code ||
|
||||
String(response?.status || error.code || 'unknown_error'),
|
||||
message:
|
||||
errorData?.message ||
|
||||
response?.statusText ||
|
||||
error.message ||
|
||||
'Something went wrong',
|
||||
url: errorData?.url ?? '',
|
||||
errors: (errorData?.errors ?? []).map((e) => ({
|
||||
message: e.message ?? '',
|
||||
})),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -29,10 +29,6 @@ import type {
|
||||
UpdateAuthDomainPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint lists all auth domains
|
||||
* @summary List all auth domains
|
||||
|
||||
@@ -26,10 +26,6 @@ import type {
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* Checks if the authenticated user has permissions for given transactions
|
||||
* @summary Check permissions
|
||||
|
||||
@@ -35,10 +35,6 @@ import type {
|
||||
UpdatePublicDashboardPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint deletes the public sharing config and disables the public sharing of a dashboard
|
||||
* @summary Delete public dashboard
|
||||
|
||||
@@ -18,10 +18,6 @@ import type { ErrorType } from '../../../generatedAPIInstance';
|
||||
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
|
||||
import type { GetFeatures200, RenderErrorResponseDTO } from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns the supported features and their details
|
||||
* @summary Get features
|
||||
|
||||
@@ -24,10 +24,6 @@ import type {
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns field keys
|
||||
* @summary Get field keys
|
||||
|
||||
@@ -37,10 +37,6 @@ import type {
|
||||
UpdateIngestionKeyPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns the ingestion keys for a workspace
|
||||
* @summary Get ingestion keys for workspace
|
||||
|
||||
@@ -21,10 +21,6 @@ import type {
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns global config
|
||||
* @summary Get global config
|
||||
|
||||
@@ -25,10 +25,6 @@ import type {
|
||||
RenderErrorResponseDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoints promotes and indexes paths
|
||||
* @summary Promote and index paths
|
||||
|
||||
@@ -42,10 +42,6 @@ import type {
|
||||
UpdateMetricMetadataPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns a list of distinct metric names within the specified time range
|
||||
* @summary List metric names
|
||||
|
||||
@@ -25,10 +25,6 @@ import type {
|
||||
TypesOrganizationDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint returns the organization I belong to
|
||||
* @summary Get my organization
|
||||
|
||||
@@ -32,10 +32,6 @@ import type {
|
||||
UpdateUserPreferencePathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint lists all org preferences
|
||||
* @summary List org preferences
|
||||
|
||||
@@ -20,10 +20,6 @@ import type {
|
||||
ReplaceVariables200,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* Execute a composite query over a time range. Supports builder queries (traces, logs, metrics), formulas, trace operators, PromQL, and ClickHouse SQL.
|
||||
* @summary Query range
|
||||
|
||||
@@ -35,10 +35,6 @@ import type {
|
||||
RoletypesPostableRoleDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint lists all roles
|
||||
* @summary List roles
|
||||
|
||||
@@ -41,10 +41,6 @@ import type {
|
||||
UpdateServiceAccountStatusPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint lists the service accounts for an organisation
|
||||
* @summary List service accounts
|
||||
|
||||
@@ -33,10 +33,6 @@ import type {
|
||||
RotateSession200,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint creates a session for a user using google callback
|
||||
* @summary Create session by google callback
|
||||
|
||||
@@ -51,10 +51,6 @@ import type {
|
||||
UpdateUserPathParameters,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint changes the password by id
|
||||
* @summary Change password
|
||||
|
||||
@@ -26,10 +26,6 @@ import type {
|
||||
ZeustypesPostableProfileDTO,
|
||||
} from '../sigNoz.schemas';
|
||||
|
||||
type AwaitedInput<T> = PromiseLike<T> | T;
|
||||
|
||||
type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
|
||||
|
||||
/**
|
||||
* This endpoint gets the host info from zeus.
|
||||
* @summary Get host info from Zeus.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { TreemapViewType } from 'container/MetricsExplorer/Summary/types';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||
|
||||
export interface MetricsTreeMapPayload {
|
||||
filters: TagFilter;
|
||||
limit?: number;
|
||||
treemap?: TreemapViewType;
|
||||
}
|
||||
|
||||
export interface MetricsTreeMapResponse {
|
||||
status: string;
|
||||
data: {
|
||||
[TreemapViewType.TIMESERIES]: TimeseriesData[];
|
||||
[TreemapViewType.SAMPLES]: SamplesData[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface TimeseriesData {
|
||||
percentage: number;
|
||||
total_value: number;
|
||||
metric_name: string;
|
||||
}
|
||||
|
||||
export interface SamplesData {
|
||||
percentage: number;
|
||||
metric_name: string;
|
||||
}
|
||||
|
||||
export const getMetricsTreeMap = async (
|
||||
props: MetricsTreeMapPayload,
|
||||
signal?: AbortSignal,
|
||||
headers?: Record<string, string>,
|
||||
): Promise<SuccessResponse<MetricsTreeMapResponse> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await axios.post('/metrics/treemap', props, {
|
||||
signal,
|
||||
headers,
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data,
|
||||
params: props,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
}
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
import axios from 'api';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
|
||||
import { Temporality } from './getMetricDetails';
|
||||
import { MetricType } from './getMetricsList';
|
||||
|
||||
export interface UpdateMetricMetadataProps {
|
||||
description: string;
|
||||
metricType: MetricType;
|
||||
temporality?: Temporality;
|
||||
isMonotonic?: boolean;
|
||||
unit?: string;
|
||||
}
|
||||
|
||||
export interface UpdateMetricMetadataResponse {
|
||||
success: boolean;
|
||||
message: string;
|
||||
}
|
||||
|
||||
const updateMetricMetadata = async (
|
||||
metricName: string,
|
||||
props: UpdateMetricMetadataProps,
|
||||
): Promise<SuccessResponse<UpdateMetricMetadataResponse> | ErrorResponse> => {
|
||||
const response = await axios.post(`/metrics/${metricName}/metadata`, {
|
||||
...props,
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
};
|
||||
};
|
||||
|
||||
export default updateMetricMetadata;
|
||||
4
frontend/src/auto-import-registry.d.ts
vendored
4
frontend/src/auto-import-registry.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
// -------------------------------------------------------------------------
|
||||
// AUTO-GENERATED FILE
|
||||
// -------------------------------------------------------------------------
|
||||
// This file is generated by scripts/update-registry.js automatically
|
||||
// This file is generated by scripts/update-registry.cjs automatically
|
||||
// whenever you run 'yarn install' or 'npm install'.
|
||||
//
|
||||
// It forces VS Code to index these specific packages to fix auto-import
|
||||
@@ -18,6 +18,7 @@ import '@signozhq/checkbox';
|
||||
import '@signozhq/combobox';
|
||||
import '@signozhq/command';
|
||||
import '@signozhq/design-tokens';
|
||||
import '@signozhq/dialog';
|
||||
import '@signozhq/icons';
|
||||
import '@signozhq/input';
|
||||
import '@signozhq/popover';
|
||||
@@ -26,4 +27,5 @@ import '@signozhq/resizable';
|
||||
import '@signozhq/sonner';
|
||||
import '@signozhq/switch';
|
||||
import '@signozhq/table';
|
||||
import '@signozhq/toggle-group';
|
||||
import '@signozhq/tooltip';
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { FilterDropdownProps } from 'antd/lib/table/interface';
|
||||
import type { FilterDropdownProps } from 'antd/lib/table/interface';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import {
|
||||
getQueueOverview,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useQuery } from 'react-query';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { useSelector } from 'react-redux';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import { getAttributesValues } from 'api/queryBuilder/getAttributesValues';
|
||||
import { DATA_TYPE_VS_ATTRIBUTE_VALUES_KEY } from 'constants/queryBuilder';
|
||||
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import useDebouncedFn from 'hooks/useDebouncedFunction';
|
||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { DataSource } from 'types/common/queryBuilder';
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
import { useState } from 'react';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import dayjs from 'dayjs';
|
||||
import * as timeUtils from 'utils/timeUtils';
|
||||
|
||||
import CustomTimePicker from './CustomTimePicker';
|
||||
|
||||
jest.mock('react-router-dom', () => {
|
||||
const actual = jest.requireActual('react-router-dom');
|
||||
|
||||
return {
|
||||
...actual,
|
||||
useLocation: jest.fn().mockReturnValue({
|
||||
pathname: '/test-path',
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('providers/Timezone', () => {
|
||||
const actual = jest.requireActual('providers/Timezone');
|
||||
|
||||
return {
|
||||
...actual,
|
||||
useTimezone: jest.fn().mockReturnValue({
|
||||
timezone: {
|
||||
value: 'UTC',
|
||||
offset: '+00:00',
|
||||
name: 'UTC',
|
||||
},
|
||||
browserTimezone: {
|
||||
value: 'UTC',
|
||||
offset: '+00:00',
|
||||
name: 'UTC',
|
||||
},
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
interface WrapperProps {
|
||||
initialValue?: string;
|
||||
showLiveLogs?: boolean;
|
||||
onValidCustomDateChange?: () => void;
|
||||
onError?: () => void;
|
||||
onSelect?: (value: string) => void;
|
||||
onCustomDateHandler?: () => void;
|
||||
onCustomTimeStatusUpdate?: () => void;
|
||||
}
|
||||
|
||||
function Wrapper({
|
||||
initialValue = '2024-01-01 00:00:00 - 2024-01-01 01:00:00',
|
||||
showLiveLogs = false,
|
||||
onValidCustomDateChange = (): void => {},
|
||||
onError = (): void => {},
|
||||
onSelect = (): void => {},
|
||||
onCustomDateHandler = (): void => {},
|
||||
onCustomTimeStatusUpdate = (): void => {},
|
||||
}: WrapperProps): JSX.Element {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedTime, setSelectedTime] = useState('custom');
|
||||
const [selectedValue, setSelectedValue] = useState(initialValue);
|
||||
|
||||
const handleSelect = (value: string): void => {
|
||||
setSelectedTime(value);
|
||||
onSelect(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<CustomTimePicker
|
||||
open={open}
|
||||
setOpen={setOpen}
|
||||
onSelect={handleSelect}
|
||||
onError={onError}
|
||||
selectedTime={selectedTime}
|
||||
selectedValue={selectedValue}
|
||||
onValidCustomDateChange={({ timeStr }): void => {
|
||||
setSelectedValue(timeStr);
|
||||
onValidCustomDateChange();
|
||||
}}
|
||||
onCustomDateHandler={(): void => {
|
||||
onCustomDateHandler();
|
||||
}}
|
||||
onCustomTimeStatusUpdate={(): void => {
|
||||
onCustomTimeStatusUpdate();
|
||||
}}
|
||||
items={[
|
||||
{ label: 'Last 5 minutes', value: '5m' },
|
||||
{ label: 'Custom', value: 'custom' },
|
||||
]}
|
||||
minTime={dayjs('2024-01-01 00:00:00').valueOf() * 1000_000}
|
||||
maxTime={dayjs('2024-01-01 01:00:00').valueOf() * 1000_000}
|
||||
showLiveLogs={showLiveLogs}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
describe('CustomTimePicker', () => {
|
||||
it('does not close or reset when clicking input while open', () => {
|
||||
render(<Wrapper />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Open popover
|
||||
fireEvent.focus(input);
|
||||
|
||||
// Type some text
|
||||
fireEvent.change(input, { target: { value: '5m' } });
|
||||
|
||||
// Click the input again while open
|
||||
fireEvent.mouseDown(input);
|
||||
fireEvent.click(input);
|
||||
|
||||
// Value should remain as typed
|
||||
expect((input as HTMLInputElement).value).toBe('5m');
|
||||
});
|
||||
|
||||
it('applies valid shorthand on Enter', () => {
|
||||
const onValid = jest.fn();
|
||||
const onError = jest.fn();
|
||||
|
||||
render(<Wrapper onValidCustomDateChange={onValid} onError={onError} />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: '5m' } });
|
||||
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
||||
|
||||
expect(onValid).toHaveBeenCalledTimes(1);
|
||||
// onError(false) may be called by internal reset logic; we only assert that
|
||||
// it was never called with a truthy error state
|
||||
expect(onError).not.toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('sets error and updates custom time status for invalid shorthand exceeding max allowed window', () => {
|
||||
const onValid = jest.fn();
|
||||
const onError = jest.fn();
|
||||
const onCustomTimeStatusUpdate = jest.fn();
|
||||
|
||||
render(
|
||||
<Wrapper
|
||||
onValidCustomDateChange={onValid}
|
||||
onError={onError}
|
||||
onCustomTimeStatusUpdate={onCustomTimeStatusUpdate}
|
||||
/>,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
fireEvent.focus(input);
|
||||
// large number of days to ensure it exceeds the 15 months allowed window
|
||||
fireEvent.change(input, { target: { value: '9999d' } });
|
||||
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
||||
|
||||
expect(onError).toHaveBeenCalledWith(true);
|
||||
expect(onCustomTimeStatusUpdate).toHaveBeenCalledWith();
|
||||
expect(onValid).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('treats close after change like pressing Enter (blur + chevron)', () => {
|
||||
const onValid = jest.fn();
|
||||
const onError = jest.fn();
|
||||
|
||||
render(<Wrapper onValidCustomDateChange={onValid} onError={onError} />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
// Open and change value so "changed since open" is true
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, { target: { value: '5m' } });
|
||||
fireEvent.blur(input);
|
||||
|
||||
// Click the chevron (which triggers handleClose)
|
||||
const chevron = document.querySelector(
|
||||
'.time-input-suffix-icon-badge',
|
||||
) as HTMLElement;
|
||||
|
||||
fireEvent.click(chevron);
|
||||
|
||||
// Should have applied the value (same as Enter)
|
||||
expect(onValid).toHaveBeenCalledTimes(1);
|
||||
expect(onError).not.toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('applies epoch start/end range on Enter via onCustomDateHandler', () => {
|
||||
const onCustomDateHandler = jest.fn();
|
||||
const onError = jest.fn();
|
||||
|
||||
render(
|
||||
<Wrapper onCustomDateHandler={onCustomDateHandler} onError={onError} />,
|
||||
);
|
||||
|
||||
const now = dayjs().valueOf();
|
||||
const later = dayjs().add(1, 'hour').valueOf();
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, {
|
||||
target: { value: `${now} - ${later}` },
|
||||
});
|
||||
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
||||
|
||||
expect(onCustomDateHandler).toHaveBeenCalledTimes(1);
|
||||
expect(onError).not.toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('uses validateTimeRange result for generic formatted ranges (valid case)', () => {
|
||||
const validateTimeRangeSpy = jest.spyOn(timeUtils, 'validateTimeRange');
|
||||
const onCustomDateHandler = jest.fn();
|
||||
const onError = jest.fn();
|
||||
|
||||
validateTimeRangeSpy.mockReturnValue({
|
||||
isValid: true,
|
||||
errorDetails: undefined,
|
||||
startTimeMs: dayjs('2024-01-01 00:00:00').valueOf(),
|
||||
endTimeMs: dayjs('2024-01-01 01:00:00').valueOf(),
|
||||
});
|
||||
|
||||
render(
|
||||
<Wrapper onCustomDateHandler={onCustomDateHandler} onError={onError} />,
|
||||
);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, {
|
||||
target: { value: 'foo - bar' },
|
||||
});
|
||||
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
||||
|
||||
expect(validateTimeRangeSpy).toHaveBeenCalled();
|
||||
expect(onCustomDateHandler).toHaveBeenCalledTimes(1);
|
||||
expect(onError).not.toHaveBeenCalledWith(true);
|
||||
|
||||
validateTimeRangeSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('uses validateTimeRange result for generic formatted ranges (invalid case)', () => {
|
||||
const validateTimeRangeSpy = jest.spyOn(timeUtils, 'validateTimeRange');
|
||||
const onValid = jest.fn();
|
||||
const onError = jest.fn();
|
||||
|
||||
validateTimeRangeSpy.mockReturnValue({
|
||||
isValid: false,
|
||||
errorDetails: {
|
||||
message: 'Invalid range',
|
||||
code: 'INVALID_RANGE',
|
||||
description: 'Start must be before end',
|
||||
},
|
||||
startTimeMs: 0,
|
||||
endTimeMs: 0,
|
||||
});
|
||||
|
||||
render(<Wrapper onValidCustomDateChange={onValid} onError={onError} />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
fireEvent.focus(input);
|
||||
fireEvent.change(input, {
|
||||
target: { value: 'foo - bar' },
|
||||
});
|
||||
fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' });
|
||||
|
||||
expect(validateTimeRangeSpy).toHaveBeenCalled();
|
||||
expect(onError).toHaveBeenCalledWith(true);
|
||||
expect(onValid).not.toHaveBeenCalled();
|
||||
|
||||
validateTimeRangeSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('opens live mode with correct label', () => {
|
||||
render(<Wrapper showLiveLogs />);
|
||||
|
||||
const input = screen.getByRole('textbox');
|
||||
|
||||
fireEvent.focus(input);
|
||||
|
||||
expect((input as HTMLInputElement).value).toBe('Live');
|
||||
});
|
||||
});
|
||||
@@ -104,6 +104,10 @@ function CustomTimePicker({
|
||||
const location = useLocation();
|
||||
|
||||
const inputRef = useRef<InputRef>(null);
|
||||
const initialInputValueOnOpenRef = useRef<string>('');
|
||||
const hasChangedSinceOpenRef = useRef<boolean>(false);
|
||||
// Tracks if the last pointer down was on the input so we don't close the popover when user clicks the input again
|
||||
const isClickFromInputRef = useRef(false);
|
||||
|
||||
const [activeView, setActiveView] = useState<ViewType>(DEFAULT_VIEW);
|
||||
|
||||
@@ -238,6 +242,21 @@ function CustomTimePicker({
|
||||
};
|
||||
|
||||
const handleOpenChange = (newOpen: boolean): void => {
|
||||
// Don't close when the user clicked the input (trigger); Ant Design treats trigger as "outside" overlay
|
||||
if (!newOpen && isClickFromInputRef.current) {
|
||||
isClickFromInputRef.current = false;
|
||||
return;
|
||||
}
|
||||
isClickFromInputRef.current = false;
|
||||
|
||||
// If the popover is trying to close and the value changed since opening,
|
||||
// treat it as if the user pressed Enter (attempt to apply the value)
|
||||
if (!newOpen && hasChangedSinceOpenRef.current) {
|
||||
hasChangedSinceOpenRef.current = false;
|
||||
handleInputPressEnter();
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(newOpen);
|
||||
|
||||
if (!newOpen) {
|
||||
@@ -406,10 +425,18 @@ function CustomTimePicker({
|
||||
const handleOpen = (e?: React.SyntheticEvent): void => {
|
||||
e?.stopPropagation?.();
|
||||
|
||||
// If the popover is already open, avoid resetting the input value
|
||||
// so that any in-progress edits are preserved.
|
||||
if (open) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (showLiveLogs) {
|
||||
setOpen(true);
|
||||
setSelectedTimePlaceholderValue('Live');
|
||||
setInputValue('Live');
|
||||
initialInputValueOnOpenRef.current = 'Live';
|
||||
hasChangedSinceOpenRef.current = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -424,11 +451,21 @@ function CustomTimePicker({
|
||||
.tz(timezone.value)
|
||||
.format(DATE_TIME_FORMATS.UK_DATETIME_SECONDS);
|
||||
|
||||
setInputValue(`${startTime} - ${endTime}`);
|
||||
const nextValue = `${startTime} - ${endTime}`;
|
||||
setInputValue(nextValue);
|
||||
initialInputValueOnOpenRef.current = nextValue;
|
||||
hasChangedSinceOpenRef.current = false;
|
||||
};
|
||||
|
||||
const handleClose = (e: React.MouseEvent): void => {
|
||||
e.stopPropagation();
|
||||
// If the value changed since opening, treat this like pressing Enter
|
||||
if (hasChangedSinceOpenRef.current) {
|
||||
hasChangedSinceOpenRef.current = false;
|
||||
handleInputPressEnter();
|
||||
return;
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
setCustomDTPickerVisible?.(false);
|
||||
|
||||
@@ -450,6 +487,9 @@ function CustomTimePicker({
|
||||
}, [location.pathname]);
|
||||
|
||||
const handleInputBlur = (): void => {
|
||||
// Track whether the value was changed since the input was opened for editing
|
||||
hasChangedSinceOpenRef.current =
|
||||
inputValue !== initialInputValueOnOpenRef.current;
|
||||
resetErrorStatus();
|
||||
};
|
||||
|
||||
@@ -552,6 +592,12 @@ function CustomTimePicker({
|
||||
readOnly={!open || showLiveLogs}
|
||||
placeholder={selectedTimePlaceholderValue}
|
||||
value={inputValue}
|
||||
onMouseDown={(e): void => {
|
||||
// Only treat as "click from input" when the actual input element is clicked (not suffix/chevron)
|
||||
if (e.target === inputRef.current?.input) {
|
||||
isClickFromInputRef.current = true;
|
||||
}
|
||||
}}
|
||||
onFocus={handleOpen}
|
||||
onClick={handleOpen}
|
||||
onChange={handleInputChange}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`DraggableTableRow Snapshot test should render DraggableTableRow 1`] = `
|
||||
<DocumentFragment>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`Editor renders correctly with custom props 1`] = `
|
||||
<div>
|
||||
|
||||
@@ -13,7 +13,8 @@ jest.mock('react-router-dom', () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('antd/es/form/Form', () => ({
|
||||
jest.mock('antd', () => ({
|
||||
...jest.requireActual('antd'),
|
||||
useForm: jest.fn().mockReturnValue({
|
||||
onFinish: jest.fn(),
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { UseMutateAsyncFunction } from 'react-query';
|
||||
import { FormInstance } from 'antd';
|
||||
import { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import type { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { OptionsQuery } from 'container/OptionsMenu/types';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import type { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import axios from 'axios';
|
||||
import { SOMETHING_WENT_WRONG } from 'constants/api';
|
||||
import { QueryParams } from 'constants/query';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Tag, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import { TableColumnsType as ColumnsType, Tag, Typography } from 'antd';
|
||||
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
||||
import { getMs } from 'container/Trace/Filters/Panel/PanelBody/Duration/util';
|
||||
import {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
Tag,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib';
|
||||
import type { RadioChangeEvent } from 'antd/lib';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { InfraMonitoringEvents } from 'constants/events';
|
||||
import { QueryParams } from 'constants/query';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useSelector } from 'react-redux';
|
||||
import { useCopyToClipboard, useLocation } from 'react-use';
|
||||
import { Color, Spacing } from '@signozhq/design-tokens';
|
||||
import { Button, Divider, Drawer, Radio, Tooltip, Typography } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib';
|
||||
import type { RadioChangeEvent } from 'antd/lib';
|
||||
import cx from 'classnames';
|
||||
import { LogType } from 'components/Logs/LogStateIndicator/LogStateIndicator';
|
||||
import QuerySearch from 'components/QueryBuilderV2/QueryV2/QuerySearch/QuerySearch';
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { ColumnsType, ColumnType } from 'antd/es/table';
|
||||
import {
|
||||
TableColumnsType as ColumnsType,
|
||||
TableColumnType as ColumnType,
|
||||
} from 'antd';
|
||||
import { FontSize } from 'container/OptionsMenu/types';
|
||||
import { IField } from 'types/api/logs/fields';
|
||||
import { ILog } from 'types/api/logs/log';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useMemo } from 'react';
|
||||
import { Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import { TableColumnsType as ColumnsType, Typography } from 'antd';
|
||||
import cx from 'classnames';
|
||||
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
|
||||
import { getSanitizedLogBody } from 'container/LogDetailedView/utils';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Button, Input, InputNumber, Popover, Tooltip, Typography } from 'antd';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import cx from 'classnames';
|
||||
import { LogViewMode } from 'container/LogsTable';
|
||||
import { FontSize, OptionsMenuConfig } from 'container/OptionsMenu/types';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`MessageTip custom action 1`] = `
|
||||
.c0 {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Tooltip } from 'antd';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import { Info } from 'lucide-react';
|
||||
|
||||
import './MQCommon.styles.scss';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`Not Found page test should render Not Found page without errors 1`] = `
|
||||
<DocumentFragment>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import type {
|
||||
TableColumnGroupType as ColumnGroupType,
|
||||
TableColumnsType as ColumnsType,
|
||||
TableColumnType as ColumnType,
|
||||
} from 'antd';
|
||||
import { Button, Dropdown, Flex, MenuProps, Switch } from 'antd';
|
||||
import { ColumnGroupType, ColumnType } from 'antd/es/table';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
|
||||
@@ -9,13 +9,11 @@ import {
|
||||
import ReactDragListView from 'react-drag-listview';
|
||||
import { ResizeCallbackData } from 'react-resizable';
|
||||
import { Table } from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import type { ColumnsType } from 'antd/lib/table';
|
||||
import cx from 'classnames';
|
||||
import { dragColumnParams } from 'hooks/useDragColumns/configs';
|
||||
import { getColumnWidth, RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { debounce, set } from 'lodash-es';
|
||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
|
||||
import ResizableHeader from './ResizableHeader';
|
||||
import { DragSpanStyle } from './styles';
|
||||
@@ -26,28 +24,18 @@ function ResizeTable({
|
||||
columns,
|
||||
onDragColumn,
|
||||
pagination,
|
||||
widgetId,
|
||||
shouldPersistColumnWidths = false,
|
||||
columnWidths,
|
||||
onColumnWidthsChange,
|
||||
...restProps
|
||||
}: ResizeTableProps): JSX.Element {
|
||||
const [columnsData, setColumns] = useState<ColumnsType>([]);
|
||||
const { setColumnWidths, selectedDashboard } = useDashboard();
|
||||
|
||||
const columnWidths = shouldPersistColumnWidths
|
||||
? (selectedDashboard?.data?.widgets?.find(
|
||||
(widget) => widget.id === widgetId,
|
||||
) as Widgets)?.columnWidths
|
||||
: undefined;
|
||||
|
||||
const updateAllColumnWidths = useRef(
|
||||
debounce((widthsConfig: Record<string, number>) => {
|
||||
if (!widgetId || !shouldPersistColumnWidths) {
|
||||
if (!onColumnWidthsChange) {
|
||||
return;
|
||||
}
|
||||
setColumnWidths?.((prev) => ({
|
||||
...prev,
|
||||
[widgetId]: widthsConfig,
|
||||
}));
|
||||
onColumnWidthsChange(widthsConfig);
|
||||
}, 1000),
|
||||
).current;
|
||||
|
||||
@@ -75,7 +63,7 @@ function ResizeTable({
|
||||
...col,
|
||||
...(onDragColumn && {
|
||||
title: (
|
||||
<DragSpanStyle className="dragHandler">
|
||||
<DragSpanStyle className="dragHandler" data-testid="drag-column-title">
|
||||
{col?.title?.toString() || ''}
|
||||
</DragSpanStyle>
|
||||
),
|
||||
@@ -106,31 +94,31 @@ function ResizeTable({
|
||||
}, [mergedColumns, pagination, restProps]);
|
||||
|
||||
useEffect(() => {
|
||||
if (columns) {
|
||||
// Apply stored column widths from widget configuration
|
||||
const columnsWithStoredWidths = columns.map((col) => {
|
||||
const dataIndex = (col as RowData).dataIndex as string;
|
||||
if (dataIndex && columnWidths) {
|
||||
const width = getColumnWidth(dataIndex, columnWidths);
|
||||
if (width) {
|
||||
return {
|
||||
...col,
|
||||
width, // Apply stored width
|
||||
};
|
||||
}
|
||||
}
|
||||
return col;
|
||||
});
|
||||
|
||||
setColumns(columnsWithStoredWidths);
|
||||
}
|
||||
}, [columns, columnWidths]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!shouldPersistColumnWidths) {
|
||||
if (!columns) {
|
||||
return;
|
||||
}
|
||||
// Collect all column widths in a single object
|
||||
|
||||
const columnsWithStoredWidths = columns.map((col) => {
|
||||
const dataIndex = (col as RowData).dataIndex as string;
|
||||
if (dataIndex && columnWidths) {
|
||||
const width = getColumnWidth(dataIndex, columnWidths);
|
||||
if (width) {
|
||||
return { ...col, width };
|
||||
}
|
||||
}
|
||||
return col;
|
||||
});
|
||||
|
||||
setColumns(columnsWithStoredWidths);
|
||||
}, [columns, columnWidths]);
|
||||
|
||||
const lastReportedWidthsRef = useRef<Record<string, number>>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!onColumnWidthsChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newColumnWidths: Record<string, number> = {};
|
||||
|
||||
mergedColumns.forEach((col) => {
|
||||
@@ -140,11 +128,20 @@ function ResizeTable({
|
||||
}
|
||||
});
|
||||
|
||||
// Only update if there are actual widths to set
|
||||
if (Object.keys(newColumnWidths).length > 0) {
|
||||
if (Object.keys(newColumnWidths).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const last = lastReportedWidthsRef.current;
|
||||
const hasChange =
|
||||
Object.keys(newColumnWidths).length !== Object.keys(last).length ||
|
||||
Object.keys(newColumnWidths).some((k) => newColumnWidths[k] !== last[k]);
|
||||
|
||||
if (hasChange) {
|
||||
lastReportedWidthsRef.current = newColumnWidths;
|
||||
updateAllColumnWidths(newColumnWidths);
|
||||
}
|
||||
}, [mergedColumns, updateAllColumnWidths, shouldPersistColumnWidths]);
|
||||
}, [mergedColumns, updateAllColumnWidths, onColumnWidthsChange]);
|
||||
|
||||
return onDragColumn ? (
|
||||
<ReactDragListView.DragColumn {...dragColumnParams} onDragEnd={onDragColumn}>
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
import { act } from '@testing-library/react';
|
||||
import { render, screen, userEvent } from 'tests/test-utils';
|
||||
|
||||
import ResizeTable from '../ResizeTable';
|
||||
|
||||
jest.mock('react-resizable', () => ({
|
||||
Resizable: ({
|
||||
children,
|
||||
onResize,
|
||||
width,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
onResize: (
|
||||
e: React.SyntheticEvent,
|
||||
data: { size: { width: number } },
|
||||
) => void;
|
||||
width: number;
|
||||
}): JSX.Element => (
|
||||
<div>
|
||||
{children}
|
||||
<button
|
||||
data-testid="resize-trigger"
|
||||
type="button"
|
||||
onClick={(e): void => onResize(e, { size: { width: width + 50 } })}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
// Make debounce synchronous so onColumnWidthsChange fires immediately
|
||||
jest.mock('lodash-es', () => ({
|
||||
...jest.requireActual('lodash-es'),
|
||||
debounce: (fn: (...args: any[]) => any): ((...args: any[]) => any) => fn,
|
||||
}));
|
||||
|
||||
const baseColumns = [
|
||||
{ dataIndex: 'name', title: 'Name', width: 100 },
|
||||
{ dataIndex: 'value', title: 'Value', width: 100 },
|
||||
];
|
||||
|
||||
const baseDataSource = [
|
||||
{ key: '1', name: 'Alice', value: 42 },
|
||||
{ key: '2', name: 'Bob', value: 99 },
|
||||
];
|
||||
|
||||
describe('ResizeTable', () => {
|
||||
it('renders column headers and data rows', () => {
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Name')).toBeInTheDocument();
|
||||
expect(screen.getByText('Value')).toBeInTheDocument();
|
||||
expect(screen.getByText('Alice')).toBeInTheDocument();
|
||||
expect(screen.getByText('Bob')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('overrides column widths from columnWidths prop and reports them via onColumnWidthsChange', () => {
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
act(() => {
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
columnWidths={{ name: 250, value: 180 }}
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
expect(onColumnWidthsChange).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 250, value: 180 }),
|
||||
);
|
||||
});
|
||||
|
||||
it('reports original column widths via onColumnWidthsChange when columnWidths prop is not provided', () => {
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
act(() => {
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
expect(onColumnWidthsChange).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 100, value: 100 }),
|
||||
);
|
||||
});
|
||||
|
||||
it('does not call onColumnWidthsChange when it is not provided', () => {
|
||||
// Should render without errors and without attempting to call an undefined callback
|
||||
expect(() => {
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
/>,
|
||||
);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('only overrides the column that has a stored width, leaving others at their original width', () => {
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
act(() => {
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
columnWidths={{ name: 250 }}
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
expect(onColumnWidthsChange).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 250, value: 100 }),
|
||||
);
|
||||
});
|
||||
|
||||
it('does not call onColumnWidthsChange on re-render when widths have not changed', () => {
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
const { rerender } = render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(onColumnWidthsChange).toHaveBeenCalledTimes(1);
|
||||
onColumnWidthsChange.mockClear();
|
||||
|
||||
rerender(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(onColumnWidthsChange).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not call onColumnWidthsChange when no column has a defined width', () => {
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={[
|
||||
{ dataIndex: 'name', title: 'Name' },
|
||||
{ dataIndex: 'value', title: 'Value' },
|
||||
]}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(onColumnWidthsChange).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls onColumnWidthsChange with the new width after a column is resized', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
|
||||
onColumnWidthsChange.mockClear();
|
||||
|
||||
// Click the first column's resize trigger — mock adds 50px to the current width (100 → 150)
|
||||
const [firstResizeTrigger] = screen.getAllByTestId('resize-trigger');
|
||||
await user.click(firstResizeTrigger);
|
||||
|
||||
expect(onColumnWidthsChange).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 150, value: 100 }),
|
||||
);
|
||||
});
|
||||
|
||||
it('does not affect other columns when only one column is resized', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onColumnWidthsChange = jest.fn();
|
||||
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onColumnWidthsChange={onColumnWidthsChange}
|
||||
/>,
|
||||
);
|
||||
|
||||
onColumnWidthsChange.mockClear();
|
||||
|
||||
// Resize only the second column (value: 100 → 150), name should stay at 100
|
||||
const resizeTriggers = screen.getAllByTestId('resize-trigger');
|
||||
await user.click(resizeTriggers[1]);
|
||||
|
||||
expect(onColumnWidthsChange).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ name: 100, value: 150 }),
|
||||
);
|
||||
});
|
||||
|
||||
it('wraps column titles in drag handler spans when onDragColumn is provided', () => {
|
||||
const onDragColumn = jest.fn();
|
||||
|
||||
render(
|
||||
<ResizeTable
|
||||
columns={baseColumns}
|
||||
dataSource={baseDataSource}
|
||||
rowKey="key"
|
||||
onDragColumn={onDragColumn}
|
||||
/>,
|
||||
);
|
||||
|
||||
const dragTitles = screen.getAllByTestId('drag-column-title');
|
||||
expect(dragTitles).toHaveLength(baseColumns.length);
|
||||
expect(dragTitles[0]).toHaveTextContent('Name');
|
||||
expect(dragTitles[1]).toHaveTextContent('Value');
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,30 @@
|
||||
import { TableProps } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import { PaginationProps } from 'antd/lib';
|
||||
import { ColumnGroupType, ColumnType } from 'antd/lib/table';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import type { PaginationProps } from 'antd/lib';
|
||||
import type { ColumnGroupType, ColumnType } from 'antd/lib/table';
|
||||
import { LaunchChatSupportProps } from 'components/LaunchChatSupport/LaunchChatSupport';
|
||||
|
||||
import { TableDataSource } from './contants';
|
||||
|
||||
type ColumnWidths = Record<string, number>;
|
||||
|
||||
export interface ResizeTableProps extends TableProps<any> {
|
||||
onDragColumn?: (fromIndex: number, toIndex: number) => void;
|
||||
widgetId?: string;
|
||||
shouldPersistColumnWidths?: boolean;
|
||||
/**
|
||||
* Pre-resolved column widths for this table, keyed by column dataIndex.
|
||||
* Use this to apply persisted widths on mount (e.g. from widget.columnWidths).
|
||||
* Do NOT pass a value that updates reactively on every resize — that creates a
|
||||
* feedback loop. Pass only stable / persisted values.
|
||||
*/
|
||||
columnWidths?: ColumnWidths;
|
||||
/**
|
||||
* Called (debounced) whenever the user finishes resizing a column.
|
||||
* The widths object contains all current column widths keyed by dataIndex.
|
||||
* Intended for persisting widths to an external store (e.g. dashboard context
|
||||
* staging buffer). The caller owns the storage; ResizeTable does not read back
|
||||
* whatever is written here.
|
||||
*/
|
||||
onColumnWidthsChange?: (widths: ColumnWidths) => void;
|
||||
}
|
||||
export interface DynamicColumnTableProps extends TableProps<any> {
|
||||
tablesource: typeof TableDataSource[keyof typeof TableDataSource];
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Radio } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/es/radio';
|
||||
import { Radio, RadioChangeEvent } from 'antd';
|
||||
|
||||
import './SignozRadioGroup.styles.scss';
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
TabsProps,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { TextProps } from 'antd/lib/typography/Text';
|
||||
import { TitleProps } from 'antd/lib/typography/Title';
|
||||
import type { TextProps } from 'antd/lib/typography/Text';
|
||||
import type { TitleProps } from 'antd/lib/typography/Title';
|
||||
import styled, { FlattenSimpleInterpolation } from 'styled-components';
|
||||
|
||||
import { IStyledClass } from './types';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ColumnType } from 'antd/es/table';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import type {
|
||||
TableColumnsType as ColumnsType,
|
||||
TableColumnType as ColumnType,
|
||||
} from 'antd';
|
||||
|
||||
export const generatorResizeTableColumns = <T>({
|
||||
baseColumnOptions,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { Radio } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib';
|
||||
import type { RadioChangeEvent } from 'antd/lib';
|
||||
import { History, Table } from 'lucide-react';
|
||||
|
||||
import { ALERT_TABS } from '../constants';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { Dispatch, SetStateAction, useState } from 'react';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import { Tag } from 'antd/lib';
|
||||
import { Button, Tag } from 'antd';
|
||||
import Input from 'components/Input';
|
||||
import { Check, X } from 'lucide-react';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import { WarningFilled } from '@ant-design/icons';
|
||||
import { Select, Tooltip } from 'antd';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { UniversalYAxisUnitMappings } from './constants';
|
||||
|
||||
@@ -49,7 +49,6 @@ export const REACT_QUERY_KEY = {
|
||||
|
||||
// Metrics Explorer Query Keys
|
||||
GET_METRICS_LIST: 'GET_METRICS_LIST',
|
||||
GET_METRICS_TREE_MAP: 'GET_METRICS_TREE_MAP',
|
||||
GET_METRICS_LIST_FILTER_KEYS: 'GET_METRICS_LIST_FILTER_KEYS',
|
||||
GET_METRICS_LIST_FILTER_VALUES: 'GET_METRICS_LIST_FILTER_VALUES',
|
||||
GET_METRIC_DETAILS: 'GET_METRIC_DETAILS',
|
||||
|
||||
@@ -38,7 +38,6 @@ const ROUTES = {
|
||||
SETTINGS: '/settings',
|
||||
MY_SETTINGS: '/settings/my-settings',
|
||||
ORG_SETTINGS: '/settings/org-settings',
|
||||
CUSTOM_DOMAIN_SETTINGS: '/settings/custom-domain-settings',
|
||||
API_KEYS: '/settings/api-keys',
|
||||
INGESTION_SETTINGS: '/settings/ingestion-settings',
|
||||
SOMETHING_WENT_WRONG: '/something-went-wrong',
|
||||
@@ -56,6 +55,7 @@ const ROUTES = {
|
||||
TRACE_EXPLORER: '/trace-explorer',
|
||||
BILLING: '/settings/billing',
|
||||
ROLES_SETTINGS: '/settings/roles',
|
||||
ROLE_DETAILS: '/settings/roles/:roleId',
|
||||
SUPPORT: '/support',
|
||||
LOGS_SAVE_VIEWS: '/logs/saved-views',
|
||||
TRACES_SAVE_VIEWS: '/traces/saved-views',
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Button,
|
||||
Col,
|
||||
Collapse,
|
||||
CollapseProps,
|
||||
Flex,
|
||||
Form,
|
||||
Input,
|
||||
@@ -20,8 +21,7 @@ import {
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import { CollapseProps } from 'antd/lib';
|
||||
import type { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import createAPIKeyApi from 'api/v1/pats/create';
|
||||
import deleteAPIKeyApi from 'api/v1/pats/delete';
|
||||
import updateAPIKeyApi from 'api/v1/pats/update';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { HTMLAttributes } from 'react';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Progress, Table } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import { Progress, Table, TableColumnsType as ColumnsType } from 'antd';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/AlertPopover';
|
||||
import AlertLabels from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels';
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import { EllipsisOutlined } from '@ant-design/icons';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Button } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import { Button, TableColumnsType as ColumnsType } from 'antd';
|
||||
import ClientSideQBSearch, {
|
||||
AttributeKey,
|
||||
} from 'components/ClientSideQBSearch/ClientSideQBSearch';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { generatePath } from 'react-router-dom';
|
||||
import { Button } from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import type { ColumnsType } from 'antd/lib/table';
|
||||
import { ResizeTable } from 'components/ResizeTable';
|
||||
import ROUTES from 'constants/routes';
|
||||
import useComponentPermission from 'hooks/useComponentPermission';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { Button } from 'antd';
|
||||
import { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import type { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import deleteChannel from 'api/channels/delete';
|
||||
import APIError from 'types/api/error';
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ describe('Alert Channels Settings List page', () => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(successNotification).toBeCalledWith({
|
||||
expect(successNotification).toHaveBeenCalledWith({
|
||||
message: 'Success',
|
||||
description: 'channel_delete_success',
|
||||
});
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { ColumnType, TablePaginationConfig } from 'antd/es/table';
|
||||
import { FilterValue, SorterResult } from 'antd/es/table/interface';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import type { ColumnType, TablePaginationConfig } from 'antd/es/table';
|
||||
import type { FilterValue, SorterResult } from 'antd/es/table/interface';
|
||||
import type { ColumnsType } from 'antd/lib/table';
|
||||
import { FilterConfirmProps } from 'antd/lib/table/interface';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import getAll from 'api/errors/getAll';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FilterDropdownProps } from 'antd/es/table/interface';
|
||||
import type { FilterDropdownProps } from 'antd/es/table/interface';
|
||||
|
||||
export interface FilterDropdownExtendsProps {
|
||||
placeholder: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FilterValue, SortOrder } from 'antd/lib/table/interface';
|
||||
import type { FilterValue, SortOrder } from 'antd/lib/table/interface';
|
||||
import Timestamp from 'timestamp-nano';
|
||||
import { Order, OrderBy } from 'types/api/errors/getAll';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Color, Spacing } from '@signozhq/design-tokens';
|
||||
import { Button, Divider, Drawer, Radio, Typography } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib';
|
||||
import type { RadioChangeEvent } from 'antd/lib';
|
||||
import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
|
||||
import {
|
||||
CustomTimeType,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { UseQueryResult } from 'react-query';
|
||||
import { Table, TablePaginationConfig, Typography } from 'antd';
|
||||
import Skeleton from 'antd/lib/skeleton';
|
||||
import { Skeleton, Table, TablePaginationConfig, Typography } from 'antd';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import {
|
||||
dependentServicesColumns,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useQueries } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
import { Spin, Table } from 'antd';
|
||||
import { ColumnType } from 'antd/lib/table';
|
||||
import type { ColumnType } from 'antd/lib/table';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { ENTITY_VERSION_V4 } from 'constants/app';
|
||||
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||
|
||||
@@ -69,9 +69,6 @@ jest.mock('antd', () => {
|
||||
))}
|
||||
</div>
|
||||
)),
|
||||
Skeleton: jest
|
||||
.fn()
|
||||
.mockImplementation(() => <div data-testid="skeleton-mock" />),
|
||||
Typography: {
|
||||
Text: jest
|
||||
.fn()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Progress, Tag, Tooltip } from 'antd';
|
||||
import { ColumnType } from 'antd/es/table';
|
||||
import { Progress, TableColumnType as ColumnType, Tag, Tooltip } from 'antd';
|
||||
import { convertFiltersToExpressionWithExistingQuery } from 'components/QueryBuilderV2/utils';
|
||||
import {
|
||||
FiltersType,
|
||||
|
||||
@@ -12,10 +12,10 @@ import {
|
||||
Row,
|
||||
Skeleton,
|
||||
Table,
|
||||
TableColumnsType as ColumnsType,
|
||||
Tag,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import getUsage, { UsageResponsePayloadProps } from 'api/billing/getUsage';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import updateCreditCardApi from 'api/v1/checkout/create';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import Breadcrumb from 'antd/es/breadcrumb';
|
||||
import { Breadcrumb } from 'antd';
|
||||
import ROUTES from 'constants/routes';
|
||||
import { Blocks, LifeBuoy } from 'lucide-react';
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom-v5-compat';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Button, Select, Skeleton } from 'antd';
|
||||
import { SelectProps } from 'antd/lib';
|
||||
import type { SelectProps } from 'antd/lib';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import { useAwsAccounts } from 'hooks/integration/aws/useAwsAccounts';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import { createMockAlertContextState } from 'container/CreateAlertV2/EvaluationSettings/__tests__/testUtils';
|
||||
import { getAppContextMockState } from 'container/RoutingPolicies/__tests__/testUtils';
|
||||
import * as appHooks from 'providers/App/App';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DefaultOptionType } from 'antd/es/select';
|
||||
import type { DefaultOptionType } from 'antd/es/select';
|
||||
import { Channels } from 'types/api/channels/getAll';
|
||||
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Button, Flex, Switch, Typography } from 'antd';
|
||||
import { BaseOptionType, DefaultOptionType, SelectProps } from 'antd/es/select';
|
||||
import { Button, Flex, SelectProps, Switch, Typography } from 'antd';
|
||||
import type { BaseOptionType, DefaultOptionType } from 'antd/es/select';
|
||||
import { getInvolvedQueriesInTraceOperator } from 'components/QueryBuilderV2/QueryV2/TraceOperator/utils/utils';
|
||||
import { YAxisSource } from 'components/YAxisUnitSelector/types';
|
||||
import { getYAxisCategories } from 'components/YAxisUnitSelector/utils';
|
||||
|
||||
@@ -179,19 +179,6 @@
|
||||
&__input.description {
|
||||
color: var(--text-ink-300);
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
color: var(--text-ink-400);
|
||||
background: var(--bg-vanilla-100);
|
||||
border: 1px solid var(--bg-vanilla-300);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: var(--text-ink-500);
|
||||
background: var(--bg-vanilla-200);
|
||||
border-color: var(--bg-vanilla-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit-alert-header {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user