diff --git a/frontend/public/Logos/android-java-monitoring.svg b/frontend/public/Logos/android-java-monitoring.svg
new file mode 100644
index 0000000000..b2eb976ea4
--- /dev/null
+++ b/frontend/public/Logos/android-java-monitoring.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/android-kotlin-monitoring.svg b/frontend/public/Logos/android-kotlin-monitoring.svg
new file mode 100644
index 0000000000..3480717db7
--- /dev/null
+++ b/frontend/public/Logos/android-kotlin-monitoring.svg
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/angular.svg b/frontend/public/Logos/angular.svg
new file mode 100644
index 0000000000..09c59e99fa
--- /dev/null
+++ b/frontend/public/Logos/angular.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/application-logs.svg b/frontend/public/Logos/application-logs.svg
new file mode 100644
index 0000000000..60bf068531
--- /dev/null
+++ b/frontend/public/Logos/application-logs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/cloudwatch-logs.svg b/frontend/public/Logos/cloudwatch-logs.svg
new file mode 100644
index 0000000000..46e787df15
--- /dev/null
+++ b/frontend/public/Logos/cloudwatch-logs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/django.svg b/frontend/public/Logos/django.svg
new file mode 100644
index 0000000000..80cbe71c82
--- /dev/null
+++ b/frontend/public/Logos/django.svg
@@ -0,0 +1,41 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/dotnet.svg b/frontend/public/Logos/dotnet.svg
new file mode 100644
index 0000000000..d204a09042
--- /dev/null
+++ b/frontend/public/Logos/dotnet.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/elb.svg b/frontend/public/Logos/elb.svg
new file mode 100644
index 0000000000..2ac7bed278
--- /dev/null
+++ b/frontend/public/Logos/elb.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/elixir.svg b/frontend/public/Logos/elixir.svg
new file mode 100644
index 0000000000..63f8541228
--- /dev/null
+++ b/frontend/public/Logos/elixir.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/express.svg b/frontend/public/Logos/express.svg
new file mode 100644
index 0000000000..4dc0362ab8
--- /dev/null
+++ b/frontend/public/Logos/express.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/falcon.svg b/frontend/public/Logos/falcon.svg
new file mode 100644
index 0000000000..22deec6694
--- /dev/null
+++ b/frontend/public/Logos/falcon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/fastapi.svg b/frontend/public/Logos/fastapi.svg
new file mode 100644
index 0000000000..85f2d13372
--- /dev/null
+++ b/frontend/public/Logos/fastapi.svg
@@ -0,0 +1 @@
+
diff --git a/frontend/public/Logos/flask.svg b/frontend/public/Logos/flask.svg
new file mode 100644
index 0000000000..257941467a
--- /dev/null
+++ b/frontend/public/Logos/flask.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/fluentbit.svg b/frontend/public/Logos/fluentbit.svg
new file mode 100644
index 0000000000..34f7d1c6d7
--- /dev/null
+++ b/frontend/public/Logos/fluentbit.svg
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/fluentd.svg b/frontend/public/Logos/fluentd.svg
new file mode 100644
index 0000000000..05ccd00206
--- /dev/null
+++ b/frontend/public/Logos/fluentd.svg
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/flutter-monitoring.svg b/frontend/public/Logos/flutter-monitoring.svg
new file mode 100644
index 0000000000..313b30ff76
--- /dev/null
+++ b/frontend/public/Logos/flutter-monitoring.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/from-log-file.svg b/frontend/public/Logos/from-log-file.svg
new file mode 100644
index 0000000000..61560fd4cf
--- /dev/null
+++ b/frontend/public/Logos/from-log-file.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-app-engine.svg b/frontend/public/Logos/gcp-app-engine.svg
new file mode 100644
index 0000000000..046144123d
--- /dev/null
+++ b/frontend/public/Logos/gcp-app-engine.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-cloud-functions.svg b/frontend/public/Logos/gcp-cloud-functions.svg
new file mode 100644
index 0000000000..2d10189401
--- /dev/null
+++ b/frontend/public/Logos/gcp-cloud-functions.svg
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-cloud-load-balancer.svg b/frontend/public/Logos/gcp-cloud-load-balancer.svg
new file mode 100644
index 0000000000..2b02982241
--- /dev/null
+++ b/frontend/public/Logos/gcp-cloud-load-balancer.svg
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
Icon_24px_LoadBalancing_Color
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-cloud-monitoring.svg b/frontend/public/Logos/gcp-cloud-monitoring.svg
new file mode 100644
index 0000000000..ab3111db6d
--- /dev/null
+++ b/frontend/public/Logos/gcp-cloud-monitoring.svg
@@ -0,0 +1 @@
+Icon_24px_Monitoring_Color
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-cloud-run.svg b/frontend/public/Logos/gcp-cloud-run.svg
new file mode 100644
index 0000000000..e2e3b7d316
--- /dev/null
+++ b/frontend/public/Logos/gcp-cloud-run.svg
@@ -0,0 +1 @@
+Icon_24px_CloudRun_Color
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-cloud-sql.svg b/frontend/public/Logos/gcp-cloud-sql.svg
new file mode 100644
index 0000000000..b6910a6d7c
--- /dev/null
+++ b/frontend/public/Logos/gcp-cloud-sql.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
Icon_24px_SQL_Color
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-cloud-storage.svg b/frontend/public/Logos/gcp-cloud-storage.svg
new file mode 100644
index 0000000000..d30e003085
--- /dev/null
+++ b/frontend/public/Logos/gcp-cloud-storage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-compute-engine.svg b/frontend/public/Logos/gcp-compute-engine.svg
new file mode 100644
index 0000000000..9ed632fae3
--- /dev/null
+++ b/frontend/public/Logos/gcp-compute-engine.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-gke.svg b/frontend/public/Logos/gcp-gke.svg
new file mode 100644
index 0000000000..9cbabc50fd
--- /dev/null
+++ b/frontend/public/Logos/gcp-gke.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/gcp-vpc.svg b/frontend/public/Logos/gcp-vpc.svg
new file mode 100644
index 0000000000..295b0ee2ab
--- /dev/null
+++ b/frontend/public/Logos/gcp-vpc.svg
@@ -0,0 +1 @@
+Icon_24px_VirtualPrivateCloud_Color
\ No newline at end of file
diff --git a/frontend/public/Logos/go.svg b/frontend/public/Logos/go.svg
new file mode 100644
index 0000000000..64e9620777
--- /dev/null
+++ b/frontend/public/Logos/go.svg
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/heroku.svg b/frontend/public/Logos/heroku.svg
new file mode 100644
index 0000000000..91f1f98ff1
--- /dev/null
+++ b/frontend/public/Logos/heroku.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/hostmetrics.svg b/frontend/public/Logos/hostmetrics.svg
new file mode 100644
index 0000000000..60bf068531
--- /dev/null
+++ b/frontend/public/Logos/hostmetrics.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/http.svg b/frontend/public/Logos/http.svg
new file mode 100644
index 0000000000..f09e4eee20
--- /dev/null
+++ b/frontend/public/Logos/http.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/java-others.svg b/frontend/public/Logos/java-others.svg
new file mode 100644
index 0000000000..7e9c623de6
--- /dev/null
+++ b/frontend/public/Logos/java-others.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/java.svg b/frontend/public/Logos/java.svg
new file mode 100644
index 0000000000..7e9c623de6
--- /dev/null
+++ b/frontend/public/Logos/java.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/javascript.svg b/frontend/public/Logos/javascript.svg
new file mode 100644
index 0000000000..9650ca78ef
--- /dev/null
+++ b/frontend/public/Logos/javascript.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/jboss.svg b/frontend/public/Logos/jboss.svg
new file mode 100644
index 0000000000..cf72755260
--- /dev/null
+++ b/frontend/public/Logos/jboss.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/lambda.svg b/frontend/public/Logos/lambda.svg
new file mode 100644
index 0000000000..0975f058ff
--- /dev/null
+++ b/frontend/public/Logos/lambda.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/llm-monitoring.svg b/frontend/public/Logos/llm-monitoring.svg
new file mode 100644
index 0000000000..7b8cb6b9a0
--- /dev/null
+++ b/frontend/public/Logos/llm-monitoring.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/nestjs.svg b/frontend/public/Logos/nestjs.svg
new file mode 100644
index 0000000000..69830240c2
--- /dev/null
+++ b/frontend/public/Logos/nestjs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/nextjs.svg b/frontend/public/Logos/nextjs.svg
new file mode 100644
index 0000000000..50ccbbd18e
--- /dev/null
+++ b/frontend/public/Logos/nextjs.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/nodejs.svg b/frontend/public/Logos/nodejs.svg
new file mode 100644
index 0000000000..0481f9f80e
--- /dev/null
+++ b/frontend/public/Logos/nodejs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/other-metrics.svg b/frontend/public/Logos/other-metrics.svg
new file mode 100644
index 0000000000..9eb82fbb25
--- /dev/null
+++ b/frontend/public/Logos/other-metrics.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/php.svg b/frontend/public/Logos/php.svg
new file mode 100644
index 0000000000..37a5e6fe7e
--- /dev/null
+++ b/frontend/public/Logos/php.svg
@@ -0,0 +1,96 @@
+
+
+ Official PHP Logo
+
+
+
+ image/svg+xml
+
+ Official PHP Logo
+
+
+ Colin Viebrock
+
+
+
+
+
+
+
+
+
+
+
+ Copyright Colin Viebrock 1997 - All rights reserved.
+
+
+ 1997
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/python-others.svg b/frontend/public/Logos/python-others.svg
new file mode 100644
index 0000000000..e771ee2541
--- /dev/null
+++ b/frontend/public/Logos/python-others.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/python.svg b/frontend/public/Logos/python.svg
new file mode 100644
index 0000000000..e771ee2541
--- /dev/null
+++ b/frontend/public/Logos/python.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/rds.svg b/frontend/public/Logos/rds.svg
new file mode 100644
index 0000000000..245d23725a
--- /dev/null
+++ b/frontend/public/Logos/rds.svg
@@ -0,0 +1,18 @@
+
+
+
+ Icon-Architecture/64/Arch_Amazon-RDS_64
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/ruby-on-rails.svg b/frontend/public/Logos/ruby-on-rails.svg
new file mode 100644
index 0000000000..3c2c7472da
--- /dev/null
+++ b/frontend/public/Logos/ruby-on-rails.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/public/Logos/rust.svg b/frontend/public/Logos/rust.svg
new file mode 100644
index 0000000000..0091b5a8c8
--- /dev/null
+++ b/frontend/public/Logos/rust.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/springboot.svg b/frontend/public/Logos/springboot.svg
new file mode 100644
index 0000000000..740097b559
--- /dev/null
+++ b/frontend/public/Logos/springboot.svg
@@ -0,0 +1 @@
+spring-icon
\ No newline at end of file
diff --git a/frontend/public/Logos/swift-monitoring.svg b/frontend/public/Logos/swift-monitoring.svg
new file mode 100644
index 0000000000..9fd1efc698
--- /dev/null
+++ b/frontend/public/Logos/swift-monitoring.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/swift.svg b/frontend/public/Logos/swift.svg
new file mode 100644
index 0000000000..9fd1efc698
--- /dev/null
+++ b/frontend/public/Logos/swift.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/tomcat-logs.svg b/frontend/public/Logos/tomcat-logs.svg
new file mode 100644
index 0000000000..487a0d7094
--- /dev/null
+++ b/frontend/public/Logos/tomcat-logs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/tomcat.svg b/frontend/public/Logos/tomcat.svg
new file mode 100644
index 0000000000..487a0d7094
--- /dev/null
+++ b/frontend/public/Logos/tomcat.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/vector.svg b/frontend/public/Logos/vector.svg
new file mode 100644
index 0000000000..b045c75543
--- /dev/null
+++ b/frontend/public/Logos/vector.svg
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/public/Logos/vercel.svg b/frontend/public/Logos/vercel.svg
new file mode 100644
index 0000000000..5f54fdea95
--- /dev/null
+++ b/frontend/public/Logos/vercel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/vm.svg b/frontend/public/Logos/vm.svg
new file mode 100644
index 0000000000..eb27e293a7
--- /dev/null
+++ b/frontend/public/Logos/vm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/vpc.svg b/frontend/public/Logos/vpc.svg
new file mode 100644
index 0000000000..289a01df5f
--- /dev/null
+++ b/frontend/public/Logos/vpc.svg
@@ -0,0 +1 @@
+aws-vpc
\ No newline at end of file
diff --git a/frontend/public/Logos/windows-events-logs.svg b/frontend/public/Logos/windows-events-logs.svg
new file mode 100644
index 0000000000..b2ffa2c456
--- /dev/null
+++ b/frontend/public/Logos/windows-events-logs.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/frontend/public/Logos/windows.svg b/frontend/public/Logos/windows.svg
new file mode 100644
index 0000000000..b2ffa2c456
--- /dev/null
+++ b/frontend/public/Logos/windows.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/frontend/public/locales/en/titles.json b/frontend/public/locales/en/titles.json
index a75e02b274..1e2b8f0b4a 100644
--- a/frontend/public/locales/en/titles.json
+++ b/frontend/public/locales/en/titles.json
@@ -3,13 +3,15 @@
"LOGIN": "SigNoz | Login",
"SERVICE_METRICS": "SigNoz | Service Metrics",
"SERVICE_MAP": "SigNoz | Service Map",
- "GET_STARTED": "SigNoz | Get Started",
+ "GET_STARTED_OLD": "SigNoz | Get Started",
"ONBOARDING": "SigNoz | Get Started",
"GET_STARTED_APPLICATION_MONITORING": "SigNoz | Get Started | APM",
"GET_STARTED_LOGS_MANAGEMENT": "SigNoz | Get Started | Logs",
"GET_STARTED_INFRASTRUCTURE_MONITORING": "SigNoz | Get Started | Infrastructure",
"GET_STARTED_AWS_MONITORING": "SigNoz | Get Started | AWS",
"GET_STARTED_AZURE_MONITORING": "SigNoz | Get Started | AZURE",
+ "GET_STARTED": "SigNoz | Get Started with SigNoz Cloud",
+ "GET_STARTED_WITH_CLOUD": "SigNoz | Get Started with SigNoz Cloud",
"TRACE": "SigNoz | Trace",
"TRACE_DETAIL": "SigNoz | Trace Detail",
"TRACES_EXPLORER": "SigNoz | Traces Explorer",
diff --git a/frontend/src/AppRoutes/Private.tsx b/frontend/src/AppRoutes/Private.tsx
index 87ad2bcc3a..c348f38a63 100644
--- a/frontend/src/AppRoutes/Private.tsx
+++ b/frontend/src/AppRoutes/Private.tsx
@@ -1,6 +1,7 @@
import getLocalStorageApi from 'api/browser/localstorage/get';
import setLocalStorageApi from 'api/browser/localstorage/set';
import getOrgUser from 'api/user/getOrgUser';
+import { FeatureKeys } from 'constants/features';
import { LOCALSTORAGE } from 'constants/localStorage';
import ROUTES from 'constants/routes';
import history from 'lib/history';
@@ -36,6 +37,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
isFetchingLicenses,
activeLicenseV3,
isFetchingActiveLicenseV3,
+ featureFlags,
} = useAppContext();
const isAdmin = user.role === USER_ROLES.ADMIN;
@@ -170,6 +172,16 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
}
}, [org]);
+ // if the feature flag is enabled and the current route is /get-started then redirect to /get-started-with-signoz-cloud
+ useEffect(() => {
+ if (
+ currentRoute?.path === ROUTES.GET_STARTED &&
+ featureFlags?.find((e) => e.name === FeatureKeys.ONBOARDING_V3)?.active
+ ) {
+ history.push(ROUTES.GET_STARTED_WITH_CLOUD);
+ }
+ }, [currentRoute, featureFlags]);
+
// eslint-disable-next-line sonarjs/cognitive-complexity
useEffect(() => {
// if it is an old route navigate to the new route
diff --git a/frontend/src/AppRoutes/pageComponents.ts b/frontend/src/AppRoutes/pageComponents.ts
index c1385e8bdf..bf84f6c804 100644
--- a/frontend/src/AppRoutes/pageComponents.ts
+++ b/frontend/src/AppRoutes/pageComponents.ts
@@ -73,6 +73,10 @@ export const OrgOnboarding = Loadable(
() => import(/* webpackChunkName: "OrgOnboarding" */ 'pages/OrgOnboarding'),
);
+export const OnboardingV2 = Loadable(
+ () => import(/* webpackChunkName: "Onboarding V2" */ 'pages/OnboardingPageV2'),
+);
+
export const DashboardPage = Loadable(
() =>
import(/* webpackChunkName: "DashboardPage" */ 'pages/DashboardsListPage'),
diff --git a/frontend/src/AppRoutes/routes.ts b/frontend/src/AppRoutes/routes.ts
index ace656085c..90e7858ba7 100644
--- a/frontend/src/AppRoutes/routes.ts
+++ b/frontend/src/AppRoutes/routes.ts
@@ -33,6 +33,7 @@ import {
NewDashboardPage,
OldLogsExplorer,
Onboarding,
+ OnboardingV2,
OrganizationSettings,
OrgOnboarding,
PasswordReset,
@@ -72,6 +73,13 @@ const routes: AppRoutes[] = [
isPrivate: true,
key: 'GET_STARTED',
},
+ {
+ path: ROUTES.GET_STARTED_WITH_CLOUD,
+ exact: false,
+ component: OnboardingV2,
+ isPrivate: true,
+ key: 'GET_STARTED_WITH_CLOUD',
+ },
{
path: ROUTES.ONBOARDING,
exact: false,
diff --git a/frontend/src/constants/features.ts b/frontend/src/constants/features.ts
index 9a2550ec0b..db64d7923f 100644
--- a/frontend/src/constants/features.ts
+++ b/frontend/src/constants/features.ts
@@ -23,4 +23,6 @@ export enum FeatureKeys {
PREMIUM_SUPPORT = 'PREMIUM_SUPPORT',
QUERY_BUILDER_SEARCH_V2 = 'QUERY_BUILDER_SEARCH_V2',
ANOMALY_DETECTION = 'ANOMALY_DETECTION',
+ AWS_INTEGRATION = 'AWS_INTEGRATION',
+ ONBOARDING_V3 = 'ONBOARDING_V3',
}
diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts
index 5c40f1ddd4..aca2ce5e33 100644
--- a/frontend/src/constants/routes.ts
+++ b/frontend/src/constants/routes.ts
@@ -7,8 +7,9 @@ const ROUTES = {
TRACE: '/trace',
TRACE_DETAIL: '/trace/:id',
TRACES_EXPLORER: '/traces-explorer',
- GET_STARTED: '/get-started',
ONBOARDING: '/onboarding',
+ GET_STARTED: '/get-started',
+ GET_STARTED_WITH_CLOUD: '/get-started-with-signoz-cloud',
GET_STARTED_APPLICATION_MONITORING: '/get-started/application-monitoring',
GET_STARTED_LOGS_MANAGEMENT: '/get-started/logs-management',
GET_STARTED_INFRASTRUCTURE_MONITORING:
diff --git a/frontend/src/container/AppLayout/AppLayout.styles.scss b/frontend/src/container/AppLayout/AppLayout.styles.scss
index 569e96f388..f5900c45b2 100644
--- a/frontend/src/container/AppLayout/AppLayout.styles.scss
+++ b/frontend/src/container/AppLayout/AppLayout.styles.scss
@@ -4,7 +4,7 @@
width: 100%;
.app-content {
- width: calc(100% - 64px);
+ width: 100%;
z-index: 0;
margin: 0 auto;
diff --git a/frontend/src/container/AppLayout/index.tsx b/frontend/src/container/AppLayout/index.tsx
index 4e0fe0a1c0..feb354245c 100644
--- a/frontend/src/container/AppLayout/index.tsx
+++ b/frontend/src/container/AppLayout/index.tsx
@@ -242,6 +242,7 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
const renderFullScreen =
pathname === ROUTES.GET_STARTED ||
pathname === ROUTES.ONBOARDING ||
+ pathname === ROUTES.GET_STARTED_WITH_CLOUD ||
pathname === ROUTES.GET_STARTED_APPLICATION_MONITORING ||
pathname === ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING ||
pathname === ROUTES.GET_STARTED_LOGS_MANAGEMENT ||
diff --git a/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss b/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss
index acf7b238f4..3d1b795ab8 100644
--- a/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss
+++ b/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss
@@ -978,14 +978,70 @@
.ingestion-setup-details-links {
display: flex;
- align-items: center;
+ flex-direction: column;
gap: 8px;
- margin-bottom: 24px;
+ margin-top: 12px;
padding: 12px;
border-radius: 4px;
background: rgba(113, 144, 249, 0.1);
color: var(--bg-robin-300, #95acfb);
+ .ingestion-key-url-container {
+ display: flex;
+ gap: 8px;
+ justify-content: space-between;
+ align-items: center;
+
+ .ingestion-key-url-label {
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--bg-robin-300, #95acfb);
+ }
+
+ .ingestion-key-url-value {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--bg-robin-300, #95acfb);
+
+ .copy-key-btn {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .ingestion-data-region-container {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ justify-content: space-between;
+
+ .ingestion-data-region-label {
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--bg-robin-300, #95acfb);
+ }
+
+ .ingestion-data-region-value {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--bg-robin-300, #95acfb);
+
+ .ingestion-data-region-value-text {
+ color: var(--bg-robin-300, #95acfb);
+ }
+
+ .copy-key-btn {
+ cursor: pointer;
+ }
+ }
+ }
+
.learn-more {
display: inline-flex;
justify-content: center;
diff --git a/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx b/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx
index ca8ce7251d..cc472ad09b 100644
--- a/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx
+++ b/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx
@@ -1,3 +1,5 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import './IngestionSettings.styles.scss';
import { Color } from '@signozhq/design-tokens';
@@ -33,6 +35,7 @@ import Tags from 'components/Tags/Tags';
import { SOMETHING_WENT_WRONG } from 'constants/api';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import dayjs from 'dayjs';
+import { useGetDeploymentsData } from 'hooks/CustomDomain/useGetDeploymentsData';
import { useGetAllIngestionsKeys } from 'hooks/IngestionKeys/useGetAllIngestionKeys';
import useDebouncedFn from 'hooks/useDebouncedFunction';
import { useNotifications } from 'hooks/useNotifications';
@@ -43,7 +46,6 @@ import {
Check,
Copy,
Infinity,
- Info,
Minus,
PenLine,
Plus,
@@ -285,6 +287,13 @@ function MultiIngestionSettings(): JSX.Element {
setSearchValue('');
};
+ const {
+ data: deploymentsData,
+ isLoading: isLoadingDeploymentsData,
+ isFetching: isFetchingDeploymentsData,
+ isError: isErrorDeploymentsData,
+ } = useGetDeploymentsData();
+
const {
mutate: createIngestionKey,
isLoading: isLoadingCreateAPIKey,
@@ -1253,22 +1262,6 @@ function MultiIngestionSettings(): JSX.Element {
return (
-
-
-
-
- Find your ingestion URL and learn more about sending data to SigNoz{' '}
-
- here
-
-
-
-
Ingestion Keys
@@ -1284,6 +1277,46 @@ function MultiIngestionSettings(): JSX.Element {
+ {!isErrorDeploymentsData &&
+ !isLoadingDeploymentsData &&
+ !isFetchingDeploymentsData && (
+
+
+
Ingestion URL
+
{
+ e.stopPropagation();
+ e.preventDefault();
+ handleCopyKey(
+ `ingest.${deploymentsData?.data.data.cluster.region.dns}`,
+ );
+ }}
+ >
+ ingest.{deploymentsData?.data.data.cluster.region.dns}
+
+
+
+
+
+
Region
+
{
+ e.stopPropagation();
+ e.preventDefault();
+ handleCopyKey(deploymentsData?.data.data.cluster.region.name || '');
+ }}
+ >
+
+ {deploymentsData?.data.data.cluster.region.name}
+
+
+
+
+
+ )}
+
{
});
it('renders MultiIngestionSettings page without crashing', () => {
- expect(
- screen.getByText(
- 'Find your ingestion URL and learn more about sending data to SigNoz',
- ),
- ).toBeInTheDocument();
-
expect(screen.getByText('Ingestion Keys')).toBeInTheDocument();
expect(
screen.getByText('Create and manage ingestion keys for the SigNoz Cloud'),
).toBeInTheDocument();
- const overviewLink = screen.getByRole('link', { name: /here/i });
- expect(overviewLink).toHaveAttribute(
- 'href',
- 'https://signoz.io/docs/ingestion/signoz-cloud/overview/',
- );
- expect(overviewLink).toHaveAttribute('target', '_blank');
- expect(overviewLink).toHaveClass('learn-more');
- expect(overviewLink).toHaveAttribute('rel', 'noreferrer');
-
const aboutKeyslink = screen.getByRole('link', { name: /Learn more/i });
expect(aboutKeyslink).toHaveAttribute(
'href',
diff --git a/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx b/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx
index 861786f2aa..ea120ec4f3 100644
--- a/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx
+++ b/frontend/src/container/OnboardingContainer/OnboardingContainer.tsx
@@ -7,12 +7,14 @@ import { Button, Card, Form, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import getIngestionData from 'api/settings/getIngestionData';
import cx from 'classnames';
+import { FeatureKeys } from 'constants/features';
import ROUTES from 'constants/routes';
import FullScreenHeader from 'container/FullScreenHeader/FullScreenHeader';
import InviteUserModal from 'container/OrganizationSettings/InviteUserModal/InviteUserModal';
import { InviteMemberFormValues } from 'container/OrganizationSettings/PendingInvitesContainer';
import history from 'lib/history';
import { UserPlus } from 'lucide-react';
+import { useAppContext } from 'providers/App/App';
import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
@@ -106,6 +108,11 @@ export default function Onboarding(): JSX.Element {
const { location } = history;
const { t } = useTranslation(['onboarding']);
+ const { featureFlags } = useAppContext();
+ const isOnboardingV3Enabled = featureFlags?.find(
+ (flag) => flag.name === FeatureKeys.ONBOARDING_V3,
+ )?.active;
+
const {
selectedDataSource,
selectedEnvironment,
@@ -384,7 +391,12 @@ export default function Onboarding(): JSX.Element {
setActiveStep(activeStep - 1);
setSelectedModule(useCases.APM);
resetProgress();
- history.push(ROUTES.GET_STARTED);
+
+ if (isOnboardingV3Enabled) {
+ history.push(ROUTES.GET_STARTED_WITH_CLOUD);
+ } else {
+ history.push(ROUTES.GET_STARTED);
+ }
}}
selectedModule={selectedModule}
selectedModuleSteps={selectedModuleSteps}
diff --git a/frontend/src/container/OnboardingQuestionaire/index.tsx b/frontend/src/container/OnboardingQuestionaire/index.tsx
index 1d7975d6c5..e383a487dd 100644
--- a/frontend/src/container/OnboardingQuestionaire/index.tsx
+++ b/frontend/src/container/OnboardingQuestionaire/index.tsx
@@ -7,6 +7,7 @@ import getAllOrgPreferences from 'api/preferences/getAllOrgPreferences';
import updateOrgPreferenceAPI from 'api/preferences/updateOrgPreference';
import { AxiosError } from 'axios';
import { SOMETHING_WENT_WRONG } from 'constants/api';
+import { FeatureKeys } from 'constants/features';
import ROUTES from 'constants/routes';
import { InviteTeamMembersProps } from 'container/OrganizationSettings/PendingInvitesContainer';
import { useNotifications } from 'hooks/useNotifications';
@@ -62,7 +63,10 @@ const ONBOARDING_COMPLETE_EVENT_NAME = 'Org Onboarding: Complete';
function OnboardingQuestionaire(): JSX.Element {
const { notifications } = useNotifications();
- const { org, updateOrgPreferences } = useAppContext();
+ const { org, updateOrgPreferences, featureFlags } = useAppContext();
+ const isOnboardingV3Enabled = featureFlags?.find(
+ (flag) => flag.name === FeatureKeys.ONBOARDING_V3,
+ )?.active;
const [currentStep, setCurrentStep] = useState
(1);
const [orgDetails, setOrgDetails] = useState(INITIAL_ORG_DETAILS);
const [signozDetails, setSignozDetails] = useState(
@@ -117,7 +121,11 @@ function OnboardingQuestionaire(): JSX.Element {
logEvent('Org Onboarding: Redirecting to Get Started', {});
- history.push(ROUTES.GET_STARTED);
+ if (isOnboardingV3Enabled) {
+ history.push(ROUTES.GET_STARTED_WITH_CLOUD);
+ } else {
+ history.push(ROUTES.GET_STARTED);
+ }
},
onError: () => {
setUpdatingOrgOnboardingStatus(false);
diff --git a/frontend/src/container/OnboardingV2Container/AddDataSource/AddDataSource.tsx b/frontend/src/container/OnboardingV2Container/AddDataSource/AddDataSource.tsx
new file mode 100644
index 0000000000..da98bf26c6
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/AddDataSource/AddDataSource.tsx
@@ -0,0 +1,813 @@
+import '../OnboardingV2.styles.scss';
+
+import { SearchOutlined } from '@ant-design/icons';
+import {
+ Button,
+ Flex,
+ Input,
+ Layout,
+ Modal,
+ Skeleton,
+ Space,
+ Steps,
+ Typography,
+} from 'antd';
+import logEvent from 'api/common/logEvent';
+import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
+import ROUTES from 'constants/routes';
+import history from 'lib/history';
+import { isEmpty } from 'lodash-es';
+import { ArrowRight, X } from 'lucide-react';
+import { useAppContext } from 'providers/App/App';
+import React, { useEffect, useRef, useState } from 'react';
+
+import OnboardingIngestionDetails from '../IngestionDetails/IngestionDetails';
+import InviteTeamMembers from '../InviteTeamMembers/InviteTeamMembers';
+import onboardingConfigWithLinks from '../onboarding-configs/onboarding-config-with-links.json';
+
+const { Header } = Layout;
+
+interface OptionGroup {
+ id: string;
+ category: string;
+ items: string[];
+}
+
+export interface Question {
+ id: string;
+ title: string;
+ description: string;
+ options: OptionGroup[];
+ uiConfig?: {
+ showSearch?: boolean;
+ filterByCategory?: boolean;
+ };
+}
+
+interface Option {
+ imgUrl?: string;
+ label: string;
+ link?: string;
+ entityID?: string;
+}
+
+interface Entity {
+ imgUrl?: string;
+ label: string;
+ dataSource: string;
+ entityID: string;
+ module: string;
+ question?: {
+ desc: string;
+ options: Option[];
+ entityID: string;
+ question?: {
+ desc: string;
+ options: Option[];
+ entityID: string;
+ };
+ };
+ tags: string[];
+ link?: string;
+}
+
+const setupStepItemsBase = [
+ {
+ title: 'Org Setup',
+ description: ,
+ },
+ {
+ title: 'Add your first data source',
+ description: ' ',
+ },
+ {
+ title: 'Configure Your Product',
+ description: ' ',
+ },
+];
+
+const ONBOARDING_V3_ANALYTICS_EVENTS_MAP = {
+ BASE: 'Onboarding V3',
+ STARTED: 'Started',
+ DATA_SOURCE_SELECTED: 'Datasource selected',
+ FRAMEWORK_SELECTED: 'Framework selected',
+ ENVIRONMENT_SELECTED: 'Environment selected',
+ CONFIGURED_PRODUCT: 'Configure clicked',
+ BACK_BUTTON_CLICKED: 'Back clicked',
+ CONTINUE_BUTTON_CLICKED: 'Continue clicked',
+ GET_HELP_BUTTON_CLICKED: 'Get help clicked',
+ GET_EXPERT_ASSISTANCE_BUTTON_CLICKED: 'Get expert assistance clicked',
+ INVITE_TEAM_MEMBER_BUTTON_CLICKED: 'Invite team member clicked',
+ CLOSE_ONBOARDING_CLICKED: 'Close onboarding clicked',
+};
+
+function OnboardingAddDataSource(): JSX.Element {
+ const [groupedDataSources, setGroupedDataSources] = useState<{
+ [tag: string]: Entity[];
+ }>({});
+
+ const { org } = useAppContext();
+
+ const [setupStepItems, setSetupStepItems] = useState(setupStepItemsBase);
+
+ const question2Ref = useRef(null);
+ const question3Ref = useRef(null);
+ const configureProdRef = useRef(null);
+
+ const [showConfigureProduct, setShowConfigureProduct] = useState(
+ false,
+ );
+
+ const [currentStep, setCurrentStep] = useState(1);
+
+ const [hasMoreQuestions, setHasMoreQuestions] = useState(true);
+
+ const [
+ showInviteTeamMembersModal,
+ setShowInviteTeamMembersModal,
+ ] = useState(false);
+
+ const [docsUrl, setDocsUrl] = useState(
+ 'https://signoz.io/docs/instrumentation/',
+ );
+
+ const [selectedDataSource, setSelectedDataSource] = useState(
+ null,
+ );
+
+ const [selectedFramework, setSelectedFramework] = useState(
+ null,
+ );
+
+ const [selectedEnvironment, setSelectedEnvironment] = useState(
+ null,
+ );
+
+ const [selectedCategory, setSelectedCategory] = useState('All');
+
+ const handleScrollToStep = (ref: React.RefObject): void => {
+ setTimeout(() => {
+ ref.current?.scrollIntoView({
+ behavior: 'smooth',
+ block: 'start',
+ inline: 'nearest',
+ });
+ }, 100);
+ };
+
+ useEffect(() => {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.STARTED}`,
+ {},
+ );
+ }, []);
+
+ const updateUrl = (url: string, selectedEnvironment: string | null): void => {
+ if (!url || url === '') {
+ return;
+ }
+
+ // Step 1: Parse the URL
+ const urlObj = new URL(url);
+
+ // Step 2: Update or add the 'source' parameter
+ urlObj.searchParams.set('source', 'onboarding');
+
+ if (selectedEnvironment) {
+ urlObj.searchParams.set('environment', selectedEnvironment);
+ }
+
+ // Step 3: Return the updated URL as a string
+ const updatedUrl = urlObj.toString();
+
+ setDocsUrl(updatedUrl);
+ };
+
+ const handleSelectDataSource = (dataSource: Entity): void => {
+ setSelectedDataSource(dataSource);
+ setSelectedFramework(null);
+ setSelectedEnvironment(null);
+
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.DATA_SOURCE_SELECTED}`,
+ {
+ dataSource: dataSource.label,
+ },
+ );
+
+ if (dataSource.question) {
+ setHasMoreQuestions(true);
+
+ setTimeout(() => {
+ handleScrollToStep(question2Ref);
+ }, 100);
+ } else {
+ setHasMoreQuestions(false);
+
+ updateUrl(dataSource?.link || '', null);
+
+ setShowConfigureProduct(true);
+ }
+ };
+
+ const handleSelectFramework = (option: any): void => {
+ setSelectedFramework(option);
+
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.FRAMEWORK_SELECTED}`,
+ {
+ dataSource: selectedDataSource?.label,
+ framework: option.label,
+ },
+ );
+
+ if (option.question) {
+ setHasMoreQuestions(true);
+
+ updateUrl(option?.link, null);
+
+ setTimeout(() => {
+ handleScrollToStep(question3Ref);
+ }, 100);
+ } else {
+ updateUrl(option.link, null);
+ setHasMoreQuestions(false);
+
+ setShowConfigureProduct(true);
+ }
+ };
+
+ const handleSelectEnvironment = (selectedEnvironment: any): void => {
+ setSelectedEnvironment(selectedEnvironment);
+ setHasMoreQuestions(false);
+
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.ENVIRONMENT_SELECTED}`,
+ {
+ dataSource: selectedDataSource?.label,
+ framework: selectedFramework?.label,
+ environment: selectedEnvironment?.label,
+ },
+ );
+
+ updateUrl(docsUrl, selectedEnvironment?.key);
+
+ setShowConfigureProduct(true);
+ };
+
+ const groupDataSourcesByTags = (
+ dataSources: Entity[],
+ ): { [tag: string]: Entity[] } => {
+ const groupedDataSources: { [tag: string]: Entity[] } = {};
+
+ dataSources.forEach((dataSource) => {
+ dataSource.tags.forEach((tag) => {
+ if (!groupedDataSources[tag]) {
+ groupedDataSources[tag] = [];
+ }
+ groupedDataSources[tag].push(dataSource);
+ });
+ });
+
+ return groupedDataSources;
+ };
+
+ useEffect(() => {
+ const groupedDataSources = groupDataSourcesByTags(
+ onboardingConfigWithLinks as Entity[],
+ );
+
+ setGroupedDataSources(groupedDataSources);
+ }, []);
+
+ const handleSearch = (e: React.ChangeEvent): void => {
+ const query = e.target.value.toLowerCase();
+
+ if (query === '') {
+ setGroupedDataSources(
+ groupDataSourcesByTags(onboardingConfigWithLinks as Entity[]),
+ );
+ return;
+ }
+
+ const filteredDataSources = onboardingConfigWithLinks.filter(
+ (dataSource) =>
+ dataSource.label.toLowerCase().includes(query) ||
+ dataSource.tags.some((tag) => tag.toLowerCase().includes(query)),
+ );
+
+ setGroupedDataSources(
+ groupDataSourcesByTags(filteredDataSources as Entity[]),
+ );
+ };
+
+ const handleFilterByCategory = (category: string): void => {
+ setSelectedDataSource(null);
+ setSelectedFramework(null);
+ setSelectedEnvironment(null);
+
+ if (category === 'All') {
+ setGroupedDataSources(
+ groupDataSourcesByTags(onboardingConfigWithLinks as Entity[]),
+ );
+
+ setSelectedCategory('All');
+ return;
+ }
+
+ const filteredDataSources = onboardingConfigWithLinks.filter(
+ (dataSource) =>
+ dataSource.tags.includes(category) ||
+ dataSource.tags.some((tag) => tag.toLowerCase().includes(category)),
+ );
+
+ setSelectedCategory(category);
+
+ setGroupedDataSources(
+ groupDataSourcesByTags(filteredDataSources as Entity[]),
+ );
+ };
+
+ useEffect(() => {
+ setSetupStepItems([
+ {
+ ...setupStepItemsBase[0],
+ description: org?.[0]?.name || '',
+ },
+ ...setupStepItemsBase.slice(1),
+ ]);
+ }, [org]);
+
+ const handleUpdateCurrentStep = (step: number): void => {
+ setCurrentStep(step);
+
+ if (step === 1) {
+ setSetupStepItems([
+ {
+ ...setupStepItemsBase[0],
+ description: org?.[0]?.name || '',
+ },
+ {
+ ...setupStepItemsBase[1],
+ description: '',
+ },
+ ...setupStepItemsBase.slice(2),
+ ]);
+ } else if (step === 2) {
+ setSetupStepItems([
+ {
+ ...setupStepItemsBase[0],
+ description: org?.[0]?.name || '',
+ },
+ {
+ ...setupStepItemsBase[1],
+ description: `${selectedDataSource?.label} ${
+ selectedFramework?.label ? `- ${selectedFramework?.label}` : ''
+ }`,
+ },
+ ...setupStepItemsBase.slice(2),
+ ]);
+ } else if (step === 3) {
+ switch (selectedDataSource?.module) {
+ case 'apm':
+ history.push(ROUTES.APPLICATION);
+ break;
+ case 'logs':
+ history.push(ROUTES.LOGS);
+ break;
+ case 'metrics':
+ history.push(ROUTES.ALL_DASHBOARD);
+ break;
+ default:
+ history.push(ROUTES.APPLICATION);
+ }
+ }
+ };
+
+ const handleShowInviteTeamMembersModal = (): void => {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.INVITE_TEAM_MEMBER_BUTTON_CLICKED}`,
+ {
+ dataSource: selectedDataSource?.label,
+ framework: selectedFramework?.label,
+ environment: selectedEnvironment?.label,
+ currentPage: setupStepItems[currentStep]?.title || '',
+ },
+ );
+ setShowInviteTeamMembersModal(true);
+ };
+
+ return (
+
+
+
+
+
+ {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.CLOSE_ONBOARDING_CLICKED}`,
+ {
+ currentPage: setupStepItems[currentStep]?.title || '',
+ },
+ );
+
+ history.push(ROUTES.APPLICATION);
+ }}
+ />
+ Get Started (2/4)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {currentStep === 1 && (
+
+
+
+
+
+ Select your data source
+
+
+ Select from a host of services to start sending data to SigNoz
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+ {Object.keys(groupedDataSources).map((tag) => (
+
+
+ {tag} ({groupedDataSources[tag].length})
+
+
+ {groupedDataSources[tag].map((dataSource) => (
+
handleSelectDataSource(dataSource)}
+ >
+
+
+ {dataSource.label}
+
+ ))}
+
+
+ ))}
+
+
+
+
+
+ {' '}
+ Filters{' '}
+
+
+
handleFilterByCategory('All')}
+ >
+ All ({onboardingConfigWithLinks.length})
+
+
+ {Object.keys(groupedDataSources).map((tag) => (
+
+ handleFilterByCategory(tag)}
+ >
+ {tag} ({groupedDataSources[tag].length})
+
+
+ ))}
+
+
+
+
+ {selectedDataSource &&
+ selectedDataSource?.question &&
+ !isEmpty(selectedDataSource?.question) && (
+
+ {selectedDataSource?.question?.desc && (
+ <>
+
+
+ {selectedDataSource?.question?.desc}
+
+
+
+
+ {selectedDataSource?.question?.options.map((option) => (
+
handleSelectFramework(option)}
+ >
+ {option.imgUrl && (
+
+ )}
+
+ {option.label}
+
+ ))}
+
+ >
+ )}
+
+ )}
+
+ {selectedFramework &&
+ selectedFramework?.question &&
+ !isEmpty(selectedFramework?.question) && (
+
+ {selectedFramework?.question?.desc && (
+ <>
+
+
+ {selectedFramework?.question?.desc}
+
+
+
+
+ {selectedFramework?.question?.options.map((option) => (
+
handleSelectEnvironment(option)}
+ >
+
+ {option.label}
+
+ ))}
+
+ >
+ )}
+
+ )}
+
+ {!hasMoreQuestions && showConfigureProduct && (
+
+ {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.CONFIGURED_PRODUCT}`,
+ {
+ dataSource: selectedDataSource?.label,
+ framework: selectedFramework?.label,
+ environment: selectedEnvironment?.label,
+ },
+ );
+
+ handleUpdateCurrentStep(2);
+ }}
+ >
+ Next: Configure your product
+
+
+ )}
+
+
+
+ )}
+
+ {currentStep === 2 && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BACK_BUTTON_CLICKED}`,
+ {
+ dataSource: selectedDataSource?.label,
+ framework: selectedFramework?.label,
+ environment: selectedEnvironment?.label,
+ currentPage: setupStepItems[currentStep]?.title || '',
+ },
+ );
+
+ handleUpdateCurrentStep(1);
+ }}
+ >
+ Back
+
+ {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.CONTINUE_BUTTON_CLICKED}`,
+ {
+ dataSource: selectedDataSource?.label,
+ framework: selectedFramework?.label,
+ environment: selectedEnvironment?.label,
+ currentPage: setupStepItems[currentStep]?.title || '',
+ },
+ );
+
+ handleFilterByCategory('All');
+ handleUpdateCurrentStep(3);
+ }}
+ >
+ Continue
+
+
+
+ )}
+
+
+
+ {currentStep === 1 && (
+
+
+ Invite a team member to help with this step
+
+
+
Or
+
+
+ Need help with setup? Upgrade now and get expert assistance.
+
+
+
+
+
+ )}
+
+ {currentStep === 2 &&
}
+
+
+
+ Invite a team member}
+ open={showInviteTeamMembersModal}
+ closable
+ onCancel={(): void => setShowInviteTeamMembersModal(false)}
+ width="640px"
+ footer={null}
+ destroyOnClose
+ >
+
+ {}}
+ onNext={(): void => setShowInviteTeamMembersModal(false)}
+ onClose={(): void => setShowInviteTeamMembersModal(false)}
+ />
+
+
+
+
+ );
+}
+
+export default OnboardingAddDataSource;
diff --git a/frontend/src/container/OnboardingV2Container/IngestionDetails/IngestionDetails.tsx b/frontend/src/container/OnboardingV2Container/IngestionDetails/IngestionDetails.tsx
new file mode 100644
index 0000000000..923334eb88
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/IngestionDetails/IngestionDetails.tsx
@@ -0,0 +1,221 @@
+import { Skeleton, Typography } from 'antd';
+import logEvent from 'api/common/logEvent';
+import getIngestionData from 'api/settings/getIngestionData';
+import { AxiosError } from 'axios';
+import { useGetDeploymentsData } from 'hooks/CustomDomain/useGetDeploymentsData';
+import { useNotifications } from 'hooks/useNotifications';
+import {
+ ArrowUpRight,
+ Copy,
+ Info,
+ Key,
+ MapPin,
+ TriangleAlert,
+} from 'lucide-react';
+import { useEffect, useState } from 'react';
+import { useQuery } from 'react-query';
+import { useCopyToClipboard } from 'react-use';
+import { IngestionInfo } from 'types/api/settings/ingestion';
+
+function maskKey(key: string, visibleStart = 4, visibleEnd = 4): string {
+ if (!key) {
+ return '';
+ }
+
+ // Ensure the key length is sufficient to be masked
+ if (key.length <= visibleStart + visibleEnd) {
+ return key; // Return the key as-is if it's too short to mask
+ }
+
+ const maskedSection = '*'.repeat(5);
+
+ // Construct and return the masked key
+ return key.slice(0, visibleStart) + maskedSection + key.slice(-visibleEnd);
+}
+
+const ONBOARDING_V3_ANALYTICS_EVENTS_MAP = {
+ BASE: 'Onboarding V3',
+ INGESTION_KEY_COPIED: 'Ingestion key copied',
+ INGESTION_URL_COPIED: 'Ingestion URL copied',
+ REGION_COPIED: 'Region copied',
+};
+
+export default function OnboardingIngestionDetails(): JSX.Element {
+ const { notifications } = useNotifications();
+ const [, handleCopyToClipboard] = useCopyToClipboard();
+
+ const [firstIngestionKey, setFirstIngestionKey] = useState(
+ {} as IngestionInfo,
+ );
+
+ const {
+ status,
+ data: ingestionData,
+ isLoading: isIngestionKeysLoading,
+ error,
+ isError,
+ } = useQuery({
+ queryFn: () => getIngestionData(),
+ });
+
+ const {
+ data: deploymentsData,
+ isLoading: isLoadingDeploymentsData,
+ isFetching: isFetchingDeploymentsData,
+ isError: isDeploymentsDataError,
+ } = useGetDeploymentsData();
+
+ const handleCopyKey = (text: string): void => {
+ handleCopyToClipboard(text);
+ notifications.success({
+ message: 'Copied to clipboard',
+ });
+ };
+
+ useEffect(() => {
+ if (
+ status === 'success' &&
+ ingestionData &&
+ ingestionData &&
+ Array.isArray(ingestionData.payload)
+ ) {
+ const payload = ingestionData.payload[0] || {
+ ingestionKey: '',
+ ingestionURL: '',
+ dataRegion: '',
+ };
+
+ setFirstIngestionKey(payload);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [status, ingestionData?.payload]);
+
+ return (
+
+ {isError && (
+
+
+ {' '}
+ {(error as AxiosError)?.message || 'Something went wrong'}
+
+
+
+
+
+
+ Find your ingestion URL and learn more about sending data to SigNoz{' '}
+
+ here
+
+
+
+
+ )}
+
+ {(isIngestionKeysLoading || !isError) && (
+ <>
+
+
+ You can use this key to send your telemetry data to SigNoz.
+
+
+
+ {isIngestionKeysLoading ||
+ isLoadingDeploymentsData ||
+ isFetchingDeploymentsData ? (
+
+
+
+
+
+
+ ) : (
+
+ {!isDeploymentsDataError &&
+ !isLoadingDeploymentsData &&
+ !isFetchingDeploymentsData && (
+
+
+ Region
+
+
+
+ {deploymentsData?.data?.data?.cluster.region.name}
+
+ {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.REGION_COPIED}`,
+ {},
+ );
+
+ handleCopyKey(
+ deploymentsData?.data?.data?.cluster.region.name || '',
+ );
+ }}
+ />
+
+
+ )}
+
+
+ Ingestion Key
+
+
+
+ {maskKey(firstIngestionKey?.ingestionKey)}
+
+ {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.INGESTION_KEY_COPIED}`,
+ {},
+ );
+ handleCopyKey(firstIngestionKey?.ingestionKey);
+ }}
+ />
+
+
+
+ )}
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/frontend/src/container/OnboardingV2Container/InviteTeamMembers/InviteTeamMembers.styles.scss b/frontend/src/container/OnboardingV2Container/InviteTeamMembers/InviteTeamMembers.styles.scss
new file mode 100644
index 0000000000..3e3db5b6ed
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/InviteTeamMembers/InviteTeamMembers.styles.scss
@@ -0,0 +1,153 @@
+.team-member-container {
+ display: flex;
+ align-items: center;
+
+ .invite-team-members-form {
+ padding: 16px 0px;
+ }
+
+ .team-member-email-input {
+ width: 80%;
+ background-color: #121317;
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+
+ .ant-input,
+ .ant-input-group-addon {
+ background-color: #121317 !important;
+ border-right: 0px;
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ }
+ }
+
+ .team-member-role-select {
+ width: 20%;
+
+ .ant-select-selector {
+ border: 1px solid #1d212d;
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ }
+ }
+
+ .remove-team-member-button {
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+ }
+}
+
+.invite-team-members-container {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+
+ .invite-team-members-add-another-member-container {
+ margin: 16px 0px;
+ display: flex;
+ justify-content: flex-end;
+ }
+
+ .next-prev-container {
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+
+ margin-top: 16px;
+ }
+
+ .error-message-container,
+ .success-message-container,
+ .partially-sent-invites-container {
+ border-radius: 4px;
+ width: 100%;
+ display: flex;
+ align-items: center;
+
+ .error-message,
+ .success-message {
+ font-size: 12px;
+ font-weight: 400;
+
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+ }
+
+ .invite-users-error-message-container,
+ .invite-users-success-message-container {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+
+ .success-message {
+ color: var(--bg-success-500, #00b37e);
+ }
+ }
+
+ .partially-sent-invites-container {
+ margin-top: 16px;
+ padding: 8px;
+ border: 1px solid #1d212d;
+ background-color: #121317;
+
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+ box-sizing: border-box;
+
+ .partially-sent-invites-message {
+ color: var(--bg-warning-500, #fbbd23);
+
+ font-size: 12px;
+ font-weight: 400;
+
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+ }
+}
+
+.lightMode {
+ .team-member-container {
+ .team-member-role-select {
+ .ant-select-selector {
+ border: 1px solid var(--bg-vanilla-300);
+ }
+ }
+
+ .team-member-email-input {
+ background-color: var(--bg-vanilla-100);
+
+ .ant-input,
+ .ant-input-group-addon {
+ background-color: var(--bg-vanilla-100) !important;
+ }
+ }
+ }
+
+ .questions-form-container {
+ .invite-users-error-message-container,
+ .invite-users-success-message-container {
+ .success-message {
+ color: var(--bg-success-500, #00b37e);
+ }
+ }
+
+ .partially-sent-invites-container {
+ border: 1px solid var(--bg-vanilla-300);
+ background-color: var(--bg-vanilla-100);
+
+ .partially-sent-invites-message {
+ color: var(--bg-warning-500, #fbbd23);
+ }
+ }
+ }
+}
diff --git a/frontend/src/container/OnboardingV2Container/InviteTeamMembers/InviteTeamMembers.tsx b/frontend/src/container/OnboardingV2Container/InviteTeamMembers/InviteTeamMembers.tsx
new file mode 100644
index 0000000000..ba1f95d313
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/InviteTeamMembers/InviteTeamMembers.tsx
@@ -0,0 +1,431 @@
+import './InviteTeamMembers.styles.scss';
+
+import { Color } from '@signozhq/design-tokens';
+import { Button, Input, Select, Typography } from 'antd';
+import logEvent from 'api/common/logEvent';
+import inviteUsers from 'api/user/inviteUsers';
+import { AxiosError } from 'axios';
+import { cloneDeep, debounce, isEmpty } from 'lodash-es';
+import { ArrowRight, CheckCircle, Plus, TriangleAlert, X } from 'lucide-react';
+import { useCallback, useEffect, useState } from 'react';
+import { useMutation } from 'react-query';
+import { SuccessResponse } from 'types/api';
+import {
+ FailedInvite,
+ InviteUsersResponse,
+ SuccessfulInvite,
+} from 'types/api/user/inviteUsers';
+import { v4 as uuid } from 'uuid';
+
+interface TeamMember {
+ email: string;
+ role: string;
+ name: string;
+ frontendBaseUrl: string;
+ id: string;
+}
+
+interface InviteTeamMembersProps {
+ isLoading: boolean;
+ teamMembers: TeamMember[] | null;
+ setTeamMembers: (teamMembers: TeamMember[]) => void;
+ onNext: () => void;
+ onClose: () => void;
+}
+
+const ONBOARDING_V3_ANALYTICS_EVENTS_MAP = {
+ BASE: 'Onboarding V3',
+ INVITE_TEAM_MEMBER_BUTTON_CLICKED: 'Send invites clicked',
+ INVITE_TEAM_MEMBER_SUCCESS: 'Invite team members success',
+ INVITE_TEAM_MEMBER_PARTIAL_SUCCESS: 'Invite team members partial success',
+ INVITE_TEAM_MEMBER_FAILED: 'Invite team members failed',
+};
+
+function InviteTeamMembers({
+ isLoading,
+ teamMembers,
+ setTeamMembers,
+ onNext,
+ onClose,
+}: InviteTeamMembersProps): JSX.Element {
+ const [teamMembersToInvite, setTeamMembersToInvite] = useState<
+ TeamMember[] | null
+ >(teamMembers);
+ const [emailValidity, setEmailValidity] = useState>(
+ {},
+ );
+ const [hasInvalidEmails, setHasInvalidEmails] = useState(false);
+
+ const [hasErrors, setHasErrors] = useState(true);
+
+ const [error, setError] = useState(null);
+
+ const [inviteUsersErrorResponse, setInviteUsersErrorResponse] = useState<
+ string[] | null
+ >(null);
+
+ const [inviteUsersSuccessResponse, setInviteUsersSuccessResponse] = useState<
+ string[] | null
+ >(null);
+
+ const [disableNextButton, setDisableNextButton] = useState(false);
+
+ const defaultTeamMember: TeamMember = {
+ email: '',
+ role: 'EDITOR',
+ name: '',
+ frontendBaseUrl: window.location.origin,
+ id: '',
+ };
+
+ useEffect(() => {
+ if (isEmpty(teamMembers)) {
+ const teamMember = {
+ ...defaultTeamMember,
+ id: uuid(),
+ };
+
+ setTeamMembersToInvite([teamMember]);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [teamMembers]);
+
+ const handleAddTeamMember = (): void => {
+ const newTeamMember = {
+ ...defaultTeamMember,
+ id: uuid(),
+ };
+ setTeamMembersToInvite((prev) => [...(prev || []), newTeamMember]);
+ };
+
+ const handleRemoveTeamMember = (id: string): void => {
+ setTeamMembersToInvite((prev) => (prev || []).filter((m) => m.id !== id));
+ };
+
+ // Validation function to check all users
+ const validateAllUsers = (): boolean => {
+ let isValid = true;
+
+ const updatedValidity: Record = {};
+
+ teamMembersToInvite?.forEach((member) => {
+ const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(member.email);
+ if (!emailValid || !member.email) {
+ isValid = false;
+ setHasInvalidEmails(true);
+ }
+ updatedValidity[member.id!] = emailValid;
+ });
+
+ setEmailValidity(updatedValidity);
+
+ return isValid;
+ };
+
+ const parseInviteUsersSuccessResponse = (
+ response: SuccessfulInvite[],
+ ): string[] => response.map((invite) => `${invite.email} - Invite Sent`);
+
+ const parseInviteUsersErrorResponse = (response: FailedInvite[]): string[] =>
+ response.map((invite) => `${invite.email} - ${invite.error}`);
+
+ const handleError = (error: AxiosError): void => {
+ const errorMessage = error.response?.data as InviteUsersResponse;
+
+ if (errorMessage?.status === 'failure') {
+ setHasErrors(true);
+
+ const failedInvitesErrorResponse = parseInviteUsersErrorResponse(
+ errorMessage.failed_invites,
+ );
+
+ setInviteUsersErrorResponse(failedInvitesErrorResponse);
+ }
+ };
+
+ const handleInviteUsersSuccess = (
+ response: SuccessResponse,
+ ): void => {
+ const inviteUsersResponse = response.payload as InviteUsersResponse;
+
+ if (inviteUsersResponse?.status === 'success') {
+ const successfulInvites = parseInviteUsersSuccessResponse(
+ inviteUsersResponse.successful_invites,
+ );
+
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.INVITE_TEAM_MEMBER_SUCCESS}`,
+ {
+ teamMembers: teamMembersToInvite,
+ successfulInvites,
+ failedInvites: inviteUsersResponse?.failed_invites || [],
+ },
+ );
+
+ setDisableNextButton(true);
+
+ setError(null);
+ setHasErrors(false);
+ setInviteUsersErrorResponse(null);
+
+ setInviteUsersSuccessResponse(successfulInvites);
+
+ setTimeout(() => {
+ setDisableNextButton(false);
+ onNext();
+ }, 1000);
+ } else if (inviteUsersResponse?.status === 'partial_success') {
+ const successfulInvites = parseInviteUsersSuccessResponse(
+ inviteUsersResponse.successful_invites,
+ );
+
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.INVITE_TEAM_MEMBER_PARTIAL_SUCCESS}`,
+ {
+ teamMembers: teamMembersToInvite,
+ successfulInvites,
+ failedInvites: inviteUsersResponse?.failed_invites || [],
+ },
+ );
+
+ setInviteUsersSuccessResponse(successfulInvites);
+
+ if (inviteUsersResponse.failed_invites.length > 0) {
+ setHasErrors(true);
+
+ setInviteUsersErrorResponse(
+ parseInviteUsersErrorResponse(inviteUsersResponse.failed_invites),
+ );
+ }
+ }
+ };
+
+ const { mutate: sendInvites, isLoading: isSendingInvites } = useMutation(
+ inviteUsers,
+ {
+ onSuccess: (response: SuccessResponse): void => {
+ handleInviteUsersSuccess(response);
+ },
+ onError: (error: AxiosError): void => {
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.INVITE_TEAM_MEMBER_FAILED}`,
+ {
+ teamMembers: teamMembersToInvite,
+ error,
+ },
+ );
+
+ handleError(error);
+ },
+ },
+ );
+
+ const handleNext = (): void => {
+ if (validateAllUsers()) {
+ setTeamMembers(teamMembersToInvite || []);
+
+ logEvent(
+ `${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.BASE}: ${ONBOARDING_V3_ANALYTICS_EVENTS_MAP?.INVITE_TEAM_MEMBER_BUTTON_CLICKED}`,
+ {
+ teamMembers: teamMembersToInvite,
+ },
+ );
+
+ setHasInvalidEmails(false);
+ setError(null);
+ setHasErrors(false);
+ setInviteUsersErrorResponse(null);
+ setInviteUsersSuccessResponse(null);
+
+ sendInvites({
+ users: teamMembersToInvite || [],
+ });
+ }
+ };
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ const debouncedValidateEmail = useCallback(
+ debounce((email: string, memberId: string) => {
+ const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
+ setEmailValidity((prev) => ({ ...prev, [memberId]: isValid }));
+ }, 500),
+ [],
+ );
+
+ const handleEmailChange = (
+ e: React.ChangeEvent,
+ member: TeamMember,
+ ): void => {
+ const { value } = e.target;
+ const updatedMembers = cloneDeep(teamMembersToInvite || []);
+
+ const memberToUpdate = updatedMembers.find((m) => m.id === member.id);
+ if (memberToUpdate) {
+ memberToUpdate.email = value;
+ setTeamMembersToInvite(updatedMembers);
+ debouncedValidateEmail(value, member.id!);
+ }
+ };
+
+ const handleRoleChange = (role: string, member: TeamMember): void => {
+ const updatedMembers = cloneDeep(teamMembersToInvite || []);
+ const memberToUpdate = updatedMembers.find((m) => m.id === member.id);
+ if (memberToUpdate) {
+ memberToUpdate.role = role;
+ setTeamMembersToInvite(updatedMembers);
+ }
+ };
+
+ return (
+
+
+
+
+ {teamMembersToInvite?.map((member) => (
+
+ ): void =>
+ handleEmailChange(e, member)
+ }
+ addonAfter={
+ // eslint-disable-next-line no-nested-ternary
+ emailValidity[member.id!] === undefined ? null : emailValidity[
+ member.id!
+ ] ? (
+
+ ) : (
+
+ )
+ }
+ />
+ handleRoleChange(value, member)}
+ className="team-member-role-select"
+ >
+ Viewer
+ Editor
+ Admin
+
+
+ {teamMembersToInvite?.length > 1 && (
+ }
+ onClick={(): void => handleRemoveTeamMember(member.id)}
+ />
+ )}
+
+ ))}
+
+
+
+ }
+ onClick={handleAddTeamMember}
+ >
+ Member
+
+
+
+
+ {hasInvalidEmails && (
+
+
+ Please enter valid emails for all team
+ members
+
+
+ )}
+
+ {error && (
+
+
+ {error}
+
+
+ )}
+
+ {hasErrors && (
+ <>
+ {/* show only when invites are sent successfully & partial error is present */}
+ {inviteUsersSuccessResponse && inviteUsersErrorResponse && (
+
+ {inviteUsersSuccessResponse?.map((success, index) => (
+
+ {success}
+
+ ))}
+
+ )}
+
+
+ {inviteUsersErrorResponse?.map((error, index) => (
+
+ {error}
+
+ ))}
+
+ >
+ )}
+
+
+ {/* Partially sent invites */}
+ {inviteUsersSuccessResponse && inviteUsersErrorResponse && (
+
+
+
+ Some invites were sent successfully. Please fix the errors above and
+ resend invites.
+
+
+
+ You can click on I'll do this later to go to next step.
+
+
+ )}
+
+
+
+
+ Cancel
+
+
+
+ Send Invites
+
+
+
+
+ );
+}
+
+export default InviteTeamMembers;
diff --git a/frontend/src/container/OnboardingV2Container/OnboardingV2.styles.scss b/frontend/src/container/OnboardingV2Container/OnboardingV2.styles.scss
new file mode 100644
index 0000000000..d0df0ca601
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/OnboardingV2.styles.scss
@@ -0,0 +1,1114 @@
+.setup-flow {
+ margin-top: 74px;
+ z-index: 1;
+
+ &__header {
+ background: rgba(11, 12, 14, 0.7);
+ backdrop-filter: blur(20px);
+ padding: 16px 0px 0px 0px;
+
+ &--sticky {
+ display: flex;
+ align-items: center;
+ padding: 0px 1rem;
+ // margin-top: 16px;
+
+ background: rgba(11, 12, 14, 0.7);
+ backdrop-filter: blur(20px);
+ z-index: 2 !important;
+ }
+ }
+
+ &__question-block {
+ position: relative;
+ padding-left: 64px;
+ margin-bottom: 40px;
+ color: #e0e0e0;
+ background-color: #0b0c0e;
+
+ &:before {
+ content: '';
+ position: absolute;
+ left: -5px;
+ top: -5px;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ background-color: var(--Ink-400, #121317);
+ border: 1px solid var(--Greyscale-Slate-400, #1d212d);
+ color: #1e1e1e;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ }
+
+ &:not(:last-child):after {
+ content: '';
+ position: absolute;
+ left: 10px;
+ top: 30px;
+ bottom: -40px;
+ width: 1px;
+ background: linear-gradient(
+ to bottom,
+ #1d212d 0%,
+ #1d212d 50%,
+ transparent 50%,
+ transparent 100%
+ );
+ background-size: 2px 10px;
+ }
+ }
+
+ &__heading {
+ font-size: 24px;
+ margin-bottom: 12px;
+ color: var(--text-vanilla-100);
+ font-weight: 600;
+ }
+
+ &__steps {
+ padding: 1rem 0rem;
+
+ .ant-steps-item-description {
+ max-width: 160px !important;
+ white-space: nowrap !important;
+ overflow: hidden !important;
+ text-overflow: ellipsis !important;
+ }
+ }
+
+ &__description {
+ font-size: 16px;
+ color: var(--text-vanilla-400);
+ margin-bottom: 48px !important;
+ line-height: 1.5;
+ }
+
+ &__search {
+ margin-bottom: 24px !important;
+ }
+
+ &__radio-label {
+ display: flex;
+ cursor: pointer;
+ white-space: nowrap;
+ }
+
+ &__radio-input {
+ display: none;
+ }
+
+ &__radio-custom {
+ padding: 10px 20px;
+ background-color: #2a2a2a;
+ color: var(--text-vanilla-400);
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 22px; /* 137.5% */
+ transition: all 0.3s ease;
+ border-radius: 4px;
+ background: var(--Ink-400, #121317);
+ cursor: pointer;
+ box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.19);
+
+ &:hover {
+ background: var(--bg-robin-500);
+ box-shadow: 0 4px 8px rgba(58, 134, 255, 0.2);
+ }
+
+ &__text {
+ color: var(--text-vanilla-400);
+ }
+
+ &--selected {
+ background: var(--bg-robin-500);
+ border-color: var(--bg-robin-500);
+ color: #fff;
+ box-shadow: 0 4px 10px rgba(58, 134, 255, 0.4);
+ }
+
+ &--animating {
+ animation: selectPulse 0.6s cubic-bezier(0.19, 1, 0.22, 1);
+ }
+ }
+
+ &__category {
+ width: 100%;
+ color: var(--greyscale-vanilla-opacity-40060, rgba(192, 193, 195, 0.6));
+ font-family: Inter;
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 22px; /* 169.231% */
+ letter-spacing: 0.52px;
+ text-transform: uppercase;
+ display: flex;
+ }
+
+ &__content-container {
+ display: flex;
+ }
+
+ &__category-filter {
+ margin-left: 20px;
+ }
+
+ &__category-filter-item {
+ cursor: pointer;
+ padding: 5px 10px;
+ margin-bottom: 5px;
+ border-radius: 4px;
+ color: #c0c1c399;
+
+ &--selected {
+ color: var(--Vanilla-100, #fff);
+ }
+ }
+
+ @media (max-width: 600px) {
+ &__question-block {
+ padding-left: 30px;
+ }
+
+ &__heading {
+ font-size: 20px;
+ }
+
+ &__description {
+ color: var(--Vanilla-400, var(--Greyscale-Vanilla-400, #c0c1c3));
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 24px; /* 150% */
+ }
+
+ &__radio-custom {
+ padding: 8px 16px;
+ font-size: 14px;
+ }
+ }
+}
+
+.background-effect {
+ position: absolute;
+ top: -300px;
+ left: -300px;
+ width: 600px;
+ height: 600px;
+ border-radius: 956px;
+ opacity: 0.08;
+ background: linear-gradient(
+ 180deg,
+ rgba(190, 107, 241, 0.9) 69.5%,
+ rgba(109, 85, 255, 0.9) 86.5%,
+ rgba(69, 104, 220, 0) 100%
+ );
+ box-shadow: 0px 10px 660px 5281px rgba(0, 0, 0, 0.25);
+ filter: blur(158px);
+ z-index: -1;
+}
+
+.left-content {
+ flex: 0 0 70%;
+ max-width: 70%;
+}
+
+.question-block {
+ position: relative;
+ padding-left: 36px;
+ margin-bottom: 40px;
+ color: var(--text-vanilla-100);
+ background-color: var(--bg-ink-500);
+
+ &:before {
+ content: '';
+ position: absolute;
+ left: -18px;
+ top: 16px;
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ background-color: var(--bg-ink-400);
+ border: 1px solid var(--bg-slate-400);
+ color: var(--bg-ink-400);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ }
+
+ &.answered {
+ &:before {
+ background-color: rgba(78, 116, 248, 0.1);
+ content: '✓';
+ color: var(--bg-robin-500);
+ font-size: 16px;
+ font-weight: 300;
+ }
+ }
+
+ &:after {
+ content: '';
+ position: absolute;
+ left: -3px;
+ top: 50px;
+ bottom: -120px;
+ width: 1px;
+ background: linear-gradient(
+ to bottom,
+ var(--bg-slate-400) 0%,
+ var(--bg-slate-400) 50%,
+ transparent 50%,
+ transparent 100%
+ );
+ background-size: 2px 10px;
+ }
+}
+
+.right-content {
+ flex: 1;
+ max-width: 30%;
+}
+
+@keyframes selectPulse {
+ 0% {
+ background-color: var(--bg-ink-400);
+ border-color: var(--bg-robin-500);
+ }
+ 20% {
+ background-color: rgba(58, 134, 255, 0.5);
+ border-color: var(--bg-robin-500);
+ }
+ 40% {
+ background-color: var(--bg-ink-400);
+ border-color: var(--bg-robin-500);
+ }
+ 60% {
+ background-color: rgba(58, 134, 255, 0.8);
+ border-color: var(--bg-robin-500);
+ }
+ 100% {
+ background-color: var(--bg-robin-500);
+ border-color: var(--bg-robin-500);
+ }
+}
+
+.onboarding-v2 {
+ margin: 0px -1rem;
+
+ .onboarding-header-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ padding: 0px 1rem;
+
+ .header-left-section {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ .onboarding-header-container-close-icon {
+ cursor: pointer;
+ }
+ }
+
+ .header-right-section {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+ }
+
+ .get-help-btn {
+ font-size: 11px;
+ padding: 6px 16px;
+ border: 1px solid var(--bg-slate-400) !important;
+ color: var(--bg-vanilla-400) !important;
+
+ &:focus-visible {
+ outline: none !important;
+ outline-offset: 0px !important;
+ }
+
+ &.rounded-btn {
+ border-radius: 50px;
+ }
+
+ &:hover {
+ border: 1px solid var(--bg-robin-500) !important;
+ color: var(--text-vanilla-100) !important;
+ }
+
+ &.primary {
+ background: var(--bg-robin-500);
+ color: var(--text-vanilla-200) !important;
+ border: none !important;
+
+ &:hover {
+ color: var(--text-vanilla-100) !important;
+ }
+ }
+
+ &.outlined {
+ border: none !important;
+ color: var(--text-vanilla-400) !important;
+
+ &:hover {
+ color: var(--text-robin-400) !important;
+ }
+ }
+
+ &.full-width {
+ width: 100%;
+ }
+ }
+}
+
+.skeleton-container {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+
+ .skeleton-input {
+ width: 100% !important;
+ display: block !important;
+ height: 18px !important;
+ }
+}
+
+.onboarding-title,
+.onboarding-filters-title,
+.onboarding-filters-item-title {
+ color: var(
+ --greyscale-vanilla-opacity-40060,
+ rgba(192, 193, 195, 0.6)
+ ) !important;
+
+ font-size: 11px !important;
+ font-style: normal !important;
+ font-weight: 500 !important;
+ line-height: 22px !important; /* 169.231% */
+ letter-spacing: 0.52px !important;
+ text-transform: uppercase !important;
+
+ cursor: pointer;
+
+ &.selected {
+ color: var(--bg-vanilla-100) !important;
+ }
+}
+
+.onboarding-filters-title {
+ margin-top: 12px !important;
+ margin-bottom: 24px !important;
+}
+
+.onboarding-filters-item-title {
+ margin: 0px !important;
+ margin-bottom: 8px !important;
+
+ &:hover {
+ color: var(--bg-robin-500) !important;
+ }
+}
+
+.onboarding-text {
+ margin-bottom: 0;
+ font-size: 14px;
+ color: var(--text-vanilla-400);
+}
+
+.onboarding-data-source-group {
+ margin-bottom: 48px;
+}
+
+.onboarding-data-source-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ margin-top: 8px;
+}
+
+.onboarding-data-source-button {
+ font-size: 13px;
+ color: var(--text-vanilla-100);
+ padding: 10px 20px;
+ height: 40px;
+ min-width: 150px;
+ border-radius: 4px;
+ background: var(--bg-ink-400);
+ box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.19);
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+
+ &:hover {
+ border: 1px solid var(--bg-robin-500) !important;
+ color: var(--text-robin-500) !important;
+ background: var(--bg-ink-400) !important;
+ box-shadow: 0 4px 8px rgba(58, 134, 255, 0.2);
+ }
+
+ &:active {
+ border: 1px solid var(--bg-robin-500) !important;
+ color: var(--text-robin-500) !important;
+ background: var(--bg-ink-400) !important;
+ box-shadow: 0 4px 8px rgba(58, 134, 255, 0.2);
+ }
+
+ &:focus {
+ border: 1px solid var(--bg-robin-500) !important;
+ color: var(--text-robin-500) !important;
+ box-shadow: 0 4px 8px rgba(58, 134, 255, 0.2);
+ background: var(--bg-ink-400) !important;
+ }
+
+ &.selected {
+ border: 1px solid var(--bg-robin-500) !important;
+
+ color: var(--text-robin-500) !important;
+ box-shadow: 0 4px 8px rgba(58, 134, 255, 0.2);
+ background: var(--bg-ink-400) !important;
+ }
+}
+
+.question-2,
+.question-3,
+.question-4 {
+ // padding-top: 64px;
+ // padding-bottom: 24px;
+ scroll-snap-align: start;
+}
+
+.question-2 {
+ height: 80vh;
+}
+
+.question-3 {
+ height: 80vh;
+}
+
+.full-viewport-height {
+ height: 100vh;
+}
+
+.questionaire-footer {
+ padding: 12px;
+ position: sticky;
+ bottom: 0;
+ margin-left: -36px;
+ padding-left: 64px;
+ background-color: var(--bg-ink-500);
+}
+
+.onboarding-configure-product-description {
+ background-color: var(--bg-slate-500);
+ border-radius: 8px;
+ padding: 12px 24px;
+
+ margin-bottom: 24px;
+}
+
+.onboarding-data-source-search {
+ margin-top: 12px;
+ margin-bottom: 24px;
+
+ .ant-input {
+ background: var(--bg-ink-400);
+ border: 1px solid var(--bg-slate-400);
+ height: 40px;
+ }
+}
+
+.onboarding-data-source-options {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 8px;
+}
+
+.onboarding-footer {
+ display: flex;
+ gap: 16px;
+ margin-bottom: 16px;
+
+ .ant-btn {
+ width: 120px;
+ }
+}
+
+.onboarding-data-source-step-container {
+ display: flex;
+ gap: 32px;
+ padding: 0px 1rem;
+}
+
+.onboarding-add-data-source-container {
+ display: flex;
+ gap: 16px;
+ box-sizing: border-box;
+ padding: 0px 1rem;
+ z-index: 1;
+ width: 100%;
+
+ .onboarding-data-sources-container {
+ width: 100%;
+ }
+
+ &.step-2 {
+ flex: 0 0 100%;
+ max-width: 100%;
+ }
+
+ .onboarding-question-header {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ width: 70%;
+ }
+
+ .question-title-container {
+ margin-bottom: 24px;
+ }
+
+ .onboarding-question {
+ color: var(--text-vanilla-100);
+ font-family: Inter;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 32px; /* 133.333% */
+ }
+
+ .question-title {
+ color: var(--text-vanilla-100);
+ font-family: Inter;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 32px; /* 133.333% */
+ padding-top: 18px;
+ }
+
+ .question-sub-title {
+ color: var(--text-vanilla-400);
+ font-family: Inter;
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 24px; /* 150% */
+ }
+
+ .data-sources-and-filters-container {
+ margin-top: 48px;
+ display: flex;
+
+ .data-sources-container {
+ flex: 0 0 70%;
+ max-width: 70%;
+
+ margin-right: 32px;
+ }
+
+ .data-source-categories-filter-container {
+ flex: 0 0 30%;
+ max-width: 30%;
+ }
+ }
+
+ .invite-user-section-content {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ }
+}
+
+.onboarding-product-setup-container {
+ display: flex;
+ padding: 0px 1rem;
+ gap: 8px;
+ box-sizing: border-box;
+ position: relative;
+
+ &_left-section {
+ position: relative;
+
+ flex: 0 0 70%;
+ max-width: 70%;
+
+ display: flex;
+ gap: 24px;
+
+ // border-right: 1px solid var(--Greyscale-Slate-400, #1d212d);
+
+ .perlian-bg {
+ background: radial-gradient(
+ circle,
+ var(--text-vanilla-400) 10%,
+ transparent 0
+ );
+ background-size: 12px 12px;
+ opacity: 1;
+ -webkit-mask-image: radial-gradient(
+ circle at 50% 0,
+ rgba(11, 12, 14, 0.1) 0,
+ rgba(11, 12, 14, 0) 56.77%
+ );
+
+ position: absolute;
+ top: -36px;
+ left: -16px;
+ width: 100%;
+ height: 100%;
+ }
+
+ .ant-btn-default {
+ border: none !important;
+ box-shadow: none;
+ background: var(--greyscale-zinc-opacity-zinc-8, rgba(171, 189, 255, 0.08));
+ }
+ }
+
+ &_right-section {
+ flex: 1;
+ max-width: 30%;
+ height: calc(100vh - 120px);
+
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+
+ position: sticky; /* Keeps the right column in view as you scroll */
+ top: 0; /* Sticky positioning starts at the top */
+ padding: 20px;
+ overflow-y: auto; /* Adds scrollability if content exceeds the set height */
+
+ .invite-user-section-content {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+
+ .ant-btn {
+ border: none !important;
+ box-shadow: none;
+ border-radius: var(--Radii-radius-round, 9999px);
+ background: var(--greyscale-zinc-opacity-zinc-8, rgba(171, 189, 255, 0.08));
+ width: 100%;
+ }
+
+ .need-help-section-content-divider {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+
+ color: var(--text-vanilla-400);
+ }
+
+ .invite-user-section-content-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ white-space: normal;
+ height: auto !important;
+ gap: 8px;
+ }
+ }
+
+ .need-help-section-content {
+ display: flex;
+ padding: 12px 16px;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 24px;
+ align-self: stretch;
+
+ border-radius: 6px;
+ background: rgba(78, 116, 248, 0.1);
+
+ .ant-typography {
+ color: var(--bg-robin-500);
+ }
+ }
+
+ .configure-product-ingestion-section-content {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+
+ .ingestion-endpoint-section {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 8px;
+ align-self: stretch;
+
+ background: var(--bg-ink-400);
+ box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.03) inset;
+ border: 1px solid var(--bg-ink-300);
+ border-radius: 4px;
+
+ .ingestion-endpoint-section-header {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ background-color: var(--bg-ink-500);
+
+ .ingestion-endpoint-copy-download-section {
+ padding: 0 8px;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+
+ .ant-typography {
+ display: contents;
+ }
+
+ .download-btn,
+ .copy-btn {
+ cursor: pointer;
+ margin: 4px;
+
+ &:hover {
+ color: var(--bg-robin-500);
+ }
+ }
+ }
+ }
+
+ .ingestion-endpoint-info-section {
+ padding: 16px;
+ background-color: var(--bg-ink-400);
+
+ width: 100%;
+
+ .ingestion-endpoint-section-text {
+ margin-bottom: 16px;
+
+ font-family: Inter;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 24px; /* 150% */
+ }
+ }
+
+ .ingestion-endpoint-section-title {
+ width: 120px;
+ height: 100%;
+ padding: 8px;
+ background-color: var(--bg-ink-400);
+
+ .ant-typography {
+ padding: 0 16px;
+ }
+ }
+
+ .ingestion-endpoint-details-section {
+ margin-top: 12px;
+
+ .ant-typography {
+ color: var(--text-vanilla-100);
+ font-family: 'Geist Mono';
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 300;
+ line-height: 24px; /* 171.429% */
+ }
+ }
+ }
+
+ .ingestion-key-details-section {
+ display: flex;
+ padding: 16px;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ gap: 24px;
+ align-self: stretch;
+
+ border-radius: 6px;
+ background: rgba(78, 116, 248, 0.1);
+
+ .ingestion-key-details-section-text {
+ &.ant-typography {
+ color: var(--bg-robin-400);
+ font-family: Inter;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 24px; /* 171.429% */
+ }
+ }
+
+ .ingestion-key-details-section-key {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+
+ .ingestion-key-label,
+ .ingestion-region-label {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .ingestion-key-value-copy {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ &.ant-typography {
+ color: var(--bg-robin-400);
+ font-family: Inter;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 24px; /* 171.429% */
+ }
+
+ .copy-btn {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .ingestion-key-region-details-section {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 8px;
+ width: 100%;
+
+ .ingestion-region-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+
+ .ingestion-region-value-copy {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ &.ant-typography {
+ color: var(--bg-robin-400);
+ font-family: Inter;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 24px; /* 171.429% */
+ }
+
+ .copy-btn {
+ cursor: pointer;
+ }
+ }
+ }
+
+ .ingestion-key-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+
+ .ingestion-key-value-copy {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ &.ant-typography {
+ color: var(--bg-robin-400);
+ font-family: Inter;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 24px; /* 171.429% */
+ }
+
+ .copy-btn {
+ cursor: pointer;
+ }
+ }
+ }
+ }
+ }
+
+ .ingestion-endpoint-section-error-container {
+ display: flex;
+ padding: 16px;
+ flex-direction: column;
+ justify-content: center;
+ align-items: flex-start;
+ gap: 24px;
+ align-self: stretch;
+
+ border-radius: 6px;
+ background: var(--bg-ink-300);
+
+ border: none !important;
+
+ .ingestion-endpoint-section-error-text {
+ color: var(--bg-cherry-500);
+
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+ }
+ }
+
+ .need-help-section-content-buttons {
+ display: flex;
+ gap: 16px;
+ }
+ }
+}
+
+.onboarding-data-source-category-container {
+ flex: 1;
+ max-width: 30%;
+ margin-top: 32px;
+
+ .onboarding-data-source-category-item {
+ margin-bottom: 8px;
+
+ .ant-typography {
+ margin-top: 0;
+ font-size: 11px !important;
+ font-weight: 400 !important;
+ color: var(--text-vanilla-400);
+ }
+ }
+}
+
+.onboarding-configure-product-container {
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+}
+
+.onboarding-configure-container {
+ height: calc(100vh - 120px);
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ overflow: auto;
+ z-index: 1;
+
+ .configure-product-docs-section {
+ height: 100%;
+ border: 1px solid var(--bg-ink-400);
+ border-radius: 5px;
+ padding: 12px;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ position: relative;
+
+ .loading-container {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ width: 50%;
+ height: 100%;
+ transform: translateX(-50%);
+
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+
+ justify-content: center;
+ align-items: center;
+ color: white;
+
+ .loading-text {
+ color: var(--text-vanilla-400);
+ font-size: 11px;
+ font-weight: 300;
+ }
+ }
+
+ .ant-typography {
+ margin-bottom: 0;
+ }
+
+ .configure-product-docs-section-iframe {
+ width: 100%;
+ height: 100%;
+ border: none;
+ z-index: 1;
+ }
+ }
+
+ .configure-product-ingestion-section {
+ flex: 1;
+ max-width: 40%;
+
+ .configure-product-ingestion-section-content {
+ height: 100%;
+ overflow: auto;
+ background-color: var(--bg-slate-500);
+ padding: 12px 24px;
+ border-radius: 8px;
+ }
+ }
+}
+
+.onboarding-data-source-button-img {
+ width: 18px;
+ height: 18px;
+}
+
+.invite-team-member-modal {
+ .ant-modal-content {
+ background-color: var(--bg-ink-500);
+ }
+
+ .ant-modal-title {
+ background-color: var(--bg-ink-500);
+ }
+
+ .invite-team-member-modal-content {
+ background-color: var(--bg-ink-500);
+ }
+}
+
+.ingestion-setup-details-links {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 24px;
+ border-radius: 4px;
+ color: var(--bg-robin-300);
+
+ .learn-more {
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ text-decoration: underline;
+
+ color: var(--bg-robin-300);
+ }
+}
+
+.lightMode {
+ .ingestion-setup-details-links {
+ background: var(--bg-vanilla-100);
+ color: var(--bg-robin-500);
+
+ .learn-more {
+ color: var(--bg-robin-500);
+ }
+ }
+}
diff --git a/frontend/src/container/OnboardingV2Container/QuestionBlock/QuestionBlock.tsx b/frontend/src/container/OnboardingV2Container/QuestionBlock/QuestionBlock.tsx
new file mode 100644
index 0000000000..d684d496b6
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/QuestionBlock/QuestionBlock.tsx
@@ -0,0 +1,174 @@
+import { SearchOutlined } from '@ant-design/icons';
+import { Avatar, Button, Flex, Input, Typography } from 'antd';
+import React, { useState } from 'react';
+
+import { Question } from '../AddDataSource/AddDataSource'; // Adjust the import path as necessary
+
+const { Title, Paragraph, Text } = Typography;
+
+interface QuestionBlockProps {
+ item: Question;
+ index: number;
+ currentQuestion: number;
+ answers: string[];
+ handleOptionChange: (questionIndex: number, option: string) => void;
+ animatingOption: string;
+ searchQuery: string;
+ handleSearch: (e: React.ChangeEvent) => void;
+ questionRefs: React.MutableRefObject<(HTMLDivElement | null)[]>;
+}
+
+function QuestionBlock({
+ item,
+ index,
+ currentQuestion,
+ answers,
+ handleOptionChange,
+ animatingOption,
+ searchQuery,
+ handleSearch,
+ questionRefs,
+}: QuestionBlockProps): JSX.Element {
+ const [selectedCategory, setSelectedCategory] = useState('All');
+
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
+ const handleCategoryClick = (category: string): void => {
+ setSelectedCategory(category);
+ };
+
+ const filteredGroups = item.options.filter(
+ (group) => selectedCategory === 'All' || group.category === selectedCategory,
+ );
+
+ return (
+ {
+ // eslint-disable-next-line no-param-reassign
+ questionRefs.current[index] = el;
+ }}
+ >
+
+ {item.title}
+
+
{item.description}
+
+
+
+
+ {item.uiConfig?.filterByCategory && (
+
+ handleCategoryClick('All')}
+ >
+ All ({item.options.reduce((acc, group) => acc + group.items.length, 0)})
+
+ {item.options.map((group) => (
+ handleCategoryClick(group.category)}
+ >
+ {group.category} ({group.items.length})
+
+ ))}
+
+ )}
+
+
+
+ );
+}
+
+export default QuestionBlock;
diff --git a/frontend/src/container/OnboardingV2Container/onboarding-configs/onboarding-config-with-links.json b/frontend/src/container/OnboardingV2Container/onboarding-configs/onboarding-config-with-links.json
new file mode 100644
index 0000000000..a3ef6027f8
--- /dev/null
+++ b/frontend/src/container/OnboardingV2Container/onboarding-configs/onboarding-config-with-links.json
@@ -0,0 +1,1404 @@
+[
+ {
+ "dataSource": "java",
+ "entityID": "dataSource",
+ "label": "Java",
+ "id": "java",
+ "imgUrl": "/Logos/java.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "question": {
+ "desc": "Which Java framework do you use?",
+ "type": "select",
+ "entityID": "framework",
+ "options": [
+ {
+ "key": "springboot",
+ "label": "Spring Boot",
+ "imgUrl": "/Logos/springboot.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-springboot/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-springboot/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-springboot/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-springboot/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "tomcat",
+ "label": "Tomcat",
+ "imgUrl": "/Logos/tomcat.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-tomcat/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-tomcat/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-tomcat/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-tomcat/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "jboss",
+ "label": "JBoss",
+ "imgUrl": "/Logos/jboss.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-jboss/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-jboss/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-jboss/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-jboss/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "Others",
+ "label": "Others",
+ "imgUrl": "/Logos/java-others.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-java/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-java/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-java/"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "python",
+ "label": "Python",
+ "imgUrl": "/Logos/python.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "python",
+ "question": {
+ "desc": "Which Python framework do you use?",
+ "type": "select",
+ "entityID": "framework",
+ "options": [
+ {
+ "key": "flask",
+ "label": "Flask",
+ "imgUrl": "/Logos/flask.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-flask/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-flask/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-flask/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "django",
+ "label": "Django",
+ "imgUrl": "/Logos/django.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-django/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-django/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-django/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "fastapi",
+ "label": "FastAPI",
+ "imgUrl": "/Logos/fastapi.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-fastapi/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-fastapi/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-fastapi/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "falcon",
+ "label": "Falcon",
+ "imgUrl": "/Logos/falcon.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-falcon/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-falcon/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-falcon/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "others",
+ "label": "Others",
+ "imgUrl": "/Logos/python-others.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-python/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-python/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-python/"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "javascript",
+ "label": "JavaScript",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "javascript",
+ "imgUrl": "/Logos/javascript.svg",
+ "question": {
+ "desc": "Which JavaScript framework do you use?",
+ "type": "select",
+ "entityID": "framework",
+ "options": [
+ {
+ "key": "nodejs",
+ "label": "NodeJs",
+ "imgUrl": "/Logos/nodejs.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-javascript/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-javascript/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-javascript/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-javascript/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "express",
+ "label": "Express",
+ "imgUrl": "/Logos/express.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-express/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-express/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-express/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-express/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "nestjs",
+ "label": "NestJS",
+ "imgUrl": "/Logos/nestjs.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nestjs/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nestjs/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nestjs/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nestjs/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "angular",
+ "label": "Angular",
+ "imgUrl": "/Logos/angular.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-angular/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-angular/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-angular/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-angular/"
+ }
+ ]
+ }
+ },
+ {
+ "key": "nextjs",
+ "label": "NextJS",
+ "imgUrl": "/Logos/nextjs.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nextjs/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nextjs/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nextjs/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-nextjs/"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "golang",
+ "label": "Golang",
+ "imgUrl": "/Logos/go.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "golang",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-golang/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-golang/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-golang/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-golang/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "php",
+ "label": "PHP",
+ "imgUrl": "/Logos/php.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "php",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-php/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-php/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-php/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-php/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "dotnet",
+ "label": ".NET",
+ "imgUrl": "/Logos/dotnet.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "dotnet",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-dotnet/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-dotnet/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-dotnet/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-dotnet/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "ruby-on-rails",
+ "label": "Ruby on Rails",
+ "imgUrl": "/Logos/ruby-on-rails.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "ruby-on-rails",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-ruby-on-rails/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-ruby-on-rails/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-ruby-on-rails/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-ruby-on-rails/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "elixir",
+ "label": "Elixir",
+ "imgUrl": "/Logos/elixir.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "elixir",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-elixir/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-elixir/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-elixir/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-elixir/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "rust",
+ "label": "Rust",
+ "imgUrl": "/Logos/rust.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "rust",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-rust/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-rust/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-rust/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-rust/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "swift",
+ "label": "Swift",
+ "imgUrl": "/Logos/swift.svg",
+ "tags": ["apm"],
+ "module": "apm",
+ "id": "swift",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-swift/",
+ "question": {
+ "desc": "What is your Environment?",
+ "type": "select",
+ "entityID": "environment",
+ "options": [
+ {
+ "key": "vm",
+ "label": "VM",
+ "imgUrl": "/Logos/vm.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-swift/"
+ },
+ {
+ "key": "k8s",
+ "label": "Kubernetes",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-swift/"
+ },
+ {
+ "key": "windows",
+ "label": "Windows",
+ "imgUrl": "/Logos/windows.svg",
+ "link": "https://signoz.io/docs/instrumentation/opentelemetry-swift/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "kubernetes-pod-logs",
+ "label": "Kubernetes Pod Logs",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "id": "kubernetes-pod-logs",
+ "link": "https://signoz.io/docs/userguide/collect_kubernetes_pod_logs/"
+ },
+ {
+ "dataSource": "docker-container-logs",
+ "label": "Docker Container Logs",
+ "imgUrl": "/Logos/docker.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/collect_docker_logs/"
+ },
+ {
+ "dataSource": "vercel-logs",
+ "label": "Vercel logs",
+ "imgUrl": "/Logos/vercel.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/vercel_logs_to_signoz/"
+ },
+ {
+ "dataSource": "heroku-logs",
+ "label": "Heroku logs",
+ "imgUrl": "/Logos/heroku.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/heroku_logs_to_signoz/"
+ },
+ {
+ "dataSource": "http-logs",
+ "label": "HTTP logs",
+ "imgUrl": "/Logos/http.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/send-logs-http/"
+ },
+ {
+ "dataSource": "syslogs",
+ "label": "Syslogs",
+ "imgUrl": "/Logos/syslogs.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/collecting_syslogs/"
+ },
+ {
+ "dataSource": "fluentd",
+ "label": "FluentD",
+ "imgUrl": "/Logos/fluentd.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/fluentd_to_signoz/"
+ },
+ {
+ "dataSource": "fluentbit",
+ "label": "FluentBit",
+ "imgUrl": "/Logos/fluentbit.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/fluentbit_to_signoz/"
+ },
+ {
+ "dataSource": "logstash",
+ "label": "Logstash",
+ "imgUrl": "/Logos/logstash.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/logstash_to_signoz/"
+ },
+ {
+ "dataSource": "tomcat-logs",
+ "label": "Tomcat logs",
+ "imgUrl": "/Logos/tomcat-logs.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/logs-management/send-logs/collect-tomcat-access-and-garbage-collector-logs/"
+ },
+ {
+ "dataSource": "vector-logs",
+ "label": "Vector Logs",
+ "imgUrl": "/Logos/vector.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/logs-management/send-logs/vector-logs-to-signoz/"
+ },
+ {
+ "dataSource": "windows-events-logs",
+ "label": "Windows Events logs",
+ "imgUrl": "/Logos/windows-events-logs.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/logs-management/send-logs/windows-events-log/"
+ },
+ {
+ "dataSource": "cloudwatch-logs",
+ "label": "Cloudwatch logs",
+ "imgUrl": "/Logos/cloudwatch-logs.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "link": "https://signoz.io/docs/userguide/send-cloudwatch-logs-to-signoz/"
+ },
+ {
+ "dataSource": "application-logs",
+ "label": "Application Logs",
+ "imgUrl": "/Logos/application-logs.svg",
+ "tags": ["logs"],
+ "module": "logs",
+ "question": {
+ "desc": "Where do you want to collect your application logs from?",
+ "type": "select",
+ "options": [
+ {
+ "key": "from-log-file",
+ "label": "From log file",
+ "imgUrl": "/Logos/from-log-file.svg",
+ "link": "https://signoz.io/docs/userguide/collect_logs_from_file/"
+ },
+ {
+ "key": "aws-lambda-nodejs-logs",
+ "label": "AWS Lambda NodeJS logs",
+ "imgUrl": "/Logos/lambda.svg",
+ "link": "https://signoz.io/docs/logs-management/send-logs/aws-lambda-nodejs/"
+ },
+ {
+ "key": "otel-python-sdk",
+ "label": "OTel Python SDK",
+ "imgUrl": "/Logos/python.svg",
+ "link": "https://signoz.io/docs/userguide/collecting_application_logs_otel_sdk_python/"
+ },
+ {
+ "key": "otel-java-sdk",
+ "label": "OTel Java SDK",
+ "imgUrl": "/Logos/java.svg",
+ "link": "https://signoz.io/docs/userguide/collecting_application_logs_otel_sdk_java/"
+ },
+ {
+ "key": "python-logs-auto-instrumentation",
+ "label": "Python logs auto-instrumentation",
+ "imgUrl": "/Logos/python.svg",
+ "link": "https://signoz.io/docs/userguide/python-logs-auto-instrumentation/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "kubernetes-infra-metrics",
+ "label": "Kuberenetes Infra Metrics",
+ "tags": ["infrastructure monitoring"],
+ "module": "metrics",
+ "imgUrl": "/Logos/kubernetes.svg",
+ "link": "https://signoz.io/docs/tutorial/kubernetes-infra-metrics/"
+ },
+ {
+ "dataSource": "hostmetrics",
+ "label": "Hostmetrics",
+ "tags": ["infrastructure monitoring"],
+ "module": "metrics",
+ "imgUrl": "/Logos/hostmetrics.svg",
+ "link": "https://signoz.io/docs/userguide/hostmetrics/"
+ },
+ {
+ "dataSource": "ec2-application-logs",
+ "label": "EC2 Application Logs",
+ "tags": ["AWS", "logs"],
+ "module": "logs",
+ "imgUrl": "/Logos/ec2.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/ec2-logs/"
+ },
+ {
+ "dataSource": "ec2-infrastructure-metrics",
+ "label": "EC2 Infra Metrics",
+ "tags": ["AWS"],
+ "module": "metrics",
+ "imgUrl": "/Logos/ec2.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/ec2-infra-metrics/"
+ },
+ {
+ "dataSource": "ecs-ec2",
+ "label": "ECS EC2",
+ "tags": ["AWS"],
+ "module": "metrics",
+ "imgUrl": "/Logos/ecs.svg",
+ "link": "https://signoz.io/docs/userguide/collecting-ecs-logs-and-metrics/"
+ },
+ {
+ "dataSource": "ecs-external",
+ "label": "ECS External",
+ "tags": ["AWS"],
+ "module": "metrics",
+ "imgUrl": "/Logos/ecs.svg",
+ "link": "https://signoz.io/docs/userguide/collecting-ecs-logs-and-metrics/"
+ },
+ {
+ "dataSource": "ecs-fargate",
+ "label": "ECS Fargate",
+ "tags": ["AWS"],
+ "module": "metrics",
+ "imgUrl": "/Logos/ecs.svg",
+ "link": "https://signoz.io/docs/userguide/collecting-ecs-sidecar-infra/"
+ },
+ {
+ "dataSource": "eks",
+ "label": "EKS",
+ "tags": ["AWS", "logs"],
+ "module": "logs",
+ "imgUrl": "/Logos/eks.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/eks/"
+ },
+ {
+ "dataSource": "elb-logs",
+ "label": "ELB Logs",
+ "tags": ["AWS", "logs"],
+ "module": "logs",
+ "imgUrl": "/Logos/elb.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/elb-logs/"
+ },
+ {
+ "dataSource": "vpc-logs",
+ "label": "VPC Logs",
+ "tags": ["AWS", "logs"],
+ "module": "logs",
+ "imgUrl": "/Logos/vpc.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/vpc-logs/"
+ },
+ {
+ "dataSource": "rds-logs",
+ "label": "RDS Logs",
+ "tags": ["AWS", "logs"],
+ "module": "logs",
+ "imgUrl": "/Logos/rds.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/rds-logs/"
+ },
+ {
+ "dataSource": "aws-lambda",
+ "label": "Lambda Logs",
+ "tags": ["AWS", "logs"],
+ "module": "logs",
+ "imgUrl": "/Logos/lambda.svg",
+ "link": "https://signoz.io/docs/aws-monitoring/lambda-logs/"
+ },
+ {
+ "dataSource": "vm-metrics-and-logging",
+ "label": "Azure VM",
+ "tags": ["Azure"],
+ "module": "apm",
+ "imgUrl": "/Logos/azure-vm.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/virtual-machines/vm-metrics/"
+ },
+ {
+ "dataSource": "app-service",
+ "label": "App Service",
+ "imgUrl": "/Logos/azure-vm.svg",
+ "tags": ["Azure"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/azure-vm.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/app-service/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/azure-vm.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/app-service/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/azure-vm.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/app-service/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "aks",
+ "label": "Azure Kubernetes Service",
+ "tags": ["Azure"],
+ "module": "apm",
+ "imgUrl": "/Logos/azure-app-service.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/aks/"
+ },
+ {
+ "dataSource": "azure-container-apps",
+ "label": "Container Apps",
+ "imgUrl": "/Logos/azure-container-apps.svg",
+ "tags": ["Azure"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/azure-container-apps.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-container-apps/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/azure-container-apps.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-container-apps/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/azure-container-apps.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-container-apps/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "azure-functions",
+ "label": "Azure Functions",
+ "imgUrl": "/Logos/azure-functions.svg",
+ "tags": ["Azure"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/azure-functions.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-fns/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/azure-functions.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-fns/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/azure-functions.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-fns/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "sql-database-metrics",
+ "label": "Azure SQL Database Metrics",
+ "tags": ["Azure"],
+ "module": "metrics",
+ "imgUrl": "/Logos/azure-sql-database-metrics.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/db-metrics/"
+ },
+ {
+ "dataSource": "azure-blob-storage",
+ "label": "Azure Blob storage",
+ "imgUrl": "/Logos/azure-blob-storage.svg",
+ "tags": ["Azure"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/azure-blob-storage.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-blob-storage/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/azure-blob-storage.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-blob-storage/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/azure-blob-storage.svg",
+ "link": "https://signoz.io/docs/azure-monitoring/az-blob-storage/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "cloud-functions",
+ "label": "Cloud functions",
+ "imgUrl": "/Logos/gcp-cloud-functions.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-cloud-functions.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcp-fns/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Cloud Function Metrics",
+ "imgUrl": "/Logos/gcp-cloud-functions.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcp-fns/fns-metrics/"
+ },
+ {
+ "key": "metrics",
+ "label": "Custom Metrics",
+ "imgUrl": "/Logos/gcp-cloud-functions.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcp-fns/custom-metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/gcp-cloud-functions.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcp-fns/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "app-engine",
+ "label": "App Engine",
+ "imgUrl": "/Logos/gcp-app-engine.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-app-engine.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/app-engine/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-app-engine.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/app-engine/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/gcp-app-engine.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/app-engine/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "compute-engine",
+ "label": "Compute Engine",
+ "imgUrl": "/Logos/gcp-compute-engine.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-compute-engine.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/compute-engine/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-compute-engine.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/compute-engine/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/gcp-compute-engine.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/compute-engine/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "cloud-storage",
+ "label": "Cloud Storage",
+ "imgUrl": "/Logos/gcp-cloud-storage.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-cloud-storage.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcs/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-cloud-storage.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcs/metrics/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "cloud-sql",
+ "label": "Cloud SQL",
+ "imgUrl": "/Logos/gcp-cloud-sql.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-cloud-sql.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/cloud-sql/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-cloud-sql.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/cloud-sql/metrics/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "cloud-load-balancer",
+ "label": "Cloud Load Balancer",
+ "imgUrl": "/Logos/gcp-cloud-load-balancer.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-cloud-load-balancer.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcp-clb/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-cloud-load-balancer.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gcp-clb/metrics/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "vpc",
+ "label": "VPC",
+ "imgUrl": "/Logos/gcp-vpc.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-vpc.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/vpc/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-vpc.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/vpc/metrics/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "gke",
+ "label": "Google Kubernetes Engine",
+ "imgUrl": "/Logos/gcp-gke.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-gke.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gke/gke-logging-and-metrics/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-gke.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gke/gke-logging-and-metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/gcp-gke.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/gke/gke-tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "cloud-run",
+ "label": "Cloud Run",
+ "imgUrl": "/Logos/gcp-cloud-run.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "logging",
+ "label": "Logs",
+ "imgUrl": "/Logos/gcp-cloud-run.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/cloud-run/logging/"
+ },
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-cloud-run.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/cloud-run/metrics/"
+ },
+ {
+ "key": "tracing",
+ "label": "Traces",
+ "imgUrl": "/Logos/gcp-cloud-run.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/cloud-run/tracing/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "cloud-monitoring",
+ "label": "Cloud Monitoring",
+ "imgUrl": "/Logos/gcp-cloud-monitoring.svg",
+ "tags": ["GCP"],
+ "module": "apm",
+ "question": {
+ "desc": "What telemetry data do you want to visualise ?",
+ "type": "select",
+ "options": [
+ {
+ "key": "metrics",
+ "label": "Metrics",
+ "imgUrl": "/Logos/gcp-cloud-monitoring.svg",
+ "link": "https://signoz.io/docs/gcp-monitoring/cloud-monitoring/metrics/"
+ }
+ ]
+ }
+ },
+ {
+ "dataSource": "llm-monitoring",
+ "label": "LLM Monitoring",
+ "imgUrl": "/Logos/llm-monitoring.svg",
+ "tags": ["LLM Monitoring"],
+ "module": "apm",
+ "link": "https://signoz.io/docs/community/llm-monitoring/"
+ },
+ {
+ "dataSource": "android-java",
+ "label": "Android Java",
+ "imgUrl": "/Logos/android-java-monitoring.svg",
+ "tags": ["mobile app monitoring"],
+ "module": "apm",
+ "link": "https://signoz.io/docs/instrumentation/mobile-instrumentation/opentelemetry-java/"
+ },
+ {
+ "dataSource": "android-kotlin",
+ "label": "Android Kotlin",
+ "imgUrl": "/Logos/android-kotlin-monitoring.svg",
+ "tags": ["mobile app monitoring"],
+ "module": "apm",
+ "link": "https://signoz.io/docs/instrumentation/mobile-instrumentation/opentelemetry-kotlin/"
+ },
+ {
+ "dataSource": "flutter",
+ "label": "Flutter",
+ "imgUrl": "/Logos/flutter-monitoring.svg",
+ "tags": ["mobile app monitoring"],
+ "module": "apm",
+ "link": "https://signoz.io/docs/instrumentation/mobile-instrumentation/opentelemetry-flutter/"
+ },
+ {
+ "dataSource": "swift",
+ "label": "iOS Swift",
+ "imgUrl": "/Logos/swift-monitoring.svg",
+ "tags": ["mobile app monitoring"],
+ "module": "apm",
+ "link": "https://signoz.io/docs/instrumentation/mobile-instrumentation/opentelemetry-swiftui/"
+ },
+ {
+ "dataSource": "frontend-monitoring",
+ "label": "Web Vitals",
+ "imgUrl": "/Logos/llm-monitoring.svg",
+ "tags": ["Frontend Monitoring"],
+ "module": "apm",
+ "link": "https://signoz.io/docs/frontend-monitoring/opentelemetry-web-vitals/"
+ }
+]
diff --git a/frontend/src/container/SideNav/SideNav.tsx b/frontend/src/container/SideNav/SideNav.tsx
index a5761ec0d8..ef21822012 100644
--- a/frontend/src/container/SideNav/SideNav.tsx
+++ b/frontend/src/container/SideNav/SideNav.tsx
@@ -60,6 +60,10 @@ function SideNav(): JSX.Element {
const { user, featureFlags, licenses } = useAppContext();
+ const isOnboardingV3Enabled = featureFlags?.find(
+ (flag) => flag.name === FeatureKeys.ONBOARDING_V3,
+ )?.active;
+
const [licenseTag, setLicenseTag] = useState('');
const userSettingsMenuItem = {
@@ -131,10 +135,15 @@ function SideNav(): JSX.Element {
menuRoute: '/get-started',
menuLabel: 'Get Started',
});
+
+ const onboaringRoute = isOnboardingV3Enabled
+ ? ROUTES.GET_STARTED_WITH_CLOUD
+ : ROUTES.GET_STARTED;
+
if (isCtrlMetaKey(event)) {
- openInNewTab('/get-started');
+ openInNewTab(onboaringRoute);
} else {
- history.push(`/get-started`);
+ history.push(onboaringRoute);
}
};
@@ -270,10 +279,13 @@ function SideNav(): JSX.Element {
const isOnboardingEnabled =
featureFlags?.find((feature) => feature.name === FeatureKeys.ONBOARDING)
?.active || false;
+
if (!isOnboardingEnabled) {
updatedMenuItems = updatedMenuItems.filter(
(item) =>
- item.key !== ROUTES.GET_STARTED && item.key !== ROUTES.ONBOARDING,
+ item.key !== ROUTES.GET_STARTED &&
+ item.key !== ROUTES.ONBOARDING &&
+ item.key !== ROUTES.GET_STARTED_WITH_CLOUD,
);
}
diff --git a/frontend/src/container/SideNav/config.ts b/frontend/src/container/SideNav/config.ts
index df86d3a16e..9eadc78003 100644
--- a/frontend/src/container/SideNav/config.ts
+++ b/frontend/src/container/SideNav/config.ts
@@ -28,6 +28,7 @@ export const routeConfig: Record = {
[ROUTES.HOME_PAGE]: [QueryParams.resourceAttributes],
[ROUTES.GET_STARTED]: [QueryParams.resourceAttributes],
[ROUTES.ONBOARDING]: [QueryParams.resourceAttributes],
+ [ROUTES.GET_STARTED_WITH_CLOUD]: [QueryParams.resourceAttributes],
[ROUTES.LIST_ALL_ALERT]: [QueryParams.resourceAttributes],
[ROUTES.LIST_LICENSES]: [QueryParams.resourceAttributes],
[ROUTES.LOGIN]: [QueryParams.resourceAttributes],
diff --git a/frontend/src/container/SideNav/menuItems.tsx b/frontend/src/container/SideNav/menuItems.tsx
index b579319f14..145982c2f0 100644
--- a/frontend/src/container/SideNav/menuItems.tsx
+++ b/frontend/src/container/SideNav/menuItems.tsx
@@ -30,6 +30,12 @@ export const getStartedMenuItem = {
icon: ,
};
+export const getStartedV3MenuItem = {
+ key: ROUTES.GET_STARTED_WITH_CLOUD,
+ label: 'Get Started',
+ icon: ,
+};
+
export const inviteMemberMenuItem = {
key: `${ROUTES.ORG_SETTINGS}#invite-team-members`,
label: 'Invite Team Member',
diff --git a/frontend/src/container/TopNav/Breadcrumbs/index.tsx b/frontend/src/container/TopNav/Breadcrumbs/index.tsx
index 771505cc8c..8ac91a539b 100644
--- a/frontend/src/container/TopNav/Breadcrumbs/index.tsx
+++ b/frontend/src/container/TopNav/Breadcrumbs/index.tsx
@@ -9,6 +9,7 @@ const breadcrumbNameMap: Record = {
[ROUTES.SERVICE_MAP]: 'Service Map',
[ROUTES.USAGE_EXPLORER]: 'Usage Explorer',
[ROUTES.GET_STARTED]: 'Get Started',
+ [ROUTES.GET_STARTED_WITH_CLOUD]: 'Get Started',
[ROUTES.ALL_CHANNELS]: 'Channels',
[ROUTES.SETTINGS]: 'Settings',
[ROUTES.DASHBOARD]: 'Dashboard',
diff --git a/frontend/src/container/TopNav/DateTimeSelection/config.ts b/frontend/src/container/TopNav/DateTimeSelection/config.ts
index 0b8aa90bff..eda6ab99b3 100644
--- a/frontend/src/container/TopNav/DateTimeSelection/config.ts
+++ b/frontend/src/container/TopNav/DateTimeSelection/config.ts
@@ -108,6 +108,7 @@ export const routesToSkip = [
ROUTES.ALL_CHANNELS,
ROUTES.USAGE_EXPLORER,
ROUTES.GET_STARTED,
+ ROUTES.GET_STARTED_WITH_CLOUD,
ROUTES.GET_STARTED_APPLICATION_MONITORING,
ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING,
ROUTES.GET_STARTED_LOGS_MANAGEMENT,
diff --git a/frontend/src/container/TopNav/DateTimeSelectionV2/config.ts b/frontend/src/container/TopNav/DateTimeSelectionV2/config.ts
index bb24e884e5..3eafb58754 100644
--- a/frontend/src/container/TopNav/DateTimeSelectionV2/config.ts
+++ b/frontend/src/container/TopNav/DateTimeSelectionV2/config.ts
@@ -181,6 +181,7 @@ export const routesToSkip = [
ROUTES.ALL_CHANNELS,
ROUTES.USAGE_EXPLORER,
ROUTES.GET_STARTED,
+ ROUTES.GET_STARTED_WITH_CLOUD,
ROUTES.GET_STARTED_APPLICATION_MONITORING,
ROUTES.GET_STARTED_INFRASTRUCTURE_MONITORING,
ROUTES.GET_STARTED_LOGS_MANAGEMENT,
diff --git a/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx b/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx
new file mode 100644
index 0000000000..fcccbba0f1
--- /dev/null
+++ b/frontend/src/pages/OnboardingPageV2/OnboardingPageV2.tsx
@@ -0,0 +1,7 @@
+import OnboardingAddDataSource from '../../container/OnboardingV2Container/AddDataSource/AddDataSource';
+
+function OnboardingPageV2(): JSX.Element {
+ return ;
+}
+
+export default OnboardingPageV2;
diff --git a/frontend/src/pages/OnboardingPageV2/index.tsx b/frontend/src/pages/OnboardingPageV2/index.tsx
new file mode 100644
index 0000000000..9fad953dfe
--- /dev/null
+++ b/frontend/src/pages/OnboardingPageV2/index.tsx
@@ -0,0 +1,3 @@
+import OnboardingPage from './OnboardingPageV2';
+
+export default OnboardingPage;
diff --git a/frontend/src/utils/downloadFile.ts b/frontend/src/utils/downloadFile.ts
new file mode 100644
index 0000000000..b8e15cf689
--- /dev/null
+++ b/frontend/src/utils/downloadFile.ts
@@ -0,0 +1,22 @@
+export function downloadFile(content: string, filename: string): Promise {
+ return new Promise((resolve, reject) => {
+ try {
+ const blob = new Blob([content], { type: 'text/plain' });
+ const url = URL.createObjectURL(blob);
+
+ const link = document.createElement('a');
+ link.href = url;
+ link.setAttribute('download', filename);
+ document.body.appendChild(link);
+ link.click();
+
+ // Clean up after the download
+ document.body.removeChild(link);
+ URL.revokeObjectURL(url);
+
+ resolve(); // Resolve the promise when download is triggered
+ } catch (error) {
+ reject(error); // Reject in case of any errors
+ }
+ });
+}
diff --git a/frontend/src/utils/permission/index.ts b/frontend/src/utils/permission/index.ts
index 2377faa1ef..61b607c251 100644
--- a/frontend/src/utils/permission/index.ts
+++ b/frontend/src/utils/permission/index.ts
@@ -87,6 +87,7 @@ export const routePermission: Record = {
TRACE_EXPLORER: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED: ['ADMIN', 'EDITOR', 'VIEWER'],
ONBOARDING: ['ADMIN'],
+ GET_STARTED_WITH_CLOUD: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_APPLICATION_MONITORING: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_INFRASTRUCTURE_MONITORING: ['ADMIN', 'EDITOR', 'VIEWER'],
GET_STARTED_LOGS_MANAGEMENT: ['ADMIN', 'EDITOR', 'VIEWER'],